Блокувати доступ до мережі до процесу?


74

Чи можна заблокувати доступ до (вихідної) мережі до одного процесу?


6
Як ви маєте намір визначити процес? ПІД, ім’я, шлях?
Марко

1
Який доступ ви хочете заблокувати? Деякі програми використовують роботу мережі через localhost(до тієї ж машини), щоб виконувати свою роботу.
фонбранд

Див. Також LD_PRELOAD або подібне, щоб запобігти доступу до мережі , якщо процес співпрацює.
Жиль

Відповіді:


78

З Linux 2.6.24+ (вважається експериментальним до 2.6.29), ви можете використовувати для цього простори мережних імен. Потрібно, щоб у вашому ядрі ( CONFIG_NET_NS=y) та util-linux за допомогою unshareінструмента були включені 'простори мережних імен' .

Потім запустити процес без доступу до мережі так само просто:

unshare -n program ...

Це створює порожній простір мережевих імен для процесу. Тобто він запускається без мережевих інтерфейсів, включаючи відсутність циклу . У нижченаведеному прикладі ми додаємо -r для запуску програми лише після того, як поточні ефективні ідентифікатори користувачів та групи були зіставлені на суперпользовательские (уникайте sudo):

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

Якщо вашому додатку потрібен мережевий інтерфейс, ви можете встановити новий:

$ 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

Зауважте, що це створить нову локальну петлю. Тобто, породжений процес не зможе отримати доступ до відкритих портів хосту 127.0.0.1.


Якщо вам потрібно отримати доступ до оригінальної мережі всередині простору імен, ви можете використовувати nsenterдля введення іншого простору імен.

Наступний приклад працює pingз мережевим простором імен, який використовується PID 1 (він вказаний через -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 -nздається, кидає "Операція не дозволена" без rootпривілеїв, чогось мені про це не вистачає?
лисини

1
Можливо, дурне запитання ... чи застосовується цей простір імен і для дочірніх процесів / названих процесів безприкладного застосування?
bonanza

3
Так. Його успадковують усі діти, які породжуються після переключення простору імен.
Michał Górny

2
Я схожа на будь-яку програму, яку я хотів би скасувати, наприклад, з sudo unshare -nуспадкованою кореневою правою. Оскільки мені потрібен sudo для виклику unshare, мені цікаво, як я можу переконатися, що названа програма не має кореневих прав.
бонанса

3
Один лайнер для обмеження процесу користувачем. Просто sudo unshare -n sudo -u dude bash -c 'echo Hello, my name is $USER'судо двічі: @ThorSummoner bbs.archlinux.org/viewtopic.php?id=205240
Якуб

21

У Linux є функція під назвою простори мережних імен, яка дозволяє вам по суті мати кілька мережевих стеків на одній машині та призначити її програмі під час її запуску. Це функція, яка зазвичай використовується для контейнерів, але ви також можете використовувати її для досягнення потрібного.

У ip netnsпідкоманду керувати ним. Створити нову мережеву область імен без доступу до чогось просто, це стан за умовчанням для нового простору імен:

root@host:~# ip netns add jail

Тепер, якщо ви перейдете на цю область імен, ви можете налаштувати її досить легко. Ймовірно, ви захочете виховувати це в цьому, і все:

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

Тепер, коли ви хочете запустити свою команду без мережі, просто запустіть її в цій в'язниці:

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

Мережа, як бажано, недосяжна. (Ви можете робити всілякі цікаві речі, оскільки окремий стек мережі включає iptablesправила тощо)


Хоча мені потрібно sudo ipбуло виконувати команди ip, як тільки я потрапив у bash, я просто виконав, su someuserщоб отримати непривілейовану оболонку для користувача 'someuser'.
шавлія

11

Ви можете використовувати iptables і перемістити цей процес у групу:

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
як видалити Pid з цих завдань, подати помилку, коли я намагаюся видалити або видалити дані з цього файлу, хоча я з користувачем root
pkm

@pkm, щоб увімкнути мережу назад, вам потрібно лише відлучити [pid] до /sys/fs/cgroup/net_cls/tasks(немає "блоку" на шляху)
горе

10

Так, із налаштованим профілем apparmor, тобто

/usr/bin/curl {
    ...

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

}

Але таким чином вам потрібно буде сформувати список дозволених файлів, щоб отримати доступ, і вся процедура може бути трохи складною. І дивіться довідковий документ тут


7

Можна використовувати пісочницю firejail (має працювати над ядрами з функцією seccomp).

Для його використання просто зробіть

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

--noprofileвимикає пісочницю за замовчуванням --net=noneвимикає мережу

Я вважаю, що більшість дистрибутивів надають пакет вже, але навіть якщо вони не firejail практично не мають ніяких залежностей, крім ядра з підтримкою набору інструментів та ядра з підтримкою простору імен / seccomp.

Є ще деякі приємні функції firejail, які можна продемонструвати firejail --helpщодо мереж (наприклад, лише надання інтерфейсу зворотного зв'язку або блокування ip / dns тощо), але це повинно зробити цю роботу. Також, це doesn't require root.


5

Ви не можете зробити це лише з iptables. Ця функція коротко існувала , але не змогла надійно працювати, і її було відмовлено.

Якщо ви можете запустити процес як виділений ідентифікатор користувача, iptables може зробити це за допомогою ownerмодуля:

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

Дивіться приклади в Iptables: узгодження вихідного трафіку з conntrack та власником. Працює з дивними краплями , iptables / pf правилом, щоб дозволити додаток / користувач XY?

Якщо ви можете запустити процес у своєму власному контейнері, ви можете його брандмауер самостійно (навіть зробити його повністю відключеним від мережі).

Модуль захисту може фільтрувати доступ процесу до функцій мереж. відповідь warl0ck дає приклад із AppArmor.


3

Рішення 1: Брандмауер:

Ми можемо використовувати брандмауери на зразок Douane або Opensnitch, Але ці програми не є на 100% ефективними або на ранній стадії розробки (мають багато помилок тощо на 2019 рік)

Рішення 2: MAC ядра:

MAC ядра можна використовувати як брандмауер. Найвідоміші - Tomoyo , Selinux та Apparmor. Це рішення є найкращим, коли стосується стабільності та ефективності (рішення брандмауера), але більшу частину часу встановити це якось складно.

Рішення 3: Firejail:

Firejail можна використовувати для блокування доступу до мережі для додатків, для цього не потрібен root, будь-який користувач може отримати від нього користь

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

Рішення 4: Скасувати загальний доступ

Unshare може запустити додаток на іншому ім'янебезпечному режимі без мережі, але для цього потрібне рішення root firejail зробити майже те саме, але не вимагає root

unshare -r -n application-comand

Рішення 5: Проксифікувати:

Одне рішення - проксифікувати додаток до нульового / підробленого проксі. Ми можемо використовувати tsocks або proxybound . Ось деякі деталі щодо налаштування

Рішення 6: Iptables:

Іншим простим рішенням є iptables, це може бути налаштування для блокування програми

  1. Створення, підтвердження нової групи ; додати потрібних користувачів до цієї групи:
    • Створити: groupadd no-internet
    • Перевірка: grep no-internet /etc/group
    • Додати користувача: useradd -g no-internet username

      Примітка. Якщо ви змінюєте вже існуючого користувача, слід запустити: usermod -a -G no-internet userName позначте:sudo groups userName

  2. Створіть сценарій на своєму шляху і зробіть його виконуваним:
    • Створити: nano /home/username/.local/bin/no-internet
    • Виконаний: chmod 755 /home/username/.local/bin/no-internet
    • Зміст: #!/bin/bash
                    sg no-internet "$@"

  3. Додайте правило iptables для відмови від мережевої активності для групи без Інтернету :


   4. Перевірте це, наприклад, у Firefox, запустивши:

  • no-internet "firefox"

   5. Якщо ви хочете зробити виняток і дозволити програмі отримати доступ до локальної мережі :

  • 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. Зробіть його постійним

   Один із способів застосувати правило iptables під час завантаження - додати це правило як послугу з 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
Це серйозно відмінне керівництво. Дякую. Хоча для мене моя команда без Інтернету ніколи не здавалася параметром, тому я зараз використовую sg no-internet.
Зак Блумквіст

@Zach я оновив свою відповідь, можливо, вас зацікавить firejail;)
intika

2

Це залежить від того, який дистрибутив ви використовуєте, але це функція, яка зазвичай входить у систему MAC ОС. Як було сказано раніше, Ubuntu або SuSE's AppArmor можуть це зробити. Якщо ви використовуєте RHEL, ви можете налаштувати SELinux так, щоб дозволити або заборонити доступ до певного номера порту на основі мітки процесу виконання. Це все, що я міг би знайти після швидкого гуглінгу, але, можливо, в Інтернеті є більш глибокі ресурси, якщо ти виглядаєш важче, і це дає тобі загальну думку.


2

Ви можете використовувати seccomp-bpf для блокування деяких системних викликів. Наприклад, можливо, потрібно заблокуватиsocket системний виклик, щоб запобігти створенню FD розеток.

Я написав приклад цього підходу, який заважає socketсистемному виклику працювати за допомогою libseccomp. Підсумок: (без перевірки помилок):

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);

Для цього не потрібно кореневих привілеїв.

Повна пісочниця є набагато складнішою, тому вам не слід використовувати це замовлення для блокування некооперативних / шкідливих програм.


Чи можете ви навести приклад, як це використовувати? Чи потрібні кореневі привілеї для роботи?
bonanza

-4

Ви можете скористатися програмою командного рядка під назвою "proxychains" і спробувати одну з наступних можливостей:

Встановіть, що він використовує ...

  • ... проксі, який не існує? (Я не знаю, чи буде він запускати його з "недійсним" проксі)
  • ... локальний проксі (наприклад, "tinyproxy", "squid", "privoxy", ...), який обмежує доступ до Інтернету? (Просто використовуйте ACL)

Я сам його не тестував, тому не знаю, чи працює він ...


Опублікувати неперевірені рішення, як правило, не є хорошою ідеєю.
Twirrim

proxychains з неіснуючим проксі (наприклад, localhost: 1234 тощо), насправді, може бути надійним підходом, однак
phil294
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.