[Iptables] Restreindre l'accès au serveur par OpenVPN

Hello à tous, :unamused:

Je m’adresse à vous parce que je galère un peu avec openVPN et Iptables.
J’ai installé OpenVPN sur mon serveur (Un dédié sous Debian Wheezy 64 bits) et sur mon PC et il fonctionne très bien, je peux m’y connecter etc.

Maintenant, j’aimerais rendre certains ports accessibles que si l’on passe par le VPN pour des raisons de sécurité. Cela permettrait, par exemple de mettre en place un site web interne (Intranet) qui ne serait accessible qu’à ceux qui sont connectés au VPN. Dans mon cas, c’est un poil plus sensible puisque je veux que seules les personnes qui ont le VPN puissent se connecter en SSH.
Dans cette phase de test, j’utilise le port 22 par défaut pour le ssh et 1194 pour OpenVPN.

Actuellement, les règles Iptables suivantes sont définies sur mon serveur dédié (iptables -L):

Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     udp  --  anywhere             anywhere             udp dpt:openvpn
DROP       all  --  anywhere             anywhere             state INVALID
ACCEPT     icmp --  anywhere             anywhere             limit: avg 2/sec burst 5
MY_DROP    tcp  --  anywhere             anywhere             tcpflags: FIN,SYN,RST,PSH,ACK,URG/NONE
MY_DROP    tcp  --  anywhere             anywhere             tcpflags: FIN,SYN/FIN,SYN
MY_DROP    tcp  --  anywhere             anywhere             tcpflags: SYN,RST/SYN,RST
MY_DROP    tcp  --  anywhere             anywhere             tcpflags: FIN,RST/FIN,RST
MY_DROP    tcp  --  anywhere             anywhere             tcpflags: FIN,ACK/FIN
MY_DROP    tcp  --  anywhere             anywhere             tcpflags: PSH,ACK/PSH
MY_DROP    tcp  --  anywhere             anywhere             tcpflags: ACK,URG/URG
 
Chain FORWARD (policy ACCEPT)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere
ACCEPT     tcp  --  anywhere             anywhere             tcpflags: FIN,SYN,RST,ACK/SYN limit: avg 1/sec burst 5
ACCEPT     tcp  --  anywhere             anywhere             tcpflags: FIN,SYN,RST,ACK/RST limit: avg 1/sec burst 5
ACCEPT     icmp --  anywhere             anywhere             icmp echo-request limit: avg 1/sec burst 5
 
Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     udp  --  anywhere             anywhere             udp dpt:openvpn
DROP       all  --  anywhere             anywhere             state INVALID
 
Chain MY_DROP (7 references)
target     prot opt source               destination
DROP       all  --  anywhere             anywhere

Mon idée: Ajouter une règle telle que: “iptables -A INPUT -i eth0 -p tcp --dport 22 -j DROP” puis une règle qui fasse exception pour les accès à ce port avec openVPN.

Problème: Je n’arrive pas à formuler cette règle ou la modification que je dois faire parce que je ne maîtrise pas assez iptables et le fonctionnement d’openVPN (interfaces réseaux et autres possibilités). Ce n’est pas faute d’avoir cherché mais les gens utilisent majoritairement des VPN pour cacher leur IP ou pour faire sauter des limitations liées à leur pays etc.

Pouvez-vous éclaircir ma lanterne sur la manière de faire ce filtrage?

Merci d’avance! :slightly_smiling:

Utilise plutôt iptables-save pour afficher les règles en place, c’est beaucoup plus facile à lire (et complet).

Tu n’as pas besoin d’exception à ta règle de blocage puisque les paquets provenant du VPN proviennent d’une interface différente d’eth0 : tun* ou tap* selon le type de VPN.

Concernant OpenVPN, de mémoire il crée une interface virtuelle genre [mono]tun0[/mono] (à vérifier avec [mono]ifconfig[/mono] par exemple) dont tu peux te servir dans [mono]iptables[/mono] pour identifier la provenance des paquets.

Edit : le reste c’est n’importe quoi, j’avais pas compris certains concepts. (voir les explications de Pascal) :blush:

Enfin, je ne sais pas si ça peut s’appliquer avec OpenVPN mais tu as aussi la possibilité de configurer la plupart des services (dont SSH) pour n’écouter que sur une interface/IP particulière. Si OpenVPN fournit [mono]tun0[/mono] et que ton service SSH n’écoute que sur cette interface (ou l’IP associée) alors tu n’as peut-être* même pas besoin de règles [mono]iptables[/mono] car il faut absolument que la connexion passe par [mono]tun0[/mono] pour pouvoir simplement arriver jusqu’à SSH.

(*) dans cette config il y a peut-être quand même une faille liée au routage automatique, si [mono]/proc/sys/net/ipv4/ip_forward[/mono] est à 1 (ce qui, si je ne m’abuse, doit être le cas si tu veux que tes clients VPN puissent accéder à autre chose que la machine serveur). Pascal, arrête moi si je dis des conneries. :mrgreen:
En tous cas ça vaut le coup d’expérimenter, car si ça marche ça rajoute encore de la sécurité.
Perso je me sers de cette méthode pour les services web d’administration qui sont sur un Apache séparé n’écoutant que sur localhost, services auxquels j’accède via du port forwarding SSH. Tu vois l’idée quoi.

Qu’entends-tu par routage “automatique” ?
ip_forward ne concerne pas le routage (qui s’applique à tout paquet émis ou reçu que la machine soit un routeur ou un hôte) mais la fonction “routeur”.
La fonction routeur ne concerne pas les paquets destinés à la machine elle-même mais seulement ceux reçus mais destinés à une autre machine.

Tu parles peut-être du fait que le noyau Linux applique le modèle d’hôte dit “faible” (weak host model), où n’importe quelle adresse locale (sauf les adresses de loopback dans 127.0.0.0/8) est accessible via n’importe quelle interface. Le service SSH n’écoutant que sur l’adresse de l’interface VPN serait donc accessible par l’interface ethernet du moment qu’on utilise l’adresse l’adresse de l’interface VPN. Si cette adresse n’est pas routée sur internet (notamment si c’est une adresse privée) alors l’exploitation de cette faille est limitée au réseau local directement connecté à l’interface ethernet.

C’est valable car les adresses de loopback sont l’exception à la règle du modèle faible : elles ne sont pas accessibles de l’extérieur.

Je veux dire avec [mono]ip_forward = 1[/mono], où tu n’as pas besoin de configurer quoi que ce soit spécifiquement pour bénéficier de la fonction routeur (si je me mélange pas trop les pinceaux, on peut arriver au même résultat avec [mono]ip_forward = 0[/mono] et des règles [mono]iptables[/mono] ? D’où le “automatique” par opposition à “manuel” quand tu dois toi-même spécifier les règles de forwarding).

[quote=“PascalHambourg”]ip_forward ne concerne pas le routage (qui s’applique à tout paquet émis ou reçu que la machine soit un routeur ou un hôte) mais la fonction “routeur”.
La fonction routeur ne concerne pas les paquets destinés à la machine elle-même mais seulement ceux reçus mais destinés à une autre machine.

Tu parles peut-être du fait que le noyau Linux applique le modèle d’hôte dit “faible” (weak host model), où n’importe quelle adresse locale (sauf les adresses de loopback dans 127.0.0.0/8) est accessible via n’importe quelle interface. Le service SSH n’écoutant que sur l’adresse de l’interface VPN serait donc accessible par l’interface ethernet du moment qu’on utilise l’adresse l’adresse de l’interface VPN.[/quote]
Effectivement j’ai confondu les deux. En fait je n’avais même aucune idée de l’existence du “weak host model” en tant qu’entité séparée, pour moi ça faisait partie intégrante de cette fonction routeur.
Vu que j’utilise très peu la fonction routeur (j’ai dû y toucher une fois… sur mon Pi que j’ai depuis reconverti en bête serveur :open_mouth:) je mélange un peu tout, et je croyais que ce “weak host model” (dont j’ai déjà constaté les effets, c’est bien pour ça que j’étais pas sûr de mon coup dans mon message précédent) ne fonctionnait que quand [mono]ip_forward = 1[/mono]. Avec tes explications je constate que je me suis planté en beauté. :laughing:

Du coup ma suggestion ne sert à rien en fait dans le cas présent, puisque les règles [mono]iptables[/mono] sont toujours nécessaires.

Bref, désolé pour le bruit inutile que j’ai provoqué, mais au moins je me coucherai un peu moins con ce soir. Comme chaque fois que tu me reprends, quoi. :stuck_out_tongue: Merci pour ces explications.

Non, on ne peut pas. iptables ne fait que du filtrage et de la modification de paquets, pas du routage.
C’est ce que j’aime dans GNU/Linux : un outil fait une chose.

Bon c’est ma soirée boulettes alors. :blush:
Comme quoi, même s’il y a pas mal de connaissances communes entre les dévs et les admins réseau, ça reste limité au final dès qu’on touche aux trucs un peu “avancés”… :wink:

Si je ne m’abuse, ip_forward est un truc qui dit : n’ignore pas les paquets qui sont pour le voisin.
Rapport avec IP & Mac, donc;

Une chose que tu peut faire c’est autoriser le trafique venant uniquement des client vpn sur le port concerné comme par exemple :

en adaptant l’adresse ip de ton client vpn… après je présume qu’il est possible d’autoriser le plage réseaux vpn…

Redondant puisque tout le trafic valide est déjà accepté par défaut (policy ACCEPT, pas de DROP/REJECT terminal).

pas exactement…

Si la règle par défaut est bloquer les ports en entrée, tu n’autorise que le réseaux du vpn à se connecter au port ssh…

[ edit ]: le fait d’accepter tout de trafic en entrée est pour moi une énorme faille de sécurité… la règle par défaut devrait être en DROP …!!!

Son firewall est une passoire…

Merci pour vos réponses :wink:

D’accord, je comprends mieux comment ça se passe, donc le problème doit être ailleurs puisque lorsque j’ajoute ma règle “iptables -A INPUT -i eth0 -p tcp --dport 22 -j DROP” la connexion est fermée (jusque là c’est normal) ensuite je me connecte à mon VPN (OpenVPN) et lorsque je re-tente de me connecter en SSH, ma connexion est refusée. Du coup, je lance un reboot depuis le pannel de mon hébergeur et je peux à nouveau me connecter (logique puisque j’ai pas encore mis la règle dans le script du firewall)
Une idée d’où pourrait venir le problème?
Ce serait lié à l’interface? Le VPN est censé utiliser tun0, j’ai vérifié elle existe. Et ma connexion passe belle et bien dans le VPN en tout cas je surfe avec l’IP de mon serveur. (Donc il a l’air de fonctionner correctement.)

[quote=“leo-25”]
[ edit ]: le fait d’accepter tout de trafic en entrée est pour moi une énorme faille de sécurité… la règle par défaut devrait être en DROP …!!!
Son firewall est une passoire…[/quote]

Effectivement, je devrais plutôt Whitelister que Blacklister, tu as raison.
En tout cas, si je faisais comme ça dans le cas présent, j’aurais toujours ce problème qui semble venir d’autre chose.

Je vous remets mes règles avec iptables-save: (D’autant plus que depuis l’autre jour suite à une erreur de ma part j’ai du réinstaller)

# Generated by iptables-save v1.4.14 on Sun Jan 12 23:51:20 2014
*raw
:PREROUTING ACCEPT [214123:204403323]
:OUTPUT ACCEPT [145080:203485906]
COMMIT
# Completed on Sun Jan 12 23:51:20 2014
# Generated by iptables-save v1.4.14 on Sun Jan 12 23:51:20 2014
*nat
:PREROUTING ACCEPT [324:20852]
:INPUT ACCEPT [82:8366]
:OUTPUT ACCEPT [491:91943]
:POSTROUTING ACCEPT [6:395]
-A POSTROUTING -o eth0 -j MASQUERADE
-A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
COMMIT
# Completed on Sun Jan 12 23:51:20 2014
# Generated by iptables-save v1.4.14 on Sun Jan 12 23:51:20 2014
*mangle
:PREROUTING ACCEPT [214123:204403323]
:INPUT ACCEPT [75128:9256237]
:FORWARD ACCEPT [138995:195147086]
:OUTPUT ACCEPT [145083:203486534]
:POSTROUTING ACCEPT [284078:398633620]
COMMIT
# Completed on Sun Jan 12 23:51:20 2014
# Generated by iptables-save v1.4.14 on Sun Jan 12 23:51:20 2014
*filter
:INPUT ACCEPT [610:84480]
:FORWARD ACCEPT [64804:190912294]
:OUTPUT ACCEPT [145065:203485886]
:MY_DROP - [0:0]
-A INPUT -p udp -m udp --dport 1194 -j ACCEPT
-A INPUT -m state --state INVALID -j DROP
-A INPUT -i venet0 -p icmp -m limit --limit 2/sec -j ACCEPT
-A INPUT -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -j MY_DROP
-A INPUT -p tcp -m tcp --tcp-flags FIN,SYN FIN,SYN -j MY_DROP
-A INPUT -p tcp -m tcp --tcp-flags SYN,RST SYN,RST -j MY_DROP
-A INPUT -p tcp -m tcp --tcp-flags FIN,RST FIN,RST -j MY_DROP
-A INPUT -p tcp -m tcp --tcp-flags FIN,ACK FIN -j MY_DROP
-A INPUT -p tcp -m tcp --tcp-flags PSH,ACK PSH -j MY_DROP
-A INPUT -p tcp -m tcp --tcp-flags ACK,URG URG -j MY_DROP
-A FORWARD -i tun0 -o eth0 -j ACCEPT
-A FORWARD -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -m limit --limit 1/sec -j ACCEPT
-A FORWARD -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK RST -m limit --limit 1/sec -j ACCEPT
-A FORWARD -p icmp -m icmp --icmp-type 8 -m limit --limit 1/sec -j ACCEPT
-A OUTPUT -m state --state INVALID -j DROP
-A MY_DROP -j DROP
COMMIT
# Completed on Sun Jan 12 23:51:20 2014

Et à cela, j’ajoute donc manuellement iptables -A INPUT -i eth0 -p tcp --dport 22 -j DROP

Ce que tu dis n’a pas beaucoup de sens.
La policy par default ne modifie pas le nombre de trou de ton système. Loin de là.

[quote=“toto12346”][quote]
le fait d’accepter tout de trafic en entrée est pour moi une énorme faille de sécurité… la règle par défaut devrait être en DROP …!!!

Son firewall est une passoire…
[/quote]
Ce que tu dis n’a pas beaucoup de sens.
La policy par default ne modifie pas le nombre de trou de ton système. Loin de là.[/quote]

C’est vrai mais il n’a pas tord d’avoir fait cette remarque, le policy par défaut ne comble pas les trous, mais peut empêcher justement d’accéder à un éventuel trou, seul un virtuose de la sécurité sachant gérer tous les services confondus et leurs ports respectifs en écoute peut laisser le tout en ACCEPT par défaut,il me faudrait vivre 200 ans pour avoir le temps de savoir gérer de A à Z tout le système, alors je DROP par défaut et me concentre seulement sur ceux qui sont en ACCEPT…

@Feldi
iptables appliqué sur l’interface VPN fonctionne de la même manière que sur l’interface eth0, il te faut seulement précisé -o eth0 OU -o tun0 pour chaque régle…

Refusée (refus immédiat) ou finit en time-out (pas de réponse) ? Ce n’est pas la même chose, et DROP provoque plutôt l’absence de réponse, alors que REJECT renvoie une réponse négative.

Note : l’ajout de la règle suivante avant la règle de blocage préserverait les connexions existantes :

Ou bien l’ajout de la condition [mono]-m state --state NEW[/mono] à la règle de blocage.
Cela te permettrait de conserver la première session SSH après avoir ajouté la règle de blocage et de vérifier ensuite si de nouvelles connexions sont possibles par eth0 et tun0.

Tu tentes de te reconnecter en SSH sur quelle adresse IP ? L’adresse publique comme auparavant ou l’adresse privée de l’interface tun0 ?

  • Si l’adresse publique, c’est normal : pour que le VPN puisse fonctionner, cette adresse ne peut être routée dans le VPN puisqu’elle sert au transport du VPN (1). Une route spécifique pour cette adresse a dû être créée sur le poste client lors de l’établissement du VPN, à vérifier avec la commande [mono]ip route[/mono].
  • Si c’est l’adresse privée, sshd écoute bien sur cette adresse, ou encore sur toutes les adresses locales (0.0.0.0) ? A vérifier avec [mono]netstat -tnl[/mono] sur le serveur.

(1) On peut passer outre pour le SSH avec du routage avancé mais ça va être compliqué.

Je sais pas si ça fait par ici mais je pense qu’on peut officiellement me nommer “Boulet du mois”, ou de l’année?

C’était bien ça, je mérite une paire de baffes et au lit :075 :mrgreen:
(Le pire c’est que j’utilise souvent la même méthode pour accéder à un autre serveur sur lequel je travaille…)

ça passait en time-out, c’était bel et bien ma règle qui faisait son DROP.

Merci beaucoup pour toutes vos réponses, parce qu’au-delà d’avoir résolu mon problème (enfin si on peut appeler ça comme ça), vous m’avez donné plein de points intéressants notamment sur iptables.

P.S: D’ailleurs si vous connaissez un bon tuto sur iptables que vous recommenderiez, je suis preneur. (Il en existe beaucoup mais ils sont par forcément bons)

On ne peut pas penser à tout. J’ai vu bien pire.

On peut, il existe même une expression pour désigner ce type de problème : PEBKAC.

Ça dépend pour quoi faire. Si c’est pour comprendre comment ça marche, je recommande celui d’Oskar Andreasson (on n’est pas obligé de le lire en entier). Si c’est pour pouvoir pondre un jeu de règles prémâché en 10 minutes sans avoir besoin de comprendre, je n’en recommande aucun.

Même si c’est évident, une bonne base reste le manuel d’iptables (et iptables-extensions sur Debian +8)

A mon avis la page de manuel est loin de suffire pour appréhender les concepts et le fonctionnement d’iptables, le parcours des paquets à travers les tables et les chaînes… C’est une bonne référence pour la syntaxe et les options quand on connaît déjà les bases. Mais je ne conseillerai jamais à personne d’aborder iptables par sa page de manuel.