여러 업링크/공급업체에 대한 라우팅

여러 업링크/공급업체에 대한 라우팅

두 개의 인터넷 연결이 가능한 컴퓨터가 있습니다. 첫 번째는 로컬 네트워크에 연결하고 라우터를 통해 인터넷에 액세스하는 데 사용되는 이더넷 인터페이스입니다. 두 번째는 ppp 연결이 있는 GSM 모뎀을 사용합니다.

다음과 같이 인터페이스를 지정할 때 각 연결을 독립적으로 사용할 수 있기를 원합니다.

ping -I eth0 www.google.com
ping -I ppp0 www.google.com

인터페이스를 선택하지 않고 eth0을 통한 연결이 작동하면 기본값은 eth0을 사용하는 것이지만 eth0을 통한 연결이 작동하지 않으면 ppp0이 사용됩니다.

나는 이것을 읽었다기사그리고 다음 규칙을 만들었습니다.

# Main table
ip route add 10.0.0.0/24 dev eth0 src 10.0.0.100
ip route add 10.64.64.64 dev ppp0 src 10.123.122.101
ip route add default via 10.0.0.1

# Specific tables
ip route add 10.0.0.0/24 dev eth0 src 10.0.0.100 table eth0
ip route add default via 10.0.0.1 table eth0
ip route add 10.64.64.64 dev ppp0 src 10.123.122.101 table ppp0
ip route add default via 10.64.64.64 table ppp0

# Rules
ip rule add from 10.0.0.100 table eth0
ip rule add from 10.123.122.101 table ppp0

언뜻 보면 작동하는 것 같습니다. 그러나 eth0 테이블은 절대 사용되지 않는 것 같습니다. 나는 다음과 같은 일이 일어날 것으로 예상합니다.

ping -I eth0 www.google.ch    # Use default gateway in table eth0
ping -I ppp0 www.google.ch    # Use default gateway in table ppp0
ping www.google.ch            # Use default gateway (main)

그러나 기본 게이트웨이(기본)를 제거하면 eth0 인터페이스가 전혀 작동하지 않습니다. 분명히 내가 이해하지 못하는 것이 있습니다. 내가 원하는 것을 달성하는 방법을 설명해 주시겠습니까?

@derobert의 답변을 바탕으로 편집하십시오.

다음 구성을 테스트했지만 여전히 동일한 오류가 발생합니다(ppp0에서는 작동하지만 eth0에서는 작동하지 않음).

노선:

# ip rule list
0:      from all lookup local
1500:   from 10.0.0.100 lookup eth0
1501:   from 10.123.122.101 lookup ppp0
2000:   from all fwmark 0x1 lookup eth0
2001:   from all fwmark 0x2 lookup ppp0
32766:  from all lookup main
32767:  from all lookup default

# ip route list table eth0
10.0.0.0/24 dev eth0  src 10.0.0.100
default via 10.0.0.1 dev eth0

# ip route list table ppp0
10.64.64.64 dev ppp0  src 10.123.122.101
default via 10.64.64.64 dev ppp0

# ip route list table main
10.64.64.64 dev ppp0  src 10.123.122.101
192.168.1.0/24 dev eth1  src 192.168.1.1
10.0.0.0/24 dev eth0  src 10.0.0.100

방화벽:

# iptables -L
Chain INPUT (policy DROP)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

# iptables -L -t mangle
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination
CONNMARK   all  --  anywhere             anywhere            CONNMARK restore
RETURN     all  --  anywhere             anywhere            mark match !0x0
MARK       all  --  anywhere             anywhere            MARK set 0x1
MARK       all  --  anywhere             anywhere            MARK set 0x2

Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination
MARK       all  --  anywhere             anywhere            MARK set 0x1
MARK       all  --  anywhere             anywhere            MARK set 0x2
CONNMARK   all  --  anywhere             anywhere            CONNMARK save

# iptables -L -t nat
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination
SNAT       all  --  10.0.0.1             anywhere            to:10.0.0.100
SNAT       all  --  10.64.64.64          anywhere            to:10.123.122.101

방해가 되지 않도록 다른 모든 방화벽 규칙을 제거했습니다. 나는 다음과 같은 결과를 얻습니다.

# ip route get 8.2.1.1 from 10.0.0.100
8.2.1.1 from 10.0.0.100 via 10.0.0.1 dev eth0

# ip route get 8.2.1.1 from 10.123.122.101
8.2.1.1 from 10.123.122.101 via 10.64.64.64 dev ppp0

# ping -I ppp0 8.8.8.8
PING 8.8.8.8 (8.8.8.8): 56 data bytes
64 bytes from 8.8.8.8: seq=0 ttl=45 time=350.108 ms
64 bytes from 8.8.8.8: seq=1 ttl=45 time=349.768 ms
64 bytes from 8.8.8.8: seq=2 ttl=45 time=329.671 ms
^C
--- 8.8.8.8 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 329.671/343.182/350.108 ms

128# ping -I eth0 8.8.8.8
PING 8.8.8.8 (8.8.8.8): 56 data bytes
^C
--- 8.8.8.8 ping statistics ---
5 packets transmitted, 0 packets received, 100% packet loss

규칙은 괜찮은 것 같았지만 또 다른 문제가 있었던 것 같습니다. 여기서 SNAT의 역할을 잘 이해하지 못합니다. 답변 구성을 반영하기 위해 규칙을 추가했지만 잘못되었을 수 있습니다.

답변1

내 구성은 약간 더 복잡하며 시스템의 NAT 및 동적(내부) 라우팅도 포함합니다.

여러 부분이 있습니다. 규칙부터 시작해 보겠습니다.

Maginot:~# ip rule ls
0:      from all lookup local 
1000:   from all lookup main 
1500:   from 173.167.51.136/29 lookup comcast 
1501:   from 76.160.165.106/29 lookup cavtel 
1502:   from 151.200.251.90/31 lookup vzdsl 
1502:   from 151.200.251.92/31 lookup vzdsl 
1502:   from 151.200.251.94 lookup vzdsl 
2000:   from all fwmark 0x1 lookup comcast 
2001:   from all fwmark 0x2 lookup cavtel 
2002:   from all fwmark 0x3 lookup vzdsl 
2500:   from all lookup comcast 
2501:   from all lookup cavtel 
2502:   from all lookup vzdsl 
32767:  from all lookup default 

(이 테이블의 이름은 에 있습니다 /etc/iproute2/rt_tables.)

보시다시피 현재 우리는 3개의 ISP를 보유하고 있으며 각 ISP에는 여러 개의 고정 IP 주소가 있습니다. 규칙 1500-1502는 이러한 소스 IP 주소에서 적절한 인터페이스로 트래픽을 보냅니다. 규칙 2000-2002는 지정된 방화벽 태그(이에 대해서는 설명하겠습니다)가 포함된 트래픽을 적절한 인터페이스로 보냅니다. 규칙 2500-2502는 아직 ISP에 할당되지 않은 트래픽에 대해 ISP의 우선순위를 부여합니다. 그 중 하나가 실패하면 해당 규칙을 삭제하고 목록의 다음 규칙을 사용할 수 있습니다.

각 라우팅 테이블은 매우 간단합니다.

Maginot:~# ip route ls table comcast
default via 173.167.51.142 dev comcast 

(로컬과 메인에는 더 많은 콘텐츠가 있지만 각각 직접 연결과 내부 경로입니다. 테이블은 기본적으로 비어 있습니다.)

다음으로, 연결이 ISP에 할당되면 해당 연결이 그대로 유지되는 것이 중요합니다(수신 연결 포함). 각 인터페이스마다 IP 주소가 다르고 ISP가 실제로 역방향 경로 필터링을 갖추고 있기 때문에 이동을 시도하는 것은 불가능합니다. 방화벽 규칙을 사용하여 동일한 ISP에 유지합니다.

SNAT가 완료되었음을 기억하세요뒤쪽에라우팅하므로 ip rule전략이 도움이 되지 않습니다. 다른 것을 사용해야 합니다(어쩌면 그게 문제일까요?)

iptables -t mangle -A PREROUTING -j CONNMARK --restore-mark
iptables -t mangle -A PREROUTING -m mark ! --mark 0 -j RETURN # if already set, we're done
iptables -t mangle -A PREROUTING -i wan                                       -j MARK --set-mark $MARK_CAVTEL
iptables -t mangle -A PREROUTING -i comcast                                   -j MARK --set-mark $MARK_COMCAST
iptables -t mangle -A PREROUTING -i vz-dsl                                    -j MARK --set-mark $MARK_VZDSL

iptables -t mangle -A POSTROUTING -o wan     -j MARK --set-mark $MARK_CAVTEL
iptables -t mangle -A POSTROUTING -o comcast -j MARK --set-mark $MARK_COMCAST
iptables -t mangle -A POSTROUTING -o vz-dsl  -j MARK --set-mark $MARK_VZDSL
iptables -t mangle -A POSTROUTING -j CONNMARK --save-mark

이는 이를 설정하는 쉘 스크립트에서 가져온 것입니다. 변수는 $MARK_…위의 규칙에서 본 태그와 일치합니다. 매우 간단합니다. 연결 태그를 복원합니다(태그는 패킷 단위라는 점을 기억하세요). 이제 (연결 태그에서) 태그가 있으면 작업이 완료된 것입니다. 그렇지 않으면 관련된 인터페이스에 따라 플래그가 설정됩니다.

마크가 복원됩니다.앞으로경로를 지정하고 나중에만 저장하세요. 그리고 어쨌든 플래그는 나가는 인터페이스로 설정됩니다(논쟁의 여지가 있음).

마지막으로 실제 NAT 규칙이 있습니다. 여러 로컬 접두사가 있습니다. 이 코드는 for 루프에서 실행되고 $local각 접두사에 대해 설정됩니다.

iptables -t nat -A POSTROUTING -s $local -o wan     -j SNAT --to-source 76.160.165.106
iptables -t nat -A POSTROUTING -s $local -o comcast -j SNAT --to-source 173.167.51.137
iptables -t nat -A POSTROUTING -s $local -o vz-dsl  -j SNAT --to-source 151.200.251.90

(참고: 일부 DMZ 서버의 DNAT 등 더 많은 규칙이 있습니다. 관련 항목은 모두 복사한 것 같습니다.)

답변2

eth0 장치의 가중치를 ppp0 장치보다 높은 우선순위로 설정해야 합니다.

예:

ip route append default scope global nexthop via 10.0.0.1 dev eth0 weight 2 nexthop via 10.64.64.65 dev ppp0 weight 3

관련 정보