После долгих проб и ошибок я смог найти ответ на свой вопрос. Проблема была не в iptables или версии Ubuntu/Linux, которую я использовал, а скорее в третьем правиле:
/sbin/iptables -A OUTPUT -p udp --dport 53 -m owner --gid-owner internet -j ACCEPT
Поскольку порт udp/53
используется для разрешения имен DNS, фоновые службы, такие как dnsmasq
, могли использовать их, поэтому разрешение имен не происходило, когда я пытался запустить программу с группой internet
, так как эти другие службы не было в этой группе. Однако в идеале эти службы должны иметь доступ к порту, поскольку они работают под учетной записью root (, а root может делать все что угодно! ), но дизайн модуля владельца iptables, похоже, не учитывает такие привилегии root.
Как только я удалил проверку модуля владельца из этого последнего правила, интернет заработал:
/sbin/iptables -A OUTPUT -p udp --dport 53 -j ACCEPT
Редактировать
Другая, не связанная напрямую, но связанная проблема связана с использованием модуля владельца для корневой группы. Мы склонны назначать корневой группе доступ к Интернету (в дополнение или вместо группы internet
)следующим образом:
/sbin/iptables -A OUTPUT -p tcp --dport 80 -m owner --gid-owner root -j ACCEPT
Однако на практике это не работает, потому что многие приложения не используют пользователя root для подключения к Интернету из соображений безопасности. Например, следующая команда не будет работать даже после выполнения вышеописанного:
sudo apt-get update
Это потому, что apt
программа внутри использует пользователя _apt
для загрузки пакетов из соображений безопасности.
Проанализировав исходный код NetworkManager, я обнаружил проблему. NetworkManager заблокирует соединение от автоматического -соединения, если не сможет получить секреты из набора ключей. Похоже, что это поведение -не настраивается и жестко прописано в nm -policy.c :
.https://github.com/NetworkManager/NetworkManager/blob/master/src/nm-policy.c
Рядом со строкой 1830 есть следующий фрагмент кода:
if (nm_device_state_reason_check (reason) == NM_DEVICE_STATE_REASON_NO_SECRETS) {
/*... */
con_v = nm_settings_connection_get_last_secret_agent_version_id (sett_conn);
if ( con_v == 0
|| con_v == nm_agent_manager_get_agent_version_id (priv->agent_mgr))
block_no_secrets = TRUE;
}
if (block_no_secrets) {
_LOGD (LOGD_DEVICE, "connection '%s' now blocked from autoconnect due to no secrets",
nm_settings_connection_get_id (sett_conn));
nm_settings_connection_autoconnect_blocked_reason_set (sett_conn, NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_NO_SECRETS, TRUE);
}
Самый простой способ обойти это поведение и заставить NetworkManager НЕ блокировать соединение при автоматическом -подключении — это не устанавливать для block_no_secrets
значение TRUE (, а просто установить для него значение FALSE или полностью удалить первый оператор if ).