커널이 tun/tap을 통해 주입된 패킷을 '화성인'으로 처리하지 않도록 하는 방법

커널이 tun/tap을 통해 주입된 패킷을 '화성인'으로 처리하지 않도록 하는 방법

새로운 테스트 케이스가 있습니다.https://github.com/xdp-project/bpf-examples여기 https://github.com/tjcw/bpf-examples/tree/tjcw-integration-0.3/AF_XDP-filter . 흐름을 필터링하기 위한 것입니다. 아이디어는 흐름의 첫 번째 패킷을 사용자 공간으로 보내고, 사용자 공간에서 흐름이 허용 가능한지 여부를 결정하도록 하고(패킷의 5튜플을 확인하여) 그에 따라 eBPF 맵에 항목을 설정하는 것입니다. 흐름의 두 번째 및 후속 패킷은 eBPF 코드에 의해 커널에서 처리됩니다. 첫 번째 패킷(tun/tap 인터페이스를 통해 커널에 다시 주입됨)이 커널에 의해 '화성인'으로 삭제된다는 점을 제외하면 테스트 사례는 작동합니다. 결과적으로 이 코드에 'ping'을 시도하면 첫 번째 패킷을 제외한 모든 패킷에 대한 응답이 표시되고, 'ssh'를 시도하면 클라이언트의 TCP 프로토콜이 시간 초과되어 재전송되는 동안 시작 시 약간의 중단이 발생합니다. SYN 패킷.

실행 시 'pwru'(cilium packet-where-are-you) 출력을 첨부합니다.

tjcw@tjcw-Standard-PC-Q35-ICH9-2009:~$ ping -c 2 192.168.122.48
PING 192.168.122.48 (192.168.122.48) 56(84) bytes of data.
64 bytes from 192.168.122.48: icmp_seq=2 ttl=64 time=2.28 ms

--- 192.168.122.48 ping statistics ---
2 packets transmitted, 1 received, 50% packet loss, time 1028ms
rtt min/avg/max/mdev = 2.282/2.282/2.282/0.000 ms
tjcw@tjcw-Standard-PC-Q35-ICH9-2009:~$

이 글을 읽는 사람 중 커널이 왜 패킷을 화성인으로 취급하는지, 그리고 이를 극복할 수 있는 방법이 있는지 아는 사람이 있습니까? uname -a가 표시된 Ubuntu 22.04를 사용하고 있습니다.

tjcw@tjcw-Standard-PC-Q35-ICH9-2009:~$ uname -a
Linux tjcw-Standard-PC-Q35-ICH9-2009 5.15.0-53-generic #59-Ubuntu SMP
Mon Oct 17 18:53:30 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
tjcw@tjcw-Standard-PC-Q35-ICH9-2009:~$
2022/11/25 11:37:02 Listening for events..
               SKB    CPU          PROCESS                     FUNC
0xffff9478f5038300      1        [<empty>]         pskb_expand_head
0xffff9478f5038300      1        [<empty>]            skb_free_head
0xffff9478f5038300      1        [<empty>] bpf_prog_run_generic_xdp
0xffff9478f5038300      1        [<empty>]  xdp_do_generic_redirect
0xffff9478f5038300      1        [<empty>]              consume_skb
0xffff9478f5038300      1        [<empty>]   skb_release_head_state
0xffff9478f5038300      1        [<empty>]         skb_release_data
0xffff9478f5038300      1        [<empty>]            skb_free_head
0xffff9478f5038300      1        [<empty>]             kfree_skbmem
0xffff9478f5038300      1    [af_xdp_user]        netif_receive_skb
0xffff9478f5038300      1    [af_xdp_user]   skb_defer_rx_timestamp
0xffff9478f5038300      1    [af_xdp_user]      __netif_receive_skb
0xffff9478f5038300      1    [af_xdp_user] __netif_receive_skb_one_core
0xffff9478f5038300      1    [af_xdp_user]                   ip_rcv
0xffff9478f5038300      1    [af_xdp_user]              ip_rcv_core
0xffff9478f5038300      1    [af_xdp_user]               sock_wfree
0xffff9478f5038300      1    [af_xdp_user]     ip_route_input_noref
0xffff9478f5038300      1    [af_xdp_user]       ip_route_input_rcu
0xffff9478f5038300      1    [af_xdp_user]      ip_route_input_slow
0xffff9478f5038300      1    [af_xdp_user]      fib_validate_source
0xffff9478f5038300      1    [af_xdp_user]    __fib_validate_source
0xffff9478f5038300      1    [af_xdp_user] ip_handle_martian_source
0xffff9478f5038300      1    [af_xdp_user]         kfree_skb_reason
0xffff9478f5038300      1    [af_xdp_user]   skb_release_head_state
0xffff9478f5038300      1    [af_xdp_user]         skb_release_data
0xffff9478f5038300      1    [af_xdp_user]            skb_free_head
0xffff9478f5038300      1    [af_xdp_user]             kfree_skbmem
0xffff9478c75d3000      1        [<empty>]         pskb_expand_head
0xffff9478c75d3000      1        [<empty>]            skb_free_head
0xffff9478c75d3000      1        [<empty>] bpf_prog_run_generic_xdp
0xffff9478c75d3000      1        [<empty>]                   ip_rcv
0xffff9478c75d3000      1        [<empty>]              ip_rcv_core
0xffff9478c75d3000      1        [<empty>]                skb_clone
0xffff9478c75d3000      1        [<empty>]              consume_skb
0xffff9478f5038c00      1        [<empty>]     ip_route_input_noref
0xffff9478f5038c00      1        [<empty>]       ip_route_input_rcu
0xffff9478f5038c00      1        [<empty>]      ip_route_input_slow
0xffff9478f5038c00      1        [<empty>]      fib_validate_source
0xffff9478f5038c00      1        [<empty>]    __fib_validate_source
0xffff9478f5038c00      1        [<empty>]         ip_local_deliver
0xffff9478f5038c00      1        [<empty>]  ip_local_deliver_finish
0xffff9478f5038c00      1        [<empty>]  ip_protocol_deliver_rcu
0xffff9478f5038c00      1        [<empty>]        raw_local_deliver
0xffff9478f5038c00      1        [<empty>]                 icmp_rcv
0xffff9478f5038c00      1        [<empty>]  __skb_checksum_complete
0xffff9478f5038c00      1        [<empty>]                icmp_echo
0xffff9478f5038c00      1        [<empty>]               icmp_reply
0xffff9478f5038c00      1        [<empty>]        __ip_options_echo
0xffff9478f5038c00      1        [<empty>]     fib_compute_spec_dst
0xffff9478f5038c00      1        [<empty>] security_skb_classify_flow
0xffff9478f5038c00      1        [<empty>]              consume_skb
0xffff9478f5038c00      1        [<empty>]   skb_release_head_state
0xffff9478f5038c00      1        [<empty>]         skb_release_data
0xffff9478f5038c00      1        [<empty>]             kfree_skbmem
0xffff9478c75d3000      1        [<empty>]               packet_rcv
0xffff9478c75d3000      1        [<empty>]              consume_skb
0xffff9478c75d3000      1        [<empty>]   skb_release_head_state
0xffff9478c75d3000      1        [<empty>]         skb_release_data
0xffff9478c75d3000      1        [<empty>]            skb_free_head

첫 번째(삭제된) 패킷은 첫 번째 pskb_expand_head부터 kfree_skbmem까지의 구간이고, 두 번째(통과된) 패킷은 두 번째 pskb_expand_head부터 끝까지의 구간이다.

답변1

이 동작은 '잘못된' 인터페이스에 들어오는 패킷 처리를 피하려는 시도인 역방향 경로 필터링으로 인해 발생합니다. 이 기능은 다음으로 끌 수 있습니다.

for device in /proc/sys/net/ipv4/conf/*
do
  echo 0 >${device}/rp_filter
done

서버에서 실행되는 스크립트에서. 이 작업이 완료되면 모든 ping 패킷에 응답합니다.

관련 정보