iptables 추적 레코드의 ID가 0인 이유는 무엇입니까?

iptables 추적 레코드의 ID가 0인 이유는 무엇입니까?

네트워크 문제를 분석하기 위해 iptables Trace를 사용하지만 ACK 패킷의 레코드 ID는 항상 0입니다.

[ 3556.086666] TRACE: raw:OUTPUT:policy:2 IN= OUT=lo SRC=10.233.52.186 DST=10.233.52.186 ID=51512  PROTO=TCP SPT=54186 DPT=80 SYN      
[ 3556.086772] TRACE: nat:OUTPUT:rule:1 IN= OUT=lo SRC=10.233.52.186 DST=10.233.52.186 ID=51512  PROTO=TCP SPT=54186 DPT=80 SYN      
[ 3556.086784] TRACE: nat:KUBE-SERVICES:rule:1 IN= OUT=lo SRC=10.233.52.186 DST=10.233.52.186 ID=51512  PROTO=TCP SPT=54186 DPT=80 SYN      
[ 3556.086793] TRACE: nat:KUBE-MARK-MASQ:rule:1 IN= OUT=lo SRC=10.233.52.186 DST=10.233.52.186 ID=51512  PROTO=TCP SPT=54186 DPT=80 SYN      
[ 3556.086803] TRACE: nat:KUBE-MARK-MASQ:return:2 IN= OUT=lo SRC=10.233.52.186 DST=10.233.52.186 ID=51512  PROTO=TCP SPT=54186 DPT=80 SYN      MARK=0x4000 
[ 3556.086814] TRACE: nat:KUBE-SERVICES:rule:2 IN= OUT=lo SRC=10.233.52.186 DST=10.233.52.186 ID=51512  PROTO=TCP SPT=54186 DPT=80 SYN      MARK=0x4000 
[ 3556.086825] TRACE: nat:KUBE-NODE-PORT:return:2 IN= OUT=lo SRC=10.233.52.186 DST=10.233.52.186 ID=51512  PROTO=TCP SPT=54186 DPT=80 SYN      MARK=0x4000 
[ 3556.086846] TRACE: nat:KUBE-SERVICES:rule:3 IN= OUT=lo SRC=10.233.52.186 DST=10.233.52.186 ID=51512  PROTO=TCP SPT=54186 DPT=80 SYN      MARK=0x4000 
[ 3556.086891] TRACE: raw:OUTPUT:rule:1 IN= OUT=eth0 SRC=10.233.52.186 DST=10.22.46.48 ID=51512  PROTO=TCP SPT=54186 DPT=30080 SYN      MARK=0x4000 
[ 3556.086900] TRACE: raw:OUTPUT:policy:2 IN= OUT=eth0 SRC=10.233.52.186 DST=10.22.46.48 ID=51512  PROTO=TCP SPT=54186 DPT=30080 SYN      MARK=0x4000 
[ 3556.086918] TRACE: filter:OUTPUT:policy:1 IN= OUT=eth0 SRC=10.233.52.186 DST=10.22.46.48 ID=51512  PROTO=TCP SPT=54186 DPT=30080 SYN      MARK=0x4000 
[ 3556.086928] TRACE: nat:POSTROUTING:rule:1 IN= OUT=eth0 SRC=10.233.52.186 DST=10.22.46.48 ID=51512  PROTO=TCP SPT=54186 DPT=30080 SYN      MARK=0x4000 
[ 3556.086939] TRACE: nat:KUBE-POSTROUTING:rule:3 IN= OUT=eth0 SRC=10.233.52.186 DST=10.22.46.48 ID=51512  PROTO=TCP SPT=54186 DPT=30080 SYN      MARK=0x4000 
[ 3556.086948] TRACE: nat:KUBE-POSTROUTING:rule:4 IN= OUT=eth0 SRC=10.233.52.186 DST=10.22.46.48 ID=51512  PROTO=TCP SPT=54186 DPT=30080 SYN      
[ 3556.087562] TRACE: raw:PREROUTING:policy:2 IN=eth0 OUT= SRC=10.22.46.48 DST=10.22.46.11 ID=0  PROTO=TCP SPT=30080 DPT=39830 SYN    
[ 3556.087592] TRACE: filter:INPUT:rule:1 IN=eth0 OUT= SRC=10.22.46.48 DST=10.233.52.186 ID=0  PROTO=TCP SPT=30080 DPT=54186 SYN    
[ 3556.087606] TRACE: filter:KUBE-NODE-PORT:return:2 IN=eth0 OUT= SRC=10.22.46.48 DST=10.233.52.186 ID=0  PROTO=TCP SPT=30080 DPT=54186 SYN    
[ 3556.087617] TRACE: filter:INPUT:policy:2 IN=eth0 OUT= SRC=10.22.46.48 DST=10.233.52.186 ID=0  PROTO=TCP SPT=30080 DPT=54186 SYN

왜?

답변1

자세한 내용은 다음에 설명되어 있습니다.RFC 6864: IPv4 ID 필드 사양이 업데이트되었습니다. 아래의 모든 인용문은 이 RFC에서 인용되었으며 순서가 반드시 일치하는 것은 아닙니다.

IPv4 ID 필드는 리어셈블리 중에 오프셋이 동일하지만 두 개의 다른 패킷에 속하는 두 조각을 구별하는 데 사용됩니다. 조각이 없으면 특별히 처리할 사항이 없습니다.

SYN과 SYN/ACK 모두 DF(Do Not Fragment) 플래그가 설정되어 있으므로 조각화가 불가능하므로 ID가 쓸모 없게 됩니다.

>> DF=1인 IPv4 데이터그램은 조각화되지 않습니다.

o 원자 데이터그램: (DF==1)&&(MF==0)&&(frag_offset==0)

원자 데이터그램에서, IPv4 ID 필드는 의미가 없으므로 임의의 값으로 설정할 수 있습니다.
원자 데이터그램에는 더 이상 소스 주소/대상 주소/프로토콜 튜플에 고유 ID가 필요하지 않습니다.
:

>> 원본 소스는 원자 데이터그램의 IPv4 ID 필드를 임의의 값으로 설정할 수 있습니다.

Linux는 DF 플래그가 있는 한 모든 SYN/ACK에 대해 0을 사용합니다.TCP 빠른 열기SYN/ACK에 실제 데이터도 포함되어 있으면 변경될 수 있습니다.

이를 위해서는 조각화가 가능하거나(예: DF=0) 조각화가 발생한 경우(예: frag_offset>0 또는 MF=1) 소스 주소/대상 주소/프로토콜 튜플 내에서 ID가 고유해야 합니다.

따라서 이 문서에서는 조각화 및 재조립에 대해서만 이 필드의 값을 정의합니다.

>>IPv4 ID 필드는 조각화 및 재조립 이외의 목적으로 사용되어서는 안 됩니다..

RFC 6864에는 트래픽 식별을 위해 ID에 의존해서는 안 된다는 점을 명확하게 명시하고 있습니다.

>> 원본 소스는 원자 데이터그램의 IPv4 ID 필드를 임의의 값으로 설정할 수 있습니다.

>> IPv4 헤더를 검사하는 모든 장치원자 데이터그램의 IPv4 ID 필드는 무시되어야 합니다..


보너스

트래픽을 식별하는 매우 제한된 방법을 제공합니다. 이것이 필요하다nftables(iptables이 작업을 수행할 수 없습니다). 페이로드 수정을 통해 IP 필드를 직접 조작할 수 없거나 IP 체크섬을 올바르게 다시 계산할 수 없습니다. 따라서 단일 ID 값을 한 번만 할당하도록 제한되어 ip id set체크섬을 올바르게 다시 계산합니다. rvalue를 입력할 수 없기 때문에(예: @th,16,16gets type tcp dport) 클라이언트 소스 포트( @th,17,15정수 유지)의 하위 15비트를 재사용하기로 선택했습니다. 이는 SYN/ACK의 대상 포트입니다.

customsynackid.nft:

table ip customsynackid        # for idempotence
delete table ip customsynackid # for idempotence

table ip customsynackid {
    chain prerouting { type filter hook prerouting priority -310; policy accept;
    ip frag-off & 0x4000 != 0 tcp flags syn|ack ip id == 0 ip id set @th,17,15
    }
}

이는 라우터(예: K8s 노드)에서 수행되도록 고안되었으며 적용할 인터페이스를 선택하여 보완할 수 있습니다.포스트 라우팅바꾸다사전 라우팅. 엔드포인트에서 수행할 수 있습니다(예: 포드에 다음 기능을 사용할 수 있는 경우).nftables그렇지 않습니다) hook prerouting그냥 hook output.

이 세트ID 필드도착하다(TCP 프로토콜dport 및 0x7fff). 예를 들어, 포트 37142에서 포트 80으로(따라서 포트 80에서 포트 37142로) TCP 연결에 대한 응답은 ID 필드가 4374(37142 & 0x7fff = 4374)인 SYN/ACK를 제공합니다.

관련 정보