Чи можна заблокувати доступ до (вихідної) мережі до одного процесу?
localhost
(до тієї ж машини), щоб виконувати свою роботу.
Чи можна заблокувати доступ до (вихідної) мережі до одного процесу?
localhost
(до тієї ж машини), щоб виконувати свою роботу.
Відповіді:
З 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
unshare -n
здається, кидає "Операція не дозволена" без root
привілеїв, чогось мені про це не вистачає?
sudo unshare -n
успадкованою кореневою правою. Оскільки мені потрібен sudo для виклику unshare, мені цікаво, як я можу переконатися, що названа програма не має кореневих прав.
sudo unshare -n sudo -u dude bash -c 'echo Hello, my name is $USER'
судо двічі: @ThorSummoner bbs.archlinux.org/viewtopic.php?id=205240
У 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'.
Ви можете використовувати 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
/sys/fs/cgroup/net_cls/tasks
(немає "блоку" на шляху)
Так, із налаштованим профілем apparmor, тобто
/usr/bin/curl {
...
# block ipv4 acces
deny network inet,
# ipv6
deny network inet6,
# raw socket
deny network raw,
}
Але таким чином вам потрібно буде сформувати список дозволених файлів, щоб отримати доступ, і вся процедура може бути трохи складною. І дивіться довідковий документ тут
Можна використовувати пісочницю firejail (має працювати над ядрами з функцією seccomp).
Для його використання просто зробіть
firejail --noprofile --net=none <path to executable>
--noprofile
вимикає пісочницю за замовчуванням
--net=none
вимикає мережу
Я вважаю, що більшість дистрибутивів надають пакет вже, але навіть якщо вони не firejail практично не мають ніяких залежностей, крім ядра з підтримкою набору інструментів та ядра з підтримкою простору імен / seccomp.
Є ще деякі приємні функції firejail, які можна продемонструвати firejail --help
щодо мереж (наприклад, лише надання інтерфейсу зворотного зв'язку або блокування ip / dns тощо), але це повинно зробити цю роботу. Також, це doesn't require root
.
Ви не можете зробити це лише з iptables. Ця функція коротко існувала , але не змогла надійно працювати, і її було відмовлено.
Якщо ви можете запустити процес як виділений ідентифікатор користувача, iptables може зробити це за допомогою owner
модуля:
iptables -A OUTPUT -m owner --uid-owner 1234 -j DROP
Дивіться приклади в Iptables: узгодження вихідного трафіку з conntrack та власником. Працює з дивними краплями , iptables / pf правилом, щоб дозволити додаток / користувач XY?
Якщо ви можете запустити процес у своєму власному контейнері, ви можете його брандмауер самостійно (навіть зробити його повністю відключеним від мережі).
Модуль захисту може фільтрувати доступ процесу до функцій мереж. відповідь warl0ck дає приклад із AppArmor.
Рішення 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, це може бути налаштування для блокування програми
groupadd no-internet
grep no-internet /etc/group
useradd -g no-internet username
usermod -a -G no-internet userName
позначте:sudo groups userName
nano /home/username/.local/bin/no-internet
chmod 755 /home/username/.local/bin/no-internet
#!/bin/bash
sg no-internet "$@"
iptables -I OUTPUT 1 -m owner --gid-owner no-internet -j DROP
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
sg no-internet
.
Це залежить від того, який дистрибутив ви використовуєте, але це функція, яка зазвичай входить у систему MAC ОС. Як було сказано раніше, Ubuntu або SuSE's AppArmor можуть це зробити. Якщо ви використовуєте RHEL, ви можете налаштувати SELinux так, щоб дозволити або заборонити доступ до певного номера порту на основі мітки процесу виконання. Це все, що я міг би знайти після швидкого гуглінгу, але, можливо, в Інтернеті є більш глибокі ресурси, якщо ти виглядаєш важче, і це дає тобі загальну думку.
Ви можете використовувати 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);
Для цього не потрібно кореневих привілеїв.
Повна пісочниця є набагато складнішою, тому вам не слід використовувати це замовлення для блокування некооперативних / шкідливих програм.
Ви можете скористатися програмою командного рядка під назвою "proxychains" і спробувати одну з наступних можливостей:
Встановіть, що він використовує ...
Я сам його не тестував, тому не знаю, чи працює він ...