La procédure qui suit permet dans un premier temps d'activer la connexion SSH sans mot de passe. Ensuite il nous est alors possible d'activer une seconde instance du service SSH sur le réseau WAN permettant l'accès uniquement avec échange de clés:

  1. LAN: Accès normal, port par défaut (22)
  2. WAN: Accès via échange de clés uniquement, port 666

Prise en charge des clés sur OpenWRT|LEDE

Simuler un $HOME/.ssh pour le compte de root et faire pointer le fichier authorized_keys vers le répertoire de configuration dropbear:

root@OpenWrt|LEDE:~# mkdir -m 0700 /root/.ssh
root@OpenWrt|LEDE:~# ln -s /etc/dropbear/authorized_keys /root/.ssh/authorized_keys

Copie de votre clé publique

Il est présumé ici que vous avez déjà créé votre trousseau de clé publique/privé dans votre compte personnel Linux. Sinon il s'agit d'en créer un via la commande usuelle:

whoami@localhost:~$ ssh-keygen -t rsa

À partir de votre compte Linux sur votre station de travail copier votre clé publique sur le routeur:

whoami@localhost:~$ ssh-copy-id root@192.168.1.1
The authenticity of host '192.168.1.1 (192.168.1.1)' can't be established.
RSA key fingerprint is SHA256:TkchSSjy4pLRzsS9c4C1TaNZIBU8L4j7lvptMEuJkmw.
Are you sure you want to continue connecting (yes/no)? yes
root@192.168.1.1's password:
Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'root@192.168.1.1'"
and check to make sure that only the key(s) you wanted were added.

Tester la connexion sans mot de passe:

whoami@localhost:~$ ssh root@192.168.1.1

Résultat OpenWRT:

 -----------------------------------------------------
 CHAOS CALMER (15.05, r46767)
 -----------------------------------------------------
root@OpenWrt:~#

Résultat LEDE:

BusyBox v1.25.1 () built-in shell (ash)

     _________
    /        /\      _    ___ ___  ___
   /  LE    /  \    | |  | __|   \| __|
  /    DE  /    \   | |__| _|| |) | _|
 /________/  LE  \  |____|___|___/|___|                      lede-project.org
 \        \   DE /
  \    LE  \    /  -----------------------------------------------------------
   \  DE    \  /    Reboot (17.01.0-rc1, r3042-ec095b5)
    \________\/    -----------------------------------------------------------

root@lede:~#

Service SSH sur le réseau WAN

En premier lieu on ajoute un couche de sécurité au service existant en ne permettant les connexions qu'à partir du réseau LAN:

uci set dropbear.@dropbear[0].Interface='lan'

Ensuite on ajoute un second service SSH sur le réseau WAN sur le port de notre choix (tout sauf le port par défaut 22, dans mon cas le port 666).

uci add dropbear dropbear
uci set dropbear.@dropbear[-1].Interface='wan'
uci set dropbear.@dropbear[-1].Port='666'

Afin de rendre le service plus sécuritaire et de n'autoriser que les connexions par échange de clés, on désactive la demande de mot de passe pour tous les usagers:

uci set dropbear.@dropbear[-1].PasswordAuth='off'
uci set dropbear.@dropbear[-1].RootPasswordAuth='off'

On valide les changements et on met en place la nouvelle configuration:

uci show dropbear
uci changes dropbear
uci commit

Correctif OpenWRT Chaos Calmer 15.05

Sur la version CC 15.05 il y a des problèmes de "timing" au démarrage du routeur pour le démon SSH. Pour corriger le tout on ajoute une règle hotplug afin de redémarrer le service SSH lors de tout changement d'état d'un interface réseau:

echo -ne '#!/bin/sh\n[ "$INTERFACE" = "wan" ] \
          && [ "$ACTION" = "ifup" -o "$ACTION" == "ifupdate" ] \
          && /etc/init.d/dropbear restart\n' \
          > /etc/hotplug.d/iface/40-dropbear

Référence: https://wiki.openwrt.org/doc/uci/dropbear

Paramétrisation du pare-feu (firewall)

Ne reste plus qu'à ajouter une règle au pare-feu afin d'accepter les requêtes TCP en destination du port choisi:

uci add firewall rule
uci set firewall.@rule[-1].name='Allow SSH from WAN port 666'
uci set firewall.@rule[-1].src='wan'
uci set firewall.@rule[-1].dest_port='666'
uci set firewall.@rule[-1].target='ACCEPT'
uci set firewall.@rule[-1].proto='tcp'
uci set firewall.@rule[-1].enabled='1'
uci changes firewall
uci commit

Référence: https://wiki.openwrt.org/doc/uci/firewall

Tests de démarrage

Afin de confirmer que tout est pleinement fonctionnel je recommande de redémarrer le routeur. Ceci permettra de valider que les deux démons SSH sont présents suivant un démarrage. Sinon on peut redémarrer les services manuellement tel que:

root@OpenWrt|LEDE:~# /etc/init.d/firewall restart
root@OpenWrt|LEDE:~# /etc/init.d/dropbear restart

Suivant le redémarrage il devrait y avoir au moins une instance SSH pour le LAN et une seconde pour le WAN:

root@OpenWrt|LEDE:~# pidof dropbear
2516 2302 2301
root@OpenWrt|LEDE:~# ps | grep drop
 2301 root      1152 S    /usr/sbin/dropbear -F -P /var/run/dropbear.1.pid -p 192.168.1.1:22 -p fd9b:4079:ea72:10::1
 2302 root      1152 S    /usr/sbin/dropbear -F -P /var/run/dropbear.2.pid -s -g -p <IP-WAN>:666 -K 300
 2516 root      1220 S    /usr/sbin/dropbear -F -P /var/run/dropbear.1.pid -p 192.168.1.1:22 -p fd9b:4079:ea72:10::1

Il est important de noter qu'une instance du démon dropbear s'ajoute à chaque connexion donc vous aurez sans aucun doute plus de deux processus mais bien 2 pid maîtres (dropbear.X.pid).

Il est aussi possible de vérifier sur quel port chaque démon est à l'écoute via la commande "lsof -i -n -P" ou "ss -pt" (remplace netstat):

root@OpenWr|LEDEt:~# lsof -i -n -P | grep dropbear
dropbear  2301   root    3u  inet   4099      0t0  TCP 192.168.1.1:22 (LISTEN)
dropbear  2302   root    3u  inet   4102      0t0  TCP <IP-WAN>:666 (LISTEN)
dropbear  2516   root    6u  inet   4372      0t0  TCP 192.168.1.1:22->192.168.80.37:48020 (ESTABLISHED)
dropbear  2516   root    7u  inet   4375      0t0  TCP 127.0.0.1:6010 (LISTEN)

Tests de connexion WAN

À cette étape il ne reste plus qu'à tester la connexion à distance sur le port WAN de diverses façons. Tout d'abord sans spécifier le port de communication:

whoami@localhost:~$ ssh <IP-WAN>
ssh: connect to host home.th0ma7.com port 22: Connection refused

En utilisant le bon port sans spécifier de nom d'utilisateur:

whoami@localhost:~$ ssh <IP-WAN> -p 666
Permission denied (publickey).

Sur le bon port avec l'utilisateur root:

whoami@localhost:~$ ssh root@<IP-WAN> -p 666
BusyBox v1.23.2 (2016-01-02 18:01:44 CET) built-in shell (ash)
  _______                     ________        __
 |       |.-----.-----.-----.|  |  |  |.----.|  |_
 |   -   ||  _  |  -__|     ||  |  |  ||   _||   _|
 |_______||   __|_____|__|__||________||__|  |____|
          |__| W I R E L E S S   F R E E D O M
 -----------------------------------------------------
 CHAOS CALMER (15.05.1, r48532)
 -----------------------------------------------------
  * 1 1/2 oz Gin            Shake with a glassful
  * 1/4 oz Triple Sec       of broken ice and pour
  * 3/4 oz Lime Juice       unstrained into a goblet.
  * 1 1/2 oz Orange Juice
  * 1 tsp. Grenadine Syrup
 -----------------------------------------------------
root@OpenWrt:~#

OPTIONEL - Trousseau de clés publique/privée (utilisateur root@OpenWRT)

Vous pouvez en profiter pour créer un trousseau de clés publique/privées pour le compte root sur le routeur:

root@OpenWrt|LEDE:~# dropbearkey -t rsa -f /etc/dropbear/id_rsa  | grep ssh-rsa > /etc/dropbear/id_rsa.pub
root@OpenWrt|LEDE:~# ls -la /etc/dropbear/*
-rw-------    1 root     root           457 Sep  4 19:51 /etc/dropbear/dropbear_dss_host_key
-rw-------    1 root     root           805 Sep  4 19:51 /etc/dropbear/dropbear_rsa_host_key
-rw-------    1 root     root           805 Jan  9 14:17 /etc/dropbear/id_rsa
-rw-r--r--    1 root     root           394 Jan  9 14:17 /etc/dropbear/id_rsa.pub