Buộc lưu lượng IP cục bộ vào giao diện bên ngoài


31

Tôi có một máy với một số giao diện mà tôi có thể cấu hình như tôi muốn, ví dụ:

  • eth1: 192.168.1.1
  • eth2: 192.168.2.2

Tôi muốn chuyển tiếp tất cả lưu lượng được gửi đến một trong những địa chỉ cục bộ này thông qua giao diện khác. Chẳng hạn, tất cả các yêu cầu đến máy chủ iperf, ftp, http tại 192.168.1.1 không chỉ được định tuyến nội bộ mà còn được chuyển tiếp qua eth2 (và mạng bên ngoài sẽ đảm nhiệm việc định tuyến lại gói đến eth1).

Tôi đã thử và xem xét một số lệnh, như iptables, ip route, v.v ... nhưng không có gì hoạt động.

Hành vi gần nhất tôi có thể nhận được là:

ip route change to 192.168.1.1/24 dev eth2

gửi tất cả 192.168.1.x trên eth2, ngoại trừ 192.168.1.1 vẫn được định tuyến nội bộ. Sau đó tôi có thể chuyển tiếp NAT tất cả lưu lượng truy cập sang giả mạo 192.168.1.2 trên eth1, được định tuyến lại thành 192.168.1.1 không? Tôi thực sự đang vật lộn với iptables, nhưng nó quá khó đối với tôi.

Mục tiêu của thiết lập này là để kiểm tra trình điều khiển giao diện mà không cần sử dụng hai PC.

Tôi đang sử dụng Linux, nhưng nếu bạn biết cách làm điều đó với Windows, tôi sẽ mua nó!

Biên tập:

Mạng bên ngoài chỉ là một cáp chéo giữa eth1 và eth2. Giả sử tôi có một máy chủ http trên máy của mình. Bây giờ tôi muốn truy cập máy chủ này từ cùng một máy, nhưng tôi muốn buộc lưu lượng TCP / IP đi qua cáp eth1 / eth2 này. Làm thế nào tôi nên cấu hình giao diện của tôi cho điều này?


Bạn có nói rằng bạn muốn tất cả lưu lượng được nhân đôi thông qua giao diện 1 và 2 nhưng chỉ được trả về giao diện 2 từ một bộ định tuyến khác? Không thể làm một số thứ khá kỳ lạ trên mạng? Sẽ tốt hơn nếu điều hướng lưu lượng được nhân đôi từ giao diện 2 sang hệ thống khác vừa giảm lưu lượng và sau đó bạn có thể theo dõi nó, hoặc sử dụng phần mềm ảo hóa để nắm bắt lưu lượng? Có lẽ tôi đang thiếu một cái gì đó trong mô tả.
Bart Silverstrim

Có vẻ như anh ta muốn tạo một gói tin, giả sử 192.168.1.1 là IP của eth1. Nhưng thay vì ngăn xếp Linux nhận gói tin đó hoàn toàn bên trong, anh ta muốn gói bị loại ra eth2 (sẽ được gửi bên ngoài trở lại vào eth1 và sau đó là ngăn xếp Linux). Tôi không chắc nếu điều này là có thể; một khi lớp mạng phát hiện địa chỉ là một giao diện bên trong, nó sẽ có ít lý do để xem xét các bảng định tuyến. Một số người khác có thể biết tốt hơn.
PP.

Câu trả lời:


15

Tôi đã mở rộng câu trả lời của caladona vì tôi không thể thấy các gói phản hồi. Ví dụ này:

  1. Trên PC cục bộ của tôi, tôi có các NIC trên các mạng con khác nhau, 192.168.1 / 24 , 192.168.2 / 24
  2. Có một bộ định tuyến / PC bên ngoài có quyền truy cập vào cả hai mạng con.
  3. Tôi muốn gửi lưu lượng truy cập hai chiều qua các NIC trên PC cục bộ.
  4. Cấu hình yêu cầu hai địa chỉ IP không sử dụng cho mỗi mạng con.

Các tuyến iptable PC cục bộ được đặt thành SNAT và lưu lượng truy cập DNAT đến IP 'giả'.

iptables -t nat -A POSTROUTING -d 192.168.1.100 -s 192.168.2.0/24 -j SNAT --to-source      192.168.2.100
iptables -t nat -A PREROUTING  -d 192.168.1.100 -i eth0           -j DNAT --to-destination 192.168.1.1
iptables -t nat -A POSTROUTING -d 192.168.2.100 -s 192.168.1.0/24 -j SNAT --to-source      192.168.1.100
iptables -t nat -A PREROUTING  -d 192.168.2.100 -i eth1           -j DNAT --to-destination 192.168.2.1

Các quy tắc làm như sau:

  1. Viết lại nguồn 192.168.2.1 thành 192.168.2.100 trên các gói đi
  2. Viết lại đích 192.168.1.100 thành 192.168.1.1 trên các gói đến
  3. Viết lại nguồn 192.168.1.1 thành 192.168.1.100 trên các gói đi
  4. Viết lại đích 192.168.2.100 thành 192.168.2.1 trên các gói đến

Tóm lại, hệ thống cục bộ hiện có thể nói chuyện với máy 'ảo' có địa chỉ 192.168.1.100 và 192.168.2.100.

Tiếp theo, bạn phải buộc PC cục bộ của bạn sử dụng bộ định tuyến bên ngoài để tiếp cận IP giả của bạn. Bạn làm điều này bằng cách tạo một tuyến đường trực tiếp đến IP thông qua bộ định tuyến. Bạn muốn chắc chắn rằng bạn buộc các gói vào phía đối diện của mạng con đích.

ip route 192.168.1.100 via $ROUTER_2_SUBNET_IP 
ip route 192.168.2.100 via $ROUTER_1_SUBNET_IP

Cuối cùng để làm cho tất cả điều này hoạt động, bộ định tuyến bên ngoài cần biết cách tiếp cận các IP giả trên PC cục bộ của bạn. Bạn có thể thực hiện bằng cách bật ARP proxy cho hệ thống của mình.

echo 1 | sudo tee /proc/sys/net/ipv4/conf/all/proxy_arp
echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward

Với thiết lập này, giờ đây bạn có thể coi IP giả là một hệ thống thực trên PC cục bộ của mình. Gửi dữ liệu đến mạng con .1 sẽ buộc các gói ra khỏi giao diện .2. Gửi dữ liệu đến mạng con .2 sẽ buộc các gói ra khỏi giao diện .1.

ping 192.168.1.100
ping 192.168.2.100

Tốt hơn nhiều theo cách của bạn! Lưu ý rằng tôi cũng cần một ip_forward để các công cụ ARP hoạt động: echo 1> / Proc / sys / net / ipv4 / ip_forward
calandoa

29

Tôi đã sử dụng thành công những điều sau trên Linux để kiểm tra thông lượng trên thẻ 10Gbps cổng kép mới ở chế độ "loopback", nghĩa là, một cổng được cắm trực tiếp vào cổng kia. Đây chỉ là một chút voodoo chỉ để buộc các gói ra khỏi dây, nhưng nếu bạn không, Linux sẽ chỉ làm chập mạch lưu lượng thông qua kernel (do đó là câu hỏi của OP). Trong câu trả lời của Casey ở trên, tôi không chắc có thực sự cần thiết phải có bộ định tuyến bên ngoài hay không ở trên, nhưng những điều sau đây hoàn toàn khép kín. Hai giao diện là eth2 và eth3.

Cung cấp IP cho các giao diện và đặt chúng trên các mạng riêng biệt:

ifconfig eth2 10.50.0.1/24
ifconfig eth3 10.50.1.1/24

Tiếp theo, chúng tôi sẽ thiết lập một kịch bản NAT kép: hai mạng giả mới được sử dụng để tiếp cận mạng kia. Trên đường ra, nguồn NAT vào mạng giả của bạn. Trên đường vào, sửa điểm đến. Và ngược lại cho các mạng khác:

# nat source IP 10.50.0.1 -> 10.60.0.1 when going to 10.60.1.1
iptables -t nat -A POSTROUTING -s 10.50.0.1 -d 10.60.1.1 -j SNAT --to-source 10.60.0.1

# nat inbound 10.60.0.1 -> 10.50.0.1
iptables -t nat -A PREROUTING -d 10.60.0.1 -j DNAT --to-destination 10.50.0.1

# nat source IP 10.50.1.1 -> 10.60.1.1 when going to 10.60.0.1
iptables -t nat -A POSTROUTING -s 10.50.1.1 -d 10.60.0.1 -j SNAT --to-source 10.60.1.1

# nat inbound 10.60.1.1 -> 10.50.1.1
iptables -t nat -A PREROUTING -d 10.60.1.1 -j DNAT --to-destination 10.50.1.1

Bây giờ hãy nói cho hệ thống biết cách truy cập từng mạng giả và chuẩn bị trước các mục arp (hãy chắc chắn thay thế địa chỉ MAC của bạn, đừng sử dụng mạng của tôi):

ip route add 10.60.1.1 dev eth2
arp -i eth2 -s 10.60.1.1 00:1B:21:C1:F6:0F # eth3's mac address

ip route add 10.60.0.1 dev eth3 
arp -i eth3 -s 10.60.0.1 00:1B:21:C1:F6:0E # eth2's mac address

Điều này đánh lừa Linux đủ để thực sự đặt các gói lên dây. Ví dụ:

ping 10.60.1.1

đi ra ngoài eth2, IP nguồn 10.50.0.1 được NATted thành 10.60.0.1 và khi nó đi vào eth3, đích 10.60.1.1 được NATted thành 10.50.1.1. Và trả lời mất một hành trình tương tự.

Bây giờ sử dụng iperf để kiểm tra thông lượng. Liên kết với các IP chính xác và chắc chắn rằng bạn đang liên hệ với IP nào (địa chỉ giả của đầu bên kia):

# server
./iperf -B 10.50.1.1 -s

# client: your destination is the other end's fake address
./iperf -B 10.50.0.1 -c 10.60.1.1 -t 60 -i 10

Đảm bảo lưu lượng truy cập thực sự đi ra khỏi dây:

tcpdump -nn -i eth2 -c 500

Bạn cũng có thể xem / Proc / ngắt chỉ để chắc chắn rằng thẻ đang được sử dụng:

while true ; do egrep 'eth2|eth3' /proc/interrupts ; sleep 1 ; done

Nhưng dù sao, tôi đã tìm thấy bài đăng này để tìm cách làm điều này, cảm ơn các bạn đã hỏi và hy vọng điều này sẽ giúp bất cứ ai khác tìm thấy bài đăng này trong tương lai.


+1 Giải pháp tuyệt vời - điều này thậm chí không cần phải kích hoạt chuyển tiếp ip! Đây chỉ là những gì tôi cần ngay bây giờ (để thử nghiệm 10 GB thông qua loopback).
Nils

14

Như mọi khi - tôi hơi muộn - nhưng ngày nay người ta có thể sử dụng các không gian tên mạng để cô lập các giao diện và ngăn chặn mọi chuyển tiếp cục bộ (và đấu tranh với iptables :)).

Tạo không gian tên (tất cả được thực hiện với các quyền cần thiết, ví dụ như root):

ip netns add ns_server
ip netns add ns_client

Lưu ý rằng trạng thái / cấu hình giao diện bây giờ phải được truy cập trong ngữ cảnh của không gian tên được gán - vì vậy chúng sẽ không xuất hiện nếu bạn chạy một liên kết ip trần vì điều này được chạy trong ngữ cảnh của không gian tên mặc định. Chạy một lệnh trong một không gian tên có thể được thực hiện bằng cách sử dụng

ip netns exec <namespace-name> <command>

làm tiền tố.

Bây giờ gán không gian tên cho giao diện, áp dụng cấu hình và thiết lập giao diện:

ip link set eth1 netns ns_server
ip netns exec ns_server ip addr add dev eth1 192.168.1.1/24
ip netns exec ns_server ip link set dev eth1 up
ip link set eth2 netns ns_client
ip netns exec ns_client ip addr add dev eth2 192.168.1.2/24
ip netns exec ns_client ip link set dev eth2 up

Bây giờ bạn có thể thực thi các ứng dụng trong không gian tên - cho máy chủ iperf chạy

ip netns exec ns_server iperf -s -B 192.168.1.1

và khách hàng:

ip netns exec ns_client iperf -c 192.168.1.1 -B 192.168.1.2

Lưu lượng bây giờ sẽ được gửi qua các giao diện vật lý vì toàn bộ mạng, giao diện, định tuyến ... được cách ly bởi các không gian tên để hạt nhân không thể khớp các địa chỉ được sử dụng trong lưu lượng truy cập với giao diện cục bộ (khả dụng).

Nếu bạn đã hoàn thành các thử nghiệm của mình, chỉ cần xóa các không gian tên:

ip netns del <namespace-name>

Các giao diện sẽ được gán lại cho không gian tên mặc định và tất cả cấu hình được thực hiện trong không gian tên sẽ biến mất (ví dụ: không cần xóa địa chỉ IP được gán).


Điều này đơn giản hơn nhiều so với phép thuật hai mặt đang được đề xuất và không yêu cầu bất kỳ sự phối hợp nào từ các máy tính khác trên mạng cũng như không có bất kỳ cấu trúc liên kết vật lý nào. Yêu cầu duy nhất của tôi là bạn thêm các lệnh để thêm các tuyến.
Huckle

3

Ok, cuối cùng tôi đã thành công trong việc thiết lập cấu hình của mình.

Ý tưởng là sử dụng một địa chỉ giả khác, để buộc tuyến đường của địa chỉ giả này đến giao diện 2, sau đó dịch địa chỉ giả với địa chỉ thật 2 bằng NAT / iptables.

Thiết lập của tôi thực sự được tạo từ một bộ định tuyến Tôi có thể telnet giữa IF1 (giao diện 1) và IF2

Trong thiết lập của tôi, FAKE_ADDR và ​​IF1_ADDR nằm trên cùng một mạng con.

ifconfig $IF1 $IF1_ADDR netmask 255.255.255.0
ifconfig $IF2 $IF2_ADDR netmask 255.255.255.0

iptables -t nat -A PREROUTING -d $FAKE_ADDR -i $IF2 -j DNAT --to-destination $IF2_ADDR
iptables -t nat -A POSTROUTING -s $IF2_ADDR -d $IF1_ADDR/24 -j SNAT --to-source $FAKE_ADDR

route add $FAKE_ADDR gw $ROUTER_ADDR

Và trên bộ định tuyến:

route add $FAKE_ADDR gw $IF2_ADDR

Nếu tôi gửi một cái gì đó đến FAKE_ADDR, pkt được chuyển tiếp qua IF1 đến bộ định tuyến, chuyển tiếp một lần nữa đến IF2, sau đó FAKE_IP được thay thế bằng IF2_ADDR. Gói được xử lý bởi máy chủ, kết quả được gửi lại cho IF1_ADDR, từ IF2_ADDR được thay thế bằng FAKE_ADDR.

Có thể sử dụng một cấu hình đơn giản hơn chỉ với một cáp chéo, nhưng vì tôi đã không thử, tôi thích đưa ra giải pháp làm việc của mình.


nếu bộ định tuyến đang gửi $ FAKE_ADDR đến $ IF2_ADDR, thì quy tắc DNAT của bạn có cần phải là "-i $ IF2" thay vì "-i $ IF1" không?
cmcginty

Bạn nói đúng Casey, sửa xong.
calandoa

1

Câu trả lời được đưa ra ở trên của Thomas Tannhäuser là tại chỗ!

Tôi đã có một tình huống tương tự: một máy duy nhất với hai giao diện enet. Kế hoạch của tôi là sử dụng một giao diện làm máy chủ (người nhận) và giao diện khác là máy khách (người gửi). Mỗi giao diện sẽ được gắn vào bộ định tuyến và iperf sẽ điều khiển lưu lượng truy cập thông qua bộ định tuyến để đo thông lượng, PPS, độ trễ, v.v.

Thật không may, cách tiếp cận iptables không trực quan và có nhiều vấn đề. Sau vài giờ bực bội, tôi từ bỏ kế hoạch tấn công này. Lấy cảm hứng từ đề xuất của Thomas, tôi đã làm một bài tập nhỏ về Không gian tên IP của Linux và bắt đầu đánh giá cao sự đơn giản và thanh lịch của giải pháp này.

Dưới đây là danh sách các lệnh chính xác mà tôi đã sử dụng để định cấu hình Fedora FC26 của mình để phục vụ trong khả năng này. Hai giao diện là enp1s0 và enp3s0. Bộ định tuyến có hai giao diện với địa chỉ 192.168.2.112 và 172.16.16.2. Mỗi đầu nối FC26 ENET được kết nối trực tiếp với giao diện bộ định tuyến tương ứng.

# How to configure the IP Namespaces
ip netns add iperf-server
ip netns add iperf-client
ip link set enp1s0 netns iperf-server
ip link set enp3s0 netns iperf-client
ip netns exec iperf-server ip addr add dev enp1s0 192.168.2.139/20
ip netns exec iperf-client ip addr add dev enp3s0 172.16.16.2/24
ip netns exec iperf-client ip link set dev enp3s0 up
ip netns exec iperf-server ip link set dev enp1s0 up
ip netns exec iperf-server route add default gw 192.168.2.112
ip netns exec iperf-client route add default gw 172.16.16.1

# Test the interfaces and network using ping
ip netns exec iperf-client ping -c1 172.16.16.1
ip netns exec iperf-server ping -c1 192.168.2.112
ip netns exec iperf-server ping -c1 172.16.16.2
ip netns exec iperf-client ping -c1 192.168.2.139

# Start Iperf Server for UDP test
ip netns exec iperf-server iperf -u -s
# Run Client against Iperf server for UDP test
ip netns exec iperf-client iperf -u -c 192.168.2.139

0

Có vẻ như bạn muốn biến hộp linux của mình thành hộp loại bộ định tuyến / cầu / cổng / tường lửa. Các tài nguyên sau đây có thể là những gì bạn đang tìm kiếm:

Dự án Bộ định tuyến Linux

Danh sách các bản phân phối bộ định tuyến hoặc tường lửa

Bộ định tuyến Linux LiveCD

Tạp chí Linux - Bộ định tuyến Linux

Cập nhật dựa trên thông tin thêm:

Tôi không nghĩ bạn sẽ có thể làm những gì bạn muốn. HĐH sẽ luôn xem xét bảng định tuyến bên trong của nó và 'xem' cả hai địa chỉ IP cục bộ. Sau đó, nó sẽ định tuyến lưu lượng trong HĐH và không bao giờ đặt nó lên dây. Bạn sẽ cần một máy thứ hai hoặc hai máy ảo (kiểm tra Xen ).


0

Có rất nhiều thứ phải trải qua ở đây, vì vậy tôi hoàn toàn không thể đảm bảo tính chính xác của mình, nhưng câu hỏi ban đầu dường như đang tìm kiếm cái gọi là kỹ thuật "gửi cho chính mình" . Tìm kiếm được liên kết cho thấy những gì tôi nghĩ là bản vá kernel được duy trì tốt nhất như các liên kết + thảo luận hàng đầu và các bản vá với các phương pháp khác trong các danh sách gửi thư khác nhau, đặc biệt. LKML.

Tôi nghĩ người ta cũng nên nhìn vào các không gian tên mạng , được thực hiện với "ip netns" của iproute2 . Điều này cũng cần thêm một số giao diện và ma thuật định tuyến, do đó, thậm chí có thể không phức tạp hơn các iptables hoopla khổng lồ trong các câu trả lời khác.

Nhận xét chắc chắn hoan nghênh nếu bất cứ ai tìm thấy một cái gì đó hữu ích với những điều này - làm thế nào, cái gì, nơi thực hiện của bạn.


0

Kiểm tra bài viết này. Ở đây các bước chi tiết được đề cập để cho phép truy cập internet vào hộp ảo vm bằng cách sử dụng chuyển tiếp NAT.

http://jackal777.wordpress.com/2012/02/13/virtualbox-host-only-networking-nat-for-iNET-access/


Trong khi về mặt lý thuyết có thể trả lời câu hỏi, tốt hơn là nên bao gồm các phần thiết yếu của câu trả lời ở đây và cung cấp liên kết để tham khảo.
Scott Pack

-1

đây là cách tôi làm cho nó hoạt động cho IPV6

ips tĩnh được chỉ định

/sbin/ifconfig eth1 inet6 add 2001:db8::1/127 
/sbin/ifconfig eth3 inet6 add 2001:db8::2/127 

thiết lập các tuyến chỉ lưu trữ đến địa chỉ "FAKE"

ip -6 route add 2001:db8::2/128 dev eth1 metric 1
ip -6 route add 2001:db8::1/128 dev eth3 metric 1

điền vào bảng Neighbor ... như arp

ip -6 neighbor add 2001:db8::1 lladdr 90:e2:ba:0d:75:e8 dev eth3 # eth1's mac address
ip -6 neighbor add 2001:db8::2 lladdr 90:e2:ba:0d:75:e9 dev eth1 # eth3's mac address

đã thêm các mục ip6tables

ip6tables -t nat -A POSTROUTING -s 2001:db8::1 -d 2013::2 -j SNAT --to-source 2001:db8::1
ip6tables -t nat -A PREROUTING -d 2001:db8::1 -j DNAT --to-destination 2001:db8::1
ip6tables -t nat -A POSTROUTING -s 2001:db8::2 -d 2013::1 -j SNAT --to-source 2001:db8::2
ip6tables -t nat -A PREROUTING -d 2001:db8::2 -j DNAT --to-destination 2001:db8::2

Bạn đang sử dụng bản phân phối nào? Lần trước tôi đã kiểm tra, kernel không có bảng NAT cho IPv6.
fukawi2
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.