소개
iptables 명령으로 추가한 규칙은 현재 커널의 방화벽 설정을 변경하지만, 실행 중인 상태만 바꾼다고 해서 영구적인 구성이 되는 것은 아닙니다. 관리자는 일반적으로 iptables-save를 사용해 IPv4 규칙을 직렬화하여 저장하고, iptables-restore를 사용해 해당 형식의 규칙을 다시 불러옵니다. Debian 및 Ubuntu 시스템에서는 적절한 부팅 시 로더가 활성화되어 있을 때 /etc/iptables/rules.v4가 일반적인 영속성 파일로 사용됩니다.
이 작업 흐름을 세 개의 독립적인 계층으로 생각해 보세요. 실행 중인 규칙 집합은 현재 커널이 적용하고 있는 규칙입니다. 저장된 규칙 파일은 디스크에 있는 텍스트일 뿐이며, 도구나 서비스가 복원해야 실제로 적용됩니다. 기준 백업은 롤백을 위해 보관하는 검증된 시작 상태입니다. 한 계층을 변경해도 다른 두 계층이 자동으로 함께 갱신되지는 않으므로, 관리자는 각 전환 단계에서 저장, 복원 및 검증을 명시적으로 수행해야 합니다.
이 실습에서는 원래 방화벽 상태를 롤백 지점으로 보존하고, 특정 서비스에 대한 제한적인 허용 규칙을 추가해 저장합니다. 그런 다음 적용하기 전에 저장된 파일을 검증하고, 규칙 집합을 다시 불러오는 과정을 시뮬레이션한 뒤, 마지막으로 원래 기준 상태를 복원합니다. 이 작업을 통해 실행 중인 규칙, 저장된 규칙 파일, 롤백 복사본이라는 세 가지 상태를 명확히 구분할 수 있습니다.
실행 중인 IPv4 방화벽 백업
이 단계에서는 변경을 수행하기 전에 시작 시점의 방화벽 상태를 저장합니다. 이후 명령이 예상대로 동작하지 않을 경우, 롤백 파일을 사용해 검증된 상태로 되돌릴 수 있습니다.
프로젝트 디렉터리로 이동합니다.
cd /home/labex/project
규칙을 변경하기 전에 테스트 서비스가 정상적으로 제공되는지 확인합니다.
curl --noproxy '*' --fail --silent http://127.0.0.1:18087/status
이는 기준 상태를 확인하는 테스트입니다. 127.0.0.1은 루프백 인터페이스를 사용하고, --noproxy '*'는 프록시 환경 변수가 설정되어 있더라도 요청을 로컬에서 처리하도록 합니다. --fail --silent는 깔끔한 응답과 신뢰할 수 있는 종료 상태를 제공합니다. 방화벽을 변경하기 전에 서비스가 정상적으로 동작하는 상태를 확인해 두면 이후의 방화벽 동작을 더 쉽게 해석할 수 있습니다.
iptables-save를 사용해 전체 IPv4 규칙 집합을 출력합니다. 파이프는 출력을 tee로 전달하며, tee는 baseline.v4에 기록하는 동시에 일반 학습자 계정으로 명령을 실행하기 쉽게 해 줍니다.
sudo iptables-save | tee baseline.v4 >/dev/null
권한 경계를 이렇게 나눈 데에는 이유가 있습니다. sudo iptables-save는 보호된 커널 규칙 집합을 읽고, 권한이 없는 tee는 프로젝트 디렉터리에 파일을 기록합니다. 마지막 리디렉션은 tee가 화면에 출력하는 복사본을 /dev/null로 보내는 것이며, 파일을 비우는 동작이 아닙니다. 생성된 백업에는 이 호스트에서 보고한 모든 IPv4 테이블과 체인이 직렬화되어 포함되며, 나중에 추가할 특정 규칙 하나만 포함되는 것은 아닙니다.
저장된 파일의 앞부분을 확인합니다.
head -n 12 baseline.v4
정확한 카운터 값은 달라질 수 있지만, 이 파일은 테이블별 섹션으로 구성된 iptables-restore 형식을 사용합니다. 최소한의 필터 섹션은 다음과 비슷합니다.
*filter
:INPUT ACCEPT ...
...
COMMIT
각 섹션은 *filter와 같은 테이블 이름으로 시작하고, 체인과 정책을 선언한 뒤 규칙을 나열하고 COMMIT으로 끝납니다. iptables-restore는 해당 표시까지 도달한 경우에만 테이블 섹션을 적용합니다. 따라서 이 파일을 독립적으로 실행하는 셸 명령 목록으로 취급해서는 안 됩니다.
파일에 필터 테이블 표시와 커밋 표시가 포함되어 있는지 확인합니다.
grep -E '^\*filter$|^COMMIT$' baseline.v4
서비스 규칙 추가 및 저장
이 단계에서는 실행 중인 방화벽에 명시적인 허용 규칙을 추가하고, 변경된 규칙 집합을 일반적인 IPv4 영속성 경로에 저장합니다.
INPUT 체인의 맨 앞에 18087 포트로 향하는 루프백 TCP 트래픽을 허용하는 규칙을 삽입합니다. 인터페이스와 포트를 제한했으므로 이 실습에 필요한 범위로 규칙이 한정됩니다.
sudo iptables -I INPUT 1 -i lo -p tcp --dport 18087 -j ACCEPT
INPUT은 호스트 자체를 대상으로 하는 트래픽을 처리합니다. -I INPUT 1은 규칙을 첫 번째 위치에 배치하고, -i lo는 루프백 인터페이스로 제한하며, -p tcp --dport 18087은 테스트 서비스를 선택합니다. -j ACCEPT는 일치하는 트래픽을 허용합니다. 이처럼 범위가 명확하고 제한적인 규칙은 여러 서비스를 광범위하게 허용하는 규칙보다 감사하고 삭제하기 쉽습니다.
실행 중인 규칙을 확인합니다. 종료 상태가 0 이면 정확한 조건과 대상이 존재한다는 뜻입니다. 이 호스트의 nftables 기반 구현에서는 일치하는 규칙을 정규화된 형식으로 출력하기도 합니다.
sudo iptables -C INPUT -i lo -p tcp --dport 18087 -j ACCEPT
실행 중인 전체 IPv4 규칙 집합을 저장합니다. /etc/iptables에 쓰려면 관리자 권한이 필요하므로 sudo tee를 사용합니다.
sudo iptables-save | sudo tee /etc/iptables/rules.v4 >/dev/null
이 명령은 규칙을 추가한 후의 새로운 스냅샷을 생성합니다. 파이프 양쪽에 sudo가 필요한 이유는 서로 다릅니다. 왼쪽 명령은 방화벽 상태를 읽고, 오른쪽 명령은 root 소유의 대상 파일을 엽니다. rules.v4 파일을 생성하는 것만으로는 규칙이 활성화되거나 자동 적용되도록 예약되지 않습니다. 이 파일은 복원 명령이나 부팅 시 서비스가 사용할 수 있도록 준비되는 것입니다.
저장된 파일에서 서비스 포트를 검색합니다. grep 뒤의 --는 옵션 해석을 끝내므로, 검색 패턴이 하이픈으로 시작할 수 있는 경우에도 유용합니다.
sudo grep -- '--dport 18087' /etc/iptables/rules.v4
출력에는 -j ACCEPT로 끝나는 INPUT 규칙이 포함되어야 합니다. 이제 실행 중인 규칙 집합과 저장된 파일 모두에 의도한 규칙이 포함되어 있습니다.
새 파일을 기준 백업과 바이트 단위로 비교하지 마세요. 패킷 카운터와 다른 소프트웨어가 관리하는 규칙은 정상적으로 변경될 수 있습니다. 이 실습에서 중요한 증거는 의도한 규칙이 실행 중인 상태와 저장된 결과물 양쪽에 모두 존재한다는 점입니다.
저장된 규칙 집합 검증 및 복원
이 단계에서는 실행 중인 규칙을 삭제하고, 저장된 파일을 적용하지 않은 상태에서 검증한 다음, 해당 파일을 다시 불러옵니다. 이 과정은 한 번의 실습 세션 안에서 재부팅 시 규칙이 복원되는 중요한 부분을 시뮬레이션합니다.
실행 중인 INPUT 체인에서 규칙을 삭제합니다.
sudo iptables -D INPUT -i lo -p tcp --dport 18087 -j ACCEPT
이 삭제는 커널의 현재 규칙 집합만 변경합니다. /etc/iptables/rules.v4 파일은 수정하지 않으므로, 저장된 규칙은 이후 명령으로 다시 복원할 수 있습니다. 이러한 의도적인 불일치를 통해 실행 중인 상태와 저장된 상태의 차이를 확인할 수 있습니다.
규칙이 없는지 확인합니다. 이 검사는 실패하는 것이 정상이며, ||는 메시지를 출력한 뒤 작업 흐름을 계속 진행하도록 합니다.
sudo iptables -C INPUT -i lo -p tcp --dport 18087 -j ACCEPT 2>/dev/null || echo "Live rule is absent"
저장된 방화벽을 적용하기 전에 iptables-restore --test를 사용합니다. 이 명령은 전체 파일을 구문 분석하고, 잘못된 구문이 있으면 오류를 보고하지만 실행 중인 규칙 집합을 교체하지는 않습니다.
sudo iptables-restore --test < /etc/iptables/rules.v4
< 연산자는 셸이 파일을 iptables-restore의 표준 입력으로 제공하도록 합니다. 아무 출력 없이 완료되면 구문이 허용되었다는 뜻이며, 아직 파일이 적용되었다는 의미는 아닙니다. 형식이 잘못되었거나 불완전한 규칙 집합을 복원하면 연결이 끊길 수 있으므로, 이러한 검증은 중요한 안전 절차입니다.
검증이 성공하면 명령은 조용히 완료됩니다. 이제 저장된 규칙을 실행 중인 방화벽에 복원합니다.
sudo iptables-restore < /etc/iptables/rules.v4
iptables로 규칙 하나를 추가하는 것과 달리 iptables-restore는 파일에 포함된 전체 테이블 섹션을 처리합니다. 따라서 영향이 큰 관리 작업으로 간주해야 합니다. 먼저 검증하고, 롤백 복사본을 보관하며, 복원 직후 중요한 접근 권한을 확인하세요. 이 실습에서는 몇 분 전에 동일한 호스트에서 저장한 파일을 사용하므로 조건이 통제되어 있습니다.
서비스 규칙이 다시 나타났는지 확인합니다.
sudo iptables -C INPUT -i lo -p tcp --dport 18087 -j ACCEPT
복원 후에도 애플리케이션에 접근할 수 있는지 확인합니다.
curl --noproxy '*' --fail --silent http://127.0.0.1:18087/status
원래 기준 상태로 롤백
이 단계에서는 1 단계에서 생성한 백업을 사용해 실행 중인 방화벽에서 실습 중 추가한 변경 사항을 제거합니다. 동시에 저장된 대상 규칙 집합은 검토할 수 있도록 그대로 유지합니다.
기준 파일을 적용하기 전에 검증합니다.
sudo iptables-restore --test < baseline.v4
여기서 baseline.v4와 /etc/iptables/rules.v4는 의도적으로 서로 다른 목적을 가집니다. 기준 파일은 원래 실행 중이던 상태를 나타내고, rules.v4는 서비스 규칙이 포함된 대상 상태를 나타냅니다. 한 파일을 복원해도 다른 파일은 수정되지 않습니다.
원래의 실행 중 규칙 집합을 복원합니다.
sudo iptables-restore < baseline.v4
실습 규칙이 더 이상 실행 중이지 않은지 확인합니다.
sudo iptables -C INPUT -i lo -p tcp --dport 18087 -j ACCEPT 2>/dev/null || echo "Original firewall baseline restored"
저장된 대상 파일은 별도의 결과물이며, 실습에서 복원했던 규칙을 여전히 포함하고 있습니다.
sudo grep -- '--dport 18087' /etc/iptables/rules.v4
이 확인은 상태가 분리되어 있음을 가장 명확하게 보여 줍니다. 실행 중인 방화벽은 롤백되었지만, 영속성 파일에는 여전히 대상 규칙이 기록되어 있습니다. 관리자는 나중에 이 파일을 다시 복원하거나, 부팅 시 영속성 서비스가 파일을 불러오도록 구성할 수 있습니다.
마지막으로, 원래의 허용적인 기준 상태로 돌아간 후에도 로컬 서비스에 접근할 수 있는지 확인합니다.
curl --noproxy '*' --fail --silent http://127.0.0.1:18087/status
운영 환경에서는 배포판의 영속성 파일을 부팅 시 불러오는 서비스가 무엇인지 확인해야 합니다. 예를 들어 Debian 계열 시스템에서는 iptables-persistent와 netfilter-persistent 같은 패키지를 함께 사용하는 경우가 많지만, 실제 설치 여부와 정책은 호스트마다 다릅니다. 올바른 rules.v4 파일을 저장하면 규칙 집합을 적용할 준비가 된 것이고, 부팅 시 자동으로 복원되는지는 로더가 설치되어 활성화되어 있는지에 따라 결정됩니다.
요약
실행 중인 IPv4 방화벽을 백업하고, 특정 서비스에 대한 규칙을 추가해 저장했습니다. 또한 iptables-restore --test로 직렬화된 규칙 집합을 검증하고, 이를 커널에 다시 불러온 뒤 원래 기준 상태로 롤백했습니다. 이 과정에서 실행 중인 방화벽과 저장된 영속성 파일 및 롤백 파일을 구분하는 방법도 익혔습니다. 이는 패킷 필터링 상태를 변경하거나 복원하기 전에 반드시 갖춰야 할 중요한 습관입니다.



