Как разрешить 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 не возвращается.

Другие вопросы по тегам