• [^] # Démarrer nginx en utilisateur non privilégié avec systemd

    Posté par (site web personnel) . En réponse au journal Recherche d'un reverse proxy. Évalué à 3.

    Nginx aussi démarre en root. Et c'est plutôt normal sous Linux vu que c'est un prérequis (la capability CAP_NET_BIND_SERVICE), par défaut, pour avoir accès au port 80.

    Ça n'est pas obligé. Il y a un hack non documenté qui permet de faire de l'activation par socket avec systemd et donc de le faire tourner sous utilisateur non privilégié.

    Mon fichier nginx.socket :

    [Unit]
    PartOf=nginx.service
    [Socket]
    # fd: 3
    ListenStream=80
    # fd: 4
    ListenStream=0.0.0.0:80
    # fd: 5
    ListenStream=443
    # fd: 6
    ListenStream=0.0.0.0:443
    BindIPv6Only=ipv6-only
    

    Mon fichier nginx.service :

    # On a besoin de nginx.socket pour ouvrir les ports et les envoyer à nginx
    [Unit]
    After=nginx.socket
    Requires=nginx.socket
    [Service]
    PIDFile=/run/nginx/pid
    ExecStart=/usr/sbin/nginx -g 'daemon on; master_process on;'
    ExecStop=-/sbin/start-stop-daemon --quiet --stop --retry QUIT/5 --pidfile /run/nginx/pid
    TimeoutStopSec=5
    Environment=NGINX=3:4:5:6:
    NonBlocking=true
    User=www-data
    # Puis plein d'options de confinement avec systemd : NoNewPrivileges=true, CapabilityBoundingSet=, ...
    

    Puis le fichier nginx.conf :

    http {
     server {
     # Les directives listen ci-dessous sont assez fictives : en réalité, nginx va écouter
     # sur des "file descriptor" (fd) passés en paramètre (cf. /etc/systemd/system/nginx.socket)
     listen [::]:80 default_server; # fd: 3
     listen 80 default_server; # fd: 4
     #[...]
     }
     server {
     listen [::]:443 ssl default_server; # fd: 5
     listen 443 ssl default_server; # fd: 6
     #[...]
     }
    }
    

    Le seul truc qu'on perd, c'est systemctl reload nginx : ça n'est pas possible car dans ce cas le nginx oublie les "file descriptors" en entrée et tente d'attraper les ports, il ne peut pas. Il faut donc faire restart à chaque fois.