Как запретить процессу знать, что Сеть работает? [closed]

Сначала давайте заблокируем все входящие и исходящие сигналы
через iptables.

vi / etc / sysconfig / iptables

*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A OUTPUT -j DROP
-A INPUT -j DROP
-A FORWARD -j DROP
COMMIT

start iptables:

 service iptables start

Мой кабель Ethernet подключен. давайте попробуем что-нибудь через терминал

ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.

, вот и все. всего 1 строчка. после этого он останавливается . очевидно, что iptables успешно блокирует его

, теперь я собираюсь отсоединить свой кабель Ethernet. мой интернет отключен.

давайте попробуем еще раз:

ping 8.8.8.8
connect: Network is unreachable

на этот раз ... мгновенно ... он вернет это сообщение.

Ясно, что это "пинг" или любая другая программа .. она определяет, включен сетевой интерфейс или нет , прежде чем он выполнит свою интернет-команду.

конечно, как только он выполнится ... он не сможет пройти через правила iptable. но то, что кажется очевидным, это .. он не сначала обращается к iptables ..

он сначала проверяет, подключен ли сетевой интерфейс или нет.

Я хотел бы выяснить, как я могу вручную сообщить ему , что сетевой интерфейс подключен.

другими словами, если я не скажу ему, что сетевой интерфейс работает .. он должен вести себя так же, как и , когда сетевой интерфейс не подключен (когда Ethernet кабель не подключен)

как это можно сделать?

-4
задан 29 January 2017 в 17:24
1 ответ

Ясно, что это "пинг" или любая другая программа ... она определяет, включен сетевой интерфейс или нет, прежде чем он выполнит свою интернет-команду.

Нет, это не так. т. Вот (некоторые из) выходных данных strace ping 8.8.8.8 из системы без функционального сетевого интерфейса :

connect(4, {sa_family=AF_INET, sin_port=htons(1025), sin_addr=inet_addr("8.8.8.8")}, 16) = -1 NETUNREACH (Network is unreachable)

Чтобы ответить на ваш конкретный вопрос , когда процесс пользовательского пространства просит ядро ​​отправить данные в удаленную систему, когда нет доступной сетевой подсистемы, он возвращает ошибку, соответствующую ситуации. Обратите внимание на отсутствие какого-либо запроса о доступности сети; программа пользовательского пространства идет прямо вперед и запрашивает подключение, но сразу же выдает ошибку, потому что ядро ​​знает, что это не может быть выполнено. Это ничем не отличается от попытки записать файл в файловой системе, в которой недостаточно места (ошибка 28, на устройстве нет места) или когда вы превысили свою дисковую квоту (ошибка 122, дисковая квота превышена) (коды ошибок приняты с благодарностью из здесь ).

Изменить : Я подозревал, что ваш следующий вопрос будет: « как мне вернуть эту ошибку в каждом конкретном случае », но Я счел разумным позволить вам все равно спросить. Как вам уже неоднократно говорили, лучший способ сделать это - использовать iptables -j REJECT , поскольку полученная ошибка точно так же передается обратно запрашивающему процессу. Вот пример в той же системе с включенной сетью, но одно правило iptables -I OUTPUT 1 -j REJECT запрещает весь трафик OUTPUT (NB это не очень хорошо идея в реальной жизни ):

sendmsg(3, {msg_name(16)={sa_family=AF_INET, sin_port=htons(0), sin_add=inet_addr("8.8.8.8")}, msg_iov(1)=[{"...."..., 64}], msg_controlln=0, msg_flags=0}, 0) = -1 EPERM (Operation not permitted)

С различными вызовами -j REJECT --reject-with ... различные ошибки передаются обратно запрашивающему процессу, но все они приводят к передаче ошибки.

Редактировать 2 : Ваша ментальная модель сетевого стека UNIX просто неверна, и идеи, которые вы сформировали из нее, неисправный; в частности iptables - это ядро ​​(*). Частично проблема может заключаться в том, что некоторые программы игнорируют некоторые ошибки, некоторые отмечают их, но продолжают работу, а некоторые завершаются. Любая конкретная программа сама решает, что она будет делать с той или иной ошибкой. Программа ping , например, завершается на ENETUNREACH , но на EPERM она просто записывает ошибку в stderr и продолжает работу. Если я правильно понимаю, это поведение, против которого вы возражаете.

Это не то, что вы можете контролировать, если вы не пишете программу . Я понимаю, что вы хотели бы, чтобы ядро ​​отправляло ошибку, которую программа не игнорирует, но ядро ​​(в нынешних условиях) не будет делать это за вас. Ничто не мешает вам написать модифицированное ядро, которое сигнализирует обо всех ошибках с помощью SIGKILL, но Linux в настоящее время этого не делает, и большинство из нас этого не хочет.

(*) Чтобы быть точным, iptables - это программа пользовательского пространства, которая позволяет нам управлять структурами netfilter внутри ядра. Но результирующая обработка пакетов и ошибок определенно является явлением пространства ядра, а не пространства пользователя.

4
ответ дан 5 December 2019 в 22:06

Теги

Похожие вопросы