Liên kết chương trình unix với giao diện mạng cụ thể


40

Câu hỏi: Làm cách nào để khởi chạy một chương trình trong khi đảm bảo rằng quyền truy cập mạng của nó bị ràng buộc thông qua giao diện mạng cụ thể?

Trường hợp: Tôi muốn truy cập hai máy riêng biệt có cùng IP (192.168.1.1), nhưng có thể truy cập thông qua hai giao diện mạng khác nhau (eth1 và eth2).

Thí dụ:

net-bind -D eth1 -exec {Program 192.168.1.1}
net-bind -D eth2 -exec {Program 192.168.1.1}

Trên đây là một xấp xỉ của những gì tôi muốn, lấy cảm hứng từ ràng buộc phần cứng được thực hiện thông qua primusrunoptirun .

Thách thức: Như được đề xuất trong một luồng liên quan , các giao diện được sử dụng không được chọn bởi chương trình, mà là bởi hạt nhân (Do đó cú pháp liên kết trước trong ví dụ trên).

Tôi đã tìm thấy một số giải pháp liên quan, không thỏa đáng. Chúng dựa trên các giao diện mạng ràng buộc thông qua danh sách đen mạng cụ thể của người dùng; tức là chạy quy trình với tư cách người dùng chỉ có thể truy cập vào một giao diện mạng cụ thể.


Bạn đang ám chỉ rằng máy của bạn được kết nối với hai mạng khác nhau, cả 192.168.1.0? Bảng định tuyến của bạn trông như thế nào? Nếu bạn muốn hạn chế các giao diện hiển thị trong một quy trình, giải pháp nhẹ nhất sẽ là các nhóm, một thùng chứa nặng hơn.
lgeorget

Có, hai mạng khác nhau, cả hai trên cùng một dải IP. Tôi không chắc chắn tôi sẽ không hạn chế các giao diện có thể nhìn thấy, chỉ ra lệnh sử dụng giao diện nào làm mặc định? :)
Skeen

3
Những gì bạn yêu cầu rất khó vì một lý do chính đáng: có hai mạng được kết nối với nhau bằng cùng một tên miền IP giống như có một thang máy trong một tòa nhà có hai tầng có cùng số. Phạm vi IP là những gì xác định miền không phải là giao diện đầu ra. Tuy nhiên, phải có một cách để làm việc xung quanh thiết kế mạng không hoàn hảo của bạn với iptables.
lgeorget

Tôi đang kết nối hệ thống của mình với hai cơ sở hạ tầng tại chỗ khác nhau, vì cơ sở hạ tầng như vậy không bao giờ được thiết kế để tương tác, và do đó thiết kế mạng bị thiếu sót trong vấn đề đó.
Skeen

1
Lập luận của tôi đối với NAT là toàn bộ không gian địa chỉ thường được ẩn đằng sau NAT và khi tôi đang kết nối hai cơ sở hạ tầng của NAT thì vụ va chạm xảy ra. - Tôi không ở bất kỳ vị trí nào để sửa đổi cơ sở hạ tầng. - Tôi đã thử sử dụng các không gian tên mạng với các cặp giao diện mạng ảo (một trong không gian tên, một trong không gian tên gốc) bắc cầu cho không gian tên gốc một đến giao diện vật lý và chạy các chương trình trong không gian tên mạng. - Điều này có vẻ như đang hoạt động, nhưng tôi không nhận được quyền truy cập ngoài không gian tên gốc (nghĩa là không có quyền truy cập bên ngoài máy).
Skeen

Câu trả lời:


35

Đối với Linux, điều này đã được trả lời trên Superuser - Làm cách nào để sử dụng các giao diện mạng khác nhau cho các quy trình khác nhau? .

Câu trả lời phổ biến nhất sử dụng một LD_PRELOADmẹo để thay đổi liên kết mạng cho một chương trình, nhưng các hạt nhân hiện đại hỗ trợ một tính năng linh hoạt hơn nhiều gọi là 'không gian tên mạng' được thể hiện thông qua ipchương trình. Câu trả lời này cho thấy làm thế nào để sử dụng này. Từ thí nghiệm của riêng tôi, tôi đã thực hiện như sau (với quyền root):

# Add a new namespace called test_ns
ip netns add test_ns

# Set test to use eth0, after this point eth0 is not usable by programs
# outside the namespace
ip link set eth0 netns test_ns

# Bring up eth0 inside test_ns
ip netns exec test_ns ip link set eth0 up

# Use dhcp to get an ipv4 address for eth0
ip netns exec test_ns dhclient eth0

# Ping google from inside the namespace
ip netns exec test_ns ping www.google.co.uk

Cũng có thể quản lý các không gian tên mạng ở một mức độ nào đó với các lệnh unsharensenter. Điều này cho phép bạn cũng tạo các không gian riêng biệt cho các PID, người dùng và các điểm gắn kết. Để biết thêm thông tin, xem:


"sau thời điểm này eth0 không thể sử dụng được bởi các chương trình bên ngoài không gian tên" - Vì vậy, tôi đang rút kết nối cho tất cả các vấn đề khác khi thực hiện việc này?
Skeen

1
@Skeen, vâng, có lẽ bạn sẽ đẩy một giao diện mà không có chương trình nào khác đang sử dụng vào không gian tên và sử dụng giao diện chính của bạn một cách bình thường.
Graeme

1
@Graerne; Cả hai giao diện đang được sử dụng tích cực; Tôi không đủ khả năng gỡ xuống các giao diện.
Skeen

và những gì với cổng mặc định? wvdialví dụ, dường như hoàn toàn không thiết lập nó ... vì vậy nó phải được xác định trong chính không gian tên
Flash Thunder

Bạn có thể bao gồm các hướng dẫn về cách hoàn tác điều đó? Bạn chỉ ip netns remove test_nsđể trở lại bình thường? Hay bạn phải làm gì đặc biệt?
Multihunter

17

Tôi chấp nhận câu trả lời của Graeme; đây chỉ đơn giản là một cách theo dõi để giải thích những thay đổi tôi đã làm với đề nghị của anh ấy để giải quyết vấn đề của tôi.

Thay vì ràng buộc giao diện vật lý bên trong không gian tên, tôi đã tạo một cặp giao diện mạng ảo, với một đầu trong không gian tên mạng và một đầu ở gốc. Các gói sau đó được định tuyến qua mạng ảo này từ không gian tên, đến không gian tên gốc và sau đó đến giao diện vật lý. - Như vậy tôi có thể chạy tất cả các lần chuyển dữ liệu thông thường của mình và ngoài ra, các quá trình bắt đầu chỉ có thể truy cập vào một giao diện cụ thể.

# Create the eth0 network namespace
ip netns add eth0_ns

# Create the virtual network pair
ip link add v_eth0a type veth peer name v_eth0b

# Move v_eth0a to the eth0_ns namespace, the virtual pair is now split
# between two network namespaces.
ip link set v_eth0a netns eth0_ns

# Configure the ends of the virtual network pairs
ip netns exec eth0_ns ifconfig v_eth0a up {{NAMESPACE_IP}} netmask {{NAMESPACE_NETMASK}}
ifconfig v_eth0b up {{ROOT_NS_IP}} netmask {{ROOT_NS_NETMASK}}

# Setup routing from namespace to root
ip netns exec eth0_ns route add default gw {{ROOT_NS_IP}} dev v_eth0a

# Setup IP forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A POSTROUTING -s {{ROUTE_SOURCE}}/24 -o {{NETWORK_INTERFACE}} -j SNAT --to-source {{ROUTE_TARGET}}

Khi các giao diện đã được thiết lập cho eth0 và eth1, với các không gian tên tương ứng eth0_ns và eth1_ns, các chương trình có thể được thực thi trên giao diện đã chỉ định thông qua;

ip netns exec eth0_ns fish
ip netns exec eth1_ns fish

4
Làm tốt! Tôi nghĩ bạn cũng có thể tạo một thiết bị cầu nối và thu hẹp không gian tên mặc định và của cặp ảo với một trong các thiết bị vật lý. Điều này có vẻ tương đương mặc dù.
Graeme

1
Tôi đã thử bắc cầu cho thiết bị ảo và vật lý; Tôi không thể truy cập mạng bên ngoài bằng giải pháp đó.
Skeen

2
Tôi đã làm, nhưng chỉ từ không gian tên mới. Tôi nghĩ rằng vấn đề tôi gặp phải liên quan đến người quản lý mạng, tôi đã không tìm ra vấn đề này hoặc tôi sẽ cập nhật câu trả lời của mình.
Graeme

Tôi có cùng một vấn đề, nhưng tôi đã thất bại trong việc sử dụng giải pháp đó. Chính xác những gì tôi nên nhập vào {{ROUTE_SOURCE}} và {{ROUTE_TARGET}} trong bước cuối cùng?
litov

@Graeme, ít nhất là trên Ubuntu tôi đã có thể để có được kết nối trở lại trong cả hai không gian tên cũng như không gian tên toàn cầu bằng cách phát hành dhclient <bridge>mỗi ở đây .
Chris Hunt

4

Giải pháp I: Tải trước một thư viện cụ thể

  • App-Route-Jail : sử dụng ld_preload để buộc cổng giao diện (ý tưởng tuyệt vời nhưng yêu cầu khả năng root hoặc mark) được sử dụng chi tiết trên ghi chú dưới đây

  • Proxybound : sử dụng ld_preload để buộc proxy vào một ứng dụng cụ thể (đây là sử dụng proxy thay vì giao diện)

  • Force-Bind : có rất nhiều tính năng nhưng rò rỉ liên kết (không đáng tin cậy)

  • Bind-Interface-IP : kết nối quá đơn giản và rò rỉ (không đáng tin cậy)

  • Bind-IP : cách kết nối quá đơn giản và rò rỉ (không đáng tin cậy)

Giải pháp II: Không gian người dùng Linux

  • IP-netns không gian người dùng linux cổ điển : giải pháp tuyệt vời nhưng yêu cầu root và giao diện chỉ có thể tồn tại trên một không gian người dùng

  • Firejail : Firejail thể ép buộc một ứng dụng sử dụng một mạng cụ thể, nhưng khả năng tương thích được giới hạn (ví dụ nó không tương thích với giao diện tun). firejail không cần rootfirejail --dns=8.8.8.8 --noprofile --net=eth0 --ip=192.168.1.1 app-command

  • Firejail với netns : Firejail có thể buộc một ứng dụng sử dụng một không gian người dùng cụ thể đã được tạo riêng biệt, điều này chúng ta hãy đặt tên cho không gian mà không có gốcfirejail --dns=8.8.8.8 --noprofile --netns=nameOfyourNS app-command

  • Firejail với giả trang và cầu nối : Firejail có thể buộc một ứng dụng sử dụng một giao diện cụ thể với iptables giả trang , điều này thật tuyệt và không yêu cầu root nhưng điều này đòi hỏi ip_forward và có thể ngụ ý tác động bảo mậtfirejail --net=br0 firefox

Giải pháp III: iptables Linux

Iptables có thể được sử dụng cho mục đích này nhưng điều này đòi hỏi ip_forward và có thể ngụ ý tác động bảo mật nếu nó không được cấu hình đúng, ví dụ 1 , ví dụ 2 , ví dụ 3 , ví dụ 4

Giải pháp (I, II & III) lưu ý:

Dây bảo vệ

Nếu bạn đang sử dụng VPN (đặc biệt là bảo vệ dây) và bạn muốn áp dụng giải pháp này cho giao diện bảo vệ dây ( bảo vệ dây với không gian người dùng ), bạn có thể làm theo hướng dẫn được liên kết để tạo không gian người dùng có giao diện wg (và do đó giới hạn ở giao diện vpn ) cũng điều này có thể được kết hợp với firejail --netns=containerđể có thể sử dụng không gian người dùng mà không cần root.

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

Cách sử dụng App-Route-Jail

  • 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
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.