본문에서 다룬 핵심 명령어와 설정을 한곳에 모았습니다. 복사하여 쓰되, 자신의 환경에 맞게 값을 조정하고, 적용 전 반드시 본문의 맥락과 안전 원칙을 확인하십시오.
B.0 사용 전 경고
이 부록의 명령어와 설정은 출발점이며, 모든 환경에 그대로 맞지는 않습니다. 다음을 반드시 지키십시오.
- 자기 자산에만 사용하십시오. 스캔과 점검은 소유하거나 서면 허가를 받은 대상에만. (1장, 10장)
- 접속 설정 변경 시 안전 절차를 지키십시오. 새 경로 우선 검증, 두 번째 세션 유지, 자동 롤백, 비상 콘솔. (6장 6.5)
- 운영 적용 전 테스트하십시오. 가능하면 테스트 환경에서 먼저 검증하십시오.
- 버전과 시점에 주의하십시오. 권장 설정(특히 암호 스위트)은 시간에 따라 변합니다. 신뢰할 수 있는 최신 가이드와 함께 사용하십시오. (8장)
2026년 현재에도 침해의 출발점은 대부분 화려한 제로데이가 아니라, 패치가 나왔는데도 미적용으로 남아 있던 알려진 취약점(n-day)과 잘못된 노출입니다. 패치 지연이 곧 침해로 이어진 Citrix Bleed(CVE-2023-4966)나 MOVEit Transfer(CVE-2023-34362)가 그 예입니다. 아래 명령들은 그 "기본"을 빠르게 점검하기 위한 것입니다.
B.1 자가 점검 — 내 서버는 지금 무엇을 겪는가 (1장, 5장)
# --- SSH 공격 관찰 (인증 로그) ---
# 실패한 로그인 시도 총 개수
sudo grep "Failed password" /var/log/auth.log | wc -l
# 시도된 사용자명 상위 목록
sudo grep "Failed password" /var/log/auth.log \
| grep -oE "for (invalid user )?[a-zA-Z0-9_-]+" \
| sort | uniq -c | sort -rn | head -20
# 공격 출발 IP 상위 목록
sudo grep "Failed password" /var/log/auth.log \
| grep -oE "from [0-9]+\.[0-9]+\.[0-9]+\.[0-9]+" \
| sort | uniq -c | sort -rn | head -20
# --- 웹 자동 공격 관찰 (Nginx 접근 로그) ---
# 흔한 공격 표적 경로에 대한 요청 집계
sudo grep -hE "\.env|\.git|wp-login|wp-admin|phpmyadmin|xmlrpc" \
/var/log/nginx/access.log \
| awk '{print $7}' | sort | uniq -c | sort -rn | head -30
# 404를 많이 유발한 경로 (탐색 시도의 흔적)
sudo awk '$9 == 404 {print $7}' /var/log/nginx/access.log \
| sort | uniq -c | sort -rn | head -30
B.2 공격면 점검 — 무엇이 노출되어 있는가 (5장)
포트 스캐너는 Nmap을 씁니다. 서브도메인 열거에 쓰는 CT 로그(Certificate Transparency)는 발급된 모든 공개 인증서가 기록되는 공개 장부로, 여기서 잊고 있던 하위 도메인이 드러나는 일이 흔합니다. 조회는 crt.sh로 합니다. 더 넓은 외부 노출 점검은 Shodan·Censys도 함께 보면 좋습니다. 스캔은 반드시 자기 자산에만 하십시오(1장, 10장).
# --- 외부 시선: 자신의 서버 포트 스캔 (자기 자산에만!) ---
nmap -sV -p- your-server-ip # 전체 포트 + 서비스 버전
nmap -sV --top-ports 1000 your-server-ip # 자주 쓰이는 상위 포트
sudo nmap -sU --top-ports 100 your-server-ip # UDP 상위 포트
# --- 내부 확인: 리스닝 포트와 프로세스 ---
sudo ss -tulpn # 권장
sudo ss -tulpn | grep ':3306' # 특정 포트 점검 (예: MySQL)
# --- 백엔드 서비스 바인딩 점검 ---
# 데이터베이스/캐시가 0.0.0.0(외부)에 바인딩되어 있으면 위험.
# 거의 항상 127.0.0.1(로컬)에만 바인딩되어야 함.
# --- 서브도메인 열거 (CT 로그 조회, 자기 도메인) ---
curl -s "https://crt.sh/?q=%25.example.com&output=json" \
| python3 -c "import sys,json; [print(c['name_value']) for c in json.load(sys.stdin)]" \
| sort -u
# --- DNS 레코드 점검 ---
dig example.com ANY +noall +answer
dig example.com MX +short
dig example.com TXT +short # SPF 등
dig _dmarc.example.com TXT +short # DMARC
# --- 민감 경로 노출 자가 점검 (자기 사이트, 200이면 즉시 차단) ---
for path in .env .git/config .git/HEAD config.php.bak \
backup.sql .DS_Store phpinfo.php server-status; do
code=$(curl -s -o /dev/null -w "%{http_code}" "https://example.com/$path")
echo "$code /$path"
done
# --- 소프트웨어 인벤토리 (데비안/우분투) ---
dpkg -l | awk '{print $2, $3}'
apt-get update && apt-get -s upgrade | grep -i security # 보안 업데이트 확인
B.3 SSH — 공개키 전용과 키 관리 (7장)
SSH 서버는 OpenSSH를 기준으로 합니다. Ed25519는 짧고 빠르면서 안전한 최신 키 방식으로, 특별한 이유가 없으면 기본으로 권장됩니다. 아래
sshd_config설정값의 근거가 궁금하면 Mozilla OpenSSH 가이드를 참고하십시오.
# --- 키 페어 생성 (로컬 기기, Ed25519) ---
ssh-keygen -t ed25519 -C "your-comment"
# 패스프레이즈는 반드시 설정할 것!
# --- 기존 키에 패스프레이즈 추가/변경 ---
ssh-keygen -p -f ~/.ssh/id_ed25519
# --- 공개키를 서버에 등록 ---
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server
# --- 공개키 접속 확인 (비밀번호 끄기 전 필수) ---
ssh -i ~/.ssh/id_ed25519 user@server
# --- SSH 에이전트 (패스프레이즈 1회 입력, 시간 제한) ---
eval "$(ssh-agent -s)"
ssh-add -t 3600 ~/.ssh/id_ed25519 # 1시간 후 자동 제거
# --- 키 파일 권한 ---
chmod 600 ~/.ssh/id_ed25519 # 개인키: 소유자만
chmod 700 ~/.ssh # 디렉터리: 소유자만
chmod 644 ~/.ssh/id_ed25519.pub # 공개키: 읽기 허용 가능
/etc/ssh/sshd_config 권장 설정:
# 인증
PasswordAuthentication no
PubkeyAuthentication yes
ChallengeResponseAuthentication no
PermitEmptyPasswords no
PermitRootLogin no
# 시도 제한과 타임아웃
MaxAuthTries 3
LoginGraceTime 30
# 유휴 세션 종료
ClientAliveInterval 300
ClientAliveCountMax 2
# 접근 사용자 제한
AllowUsers your-user
# 불필요한 전달 기능 (필요에 따라 검토)
AllowAgentForwarding no
AllowTcpForwarding no
X11Forwarding no
# --- 설정 검증 후 재시작 (6.5 절차 준수) ---
sudo sshd -t # 문법 검증 (필수)
sudo systemctl restart ssh
# → 반드시 새 세션으로 접속 확인. 기존 세션은 닫지 말 것.
현장에서 가장 흔하게 사람을 잠가버리는 한 줄이 바로 위 재시작입니다. 저는 운영 서버에서 SSH 설정을 바꿀 때, 기존 세션은 그대로 둔 채 두 번째 터미널로 새로 접속이 되는지 확인하기 전에는 절대 원래 창을 닫지 않습니다. 키 로그인이 되는 걸 확인한 뒤에야
PasswordAuthentication no로 넘어가십시오.
B.4 안전한 변경 — 자기 자신을 잠그지 않기 (6장 6.5)
# --- 방화벽 변경 전 자동 롤백 안전장치 ---
# 1) 현재 방화벽 규칙 백업
sudo iptables-save > /root/iptables.backup
# 2) 10분 뒤 자동 복원 예약
echo "iptables-restore < /root/iptables.backup" | sudo at now + 10 minutes
# 3) 방화벽 변경 수행 후 새 세션으로 접속 테스트
# - 정상이면: 예약 작업 취소 (atq로 번호 확인 후 atrm <번호>)
# - 실패하면: 그대로 두면 10분 뒤 자동 복구됨
# 예약된 작업 확인 / 취소
atq # 작업 목록
atrm <작업번호> # 작업 취소
SSH-over-Tunnel 안전 전환 순서 (6.5): ① 직접 SSH 유지한 채 터널 SSH 구성 → ② 새 세션으로 터널 SSH 작동 확인 → ③ 자동 롤백 안전장치 설정 → ④ 직접 SSH 포트 차단 → ⑤ 새 세션으로 터널 SSH 재확인(직접 SSH는 막혔는지 외부에서 확인) → ⑥ 정상이면 안전장치 취소 → ⑦ 외부 포트 스캔으로 22번이 안 보임을 검증.
B.5 Cloudflare Tunnel (6장)
Cloudflare Tunnel은 서버의 인바운드 포트를 인터넷에 열지 않고도 외부에서 접속하게 해 주는 방식입니다(공격 표면을 크게 줄여 줍니다). 설치·구성 공식 문서는 Cloudflare Zero Trust 문서를 참고하십시오.
# --- 설치 후 인증 ---
cloudflared tunnel login
# --- 터널 생성 / 목록 ---
cloudflared tunnel create my-tunnel
cloudflared tunnel list
~/.cloudflared/config.yml 예시:
tunnel: <터널 ID>
credentials-file: /home/user/.cloudflared/<터널 ID>.json
ingress:
- hostname: example.com
service: http://127.0.0.1:8080
- service: http_status:404 # 필수: 마지막 catch-all
# --- DNS 라우팅 / 실행 / 서비스 등록 ---
cloudflared tunnel route dns my-tunnel example.com
cloudflared tunnel run my-tunnel # 테스트 실행
sudo cloudflared service install # 상시 실행 등록
# → 터널 작동 확인 후, 안전 절차에 따라 인바운드 웹 포트 차단
B.6 TLS와 인증서 (8장)
무료 인증서는 Let's Encrypt로 발급합니다(certbot이 그 자동화 도구). 순방향 비밀성(Forward Secrecy)이란 서버의 개인키가 나중에 유출돼도 과거 통신 기록은 풀 수 없게 하는 성질입니다 — 강한 설정의 핵심 요소입니다.
# --- 인증서 발급과 자동 갱신 (certbot, Nginx) ---
sudo certbot --nginx -d example.com -d www.example.com
sudo certbot renew --dry-run # 자동 갱신 작동 검증
# --- TLS 설정 검증은 SSL Labs로 (본문 8.4) ---
# 자기 도메인을 SSL Labs SSL 서버 테스트에 입력하여 등급 확인
설정값을 직접 고르기 어렵다면 Mozilla SSL Configuration Generator에서 서버·버전에 맞는 블록을 받아 쓰고, 적용 결과는 SSL Labs SSL 서버 테스트로 등급을 확인하십시오. 명령줄에서 점검하려면 testssl.sh도 유용합니다.
TLS 설정 원칙(구체적 암호 스위트 목록은 최신 가이드 참조):
- TLS 1.2 이상만 허용, 이전 버전 명시적 비활성화
- 강한 암호 스위트만, 순방향 비밀성 우선
- OCSP 스테이플링 활성화
- 오리진 통신도 암호화(프록시 사용 시)
B.7 보안 헤더 (9장)
Nginx server 블록 예시:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "DENY" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;
# CSP는 9.2 절차에 따라 관찰 모드로 먼저 도입 후 강제
HSTS(HTTP Strict Transport Security)는 "이 사이트는 앞으로 무조건 HTTPS로만 접속하라"고 브라우저에 지시하는 헤더이고, CSP(Content Security Policy)는 페이지가 불러올 수 있는 스크립트·자원의 출처를 제한해 XSS 등을 막는 헤더입니다. 각 헤더의 의미와 값은 MDN Web Docs에서 확인하고, CSP는 작성 후 CSP Evaluator로 약점을 점검하십시오.
HSTS 단계적 적용: 짧은 max-age → 모든 하위 도메인 HTTPS 확인 후 includeSubDomains → 모든 준비 후 preload(되돌리기 어려우므로 신중히).
적용 결과는 securityheaders.com이나 Mozilla Observatory에 도메인을 넣어 한눈에 등급으로 확인할 수 있습니다.
# --- 헤더 적용 검증 ---
curl -sI https://example.com
# 보안 헤더만 추출
curl -sI https://example.com | grep -iE \
"strict-transport|content-security|x-frame|x-content-type|referrer-policy|permissions-policy"
B.8 추가 방어 — fail2ban (7장)
fail2ban은 로그에서 반복 실패(무차별 대입)를 감지해 해당 IP를 일정 시간 차단해 주는 도구입니다.
# 설치 (데비안/우분투)
sudo apt-get install fail2ban
/etc/fail2ban/jail.local 예시:
[sshd]
enabled = true
maxretry = 3
bantime = 3600
findtime = 600
(6장 방식으로 SSH를 인터넷에서 숨겼다면 무차별 대입 자체가 거의 도달하지 않으므로, fail2ban은 인터넷에 노출된 SSH를 운영할 때 특히 유용합니다.)
B.9 자가 진단 도구 (10장)
다섯 영역을 한 번에 점검(모두 자기 자산에만):
| 도구 | 점검 대상 | 본문 |
|---|---|---|
testssl.sh | TLS 설정과 등급 | 8장 |
sslyze | 심층 TLS 분석 | 8장 |
curl -sI (CSP·HSTS 등) | 보안 헤더 | 9장 |
OWASP ZAP · nmap | 포트·노출 | 5·6장 |
nuclei | 알려진 취약점(n-day) | 4장 |
여기서 n-day란 이미 공개·패치된 취약점을 말합니다. 패치가 있었는데도 미적용으로 대규모 침해가 난 Log4Shell(CVE-2021-44228)이 대표적이며, nuclei는 이런 알려진 취약점이 내 서버에 남아 있는지 빠르게 확인해 줍니다. 자세한 사용법은 10장을 참조하십시오.
B.10 빠른 우선순위 — 시간이 없다면 (15장, 부록 A.3)
- SSH 공개키 전용 + 비밀번호 인증 끄기 (B.3)
- 소프트웨어 최신 패치 유지 (B.2)
- 노출된 파일·디버그 모드 차단 (B.2, 11장) — 운영에서 디버그 모드를 켜둔 위험은 Laravel Ignition RCE(CVE-2021-3129)에서 실제로 드러났습니다.
- TLS 1.2 이상 + 강한 암호 스위트 (B.6)
- 검증된 백업 3-2-1 + 복구 테스트 (13장)
사용한 계정 비밀번호가 이미 유출돼 있는지는 Have I Been Pwned에서 확인하고, 위 우선순위에서 더 무엇을 점검하면 좋을지 막막하다면 CISA의 실제 악용 취약점 목록(KEV)에 오른 항목부터 내 환경에 해당하는지 보십시오.