Блокировать сетевой доступ процесса?

74

Можно ли заблокировать (исходящий) доступ к сети одного процесса?

larkee
источник
6
Как вы намерены определить процесс? PID, имя, путь?
Марко
1
Какой доступ вы хотите заблокировать? Некоторые программы используют доступ localhostк сети через (к тому же компьютеру) для выполнения своей работы.
vonbrand
См. Также 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привилегий, что-то я пропустил об этом?
baldrs
1
Может быть, глупый вопрос ... это пространство имен также применимо к дочерним процессам / вызываемым процессам неразделенного приложения?
Bonanza
3
Да. Он наследуется всеми потомками, порожденными после переключения пространства имен.
Михал Гурны
2
Я похож на любую программу, которую я хотел бы отменить, например, sudo unshare -nунаследовал права root. Поскольку мне нужен sudo для вызова unshare, мне интересно, как я могу убедиться, что вызываемая программа не имеет прав root.
Bonanza
3
Один лайнер, чтобы ограничить процесс для пользователя. Просто дважды sudo: 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

Теперь, если вы переключитесь на это пространство имен, вы можете настроить его довольно легко. Вы, вероятно, захотите поднять в нем 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правила и т. Д.)

derobert
источник
Хотя мне нужно sudo ipбыло выполнять команды ip, как только я попал в bash, я просто su someuserзапустил, чтобы получить непривилегированную оболочку для пользователя 'someuser'.
мудрец
11

Вы можете использовать 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
Ян Мюллер
источник
1
как удалить pid из этого файла задач, он дает ошибку при попытке удалить или удалить данные из этого файла, хотя я с правами пользователя root
pkm
@pkm, чтобы включить сетевое взаимодействие, вам нужно только повторить [pid] в /sys/fs/cgroup/net_cls/tasks(без 'block' в пути)
Горе
10

Да, с настроенным профилем apparmor, т.е.

/usr/bin/curl {
    ...

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

}

Но в этом случае вам также потребуется сгенерировать список разрешенных файлов для доступа, вся процедура может быть немного сложной. И см. Справочный документ здесь

маргаритка
источник
7

Вы можете использовать firejail sandbox (должен работать на ядрах с функцией seccomp).

Чтобы использовать это просто сделать

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

--noprofileотключает песочницу по умолчанию --net=noneотключает сеть

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

Есть некоторые другие приятные особенности firejail, которые могут быть показаны в firejail --helpотношении работы в сети (например, только предоставление интерфейса обратной связи или блокировка ip / dns и т. Д.), Но это должно сработать. Кроме того, это doesn't require root.

pruzinat
источник
5

Вы не можете сделать это только с помощью iptables. Эта особенность существовала недолго , но ее нельзя было заставить работать надежно, и она была заброшена.

Если вы можете запустить процесс как выделенный идентификатор пользователя, iptables может сделать это с помощью ownerмодуля:

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

Смотрите примеры в Iptables: сопоставление исходящего трафика с conntrack и владельцем. Работает со странным капель , IPTables / правило пФ только позволяют приложения 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

Unshare может запускать приложение в другом домене без сети, но для этого требуется, чтобы решение root firejail делало почти то же самое, но не требует root

unshare -r -n application-comand

Решение 5: Proxify:

Одним из решений является прокси приложения к пустому / поддельному прокси. Мы можем использовать 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
intika
источник
1
Это действительно отличный гид. Спасибо. Хотя для меня моя команда no-internet никогда не передавала параметр, поэтому я использую sg no-internetсейчас.
Зак Блумквист
@ Зач я обновил свой ответ, возможно, вас заинтересует firejail;)
intika
2

Это зависит от того, какой дистрибутив вы используете, но эта функция обычно включена в систему MAC ОС. Как указывалось ранее, Ubuntu или SuSE AppArmor могут это сделать. Если вы используете RHEL, вы можете настроить SELinux, чтобы разрешить или запретить доступ к определенному номеру порта на основе метки исполняемого процесса. Это все, что я смог найти после некоторого быстрого поиска в Google, но в Интернете, возможно, есть более глубокие ресурсы, если вы посмотрите более усердно, и это дает вам общее представление.

Bratchley
источник
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);

Это не нуждается в привилегиях суперпользователя.

Однако полная песочница намного сложнее, поэтому вам не следует использовать этот приказ для блокировки неработоспособных / вредоносных программ.

ysdx
источник
Не могли бы вы привести пример, как это использовать? Требуются ли для работы права root?
золотое дно
-4

Вы можете использовать программу командной строки под названием «proxychains» и попробовать одну из следующих возможностей:

Настройте, что он использует ...

  • ... прокси, который не существует? (Я не знаю, будет ли он работать с «недействительным» прокси)
  • ... локальный прокси (например, "tinyproxy", "squid", "privoxy", ...), который ограничивает доступ к Интернету? (Просто используйте ACL)

Я не проверял это сам, поэтому я не знаю, работает ли он ...

drkhsh
источник
Опубликовать непроверенные решения, как правило, не очень хорошая идея.
Twirrim
прокси-цепочки с несуществующим прокси-сервером (например, localhost: 1234 и т. п.), на самом деле, могут быть надежным подходом
phil294