"ip" 명령을 사용하여 경로를 생성할 때 전역 범위가 유효하지 않은 이유는 무엇입니까?

"ip" 명령을 사용하여 경로를 생성할 때 전역 범위가 유효하지 않은 이유는 무엇입니까?

고정 NAT를 생성하려고 하는데 명령을 실행하면 ip route add nat 172.31.19.02 via 10.0.2.2오류가 발생 Error: Invalid scope.하고 전역 범위를 지정할 때에도 동일한 오류가 발생합니다. 위에 설명된 내용을 재현하려고 합니다.상태 비저장 NAT에 iproute2 사용페이지.

내 네트워크 설정은 동일한 서브넷에 있는 두 개의 물리적 인터페이스(ens5, ens6)와 내 Tinc VPN(VPN)용 가상 인터페이스로 구성됩니다. 주소 10.0.2.2는 Tinc 인터페이스에서 액세스할 수 있습니다. 목표는 에서 로 트래픽을 전달하는 것 172.31.19.02입니다 10.0.2.2.

내가 아는 한IP 주소문서 페이지는 global"어디서나 유효"해야 합니다. 이것이 잘못된 것입니까?

관련 부분 ip a:

2: ens5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether [...]
    inet 172.31.19.01/20 brd 172.31.31.255 scope global ens5
       valid_lft forever preferred_lft forever
[...]
3: ens6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether [...]
    inet 172.31.19.02/20 brd 172.31.31.255 scope global ens6
       valid_lft forever preferred_lft forever
[...]
4: vpn: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 500
    link/none
    inet 10.0.2.1/24 scope global homeforward
       valid_lft forever preferred_lft forever
[...]

내 라우팅 테이블:

$ ip r
default via 172.31.16.1 dev ens5 proto static
10.0.2.0/24 dev homeforward proto kernel scope link src 10.0.2.1
172.31.16.0/20 dev ens6 proto kernel scope link src 172.31.19.02
172.31.16.0/20 dev ens5 proto kernel scope link src 172.31.19.01
$ ip r ls table 1000
default via 172.31.16.1 dev ens5 proto static
172.31.19.01 dev ens5 proto static scope link
$ ip r ls table 1001
default via 172.31.16.1 dev ens6 proto static
172.31.19.02 dev ens6 proto static scope link

답변1

Linux의 라우팅된 상태 비저장 NAT(일명 "IP NAT dumb")는 다음과 같은 간단한 이유로 더 이상 작동하지 않습니다.매뉴얼 페이지말하다:

경고: 라우팅된 NAT는 Linux 2.6에서 더 이상 지원되지 않습니다.

그래서 이와 같은 예를 들면이것:

[root@masq-gw]# ip route add nat 205.254.211.17 via 192.168.100.17
[root@masq-gw]# ip rule add nat 205.254.211.17 from 192.168.100.17
[root@masq-gw]# ip route flush cache
[root@masq-gw]# ip route show table all | grep ^nat
nat 205.254.211.17 via 192.168.100.17  table local  scope host
[root@masq-gw]# ip rule show
0:      from all lookup local 
32765:  from 192.168.100.17 lookup main map-to 205.254.211.17 
32766:  from all lookup main 
32767:  from all lookup 253

더 이상 작동하지 않습니다.

이 기능은 커널에 추가되었습니다2.1.15(1996) 및커널 2.6.9에서 제거됨(2004) (그러나 아마도 이전의 일부 커널일 수도 있음):

<[email protected]>
  [IPV4]: Kill remnant of ip_nat_dumb

  This line in net/ipv4/Makefile was left behind when the rest of the
  dumb NAT option was taken out.

  Signed-off-by: Herbert Xu <[email protected]>
  Signed-off-by: David S. Miller <[email protected]>

이것설명하다대체 상태 비저장 NAT에서 제공되는 경우 다음을 사용합니다.tc nat커널 2.6.24에 다시 추가되었습니다:

이전에는 IPv4 라우팅 하위 시스템에 통합된 상태 비저장 NAT 기능이 있었습니다. NAT가 서브넷 간 기반으로 작동하므로 NAT 규칙의 수가 상대적으로 적다면 이는 좋은 솔루션입니다. 그 이유는 SNAT의 경우 경로 기반 시스템이 규칙을 통해 선형 스캔을 수행해야 하기 때문입니다.

규칙 수가 많은 경우 이를 실현하려면 라우팅 하위 시스템을 크게 수정해야 합니다.


TC

이것은기초적인제가 만든 DNAT 예시입니다. 상태 비저장 NAT를 수행하기 위한 인터페이스는 다음과 같습니다. ens5(동일한 LAN에 두 개의 네트워크 카드가 있는 설정을 사용하지 않을 것입니다. 추가 설정이 없으면 다음과 관련된 다른 문제가 발생합니다.ARP 플럭스및 역방향 경로 필터링. 추가 라우팅 테이블이 있기 때문에 이미 알고 있는 것 같지만 이 예를 간단하게 유지하겠습니다. 해당 테이블의 로컬 주소는 172.31.19.1 및 172.31.19.2입니다. 어느입구172.31.19.2에 대한 트래픽은 대상 10.0.2.2에 DNATed되어 있습니다.출구10.0.2.2의 트래픽은 소스 172.31.19.2로 SNAT됩니다. 평소에 하던대로,프리오큐 디스크선호하는 속성 때문이 아니라 단순성 때문에 사용하십시오.

tc qdisc add dev ens5 ingress
tc filter add dev ens5 ingress protocol ip matchall \
   action nat ingress 172.31.19.2/32 10.0.2.2/32

tc qdisc add dev ens5 root handle 1: prio
tc filter add dev ens5 parent 1: protocol ip matchall \
   action nat egress 10.0.2.2/32 172.31.19.2/32

netfilter의 상태 저장 연결 추적과 예상치 못한 상호 작용이 발생할 수 있습니다.


nftables

nftables를 사용하여 동일한 작업을 수행할 수도 있습니다.nftables 위키.

nft add table ip natdumb

nft add chain ip natdumb prerouting '{ type filter hook prerouting priority -350; policy accept; }'
nft add rule ip natdumb prerouting ip daddr 172.31.19.2 ip daddr set 10.0.2.2

nft add chain ip natdumb postrouting '{ type filter hook postrouting priority 350; policy accept; }'
nft add rule ip natdumb postrouting ip saddr 10.0.2.2 ip saddr set 172.31.19.2

마찬가지로 netfilter의 conntrack과 상호작용이 있을 수 있습니다. netfilter NAT 커널 모듈이 로드되지 않았거나 적어도 현재 네임스페이스에서 활성화된 경우(대신 모든 응답 패킷을 스트림 으로 처리하는 동안 ) notrack작동하게 만들 수 있는 모든 항목을 제거했습니다 . 부담 없이 시도해 보세요.notrackNEWESTABLISHED

답변2

경로를 추가할 때 커널은 동일한 L2(데이터 링크 계층) 연결에서 라우팅 게이트웨이에 직접 연결할 수 있어야 하므로 더 낮은 범위를 통해 새 범위에 도달할 수 있는지 확인합니다.

이 답변(https://superuser.com/a/1389304)에는 이 범위 개념과 이를 설정해야 하는 이유/시기에 대해 빠르고 명확하게 설명되어 있습니다.

이러한 경로는 현재 있는 서브넷을 Linux 커널에 알려주는 방법입니다.

IP 주소를 추가하면 이 정보는 숨겨진 내 현재 서브넷 필드에 저장되지 않고 숨겨진 내 현재 서브넷 필드에 저장됩니다. 대신, 지정된 게이트웨이 없이 항상 "범위 링크" 경로("장치 경로" 또는 "인터페이스 경로"라고도 함)로 변환되며 커널이 주소에 직접 연결할 수 있는지 여부를 확인해야 할 때마다 단순히 경로를 수행합니다. 테이블체크.

일반적으로 이러한 경로는 IP 주소를 구성하면 자동으로 추가됩니다. 예를 들어 ip addr add 192.168.1.5/24를 실행하면 IP 주소 192.168.1.5가 할당되고 192.168.1.0/24에 대한 서브넷 경로가 생성됩니다. 따라서 일반적인 사용 중에는 이러한 경로를 추가할 필요가 없습니다.

그러나 맹목적으로 "모든 경로를 제거"하면 자동으로 생성된 경로도 제거되고 커널의 "내 서브넷에 있는 이 주소는 무엇입니까?" 확인이 더 이상 작동하지 않습니다. 이것이 결국 경로를 수동으로 다시 추가해야 하는 이유입니다.

(라우팅 게이트웨이(다음 홉)는 동일한 L2 연결에서 직접 연결할 수 있어야 하며 다른 게이트웨이 뒤에 있을 수 없기 때문에 커널은 IP 경로 추가 중에 이 확인을 수행해야 합니다. 즉, 게이트웨이는 서브넷에 있어야 합니다.

경로 범위는 이러한 제한을 표현하는 일반적인 메커니즘입니다. 새 경로의 다음 홉은 범위가 더 낮은 기존 경로를 통해 도달할 수 있어야 합니다. 즉, 원격 호스트(전역 범위)에 도달하기 전에 로컬 호스트(링크 범위)를 거쳐야 합니다. )

편집하다:

하지만 그것만으로는 충분하지 않습니다. 테스트 환경에서 실행하려고 노력했지만 지금까지는 성공하지 못했습니다. Error: Invalid scope.그것도 계속해서 일어나고 있어요.

관련 정보