ufw 규칙 오류로 VPS 접속이 막혔을 때 복구
ufw로 VPS 접속이 차단됐다면 공급자 콘솔이나 rescue system에서 ufw를 중지하고, 실제 적용된 규칙을 확인해 SSH 재차단을 방지하는 절차를 안내합니다.
처음부터 다시 접속하기
ufw 때문에 VPS에서 접속이 차단되었다면 다시 접속하는 방법은 공급자의 콘솔 또는 복구 모드뿐이다. 차단 규칙이 적용된 뒤에는 SSH를 사용한 해결 방법이 없기 때문이다. 커널은 sshd가 패킷을 받기 전에 해당 패킷을 삭제한다. 따라서 네트워크를 통해 로그인하거나 복구할 수 없다. 공급자의 제어판에서 콘솔을 열고 해당 프롬프트에서 로그인한 다음 명령 하나를 실행한다.
sudo ufw disableFirewall stopped and disabled on system startup이 표시되어야 한다. 1~2초 이내에 새 SSH 연결이 다시 작동한다. 설정한 내용은 손실되지 않는다. disable은 커널에서 규칙을 언로드하고 /etc/ufw/ufw.conf에 ENABLED=no를 기록한다. 규칙은 다음 ufw enable를 기다리며 /etc/ufw/user.rules에 디스크에 그대로 남아 있다.
재부팅한 뒤 해결되기를 기대하지 않는다. ufw는 부팅 시 자동으로 시작하므로 ENABLED=yes이면 네트워크가 올라오기 전에 동일한 규칙 세트가 다시 로드된다. ufw로 인해 접속이 차단된 상태에서는 재부팅해도 아무것도 달라지지 않는다.
콘솔에는 사용자가 설정하지 않았을 수 있는 암호가 필요하다
웹 콘솔(VNC 또는 serial)은 컴퓨터에 연결된 키보드다. 네트워크 경로가 아니므로 방화벽 규칙으로 차단할 수 없다. 하지만 로컬 로그인이 필요하다. 여기서 key only 설정이 실패한다. sudo 사용자에게 암호를 설정하지 않았고 root 로그인이 잠겨 있으면 콘솔에 응답할 수 없는 로그인 프롬프트가 표시된다. 아직 SSH를 사용할 수 있을 때 지금 암호를 설정한다: sudo passwd yourname. 대부분의 패널에서는 root 암호도 재설정할 수 있으며, 이 작업을 수행하면 일반적으로 재부팅이 필요하다.
콘솔을 사용할 수 없으면 provider의 rescue system으로 부팅한다. rescue system은 디스크를 마운트하지 않은 별도의 운영 체제로 실행되므로 외부에서 ufw를 끌 수 있다.
lsblk
sudo mount /dev/vda1 /mnt
sudo sed -i 's/^ENABLED=yes/ENABLED=no/' /mnt/etc/ufw/ufw.conf
sudo umount /mnt먼저 lsblk을 실행한다. root partition이 항상 /dev/vda1인 것은 아니기 때문이다. 일반 system으로 재부팅하면 직접 활성화할 때까지 ufw가 꺼진 상태로 유지된다.
최소 복구 절차
다음 순서로 진행합니다. 처음 4단계는 안전합니다. 그 이후 단계는 안전하지 않습니다.
- 규칙을 해제하고 다시 접속할 수 있도록
sudo ufw disable을 실행합니다. - 추가한 규칙을 해당 규칙을 추가한 명령 형식으로 출력하려면
sudo ufw show added을 실행합니다. 이 명령은 ufw가 비활성 상태일 때도 작동하지만ufw status은 작동하지 않습니다. - sshd가 실제로 수신 대기하는 포트를 확인하려면
sudo sshd -T | grep -i '^port'을 실행합니다. 포트를 변경하지 않았다면port 22을 출력합니다. - 실제 포트를 사용하여
sudo ufw allow 22/tcp을 실행합니다. 그러면 다음에 enable할 때 같은 접속 차단이 반복되지 않습니다. - 먼저 롤백을 예약한 후
sudo ufw enable을 실행합니다. 롤백 예약 방법은 이 페이지 아래에 설명되어 있습니다.
ufw reset이 실제로 수행하는 작업
ufw reset은 첫 단계가 아니라 최후의 수단이다. 방화벽을 비활성화하고 모든 규칙 파일을 백업한 다음, 기본 정책을 들어오는 트래픽은 거부하고 나가는 트래픽은 허용하도록 되돌린다. 파일마다 백업 항목을 한 줄씩 출력한다.
Backing up 'user.rules' to '/etc/ufw/user.rules.20260813_101500'reset 후에는 허용 규칙이 하나도 남지 않는다. 따라서 SSH를 통해 실행하지 말고 콘솔에서 실행해야 한다. 다시 활성화하기 전에 SSH 규칙을 추가해야 한다. 백업 파일은 일반 텍스트 형식이다. sudo grep -n dport /etc/ufw/user.rules.20260813_101500을 사용하면 기존 규칙을 확인할 수 있다. 이를 통해 삭제할 의도가 없었던 규칙 세트를 다시 구성할 수 있다.
ufw가 규칙을 저장하는 위치
기억에 의존해 추측하기보다 파일을 직접 확인하는 편이 정확하다. 전체 상태는 다음 5개 경로에 저장된다.
/etc/ufw/user.rules및/etc/ufw/user6.rules: 추가한 규칙이다. 규칙이 평가되는 순서대로 저장된다./etc/ufw/before.rules및/etc/ufw/after.rules, 그리고6변형 파일: 규칙을 감싸는 ufw 프레임워크다. 여기에는 이미 설정된 연결을 허용하는 규칙과 loopback 규칙이 포함된다./etc/default/ufw: 기본 정책과IPV6스위치다./etc/ufw/ufw.conf:ENABLED및 로그 수준이다./var/log/ufw.log: 로깅을 활성화한 뒤 차단된 항목이다.
ufw는 파일을 다시 작성하기 전에 타임스탬프가 포함된 사본을 저장한다. 따라서 ls /etc/ufw/에는 user.rules.20260813_101500과 같은 이름의 파일이 쌓인다. 이것이 변경 사항을 되돌릴 수 있는 기록이다. 설정을 되돌리기 전에 확인하는 것이 좋다.
디스크의 파일이 아니라 커널에 로드된 규칙을 확인하려면 sudo ufw show raw 또는 sudo iptables -S와 sudo ip6tables -S을 사용한다. Ubuntu 22.04 및 24.04에서는 이 명령이 nft 기반 버전으로 동작한다. 따라서 sudo nft list ruleset는 같은 규칙을 새로운 구문으로 출력한다.
ufw를 활성화하면 SSH 세션이 끊기는 이유는 무엇입니까?
기본 수신 정책은 deny입니다. SSH 포트에 대한 규칙 없이 ufw를 활성화하면 새 연결이 모두 차단됩니다. ufw는 이 점을 경고합니다. Command may disrupt existing ssh connections. Proceed with operation (y|n)? SSH 허용 규칙이 없는 상태에서 y에 응답하는 것이 이 페이지의 모든 문제를 일으키는 가장 일반적인 원인입니다.
혼란스러운 부분은 지연입니다. /etc/ufw/before.rules은 사용자가 직접 만든 규칙보다 먼저 ESTABLISHED,RELATED 상태의 패킷을 허용합니다. 따라서 명령을 입력한 SSH 세션은 정상적으로 계속 동작합니다. 연결 차단은 다음 연결에서만 나타나며, 이 연결은 몇 시간 뒤에 시도될 수도 있습니다. 그러면 방화벽 변경이 원인이라는 사실을 알아차리기 어렵습니다. 첫 번째 SSH 세션을 종료하기 전에 항상 두 번째 SSH 세션을 열어 정상적으로 연결되는지 확인해야 합니다.
apt와 DNS가 정책 변경 후 작동하지 않는 이유
sudo ufw default deny outgoing은 아웃바운드 DNS(domain name system) 쿼리와 아웃바운드 HTTP를 차단하므로 이름 확인이 중단되고 패키지 업데이트가 작동하지 않는다. apt update은 Temporary failure resolving 'archive.ubuntu.com'을 보고한다. 인바운드 SSH는 계속 작동한다. SSH에 대한 응답은 ESTABLISHED 상태이므로 프레임워크 규칙을 통과하기 때문이다. 따라서 방화벽이 원인이 아닌 것처럼 보이지만 실제 원인은 방화벽이다.
아웃바운드 거부 정책을 사용하려면 시스템에 실제로 필요한 트래픽을 허용한다.
sudo ufw allow out 53
sudo ufw allow out 80/tcp
sudo ufw allow out 443/tcp
sudo ufw allow out 123/udp마지막 규칙이 없으면 시간이 틀어진다. 시간이 틀리면 TLS(transport layer security) 인증서 검증이 실패하므로 curl은 포트가 아니라 날짜를 기준으로 실패하기 시작한다. 이 증상은 정책을 변경한 뒤 며칠 후에 나타난다. 따라서 아웃바운드 거부 정책은 한 번 설정하고 방치하는 시스템이 아니라 모니터링하는 시스템에 적용해야 한다.
ufw 규칙이 일치하지 않는 이유는 무엇입니까?
ufw는 사용자 규칙을 순서대로 평가하고 처음 일치하는 규칙에서 처리를 중지합니다. 포괄적인 allow 뒤에 추가한 deny는 허용 규칙이 이미 패킷에 대한 결정을 내렸으므로 적용되지 않습니다. 번호를 포함해 순서를 출력한 다음, 필요한 위치에 규칙을 삽입합니다.
sudo ufw status numbered
sudo ufw insert 1 deny from 203.0.113.10 to any port 22
sudo ufw delete 4sudo ufw --dry-run allow 8080/tcp는 적용될 규칙을 출력하지만 아무것도 변경하지 않습니다. 규칙을 실제로 활성화하기 전에 안전하게 확인하는 방법입니다.
애플리케이션 프로필에도 주의할 점이 있습니다. sudo ufw allow OpenSSH는 /etc/ufw/applications.d/openssh-server의 프로필을 사용하며, 이 프로필은 port 22를 의미합니다. sshd가 2222에서 수신 대기하도록 변경했다면 규칙은 사용 중인 서비스가 없는 port를 열고, 규칙 세트는 올바르게 보이지만 접속할 수 없게 됩니다. port를 변경한 뒤에는 port 번호를 직접 사용합니다. 나머지 구문은 VPS용 ufw 방화벽 기본 사항에서 설명합니다.
IPv4 규칙으로는 왜 실제 상태가 설명되지 않습니까?
트래픽의 절반은 IPv4가 아니기 때문입니다. Ubuntu는 IPV6=yes를 /etc/default/ufw에 제공하며, ufw는 /etc/ufw/user6.rules에 별도의 v6 규칙 세트를 유지합니다. ufw allow from 203.0.113.10 to any port 22과 같이 IPv4 주소를 사용해 작성한 규칙은 v6 규칙을 전혀 생성하지 않습니다. VPS에 AAAA 레코드가 있고 클라이언트가 IPv6를 우선 사용하면, ufw status에 올바르게 보이는 규칙이 있어도 연결이 시간 초과될 수 있습니다. ssh -6 user@host에 ssh -4 user@host를 사용해 차이를 테스트합니다. 첫 번째 명령은 작동하고 두 번째 명령은 작동하지 않는다면, 문제는 v6 규칙 세트에 있습니다.
반대 상황은 보안 측면에서 더 위험합니다. IPV6=no인 경우 ufw는 ip6tables를 전혀 관리하지 않으므로 v6 정책은 커널 기본값인 ACCEPT로 유지됩니다. 닫혀 있다고 생각한 포트가 IPv6 주소에서는 응답하며, 어떤 ufw 명령에도 해당 포트가 표시되지 않습니다. sudo ip6tables -S 및 ss -tlnp로 확인하고, 전체 내용은 ufw가 IPv6 포트를 처리하는 방식을 참조합니다.
ufw가 포트를 거부하는데 Docker 포트가 열려 있는 이유는 무엇입니까?
Docker는 nat 테이블에 DNAT(destination network address translation) 규칙을 작성하고, 자체 체인을 FORWARD에 삽입하여 포트를 게시합니다. ufw 규칙은 INPUT 경로에 배치됩니다. 컨테이너로 향하는 트래픽은 호스트로 전달되는 대신 포워딩되므로, 거부 규칙이 있는 체인에 도달하지 않습니다. 따라서 ufw가 활성화되어 모든 트래픽을 거부하더라도 docker run -p 5432:5432은 인터넷에서 접근할 수 있습니다.
sudo iptables -t nat -S DOCKER가장 간단한 해결 방법은 루프백에 게시하는 것입니다. -p 127.0.0.1:5432:5432는 호스트 측을 127.0.0.1에 바인딩하므로 ufw 설정과 관계없이 외부에서는 접근할 수 없습니다. 서비스를 외부에 공개해야 하는 경우는 ufw에서 Docker 포트 게시에서 설명합니다.
규칙을 적용하기 전에 롤백 예약
이 습관이 방화벽 작업을 안전하게 유지한다. 위험한 변경을 하기 전에 실행 취소를 예약한다. 변경으로 접속이 차단되면 5분 후 시스템이 자동으로 복구되므로 콘솔을 열 필요가 없다.
sudo systemd-run --on-active=5m --unit=ufw-rollback /usr/sbin/ufw disablesystemd가 Running timer as unit: ufw-rollback.timer를 출력한다. 이제 변경을 적용한다. 그 후에도 새 SSH 세션을 열 수 있으면 롤백을 취소한다.
sudo systemctl stop ufw-rollback.timer새 세션을 열 수 없으면 기다린다. ufw가 자동으로 중지되고 다음 접속 시도가 성공한다. 기존의 shutdown -r +5 트릭은 ufw에서 도움이 되지 않는다. ufw가 부팅할 때 동일한 규칙 집합을 다시 로드하기 때문이다.
두 번째 접속 방법을 마련합니다
- 필요해지기 전에 provider 콘솔에 한 번 로그인하여 password가 작동하는지 확인합니다. 한 번도 테스트하지 않은 콘솔은 backup이 아닙니다.
- 자체 key를 사용하는 두 번째 sudo user를 유지합니다.
authorized_keys파일 하나가 손상되어도 접속이 완전히 차단되지 않습니다. - provider가 패널에서 ufw와 별도로 network firewall을 실행하는지 확인합니다. 이 firewall도 같은 port를 차단하며,
ufw status에는 절대 표시되지 않습니다. - 해당 address가 동적이라면
ufw allow from <your home address>을 유일한 SSH rule로 설정하지 않습니다. provider가 밤사이에 address를 변경하면 접속할 수 없게 됩니다.
이 모든 작업을 수행하기에 가장 좋은 시점은 새 server에서 다른 초기 설정 작업과 함께 진행할 때입니다. 새 VPS에서 처음 10분에 처리하면 됩니다.
거부되거나 시간 초과가 발생했다는 것은 어느 계층에서 실패했는지를 보여 준다
Connection refused은 패킷이 서버에 도달했고 무언가가 TCP reset을 다시 보냈다는 뜻이다. 네트워크 경로는 정상이다. 따라서 sshd가 중지되었거나 다른 포트에서 listening 중이다. ufw는 기본적으로 거부하지 않고 패킷을 drop하므로 방화벽이 원인인 경우는 드물다.
Connection timed out은 아무 응답도 돌아오지 않았다는 뜻이다. 이는 ufw, provider network firewall 또는 잘못된 주소가 패킷을 drop할 때 나타나는 전형적인 신호다. 이 두 오류를 올바르게 해석하면 한 시간 동안 원인을 추측하는 일을 줄일 수 있으며, connection refused와 timed out의 차이에서 나머지 경우도 설명한다.
다음 변경 전에 로깅을 활성화합니다
sudo ufw logging on
sudo tail -f /var/log/ufw.log차단된 패킷은 다음과 같이 표시됩니다.
[UFW BLOCK] IN=eth0 OUT= SRC=203.0.113.10 DST=192.0.2.5 LEN=60 PROTO=TCP SPT=51234 DPT=22 WINDOW=64240 SYNSRC=에 자체 주소가 포함된 DPT=22은 사용자를 차단한 것이 네트워크나 sshd가 아니라 ufw라는 증거입니다. rsyslog가 없는 최소 이미지에는 /var/log/ufw.log이 없으며, 동일한 줄은 sudo journalctl -k | grep UFW에서 확인할 수 있습니다. ufw는 자체 로깅 규칙에 rate limit을 적용하므로, 로그 줄이 없다고 해서 패킷이 허용되었다는 의미는 아닙니다.
직접 추가하지 않은 규칙을 발견한 경우
규칙 세트가 저절로 변경되었다면 방화벽 문제가 아닙니다. 누군가 root 권한으로 변경한 것입니다. sudo grep ufw /var/log/auth.log를 실행해 어떤 sudo 명령이 실행되었고 어떤 계정이 사용되었는지 확인한 다음, last을 실행해 해당 시각 전후의 로그인 기록을 확인합니다. 계정이 아는 사용자와 일치하지 않으면 방화벽 디버깅을 중단하고 침해된 VPS 점검 목록에 따라 조사해야 합니다. 다른 사람이 제어하는 서버에서 방화벽을 다시 활성화해도 문제를 숨길 뿐입니다.
원인 파악이 끝났다면 같은 접속 차단이 반복되지 않도록 ufw를 다시 활성화한다.
실제로 사용하는 SSH 포트를 허용한다. 롤백을 예약한다. ufw를 활성화한다. 그런 다음 다른 터미널에서 완전히 새로운 SSH 세션을 열어 연결되는지 확인한다. 새 세션이 연결된 후에만 현재 작업 중인 세션을 종료한다.
하루 동안 로깅을 활성화해 둔다. 로그를 확인하면 user.rules를 읽는 것보다 허용하지 않은 항목을 훨씬 빠르게 파악할 수 있다.
FAQ
ufw disable이 규칙을 삭제합니까?
아닙니다. disable는 커널에서 ruleset을 언로드하고 ENABLED=no을(를) /etc/ufw/ufw.conf에 기록합니다. 규칙은 /etc/ufw/user.rules 및 /etc/ufw/user6.rules에 그대로 남아 있으며, 방화벽이 비활성 상태일 때 sudo ufw show added로 규칙을 확인할 수 있습니다. 규칙을 삭제하는 명령은 ufw reset이며, 먼저 각 파일을 백업한 뒤 Backing up 'user.rules' to '/etc/ufw/user.rules.20260813_101500'과 같은 줄을 출력합니다.
VPS를 재부팅하면 ufw 차단이 해제됩니까?
아닙니다. ufw는 /etc/ufw/ufw.conf의 ENABLED=yes에서 부팅 시 시작되므로 동일한 규칙이 네트워크가 시작되기 전에 다시 로드되고, 다시 접속할 수 없게 됩니다. ufw를 중지한 뒤 재부팅하거나, rescue mode에서 디스크를 마운트하고 해당 파일을 수정한 뒤 재부팅해야 해결됩니다. provider console을 사용해 그곳에서 sudo ufw disable를 실행합니다.
ufw가 포트를 거부하는데 Docker 컨테이너에 접근할 수 있는 이유는 무엇입니까?
Docker는 게시된 각 포트에 대해 자체 DNAT 및 FORWARD 규칙을 작성합니다. 해당 트래픽은 host에 전달되지 않고 컨테이너로 전달되므로, ufw deny 규칙이 있는 INPUT chain을 거치지 않습니다. 포트를 host에서만 사용한다면 -p 127.0.0.1:5432:5432으로 loopback에 게시합니다. Docker가 설치한 규칙은 sudo iptables -t nat -S DOCKER로 확인합니다.
console password가 없고 rescue mode도 없습니다. 어떤 방법이 있습니까?
남은 방법은 provider가 제공하는 기능을 사용하는 것입니다. 일반적으로 서버를 재부팅하는 control panel의 password reset을 사용하거나, 디스크를 다른 instance에 연결해 그곳에서 /etc/ufw/ufw.conf를 수정할 수 있습니다. 서버를 rebuild하기 전에 support에 문의합니다. rebuild하면 서버의 데이터가 삭제되기 때문입니다. 다시 접속한 뒤 sudo passwd yourname를 실행하고 console login을 한 번 테스트합니다. 그러면 다음에 접속이 차단되어도 복구에 2분만 걸립니다.