← 글 목록

라즈베리파이 NAS 외부 접속 장애, 원인은 UFW 방화벽 규칙 누락

/ 6분 분량

집에서 라즈베리파이로 돌리고 있는 NAS(samba)와 WireGuard VPN이 갑자기 외부에서 안 열려서 급하게 원인을 추적했습니다. 결론부터 말하면 하루 전에 방화벽 규칙을 정리하다가 실수로 VPN 포트 하나를 빠뜨린 게 원인이었습니다.

학습 주제

  • 주제: 라즈베리파이 NAS(Samba + WireGuard) 외부 접속 불가 트러블슈팅
  • 학습 날짜: 2026-08-05

탐구 과정

외부에서 ~/shared 디렉토리로 접속하려는데 연결이 안 됐습니다. 평소 잘 쓰던 환경이라 뭐가 바뀐 건지 감이 안 잡혀서 하나씩 체크리스트를 세워서 점검했습니다.

먼저 의심한 건 서비스 자체의 문제였습니다.

  • ~/shared 로컬 접근은 정상이었고, smbd/nmbd도 445/139 포트에서 정상적으로 리스닝 중이었습니다. Samba 자체는 문제가 없다는 뜻이었습니다.
  • WireGuard 인터페이스(wg0)도 51820 UDP 포트에서 정상 리스닝 중이었고, IP 포워딩도 켜져 있었습니다.

그런데 wg show로 피어 상태를 보니 뭔가 이상했습니다. "laptop" 피어는 마지막 handshake가 23시간 34분 전으로 너무 오래됐고, "pad" 피어는 아예 handshake 기록 자체가 없었습니다. 즉, 터널이 열린 적이 없거나 끊긴 지 오래됐다는 신호였습니다.

혹시 라즈베리파이의 로컬 IP가 바뀌어서 그런가 싶었지만, wlan0의 IP(172.30.1.94)는 최근 계속 안정적이었습니다. eth0가 NO-CARRIER 상태인 것도 눈에 띄었지만, 이 기기는 부팅 이후 계속 WiFi로만 동작해왔던 거라 이번 문제와는 무관하다고 판단했습니다.

서비스도 정상, IP도 정상인데 왜 안 될까 고민하다가, 최근에 UFW 방화벽을 켰던 기억이 났습니다. 방화벽 로그를 직접 들여다보기로 했습니다.

핵심 학습 내용

sudo ufw status와 /var/log/ufw.log를 확인하니 답이 바로 나왔습니다. 실시간으로 UFW가 WireGuard 포트를 막고 있었습니다.

[UFW BLOCK] IN=wlan0 SRC=222.112.226.63 DST=172.30.1.94 PROTO=UDP SPT=60405 DPT=51820

기존 UFW 규칙을 보니 22/80/443 포트, 그리고 172.30.1.0/24(LAN 대역), 10.0.0.0/24(WireGuard 터널 내부 대역)만 허용되어 있었습니다. 정작 WireGuard가 리스닝하는 51820/udp 포트 자체를 외부(Anywhere)에서 허용하는 규칙은 빠져 있었습니다.

여기서 헷갈렸던 부분이 하나 있었는데, "10.0.0.0/24를 허용했으니 VPN도 되는 거 아닌가?" 하는 생각이었습니다. 하지만 이 규칙은 이미 터널이 수립된 이후, 즉 VPN 터널 내부를 오가는 트래픽에만 적용되는 규칙입니다. 터널을 처음 여는 handshake 패킷은 외부 공인 IP(예: 222.112.226.63)에서 51820/udp로 직접 들어오는 패킷이라서, 이 규칙과는 전혀 별개로 막혀버린 거였습니다. 즉 "터널 안쪽 트래픽 허용"과 "터널을 여는 관문 자체 허용"은 완전히 다른 문제였습니다.

/etc/ufw/user.rules 파일의 수정 시각을 확인하니 하루 전(8/4 16:59)이었고, 그날 방화벽 규칙을 정리하면서 이 규칙 하나가 누락된 것으로 결론지었습니다.

해결은 간단했습니다.

sudo ufw allow 51820/udp comment 'WireGuard VPN - public'

적용 후 규칙을 확인하니:

[ 7] 51820/udp    ALLOW IN    Anywhere    # WireGuard VPN - public
[12] 51820/udp (v6) ALLOW IN  Anywhere (v6)

그리고 30초 정도 지나 wg show를 다시 확인하니 "laptop" 피어의 handshake가 37초 전으로 즉시 갱신됐습니다. 바로 재연결이 확인됐습니다.

이해한 내용

이번 트러블슈팅으로 명확해진 건 방화벽 규칙을 짤 때 "트래픽의 방향과 단계"를 구분해서 생각해야 한다는 점입니다.

  • 서비스가 정상 작동 중이라도, 방화벽에서 막히면 외부에서는 죽은 것처럼 보입니다.
  • VPN 터널 내부 대역(10.0.0.0/24)을 허용하는 것과, VPN 자체를 여는 포트(51820/udp)를 허용하는 것은 서로 다른 레이어의 문제입니다. 터널이 이미 열려 있어야만 내부 대역 규칙이 의미가 있고, 애초에 터널을 여는 handshake 패킷은 외부 공인 IP 기준으로 별도 허용이 필요합니다.
  • 문제가 생겼을 때는 서비스 레벨(포트 리스닝 여부) → 네트워크 레벨(IP, 인터페이스 상태) → 방화벽 레벨 순으로 점검 범위를 좁혀가는 게 효율적이었습니다. 특히 방화벽 로그(/var/log/ufw.log)를 실시간으로 확인한 게 결정적이었습니다. [UFW BLOCK] 로그 한 줄이 원인을 바로 알려줬습니다.
  • 방화벽 규칙을 수정한 시점(/etc/ufw/user.rules의 mtime)을 확인해서 "언제부터 문제가 시작됐을지" 역추적한 것도 유용한 접근이었습니다.

실전 적용

앞으로 UFW 같은 방화벽 규칙을 수정할 때는 체크리스트를 만들어서 적용하는 게 안전할 것 같습니다.

  • 방화벽 규칙 변경 후에는 반드시 외부에서 실제로 접속 테스트를 해보고 넘어가기
  • 서비스별로 필요한 포트 목록을 별도로 문서화해두고, 규칙 정리 시 이 목록과 대조하기 (Samba: 445/139, WireGuard: 51820/udp 등)
  • wg show의 handshake 시각을 주기적으로 모니터링하는 간단한 스크립트를 짜서, 피어 연결이 끊기면 바로 알림을 받도록 해두면 이런 장애를 더 빨리 감지할 수 있을 듯합니다.

추가 학습 계획

  • UFW 규칙을 코드로 관리(예: 스크립트나 Ansible)해서 수정 이력을 남기고, 실수로 규칙이 누락되는 걸 방지하는 방법을 알아볼 예정입니다.
  • WireGuard의 handshake 메커니즘을 더 자세히 파고들어서, keepalive 설정이나 NAT 환경에서의 동작 방식도 정리해보고 싶습니다.
  • 방화벽 로그를 자동으로 모니터링하고 이상 패턴을 알려주는 간단한 로그 감시 도구를 만들어보는 것도 다음 목표입니다.