Petites explications

Je passe une partie de ma vie derrière un proxy qui bloque le port 22. Ce n'est pas une raison pour ne pas me connecter en ssh à mon serveur. Jusqu'à maintenant, j'avais une redirection sur mon routeur 443 -> 22. Sauf que depuis que j'ai mon blog, je me suis dit que ça serait cool d'avoir du ssl (parce que c'est bien, et parce que le mettre en place, me ferait apprendre des choses) d'autant plus que je compte un jour avoir un webmail (mais c'est pas pour tout de suite).

Un jour vpm m'a parlé de sslh qui permet d'avoir du ssh et du ssl sur le port 443. N'ayant pas l'utilité à l'époque, j'ai gardé le nom en me disant que ça pouvait être pratique.

Mise en place du https sur OpenBSD

As usual c'est dans la FAQ. Juste pour les commandes d'openssl car j'utilise nginx.

Pour nginx il suffit juste de rajouter dans /etc/nginx/nginx.conf

server {
    listen       8443;
    server_name  blog.chown.me;
    root         /var/www/pelican;

   ssl                  on;
   ssl_certificate      /etc/ssl/server.crt;
   ssl_certificate_key  /etc/ssl/private/server.key;

    ssl_session_timeout  5m;

    ssl_protocols  SSLv2 SSLv3 TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers  HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers   on;
}

Ensuite on peut vérifier avec https://www.ssllabs.com/ssltest/analyze.html?d=blog.chown.me (je remercie Gilles pour le lien) que les options marchent bien. Ça ne sert à rien de cliquer, j'ai des règles anti-ddos (me demandez pas pourquoi) et donc ssllabs se fait bloquer rapidement.

Dans mon cas j'ai un F parce que mon cert n'est pas signé et un A si on ne prend pas en compte ce problème.

Bah pourquoi tu n'as pas de certificat signé ?

Parce que :

  • c'est payant
  • j'ai la flemme de m'en faire un via CACERT

Et surtout parce que c'est une histoire de confiance. Je n'ai aucune raison d'avoir confiance en une boite pour un certificat. Qui me dit qu'elle ne va pas vendre (ou donner) un faux certificat à un état pour faire du MITM sans problème ? Oui à l'échelle d'un blog comme le mien la proba est de 0 pour un site comme gmail, la question c'est juste combien ils en font par an.

Ensuite on peut prendre en compte le fait qu'elles se font de temps en temps trouer. Bref, je n'ai aucune raison de leur donner de l'argent.

Je fais beaucoup plus confiance aux chiffres (je suis plutôt cartésien). Du coup je donne les fingerprints signés par ma clé gpg : iota.chown.me/fingerprint.asc.txt

On en revient à une question de confiance, comment savez vous que c'est bien ma clé ? Bah simple y a des gens qui l'ont signé (pas beaucoup mais ça progresse).

«Talk is cheap show me the code»

Maintenant qu'on a un serveur qui acceptent du HTTPS sur le port 8443 (c'est bloqué par pf, donc n'essayez pas) installons sslh qui est dans les ports en version 1.11 (la dernière version est la 1.14 :/)

cd /usr/port/net/sslh
make install

À la fin de l'install on est notifié de l'installation de deux scripts dans /etc/rc.d/ : sslh_fork et sslh_select

En lisant la man page de sslh

   sslh comes in two versions: sslh-fork forks a new process for each
   incoming connection. It is well-tested and very reliable, but incurs
   the overhead of many processes. sslh-select uses only one thread, which
   monitors all connections at once.  It is more recent and less tested,
   but only incurs a 16 byte overhead per connection. Also, if it stops,
   you'll lose all connections, which means you can't upgrade it remotely.

N'étant pas d'humeur joueuse, j'ai choisi de prendre sslh_fork.

On édite /etc/rc.conf.local par rapport à la conf de nginx

sslh_fork_flags="--user=_sslh --listen :::443 --listen 0.0.0.0:443 --ssh 127.0.0.1:22 --ssl 127.0.0.1:8443"

C'est peut-être possible de laisser en 443 pour ssl, mais pas envie d'avoir à débugger donc je ne me prends pas la tête.

Conclusion

J'ai donc du ssl (avec du Perfect Forward Secrecy \o/) et en même temps je garde la capacité à outrepasser le blocage du port 22.

Great success!

Oups j'ai pas tout vérifié

Quand je publie un article, je regarde son succès avec tail -f /var/www/logs/access.log. Là en même temps je vérifiais que https marchait bien (toujours publier avant de vérifier, sinon c'est pas marrant (oui je sais, je suis d'humeur joueuse, mais c'est après coup)). En regardant les logs que vois-je ? Des accès de 127.0.0.1. Ce qui est logique puisque les requêtes viennent de sslh, qui est sur la machine.

Du coup ça rend caducs mes logs puisque je ne peux pas dire qui a accédé au serveur.

Logons sur sslh

On ajoute dans /etc/syslog.conf

!sslh-fork
*.*                                                     /var/log/sslh

Comme ça on obtient les ips dans ce fichier. (Faudra ptet que je tweak un peu le logging parce que là je vais avoir beaucoup de choses).

Hum, et ta règle anti ddos ?

Je vous parlais de ma règle anti-ddos du coup elle est inefficace puisque j'ai un set skip on lo0. Donc si on me bruteforce mon ssh via le port 443, je ne peux rien faire (même si au final il n'y a que peu de risque, puisqu'il faudrait trouver un OTP valide mais bon.

La solution m'est venue de vpm (toujours le même)

14:18:05 <vpm> Par contre, pourquoi est-ce que ça rend caduque l'anti ddos ? Tu ne filtres pas sur l'if externe ?

Donc non sur mon serveur j'ai qu'une interface, mais ... mais je peux filtrer sur l'alix. \o/

Je rajoute juste

pass in on $ext_if proto tcp to $ext_if port { www, https } rdr-to $server \
keep state (max-src-conn 100, max-src-conn-rate 15/5, overload <brutewww> flush global)

Et voilà problem solved.

Et sous Debian ?

Pour les gens sous Debian iMil m'a fait remarquer ce lien.