패킷 생성을 고려하지 않는 IP 규칙 수정 방법은 무엇입니까?

패킷 생성을 고려하지 않는 IP 규칙 수정 방법은 무엇입니까?

문제: L4 트래픽을 특정 인터페이스 밖으로 라우팅하기 위해 작성된 IP 규칙은 패킷이 다른 소스 주소로 생성되는 경우 존중되지 않습니다.

개요 호스트 주소와 다른 소스 주소로 패킷을 생성하고 싶습니다. 이를 달성하기 위해 저는 Python 패키지 Scapy를 사용하고 있습니다. 참고: 내 목표는 DNS 트래픽을 보내기 위해 보내는 것입니다. 그러나 DNS 요청에서 소스 주소를 스푸핑할 수 있는 간단한 솔루션을 찾을 수 없었기 때문에 포트 53에서 src 및 dst 주소를 사용하여 UDP 패킷을 생성하고 있습니다. 현재 실제 DNS 프로토콜이 아닌 L3 및 L4만 테스트하고 있기 때문에 이것이 여전히 작동한다고 믿습니다. 여기 내 스크립트가 있습니다

#!/usr/bin/python3

# The following is designed to generate a packet with a different source address

import sys 
from scapy.all import *

def main():
    S = "10.0.26.122" # spoofed source IP address
    D = "10.0.26.123" # destination IP address
    SP = 53 # source port
    DP = 53 # destination port
    payload = "This is a fake message" # packet payload

    spoofed_packet = IP(src=S, dst=D) / UDP(sport=53, dport=53) / payload
    send(spoofed_packet)

#Entry point
main()

스크립트를 실행하기 전에 내 라우팅 테이블은 다음과 같습니다.

# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         10.104.8.1      0.0.0.0         UG    101    0        0 ens192
10.0.21.0       0.0.0.0         255.255.255.0   U     104    0        0 ens256
10.0.26.0       0.0.0.0         255.255.255.0   U     0      0        0 ens224
10.0.27.0       0.0.0.0         255.255.255.0   U     102    0        0 ens193
10.0.28.0       10.0.29.1       255.255.255.0   UG    100    0        0 ens161
10.0.29.0       0.0.0.0         255.255.255.0   U     100    0        0 ens161
10.104.8.0      0.0.0.0         255.255.255.0   U     101    0        0 ens192
10.212.134.0    10.104.8.1      255.255.255.0   UG    101    0        0 ens192
192.168.122.0   0.0.0.0         255.255.255.0   U     0      0        0 virbr0

다음은 IP 인터페이스입니다.

# ip -br a
lo               UNKNOWN        127.0.0.1/8
ens161           UP             10.0.29.122/24
ens192           UP             10.104.8.122/24
ens193           UP             10.0.27.122/24
ens224           UP             10.0.26.122/24
ens256           UP             10.0.21.122/24
virbr0           DOWN           192.168.122.1/24
virbr0-nic       DOWN
ip_vti0@NONE     DOWN

스크립트를 실행하면 ./packet-gen.py "10.0.26.122" "10.0.26.123"작동합니다. 아직 IP 규칙/별도의 라우팅 테이블을 구축하지 않았기 때문입니다. 호스트(10.0.26.122)와 맨 끝 호스트(10.0.26.123)에서 tcpdump를 수행했는데 UDP 패킷이 전송되는 것을 확인했습니다. 또한 dig www.google.com @10.0.26.123실제 DNS 요청이 수행되는 것을 테스트 하고 확인하고 응답을 받았습니다.

이제 문제입니다. 기본 테이블에서 경로 항목을 제거한 다음 포트 번호를 기준으로만 경로를 지정하고 싶습니다. 이를 위해 다음을 실행하여 먼저 10.0.26.0/24에 대한 경로 항목을 제거합니다.

# ip route del 10.0.26.0/24 dev ens224
# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         10.104.8.1      0.0.0.0         UG    101    0        0 ens192
10.0.21.0       0.0.0.0         255.255.255.0   U     104    0        0 ens256
10.0.27.0       0.0.0.0         255.255.255.0   U     102    0        0 ens193
10.0.28.0       10.0.29.1       255.255.255.0   UG    100    0        0 ens161
10.0.29.0       0.0.0.0         255.255.255.0   U     100    0        0 ens161
10.104.8.0      0.0.0.0         255.255.255.0   U     101    0        0 ens192
10.212.134.0    10.104.8.1      255.255.255.0   UG    101    0        0 ens192
192.168.122.0   0.0.0.0         255.255.255.0   U     0      0        0 virbr0

항목이 제거됩니다. 스크립트를 다시 실행하면 작동하지 않습니다. 발굴 요청도 실패합니다. 이는 기본 커널 라우팅 테이블에 L3 경로가 없기 때문에 예상됩니다.

L4에서 라우팅하기 위해 먼저 ens224를 통해 모든 트래픽을 보내기 위해 새로운 IP 라우팅 테이블을 만들었습니다.

# ip route add table 53 0.0.0.0/0 dev ens224

그런 다음 포트 53을 사용하여 모든 트래픽을 캡처하는 IP 규칙을 만들고 사용자 지정 테이블 53을 보냅니다.

# ip rule add ipproto udp dport 53 lookup 53

또한 rp_filter에 대한 특수 sysctl 규칙을 너무 느슨하게 만들어 엄격한 역방향 경로 전달 규칙을 완화했습니다.

# sysctl -w "net.ipv4.conf.ens224.rp_filter=2"

내 작업을 확인하려면 다음이 표시됩니다.

# ip route list table 53
default dev ens224 scope link
# ip rule list
0:      from all lookup local
32765:  from all ipproto udp dport 53 lookup 53
32766:  from all lookup main
32767:  from all lookup default
# ip route get 10.0.26.123 ipproto udp dport 53
10.0.26.123 dev ens224 table 53 src 10.0.26.122 uid 0
    cache
# ip route get 10.0.26.123
10.0.26.123 via 10.104.8.1 dev ens192 src 10.104.8.122 uid 0
    cache

마지막 명령은 기본적으로 통신이 DNS가 아닌 경우 기본 경로를 사용함을 보여줍니다.

이것을 테스트하기 위해 먼저 10.0.26.123에 ping을 시도합니다. 예상대로 실패합니다. 이제 dig request를 수행하려고 하는데 dig www.google.com @10.0.26.123작동합니다. 발굴 요청은 기본 테이블로 이동하기 전에 IP 규칙에 도달하고 적절하게 라우팅됩니다. 트래픽이 tcpdump(10.0.26.123)를 사용하여 서비스에 도달하고 내 호스트(10.0.26.122)에서 오는 것을 확인합니다.

이제 scapy 스크립트를 다시 실행해 보지만 아무것도 실행되지 않습니다. 호스트와 동일한 소스 주소를 사용하더라도 내 호스트나 서버의 tcpdump에는 아무것도 없습니다. 소스 주소를 변경해 보았지만 변경은 없었습니다. 기본 테이블에 10.0.26.0/24에 대한 기본 L3 경로를 다시 추가하면 scapy 스크립트가 다시 작동합니다. 내가 여기서 무엇을 놓치고 있는 걸까요? 생성된 트래픽이 내가 만든 IP 규칙 세트를 준수하지 않는 이유는 무엇입니까?

답변1

Scapy는 OS 라우팅 메커니즘을 사용하지 않고 오히려 Scapy가 시작될 때(또는 메소드가 호출될 conf.route때마다) OS 라우팅 테이블에서 동기화되는 자체 라우팅 테이블(객체)을 사용합니다.conf.route.resync()

Scapy의 라우팅 메커니즘은 설명하는 동작을 설명하는 소스 라우팅을 지원하지 않습니다.

관련 정보