새로 산 Linux VPS는 OS 설치 직후 공인 IP가 스캐너 시야에 들어옵니다. 우리가 모니터링한 Ubuntu 22.04 한 대는 가동 후 4시간도 안 되어 /var/log/auth.log에 전 세계 SSH 브루트포스 시도가 천 건 이상 쌓였습니다. 클라우드 보안 그룹이 일부를 막아 주지만, OS 안의 방화벽이야말로 직접 통제할 수 있는 두 번째 방어선입니다.
Ubuntu / Debian 계열 서버라면 UFW(Uncomplicated Firewall)가 사실상 정답에 가깝습니다. 문법이 단순하고 iptables와 자연스럽게 연동되며 문서도 잘 갖춰져 있습니다. 이 글은 iptables 체인 수십 줄을 나열하지 않고, 프로덕션에서 반복 검증한 UFW 설정 흐름을 체크리스트로 정리합니다——설치와 SSH 개방부터 웹 포트, Docker 공존, 클라우드 보안 그룹 협업, 그리고 가장 중요한 「자신을 밖에 가두지 않고 방화벽을 설정하는 방법」까지.
전제: SSH 또는 클라우드 콘솔 VNC로 서버에 로그인했고 sudo 권한이 있습니다. 이미 SSH가 안 된다면 먼저 Linux 서버 SSH 연결 거부 트러블슈팅 가이드로 네트워크 문제인지 방화벽 문제인지 가른 뒤 이 글로 돌아오세요.
클라우드 서버에 방화벽이 왜 필요할까요?
「클라우드 사면 보안 그룹이 있으니 OS는 안 봐도 된다」고 생각하는 분이 많습니다. 실제로 두 층의 역할은 다릅니다. 클라우드 보안 그룹은 가상 NIC 바깥에서 트래픽을 걸러 콘솔로 관리하고, UFW는 OS 커널 netfilter 층에서 걸러 명령줄로 관리합니다. 한 층만 쓰면 현관만 잠그고 침실 문은 연 채——내부망 횡적 이동, 잘못 노출된 서비스, 침입 후 리버스 셸까지 시스템 수준 규칙이 받쳐 줘야 합니다.
UFW 하단은 Ubuntu 공식 UFW 문서가 설명하는 iptables 프론트엔드입니다. ufw allow 22를 쓰면 대응 ACCEPT 규칙으로 바뀝니다. 자연어에 가까운 문법에 ufw status numbered로 정책을 한눈에 보고, 규칙을 바꿔도 헷갈리지 않는 게 장점입니다.
| 계층 | 도구 | 관리 진입점 | 전형적 용도 |
|---|---|---|---|
| 클라우드(바깥) | 보안 그룹 / Network ACL | 웹 콘솔 | 거친 인바운드: 22/80/443만 |
| OS(안쪽) | UFW / firewalld | SSH 명령줄 | 세밀한 제어: IP, 포트, 속도 제한 |
| 애플리케이션 | fail2ban / CrowdSec | 설정 파일 | 브루트포스 출처 IP 동적 차단 |
1단계: UFW 설치 및 확인
Ubuntu 데스크톱과 많은 Server 이미지에는 UFW가 기본 포함되지만, 최소 이미지에는 없을 수 있습니다. 먼저 확인하세요.
sudo apt update
sudo apt install ufw -y
# 현재 상태 확인(inactive는 아직 미활성)
sudo ufw status verbose
# 부팅 시 자동 시작(enable 전에 규칙을 맞추는 것을 권장)
sudo systemctl enable ufw
Status: inactive가 나오면 규칙을 하나씩 넣어도 아직 적용되지 않습니다——가장 안전한 설정 창입니다. SSH를 열기 전에 ufw enable 하면 안 됩니다. 즉시 원격 접속을 잃습니다.
2단계: SSH 개방(가장 중요한 규칙)
SSH는 관리 통로이므로 가장 먼저 열어야 합니다. sshd를 비표준 포트(예: 2222)로 바꿨다면 규칙 포트는 sshd_config와 일치해야 하고, 보안 그룹도 같이 맞추세요.
# 기본 22번 포트 sudo ufw allow 22/tcp comment 'SSH' # 사용자 지정 포트 sudo ufw allow 2222/tcp comment 'SSH custom' # 사무실 출구 IP만 허용(프로덕션 권장) sudo ufw allow from 203.0.113.50 to any port 22 proto tcp # 서비스 이름(/etc/services에 정의된 경우) sudo ufw allow OpenSSH
sshd가 실제로 리슨하는지 확인: sudo ss -tlnp | grep ssh. 0.0.0.0:22 또는 [::]:22가 보이면 정상입니다. ListenAddress가 127.0.0.1이면 UFW로 열어도 소용없습니다——sshd 설정 문제이지 방화벽 문제가 아닙니다.
SSH 포트와 보안 그룹 조합은 Linux 클라우드 호스트 최소 노출면 방화벽 결정 FAQ의 SSH/HTTPS 트레이드오프 매트릭스가 장기 정책 설계에 도움이 됩니다.
3단계: 기본 정책 설정
UFW 권장 기준선은 인바운드 전부 거부, 아웃바운드 전부 허용입니다. 아웃바운드를 열어 두면 apt 패키지, API, DNS 조회가 가능하고, 인바운드는 필요한 서비스 포트만 엽니다.
sudo ufw default deny incoming
sudo ufw default allow outgoing
# 현재 규칙 확인(번호 포함, 삭제에 편함)
sudo ufw status numbered
컴플라이언스로 아웃바운드도 조이려면 ufw default deny outgoing 후 DNS(53), HTTPS(443) 등을 allow out으로 하나씩 추가할 수 있습니다. 다만 대부분 Web / API 서버는 인바운드만 조이고 아웃바운드는 전부 여는 편이 가성비가 가장 좋습니다.
4단계: 업무 포트 개방
실제로 돌리는 서비스에 맞춰 규칙을 추가하세요. 흔한 조합은 다음과 같습니다.
# HTTP / HTTPS(Nginx, Caddy, Apache) sudo ufw allow 80/tcp sudo ufw allow 443/tcp # 서비스 이름 단축 sudo ufw allow 'Nginx Full' # 개발 환경에서 Node 등 임시 개방 sudo ufw allow 3000/tcp comment 'dev API' # 특정 출처 IP에서 관리 패널 접근 sudo ufw allow from 198.51.100.0/24 to any port 8080 proto tcp
프로덕션에서는 443 리버스 프록시로 되면 3000/8080을 직접 노출하지 마세요. UFW에는 22 + 80 + 443 세 포트만 열고 앱은 127.0.0.1에서 리슨하게 한 뒤 Nginx나 Caddy로 TLS 종료——공격면이 한 번에 줄어듭니다.
5단계: 활성화 및 검증
규칙을 다 넣었으면 공식적으로 켭니다.
sudo ufw enable
# 기존 SSH가 끊길 수 있다는 확인에 y 입력
sudo ufw status verbose
sudo ufw status numbered
다른 머신에서 테스트하세요: nc -zv your.server.ip 22는 open이어야 하고, 열지 않은 포트(예: 3306)는 타임아웃 또는 거부됩니다. SSH가 끊기면 즉시 클라우드 콘솔 VNC에서 sudo ufw disable로 롤백하고 빠진 규칙을 찾은 뒤 다시 하세요.
심화: 속도 제한, 삭제, 규칙 순서
UFW는 allow보다 세밀한 동작도 지원합니다. 자주 쓰는 시나리오 몇 가지입니다.
# 속도 제한: SSH 브루트포스 방지(30초당 6회) sudo ufw limit 22/tcp # 번호로 규칙 삭제(먼저 status numbered로 번호 확인) sudo ufw delete 3 # 특정 IP 거부 sudo ufw deny from 192.0.2.100 # 모든 규칙 초기화(신중히 사용) sudo ufw reset
ufw limit는 하단에서 iptables recent 모듈로 연결 빈도를 제한해 SSH에 효과적입니다. 다만 키 로그인과 비밀번호 인증 끄기를 대체하지는 못합니다. 규칙은 추가 순서대로 매칭되므로 더 구체적인 규칙은 앞에 두세요——allow가 안 먹히면 뒤의 deny에 덮였는지 확인하세요.
Docker / Kubernetes와 공존할 때 주의점
UFW가 「설정했는데 안 먹는」 대표 사례입니다. Docker는 기본으로 iptables에 자체 체인을 넣어 UFW 규칙을 우회할 수 있어, 3306을 안 열었다고 생각해도 컨테이너 포트가 공인망에 보일 수 있습니다.
대응(권장 순):
- 컨테이너는 127.0.0.1에 바인드——
-p 127.0.0.1:3000:3000, 호스트 리버스 프록시로 외부 공개 - docker-compose에 ports를 쓰지 않기, 내부 네트워크 + 리버스 프록시
- Docker 설정
"iptables": false(포워딩 규칙은 직접 관리, 고급 사용자) - 클라우드 보안 그룹으로 최종 방어——Docker가 UFW를 우회해도 바깥에서 걸러짐
K8s 노드는 더 복잡해 보통 Calico/Cilium NetworkPolicy를 쓰고 UFW는 노드 수준 보조입니다. 단일 VPS에서 Docker Compose만 돌리면 첫 번째 방법(loopback 바인드)으로 충분한 경우가 많습니다.
클라우드 보안 그룹과 UFW 협업
두 층 모두 설정하고 정책은 일치해야 합니다. 보안 그룹에서 22를 열었으면 UFW도 allow 22. 보안 그룹에 3306이 없으면 UFW에서 allow 해도 외부망에서는 못 들어옵니다——다만 내부망 침해된 머신이 스캔할 수 있으니 UFW에서도 deny 해 두세요.
권장 역할 분담:
- 보안 그룹: 거친 단위, 22/80/443만, 출처 IP는 사무실이나 CDN으로 조임
- UFW: 세밀한 단위, 서비스 주석, SSH limit, 악성 IP 차단
- fail2ban: 동적 층, 로그를 읽어 자동 차단
어느 층을 바꿔도 외부 프로브로 검증하세요: nmap -p 22,80,443,3306 your.server.ip(자기 서버만 스캔하세요). 3306이 open인데 DB를 의도적으로 노출하지 않았다면 Docker 바인드나 앱 리슨 주소를 바로 조사하세요.
트러블슈팅: UFW 켠 뒤 서비스 접속 불가
다음 순서로 보면 10분 안에 대부분 원인을 찾습니다.
sudo ufw status verbose——규칙이 실제로 있는지, 포트·프로토콜(tcp/udp)이 맞는지sudo ss -tlnp——앱이0.0.0.0이 아니라127.0.0.1만 리슨하는지- 클라우드 보안 그룹 인바운드 규칙이 맞는지
- Docker가 UFW를 우회하는지
- 임시
sudo ufw disable로 비교 테스트(끝나면 enable 복구)
특정 출처 IP만 안 되면 deny from이나 fail2ban 차단을 보세요. UFW 로그는 기본으로 상세하지 않습니다. 필요하면 /etc/ufw/ufw.conf에서 LOGLEVEL=medium 설정 후 sudo ufw reload, /var/log/ufw.log에서 거부 패킷을 확인하세요.
배포 체크리스트(그대로 실행 가능)
신규 서버나 OS 재설치 후 순서대로 돌리세요.
sudo apt install ufw -y
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp comment 'SSH' # 또는 사용자 지정 포트
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw limit 22/tcp # 선택: SSH 속도 제한
sudo ufw enable
sudo ufw status verbose
마지막으로 OS 강화도 잊지 마세요: SSH 키 로그인, root 비밀번호 로그인 끄기, unattended-upgrades 정기 업데이트. 방화벽은 경계 방어일 뿐 만병통치약은 아닙니다——그래도 자동 스캔 90%는 문 앞에서 막아 주어 더 깊은 보안 설정에 시간을 벌어 줍니다.
안정 운영 노드: 방화벽 설정 불안을 줄이기
Linux VPS를 여러 대 관리할 때 고정 출구 IP 점프 호스트로 SSH 중계를 두는 경우가 많습니다. 보안 그룹과 UFW는 점프 IP만 허용하고, 로컬에서는 키로 체인 접속합니다. Mac mini는 이런 용도에 잘 맞습니다. macOS는 네이티브 Unix 환경에 Terminal과 OpenSSH가 바로 쓰이고, M4 칩 대기 전력은 약 4W로 7×24 책상 위 중계 노드에 적합해 x86 소형 호스트보다 전력·소음이 적습니다.
같은 가격대 Windows를 상시 점프 호스트로 쓰면 전력과 팬 소음이 큽니다. macOS는 크래시율이 낮고 FileVault·Gatekeeper와 맞추면 개인키 보관도 안심됩니다. Mac에서 Xcode나 Docker로 릴리스 빌드까지 돌린다면 클라우드 Mac mini로 「점프 + 빌드」를 한 노드에 합쳐 전환을 줄일 수 있습니다.
안정적인 원격 운영 환경을 계획 중이라면 VPSSPark 클라우드 Mac mini M4는 저전력 점프 호스트 겸 개발 노드로 현실적인 선택입니다—— 지금 플랜 확인하기 , 서버 보안 강화를 새벽 혼자 하는 일로 만들지 마세요.