Nginx: Difference between revisions

Klinger (talk | contribs)
mNo edit summary
Makefu (talk | contribs)
Restructure to start with an example, put the openssl stuff and troubleshooting at the back
Line 1: Line 1:
[https://nginx.org/ {{PAGENAME}}] ([[wikipedia:en:{{PAGENAME}}]]) is a lightweight webserver. Configuration is handled using the {{nixos:option|services.nginx.}} options.
[https://nginx.org/ {{PAGENAME}}] ([[wikipedia:en:{{PAGENAME}}]]) is a lightweight webserver. Configuration is handled using the {{nixos:option|services.nginx.}} options.
== Replace dependencies like openssl ==
In wake of the 2022 OpenSSL library, Nix can support in mitigating the library by downgrading (or replacing) the SSL library. For this, the [[Overlay|overlay]] facility of nixpkgs can be used:
<syntaxHighlight lang=nix>
nixpkgs.overlays = [
  (final: super: {
        nginxStable = super.nginxStable.override { openssl = super.pkgs.libressl; };
    } )
];
</syntaxHighlight>
When utilizing NixOS options the following configuration will also work:
<syntaxHighlight lang=nix>
services.nginx.package = pkgs.nginxStable.override { openssl = pkgs.libressl; };
</syntaxHighlight>
== Let's Encrypt certificates ==
The nginx module for NixOS has native support for Let's Encrypt certificates;  {{nixos:option|services.nginx.+acme}}. The {{manual:nixos|sec=#module-security-acme-nginx|chapter=Chapter 20. SSL/TLS Certificates with ACME}} explains it in detail.
=== Minimal Example ===
Assuming that <code>myhost.org</code> resolves to the IP address of your host and port 80 and 443 has been opened.
<syntaxHighlight lang=nix>
services.nginx.enable = true;
services.nginx.virtualHosts."myhost.org" = {
    addSSL = true;
    enableACME = true;
    root = "/var/www/myhost.org";
};
security.acme = {
  acceptTerms = true;
  defaults.email = "foo@bar.com";
};
</syntaxHighlight>
This will set up nginx to serve files for <code>myhost.org</code>, automatically request an ACME SSL Certificate and will configure systemd timers to renew the certificate if required.
== Troubleshooting ==
=== Read-only Filesystem for nginx upgrade to 20.09 ===
With the upgrade to nixos-20.09 the nginx comes with extra hardening parameters, most prominently the restriction of write access to the Operating System Disk.
When you see errors like <code>[emerg] open() "/var/spool/nginx/logs/binaergewitter.access.log" failed (30: Read-only file system)</code> you can add extra paths to nginx service like this:
<syntaxHighlight lang=nix>
  systemd.services.nginx.serviceConfig.ReadWritePaths = [ "/var/spool/nginx/logs/" ];
</syntaxHighlight>
=== SIGTERM received from 1 ===
If you turn debug logging on:
<pre>
services.nginx.logError = "stderr debug";
</pre>
You may see this:
<pre>
[notice] 12383#12383: signal 15 (SIGTERM) received from 1, exiting
</pre>
This means systemd is killing nginx for you, but systemd (in nixOS 20.09) isn't nice enough to tell you why it's happening. Chances are it's because your nginx config has daemon mode turned on, turn off daemon mode in your nginx config like so:
<pre>
daemon off;
</pre>
And it should fix nginx so systemd won't go killing your nginx anymore.
=== Escape special chars in Regular Expressions ===
Some nginx configuration options like <code>locations</code> allows the use of Regular Expressions.
Be ware that you [https://nixos.org/manual/nix/stable/language/values.html#type-string need to escape some special chars] like <code>\</code>, if provided by a double quoted <code>" "</code> string.
A common example found on the internet is:
<syntaxHighlight lang="nix">
locations."~ ^(.+\.php)(.*)$"  = {
    ...
};
</syntaxHighlight>
But in this case the <code>\.php</code> part will be parsed by Nix to <code>.php</code>. In RegEx the dot represents any character instead of the dot character itself.
Thus the path /gly'''php'''ro.css will be matched, too. Additionaly to the intended  match of <code>/somephpfile.php?param=value</code>.
To circumvent this error <code>\.php</code> has to be double escaped as <code>\\.php</code>
<syntaxHighlight lang="nix">
locations."~ ^(.+\\.php)(.*)$"  = {
    ...
};
</syntaxHighlight>
=== General ===
Nginx is run as the systemd service nginx, so <code>systemctl status nginx</code> may say something useful. If you have a problem with configuration, you can find the configuration location in the <code>systemctl status</code>, it should be at <code>/nix/store/*-nginx.conf</code>.


== Sample setups ==
== Sample setups ==
Line 338: Line 247:
systemd.services.hedgedoc.serviceConfig.UMask = "0000";
systemd.services.hedgedoc.serviceConfig.UMask = "0000";
</syntaxhighlight>
</syntaxhighlight>
== Let's Encrypt certificates ==
The nginx module for NixOS has native support for Let's Encrypt certificates;  {{nixos:option|services.nginx.+acme}}. The {{manual:nixos|sec=#module-security-acme-nginx|chapter=Chapter 20. SSL/TLS Certificates with ACME}} explains it in detail.
=== Minimal Example ===


Assuming that <code>myhost.org</code> resolves to the IP address of your host and port 80 and 443 has been opened.
<syntaxhighlight lang="nix">
services.nginx.enable = true;
services.nginx.virtualHosts."myhost.org" = {
    addSSL = true;
    enableACME = true;
    root = "/var/www/myhost.org";
};
security.acme = {
  acceptTerms = true;
  defaults.email = "foo@bar.com";
};
</syntaxhighlight>
This will set up nginx to serve files for <code>myhost.org</code>, automatically request an ACME SSL Certificate and will configure systemd timers to renew the certificate if required.
== Troubleshooting ==
=== Read-only Filesystem for nginx upgrade to 20.09 ===
With the upgrade to nixos-20.09 the nginx comes with extra hardening parameters, most prominently the restriction of write access to the Operating System Disk.
When you see errors like <code>[emerg] open() "/var/spool/nginx/logs/binaergewitter.access.log" failed (30: Read-only file system)</code> you can add extra paths to nginx service like this:
<syntaxhighlight lang="nix">
  systemd.services.nginx.serviceConfig.ReadWritePaths = [ "/var/spool/nginx/logs/" ];
</syntaxhighlight>
=== SIGTERM received from 1 ===
If you turn debug logging on:
<pre>
services.nginx.logError = "stderr debug";
</pre>
You may see this:
<pre>
[notice] 12383#12383: signal 15 (SIGTERM) received from 1, exiting
</pre>
This means systemd is killing nginx for you, but systemd (in nixOS 20.09) isn't nice enough to tell you why it's happening. Chances are it's because your nginx config has daemon mode turned on, turn off daemon mode in your nginx config like so:
<pre>
daemon off;
</pre>
And it should fix nginx so systemd won't go killing your nginx anymore.
=== Escape special chars in Regular Expressions ===
Some nginx configuration options like <code>locations</code> allows the use of Regular Expressions.
Be ware that you [https://nixos.org/manual/nix/stable/language/values.html#type-string need to escape some special chars] like <code>\</code>, if provided by a double quoted <code>" "</code> string.
A common example found on the internet is:
<syntaxhighlight lang="nix">
locations."~ ^(.+\.php)(.*)$"  = {
    ...
};
</syntaxhighlight>
But in this case the <code>\.php</code> part will be parsed by Nix to <code>.php</code>. In RegEx the dot represents any character instead of the dot character itself.
Thus the path /gly'''php'''ro.css will be matched, too. Additionaly to the intended  match of <code>/somephpfile.php?param=value</code>.
To circumvent this error <code>\.php</code> has to be double escaped as <code>\\.php</code>
<syntaxhighlight lang="nix">
locations."~ ^(.+\\.php)(.*)$"  = {
    ...
};
</syntaxhighlight>
=== General ===
Nginx is run as the systemd service nginx, so <code>systemctl status nginx</code> may say something useful. If you have a problem with configuration, you can find the configuration location in the <code>systemctl status</code>, it should be at <code>/nix/store/*-nginx.conf</code>.
== Replace dependencies like openssl ==
In wake of the 2022 OpenSSL library, Nix can support in mitigating the library by downgrading (or replacing) the SSL library. For this, the [[Overlay|overlay]] facility of nixpkgs can be used:
<syntaxHighlight lang=nix>
nixpkgs.overlays = [
  (final: super: {
        nginxStable = super.nginxStable.override { openssl = super.pkgs.libressl; };
    } )
];
</syntaxHighlight>
When utilizing NixOS options the following configuration will also work:
<syntaxHighlight lang=nix>
services.nginx.package = pkgs.nginxStable.override { openssl = pkgs.libressl; };
</syntaxHighlight>


== See more ==
== See more ==