Lệnh chạy một tiến trình con ngoại tuyến tinh tế (không có mạng bên ngoài) trên Linux


15

Tôi có một chương trình tôi muốn thử nghiệm ở chế độ ngoại tuyến mà không làm mất mạng thực tế của tôi. Chương trình này vẫn sẽ cần kết nối với các socket cục bộ, bao gồm các socket miền unix và loopback. Nó cũng cần nghe trên loopback và hiển thị cho các ứng dụng khác.

Nhưng các nỗ lực để kết nối với một máy từ xa sẽ thất bại.

Tôi muốn có một tiện ích hoạt động như strace/ unshare/ sudovà chỉ cần chạy một lệnh với Internet (và LAN) được che giấu và mọi thứ khác vẫn hoạt động:

$ offline my-program-to-test

Câu hỏi này có gợi ý về câu trả lời: Chặn truy cập mạng của một quá trình?

Có một vài gợi ý ở đó, chẳng hạn như chạy như một người dùng khác sau đó thao tác với iptables hoặc unshare -n. Nhưng trong cả hai trường hợp, tôi không biết câu thần chú để có được các ổ cắm tên miền unix và loopback được chia sẻ với hệ thống chính - câu trả lời cho câu hỏi đó chỉ cho tôi biết cách chia sẻ toàn bộ mạng.

Chương trình tôi đang thử nghiệm vẫn cần kết nối với máy chủ X và dbus của tôi và thậm chí có thể nghe trên loopback cho các kết nối từ các ứng dụng khác trên hệ thống.

Lý tưởng nhất là tôi muốn tránh tạo chroots hoặc người dùng hoặc VM hoặc tương tự, vì nó trở nên khó chịu như việc rút cáp mạng. tức là điểm của câu hỏi là làm thế nào tôi có thể làm điều này đơn giản như a sudo.

Tôi thích quy trình chạy bình thường 100% ngoại trừ các cuộc gọi mạng chỉ định địa chỉ không phải địa phương sẽ không thành công. Lý tưởng nhất là giữ cùng một uid, cùng một homedir, cùng pwd, mọi thứ giống nhau ngoại trừ ... ngoại tuyến.

Tôi đang sử dụng Fedora 18, vì vậy các câu trả lời Linux không thể truy cập chỉ là tốt (dự kiến, thậm chí).

Tôi thậm chí rất vui khi giải quyết vấn đề này bằng cách viết chương trình C, nếu đó là những gì liên quan, vì vậy câu trả lời liên quan đến việc viết C là tốt. Tôi chỉ không biết những tòa nhà mà chương trình C sẽ cần phải thực hiện để thu hồi quyền truy cập mạng bên ngoài trong khi vẫn giữ mạng cục bộ.

Bất kỳ nhà phát triển nào đang cố gắng hỗ trợ "chế độ ngoại tuyến" có thể sẽ đánh giá cao tiện ích này!

Câu trả lời:


9

Câu trả lời truyền thống là chạy chương trình như một người dùng khác và sử dụng iptables -m owner. Bằng cách đó, cấu hình mạng được chia sẻ. Tuy nhiên, với sự ra đời của không gian tên, có một cách dễ dàng hơn.

Với các không gian tên, bạn không chia sẻ mạng, sau đó tạo liên kết mạng ảo nếu bạn cần truy cập mạng hạn chế.

Để chia sẻ các socket miền unix, tất cả những gì bạn cần là có một kernel đủ gần đây, sau bản vá 2010 này , từ 2.6.36 trở lên (đó là trường hợp trên tất cả các bản phân phối hiện tại tại thời điểm viết trừ RHEL / CentOS).

Chạy chương trình trong không gian tên IP của chính nó. Trước khi bắt đầu chương trình, hãy thiết lập giao diện ethernet ảo. Dường như không có nhiều tài liệu; Tôi tìm thấy câu thần chú đúng trong một vài blog:

Trong đoạn mã dưới đây, tôi sử dụng ns_execwrapper này xung quanhsetns được liệt kê trong man page để đưa lên phía chủ nhà của liên kết mạng từ quá trình chạy trong không gian tên bị hạn chế. Bạn thực sự không cần điều này: bạn có thể thiết lập phía máy chủ của liên kết từ bên ngoài không gian tên bị hạn chế. Làm điều đó từ bên trong chỉ đơn giản là tạo điều kiện cho việc điều khiển luồng, nếu không, bạn cần một số đồng bộ hóa để thiết lập liên kết sau khi được thiết lập nhưng trước khi bắt đầu chương trình của bạn.

unshare -n -- sh -c '
  # Create a virtual ethernet interface called "confined",
  # with the other end called "global" in the namespace of PID 1
  ip link add confined type veth peer name global netns 1

  # Bring up the confined end of the network link
  ip addr add 172.16.0.2/30 dev confined
  ip link set confined up

  # Bring up the global end of the network link
  ns_exec /proc/1/ns/net ifconfig global 172.16.0.1 netmask 255.255.255.252 up

  # Execute the test program
  exec sudo -E -u "$TARGET_USER" "$0" "$@"
' /path/to/program --argument

Bạn cần phải làm tất cả điều này như root. Việc giới thiệu các không gian tên người dùng trong kernel 3.8 có thể làm cho điều này có thể thực hiện được mà không có quyền đặc biệt, ngoại trừ thiết lập kết thúc toàn cầu của liên kết mạng.

Tôi không biết cách chia sẻ localhost giữa hai không gian tên. Giao diện ethernet ảo tạo ra một cầu nối điểm. Bạn có thể sử dụng iptablesquy tắc chuyển tiếp để chuyển hướng lưu lượng truy cập từ / đến lonếu muốn.


Thông tin bổ sung tốt, cảm ơn. Tôi nghĩ rằng veth cho tôi một liên kết đến "bên ngoài" không gian tên nhưng không gian tên mới của tôi vẫn chiếm một nút mạng riêng, thay vì cùng một nút mạng trừ đi các giao diện không cục bộ. Ý nghĩa của nó là -chuyển đổi) các cổng sẽ cần được hiển thị trong cả hai không gian tên ... bắt đầu đoán những gì tôi muốn là không thể ở đây: - /
Havoc P

1

Điều này cũng có thể đạt được với các nhóm phù hợp với quy tắc iptables. Tôi đã viết một công cụ để trừu tượng các bước. Mặc dù nó yêu cầu quyền root cho thiết lập ban đầu và nếu không là nhị phân setuid, tôi nghĩ rằng nó cung cấp một cách khá đơn giản để xử lý vấn đề trong câu hỏi. Nó đòi hỏi một phiên bản iptables đủ gần đây và các mô đun bộ lọc mạng thích hợp có sẵn.

https://github.com/quitesimpleorg/qsni


0

/ !! \ Đây có lẽ không phải là một câu trả lời hợp lệ vì điều này sẽ làm giảm tất cả lưu lượng truy cập của bạn với bạn, không chỉ là lưu lượng truy cập của một pid.

Tôi chưa sử dụng nó, nhưng tôi nghĩ bạn có khả năng sử dụng Comcast:

https://github.com/tylertreat/Comcast

đặt thành mất gói 100%

Một lần nữa, tôi đã không kiểm tra điều này, nhưng về mặt lý thuyết, đã sửa đổi từ readme của họ, bạn có thể làm:


Linux

Trên Linux, bạn có thể sử dụng iptablesđể loại bỏ các gói đến và đi.

$ iptables -A INPUT -m statistic --mode random --probability 1 -j DROP
$ iptables -A OUTPUT -m statistic --mode random --probability 1 -j DROP

Ngoài ra, bạn có thể sử dụng tcmà hỗ trợ một số tùy chọn bổ sung.

$ tc qdisc change dev eth0 root netem reorder 0 duplicate 0 corrupt 1

Để thiết lập lại:

$ tc qdisc del dev eth0 root netem
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.