본문 바로가기
IT/Linux

[Linux] iptables에서 nftables로 전환: 레거시 방화벽 마이그레이션 가이드

by 수누다 2026. 7. 8.

[Linux] iptables에서 nftables로 전환: 레거시 방화벽 마이그레이션 가이드

리눅스 서버를 오래 운영하다 보면 방화벽 규칙이 점점 덕지덕지 붙는 순간이 오더라고요. 저도 홈랩과 실서버를 같이 굴리면서 iptables nftables 전환 작업을 몇 번 했었는데, 처음엔 "굳이 잘 돌아가는 걸 왜 바꿔?" 싶었어요. 근데 규칙이 늘어나고, IPv4와 IPv6를 따로 관리하고, 서비스별 예외가 계속 생기기 시작하면 이야기가 확 달라져요. 그때부터는 레거시 방화벽 구조가 발목을 잡기 시작하거든요. 이번 글에서는 iptables에서 nftables로 전환할 때 어떤 흐름으로 접근하면 덜 고생하는지, 제가 직접 해보며 삽질했던 포인트까지 묶어서 정리해보겠습니다.

특히 이 글은 새로운 방화벽을 처음 설계하는 분보다는, 이미 운영 중인 규칙을 가진 상태에서 nftables 마이그레이션을 고민하는 분들께 맞춰 썼습니다. "규칙은 많은데 서비스 중단은 싫다", "iptables-save 출력은 복잡한데 어떻게 옮겨야 할지 모르겠다" 같은 상황이 딱 여기에 해당합니다.

iptables nftables 전환 아키텍처를 보여주는 리눅스 방화벽 마이그레이션 이미지

레거시 체인과 테이블이 nftables의 통합 규칙셋으로 재구성되는 흐름을 보여주는 개요 이미지입니다.

왜 지금 iptables에서 nftables로 전환해야 할까요

쉽게 말해, nftablesLinux 커널의 Netfilter(넷필터, 리눅스 패킷 필터링 프레임워크) 위에서 동작하는 더 현대적인 규칙 관리 방식이에요. 예전에는 iptables, ip6tables, arptables, ebtables처럼 도구가 나뉘어 있었는데, nftables 쪽은 이걸 훨씬 일관되게 다룰 수 있게 정리해둔 느낌이 강합니다.

제가 직접 운영하면서 체감한 장점은 크게 세 가지였어요. 첫째, 규칙 표현이 훨씬 읽기 좋습니다. 둘째, IPv4와 IPv6를 한 구조 안에서 관리하기가 정말 편해요. 셋째, 집합(Set, 셋)과 맵(Map, 매핑) 같은 기능을 활용하면 반복 규칙이 크게 줄어듭니다. 예전엔 포트 하나 열 때마다 규칙을 늘어놓았는데, nftables에서는 묶어서 다루니까 관리가 훨씬 편하더라고요.

항목 iptables nftables
규칙 구조 테이블/체인/룰이 분산되어 장황해지기 쉬움 문법이 비교적 일관적이고 집합 활용이 쉬움
IPv4/IPv6 관리 보통 분리 관리 inet 패밀리로 통합 관리 가능
변환 도구 기존 자산 많음 iptables-translate 같은 변환 도구 활용 가능
장기 운영성 레거시 환경과의 호환성은 좋음 새 규칙 설계와 정리에 유리

여기서 중요한 포인트가 하나 있어요. iptables를 무조건 즉시 버리라는 뜻은 아닙니다. 실제 운영에서는 배포판 기본값, 커널 버전, 시스템 서비스와의 연동 방식까지 같이 봐야 하거든요. 다만 새로 정리할 기회가 있다면 nftables 쪽이 구조적으로 훨씬 낫다는 건 분명해요.

iptables에서 nftables로 전환 전에 꼭 확인할 체크리스트

저도 처음엔 규칙부터 바꾸려고 달려들었는데, 나중에 보니 그게 제일 위험한 접근이었어요. 리눅스 방화벽 교체 전에 아래 항목부터 확인하는 게 훨씬 안전합니다.

  1. 현재 규칙 백업
    현재 적용된 IPv4/IPv6 규칙을 반드시 저장합니다.
  2. 원격 접속 경로 확인
    SSH 관리 포트가 어디서 열려 있는지 먼저 확인합니다. 이거 놓치면 진짜 난감해집니다.
  3. 배포판의 기본 방화벽 스택 확인
    일부 환경은 iptables 명령이 내부적으로 nft 백엔드를 쓰기도 해요. 헷갈리기 쉬운 부분이죠.
  4. 자동 시작 서비스 확인
    재부팅 후 `nftables.service` 또는 배포판별 방화벽 서비스가 어떤 규칙을 로드하는지 봐야 합니다.
  5. 롤백 경로 준비
    문제가 생기면 바로 이전 규칙으로 되돌릴 방법을 준비해둡니다.

예를 들어 현재 규칙 백업은 이렇게 해두면 돼요.

sudo iptables-save > /root/iptables-backup.rules
sudo ip6tables-save > /root/ip6tables-backup.rules

그리고 nftables 쪽 현재 상태도 함께 확인해보세요.

sudo nft list ruleset

출력이 비어 있더라도 괜찮습니다. 중요한 건 지금 시스템이 무엇을 기준으로 패킷을 처리하는지 감을 잡는 거예요.

nftables 개념, 쉽게 말해 이렇게 이해하면 됩니다

저도 처음엔 `table`, `chain`, `hook` 같은 용어가 한꺼번에 나와서 좀 헷갈렸는데요. 쉽게 말해 이렇습니다.

  • Table(테이블): 규칙을 묶는 큰 서랍이에요.
  • Chain(체인): 실제 패킷이 지나가며 검사되는 규칙 목록입니다.
  • Hook(훅): 커널 네트워크 경로의 어느 지점에서 체인을 실행할지 정하는 연결점입니다.
  • Set(셋): IP, 포트 같은 값을 묶어 재사용하는 구조예요.

iptables에서는 INPUT, OUTPUT, FORWARD 체인 중심으로 익숙해져 있다 보니 nftables 문법이 낯설게 느껴지는데, 구조를 이해하고 나면 오히려 더 명확합니다. 특히 `inet` 패밀리를 쓰면 IPv4와 IPv6 규칙을 함께 다룰 수 있어서, 실무에서 규칙 중복이 많이 줄어들어요.

레거시 규칙을 그대로 옮기기보다 재설계가 필요한 이유

이 부분이 꽤 중요합니다. iptables-translate는 분명 유용한 도구입니다. 하지만 "기계적으로 변환된 규칙 = 가장 좋은 nftables 규칙"은 아니더라고요. 번역은 되는데, 구조가 지저분하게 남는 경우가 많아요. 그래서 저는 보통 이렇게 접근합니다. 먼저 변환 도구로 초안을 만들고, 그다음 사람이 읽기 좋은 구조로 다시 정리합니다. 처음엔 귀찮아 보여도 장기적으로 훨씬 이득이에요.

실전: iptables 규칙을 nftables로 마이그레이션하는 순서

이제 본격적으로 옮겨보겠습니다. 여기서는 가장 흔한 서버 기준으로 설명할게요. SSH는 열어두고, 이미 확립된 연결은 유지하고, 기본 정책은 보수적으로 가져가는 흐름입니다.

1. 현재 iptables 규칙 확인

sudo iptables -S
sudo ip6tables -S

규칙을 읽어보면서 실제로 필요한 것과 과거 흔적을 구분하는 게 먼저예요. 저 같은 경우 예전에 테스트하다 남긴 포트 허용 규칙이 생각보다 많았습니다. 이런 건 옮기기 전에 정리하는 게 맞아요.

2. 변환 초안 생성

단일 규칙 한 줄은 `iptables-translate`로, 전체 저장본은 `iptables-restore-translate`로 보는 식으로 접근하면 편합니다.

sudo iptables-translate -A INPUT -p tcp --dport 22 -j ACCEPT
sudo iptables-save | sudo iptables-restore-translate

출력 결과를 바로 적용하기보다, 먼저 파일로 저장해서 검토하는 쪽을 권장해요.

sudo sh -c 'iptables-save | iptables-restore-translate > /root/translated.nft'

여기서 중요한 포인트! 변환 결과를 그대로 믿지 마시고, 불필요하게 중복된 규칙이나 체인 구조를 꼭 점검하세요.

iptables nftables 전환 과정에서 iptables-translate를 사용하는 터미널 이미지

기존 iptables 규칙을 읽고 nftables 초안으로 변환하는 과정의 핵심 명령 흐름을 보여주는 이미지입니다.

3. 사람이 읽기 좋은 nftables 규칙으로 정리

제가 실제로는 아래처럼 새 파일을 다시 구성하는 편입니다. 예시는 가장 기본적인 서버용 필터 규칙셋입니다.

table inet filter {
    chain input {
        type filter hook input priority 0;
        policy drop;

        iif lo accept
        ct state established,related accept
        ct state invalid drop

        tcp dport 22 accept
        tcp dport 80 accept
        tcp dport 443 accept

        ip protocol icmp accept
        ip6 nexthdr ipv6-icmp accept
    }

    chain forward {
        type filter hook forward priority 0;
        policy drop;
    }

    chain output {
        type filter hook output priority 0;
        policy accept;
    }
}

이 규칙은 설명하기도 좋고, 나중에 봐도 의도가 비교적 분명합니다. `ct state established,related accept` 같은 부분은 기존 연결을 유지하는 데 아주 중요해서 빠뜨리면 안 돼요. 저도 초반에 이걸 빼먹고 "왜 응답 패킷이 이상하지?" 하며 한참 들여다봤었습니다.

4. Set으로 반복 규칙 줄이기

nftables의 진짜 장점은 이런 반복 제거에서 드러나요.

table inet filter {
    set allowed_tcp_ports {
        type inet_service
        elements = { 22, 80, 443 }
    }

    chain input {
        type filter hook input priority 0;
        policy drop;

        iif lo accept
        ct state established,related accept
        tcp dport @allowed_tcp_ports accept
    }
}

포트가 많아질수록 이 방식이 진짜 편하더라고요. 나중에 하나 추가하거나 제거할 때도 눈에 잘 들어옵니다.

5. 문법 검증 후 적용

실제 적용 전에는 반드시 문법 검사를 먼저 해요.

sudo nft -c -f /etc/nftables.conf

이상 없으면 적용합니다.

sudo nft -f /etc/nftables.conf

그리고 자동 시작도 확인해둬요.

sudo systemctl enable nftables
sudo systemctl restart nftables

배포판에 따라 서비스 이름이나 기본 설정 경로가 조금 다를 수 있으니, 이 부분은 현재 환경 기준으로 꼭 다시 확인하셔야 해요.

⚠️ 트러블슈팅: 제가 실제로 겪었던 문제들

여기서부터가 실전입니다. 문서만 보면 금방 끝날 것 같지만, 실제로는 작은 차이 때문에 시간이 꽤 들어가요. 저도 삽질 좀 했습니다 ㅎㅎ

SSH 접속이 갑자기 끊길 뻔한 경우

가장 흔한 문제입니다. 기본 정책을 `drop`으로 바꿨는데 SSH 허용 규칙 순서가 뒤에 있거나, 아예 빠져 있으면 바로 위험해져요. 그래서 저는 항상 아래 순서를 지킵니다.

  1. 현재 접속 세션을 유지하는 `established,related` 규칙 먼저 추가
  2. SSH 허용 규칙 추가
  3. 그다음 기본 정책 적용

이 순서를 지키면 사고 확률이 많이 줄어들어요.

iptables와 nftables가 동시에 있는 것처럼 보이는 경우

이건 처음 보면 꽤 혼란스러워요. 배포판에 따라 `iptables` 명령이 내부적으로 nft 기반 호환 레이어를 쓰는 경우가 있거든요. 그래서 "분명 nft로 바꿨는데 iptables 명령도 뭔가 보인다?" 같은 상황이 생깁니다. 이럴 땐 감으로 보지 말고, 실제 활성 규칙셋이 무엇인지 `nft list ruleset` 기준으로 확인하는 습관이 필요해요.

변환은 됐는데 규칙이 너무 지저분한 경우

이건 거의 반드시 겪어요. `iptables-translate`는 시작점으로는 훌륭하지만, 최종 결과물로 보기엔 장황한 경우가 많습니다. 여기서 시간을 조금 더 써서 `set`, `inet`, 상태 기반 매칭 중심으로 재구성하면 나중에 유지보수가 훨씬 쉬워져요. 제가 직접 써보니 이 단계가 가장 큰 차이를 만들었습니다.

nftables 마이그레이션 시 set 기반 규칙 구성을 설명하는 리눅스 방화벽 이미지

반복되는 포트 허용 규칙을 set으로 정리해 유지보수성을 높이는 구성을 시각화한 이미지입니다.

검증: nftables 마이그레이션 후 무엇을 확인해야 할까요

규칙 적용이 끝났다고 바로 마무리하면 안 돼요. 실제로 원하는 동작이 나오는지 검증이 꼭 필요합니다.

기본 검증 명령

sudo nft list ruleset
sudo ss -tulpn
sudo journalctl -u nftables --no-pager

첫 번째는 현재 규칙셋 확인, 두 번째는 실제 리슨(Listen, 수신 대기) 포트 확인, 세 번째는 서비스 적용 로그 확인입니다. 저는 여기에 외부 호스트에서 실제 접속 테스트도 꼭 붙입니다. 서버 안에서만 보면 놓치는 게 있거든요.

체크해야 할 항목

  • SSH, 웹, 모니터링 포트가 의도대로 열려 있는지
  • 허용하지 않은 포트가 막혀 있는지
  • 재부팅 후에도 동일한 규칙이 유지되는지
  • IPv6 트래픽도 의도대로 동작하는지

특히 재부팅 검증은 꼭 해보세요. 적용은 됐는데 부팅 후 원래 규칙이 다시 올라오거나, 반대로 아무 규칙도 안 올라오는 경우가 있거든요. 저도 예전에 이걸 놓쳐서 "어제 분명 됐는데 왜 오늘 다르지?" 하며 로그를 뒤졌던 적이 있습니다.

iptables nftables 전환 후 규칙 검증과 포트 확인을 보여주는 운영 점검 이미지

적용된 규칙셋과 실제 서비스 포트 상태를 함께 확인하는 검증 단계의 결과 이미지입니다.

iptables와 nftables, 어떤 방식으로 운영 정리하는 게 좋을까요

운영 기준으로 보면 저는 이렇게 정리해요. 기존 시스템이 매우 안정적으로 돌고 있고 외부 의존성이 강하면, 한 번에 크게 바꾸기보다 단계적으로 옮기는 게 맞습니다. 반대로 규칙이 이미 복잡하고, 중복이 많고, 앞으로도 계속 확장될 예정이라면 nftables로 정리할 가치가 충분해요.

운영 상황 권장 접근
단순한 단일 서비스 서버 기본 규칙을 nftables로 재작성 후 빠르게 전환
규칙이 많은 오래된 서버 iptables 백업 후 변환 초안 생성, 단계적 검증
IPv4/IPv6 동시 운영 inet 테이블 중심으로 통합 설계
반복 포트/주소 규칙이 많음 set과 map 활용으로 구조 단순화

혹시 이런 경험 있으신가요? 규칙은 분명 맞는 것 같은데, 몇 달 뒤 다시 보면 왜 이렇게 짰는지 본인도 기억이 안 나는 경우요. 사실 리눅스 방화벽은 "작동만 하면 된다"가 아니라, 나중에 다시 읽어도 이해되는 구조가 정말 중요합니다. nftables는 바로 그 지점에서 큰 장점이 있어요.

정리: 리눅스 방화벽 교체는 번역보다 재설계가 핵심입니다

이번 iptables nftables 전환의 핵심은 단순 치환이 아닙니다. 리눅스 방화벽 교체를 한다고 생각하면, 기존 규칙을 점검하고, 필요한 것만 남기고, nftables 문법과 구조에 맞게 다시 정리하는 과정이 훨씬 중요합니다. `iptables-translate`는 좋은 출발점이지만, 최종 목적지는 결국 사람이 관리하기 좋은 규칙셋이어야 해요.

제가 직접 해보니 가장 중요한 건 세 가지였습니다. 백업, 순서, 검증입니다. 백업 없이 시작하지 말 것. SSH 같은 필수 허용 규칙을 먼저 둘 것. 적용 후에는 반드시 외부에서 검증할 것. 이 세 가지만 지켜도 큰 사고를 많이 줄일 수 있어요.

다음 글에서는 `nftables`에서 NAT(Network Address Translation, 네트워크 주소 변환) 규칙과 포트 포워딩을 정리하는 방법도 다뤄볼까 합니다. 홈랩 돌리시는 분들은 그쪽도 꽤 자주 쓰시거든요. 이전 글에서 다룬 리눅스 네트워크 기본 흐름과 함께 보시면 훨씬 이해가 잘 되실 겁니다.

iptables nftables 전환 핵심 체크리스트를 요약한 인프라 운영 인포그래픽

전환 이유, 절차, 검증 포인트를 한 번에 복습할 수 있도록 요약한 마무리 인포그래픽입니다.

자주 묻는 질문

iptables 규칙을 그대로 자동 변환해서 써도 될까요?

가능은 하지만 권장하지는 않아요. 초안 생성에는 좋지만, 장기 운영을 생각하면 사람이 읽기 좋은 형태로 정리하는 게 훨씬 낫습니다.

nftables 마이그레이션 시 가장 위험한 실수는 뭔가요?

원격 접속 허용 규칙보다 먼저 기본 차단 정책을 적용하는 거예요. SSH 세션이 끊기면 복구가 번거로워집니다.

IPv6를 안 쓰는 것 같으면 무시해도 될까요?

환경에 따라 다르지만, 실제로는 IPv6가 살아 있는 경우가 적지 않아요. 인터페이스와 서비스 노출 상태를 먼저 확인해보는 게 안전합니다.

netfilter를 꼭 깊게 알아야 하나요?

커널 내부까지 깊게 파고들 필요는 없지만, 패킷이 어느 훅(hook)을 지나고 어느 체인에서 처리되는지 정도는 이해해두면 문제 해결이 훨씬 빨라져요.