9 votes

Nginx - peut-on utiliser "si" en toute sécurité au niveau d'un bloc serveur ?

La documentation de Nginx prévient en termes clairs que si c'est le mal et doit être évité dans la mesure du possible, et des avertissements similaires sont disséminés sur toute la longueur et la largeur de l'internet.

Cependant, la plupart de ces avertissements se concentrent spécifiquement sur la gravité de la situation. if se comporte en location blocs. De plus, les docs de Nginx disent que :

Les seules choses sûres à 100 % qui peuvent être faites à l'intérieur dans un contexte d'emplacement sont :

  • retour ... ;

  • réécrire ... dernier ;

Ma question est la suivante : est-il prudent d'utiliser une if au niveau de la server (plutôt qu'un bloc location bloc) si la seule directive qu'il contient est un return ? Par exemple, la redirection suivante www-to-non-www :

server {
    listen 80;
    server_name example.com www.example.com;

    if ($http_host != example.com) {
        return 301 http://example.com$request_uri;
    }

    # more config
}

Question secondaire : Je suis conscient que la méthode recommandée pour faire ce genre de chose est de faire deux server qui ont des valeurs différentes pour server_name . Si cela est une utilisation acceptable pour if est-ce qu'il y a une raison de continuer à utiliser deux systèmes séparés server des blocs ?

1 votes

D'après ce que j'ai compris, les blocs de deux serveurs sont la meilleure pratique et sont plus performants.

0 votes

Tim - Vous savez pourquoi ? Est-ce simplement que vous évitez l'obligation d'évaluer l'objet de l'opération ? if puisque cette détermination est faite par la logique de choix du serveur, qui s'exécuterait dans tous les cas ? Cette logique est-elle simplement plus optimisée que if ?

0 votes

Je suppose que c'est simplement plus efficace en interne dans Nginx. Je vais probablement en rester là car c'est à peu près la limite de mes connaissances dans ce domaine, d'autres en sauront plus.

4voto

kbolino Points 302

De "If is Evil" :

Dans certains cas, il est également possible de déplacer les ifs au niveau du serveur (où ils sont en sécurité car seules les autres directives du module de réécriture sont autorisées).

Cela suggère que if dans un server est plus sûre(r) que dans un location bloc.

2voto

Tero Kilkanen Points 32968

Une des premières étapes lorsque nginx reçoit une requête est d'évaluer le HTTP Host et sélectionner l'hôte virtuel en fonction du résultat de cette évaluation.

Cela signifie que le Host est toujours traité.

Maintenant, si vous spécifiez un if pour la redirection, cela signifie que l'instruction Host sera vérifié deux fois, d'abord pour sélectionner l'hôte virtuel, puis pour vérifier l'adresse de l'utilisateur. if condition. C'est deux fois plus de travail pour le processeur.

Un contre-argument pourrait être la consommation de mémoire pour un bloc serveur séparé. Cependant, l'allocation de mémoire est la même pendant toute la durée de vie du processus nginx, alors que la double évaluation de la fonction Host L'en-tête se produit à chaque demande.

1voto

ROSE Points 134

Je ne sais pas ce que vous entendez par "sûr", mais laissez-moi vous parler d'un cas que j'ai rencontré récemment. J'avais besoin de refuser l'accès à un site à moins qu'un certain paramètre ne soit passé. Disons que la configuration ressemble à ceci :

server {
    server_name localhost;
    root /usr/share/nginx/html;
    try_files $uri /index.html;
}

J'ai ajouté un if :

    ...
    if ($arg_secret-key != 123456) {
        return 404;
    }

Pero nginx me donnerait 404 même si je fournissais le secret :

$ curl -sS localhost/?secret-key=123456

Il s'est avéré que try_files a fait une redirection interne vers /index.html (sans passer le paramètre), ce qui a donné lieu à 404. Pour que cela fonctionne, il fallait donc procéder de cette façon :

try_files $uri /index.html$is_args$args;

Mais en fait, je devais interdire l'accès à la page principale uniquement :

    ...
    location = / {
        if ($arg_secret-key != 123456) {
            return 404;
        }
    }

Et comme ça, ça a marché sans changer try_files . C'est parce qu'il y a aussi le index module . Et try_files n'est pas hérité par le location bloc. Ainsi, le index fait la bonne redirection vers /index.html?secret-key=123456 et pour la nouvelle demande, il n'y a plus rien à faire pour try_files .

Si vous n'êtes pas sûr de ce qui se passe, vous pouvez exécuter nginx construit avec --with-debug et configurer le journal d'erreurs avec l'option debug niveau, par exemple :

nginx.conf :

error_log  /var/log/nginx/error.log debug;
server {
    server_name localhost;
    root /usr/share/nginx/html;
    ...
}

$ docker run --rm --name nginx -p 1111:80 -dv $PWD/nginx.conf:/etc/nginx/conf.d/default.conf nginx:alpine nginx-debug -g 'daemon off;'
// launch `docker logs -f nginx` in a separate console, use Enter to separate requests
// processing starts with "generic phase: 0"
$ curl -sS localhost:1111/?secret-key=123456
// change nginx.conf
$ docker exec nginx nginx -s reload
$ curl -sS localhost:1111/?secret-key=123456
...
$ docker stop nginx

En savoir plus aquí .

Pour votre deuxième question, je pense que dans votre cas, avoir 2 server est préférable. Parce que c'est ce qui est suggéré par les développeurs, et si vous choisissez l'option if un jour, vous pourriez rencontrer un problème après avoir modifié la configuration. Ou vous pourriez vous rendre compte que dans certains cas, le système ne fonctionne pas comme vous l'aviez prévu (dans les cas plus complexes). On pourrait dire, if introduit une complexité dans la configuration que vous pourriez ne pas connaître. En tant que tel, j'utiliserais if si je comprenais bien comment tout cela fonctionne, ou si je n'avais pas d'autre choix. Et le if semble être pire en termes de performances. Bien que ce ne soit qu'une spéculation, et je ne peux pas fournir de chiffres. Dans mon cas, je ne vois pas de solution de contournement, et c'est donc ce que je vais utiliser pour l'instant.

-1voto

Robin Moerland Points 21

Sie puede le faire, mais c'est fortement déconseillé. Il y a déjà une version officielle explication à ce sujet .

Pour faire fonctionner plusieurs sites, je recommande de créer plusieurs fichiers de configuration pour chaque site, puis d'inclure l'emplacement dans le fichier de configuration principal. nginx.conf .

1 votes

Joseph a fait un lien vers l'article "if is evil" dans sa question. Je pense qu'il espérait un peu plus de détails, et plus de profondeur sur l'utilisation de if par rapport à l'utilisation de blocs de serveurs multiples. Votre réponse est un peu légère en termes de détails.

2 votes

En fait, les documents officiels suggèrent de déplacer if à la server si possible, afin d'éviter certaines des limitations connues.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X