한 인터페이스에서 다른 인터페이스로 ICMP 패킷의 소스 주소 변경

한 인터페이스에서 다른 인터페이스로 ICMP 패킷의 소스 주소 변경

내 상자에는 두 개의 이더넷 인터페이스가 있습니다. 작업 중인 시스템의 제한으로 인해 인터페이스 1의 소스 주소를 가지려면 모든 ICMP 응답 메시지가 필요합니다.

한 가지 예:

인터페이스 0에서 들어오는 TTL이 0인 패킷은 삭제되고 소스 주소가 0인 ICMP 응답이 생성되어 0에서 라우팅됩니다. TTL이 0인 다른 패킷이 인터페이스 1에서 들어오면 삭제되고 ICMP 응답이 생성됩니다. 소스 주소는 인터페이스 1이 아니라 인터페이스 0이어야 하며 여전히 인터페이스 1에서 라우팅되어야 합니다. 가능합니까?

두 인터페이스 중 하나에서 오는 다른 프로토콜의 소스 주소에 영향을 미치고 싶지 않습니다.

편집하다:

특정 상자에 대한 현재 설정은 다음과 같습니다.

IP-BR 링크

lo           UNKNOWN   00:00:00:00:00:00 <LOOPBACK, UP, LOWER_UP>
sit0@NONE    DOWN      0.0.0.0 <NOARP>
np0          UNKNOWN   <POINTTOPOINT,MULTICAST,NOARP,UP,LOWER_UP>
np1          UNKNOWN   <POINTTOPOINT,MULTICAST,NOARP,UP,LOWER_UP>
eth0         UP        <POINTTOPOINT,MULTICAST,NOARP,UP,LOWER_UP>

ip -4 -br 주소

lo           UNKNOWN   127.0.0.1/8
np0          UNKNOWN   192.0.0.1/24
np1          UNKNOWN   192.10.1.1/24
eth0         UP        193.10.1.1/24

IP 라우팅

default dev np1 scope linke
192.0.0.0/24 dev np0 proto kernel scope link src 192.0.0.1
192.10.1.0/24 dev np1 proto kernel scope link src 192.10.1.1
193.10.1.0/24 dev eth0 proto kernel scope link src 193.10.1.1

시스템이 VPN을 실행하도록 설정되어 있지 않습니다. 시스템에는 물리적 이더넷(eth0) 1개와 가상 이더넷 인터페이스(np0 및 np1) 2개가 있습니다.

위의 이름 지정을 사용하여 인터페이스 0을 eth0으로, 인터페이스 1을 np1로 설정합니다.

답변1

L4 프로토콜 기반 라우팅 규칙

리눅스커널 >= 4.17정책 라우팅은 IP의 레이어 4 프로토콜을 기반으로 수행될 수 있습니다.

  • 스포츠, dport 및IP 프로토타입 매칭(완전한 5튜플 매칭 지원) 데이터 센터의 정책 기반 라우팅에 대한 일반적인 사용 사례에는 5튜플 일치가 필요합니다.

[...]

처음에 시스템에서 생성된 모든 ICMP 응답(이름은상자) 원래 소스 노드로 돌아가면 호스트에서 해당 노드로 나가는 모든 트래픽과 마찬가지로 해당 소스를 향하는 인터페이스의 주소를 사용합니다.

# ip route get to 192.10.1.201
192.10.1.201 dev np1 src 192.10.1.1 uid 0 
    cache 
# ip route get to 193.10.1.200
193.10.1.200 dev eth0 src 193.10.1.1 uid 0 
    cache 

일반적으로 사용되는 것과 다른 암시적 소스 주소를 사용하여 관련 경로에 대해 중복되지만 수정된 항목을 표시하는 라우팅 테이블을 추가한 다음 라우팅 규칙을 사용하여 해당 라우팅 테이블을 선택할 수 있습니다. 단, 프로토콜이 ICMP인 경우에만 가능합니다. 이 라우팅 테이블은 주소와 (일반) 경로를 구성한 후에 채워야 추가가 불가능한 경로로 거부되지 않습니다. 항상 그렇듯이 어떤 이유로든 경로가 사라지면(예: 인터페이스가 다운되었다가 다시 나타나는 경우) proto kernel기본 라우팅 테이블의 경로와 달리 다시 추가되지 않습니다. 그럴 때마다 다시 추가해야 합니다. 이벤트가 발생합니다.

여기서 인터페이스에서 나오는 트래픽에 대한 중복 경로를 변경하는 동작은 np1다른 소스 주소(192.10.1.1 대신 193.10.1.1)를 암시합니다.

ip route add 192.10.1.0/24 dev np1 src 193.10.1.1 table 1000

재정의하려면 이 내용을 적용해야 합니다.기본ICMP 전용 테이블:

ip rule add pref 100 ipproto icmp lookup 1000

비ICMP 트래픽에는 변화가 없습니다 np1.

# ip route get to 192.10.1.201
192.10.1.101 dev np1 src 192.10.1.1 uid 0 
    cache 

그러나 ICMP 트래픽의 경우 np1:

# ip route get to 192.10.1.201 ipproto icmp
192.10.1.201 dev np1 table 1000 src 193.10.1.1 uid 0 
    cache 

따라서 OP 질문의 두 가지 경우가 모두 충족됩니다. ICMP(예: ICMP 시간 초과), 응답 여부에 관계없이 eth0힌트가 있는 주소에서 응답합니다.eth0np1

이는 ping과 같은 로컬로 시작된 ICMP에도 영향을 미칩니다(아래 참조).


참고 사항 및 세부정보

  • 경고: (레이어 2) 이더넷 인터페이스 및 ARP

    이더넷 인터페이스 의 경우 np1이러한 ICMP 오류에 의해 직접 트리거된 ARP 요청도 라우팅 규칙을 따르며 위에 192.10.1.1 대신 193.10.1.1에서 192.10.1.201을 요청하는 것으로 표시됩니다. 단, 노드에 ARP 항목이 없는 경우에만 해당됩니다. 기존의상자노드가 ARP 요청 자체를 구문 분석하지 않는 경우상자바로 직전(즉, 노드가 때때로 발생하는 경우에만 발생함)상자ARP 캐시에 있지만상자노드는 ARP 캐시에 없으며 일반적으로 그렇지 않습니다. 다른 Linux 시스템은 기본적으로 신경 쓰지 않습니다.호스트 모델기본적으로 이러한 ARP 요청을 수락합니다. 일부 다른 운영 체제에서는 이 "잘못된" ARP 요청에 관심을 갖고 응답하지 않을 수 있습니다.

    정말로 중요한 경우, 이미 희귀한 이 상태는 완전히 예방할 수 있습니다.arp_announce=1:

    - 1 - Try to avoid local addresses that are not in the target's
      subnet for this interface. [...]
    

    따라서 np1인터페이스의 경우:

    sysctl -w net.ipv4.conf.np1.arp_announce=1
    
  • ping명령은 변경된 소스 주소도 사용합니다.

    pingICMP 응답이 아니므로 평소대로 작동해야 합니다.

    실제로 문서화되지 않은 옵션의 영향을 받는 ICMP 유형(및 코드)을 제한할 수 있습니다. 소스에서 처리되는 방식에 따라 ICMP 유형 + 코드를 라우팅 규칙 선택기의 대상 포트에 매핑합니다.

    include/net/flow.h:

    union flowi_uli {
        struct {
            __be16  dport;
            __be16  sport;
        } ports;
    
        struct {
            __u8    type;
            __u8    code;
        } icmpt;
    
    
    union flowi_uli     uli;
    #define fl4_sport       uli.ports.sport
    #define fl4_dport       uli.ports.dport
    #define fl4_icmp_type       uli.icmpt.type
    #define fl4_icmp_code       uli.icmpt.code
    

    net/ipv4/fib_rules.c:

        if (fib_rule_port_range_set(&rule->dport_range) &&
            !fib_rule_port_inrange(&rule->dport_range, fl4->fl4_dport))
            return 0;
    

    공용체 덕분에 fl4->fl4_dport<=>는 전용 구문이 없는 유형 + 코드와 함께 사용할 fl4_icmp_type * 256 + fl4_icmp_code수 있습니다.ip rule ... ipproto icmp dport ...

    따라서 유형 8(ICMP 요청) 이외의 것으로 제한하는 것은 0-7 + 9-255로 제한하는 것을 의미합니다. 256을 곱하고 충분한 종료 간격(+255)으로 조정하면 1-2047이 됩니다(0은 유효하지 않으며 1부터 시작함). 유형 0 코드 0의 ICMP 응답은 일치하지 않지만 일치할 필요는 없습니다. 실제로 응답되기 때문에 암시된 원본은 사용되지 않으며 대신 원격 ICMP 요청에 사용되는 실제 로컬 대상이 사용되며 응답 원본으로 사용됩니다) + 2304-65534 (65535 ditto). 원래 라우팅 규칙으로 시작합니다.

    ip rule add pref 100 ipproto icmp lookup 1000
    
    • 두 가지 규칙으로 바꾸십시오.

      ip rule del pref 100
      
      ip rule add pref 100 ipproto icmp dport 1-2047 lookup 1000
      ip rule add pref 101 ipproto icmp dport 2304-65534 lookup 1000
      
    • 또는 초기 규칙을 유지하고 건너뛰도록 규칙을 추가합니다(ICMP Echo 요청에는 항상 코드 0이 있으므로 2048로 단순화할 수 있음).

      ip rule del pref 100
      ip rule del pref 101
      
      ip rule add pref 100 ipproto icmp lookup 1000
      ip rule add pref 101 lookup 424242
      ip rule add pref 99 ipproto icmp dport 2048-2303 goto 101
      

    어느 것을 선택하든 ping명령은 다시 변경되지 않습니다.

    # ip route get to 192.10.1.201 ipproto icmp dport 2048
    192.10.1.201 dev np1 src 192.10.1.1 uid 0 
        cache 
    

    ICMP 리디렉션(유형 5)은 비슷한 방식으로 예외에 추가되어야 합니다.

관련 정보