Opérations de bases pour rendre nginx moins indiscret

Par défaut, nginx renvoie différentes informations un peu gênantes du point de vue de la sécurité de votre serveur et de ses applications :

  • Numéro de version de nginx
  • Le fait que c'est bien un nginx qui répond

Dans le cas de certains serveurs applicatifs, d'autres informations peuvent fuiter entre autres par le biais des entêtes HTTP leakant ainsi des informations non-vitales pour la bonne exécution de votre application mais particulièrement savoureuses pour vos futures amis qui voudront défoncer votre serveur et vos applis.

Voici donc un peu de configuration pour limiter ces effets.

WARNING : On précisera que ce que nous faisons ici n'est pas plus que de cacher la merde sous le tapis. Si votre logiciel contient une faille dans une version donnée, votre logiciel gardera sa faille malgré tous les soins que nous porterons aux configuration ci-dessous. En un mot : mettez vos infras à jour #screugneugneu

Empêcher la fuite du numéro de version de nginx

Pour cacher le numéro de version de nginx, on ajoute à la clause http de votre fichier de configuration de nginx (la plupart du temps /etc/nginx/nginx.config), le paramètre server_tokens avec une valeur à off :

http {
  [...]
  server_tokens off; # prevent nginx leaking its version
  [...]

Ensuite on recharge la configuration :

  $ sudo systemctl reload nginx

Pour vérifier que la configuration est bonne, on peut naviguer vers une page qui n'existe pas sur votre serveur afin d'obtenir une page d'erreur 404. Si vous avez la page d'erreur par défaut de nginx, ça devrait ressembler à ceci :

Avant d'avoir passé server_tokens à off :

nginx before server_tokens off

Après le passage de server_tokens à off :

nginx after server_tokens off

Supprimer l'entête Server

À la réponse des requêtes qu'il traite, nginx ajoute par défaut l'entête suivante :

  Server: nginx

Pas cool.
Pour empêcher ça, on va devoir ajouter le module headers_more. Sur debian/ubuntu, ce module est installé via le paquet nginx-extras

On installe donc ce paquet :

  $ sudo apt install nginx-extras

On peut alors ajouter à notre section http de notre fichier /etc/nginx/nginx.conf la clause suivante more_set_headers :

http {
  [...]
  more_set_headers 'Server: '; # prevent leaking nginx name ; needs nginx-extras
  [...]
  server_tokens off; # prevent nginx leaking its version
  [...]

Ensuite on recharge la configuration :

  $ sudo systemctl reload nginx

Pour vérifier que ce changement est pris en compte, on peut utiliser l'inspecteur du navigateur (souvent accessible via le raccourci clavier Ctrl+Shift+I, aller dans l'inspecteur réseau, puis regarder les entêtes (headers) de réponse.

Avant la modification :

nginx before overriding Server header

Après la modification : cet entête n'est plus exposé.

Remarque : l'information est toujours disponible en consultant des pages renvoyant des erreurs (types 4xx/5xx) :

nginx after server_tokens off and removing server header

Il conviendra de proposer à vos utilisateur des pages d'erreur personnalisées.

Bloquer les entêtes renvoyés par nos serveurs applicatifs

Venons-en aux serveurs applicatifs qui peuvent être indiscrets. C'est par exemple le cas des serveurs nodejs basés sur Express.

Par défaut on a un magnifique (ironique hein) entête qui nous dit tout joyeusement "hey coucou je suis une app tournant sous le framework Express !"

express server leaking he's here

Nice.

Alors soit vos développeurs codent normalement et suppriment ce vilain entête quand la variable d'environnement NODE_ENV est à production ; soit ils ne le font pas.

Dans ce dernier cas, en plus de leur coller une bonne paire de baffes, on va réparer leur bêtises en attendant un patch.

Notre nginx est configuré pour faire reverse proxy de noter app nodejs. On peut donc lui demander de nous supprimer l'entête X-powered-by. Pour ce faire, on va utiliser le paramètre proxy_hide_header dans notre section location :

  location / {
     [...]                     
     proxy_hide_header X-powered-by;
     proxy_pass http://192.168.1.1;
     [...]
  }

Ensuite on recharge la configuration :

  $ sudo systemctl reload nginx

Cet entête a disparu :

express server header has vanished

Vous pouvez rappeler à vos collègues de vous fêter un joyeux Adminsys day la prochaine fois <3

Remarque finale
  • Les entêtes HTTP c'est important, prenez-en soin.
  • nginx ou les autres serveurs web (apache &co) : même combat
  • ne croyez pas pour autant être en sécurité, un petit coup de nmap pourra vous convaincre que nos petits efforts sont bien minces :)
  • des fois gérer un header ça permet aussi de se protéger de failles de sécu en urgence en attendant que les softs soient patchés, exemple : HTTPPoxy