Ubuntu 26.04 운영체제의 Xen 가상서버에 ansible 설치 후 중앙관리 서버로 만드는 것이 목적입니다.
특히, ansible과 연동되는 WEB UI를 구성하여 보다 편리하게 서버를 관리하려고 합니다.
AWX 오픈소스 툴이 있지만 제 상황에서는 많은 기능과 확장성이 필요 없고 단순한 기능들 혹은 제가 만든 bash 명령어들을 수행하고 결과를 확인하는 정도면 충분합니다. 따라서 아래처럼 WEB UI를 만들어서 사용해보았습니다.
나만의 원격 명령어 도구 생성!
ansible 설치 시에는 최신 패치를 사용할 수 있고 기존 운영체제 내 환경과 따로 분리하는 방식인 pipx, 일반적인 패키지 설치 방식(apt)가 있습니다.
본 가상서버는 ansible 외에 특별한 서비스 운영이 없고 관리를 편하게 하기 위해서 단순 패키지 설치 방식으로 진행하겠습니다.
주의할 점으로는 패키지로 설치한 ansible-core 2.20.x 버전은 관리 대상(target) 서버에게 Python 3.9.x 이상을 요구합니다.
만일 대상 서버가 파이썬 버전을 충족하지 못한다면 3.9 이상으로 서버에 설치해두는 것이 좋고 레거시의 경우 raw, script 같은 모듈로만 관리하는 것이 좋습니다.
만일 다른 버전의 ansible을 설치하길 원한다면 아래 방식대로 진행하면 안됩니다.
apt update -y && apt upgrade -y
apt install -y ansible
ansible --version
ansible localhost -m ping
"ping": "pong"으로 돌아오면 정상입니다. 이 시점엔 인벤토리가 없어서 No inventory was parsed, only implicit localhost 경고가 뜨는데, (Ansible이 항상 암묵적 localhost를 가지고 있기 때문에) 이 경고는 무시해도 됩니다.
mkdir -p /opt/ansible/{inventory,playbooks,roles,group_vars,host_vars}
# (선택) 계정이 뚜렷하게 있을 시 권한 작업 진행
chown -R $USER:$USER /opt/ansible
ansible.cfg 작성cat > /opt/ansible/ansible.cfg << 'EOF'
[defaults]
inventory = ./inventory/hosts.ini
host_key_checking = False
retry_files_enabled = False
interpreter_python = /usr/bin/python3
roles_path = ./roles
collections_path = ./collections
[privilege_escalation]
become = True
become_method = sudo
become_user = root
[ssh_connection]
pipelining = True
EOF
host_key_checking = False는 초기 세팅 편의를 위해 설정한 내역으로 실제 운영 시에는 known_hosts로 관리하도록 바꾸는 게 좋습니다.
hosts.ini 작성cat > /opt/ansible/inventory/hosts.ini << 'EOF'
# 예시 그룹 구조 - 실제 대상 넣으면서 수정
[fortigate]
# fw ansible_host=x.x.x.x
[linux_servers]
# web01 ansible_host=x.x.x.x
[all:vars]
ansible_python_interpreter=/usr/bin/python3
ansible_become_method=sudo
EOF
앞단에 프록시 용도로 nginx를 두는 것을 권장합니다. 일단은 테스트 구축 시 확인하기 위한 용도로 설정합니다.
apt install -y nginx
===
nginx version: nginx/1.28.3 (Ubuntu)
===
mkdir -p /home/ansible-console
vi /etc/nginx/sites-available/ansible
===
server {
listen 80;
server_name $DOMAIN_OR_$IP;
root /var/www/ansible-console;
index index.html;
}
===
ln -s /etc/nginx/sites-available/ansible /etc/nginx/sites-enabled/
nginx -t
systemctl reload nginx
※ 웹 소스 코드의 경우 AI Agent를 사용하였습니다.
1. **그룹 관리**
- 디렉터리(인벤토리) 그룹의 생성, 수정, 삭제 및 목록 조회 기능
2. **호스트 관리**
- 앤서블로 관리할 대상 호스트 정보 저장, 수정, 삭제 기능
3. **호스트 조회 및 상세 뷰**
- 호스트 IP, 연결 방법(SSH 등), 운영체제(OS), 소속 그룹 등 필요한 핵심 정보를 데이터 테이블(표) 형태로 출력
- 텍스트 검색 기능 및 테이블 인덱스(컬럼)별 오름차순/내림차순 정렬 기능 필수
- 데이터 테이블에서 호스트가 있는 한 줄(Row)을 클릭하면, 해당 호스트의 전체 상세 정보를 확인할 수 있는 UI(모달 창 또는 상세 페이지) 제공
4. **명령어 파일 정리 (생성 및 검증)**
- 명령어(Playbook 또는 Script) 파일을 작성할 수 있는 에디터 기능
- 작성한 명령어 파일의 문법이나 구조가 올바른지 검사(Validation/Linting)하는 기능 포함
5. **명령어 파일 목록 확인**
- 저장 및 관리 중인 명령어 파일들의 목록을 확인하는 기능
6. **명령어 파일 실행 이력 확인**
- 언제, 어떤 명령어 파일을 실행했는지 전체 실행 이력(History) 목록 제공
- 특정 실행 이력을 선택하면, **실행 대상이 된 호스트별로 결과(성공/실패 및 로그 출력)**를 상세하게 확인할 수 있는 기능
기능 명세를 모두 만족한다면 구조나 ui는 당신이 자유롭게 결정해도 됩니다. 다만, 깔끔한 형태로 해주세요.
초록 색과 노란 색을 메인 컬러로 하여 많이 사용해주세요.
웹의 성격이 마케팅, 대표 홈페이지가 아니라 실제 서버 운영용 콘솔 개념입니다.
노후화 된 레거시 자원을 ansible raw나 script로 관리할 예정임을 감안하고 디자인해주세요.
전형적인 AI가 만든 웹 UI이지만...💭 개인적으로는 편리한 운영이 목적이므로 기능 명세 항목을 만족하면 상관 없습니다.
다만, 추후 확장성을 고려하여 구조를 손보기로 하였고 최상단을 Ansible-console이 아니라 운영 관리 도구 문자열로 두고 확정 추가 프로젝트인 FortiGate 방화벽 관련 매뉴를 트리 구조에 추가하기로 하였습니다.
본 게시글은 ansible 용도로 작성하였기 때문에 ansible 쪽만 이어서 기재하겠습니다.
로그인 기능을 구현함과 동시에 아래 기능들을 완성하였습니다.
✅ 첫 접속 → 회원가입 (최초 가입 계정이 admin임을 안내) → 이후 접속 → 로그인 화면
✅ 로그인 시 1차 비밀번호(bcrypt 해시) 인증 → 2차 OTP혹은 이메일 인증
✅ 쿠키 세션 30분, 활동 시 자동 연장 → 세션 카운트다운 + 수동 연장 버튼 → 만료 시 자동 로그아웃
✅ 감사추적을 세션 이메일 기반으로 전환
✅ 미로그인 시 모든 API 차단(401)
✅ 비밀번호 해시·시크릿 미노출
만들다 곰곰히 생각해보니 더이상 ansible만을 다루는 건 아닌 것 같아 규모가 확장됨에 따라 새로운 인프라 관리 콘솔로 제작할 예정입니다.
pipx는 venv를 자동으로 관리해주는 도구입니다. Ubuntu 26.04에서는 apt install -y pip가 불가하여 별도로 내부 패키지와 분리하기 위해 venv 환경을 만들어 사용합니다. pipx를 사용하면 venv를 더 편하게 이용할 수 있습니다.
apt install -y pipx apache2-utils tar
pipx --version
===
1.8.0
===
제가 하려던 작업은 레거시 포함 서버들의 비밀번호 변경이 포함되어 있어 sshpass 패키지도 설치하였습니다.
apt install -y sshpass
sshpass -V | head -1
===
sshpass 1.10
===
웹·앱을 직접 pipx로 넣을 수는 없습니다. 대신, uvicorn을 pipx로 설치하고 그 venv에 fastapi·ansible-runner를 inject합니다. 결과적으로 pipx가 venv를 관리하고 서버 관리자는 uvicorn 절대 경로로 앱을 띄우는 구조입니다.
우선은 소스 코드부터 옮겨줍니다. /opt/ansible-console로 옮겨 주었습니다.
ls -al /opt/ansible-console
트리 명령어로 구조를 확인하면 주 작업 폴더는 /opt이고 하단에는 ansible 설정 파일과 ansible console 웹 프로젝트 폴더가 있습니다.
tree /opt
===
/opt
├── ansible
│ ├── ansible.cfg
│ ├── group_vars
│ ├── host_vars
│ ├── inventory
│ ├── playbooks
│ └── roles
└── ansible-console
├── backend
│ ├── app.py
│ ├── db.py
│ ├── inventory.py
│ ├── jobs.py
│ ├── requirements.txt
│ ├── runner.py
│ ├── secrets
│ └── vault.py
├── deploy
│ ├── ansible-console.service
│ └── nginx-ansible.conf
├── frontend
│ └── index.html
└── README.md
12 directories, 12 files
===
/opt 하단에 있는 두 서비스 ansible과 web-ui에서 사용하는 계정을 동일하게 맞춰서 각 파일 별로 동일한 계정이 관리하는 파일 계층에서 묶어주는 것이 나중에 관리하기 수월합니다.
useradd -r -d /opt/ansible -s /bin/bash ansible
chown -R ansible:ansible /opt/ansible /opt/ansible-console
pipx로 uvicorn 설치pipx로 앱 의존성을 ansible 계정 홈(/opt/ansible/.local)에 설치합니다.
sudo -u ansible -H bash -lc '
pipx ensurepath
pipx install uvicorn
pipx inject uvicorn fastapi ansible-runner ansible-core pyyaml
'
ansible-core가 크기 때문에 위 작업은 시간이 걸립니다. 저는 1분 정도 소요되었습니다. 마지막에 injected package pyyaml into venv uvicorn 비슷한 메시지가 나오면 통과입니다.
systemd에서 절대 경로(/opt/ansible/.local/bin/uvicorn)로 호출할 거라 PATH 등록이 필요 없습니다. 관련 경고를 무시하고 진행합니다.
sudo -u ansible /opt/ansible/.local/bin/uvicorn --version
# 임시로 백그라운드 실행해보기
sudo -u ansible /opt/ansible/.local/bin/uvicorn \
--app-dir /opt/ansible-console/backend app:app \
--host 127.0.0.1 --port 8000 &
# 응답 여부 확인
curl -s -o /dev/null -w "HTTP %{http_code}\n" http://127.0.0.1:8000/api/state
HTTP 200 코드가 반환되면 성공입니다. 백그라운드에 올렸던 임시 프로세스를 종료시킵니다.
pkill -f "uvicorn.*app:app"
Vault 마스터 비밀번호 파일 생성root나 시스템 계정의 비밀번호가 아니라, vault 안에서 사용할 Secret Key 문자열을 생성해야 합니다.
파일 위치는 취향에 따라 다르겠지만 저는 앱과 분리하기 위해서 /etc 하단에 별도 폴더를 생성하여 파일을 넣어 두겠습니다.
❌ /opt/ansible-console 안에 넣을 경우 → 관리가 용이하지만 앱과 분리하기 번거로워짐
✅ /etc/$별개_폴더_생성 안에 넣을 경우 → 앱과 분리하기 수월함
mkdir -p /etc/ansible-console
vi /etc/ansible-console/vault_pass
===
# 문자열 입력 후 저장
===
chown root:ansible /etc/ansible-console/vault_pass
chmod 640 /etc/ansible-console/vault_pass
ls -al /etc/ansible-console/vault_pass
===
-rw-r----- 1 root ansible 11 Sep 7 10:18 /etc/ansible-console/vault_pass
===
# ansible 전용 계정으로 접근 가능한지 확인
sudo -u ansible cat /etc/ansible-console/vault_pass | wc -c
===
# $입력한_비밀번호_글자_수+1
===
wc -c 명령어는 파일이 몇 Byte인지 세고 출력합니다. 예를 들어 비밀번호를 15자리로 설정한 경우 15자리 + 개행 1로 판단하여, 16이 출력됩니다. 줄바꿈이 없어도 개행은 +1 됩니다.
안전한 비밀번호 설정을 위해 특수문자 및 대·소문자, 숫자를 포함한 20자리 이상의 비밀번호를 설정하는 것을 권장합니다.
systemd 유닛 파일 생성 후 실행pipx 경로랑 vault 파일 위치를 실제 세팅에 맞게 반영해서 새로 작성합니다.
sudo tee /etc/systemd/system/ansible-console.service > /dev/null <<'EOF'
[Unit]
Description=Ansible Console (FastAPI backend)
After=network.target
[Service]
Type=simple
User=ansible
Group=ansible
WorkingDirectory=/opt/ansible-console/backend
# 앱에서 사용할 환경 변수 선언
Environment=ANSIBLE_CONSOLE_DB=/opt/ansible-console/backend/console.db
Environment=ANSIBLE_CONSOLE_FRONTEND=/opt/ansible-console/frontend
Environment=ANSIBLE_CONSOLE_VAULT_PASS_FILE=/etc/ansible-console/vault_pass
Environment=ANSIBLE_HOST_KEY_CHECKING=False
# 바인딩 주소 127.0.0.1 로만 설정 → 외부 노출은 nginx가 수행함
ExecStart=/opt/ansible/.local/bin/uvicorn --app-dir /opt/ansible-console/backend app:app --host 127.0.0.1 --port 8000
Restart=on-failure
RestartSec=3
[Install]
WantedBy=multi-user.target
EOF
# 실행
systemctl daemon-reload
systemctl enable ansible-console --now
# 10초 정도 대기 후 명령어 실행
systemctl status ansible-console --no-pager
Active: active (running)이라는 문구와 해당 문구가 초록색으로 출력되는지 확인합니다.
curl 질의로 실행 결과 확인curl -s http://127.0.0.1:8000/api/state | head -c 200
첫 줄이 {"groups":[... JSON 문자열로 시작하는지 확인합니다.
echo
curl -s http://127.0.0.1:8000/api/vault
두 번째 줄이 {"configured":true,"keys":[]} JSON 문자열인지 확인합니다. journalctl 결과에 에러가 출력되지 않으면 됩니다.
basic auth 사용자 만들기웹 로그인용 계정입니다. 아래 명령어로 생성합니다.
# 최초 계정 생성
htpasswd -c /etc/nginx/.htpasswd $username
# 이후 새로운 계정 생성 또는 기존 계정 비밀번호 변경 시
htpasswd /etc/nginx/.htpasswd $username
-c 옵션은 파일이 없어 생성하겠다는 의미이므로 최초 계정 생성 시에만 사용해야 합니다. 아니면 이후 계정 생성하면서 덮어쓰기 되어 기존 계정 내역이 사라집니다.
allow_ip 점검/opt/ansible-console/deploy/nginx-ansible.conf 안에 접근 IP 대역이 기재되어 있습니다. 필요 시 상황에 맞춰 수정합니다.
nginx 폴더로 복사rm -f /etc/nginx/sites-enabled/*
cp /opt/ansible-console/deploy/nginx-ansible.conf /etc/nginx/sites-available/ansible-console
ln -s /etc/nginx/sites-available/ansible-console /etc/nginx/sites-enabled/
# 설정파일 검사
nginx -t
===
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
===
systemctl reload nginx
systemctl status nginx --no-pager | head -n 5
active (running)인지 확인합니다.
curl로 nginx 프로세스 접근 테스트① 인증 없이 접근 → HTTP CODE 401 (Unauthorized) ✔️
curl -s -o /dev/null -w "no auth: HTTP %{http_code}\n" http://$Server_IP/
② 인증 붙여서 접근 → HTTP CODE 200 (OK) ✔️
curl -su $username:$htpasswd -o /dev/null -w "with auth: HTTP %{http_code}\n" http://$Server_IP/
③ API 프록시 접근 → {"groups":[... JSON 출력 ✔️
curl -su $username:$htpasswd http://$Server_IP/api/state | head -c 100
htpasswd 로그인 창이 출력됩니다.
로그인 시 아래와 같이 메인 화면이 출력됩니다.
① 그룹 추가
② (기등록 그룹) 수정
③ 하위 그룹 생성
④ (기등록 그룹) 삭제
sudo -u ansible touch /opt/ansible/inventory/hosts.ini
sudo -u ansible cp /opt/ansible-console/backend/app.py /opt/ansible-console/backend/app.py_ori
sudo -u ansible vi /opt/ansible-console/backend/app.py
===
# 파일 최상단 아래 import 구문 밑에 경로 추가
INVENTORY_EXPORT_PATH = os.environ.get("ANSIBLE_CONSOLE_INVENTORY_PATH", "/opt/ansible/inventory/hosts.ini")
# 경로 참조하도록 함수 만들기
def _export_inventory():
"""DB 변경 후 실제 Ansible이 읽는 인벤토리 파일로 export."""
try:
text = inventory.build_ini()
with open(INVENTORY_EXPORT_PATH, "w", encoding="utf-8") as f:
f.write(text)
except Exception as e:
# 인벤토리 쓰기 실패는 API 실패로 전파하지 않음 (로그만)
print(f"[inventory export] {e}")
# 6곳의 라우트 함수 return 문 바로 앞에 _export_inventory() 호출 추가:
create_group → return 앞
update_group → return 앞
remove_group → return 앞
create_host → return 앞
update_host → return 앞
remove_host → return 앞
===
systemctl restart ansible-console
① 그룹 추가: 신규 그룹 추가 완료
② (기등록 그룹) 수정: 신규 그룹 데이터 및 신규 하위 그룹 데이터 수정 완료
③ 하위 그룹 생성: 신규 그룹에 하위 그룹 추가 완료
④ (기등록 그룹) 삭제: 기등록 그룹 및 하위 그룹 삭제 완료
부가 기능으로 하위 그룹이 존재하는 상위 그룹 삭제 시도 시 팝업 알림으로 하위 그룹 먼저 삭제하라는 알림이 발생합니다.
cat /opt/ansible/inventory/hosts.ini
seed 데이터db.py 파일 안에 _seed() 함수가 DB가 비어있으면 자동으로 샘플 그룹·호스트·파일들(rocky9-web01, centos5-old03, os-info-collect.sh 등)을 추가해서 넣습니다. 데모 용으로 확인할 때 만들어둔 기능이지만 실서버에는 필요 없으니 삭제합니다. 무엇보다 이 함수 기능 때문에 *.py 설정파일 수정 후 systemctl restart ansible-console을 하면 기존 데이터 외 seed 데이터가 자꾸 생성되어 매번 삭제하기 번거롭습니다.
def init_db():
with _lock, _conn() as c:
c.executescript(SCHEMA)
# 마이그레이션: 구 DB에 vault_var 컬럼이 없으면 추가
cols = [r["name"] for r in c.execute("PRAGMA table_info(hosts)").fetchall()]
if "vault_var" not in cols:
c.execute("ALTER TABLE hosts ADD COLUMN vault_var TEXT DEFAULT ''")
# 실서버 배포용: 시드 데이터 자동 삽입 없음 (필요 시 _seed() 수동 호출)
DB 초기화 부분에서 seed 함수 호출 구문을 삭제했습니다. 함수는 여전히 선언되어 있기에 필요 시 수동으로 넣고 실행하면 됩니다.
apt install -y splite3
sudo -u ansible sqlite3 /opt/ansible-console/backend/console.db <<'SQL'
DELETE FROM hosts WHERE name IN ('rocky9-web01','rocky9-web02','rocky8-api01','rocky9-db01','centos7-old01','centos6-old02','centos5-old03');
DELETE FROM files WHERE name IN ('os-info-collect.sh','passwd-rotate.sh');
DELETE FROM executions;
DELETE FROM results;
SQL
systemctl restart ansible-console
seed 호스트가 싹 사라졌습니다.
① 호스트 추가
② (기등록 호스트) 수정
③ (기등록 호스트) 삭제
호스트 추가 방식에는 두 가지가 있습니다.
❌ 1. vault 패스워드 암호화 파일 생성 후 패스워드 기반 접근 (레거시 raw 방식)
✅ 2. ssh-key 기반 인증으로 접근 (권장)
👉 레거시 서버의 경우에도 인증은 key 기반으로 가능합니다. 다만, 명령줄 입력 시에만 raw 방식으로 진행하면 됩니다.
key 인증을 우선적으로 사용하되 일회성 작업으로 등록하거나 key 기반 방식이 불가한 서버가 있을 경우 사용할 수 있도록 vault 패스워드 인증 기능을 구현하였습니다.
ssh-copy-id로 호스트 등록# 생성
sudo -u ansible ssh-keygen -t rsa -b 4096 -f /opt/ansible/.ssh/id_rsa -N ''
# client 서버에 key 배포
sudo -u ansible ssh-copy-id -i /opt/ansible/.ssh/id_rsa.pub root@$Server_IP
# sshd port가 22번이 아닌 경우
sudo -u ansible ssh-copy-id -i /opt/ansible/.ssh/id_rsa.pub -p 00000 root@$Server_IP
# 인증 테스트 (비밀번호 없이 명령어 실행 가능해야 성공)
ssh -i /opt/ansible/.ssh/id_rsa 'root@$Server_IP'
인증 방식을 키 기반으로 하는 것 외에 특이사항은 없습니다.
수정 및 삭제도 정상적으로 동작합니다.
호스트의 OS에 따라 레거시 임을 분류하여 색상을 노란 색으로 표시하고 있습니다. 또한 백그라운드에서 동작 시에도 ansible raw 모듈을 사용하며, 파이썬 동작 없이 shell 명령어로 주고 받고 레거시 KexAlgorithms 옵션을 사용합니다.
이에 호스트의 운영체제 선택은 매우 중요합니다. 호스트 목록에서 육안으로 분류하는 목적도 있으니 다양한 운영체제 항목을 생성해두었습니다.
ssh-copy-id 호스트 등록 과정 통합위 key 생성 및 배포 (ansible master 서버에서) 과정을 호스트 등록 (web ui에서)에서 가능하도록 수정하였습니다.
호스트 등록을 위해 web과 서버 터미널에서 두 번 작업할 필요가 없습니다.
인증 방식
key기반 선택 시
ansible 계정의 rsa_key가 생성되어 있는지 확인 후 생성되어 있지 않다면 에러 문구를 출력, 생성되어 있다면 등록한 호스트 정보로 키를 등록하고 접근 테스트를 진행합니다.
동일한 IP 등록 제한 기능은 일부러 배제하였습니다. 같은 서버를 다른 부서에서 사용하는 경우가 있어 다른 그룹으로 등록하여 작업할 일이 있기 때문입니다.
인증 방식 패스워드 선택 시
vault암호화로 연결
호스트의 연결 상태를 확인할 수 있는 아이콘이 출력됩니다. Default 상태는 체크 안 함 입니다.
전체 연결 확인 버튼으로 등록된 호스트 전체의 연결 상태를 확인할 수 있습니다.
특정 호스트 체크박스 선택 시 선택 확인 버튼이 활성화됩니다. 선택한 호스트만 연결 상태를 확인할 수 있습니다.
검색 후 선택 확인 시 연결 상태 점검 후에도 검색 필터링 내역은 유지됩니다.
연결 상태 점검 후 에러 발생 시 아이콘 색이 붉은 색으로 변경되며, 클릭하면 에러 원문과 간단한 설명을 확인할 수 있습니다.
*.csv, *.txt 파일을 파싱 가능합니다. 토글을 통해 어떤 방식으로 호스트를 등록할 것인지 업로드하는 사용자가 선택할 수 있으며, 이 선택 값이 우선순위로 적용되어 파일 내부에 다른 방식의 인증에 필요한 정보가 포함되어 있더라도 무시하고 사용자가 선택한 인증방식으로 등록합니다.
다만, 비밀번호 평문 값이 그대로 입력된 파일을 업로드하는 것에 대한 재고가 필요합니다. 기능 구현 후 어떻게 보안성을 유지할 것인지 생각하여 업데이트가 필요합니다.
그룹 정보는 /로 하위 그룹임을 나타냅니다. 존재하지 않는 그룹 정보를 넣을 경우 에러가 발생하며, 해당 그룹 명으로 등록한 호스트는 모두 제외됩니다.
호스트 대량 등록 작업이 완료된 이후에는 본 작업에서 등록한 호스트 전체를 연결 테스트로 확인할 수 있습니다.
대상 호스트가 접근이 가능한 경우 삭제와 동시에 등록한 키도 삭제하지만, 불가한 경우 알림을 출력하고 호스트 목록에서는 삭제합니다.
① 목록 확인 (탭 이동)
② (기등록 명령파일) 수정
③ (기등록 명령파일) 실행
④ (기등록 명령파일) 삭제
⑤ 작성·검사 (탭 이동)
⑥ 새로 작성 (textarea 내용 모두 삭제)
⑦ 민감 파일 설정 여부
⑧ 파일 검사
⑨ 저장
위 기능 모두 정상 동작하였습니다. 결과 값은 실행 이력 매뉴에서 확인 가능합니다.
🔐 민감 파일 자동 검사 구문
# `runner.py` 內
SECRET = re.compile(r"passwd|chpasswd|shadow|password|secret|token", re.I)
...
if has_secret and not sensitive:
msgs.append({"lv": "w", "line": 0,
"text": '패스워드/시크릿 패턴 감지 — "민감 파일"로 표시해 Vault·no_log를 적용하세요.'})
정규식 문법 기준으로 위 문자열이 잡히면 민감 파일로 간주하고 경고만 출력합니다.
체크박스는 수동 동작에만 의존합니다.
.sh 파일도 playbook 하단에 저장현재는 yaml 파일만 playbook 하단에 저장하고, bash script는 DB에만 저장합니다.
.sh 파일도 playbook 하단에 저장하도록 변경하였습니다. 단, 수동으로 민감 파일로 체크한 경우 파일 시스템에 저장되지 않습니다.
yaml 파일 작성 칸 구분현 UI 및 기능은 bash 기준으로 구성되어 있습니다. 이용자가 구분할 수 있도록 yaml 작성 탭을 별도로 제작하여 구분합니다.
스크립트 자체의 정보 값에 실행 그룹을 넣는 것이 아니라 스크립트 목록에서 이미 등록된 실행 그룹들을 불러와서 자유롭게 실행할 수 있도록 변경합니다. 이 과정에서 target_group_id 컬럼은 완전히 제거하였습니다. 컬럼 제거 시 당장 발생하는 문제는 초기 UI 소스 코드 중 seed 데이터 생성 시 해당 컬럼까지 만든다는 점인데, 어차피 함수를 실행하지 않도록 DB init 구문에서 제거하였기 때문에 괜찮습니다.
그룹 출력은 별도의 팝업이 아니라 실행 목록 페이지 안에서 해결하도록 프롬프트를 작성하였고 그룹 출력 시 정렬 상태를 최상위 그룹 기준으로 같은 값을 가진 그룹끼리 묶어서 출력하도록 변경하였습니다.
만일, 그룹 선택을 하지 않고 스크립트 실행 버튼을 누른다면 실행이 불가하도록 설정하였습니다.
민감 파일로 체크하고 저장한 스크립트를 실행하면 결과 값은 이력에서 확인할 수 없습니다. DB에도 저장되지 않습니다.
sudo -u ansible sqlite3 /opt/ansible-console/backend/console.db "SELECT host_name, length(stdout), substr(stdout,1,100) FROM results ORDER BY id ASC LIMIT 1;"
log 하단에 저장한 개의 yaml 또는 bash script 실행 시 모든 실행 대상 호스트와 호스트의 결과(성공 및 실패)를 /opt/ansible/log에 남기도록 설정하였습니다.
로그인 기능을 htpasswd로 대체하였더니 작업자의 정보가 남지를 않습니다. 회원 기능은 추후 배포 시에 대규모 수정 사항 중 하나로 추가해두고 일단 basic auth 값을 nginx 단에서 넘겨주도록 설정하여 처리하였습니다.
vi /etc/nginx/sites-available/ansible-console
===
proxy_set_header X-Remote-User $remote_user;
===
systemctl reload nginx
실행자와 등록·수정자까지만 기록하겠습니다.