3.6 이후 커널에서의 다중 경로 라우팅


16

모두 알다시피 ipv4 라우트 캐시는 3.6 Linux 커널 시리즈에서 제거되어 다중 경로 라우팅에 심각한 영향을 미쳤습니다. IPv6 라우팅 코드 (IPv6와 달리)는 라운드 로빈 방식으로 다음 홉을 선택하므로 지정된 소스 IP에서 지정된 대상 IP 로의 패킷이 항상 동일한 다음 홉을 통과하지는 않습니다. 3.6 이전에 라우팅 캐시는 일단 선택된 다음 홉이 캐시에 머무르면서 동일한 상황에서 동일한 소스로의 모든 추가 패킷이 다음 홉을 통과하는 상황을 수정했습니다. 이제 각 패킷에 대해 다음 홉이 다시 선택되어 이상한 일이 발생합니다. 라우팅 테이블에 동일한 비용의 기본 경로가 각각 하나의 인터넷 공급자를 가리키는 경우 초기 SYN 및 최종 ACK 때문에 TCP 연결을 설정할 수도 없습니다. 다른 경로를 통해 이동

다중 경로 라우팅의 정상적인 동작을 복원하여 패킷 당이 아닌 플로우 당 다음 홉이 선택되도록 비교적 쉬운 방법이 있습니까? IPv6에서와 같이 IPv4 다음 홉 선택을 해시 기반으로 만드는 패치가 있습니까? 아니면 어떻게 다룰까요?


다음과 유사한 "분할 액세스"설정이 있습니까 : lartc.org/howto/lartc.rpdb.multiple-links.html ? 그렇다면 규칙 세트와 경로는 어떻게 생겼습니까?
the-wabbit 2016 년

"ip route get 173.194.112.247"를 여러 번 사용하고 출력을 게시하십시오
c4f4t0r

맛있는 질문 감사합니다. :) 우선, 당신은 우리에게 예제를주지 않았습니다. 그래서 당신이 그와 같은 가정을 가지고 있다고 ip ro add 8.8.8.8/32 nexthop via 1.2.3.4 nexthop via 1.2.3.5가정합니다.
poige

예, 맞습니다. 그러나 일반적으로 IP 경로는 다음 홉이 여러 개인 0.0.0.0/0입니다.
유진

맞아요. 정확히 그렇습니다. 필자의 경우 "제공자 1"및 "제공자 2"는 내부 네트워크 및 제공자의 네트워크에 연결된 보더 라우터이며 소스 NAT를 수행합니다. 내부 라우터에는 2 개의 홉이 provider1 및 provider2를 가리키는 기본 게이트웨이가 있으며 다른 경로는 없습니다. 방화벽 규칙은 클라이언트 시스템에 대한 일부 서비스 (예 : HTTP)를 허용하고 다른 모든 것을 차단합니다.
유진

답변:


8

가능하면 Linux Kernel> = 4.4 ...로 업그레이드하십시오.

해시 기반 다중 경로 라우팅 이 도입되었으며, 이는 여러 가지면에서 3.6 이전의 동작보다 낫습니다. 개별 연결에 대한 경로를 안정적으로 유지하기 위해 소스 및 대상 IP의 해시 (포트는 무시 됨)를 사용하는 흐름 기반입니다. 한 가지 단점은 3.6 이전에 사용 가능한 다양한 알고리즘 / 구성 모드가 있다고 생각하지만 이제 주어진 것을 얻습니다!. weight그래도 경로 선택에 영향을 줄 수 있습니다 .

내 상황 에 있다면 실제로 원 3.6 >= behaviour < 4.4하지만 더 이상 지원되지 않습니다.

> = 4.4로 업그레이드하면 다른 모든 명령없이 트릭을 수행해야합니다.

ip route add default  proto static scope global \
nexthop  via <gw_1> weight 1 \
nexthop  via <gw_2> weight 1

또는 장치별로 :

ip route add default  proto static scope global \
 nexthop  dev <if_1> weight 1 \
 nexthop  dev <if_2> weight 1

이 솔루션을 찾는 사람은 net.ipv4.fib_multipath_use_neigh를 참조하여 "삭제 된"nexthop / gateway를 자동으로 비활성화하십시오.
Rostislav Kandilarov

6

"상대적으로 쉬운"은 어려운 용어이지만

  1. 단일 기본 게이트웨이를 사용하여 각 링크에 대한 라우팅 테이블 설정 (링크 당 하나의 테이블)
  2. netfilter를 사용하여 단일 스트림의 모든 패킷에서 동일한 마크를 찍습니다.
  3. IP 규칙 테이블을 사용하여 마크에 따라 다른 라우팅 테이블을 통해 패킷을 라우팅
  4. 게이트웨이 / 링크를 통해 세션 내 첫 패킷의 균형을 맞추려면 멀티 넥스트 가중치 가중 경로를 사용하십시오.

이 항목에 대한 netfilter 메일 링리스트 에서 목록 을 훔치는 토론 이있었습니다 .

1. 라우팅 규칙 (RPDB 및 FIB)

ip route add default via <gw_1> lable link1
ip route add <net_gw1> dev <dev_gw1> table link1
ip route add default via <gw_2> table link2
ip route add <net_gw2> dev <dev_gw2> table link2

/sbin/ip route add default  proto static scope global table lb \
 nexthop  via <gw_1> weight 1 \
 nexthop  via <gw_2> weight 1

ip rule add prio 10 table main
ip rule add prio 20 from <net_gw1> table link1
ip rule add prio 21 from <net_gw2> table link2
ip rule add prio 50 fwmark 0x301 table link1
ip rule add prio 51 fwmark 0x302 table link2
ip rule add prio 100 table lb

ip route del default

2. 방화벽 규칙 (ipset을 사용하여 "흐름"LB 모드 강제 적용)

ipset create lb_link1 hash:ip,port,ip timeout 1200
ipset create lb_link2 hash:ip,port,ip timeout 1200

# Set firewall marks and ipset hash
iptables -t mangle -N SETMARK
iptables -t mangle -A SETMARK -o <if_gw1> -j MARK --set-mark 0x301
iptables -t mangle -A SETMARK -m mark --mark 0x301 -m set !
--match-set lb_link1 src,dstport,dst -j SET \
          --add-set lb_link1 src,dstport,dst
iptables -t mangle -A SETMARK -o <if_gw2> -j MARK --set-mark 0x302
iptables -t mangle -A SETMARK -m mark --mark 0x302 -m set !
--match-set lb_link2 src,dstport,dst -j SET \
          --add-set lb_link2 src,dstport,dst

# Reload marks by ipset hash
iptables -t mangle -N GETMARK
iptables -t mangle -A GETMARK -m mark --mark 0x0 -m set --match-set
lb_link1 src,dstport,dst -j MARK --set-mark 0x301
iptables -t mangle -A GETMARK -m mark --mark 0x0 -m set --match-set
lb_link2 src,dstport,dst -j MARK --set-mark 0x302

# Defining and save firewall marks
iptables -t mangle -N CNTRACK
iptables -t mangle -A CNTRACK -o <if_gw1> -m mark --mark 0x0 -j SETMARK
iptables -t mangle -A CNTRACK -o <if_gw2> -m mark --mark 0x0 -j SETMARK
iptables -t mangle -A CNTRACK -m mark ! --mark 0x0 -j CONNMARK --save-mark
iptables -t mangle -A POSTROUTING -j CNTRACK

# Reload all firewall marks
# Use OUTPUT chain for local access (Squid proxy, for example)
iptables -t mangle -A OUTPUT -m mark --mark 0x0 -j CONNMARK --restore-mark
iptables -t mangle -A OUTPUT -m mark --mark 0x0 -j GETMARK
iptables -t mangle -A PREROUTING -m mark --mark 0x0 -j CONNMARK --restore-mark
iptables -t mangle -A PREROUTING -m mark --mark 0x0 -j GETMARK

위의 일부 변형에 대해서는 netfilter 메일 링리스트 토론을 따르고 싶을 수도 있습니다.


확실하지,하지만하는 것이 더 간단 할 수있는 u32중요한 매개 변수는 해시하고 얻을 다음에 할당 "라벨" ip rule
poige

고맙지 만, 그것은 매우 복잡한 해결책처럼 보입니다. 내가 이해하지 못하는 것은 여기에서 "단일 스트림의 모든 패킷에 동일한 마크를 찍는"부분을 담당하는 부분은 무엇입니까? 그 ipset 마술은 어떻게 작동합니까? ipset은 해시되어 규칙과 일치 할 수있는 특정 IP 세트 일뿐이라고 생각했습니다.
유진

당신은 맞습니다 ipset-그것은 사용하여 채워지고 사용되는 --add-set것과 일치 하는 세트를 만드는 것입니다 --match-set-그러나 이것은 대부분 NEW 상태의 연결에 대한 것입니다. ESTABLISHED 상태 연결 --restore-mark의 경우 CONNMARK대상 의 매개 변수를 사용하여 마크에 패킷에 스탬프가 찍 힙니다. 이 지시문은 연결 마크를 패킷에 복사합니다. 연결 마크는 이전 --save-markPOSTROUTING체인을 사용하여 설정됩니다 (새로운 연결에 속하는 패킷이 통과하는 위치). 대본이 지나치게 복잡해 보이지만 아이디어를 전달합니다.
the-wabbit

1
예, 이제 아이디어가 생겼습니다. 마지막 질문 : 커널 개발자가 왜 ipv4에 해시 기반 다음 홉 선택을 도입하지 않는지 이해합니까? 라우트 캐시 제거와 함께 구현하지 않는 이유가 있습니까? ipv6에 대한 비슷한 솔루션은 꽤 잘 작동합니다. 그런 수수께끼의 마술이 그렇게 간단한 일을하는 데 지나치지 않습니까?
유진

1
@Eugene 불행히도, 나는 IP 스택 개발 (또는 일반적으로 Linux Kernel 개발)에 가깝기 때문에 귀하의 질문에 권위있게 답할 수는 없지만 IPv4로 다른 공급자를 사용하는 다중 경로는 너무 많은 것으로 간주됩니다 더 이상 작업 할 수있는 코너 케이스. netfilter CONNMARKs를 사용하는 것은 분명히 더러운 멍청이처럼 보이지만 라우트 캐시 코드 삭제 결정에서 "사용 가능한 해결 방법"으로 간주되었을 수도 있습니다.
the-wabbit
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.