web-dev-qa-db-fra.com

Comment autoriser le DNS via le filtrage d'interface à l'aide d'iptables dans Ubuntu Headless

J'ai déjà vu certaines questions faisant référence aux DNS statiques, aux envois de serveurs openVPN, etc., mais aucune d'entre elles ne s'applique réellement ou nécessite des outils d'interface graphique et j'utilise un noyau sans tête Ubuntu dans lequel j'utilise SSH.

root@redacted:~# lsb_release -a
Distributor ID: Ubuntu
Description:    Ubuntu 14.04.3 LTS
Release:        14.04
Codename:       trusty

Lorsque la machine est uniquement connectée via eth0 au réseau local, tout fonctionne correctement. Je peux faire un ping directement sur les IP (8.8.8.8) et les noms de domaine résolus (google.com).

wget -q -O - ipecho.net/plain #Shows my ISPs provided Public IP

Lorsque la machine est connectée via tun0 via le réseau VPN, je peux envoyer une requête ping directement aux adresses IP (8.8.8.8) et aux noms de domaine résolus (google.com).

wget -q -O - ipecho.net/plain #Shows my VPNs provided Public IP

Tout comme prévu jusqu'ici ...

Maintenant, le problème vient ... J'ajoute les règles iptables suivantes pour forcer un utilisateur spécifique à ne pouvoir utiliser que l'adaptateur 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

Si vous êtes curieux, la deuxième règle permet de rendre accessible une interface utilisateur Web sur mon réseau local exécuté en tant qu'utilisateur vpnonly.

Alors maintenant, lorsque je lance des processus que je ne veux pas pouvoir communiquer sur mon IP publique, empêchant ainsi les fuites si le VPN tombe en panne/déconnecte/etc., je les exécute simplement sous vpnonly, dont le seul groupe est vpnonly. CEPENDANT lorsque j'exécute un processus en tant que vpnonly, je peux effectuer un ping directement sur les adresses IP (8.8.8.8) mais je ne le peux pas résoudre les noms de domaine (google.com).

root@redacted:~# Sudo -u vpnonly ping -c 2 google.com
ping: unknown Host google.com

Même si je pouvais le faire résoudre à nouveau les noms de domaine, ce serait satisfaisant, mais ce que j'aimerais VRAIMENT faire est de configurer JUSTE le VPN pour qu'il utilise un DNS spécifique et distinct, tout en laissant eth0 utiliser 8.8.8.8, 8.8. 4.4.

J'ai googlé tout ce que je peux penser en rapport avec cela et je ne peux pas le résoudre ... J'espère avoir ajouté suffisamment de détails, mais nous ajouterons volontiers d'autres éléments sur demande.

EDIT 1: Full 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

Edit 2:

Tout fonctionne correctement jusqu'à ce que les règles iptables soient ajoutées. À ce stade, le seul problème que je rencontre est la résolution du nom de domaine. Mon vpn fournit également un DNS non connecté. La solution serait-elle de changer mon entrée de serveur de noms/etc/network/interfaces de 192.168.x.1 en l'adresse IP DNS fournie par mon VPN, puis d'autoriser toutes les connexions à cette adresse IP DNS avant le rejet? Je voulais demander avant d'essayer, un pour m'assurer que c'était aussi sûr que je le crois logiquement, et deux j'offre une prime de toute façon. Je veux m'assurer qu'il n'y a pas de fuites et ne pas en introduire une via DNS ...

Après avoir approfondi les connaissances, plutôt que de modifier les interfaces, devrais-je simplement autoriser explicitement 192.168.x.1 et l’adresse IP du DNS VPN avant le rejet?

Ce que je voudrais VRAIMENT faire, c’est forcer ces requêtes DNS à travers l’adaptateur tun0, faire TOUTE communication avec le monde extérieur de l’utilisateur "vpnonly" passer par le VPN, dans la mesure du possible.

1
DeeJayh

Un moyen simple est de créer un service .conf qui conservera toutes les règles iptables que vous aimez.

Vous pouvez installer un paquet pour faire ceci, mais la manière manuelle est comme telle:

Sudo vi /etc/init/persist-iptables.conf

Vous pouvez le nommer comme bon vous semble, assurez-vous simplement qu'il se trouve dans /etc/init/ et qu'il se termine par .conf

Ensuite, vous voulez insérer les lignes suivantes:

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

Désormais, lorsque votre système redémarrera (ce qui effacera vos tables IP), il sera automatiquement exécuté pour mettre à jour à nouveau les iptables. Vous pouvez aussi appeler vous-même avec Sudo service persist-iptables start

Ce fichier autorisera tout le trafic localhost, autorisera tout le trafic DNS (c'est à vous de vous assurer qu'il s'agit du bon DNS provenant de votre routeur), autorisera tout le trafic local, transférera le trafic des adaptateurs eth à l'adaptateur tun et postroute le masquera, et enfin déposer tout autre trafic.

0
DeeJayh

Première question, pouvez-vous accéder à votre serveur DNS? Si vous bloquez l'accès à tous à l'exception de tun0, vous pouvez également bloquer l'accès au DNS.

Si vous utilisez un type de serveur DNS localement, soyez aussi complet que Bind, ou quelque chose comme Dnsmasq, ce service devra également pouvoir accéder à Internet.

Je suggérerais d'ajouter une entrée de journal à votre iptables, avant le rejet, pour voir quel trafic est rejeté.

L'utilisation du port 53 est un moyen standard de déjouer la sécurité. Il est donc probablement peu judicieux d'ouvrir *: 53. Vous ferez donc mieux de nommer spécifiquement votre serveur DNS (local et amont) comme cibles acceptables pour le trafic. Je suppose que par --sport xxxx, vous vouliez dire que vous utilisez un port non standard au lieu de: 80 pour votre service Web. Sinon, vous devriez spécifier cela dans votre règle 192.168 (idem pour l'IP, ce devrait être une adresse complète sur/32).

N'oubliez pas non plus que si vous souhaitez utiliser ping pour tester, vous devez configurer les entrées iptables pour ICMP. ICMP 8 (echo) est un ping, ICMP 0 est une réponse au ping.

Cela vaut également la peine de considérer vos itinéraires, car vous devrez vous assurer que le trafic par défaut est tun0. Si tun0 est la seule interface autorisée, vous devez vous assurer que tous les itinéraires dont vous avez besoin envoient le trafic de cette façon.

Si cela ne permet pas de diagnostiquer vos problèmes, utilisez ethtool pour détecter le réseau, pour voir quelles conversations ont lieu et quelles ne le sont pas. Cela pourrait être quelque chose de bizarre, comme si le REQ était autorisé mais que l'ACK ne revienne pas.

0
sibaz