환경:
[root@VM-32-4-centos ~]# uname -r
3.10.0-514.26.2.el7.x86_64
다음 체인에서 로그 인쇄를 설정했습니다.
[root@VM-32-4-centos ~]# iptables -A INPUT -p tcp --dport 8000 -j LOG --log-prefix "INPUT DPORT 8000 LOGS: "
[root@VM-32-4-centos ~]# iptables -A INPUT -p tcp --sport 8000 -j LOG --log-prefix "INPUT SPORT 8000 LOGS: "
[root@VM-32-4-centos ~]# iptables -A OUTPUT -p tcp --dport 8000 -j LOG --log-prefix "OUTPUT DPORT 8000 LOGS: "
[root@VM-32-4-centos ~]# iptables -A OUTPUT -p tcp --sport 8000 -j LOG --log-prefix "OUTPUT SPORT 8000 LOGS: "
[root@VM-32-4-centos ~]# iptables -t nat -A POSTROUTING -p tcp --sport 8000 -j LOG --log-prefix "POSTROUTING SPORT 8000 LOGS: "
[root@VM-32-4-centos ~]# iptables -t nat -A POSTROUTING -p tcp --dport 8000 -j LOG --log-prefix "POSTROUTING DPORT 8000 LOGS: "
그런 다음 telnet 명령을 실행합니다.
telnet 127.0.0.1 8000
tail -f /var/log/message, 다음을 표시합니다.
May 2 23:54:47 VM-32-4-centos kernel: OUTPUT DPORT 8000 LOGS: IN= OUT=lo SRC=127.0.0.1 DST=127.0.0.1 LEN=60 TOS=0x10 PREC=0x00 TTL=64 ID=6163 DF PROTO=TCP SPT=51096 DPT=8000 WINDOW=43690 RES=0x00 SYN URGP=0
May 2 23:54:47 VM-32-4-centos kernel: POSTROUTING DPORT 8000 LOGS: IN= OUT=lo SRC=127.0.0.1 DST=127.0.0.1 LEN=60 TOS=0x10 PREC=0x00 TTL=64 ID=6163 DF PROTO=TCP SPT=51096 DPT=8000 WINDOW=43690 RES=0x00 SYN URGP=0
May 2 23:54:47 VM-32-4-centos kernel: INPUT DPORT 8000 LOGS: IN=lo OUT= MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00 SRC=127.0.0.1 DST=127.0.0.1 LEN=60 TOS=0x10 PREC=0x00 TTL=64 ID=6163 DF PROTO=TCP SPT=51096 DPT=8000 WINDOW=43690 RES=0x00 SYN URGP=0
May 2 23:54:47 VM-32-4-centos kernel: OUTPUT SPORT 8000 LOGS: IN= OUT=lo SRC=127.0.0.1 DST=127.0.0.1 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=TCP SPT=8000 DPT=51096 WINDOW=43690 RES=0x00 ACK SYN URGP=0
May 2 23:54:47 VM-32-4-centos kernel: INPUT SPORT 8000 LOGS: IN=lo OUT= MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00 SRC=127.0.0.1 DST=127.0.0.1 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=TCP SPT=8000 DPT=51096 WINDOW=43690 RES=0x00 ACK SYN URGP=0
May 2 23:54:47 VM-32-4-centos kernel: OUTPUT DPORT 8000 LOGS: IN= OUT=lo SRC=127.0.0.1 DST=127.0.0.1 LEN=52 TOS=0x10 PREC=0x00 TTL=64 ID=6164 DF PROTO=TCP SPT=51096 DPT=8000 WINDOW=342 RES=0x00 ACK URGP=0
May 2 23:54:47 VM-32-4-centos kernel: INPUT DPORT 8000 LOGS: IN=lo OUT= MAC=00:00:00:00:00:00:00:00:00:00:00:00:08:00 SRC=127.0.0.1 DST=127.0.0.1 LEN=52 TOS=0x10 PREC=0x00 TTL=64 ID=6164 DF PROTO=TCP SPT=51096 DPT=8000 WINDOW=342 RES=0x00 ACK URGP=0
죄송합니다. 로컬로 액세스할 때 SYN 패킷이 POSTROUTING을 거치는 이유는 무엇입니까?
후속 ACK+SYN 패킷은 POSTROUTING을 거치지 않습니다. 이유는 무엇입니까?
왜 이런 일이 발생하는지 물어봐도 될까요? 관련 정보가 있나요?
감사해요.
답변1
다음은 Linux 네트워크 스택을 통해 패킷이 이동하는 방법을 설명하는 Netfilter 및 일반 네트워킹의 패킷 흐름 다이어그램입니다(라우팅이 아닌 브리징에 사용되는 아래 파란색 링크 계층 필드는 무시할 수 있음).
패킷이 시스템에 로컬로 유지되도록 하려면 라우팅 스택이 lo
(루프백) 인터페이스를 사용하기 전에 패킷을 평가해야 합니다.
# ip route get 127.0.0.1
local 127.0.0.1 dev lo src 127.0.0.1 uid 0
cache <local>
따라서 회로도에 설명된 흐름을 따릅니다.
- 현지 프로세스에 의해 발급됨
- 라우팅 결정: 출력 인터페이스
lo
- 다양한 체인이 출력에 걸려있습니다.
- POSTROUTING의 다양한 체인 후크: 이는 항상 전달되거나 나가는 패킷에서 발생합니다.
lo
마지막으로 회로도 오른쪽의 인터페이스 로 전송됩니다.
이제 인터페이스 lo
는 루프백이라는 목적을 달성합니다. 패킷은 인터페이스를 통해 다시 lo
회로도의 왼쪽으로 돌아갑니다. 다시 lo
인터페이스로 돌아갑니다. 하지만 이번에는 나가는 것이 아니라 들어오는 것입니다.
- 인터페이스 "로부터"
lo
들어오는 패킷 - PREROUTING에 연결된 다양한 체인: 이는 항상 수신된 패킷에서 발생합니다.
- 라우팅 결정: 목적지는 로컬 프로세스가 됩니다.
- INPUT의 다양한 체인
- 로컬 프로세스에서 수신됨
이제 문제가 생겼습니다. NAT입니다. NAT 규칙은 동일한 흐름의 다른 모든 패킷이 동일한 방식으로 변환되는 방법을 결정하는 데 사용됩니다. 특정 흐름이 NAT되면 동일한 흐름(응답 포함)에 대한 다른 모든 패킷은 Netfilter 및 conntrack(NAT 수행 방법을 포함하여 이 흐름에 대한 필수 정보를 기억함)에 의해 직접 처리됩니다. 통과되지 않습니다.iptables더 이상은 아닙니다. 회로도에 이에 대한 메모가 있습니다.
"새" 연결에 대해서만 "nat" 테이블을 참조하세요.
그런 다음 이 스트림에 대한 NAT에 관한 다른 모든 것은 호출하지 않는 Netfilter에 의해 단락됩니다.iptablesNat은 더 이상 푹 빠져 있지 않습니다.
이를 통해 nat 테이블을 사용하여 결과를 해석할 수 있습니다. 두 개의 nat/POSTROUTING 규칙을 사용합니다.
흐름의 첫 번째 패킷: 초기 쿼리(SYN 패킷)가 NAT 규칙을 통과합니다.
- 일치 항목을 필터링
--dport
하고 로깅을 트리거합니다. - 일치 하지 않음
--sport
(로그 없음)
- 일치 항목을 필터링
이 흐름에 대한 모든 후속 패킷(포트 8080에 있는 애플리케이션의 응답 포함)은 흐름이 이미 존재하기 때문에 더 이상 nat 테이블을 통과하지 않습니다(예: 패킷이 "NEW" 상태가 아님).
따라서 최종
--sport
규칙은 아무것도 기록하지 않습니다.
lo
마찬가지로 nat/PREROUTING(또는 거의 사용되지 않는 nat/INPUT)에 LOG 규칙을 추가하면 로컬 스트림의 첫 번째 패킷이 항상 전송되기 때문에 인터페이스에서 오는 내용이 표시되지 않습니다.도착하다 lo
받기 전에~에서 lo
: 그런 과정은 항상 존재합니다.
다음 명령을 사용하여 mangle/POSTROUTING에 로그인하는 경우:
iptables -t mangle -A POSTROUTING -p tcp --sport 8000 -j LOG --log-prefix "mangle POSTROUTING SPORT 8000 LOGS: "
iptables -t mangle -A POSTROUTING -p tcp --dport 8000 -j LOG --log-prefix "mangle POSTROUTING DPORT 8000 LOGS: "
필터/입력 및 필터/출력과 마찬가지로 로그에서 모든 쿼리와 모든 응답 패킷을 볼 수 있습니다.
위의 내용이 아닌 경우 항상 발생하는 것처럼 새 상태 패킷만 보는 필터를 추가합니다.냇테이블:
iptables -t mangle -A POSTROUTING -m conntrack --ctstate NEW -p tcp --sport 8000 -j LOG --log-prefix "mangle POSTROUTING SPORT 8000 LOGS: "
iptables -t mangle -A POSTROUTING -m conntrack --ctstate NEW -p tcp --dport 8000 -j LOG --log-prefix "mangle POSTROUTING DPORT 8000 LOGS: "
그런 다음 동일한 초기 동작이 다시 발생합니다. 각 스트림의 첫 번째 패킷에 대한 로그는 하나만 있습니다(따라서 --sport
스트림의 첫 번째 패킷은 응답이므로 절대 발생하지 않음).