From 901ca67e18c4923c7e5740992a0b63454ac84763 Mon Sep 17 00:00:00 2001 From: Yax <1949284+kianby@users.noreply.github.com> Date: Sat, 21 Sep 2019 18:07:24 +0200 Subject: [PATCH] new post --- .../2019/2019-09-21-http-proxy-et-securite.md | 30 ++++++++++++++++++ static/images/2019/http-proxy.png | Bin 0 -> 17261 bytes 2 files changed, 30 insertions(+) create mode 100755 posts/2019/2019-09-21-http-proxy-et-securite.md create mode 100644 static/images/2019/http-proxy.png diff --git a/posts/2019/2019-09-21-http-proxy-et-securite.md b/posts/2019/2019-09-21-http-proxy-et-securite.md new file mode 100755 index 0000000..e38c7bf --- /dev/null +++ b/posts/2019/2019-09-21-http-proxy-et-securite.md @@ -0,0 +1,30 @@ + + + + +Dans une modeste configuration d'hébergement de services Web, à moins de faire tourner ses services [monolithiquement]({{ site_url }}/2018/choix-du-systeme-pour-sauto-heberger/), on a souvent un serveur HTTP frontal qui porte le certifical SSL et redispatche les requêtes vers des applications réparties dans des machines virtuelles ou des containers. + +![Architecture Proxy HTTP]({{ site_url }}/images/2019/http-proxy.png) + +La sécurité de mon serveur est assurée par le pare-feu (qui laisse passer uniquement les flux autorisés) et l'outil [fail2ban](https://github.com/fail2ban/fail2ban) qui rajoute des règles de blocage dans iptables en scrutant les logs systèmes et applicatifs. Les applications sont distribuées dans des containers et produisent leur log applicatif. Cela pose deux problèmes : + +1. le log de l'application est dans un container applicatif alors que l'outil de blocage fail2ban est dans le container frontal +2. le serveur HTTP du frontal fait office de proxy donc l'application ne connaît que l'adresse IP du frontal ; le log est inexploitable pour bannir des intrusions. + +Pour résoudre le point 1, il faut rapatrier les logs du container applicatif vers le frontal. C'est faisable de plusieurs manières, une simple, préservant l'indépendance du container, consiste à exporter le log en TCP/IP avec [rsyslog](https://www.rsyslog.com) et à configurer son écoute dans le container frontal. + +Pour le point 2, il faut acheminer l'adresse IP réelle du visiteur vers le container applicatif. Techniquement, c'est déjà le cas en utilisant l'entête HTTP *X-Forwarded-For* dans la configuration HTTP mais l'application n'en tire pas forcément parti pour ses logs. C'est là que NginX propose un génial module [ngx_http_realip](https://nginx.org/en/docs/http/ngx_http_realip_module.html) qui permet au container applicatif de remplacer l'adresse IP reçue (celle du frontal) avec l'adresse IP réelle. + +Sur le NginX du frontal, on passe l'adresse IP réelle dans l'entête **X-Real-IP** : + + proxy_pass http://10.10.10.2; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + +Sur le NginX applicatif, on remplace l'adresse IP par l'adresse réelle : + + set_real_ip_from 10.0.0.0/8; + real_ip_header X-Real-IP; + real_ip_recursive on; + +Avec cette configuration, le log applicatif contient les adresses IP réelles. Il est exporté vers le container frontal et des règles fail2ban peuvent être ajoutées pour l'exploiter et bannir des tentatives d'intrusion. \ No newline at end of file diff --git a/static/images/2019/http-proxy.png b/static/images/2019/http-proxy.png new file mode 100644 index 0000000000000000000000000000000000000000..c9b0bd86509d03e0848b172210d9a6e2f7e374bd GIT binary patch literal 17261 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 KDtSs5BmNh-f-YYG literal 0 HcmV?d00001