Swag
Introduction¶
Avant-propos¶
Si certains services comme Ollama peuvent rester uniquement en local, d'autres comme Home Assistant gagnent à être exposés, afin de pouvoir etre utilisés en déplacement. Plusieurs solutions sont possibles comme l’utilisation d'un VPN ou le recours à un reverse-proxy. C'est cette dernière que l'on abordera ici.
C'est quoi ?¶
SWAG pour "Secure Web Application Gateway", est une application de reverse-proxy basée sur nginx, incluant certbot pour la création de certificats SSL et fail2ban comme protection primaire. Moddable, le conteneur est édité par linuxserver.io et propose de facilement associer un nom de domaine à un service, en toute sécurité.
Elle se défini elle-même par :
SWAG - Secure Web Application Gateway (anciennement connu sous le nom de letsencrypt, sans rapport avec Let's Encrypt™) met en place un serveur web Nginx et un reverse proxy avec un support php et un client certbot intégré qui automatise les processus gratuits de génération et de renouvellement des certificats de serveur SSL (Let's Encrypt et ZeroSSL). Il contient également fail2ban pour la prévention des intrusions.
Avantages & inconvénients¶
- SWAG est une application plutôt clef en main, incluant plusieurs outils fondamentaux.
- nginx est l'un des reverse-proxy les plus efficace en terme de rapidité et de consommation de ressources
- Le renouvellement du certificat SSL (permettant de faire du https) est automatique
- On peut assez facilement renforcer la sécurité
- Malgré son aspect clef-en-main, il demande une configuration manuelle dans tous les cas.
- Il restera toujours moins sécurisé qu'un accès par VPN uniquement
- Il est nécessaire d'ouvrir au moins un port sur son routeur (:443)
Alternatives¶
Les alternatives les plus connues sont :
Installation¶
Prérequis¶
Un certain nombre de prérequis sont non-négociables :
- CPU avec 1 coeurs
- 512 Mo de DDR
- 4 GB de HDD
- Accès SSH
- Docker
- Un NDD (Nom de Domaine)
- Le port 443 d'ouvert et redirigé vers l'IP du proxy
Docker, compose et validation DNS¶
C'est la seule méthode prise en charge. Linuxserver est une communauté basée autour de la publication de conteneurs, il est donc normal de retrouver ceux-ci dans les méthodes recommandées.
Bonnes pratiques :
Personnellement, mon serveur proxy est une machine virtuelle dédiée, très légère. Je ne peux que recommander d'utiliser une machine dédiée au serveur proxy, celui-ci étant un point d'entrée pour de potentiels pirates. Ainsi, si le port 443 du routeur est ouvert et redirigé sur l'adresse du serveur proxy, il constitue une surface d'attaque non négligeable. Surface que l'on diminue en ne laissant qu'un seul service accessible.
Certificat OVH
Le docker & le compose fournis ici sont configurés pour un domaine loué chez OVH. Le provider peut évidemment changer. Plus d'infos sur la page dédiée. La configuration montre donc la demande automatisée d'un certificat SSL permettant de passer au HTTPS à partir d'un domaine chez OVH, pour le domaine lui-meme et l'ensemble des sous-domaines. (www.domain.com,photos.domain.com,cloud.domaine.com,...)
Comme d'habitude, le docker-compose est compatible Portainer et Komodo.
docker run -d \
--name swag \
--cap-add NET_ADMIN \
-e PUID=1000 \
-e PGID=1000 \
-e TZ=Etc/UTC \
-e URL=domaine.com \
-e VALIDATION=dns \
-e SUBDOMAINS=wildcard \
-e DNSPLUGIN=ovh \
-e DOCKER_MODS=linuxserver/mods:swag-dashboard
-v ./config:/config \
-p 443:443 \
-p 81:81 \
--restart unless-stopped \
lscr.io/linuxserver/swag:latest
services:
swag:
image: lscr.io/linuxserver/swag:latest
container_name: swag
cap_add:
- NET_ADMIN
environment:
- PUID=1000
- PGID=1000
- TZ=Etc/UTC
- URL=domaine.com
- VALIDATION=dns
- SUBDOMAINS=wildcard
- DNSPLUGIN=ovh
- DOCKER_MODS=linuxserver/mods:swag-dashboard
volumes:
- ./config:/config
ports:
- 443:443
- 81:81
restart: unless-stopped
docker compose up -d qui installe ça.
Et là, ça échoue. Pas de panique, c'est normal : on ne lui a pas donné les autorisations pour vérifier que le domaine est bien le notre.
On vérifie tout d'abord sur le tableau de bord de son domaine que ce dernier pointe bien sur son adresse IP publique. On peut trouver celle-ci sur des sites dédiés. Normalement, on devrait avoir un enregistrement dit "A" pour une adresse IPv4. Ensuite, on se rend sur le site API d'OVH et on entre les autorisations suivantes :
On défini le temps de validation sur infini. Enfin, on se connecte sur le serveur proxy via SSH (ou on y accède via docker exec -it swag /bin/bash) et on cherche le fichier ovh.ini dans ./config/dns-conf/ovh.ini et on le rempli avec les clefs d'API générées sur le site d'OVH.
# OVH API credentials used by Certbot
dns_ovh_endpoint = ovh-eu
dns_ovh_application_key = MDAwMDAwMDAwMDAw
dns_ovh_application_secret = MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw
dns_ovh_consumer_key = MDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAw
compose.yaml et on relance (ou on peut relancer directement avec la commande docker run donnée au dessus.)
Si tout s'est bien passé, on devrait avoir un tableau de bord sur http://IP:81. Celui-ci n'est qu'indicatif et ne permet que de consulter des statistiques.
A ce stade, on devrait avoir un nom de domaine qui pointe vers l'IP du routeur, le routeur qui récupère le port 443 (HTTPS) et le transmet au serveur proxy.
Configuration du proxy¶
Une multitude de templates existent déjà pour exposer certains services. Pour ajouter un proxy, il suffit de se rendre dans le repertoire ./config/nginx/proxy-conf/. Une commande ls permet de découvrir plusieurs dizaines de configurations possibles sous le format .sample.
Prenons l'exemple de Home Assistant que l'on veut exposer sur assist.domain.org. On commence par créer le sous-domaine assist chez OVH et on le pointe vers l'IP (champ A) ou le domaine, si celui-ci pointe déjà sur l'IP publique (Champ CNAME). Une fois le délais de propagation passé (de quelques secondes à plusieurs heures), l'adresse choisie devrait répondre sur http(s)://assist.domain.org et une page 404 de SWAG devrait apparaitre. Si tel est le cas, c'est parfait : l'adresse arrive bien sur le proxy.
Dans ./config/nginx/proxy-conf/ on trouve homeassistant.subdomain.conf.sample et on le renome en le copiant (pour garder l'original) :
Deux renommages
On a renommé ici le homeassistant en assist, soit le sous domaine choisi ET on a enlevé le .sample.
On ouvre le fichier avec nano et on modifie le fichier pour correspondre à notre infra :
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name assist.*; ## Ici, on change le sous-domaine par celui désiré
include /config/nginx/ssl.conf;
client_max_body_size 0;
location / {
include /config/nginx/proxy.conf;
include /config/nginx/resolver.conf;
set $upstream_app IP; # Ici, on remplace IP par l'adresse de home assistant
set $upstream_port 8123;
set $upstream_proto http;
proxy_pass $upstream_proto://$upstream_app:$upstream_port;
}
location ~ ^/(api|local|media)/ {
include /config/nginx/proxy.conf;
include /config/nginx/resolver.conf;
set $upstream_app IP; # Ici, on remplace IP par l'adresse de home assistant
set $upstream_port 8123;
set $upstream_proto http;
proxy_pass $upstream_proto://$upstream_app:$upstream_port;
}
}
On ferme, et ... Après quelques secondes, https://assist.domain.org devrait afficher la page d'acceuil de l'instance Home Assistant. L'instance est maintenant exposée.
Sécurisation¶
Fail2Ban¶
Par défaut, le conteneur SWAG contient l'outil fail2ban qui permet de bannir une adresse IP en cas de tentative de brute-force. Après 3 tentatives de login incorrectes, f2b va bannir l'adresse IP concernée pour une durée de 600 secondes par défaut.
Pour modifier le nombre de tentatives avant un bannissement ou la durée de celui-ci, il suffit de se rendre dans le fichier ./config/fail2ban/jail.local et de modifier les valeurs BANTIME ou MAXRETRY.
Valeurs par défaut
Les valeurs par défaut sont idéales pour la protection anti-bot. Les modifier peut entrainer des risques d'attaque, notamment en modifiant la valeur MAXRETRY.
Crowdsec¶
Un outil formidable pour augmenter la sécurité est crowdsec, qui permet de bannir des adresses IP soit à partir d'un comportement anormal tel qu'un scan de ports ouverts ou à partir de listes d'adresses réputées malveillantes.
Pour l'utliser, il faut d'abord modifier le compose.yaml ou la commande docker exécutée et y ajouter le conteneur crowdsec :
- DOCKER_MODS=linuxserver/mods:swag-dashboard|DOCKER_MODS=linuxserver/mods:swag-crowdsec
- CROWDSEC_LAPI_URL=http://crowdsec:8080
- CROWDSEC_API_KEY=
# On ajoute un 'pipe' puis le mod à ajouter : crowdsec
# Puis on ajoute, toujours dans cette section, les arguments obligatoires du nouveau conteneur mais en laissant vide l'API pour l'instant.
Dans la section ports, on ajoute une ligne avec 8080:8080 pour crowdsec.
On relance le compose avec docker compose stop && docker compose up -d puis on vérifie que crowdsec est bien présent avec docker ps qui permet de lister les conteneurs actifs.
Bien que le conteneur soit maintenant présent, il faut lui donner les logs de SWAG à analyser. On modifie le fichier ./config/nginx/nginx.conf et dans le bas, on ajoute, en dessous de la ligne commentée :
On valide puis on enregistre le bouncer (l'analyseur de logs) sur l'API du conteneur crowdsec, qui va renvoyer une valeur à conserver :
Pour terminer, on reprend une dernière fois notre compose.yaml pour y entrer la clef d'API de crowdsec. On modifie donc la ligne concernée puis on relance le compose (ou la commande docker complète) une dernière fois :
Crowdsec est maintenant installé.