Định tuyến đa đường trong hạt nhân sau 3.6


15

Như tất cả các bạn có thể biết, bộ đệm tuyến ipv4 đã bị xóa trong loạt kernel Linux Linux 3.6, ảnh hưởng nghiêm trọng đến định tuyến đa đường. Mã định tuyến IPv4 (không giống như IPv6) chọn hop tiếp theo theo kiểu vòng tròn, vì vậy các gói từ IP nguồn đã cho đến IP đích đã cho không luôn luôn đi qua cùng một bước tiếp theo. Trước 3.6, bộ đệm định tuyến đã sửa chữa tình huống đó, vì bước nhảy tiếp theo, một khi được chọn, sẽ nằm trong bộ đệm và tất cả các gói tiếp theo từ cùng một nguồn đến cùng đích sẽ đi qua bước nhảy tiếp theo. Bây giờ bước nhảy tiếp theo được chọn lại cho mỗi gói, điều này dẫn đến những điều kỳ lạ: với 2 tuyến mặc định chi phí bằng nhau trong bảng định tuyến, mỗi tuyến trỏ đến một nhà cung cấp internet, tôi thậm chí không thể thiết lập kết nối TCP, bởi vì SYN ban đầu và ACK cuối cùng đi qua các tuyến đường khác nhau,

Có cách nào tương đối dễ dàng để khôi phục hành vi thông thường của định tuyến đa đường, để bước nhảy tiếp theo được chọn trên mỗi luồng thay vì mỗi gói không? Có các bản vá xung quanh để làm cho IPv4 lựa chọn hop tiếp theo dựa trên hàm băm, giống như nó dành cho IPv6 không? Hoặc làm thế nào để tất cả các bạn đối phó với nó?


Bạn có thiết lập "truy cập phân chia" tương tự như ở đây không: lartc.org/howto/lartc.rpdb.mult Môn-links.html ? Nếu vậy, quy tắc và tuyến đường của bạn trông như thế nào?
the-wợi

thử sử dụng "ip route get 173.194.112.247" nhiều lần và đăng kết quả đầu ra
c4f4t0r

Cảm ơn câu hỏi ngon. :) trước hết, bạn đã không cho chúng tôi một ví dụ. Vì vậy, tôi cho rằng bạn có một cái gì đó giống như ip ro add 8.8.8.8/32 nexthop via 1.2.3.4 nexthop via 1.2.3.5là giả định chính xác?
poige

Có, điều đó đúng, nhưng thông thường, tuyến ip sẽ thêm 0.0.0.0/0 với nhiều bước nhảy tiếp theo.
Eugene

the-wợi, vâng, chính xác như thế. "Nhà cung cấp 1" và "nhà cung cấp 2" trong trường hợp của tôi là các bộ định tuyến biên được kết nối với mạng nội bộ và mạng của nhà cung cấp và họ có nguồn NAT. Trên bộ định tuyến nội bộ của tôi, tôi chỉ có cổng mặc định với 2 bước nhảy chỉ đến nhà cung cấp1 và nhà cung cấp2, không có tuyến nào khác. Các quy tắc tường lửa chỉ cho phép một số dịch vụ (như HTTP) cho các máy khách và chặn mọi thứ khác.
Eugene

Câu trả lời:


8

Nếu có thể, hãy nâng cấp lên Linux Kernel> = 4.4 ....

Định tuyến đa đường dựa trên băm đã được giới thiệu, theo nhiều cách là tốt hơn so với hành vi 3.6 trước. Nó dựa trên luồng, lấy một hàm băm của IP nguồn và đích (các cổng bị bỏ qua) để giữ đường dẫn ổn định cho các kết nối riêng lẻ. Một nhược điểm là tôi tin rằng có nhiều thuật toán / chế độ cấu hình khác nhau có sẵn trước 3.6, nhưng bây giờ bạn đã có được những gì bạn đã đưa ra!. Bạn có thể sử dụng ảnh hưởng đến sự lựa chọn của con đường weightmặc dù.

Nếu bạn ở trong hoàn cảnh của tôi thì bạn thực sự muốn 3.6 >= behaviour < 4.4nhưng nó không còn được hỗ trợ.

Nếu bạn nâng cấp lên> = 4.4 thì việc này sẽ thực hiện thủ thuật mà không cần tất cả các lệnh khác:

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

Hoặc bằng thiết bị:

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

Đối với bất kỳ ai đến với giải pháp này - hãy xem tại: net.ipv4.fib_multipath_use_neigh để tự động vô hiệu hóa "bỏ" nexthop / gateway.
Rostislav Kandilarov

6

"Tương đối dễ dàng" là một thuật ngữ khó, nhưng bạn có thể

  1. thiết lập các bảng định tuyến cho mỗi liên kết của bạn - một bảng cho mỗi liên kết, với một cổng mặc định duy nhất
  2. sử dụng bộ lọc mạng để đóng dấu giống hệt nhau trên tất cả các gói của một luồng
  3. sử dụng bảng quy tắc ip để định tuyến các gói thông qua các bảng định tuyến khác nhau tùy thuộc vào nhãn hiệu
  4. sử dụng tuyến có trọng số nhiều nexthop để cân bằng các gói đầu tiên trong phiên qua các cổng / liên kết của bạn.

Đã có một cuộc thảo luận tại danh sách gửi thư của netfilter về chủ đề này, nơi tôi đang đánh cắp các danh sách từ:

1. Quy tắc định tuyến (RPDB và 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. Quy tắc tường lửa (sử dụng ipset để buộc chế độ LB "chảy")

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

Bạn có thể muốn theo dõi cuộc thảo luận danh sách gửi thư của bộ lọc mạng cho một số biến thể ở trên.


Không chắc chắn, nhưng có thể đơn giản hơn để u32có được các tham số quan trọng được băm và sau đó "nhãn" được gán cho ip rule's
poige

Cảm ơn bạn, nhưng đó có vẻ là giải pháp khá phức tạp. Điều tôi không hiểu lắm là phần nào ở đây chịu trách nhiệm cho "đóng dấu giống hệt nhau trên tất cả các gói của một luồng"? Làm thế nào mà phép thuật ipset hoạt động? Tôi nghĩ rằng ipset chỉ là một tập hợp các IP cụ thể được băm và có thể được khớp với các quy tắc.
Eugene

Bạn đã đúng ipset- đó chỉ là tạo các bộ được lấp đầy bằng cách sử dụng --add-setvà khớp với việc sử dụng --match-set- nhưng điều này chủ yếu dành cho các kết nối ở trạng thái MỚI. Đối với các kết nối trạng thái THÀNH LẬP, dấu được đóng dấu trên các gói bằng cách sử dụng --restore-marktham số của CONNMARKđích - lệnh này sẽ sao chép dấu của kết nối vào gói. Dấu của kết nối được đặt trước đó bằng cách sử dụng --save-marktrong POSTROUTINGchuỗi (nơi các gói thuộc kết nối MỚI sẽ đi qua). Kịch bản có vẻ quá phức tạp với tôi, nhưng nó truyền đạt ý tưởng.
the-wợi

1
Vâng, bây giờ tôi đã có ý tưởng, tôi nghĩ. Câu hỏi cuối cùng: bạn có hiểu tại sao các nhà phát triển kernel không giới thiệu lựa chọn hop tiếp theo dựa trên hàm băm cho ipv4 không? Có một số lý do để không thực hiện nó cùng với loại bỏ bộ đệm tuyến đường? Giải pháp tương tự cho ipv6 hoạt động khá tốt. Không phải tất cả những điều đó có nghĩa là ma thuật quá mức cho một nhiệm vụ đơn giản như vậy sao?
Eugene

1
Thật không may @Eugene, tôi không đủ gần để phát triển ngăn xếp IP (hay nói chung là phát triển Kernel Linux) để trả lời một cách có thẩm quyền bất kỳ câu hỏi nào của bạn, nhưng tôi sẽ suy đoán rằng việc sử dụng nhiều nhà cung cấp khác nhau với IPv4 được coi là quá nhiều một trường hợp góc để đặt thêm bất kỳ công việc vào nó. Sử dụng các bộ lọc mạng bộ lọc rõ ràng trông giống như một loại bùn khó chịu, nhưng thậm chí có thể được coi là một "cách giải quyết có thể sử dụng" trong quyết định bỏ mã bộ đệm tuyến đường.
the-wợi
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.