Как разрешить DNS через фильтрацию интерфейсов с помощью iptables в Ubuntu Headless
Я видел несколько вопросов, относящихся к статическим DNS, запросам openVPN-серверов и т. Д., Но ни один из них не подходит, или они требуют инструментов с графическим интерфейсом, и я использую безголовое ядро Ubuntu, в которое я использую SSH.
root@redacted:~# lsb_release -a
Distributor ID: Ubuntu
Description: Ubuntu 14.04.3 LTS
Release: 14.04
Codename: trusty
Когда машина подключена только через eth0 к локальной сети, все работает нормально. Я могу пинговать IP-адреса напрямую (8.8.8.8) и разрешать доменные имена (google.com).
wget -q -O - ipecho.net/plain #Shows my ISPs provided Public IP
Когда машина подключена через tun0 с использованием сети VPN, я могу напрямую пропинговать IP-адреса (8.8.8.8) и разрешать доменные имена (google.com).
wget -q -O - ipecho.net/plain #Shows my VPNs provided Public IP
Все, как и ожидалось, пока...
Теперь проблема возникает... Я добавляю следующие правила iptables, чтобы заставить конкретного пользователя использовать только адаптер tun0:
sudo iptables -A OUTPUT -m owner --gid-owner vpnonly -o lo -j ACCEPT
sudo iptables -A OUTPUT -m owner --gid-owner vpnonly -o eth0 -p tcp -d 192.168.x.x/24 --sport xxxx -j ACCEPT
sudo iptables -A OUTPUT -m owner --gid-owner vpnonly \! -o tun0 -j REJECT
Если вам интересно, второе правило разрешает доступ к веб-интерфейсу в моей локальной сети, который запускается как пользователь vpnonly.
Так что теперь, когда я запускаю процессы, которые я не хочу иметь возможности общаться по общедоступному IP-адресу, таким образом предотвращая утечки, если VPN отключается / отключается / и т.д., я просто запускаю их под vpnonly, единственная группа которого vpnonly. ОДНАКО, когда я запускаю процесс как vpnonly, я могу напрямую пропинговать IP-адреса (8.8.8.8), но не могу разрешить доменные имена (google.com).
root@redacted:~# sudo -u vpnonly ping -c 2 google.com
ping: unknown host google.com
Даже если бы я мог получить разрешение на повторное разрешение доменных имен, это было бы удовлетворительно, но я бы ДЕЙСТВИТЕЛЬНО хотел бы сделать так, чтобы просто настроить VPN на использование отдельного конкретного DNS, оставив eth0 для использования 8.8.8.8, 8.8.4.4.
Я погуглил все, что мог придумать, связанный с этим и не могу решить... Надеюсь, я добавил достаточно подробностей, но с удовольствием добавлю больше по запросу
РЕДАКТИРОВАТЬ 1: Полный Iptables
root@redacted:~# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all -- anywhere anywhere owner GID match vpnonly
ACCEPT tcp -- anywhere 192.168.x.x/24 owner GID match vpnonly tcp spt:xxxx
REJECT all -- anywhere anywhere owner GID match vpnonly reject-with icmp-port-unreachable
-
root@redacted:~# iptables -L -v
Chain INPUT (policy ACCEPT 16407 packets, 12M bytes)
pkts bytes target prot opt in out source destination
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 6230 packets, 675K bytes)
pkts bytes target prot opt in out source destination
3751 2800K ACCEPT all -- any lo anywhere anywhere owner GID match vpnonly
6635 3332K ACCEPT tcp -- any eth0 anywhere 192.168.x.x/24 owner GID match vpnonly tcp spt:xxxx
4 224 REJECT all -- any !tun0 anywhere anywhere owner GID match vpnonly reject-with icmp-port-unreachable
Изменить 2:
Все работает правильно, пока не добавлены правила iptables, и единственной проблемой, с которой я сталкиваюсь, является разрешение доменных имен. Мой vpn также предоставляет DNS без регистрации. Будет ли решение этой проблемы изменить запись моего /etc/network/interfaces nameserver с 192.168.x.1 на IP-адрес DNS, предоставленный моей VPN, а затем разрешить все подключения к этому DNS-IP до отказа? Я хотел спросить, прежде чем пытаться, один, чтобы убедиться, что это было так же безопасно, как я полагаю, что это логично, и два, я предлагаю вознаграждение в любом случае. Я хочу убедиться, что нет утечек, и не хочу вводить их через DNS...
После дальнейшего просвещения, вместо того, чтобы изменять интерфейсы, я должен просто разрешить 192.168.x.1 и VPN DNS IP явно до отклонения?
То, что я ДЕЙСТВИТЕЛЬНО хотел бы сделать, это заставить эти запросы DNS через адаптер tun0, сделать ЛЮБОЙ обмен данными с внешним миром от пользователя "vpnonly" через VPN, если это вообще возможно.
2 ответа
Самый простой способ - создать сервис.conf, который сохранит любые правила iptables, которые вам нравятся.
Вы можете установить пакет, чтобы сделать это, но ручной способ таков:
sudo vi /etc/init/persist-iptables.conf
Вы можете назвать его как угодно, просто убедитесь, что он в /etc/init/
и заканчивается .conf
Затем вы хотите вставить следующие строки:
description "Persist IPTables on Boot"
start on runlevel [2345]
script
# Accept all loopback traffic localhost or 127.0.0.1
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
# Accept any DNS traffic, I use a DD-WRT router with
# Force DNS Redirection to a non-logging DNS
iptables -A OUTPUT -d 255.255.255.255 -j ACCEPT
iptables -A INPUT -s 255.255.255.255 -j ACCEPT
# Accept all local traffic from 192.168.1.1-192.168.1.255
iptables -A INPUT -s 192.168.1.0/24 -d 192.168.1.0/24 -j ACCEPT
iptables -A OUTPUT -s 192.168.1.0/24 -d 192.168.1.0/24 -j ACCEPT
# Forward all eth0, eth1, etc through tun interfaces
iptables -A FORWARD -i eth+ -o tun+ -j ACCEPT
iptables -A FORWARD -i tun+ -o eth+ -j ACCEPT
# Postroute masquerade through tun interfaces
iptables -t nat -A POSTROUTING -o tun+ -j MASQUERADE
# Drop any other traffic through eth adapters
iptables -A OUTPUT -o eth+ ! -d a.b.c.d -j DROP
end script
Теперь, когда ваша система перезагружается (что очищает ваши IP-таблицы), она будет запускаться автоматически, чтобы снова обновить iptables. Вы можете также назвать это самостоятельно с sudo service persist-iptables start
Этот файл разрешит весь трафик локального хоста, разрешит весь трафик DNS (это зависит от вас, чтобы убедиться, что это ПРАВИЛЬНЫЕ днс, поступающие с вашего маршрутизатора), разрешит весь локальный трафик, перенаправит трафик с адаптеров eth на адаптер tun и пострассирует его, и, наконец, отбросить любой другой трафик.
Первый вопрос, можете ли вы получить доступ к вашему DNS-серверу? Если вы блокируете доступ ко всем, кроме tun0, возможно, вы блокируете доступ к DNS.
Если вы используете какой-либо DNS-сервер, локально заполненный Bind, или что-то вроде dnsmasq, то эта служба также должна иметь доступ к Интернету.
Я бы предложил добавить запись журнала в ваши iptables, прежде чем отклонять, чтобы увидеть, какой трафик отклоняется.
Использование порта 53 является стандартным способом преодоления безопасности, поэтому открытие *:53, вероятно, неразумно, поэтому вам лучше всего конкретно назначить свой DNS-сервер (локальный и восходящий) в качестве приемлемых целей для трафика. Я предполагаю, что --sport xxxx вы подразумевали, что используете нестандартный порт вместо:80 для своего веб-сервиса. Если нет, вы должны указать это в своем правиле 192.168 (то же самое для IP, это должен быть полный адрес /32).
Также не забывайте, что если вы хотите использовать ping для тестирования, вам нужно настроить iptable-записи для ICMP. ICMP 8 (эхо) является пингом, ICMP 0 является пинг-ответом.
Также стоит подумать, какие маршруты у вас есть, так как вам нужно убедиться, что для трафика по умолчанию задан tun0. Если tun0 - единственный допустимый интерфейс, вам нужно убедиться, что все маршруты, которые вам нужны, отправляют трафик таким образом.
Если это не помогает диагностировать ваши проблемы, используйте ethtool, чтобы провести анализ сети, чтобы узнать, какие разговоры происходят, а какие нет. Это может быть что-то странное, например, REQ разрешен, но ACK не возвращается.