Можно ли заблокировать (исходящий) доступ к сети одного процесса?
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
унаследовал права root. Поскольку мне нужен sudo для вызова unshare, мне интересно, как я могу убедиться, что вызываемая программа не имеет прав root.
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
Теперь, если вы переключитесь на это пространство имен, вы можете настроить его довольно легко. Вы, вероятно, захотите поднять в нем lo, вот и все:
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 и переместить этот процесс в cgroup:
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
(без 'block' в пути)
Да, с настроенным профилем apparmor, т.е.
/usr/bin/curl {
...
# block ipv4 acces
deny network inet,
# ipv6
deny network inet6,
# raw socket
deny network raw,
}
Но в этом случае вам также потребуется сгенерировать список разрешенных файлов для доступа, вся процедура может быть немного сложной. И см. Справочный документ здесь
Вы можете использовать firejail sandbox (должен работать на ядрах с функцией 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 / правило пФ только позволяют приложения 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
Unshare может запускать приложение в другом домене без сети, но для этого требуется, чтобы решение root firejail делало почти то же самое, но не требует root
unshare -r -n application-comand
Решение 5: Proxify:
Одним из решений является прокси приложения к пустому / поддельному прокси. Мы можем использовать 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 AppArmor могут это сделать. Если вы используете RHEL, вы можете настроить SELinux, чтобы разрешить или запретить доступ к определенному номеру порта на основе метки исполняемого процесса. Это все, что я смог найти после некоторого быстрого поиска в Google, но в Интернете, возможно, есть более глубокие ресурсы, если вы посмотрите более усердно, и это дает вам общее представление.
Вы можете использовать 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» и попробовать одну из следующих возможностей:
Настройте, что он использует ...
Я не проверял это сам, поэтому я не знаю, работает ли он ...