Chặn truy cập mạng của một quá trình?


74

Có thể chặn truy cập mạng (đi) của một quy trình không?


6
Làm thế nào để bạn có ý định xác định quá trình? PID, tên, đường dẫn?
Marco

1
Bạn muốn chặn truy cập nào? Một số chương trình sử dụng truy cập mạng thông qua localhost(đến cùng một máy) để thực hiện công việc của họ.
vonbrand

Xem thêm LD_PRELOAD hoặc tương tự để ngăn chặn truy cập mạng , nếu quá trình này đang hợp tác.
Gilles

Câu trả lời:


78

Với Linux 2.6.24+ (được xem là thử nghiệm cho đến 2.6,29), bạn có thể sử dụng các không gian tên mạng cho điều đó. Bạn cần kích hoạt 'không gian tên mạng' trong kernel ( CONFIG_NET_NS=y) và linux-linux với unsharecông cụ.

Sau đó, bắt đầu một quá trình không có quyền truy cập mạng cũng đơn giản như:

unshare -n program ...

Điều này tạo ra một không gian tên mạng trống cho quá trình. Đó là, nó được chạy không có giao diện mạng, kể cả không có loopback . Trong ví dụ dưới đây, chúng tôi thêm -r để chỉ chạy chương trình sau khi ID người dùng và nhóm hiệu quả hiện tại đã được ánh xạ tới các siêu người dùng (tránh sudo):

$ unshare -r -n ping 127.0.0.1
connect: Network is unreachable

Nếu ứng dụng của bạn cần giao diện mạng, bạn có thể thiết lập giao diện mới:

$ unshare -n -- sh -c 'ip link set dev lo up; ping 127.0.0.1'
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=32 time=0.066 ms

Lưu ý rằng điều này sẽ tạo ra một loopback mới, cục bộ . Đó là, quá trình sinh sản sẽ không thể truy cập các cổng mở của máy chủ 127.0.0.1.


Nếu bạn cần có quyền truy cập vào mạng ban đầu bên trong không gian tên, bạn có thể sử dụng nsenterđể nhập không gian tên khác.

Ví dụ sau đây chạy pingvới không gian tên mạng được sử dụng bởi PID 1 (được chỉ định thông qua -t 1):

$ nsenter -n -t 1 -- ping -c4 example.com
PING example.com (93.184.216.119) 56(84) bytes of data.
64 bytes from 93.184.216.119: icmp_seq=1 ttl=50 time=134 ms
64 bytes from 93.184.216.119: icmp_seq=2 ttl=50 time=134 ms
64 bytes from 93.184.216.119: icmp_seq=3 ttl=50 time=134 ms
64 bytes from 93.184.216.119: icmp_seq=4 ttl=50 time=139 ms

--- example.com ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3004ms
rtt min/avg/max/mdev = 134.621/136.028/139.848/2.252 ms

4
unshare -ndường như ném "Hoạt động không được phép" mà không có rootđặc quyền, tôi còn thiếu điều gì không?
hói

1
Có lẽ một câu hỏi ngu ngốc ... không gian tên này cũng áp dụng cho các quy trình con / được gọi là các quy trình của ứng dụng không chia sẻ?
bonanza

3
Đúng. Nó được kế thừa bởi tất cả trẻ em sinh ra sau khi chuyển đổi không gian tên.
Michał Górny

2
Tôi trông giống như bất kỳ chương trình nào mà tôi muốn hủy bỏ, ví dụ như với quyền sudo unshare -nthừa kế gốc. Vì tôi cần sudo để gọi unshare, tôi tự hỏi làm thế nào tôi có thể chắc chắn rằng chương trình được gọi không có quyền root.
bonanza

3
Một lớp lót để hạn chế quá trình cho người dùng. Chỉ cần sudo hai lần: sudo unshare -n sudo -u dude bash -c 'echo Hello, my name is $USER'@ThorSummoner bbs.archlinux.org/viewtopic.php?id=205240
Jakub Bochenski

21

Linux có một tính năng gọi là không gian tên mạng , cho phép bạn về cơ bản có nhiều ngăn xếp mạng trên cùng một máy và gán một cho chương trình khi chạy nó. Đây là một tính năng thường được sử dụng cho các container, nhưng bạn cũng có thể sử dụng nó để thực hiện những gì bạn muốn.

Các ip netnstiểu ban quản lý nó. Tạo một không gian tên mạng mới mà không có quyền truy cập vào bất cứ điều gì thật dễ dàng, đó là trạng thái mặc định của một không gian tên mới:

root@host:~# ip netns add jail

Bây giờ, nếu bạn chuyển sang không gian tên đó, bạn có thể định cấu hình nó khá dễ dàng. Bạn có thể muốn đưa ra lo trong đó, và đó là:

root@host:~# ip netns exec jail /bin/bash
root@host:~# ip addr add 127.0.0.1/8 dev lo
root@host:~# ip link set dev lo up
root@host:~# exit

Bây giờ khi bạn muốn chạy lệnh của mình mà không có mạng, bạn chỉ cần chạy nó trong nhà tù đó:

root@host:~# ip netns exec jail su user -c 'ping  8.8.8.8'
connect: Network is unreachable

Mạng là, như mong muốn, không thể truy cập. (Bạn có thể thực hiện tất cả các loại điều thú vị như một ngăn xếp mạng riêng biệt bao gồm iptablescác quy tắc, v.v.)


Mặc dù tôi cần sudo ipphải thực thi các lệnh ip, nhưng khi tôi gặp sự cố, tôi chỉ thực hiện su someuserđể có được một lớp vỏ không có đặc quyền cho người dùng 'someuser'.
hiền triết

11

Bạn có thể sử dụng iptables và chuyển quá trình đó thành một nhóm:

mkdir /sys/fs/cgroup/net_cls/block
echo 42 > /sys/fs/cgroup/net_cls/block/net_cls.classid

iptables -A OUTPUT -m cgroup --cgroup 42 -j DROP

echo [pid] > /sys/fs/cgroup/net_cls/block/tasks

1
Làm thế nào để loại bỏ pid ra khỏi tệp tác vụ đó, nó đưa ra lỗi khi tôi cố xóa hoặc xóa dữ liệu khỏi tệp đó mặc dù tôi đang sử dụng root
pkm

@pkm để cho phép kết nối lại mạng, bạn chỉ cần lặp lại [pid] thành /sys/fs/cgroup/net_cls/tasks(không có 'chặn' trong đường dẫn)
Đau buồn

10

Có, với hồ sơ apparmor tùy chỉnh, tức là

/usr/bin/curl {
    ...

    # block ipv4 acces
    deny network inet,
    # ipv6 
    deny network inet6,
    # raw socket
    deny network raw,

}

Nhưng theo cách đó, bạn sẽ cần phải tạo một danh sách các tệp được phép truy cập, toàn bộ quy trình có thể hơi phức tạp. Và xem tài liệu trợ giúp tại đây


7

Bạn có thể sử dụng hộp cát firejail (nên hoạt động trên các hạt nhân có tính năng seccomp).

Để sử dụng nó chỉ cần làm

firejail --noprofile --net=none <path to executable>

--noprofilevô hiệu hóa hộp cát mặc định --net=nonevô hiệu hóa kết nối mạng

Tôi tin rằng hầu hết các bản phân phối đều đã cung cấp gói nhưng ngay cả khi chúng không bắt lửa, hầu như không có phụ thuộc nào ngoài việc xây dựng chuỗi công cụ và không gian tên / seccomp được kích hoạt.

Có một số tính năng hay khác của firejail có thể được hiển thị firejail --helpliên quan đến kết nối mạng (chẳng hạn như chỉ cung cấp giao diện loopback hoặc chặn ip / dns, v.v.) nhưng điều này sẽ thực hiện công việc. Ngoài ra, nó doesn't require root.


5

Bạn không thể làm điều đó với iptables một mình. Tính năng này tồn tại trong một thời gian ngắn , nhưng không thể được thực hiện để hoạt động đáng tin cậy và đã bị bỏ rơi.

Nếu bạn có thể chạy quy trình dưới dạng ID người dùng chuyên dụng, iptables có thể thực hiện với ownermô-đun:

iptables -A OUTPUT -m owner --uid-owner 1234 -j DROP

Xem các ví dụ trong Iptables: khớp lưu lượng gửi đi với conntrack và chủ sở hữu. Hoạt động với các giọt lạ , quy tắc iptables / pf để chỉ cho phép ứng dụng / người dùng XY?

Nếu bạn có thể chạy quy trình trong vùng chứa riêng của mình, bạn có thể tường lửa vùng chứa đó một cách độc lập (thậm chí làm cho nó bị ngắt hoàn toàn khỏi mạng).

Một mô-đun bảo mật có thể lọc quyền truy cập của một quá trình vào các tính năng mạng. Câu trả lời của warl0ck đưa ra một ví dụ với AppArmor.


3

Giải pháp 1: Tường lửa:

Chúng tôi có thể sử dụng tường lửa như Douane hoặc Opensnitch NHƯNG những ứng dụng đó không hiệu quả 100% hoặc trong giai đoạn phát triển ban đầu (có rất nhiều lỗi, v.v. vào năm 2019)

Giải pháp 2: Hạt nhân MAC:

Kernel MAC có thể được sử dụng như một bức tường lửa được biết đến nhiều nhất là Tomoyo , SELinuxAppArmor Giải pháp này là tốt nhất một khi nó đến sự ổn định và hiệu quả (giải pháp tường lửa) nhưng hầu hết thời gian thiết lập này là bằng cách nào đó phức tạp.

Giải pháp 3: Firejail:

Firejail có thể được sử dụng để chặn truy cập mạng cho một ứng dụng không yêu cầu root bất kỳ người dùng nào cũng có thể hưởng lợi từ nó

firejail --noprofile --net=none command-application

Giải pháp 4: Không chia sẻ

Unshare có thể khởi động một ứng dụng trên một tên khác mà không cần mạng nhưng điều này đòi hỏi giải pháp root firejail thực hiện gần như chính xác nhưng không yêu cầu root

unshare -r -n application-comand

Giải pháp 5: Xấp xỉ:

Một giải pháp là ủy quyền cho ứng dụng thành proxy rỗng / giả . Chúng tôi có thể sử dụng tsocks hoặc proxy . Dưới đây là một số chi tiết về thiết lập

Giải pháp 6: Iptables:

Một giải pháp dễ dàng khác là iptables, nó có thể được thiết lập để chặn một ứng dụng

  1. Tạo, xác nhận nhóm mới ; thêm người dùng cần thiết vào nhóm này:
    • Tạo nên: groupadd no-internet
    • Xác thực: grep no-internet /etc/group
    • Thêm người dùng: useradd -g no-internet username

      Lưu ý: Nếu bạn đang sửa đổi người dùng hiện có, bạn nên chạy: usermod -a -G no-internet userName kiểm tra với:sudo groups userName

  2. Tạo một tập lệnh trong đường dẫn của bạn và làm cho nó có thể thực thi được:
    • Tạo nên: nano /home/username/.local/bin/no-internet
    • Thực thi: chmod 755 /home/username/.local/bin/no-internet
    • Nội dung: #!/bin/bash
                    sg no-internet "$@"

  3. Thêm quy tắc iptables để bỏ hoạt động mạng cho nhóm không có internet :
    • iptables -I OUTPUT 1 -m owner --gid-owner no-internet -j DROP

      Lưu ý: Đừng quên thực hiện các thay đổi vĩnh viễn, vì vậy nó sẽ được áp dụng tự động sau khi khởi động lại . Làm điều đó, phụ thuộc vào phân phối Linux của bạn.


   4. Kiểm tra nó, ví dụ trên Firefox bằng cách chạy:

  • no-internet "firefox"

   5. Trong trường hợp bạn muốn tạo một ngoại lệ và cho phép một chương trình truy cập mạng cục bộ :

  • iptables -A OUTPUT -m owner --gid-owner no-internet -d 192.168.1.0/24 -j ACCEPT
  • iptables -A OUTPUT -m owner --gid-owner no-internet -d 127.0.0.0/8 -j ACCEPT
  • iptables -A OUTPUT -m owner --gid-owner no-internet -j DROP

   6. Làm cho nó vĩnh viễn

   Một cách để áp dụng quy tắc iptables khi khởi động là thêm quy tắc dưới dạng dịch vụ với systemd

cat /usr/lib/systemd/system/nonet.service
[Unit]
Description=Nonet group iptable update
After=network.target
After=xsession.target
After=iptables.service
After=shorewall.service

[Service]
Type=oneshot
RemainAfterExit=true
StandardOutput=journal
ExecStart=/bin/bash /home/user/Scripts/Nonet.iptables.sh

1
Đây là một hướng dẫn nghiêm túc xuất sắc. Cảm ơn bạn. Mặc dù, đối với tôi, lệnh không có internet của tôi dường như không bao giờ vượt qua tham số, vì vậy sg no-internetbây giờ tôi đang sử dụng .
Zach Bloomquist

@Zach tôi đã cập nhật câu trả lời của tôi, bạn có thể quan tâm đến firejail;)
intika

2

Nó phụ thuộc vào bản phân phối bạn đang sử dụng nhưng đó là một tính năng thường có trong hệ thống MAC của HĐH. Như đã nêu trước đây, Ubuntu hoặc AppArmor của SuSE có thể làm điều này. Nếu bạn đang sử dụng RHEL, bạn có thể định cấu hình SELinux để cho phép hoặc từ chối quyền truy cập vào một số cổng cụ thể dựa trên nhãn của quy trình thực thi. Đây là tất cả những gì tôi có thể tìm thấy sau một số thông tin nhanh nhưng có lẽ có nhiều tài nguyên chuyên sâu hơn trên mạng nếu bạn chăm chỉ hơn và nó cung cấp cho bạn ý tưởng chung.


2

Bạn có thể sử dụng seccomp-bpf để chặn một số cuộc gọi hệ thống. Ví dụ có thể muốn chặnsocket cuộc gọi hệ thống để ngăn quá trình tạo ổ cắm FD.

Tôi đã viết một ví dụ về phê duyệt này để ngăn socketcuộc gọi hệ thống hoạt động bằng libseccomp. Tóm tắt là (không kiểm tra lỗi):

scmp_filter_ctx ctx = seccomp_init(SCMP_ACT_ALLOW);
seccomp_arch_add(ctx, SCMP_ARCH_NATIVE);
seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EACCES), SCMP_SYS(socket), 1, SCMP_CMP(0, SCMP_CMP_EQ, pf));
seccomp_load(ctx);
execvp(argv[1], argv+1);

Điều này không cần đặc quyền gốc.

Tuy nhiên, một hộp cát hoàn chỉnh phức tạp hơn nhiều, vì vậy bạn không nên sử dụng lệnh không theo thứ tự này để chặn các chương trình không hợp tác / độc hại.


Bạn có thể cho một ví dụ về cách sử dụng này? Nó có yêu cầu quyền root để làm việc không?
bonanza

-4

Bạn có thể sử dụng chương trình dòng lệnh gọi là "proxychains" và thử một trong các khả năng sau:

Thiết lập nó sử dụng ...

  • ... một proxy không tồn tại? (Tôi không biết liệu nó có chạy nó với proxy "không hợp lệ" không)
  • ... một proxy cục bộ (như "tinyproxy", "squid", "privateoxy", ...) có giới hạn quyền truy cập vào internet không? (Chỉ cần sử dụng ACL)

Tôi chưa tự mình kiểm tra nên tôi không biết nó có hoạt động không ...


Đăng các giải pháp chưa được kiểm tra thường không phải là một ý tưởng tốt.
Twirrim

proxychains với proxy không tồn tại (như localhost: 1234 hoặc tương tự) thực sự có thể là một cách tiếp cận vững chắc, tuy nhiên
phil294
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.