SSH et VPN

Yep ,

je possède un petit VPS chez ovh sous debian 8 sur lequel je me connecte en SSH sans problème sauf que dès que je lance mon client VPN ( HideMyAss) sur ce ptit serveur , ma connexion SSH se coupe et ne remonte pas. D’après vous quel solution puis je mettre en pratique pour continuer à accéder à mon serveur dédié en SSH pendant la connexion VPN.

D’avance merci pour l’aide :wink:

Plop

Probable problème de route par défaut.
Je suppose que le client VPN modifie la route par défaut de ton VPS pour la faire passer par le VPN. Deux conséquences :

  • si le sysctl rp_filter=1 sur l’interface LAN du VPS, les paquets provenant d’internet à l’exception des paquets transportant le VPN seront jetés ;
  • les paquets sortants vers internet à l’exception des paquets transportant le VPN seront routés par le VPN. Cela concerne les paquets des connexions déjà établies avant l’activation du VPN, qui continuent à avoir l’adresse de la machine comme adresse source et non l’adresse attribuée à l’interface VPN. Là, trois cas :
  • l’opérateur du VPN route les paquets quelle que soit leur adresse source, tout va bien ;
  • l’opérateur du VPN bloque les paquets ayant une adresse source différente de celle attribuée par le VPN, ça ne passe pas ;
  • l’opérateur du VPN attribue une adresse IP privée et NATe les paquets sortants avec une de ses adresses IP publiques. Les paquets ont une adresse source différente et ne sont pas reconnus par le destinataire comme appartenant à une connexion existante, ça ne marche pas.

Pour éviter les cas qui ne marchent pas, il faut forcer le routage des paquets concernés par l’interface LAN du VPS. Différentes méthodes existent selon tes besoins :

  • si tu te connectes seulement depuis une adresse fixe, tu peux ajouter une route statique pour cette adresse via la passerelle du VPS. C’est la méthode la plus simple ;
  • si toutes les connexions SSH se font hors du VPN, tu peux forcer le routage des paquets de réponse SSH (port source 22 ou autre) via la passerelle du VPS ;
  • tu peux forcer le routage des paquets ayant comme adresse source l’adresse de l’interface LAN via la passerelle du VPS. C’est la méthode la plus polyvalente.
1 J'aime

Merci de prendre le temps de me répondre :wink:

En l’occurrence oui je ne me connecte que depuis chez moi avec une IP fixe … Peux tu m’aider pour l’ajout de la route fixe ?! Je ne suis pas très à l’aise avec Iptable …

Plop

iptables sert à créer des règles de filtrage, pas des routes. On crée des routes statiques avec route ou ip route. Par exemple avec $routeur=adresse de la passerelle par défaut du VPS (obtenue avec ip route) et $client=adresse publique d’où tu te connectes :

ip route add $client via $routeur

Pour que la route soit persistante, il faut exécuter la commande à chaque démarrage, par exemple avec une option up dans le paragraphe de configuration de l’interface réseau du fichiers /etc/network/interfaces.

Teste d’abord la route sans la rendre persistante, car si tu mets la mauvaise passerelle tu ne pourras plus te connecter depuis ton adresse.

Super ça fonctionne merci !!

J’abuse de ton temps mais peux tu m’expliquer brièvement ce que la commande ip route fait ?
J’ai envie de comprendre ce quez j’applique

PS: par contre le script du client VPN n’arrive plus a checker sa propre addresse “Failed to check IP address.”

Plop

La commande ip route sert à manipuler les routes des tables de routage IP du noyau. Une route sert à indiquer de quelle façon un paquet doit être envoyé en fonction de son adresse source, par quelle interface, via quel routeur…

Si tu copies les sorties de ip route du VPS avec et sans VPN, je peux expliquer les différentes routes présentes.

Concernant le script client, il faudrait savoir comment il fait cette vérification car je ne vois pas le rapport avec l’ajout d’une route vers ton adresse IP.

Extrait de la commande ip route sans le VPN :

default via $routeur dev eth0
$routeur dev eth0  scope link
$client via $routeur dev eth0

`
Extrait de la commande ip route avec le VPN :

0.0.0.0/1 via 10.200.143.1 dev tun0
default via $routeur dev eth0
10.200.143.0/24 dev tun0  proto kernel  scope link  src 10.200.143.137
128.0.0.0/1 via 10.200.143.1 dev tun0
$routeur dev eth0  scope link
$client via $routeur dev eth0
$client_VPN via $routeur dev eth0

Concernant le check d’adresse IP je suppose qu’il passe par ce genre de commandes :

dig +short myip.opendns.com @resolver1.opendns.com

ou

wget http://checkip.dyndns.org -O - -o /dev/null | cut -d : -f 2 | cut -d \< -f 1

ou

wget -qO - icanhazip.com

Et effectivement aucune de ses commandes ne fonctionnent, elle n’aboutissent pas.

Plop

Voilà j’ai trouvé le paragraphe dans le script de connexion du client VPN qui check l’adresse IP publique:

# Create script to check for IP
cat <<EOF > /tmp/hma-ipcheck.sh
#!/bin/bash
ip=""
attempt=0
while [ "\$attempt" -lt "3" ]; do
	attempt=\$((\$attempt+1))
	sleep 1
	if [[ "\$ip" == "" ]] ; then
	ip=\$($curl --connect-timeout 10 --max-time 10 geoip.hmageo.com/ip/ 2>/dev/null)
	fi
	if [[ "\$ip" == "" ]] ; then
	sleep 1
	ip=\$($curl --connect-timeout 10 --max-time 10 icanhazip.com 2>/dev/null)
	fi
	if [[ "\$ip" == "" ]] ; then
	sleep 1
	ip=\$($curl --connect-timeout 10 --max-time 10 ipecho.net/plain 2>/dev/null)
	else
	attempt=3
	fi
done

if [[ "\$ip" == "" ]] ; then
	echo "Failed to check IP address."
else
	echo "Your IP is \$ip"
fi
EOF
default via $routeur dev eth0

“default” = 0.0.0.0/0, soit n’importe quelle adresse, tout l’espace d’adressage. Il s’agit de la route par défaut qui détermine le routage des destinations qui ne sont pas prises en compte par une route plus précise. Ici, les paquets sont envoyés par l’interface eth0 au routeur dont l’adresse est $routeur. Cette route peut être créée par l’option “gateway” du fichier /etc/network/interfaces. Il ne doit y en avoir qu’une seule pour tout le système, quel que soit le nombre d’interfaces présentes et de réseaux connectés.

$routeur dev eth0  scope link

Cette route, si tu l’as transcrite correctement, indique que les paquets destinés à l’adresse $routeur sont émis directement sur l’interface eth0. Habituellement la table de routage contient plutôt une route pour tout le bloc d’adresses du sous-réseau local (noté avec un /N ou N est la taille du préfixe CIDR, par exemple /24 pour un masque 255.255.255.0). Mais si la machine n’a pas de voisins dans le sous-réseau ou n’a pas besoin de communiquer directement avec eux, une route pour le routeur suffit.

$client via $routeur dev eth0

Il s’agit de la route créée par la commande ip route add. Pour le moment elle est redondante avec la route par défaut, mais lorsque le VPN remplace la route par défaut ou ajoute des routes qui ayant priorité sur la route par défaut (voir plus bas), cette route maintiendra le routage de l’adresse $client via le routeur $routeur et non via le VPN.

0.0.0.0/1 via 10.200.143.1 dev tun0
128.0.0.0/1 via 10.200.143.1 dev tun0

Ces deux routes créées par le VPN vont ensemble. A elles deux, elles couvrent tout l’espace d’adressage (0.0.0.0/1 = 0.0.0.0 à 127.255.255.255 et 128.0.0.0/1 = 128.0.0.0 à 255.255.255.255) et sont donc équivalentes à une route par défaut, à une nuance près : comme elles ont individuellement une plage de destination plus petite qu’une vraie route par défaut, elles ont priorité sur celle-ci. C’est une astuce pour ne pas modifier la route par défaut existante tout en la rendant inactive lorsque le VPN est actif, puisqu’il ne doit pas y avoir plusieurs routes par défaut (car on ne peut pas déterminer avec fiabilité laquelle sera prise en compte).

Avec ces deux routes les paquets non couverts par une route plus précise sont envoyés par l’interface du VPN tun0. Une adresse de routeur correspondant à l’adresse du serveur VPN à l’intérieur du VPN est mentionnée mais elle n’est pas utilisée car une interface “tun” est de type point-à-point.

10.200.143.0/24 dev tun0  proto kernel  scope link  src 10.200.143.137

Cette route indique que les paquets destinés au sous-réseau du VPN ( 10.200.143.0/24 = 10.200.143.0 à 10.200.143.255) sont émis par l’interface tun0 avec l’adresse source par défaut 10.200.143.137, qui doit être l’adresse configurée sur l’interface tun0. Comme c’est une adresse privée, on peut en déduire que l’opérateur du VPN fait du NAT en sortie vers internet (cf. mon premier message).


Concernant la vérification de l’adresse du script, elle est effectuée via des requêtes HTTP vers trois sites différents qui n’ont rien à voir avec l’adresse de ta connexion utilisée pour SSH. Je ne vois donc pas en quoi la route ajoutée peut interférer.

As-tu essayé d’exécuter les commandes curl manuellement sans la redirection de la sortie d’erreur2>/dev/null avec et sans VPN pour voir le résultat et le message d’erreur ?

1 J'aime

Tes explications sont hyper clair , c’est vraiment sympa :slight_smile:

Pour le script qui ne fonctionne pas , j’ai trouvé la cause … C’est la résolution DNS qui ne fonctionne pas, si je fais curl --connect-timeout 10 --max-time 10 64.182.208.182 , cela fonctionne impeccable …

Encore merci pour ton aide.

RESOLU

Plop

Je me doutais que la résolution DNS était en cause, c’est un classique. Et le problème existait déjà avant l’ajout de la route (mais tu ne voyais peut-être pas le message car la connexion SSH était déjà interrompue).

Si le VPS utilise les DNS de l’hébergeur qui sont réservés à ses clients, alors si les requêtes DNS passent par le VPN et sortent avec une adresse IP propre au VPN, elles ne seront pas reconnues comme provenant d’un client légitime. Il faut

  • soit ajouter des routes pour les adresses de ces DNS pour que les requêtes ne passent pas par le VPN, comme pour l’adresse du client SSH (mais alors l’hébergeur verra toutes les requêtes DNS de ton VPS),
  • soit modifier les DNS déclarés dans /etc/resolv.conf lors de l’établissement du VPN pour que le VPS utilise des DNS joignables à travers le VPN (ex: ceux fournis par l’opérateur VPN, ou des DNS ouverts comme ceux de Google ou FDN).

Utiliser les adresses IP des sites au lieu des noms de domaine n’est généralement pas une bonne idée :

  • si le site est hébergé sur un serveur mutualisé, l’accès par adresse IP ne fonctionne que pour le site par défaut ; la parade consiste à enregistrer l’adresse IP et le nom du site dans /etc/hosts ;
  • le site peut changer d’adresse IP.

Ouais je vais modifier le resolv.conf , merci :wink:

Plop