Restreindre l'accès à un serveur et placer un WAF devant votre application
Dès le premier déploiement,
erpc worker n'autorise SSH que depuis votre adresse et ignore toute autre connexion entrante. Une table [waf] place un proxy de filtrage devant votre API.Cette page décrit ERPC CLI
v0.1.0-rc.4, une préversion.Le pare-feu
Un déploiement configure le pare-feu du serveur avant le premier démarrage de l'application :
- SSH uniquement depuis
firewall.ssh_allowet l'adresse d'où provient le déploiement ; - toute autre connexion entrante ignorée, sauf
run.portdepuisfirewall.app_allow; pour une application derrière un WAF, le port du WAF à sa place, et seulement là où le WAF du serveur applique déjà les règles que[waf]définit désormais (plus bas).
Chaque modification s'exécute sous un minuteur de rollback de 120 secondes et n'est conservée qu'une fois qu'une nouvelle connexion parvient à entrer, si bien qu'une modification erronée ne peut pas vous enfermer dehors.
La liste blanche survit toutefois à l'adresse depuis laquelle elle a été créée : si l'adresse de votre domicile change, pour revenir sur le serveur, il faut passer par le support ERPC pour un serveur ERPC, ou par la console du fournisseur pour votre propre serveur. Gardez dans
firewall.ssh_allow une seconde adresse depuis laquelle vous pouvez joindre le serveur (un bureau, une sortie VPN) avant de vous fier à celle de votre domicile.Si votre adresse change, ajoutez toutes les adresses fixes qu'utilisent vos administrateurs :
bash
Placer un WAF devant votre application
Ajoutez une table à
erpc.toml :toml
erpc worker deploy exécute alors un proxy inverse HTTP sur le serveur, dans sa propre unité systemd (erpc-waf-<app>-<env>) : un utilisateur dynamique non privilégié, sans clé, sans secret et sans rien qui appartienne au worker, limité à 1 GiB de mémoire. Il écoute sur waf.port, lit chaque requête avant l'application, refuse ce que ses règles désignent et transmet le reste à l'application sur 127.0.0.1:<run.port>.-
L'application reste sur le loopback. Son propre port n'est jamais ouvert depuis l'extérieur.
erpc worker apiet le contrôle de santé joignent l'application sur le loopback, sans passer par le WAF. -
Qui peut se connecter reste défini par la liste du pare-feu, et le port du WAF est le seul endroit où cette liste peut indiquer tout le monde :shSi personne n'est listé, le WAF écoute mais personne n'est admis, et le déploiement le signale.
-
Le port n'est ouvert qu'une fois que le WAF y écoute, jamais avant. Un déploiement dont le WAF ne démarre pas échoue et en indique la raison, tandis que l'application tourne toujours.
-
Lorsque vous modifiez
[waf], le port n'est ouvert à personne d'autre tant qu'un déploiement n'a pas mis en place les nouvelles règles. -
Retirer
[waf]deerpc.tomlpuis déployer retire le WAF du serveur.
Paramètres du WAF
Seul
port est obligatoire. Toutes les clés, avec leur valeur par défaut :toml
rate, max_connections_per_address, ban et new_connections se désactivent avec false (ban = false), et une clé omise prend sa valeur par défaut. erpc worker check indique ce que fera la table [waf], et ce qui ne va pas, avant tout déploiement.Ce que fait le WAF sans aucun paramètre
- Une requête qui ne se lit pas comme une seule requête HTTP/1 sans ambiguïté reçoit 400, de même qu'un chemin qui n'est pas sous forme normale.
- Une demande de changement de protocole (
Upgrade) reçoit 501. - Chaque refus compte pour le bannissement, et chaque refus met fin à sa connexion.
- Une adresse est une adresse IPv4, ou un
/64IPv6. - Le WAF ne transmet pas les en-têtes de la connexion entre le client et le proxy (
Connectionet les en-têtes qu'il nomme,Keep-Alive,Proxy-Authenticate,Proxy-Authorization,Proxy-Connection,TE,Trailer), niExpect, ni les en-têtes dont le nom contient un tiret bas, ni lesForwarded,X-Real-IPetX-Forwarded-Protofournis par le client lui-même. Il définitX-Real-IPsur l'adresse d'où vient la connexion et ajoute cette adresse à la fin deX-Forwarded-For; seule la dernière entrée deX-Forwarded-Forest attestée par le proxy.
Voir ce que fait le WAF
Une requête transmise ne laisse aucune ligne de log, et aucun en-tête ni corps n'est jamais journalisé ; la chaîne de requête d'une requête bloquée l'est, dans la limite de ces 200 octets. Ce qu'envoie un client ne peut pas écrire sur votre terminal : le WAF écrit son journal en ASCII imprimable.
Ce que le WAF ne fait pas
- Pas de TLS. Il parle HTTP/1.1 en clair sur son port.
- Pas de HTTP/2 : il y répond par 400.
- Pas de WebSocket, ni aucun autre
Upgrade: 501. - Aucun examen de l'intérieur des corps. Un corps est mesuré, jamais lu. La liste des sondes est courte et sert de filtre contre le bruit, pas de garantie : la vérification de ses entrées reste l'affaire de l'application.
- Pas d'authentification. Décider qui peut appeler l'application revient à l'application, et à la liste du pare-feu.
- Une adresse est un client. Des clients derrière un même NAT, proxy ou CDN partagent un débit et un bannissement ; un client doté de nombreuses adresses dispose d'autant de débits.
- Les bannissements et les compteurs sont oubliés lorsque le WAF redémarre.
- Il garde en mémoire au plus 8192 adresses et maintient au plus 1024 connexions à la fois.
- Il n'écoute qu'en IPv4, si bien qu'une entrée IPv6 dans
app_allowne mène encore à rien. - Un chemin est comparé selon les octets qu'il donne une fois décodé. Une application qui lit les chemins de façon plus souple (en ignorant la casse, les paramètres
;, ou en décodant deux fois) peut être atteinte sous un nom quedeny_pathsne couvre pas.allow_pathsn'a pas cette faille : ce qui n'est pas listé n'est pas transmis. - Un lecteur lent est servi jusqu'au bout. Un client qui continue de recevoir une réponse, aussi lentement que ce soit, est servi jusqu'à la fin.
- Un afflux de requêtes peut interrompre un gros envoi. Le WAF tourne sur un seul thread, si bien qu'un afflux peut interrompre un gros envoi avec 408. Une application qui accepte des corps volumineux augmente
body_timeout_secsen même temps quemax_body_bytes.
Le guide du worker contient toutes les règles, y compris le cas où une modification de
app_allow est mise en attente jusqu'au prochain déploiement.





