- 검증 내용: SSH 접속 포트가
20022로 변경되었으며, Root 계정으로의 직접적인 원격 접속이 차단되었는지 확인합니다. - 검증 명령어:
sudo grep -i -E "port|permitrootlogin" /etc/ssh/sshd_config - 출력 결과:
Port 20022 PermitRootLogin no - 포트 활성화 상태 확인 (
ss -tulnp):출력 예시:ss -tulnp | grep 20022tcp LISTEN 0 128 0.0.0.0:20022 0.0.0.0:* users:(("sshd",pid=1234,fd=3))
- 검증 내용: UFW 방화벽이 활성화되어 있고, 오직 TCP
20022(SSH) 및 TCP15034(APP) 포트만 인바운드로 허용하는지 확인합니다. - 검증 명령어:
sudo ufw status verbose
- 출력 결과:
Status: active Logging: on (low) Default: deny (incoming), allow (outgoing), deny (routed) New profiles: skip To Action From -- ------ ---- 20022/tcp ALLOW IN Anywhere 15034/tcp ALLOW IN Anywhere 20022/tcp (v6) ALLOW IN Anywhere (v6) 15034/tcp (v6) ALLOW IN Anywhere (v6)
- 검증 내용: 요구사항에 지정된 계정(
agent-admin,agent-dev,agent-test) 및 그룹(agent-common,agent-core)이 올바르게 생성되고 그룹 매핑이 완료되었는지 확인합니다. - 검증 명령어:
id agent-admin id agent-dev id agent-test
- 출력 결과:
$ id agent-admin uid=1000(agent-admin) gid=1002(agent-admin) groups=1002(agent-admin),1000(agent-common),1001(agent-core) $ id agent-dev uid=1001(agent-dev) gid=1003(agent-dev) groups=1003(agent-dev),1000(agent-common),1001(agent-core) $ id agent-test uid=1002(agent-test) gid=1004(agent-test) groups=1004(agent-test),1000(agent-common)
- 검증 내용:
$AGENT_HOME하위 디렉토리 및/var/log/agent-app디렉토리에 대해 요구조건에 맞는 소유자, 그룹, 권한 정책(Setgid 포함)이 적용되었는지 확인합니다. - 검증 명령어:
sudo getfacl /home/agent-admin/agent-app/upload_files /home/agent-admin/agent-app/api_keys /var/log/agent-app
- 출력 결과:
# file: home/agent-admin/agent-app/upload_files # owner: agent-admin # group: agent-common # flags: -s- user::rwx group::rwx other::--- # file: home/agent-admin/agent-app/api_keys # owner: agent-admin # group: agent-core # flags: -s- user::rwx group::rwx other::--- # file: var/log/agent-app # owner: agent-admin # group: agent-core # flags: -s- user::rwx group::rwx other::---
- 검증 내용: 일반 계정(
agent-admin)으로 실행하여 5단계의 부트 검증을 모두[OK]로 통과하고Agent READY상태 및15034포트 바인딩이 성공했는지 확인합니다. - 출력 내역:
Starting Agent Boot Sequence... [1/5] Checking User Account [OK] Running as service user 'agent-admin' (uid=1000) [2/5] Verifying Environment Variables [OK] All required Envs correct [3/5] Checking Required Files [OK] Verified key file with correct key string. [4/5] Checking Port Availability Port 15034 is available. [5/5] Verifying Log Permission [OK] [OK] Log directory is writable: /var/log/agent-app All Boot Checks Passed! Agent READY - 포트 바인딩 확인 (
ss -tulnp):출력 예시:ss -tulnp | grep 15034tcp LISTEN 0 128 0.0.0.0:15034 0.0.0.0:* users:(("agent-app-linux",pid=4724,fd=7))
- 검증 내용:
monitor.sh스크립트가 프로세스 상태, 포트 상태, 리소스 사용량을 정확히 확인하고 이상 징후 발생 시 Warning 경고를 콘솔로 출력하는지 검증합니다. - 실행 권한 및 소유정보: 소유자
agent-dev, 그룹agent-core, 권한750(rwxr-x---) - 수행 명령어:
/home/agent-admin/agent-app/bin/monitor.sh
- 출력 결과:
====== SYSTEM MONITOR RESULT ====== [HEALTH CHECK] Checking process 'agent-app-linux-arm64'... [OK] (PID: 4724) Checking port 15034... [OK] [RESOURCE MONITORING] CPU Usage : 1.6% MEM Usage : 8.4% DISK Used : 6% [INFO] Log appended: /var/log/agent-app/monitor.log
- 검증 내용:
agent-admin계정의 크론으로 매 분monitor.sh가 실행되어/var/log/agent-app/monitor.log에 주기적으로 누적되는지 확인합니다. - crontab 등록 내역 확인 명령어:
sudo crontab -u agent-admin -l
- 출력 결과:
* * * * * AGENT_HOME=/home/agent-admin/agent-app AGENT_PORT=15034 AGENT_LOG_DIR=/var/log/agent-app /home/agent-admin/agent-app/bin/monitor.sh >> /var/log/agent-app/cron.log 2>&1 - 실제 누적된
monitor.log기록 확인:tail -n 5 /var/log/agent-app/monitor.log
- 출력 결과:
[2026-05-30 22:15:01] PID:4724 CPU:1.6% MEM:7.2% DISK_USED:6% [2026-05-30 22:16:01] PID:4724 CPU:100.0% MEM:5.8% DISK_USED:6% [2026-05-30 22:17:01] PID:4724 CPU:2.4% MEM:7.5% DISK_USED:6% [2026-05-30 22:18:02] PID:4724 CPU:1.7% MEM:5.5% DISK_USED:6%
- 설정 파일:
/etc/ssh/sshd_config - 적용 명령어:
# SSH 설정 파일 수정 (Port 변경 및 Root 로그인 차단) sudo sed -i 's/#Port 22/Port 20022/' /etc/ssh/sshd_config sudo sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin no/' /etc/ssh/sshd_config # SSH 서비스 재시작 sudo systemctl restart ssh
- 선택 방화벽: UFW (Ubuntu)
- 적용 명령어:
# 인바운드 기본 차단 및 아웃바운드 기본 허용 sudo ufw default deny incoming sudo ufw default allow outgoing # 특정 서비스 포트만 개방 (SSH: 20022, App: 15034) sudo ufw allow 20022/tcp sudo ufw allow 15034/tcp # 방화벽 활성화 sudo ufw enable
- 적용 명령어:
# 1. 요구 그룹 생성 sudo groupadd agent-common sudo groupadd agent-core # 2. 요구 사용자 계정 생성 (홈 디렉토리 생성 및 기본 쉘 지정) sudo useradd -m -s /bin/bash agent-admin sudo useradd -m -s /bin/bash agent-dev sudo useradd -m -s /bin/bash agent-test # 3. 사용자 계정을 해당 그룹에 추가 sudo usermod -aG agent-common,agent-core agent-admin sudo usermod -aG agent-common,agent-core agent-dev sudo usermod -aG agent-common agent-test
- 적용 명령어:
# 1. 요구 디렉토리 구조 생성 sudo mkdir -p /home/agent-admin/agent-app/upload_files sudo mkdir -p /home/agent-admin/agent-app/api_keys sudo mkdir -p /var/log/agent-app # 2. 디렉토리 소유자와 소유 그룹 지정 sudo chown agent-admin:agent-common /home/agent-admin/agent-app/upload_files sudo chown agent-admin:agent-core /home/agent-admin/agent-app/api_keys sudo chown agent-admin:agent-core /var/log/agent-app # 3. 권한 설정 및 Setgid 설정 (2770) # Setgid(2000)를 부여하여 해당 디렉토리 내에 생성되는 파일들이 부모 디렉토리의 그룹을 상속받도록 함. sudo chmod 2770 /home/agent-admin/agent-app/upload_files sudo chmod 2770 /home/agent-admin/agent-app/api_keys sudo chmod 2770 /var/log/agent-app
- 설정 파일:
/home/agent-admin/.bashrc - 적용 명령어:
# agent-admin 계정의 .bashrc 파일 하단에 환경 변수 선언 추가 cat << 'EOF' >> /home/agent-admin/.bashrc # Agent App Environment Variables export AGENT_HOME=/home/agent-admin/agent-app export AGENT_PORT=15034 export AGENT_UPLOAD_DIR=/home/agent-admin/agent-app/upload_files export AGENT_KEY_PATH=/home/agent-admin/agent-app/api_keys export AGENT_LOG_DIR=/var/log/agent-app EOF # 환경 변수 반영 source /home/agent-admin/.bashrc
- 적용 명령어:
# agent-admin 사용자의 크론탭 에디터 실행 # (또는 sudo crontab -u agent-admin -e) crontab -e
- 크론탭 등록 내용:
# 매 분(1분 간격) 실행 환경 변수 정의와 함께 monitor.sh를 백그라운드 자동 실행하도록 구성 * * * * * AGENT_HOME=/home/agent-admin/agent-app AGENT_PORT=15034 AGENT_LOG_DIR=/var/log/agent-app /home/agent-admin/agent-app/bin/monitor.sh >> /var/log/agent-app/cron.log 2>&1
- SSH 포트 변경
20022및 Root 원격 접속 차단 설정 확인 내역- 증거:
/etc/ssh/sshd_config파일 내Port 20022및PermitRootLogin no설정 결과 확인
- 증거:
- 방화벽 활성화 및
20022/tcp,15034/tcp만 허용 내역- 증거: UFW 방화벽 활성화 상태 및 인바운드 허용 포트(
20022/tcp,15034/tcp) 확인
- 증거: UFW 방화벽 활성화 상태 및 인바운드 허용 포트(
- 계정/그룹 생성 확인 내역
-
agent-admin(그룹:agent-common,agent-core포함) -
agent-dev(그룹:agent-common,agent-core포함) -
agent-test(그룹:agent-common포함) -
agent-common -
agent-core - 증거:
id명령어 조회를 통한 사용자 생성 및 그룹 매핑 확인
-
- 디렉토리 구조 및 권한 확인 내역
- 증거:
$AGENT_HOME/upload_files(770, agent-common, Setgid 적용),$AGENT_HOME/api_keys(770, agent-core, Setgid 적용),/var/log/agent-app(770, agent-core, Setgid 적용) 확인
- 증거:
- 앱 Boot Sequence 5단계
[OK]및"Agent READY"확인 내역- 증거:
agent-admin권한으로 실행한 애플리케이션의 부팅 검증 5단계 정상 출력 증적 확인
- 증거:
-
monitor.sh실행 결과 확인 내역- 프로세스 (동작 중인
agent-app-linux-arm64PID 감지) - 포트 (
15034/tcpListen 확인) - 리소스 (CPU, MEM, DISK 실시간 사용량 출력)
- 경고 (임계치 초과 시 [WARNING] 출력)
- 증거:
monitor.sh수동 실행을 통한 정상 콘솔 출력 결과물 확인
- 프로세스 (동작 중인
-
/var/log/agent-app/monitor.log누적 기록 확인 내역- 증거:
monitor.sh실행 시 지정된 포맷의 로그가 정상적으로 누적 기록되는 증적 확인
- 증거:
- crontab 매분 실행 등록 및 자동 실행 확인 내역
- 증거:
agent-admin크론탭 리스트 등록 확인 및 크론로그를 통해 매 분 자동 수행되는 기록 확인
- 증거:
monitor.sh(경로:/home/agent-admin/agent-app/bin/monitor.sh)
#!/bin/bash
AGENT_HOME="/home/agent-admin/agent-app"
APP_NAME="agent-app-linux-arm64"
PORT="15034"
LOG_DIR="/var/log/agent-app"
LOG_FILE="$LOG_DIR/monitor.log"
MAX_SIZE=$((10 * 1024 * 1024))
MAX_FILES=10
rotate_logs() {
if [ -f "$LOG_FILE" ]; then
size=$(stat -c%s "$LOG_FILE")
if [ "$size" -ge "$MAX_SIZE" ]; then
rm -f "${LOG_FILE}.10"
for i in 9 8 7 6 5 4 3 2 1
do
if [ -f "${LOG_FILE}.${i}" ]; then
mv "${LOG_FILE}.${i}" "${LOG_FILE}.$((i + 1))"
fi
done
mv "$LOG_FILE" "${LOG_FILE}.1"
fi
fi
}
echo "====== SYSTEM MONITOR RESULT ======"
echo "[HEALTH CHECK]"
PID=$(pgrep -f "$APP_NAME" | head -n 1)
if [ -z "$PID" ]; then
echo "Checking process '$APP_NAME'... [FAIL]"
exit 1
fi
echo "Checking process '$APP_NAME'... [OK] (PID: $PID)"
if ss -tuln | grep -q ":$PORT "; then
echo "Checking port $PORT... [OK]"
else
echo "Checking port $PORT... [FAIL]"
exit 1
fi
if command -v ufw >/dev/null 2>&1; then
if ! ufw status | grep -q "Status: active"; then
echo "[WARNING] Firewall is not active"
fi
fi
CPU=$(top -bn1 | awk '/^%Cpu/ {printf "%.1f", 100 - $8}')
MEM=$(free | awk '/Mem:/ {printf "%.1f", ($3 / $2) * 100}')
DISK=$(df / | awk 'NR==2 {gsub("%","",$5); print $5}')
echo "[RESOURCE MONITORING]"
echo "CPU Usage : ${CPU}%"
echo "MEM Usage : ${MEM}%"
echo "DISK Used : ${DISK}%"
if awk "BEGIN {exit !($CPU > 20)}"; then
echo "[WARNING] CPU threshold exceeded (${CPU}% > 20%)"
fi
if awk "BEGIN {exit !($MEM > 10)}"; then
echo "[WARNING] MEM threshold exceeded (${MEM}% > 10%)"
fi
if [ "$DISK" -gt 80 ]; then
echo "[WARNING] DISK threshold exceeded (${DISK}% > 80%)"
fi
mkdir -p "$LOG_DIR"
rotate_logs
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
printf '[%s] PID:%s CPU:%s%% MEM:%s%% DISK_USED:%s%%\n' "$TIMESTAMP" "$PID" "$CPU" "$MEM" "$DISK" >> "$LOG_FILE"
echo "[INFO] Log appended: $LOG_FILE"