Làm thế nào để sử dụng các giao diện mạng khác nhau cho các quy trình khác nhau?


59

Tôi có hai giao diện mạng trên PC Linux và tôi cần đặt thủ công giao diện mà một quy trình nhất định sẽ sử dụng.

Chương trình (Twinkle softphone) không có tùy chọn tương tự, vì vậy tôi tin rằng nó phải được đặt bên ngoài.

Tôi làm nó như thế nào?

Chỉnh sửa: Tôi không cố làm cho quá trình máy chủ liên kết với một giao diện cụ thể, mà là để làm cho chương trình máy khách liên hệ với máy chủ bằng giao diện cụ thể.


khách hàng cũng sử dụng liên kết / kết nối, xem tài liệu bind.c.txt về cách buộc ircII (chương trình irc-client) vào một ip đã cho: 'Ví dụ trong bash để sử dụng IP ảo của bạn làm tài khoản gửi đi cho ircII: BIND_ADDR = "your-virt-ip" LD_PRELOAD =. / Bind.so ircII '
akira

Tôi đã tìm thấy một cách tiếp cận khác ở đây, tôi hy vọng nó hữu ích (tôi chắc chắn hy vọng việc định tuyến chính sách hạt nhân được mô tả được bật theo mặc định hiện nay): kindlund.wordpress.com/2007/11/19/ Khăn
Savvas Radevic

Câu trả lời:


48

bạn có thể thay thế mã trong thời gian chạy bằng cách sử dụng LD_PRELOAD (@windows bạn có thể sử dụng một kỹ thuật tương tự được gọi là đường vòng , khá lạ mắt). những gì nó làm là để thông báo cho trình liên kết động trước tiên tải tất cả các lib vào quá trình bạn muốn chạy và sau đó thêm một số ontop của nó. bạn thường sử dụng nó như thế này:

% LD_PRELOAD=./mylib.so ls

và bằng cách đó bạn thay đổi những gì lskhông.

cho vấn đề của bạn, tôi sẽ thử http://www.ryde.net/code/bind.c.txt , mà bạn có thể sử dụng như:

% BIND_ADDR="ip_of_ethX" LD_PRELOAD=./bind.so twinkle

đây là cách bạn xây dựng nó:

% wget http://www.ryde.net/code/bind.c.txt -O bind.c
% gcc -nostartfiles -fpic -shared bind.c -o bind.so -ldl -D_GNU_SOURCE

một cách làm dài hơn là http://daniel-lange.com/archives/53-Binding-appluggest-to-a-specific-IP.html

hack và công cụ tương tự:


7
Ái chà, cái quái gì thế. +1
sinni800

1
Xin chào, đây có vẻ là một mẹo thực sự hay, nhưng nó không hiệu quả với tôi. Tôi có hai modem 3G, khi được kết nối, mở hai giao diện (ppp0 và ppp1). Nếu tôi cố gắng ép buộc một trong hai IP, tôi luôn luôn đi ra ngoài với cùng một giao diện (tôi thấy điều đó bởi vì tôi có hai trường hợp của wireshark, một cho mỗi giao diện). Tôi cũng đã xóa các bản in gỡ lỗi khỏi bind.c và thực sự tôi thấy rằng thư viện "quá tải" đã được tải, vì vậy tôi không biết tại sao nó không hoạt động.
Andrea Spadaccini

3
LD_PRELOAD bị bỏ qua nếu UID hiệu quả của bạn không giống với UID thực của bạn.
matthias krull

Các force_binddự án do Catalin M. Boie hỗ trợ ipv6
BurnsBA

Hoạt động tuyệt vời nhưng phải thêm #include <arpa / inet.h> để quá trình biên dịch thành công.
anno

31

ip netns có thể làm điều này.

TL; DR: Tạo không gian tên mạng, liên kết giao diện với chúng và sau đó chạy "ip netns exec NAME cmd ..."

Chỉ cần kiểm tra xem distro của bạn có hỗ trợ mạng ip không ... (Backtrack 5r3 thì không, trong khi Kali thì không;))

TRONG CHI TIẾT:

#create netns
ip netns add myNamespace
#link iface to netns
ip link set eth0 netns myNamespace
#set ip address in namespace
ip netns exec myNamespace ifconfig eth0 192.168.0.10/24 up
#set loopback (may be needed by process run in this namespace)
ip netns exec myNamespace ifconfig lo 127.0.0.1/8 up
#set route in namespace
ip netns exec myNamespace route add default gw 192.168.0.1
#force firefox to run inside namespace (using eth0 as outgoing interface and the route)
ip netns exec myNamespace firefox

Tại sao điều này tốt hơn là ràng buộc ip thông qua LD_PRELOAD? Bởi vì LD_PRELOAD không kiểm soát tuyến đường mà các quy trình sử dụng. Nó sẽ sử dụng tuyến đường đầu tiên.

Và vì nó luôn sử dụng cùng một tuyến đường, nên nó sẽ mặc định cho giao diện được đăng ký với tuyến đường (đó không phải là những gì chúng ta muốn)


2
Hãy cố gắng để thêm chi tiết cho câu trả lời của bạn.
Renju Chandran chingath

4
không làm điều này trên máy chủ từ xa nếu eth0 là giao diện mạng công cộng ..
ygrek

1
dòng cuối cùng sẽ làip netns exec myNamespace firefox
meuh

1
Sử dụng "sudo ip netns del <namepace-name>" để xóa không gian tên khi cần!
Eduardo Lucio

1
@EduardoLucio có thể thực hiện nó như sau: sudo ip netns exec myNamespace su -u someUser -c firefox
olivervbk

2

Tôi không nghĩ có thể buộc một quá trình sử dụng một giao diện nhất định.

Tuy nhiên, tôi nghĩ rằng bạn có thể chơi với ipchain / iptables và buộc rằng một cổng nào đó mà quá trình của bạn đang nghe sẽ chỉ nhận các gói đi qua một giao diện cụ thể.

HOWTO hữu ích: http://tldp.org/HOWTO/IPCHAINS-HOWTO.html


2
Hai bài viết được bình chọn cao hơn chứng minh khác.
Paul Gear

2

Dựa vào câu trả lời @olivervbk dưới đây là của tôi!

Chạy tất cả các lệnh là "root".

Sử dụng lệnh ...

ip a

... Để tìm ra tên của giao diện mạng mà bạn sẽ muốn sử dụng.

Chạy các lệnh dưới đây làm mẫu ...

ip netns add [INTERFACE_NAME]_ns
ip link set dev [INTERFACE_NAME] netns [INTERFACE_NAME]_ns
ip netns exec [INTERFACE_NAME]_ns ifconfig [INTERFACE_NAME] 10.1.1.10/24 up
ip netns exec [INTERFACE_NAME]_ns ifconfig lo 127.0.0.1/8 up
ip netns exec [INTERFACE_NAME]_ns route add default gw 10.1.1.1
ip netns exec [INTERFACE_NAME]_ns dhcpcd [INTERFACE_NAME]
ip netns exec [INTERFACE_NAME]_ns sudo -b -u [YOUR_USER] [APP_NAME] 2> /dev/null 1> /dev/null &
  • [INTERFACE_NAME] - Thay thế bằng tên của giao diện mạng đã chọn.
  • [YOU_USER] - Thay thế bằng tên người dùng của bạn.
  • [APP_NAME] - Tên của ứng dụng sẽ được thực thi trong không gian tên "[INTERFACE_NAME] _ns". Ví dụ: "firefox".

LƯU Ý I: Các cờ "-b -u" trong lệnh "sudo" cho phép ứng dụng chạy bằng người dùng của bạn (không phải "root") và trong nền giải phóng thiết bị đầu cuối. Các 2> /dev/null 1> /dev/null &đoạn là để ngăn chặn đầu ra từ "[APP_NAME]" được in tại nhà ga.
CHÚ THÍCH II: Các giá trị của ip "10.1.1.10" và "10.1.1.1" là tùy ý.
CHÚ THÍCH III: Để làm việc cho tôi, tôi phải chạy dhcpcd [INTERFACE_NAME]lệnh.

Để xóa không gian tên, hãy sử dụng ...

ip netns del [INTERFACE_NAME]_ns

... hoặc là...

ip -all netns delete

... Để loại bỏ bất kỳ thứ gì tồn tại.


1

Thông thường nếu một chương trình không có tùy chọn để thiết lập giao diện nghe, thì đó là nghe trên TẤT CẢ các giao diện. (Bạn có thể xác minh điều này với lsof -i).

Tạo các quy tắc tường lửa iptables làm giảm lưu lượng truy cập đến các cổng của nó trên các giao diện mà bạn không muốn nó hiển thị trên đó là cách dễ nhất để làm.


1

Phương án I:

Sử dụng ld_preload để buộc cổng giao diện https://github.com/Intika-Linux-Network/App-Route-Jail

Buộc một ứng dụng sử dụng giao diện mạng cụ thể

Chúng ta cần tìm cổng nào mà giao diện mạng đang sử dụng, sau đó buộc cổng đó vào ứng dụng bị bỏ tù của chúng ta và do đó buộc ứng dụng phải liên kết với một giao diện mạng cụ thể

  • Cách tìm cổng giao diện (có nhiều giải pháp để tìm cổng ở đây là một số lệnh cho phép tìm cổng được sử dụng)
$ route
$ route -n
$ ip rule list
$ ip route show
$ netstat -rn
$ cat /etc/network/interfaces
$ cat /etc/sysconfig/network-scripts/ifcfg-eth0
$ traceroute www.google.com
$ ip route show 0.0.0.0/0 dev eth0

Mỗi cổng ứng dụng

  • Xây dựng ứng dụng-Tuyến-tù
git clone https://github.com/Intika-Linux-Network/App-Route-Jail.git
cd Approute-Utils
chown 755 make.sh
./make.sh
  • Thêm tuyến đường cho các gói được đánh dấu trong tương lai (đối với ứng dụng bị bỏ tù) trong ví dụ 192.168.1.1này được sử dụng làm cổng bắt buộc, quy tắc tuyến này sẽ không ảnh hưởng đến các ứng dụng khác, ví dụ thao tác này chỉ được thực hiện một lần khi khởi động hệ thống nếu bạn muốn sử dụng giải pháp này hàng ngày
ip rule add fwmark 10 table 100
ip route add default via 192.168.1.1 table 100
  • Bắt đầu ứng dụng mà bạn muốn vào tù
MARK=10 LD_PRELOAD=./mark.so firefox
  • Kiểm tra địa chỉ IP wan
MARK=10 LD_PRELOAD=./mark.so wget -qO- ifconfig.me

Phương án II:

Firejail https://firejail.wordpress.com/ có thể buộc ứng dụng sử dụng một mạng cụ thể, nhưng khả năng tương thích bị hạn chế.

firejail --dns=8.8.8.8 --net=eth0 --ip=192.168.1.1

Lưu ý rằng đánh dấu là không thể đối với người dùng bình thường, bạn phải chạy bằng root.
jornane

-2

Tại sao bạn muốn một chương trình sử dụng một giao diện khác với giao diện được kết nối với máy chủ để nói chuyện với máy chủ đó? Và nếu hệ thống không sử dụng giao diện được kết nối với máy chủ để nói chuyện với máy chủ đó, thì đó là vấn đề ở cấp hệ thống (bảng định tuyến) và không liên quan gì đến quá trình xảy ra muốn nói chuyện với máy chủ đó.

Các máy chủ khác nhau trên mạng IP có địa chỉ IP khác nhau. Nhân nên biết giao diện nào sẽ sử dụng để tiếp cận một địa chỉ IP cụ thể dựa trên bảng định tuyến. Nếu bạn đang cố gắng nói chuyện với hai máy chủ khác nhau có cùng địa chỉ IP, hệ thống sẽ bị lẫn lộn (bởi vì, trong số những thứ khác, nó chỉ lập chỉ mục các kết nối bên trong theo địa chỉ đích). Bạn có thể làm cho nó hoạt động, nhưng đó là một sửa chữa ở cấp hệ thống liên quan đến việc đặt một máy chủ vào một mạng logic riêng biệt chỉ được kết nối với máy thông qua phần mềm NAT.

Vì vậy, nếu họ có địa chỉ IP khác nhau, hãy sử dụng các tuyến đường để chọn giao diện chính xác. Nếu chúng có cùng địa chỉ IP, bạn cần sử dụng NAT để chúng có các địa chỉ IP khác nhau cho hệ thống.


3
Thứ nhất, có thể có nhiều tuyến hợp lệ giữa máy khách và máy chủ, nhưng với các đặc điểm khác nhau phù hợp với các loại lưu lượng khác nhau; ví dụ UMTS (Dữ liệu di động) có thể tốn tiền nhưng có phạm vi lớn hơn WiFi, nhưng cả hai đều chậm hơn kết nối sợi quang. Nếu các nhà cung cấp ngược dòng thực hiện lọc nguồn (hoặc NAT), bạn không có lựa chọn nào khác ngoài việc gửi giao diện 'bên phải'. Thứ hai, ảnh hưởng đến định tuyến không phải là lý do duy nhất để chọn địa chỉ nguồn. Ngay cả khi cả hai địa chỉ trên cùng một giao diện, việc kiểm soát ràng buộc khi bắt đầu kết nối là điều hữu ích, với tư cách là máy chủ

Một trường hợp là nếu bạn có các IP công cộng khác nhau và bạn muốn khởi chạy một quy trình mới trong mỗi một cho các kết nối đi.
Rfraile
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.