Accéder à un serveur derrière un router 4G en Algérie
En Algérie, un serveur connecté à internet à travers un router 4G n'est pas accessible depuis l'extérieur (en dehors du LAN).
C'est le cas notamment avec l'opérateur Djezzy. Même en ouvrant et en redirigeant les ports nécessaires pour une connexion SSH ou HTTP, le serveur demeure inaccessible.
Il est donc probable que les adresses IP rapportées sur ce type de modems ou en utilisant la ligne de commande soient non-adressables.
Une démarche quelque peu compréhensible si on considère que cela permet de protéger les devices téléphoniques, principaux clients de ce type de réseau.
Comment accéder à un serveur dans ces conditions.
Redirection de ports à travers un serveur distant avec SSH
Cette technique utilise la fonctionnalité de tunneling apportée en natif sur OpenSSH.
Paramétrage du serveur distant
Par défaut le serveur distant n'ouvre la redirection que sur son interface locale 1). Ceci est insuffisant.
Nous devons donc paramétrer le serveur ssh pour que le port forwardé soit accessible sur l'interface publique avec l'instruction suivante dans le fichier de configuration /etc/ssh/sshd_config
:
GatewayPorts clientspecified
Créer la redirection depuis le client
Nous initions une connexion depuis le serveur en 4G (Serveur Hidden) vers un serveur accessible et proprement adressable (Serveur Visible). Le Serveur Visible fonctionnera alors comme une passerelle pour accéder au Serveur Hidden.
ssh -N -f -g -R *:11122:localhost:22 limiteduser@ip.serveur.visible
Avec cette commande nous donnons accès au port 22 du Serveur Hidden à travers le port 11122 du Serveur Visible.
L'utilisateur limiteduser est restreint et a /bin/false comme shell.
Donc, avec la commande suivante, nous nous connectons au port 22 du Serveur Hidden.
ssh -p 11122 userServeurHidden@ip.serveur.visible
Pour maintenir ce tunnel ouvert, nous pouvons nous aider avec un cron job qui testera le fonctionnement et qui relancera le tunnel si celui-ci venait à être coupé. 2)
- keep_tunnel_alive.sh
# Si le tunnel ne fonctionne pas if ! $(timeout 2 -p 11122 userb@64.212.113.165 echo &>/dev/null) ; then # S'assurer de tuer le process de connexion s'il existe procid=$(ps aux | grep limiteduser | grep 11122 | grep -v grep | awk '{print $2}') if [ ! -z "$procid" ]; then kill $procid fi # Initier la connexion # les options supplémentaires comme Control{Master,Persist,...} et autres # ... aident à optimiser les conditions de connexion # voir man ssh timeout 60 ssh -N -f -g -o ControlMaster=auto \ -o ControlPath=/tmp/%u:%r@%h:%p \ -o ControlPersist=120m \ -o PubkeyAuthentication=yes \ -o PasswordAuthentication=no \ -o ServerAliveInterval=60 \ -o ServerAliveCountMax=3 \ -R *:11122:localhost:22 \ limiteduser@64.212.113.165 fi
Dans ce script à lancer par cron on peut initier d'autres connexions pour donner accès à d'autres ports comme une application web par exemple.