Table of Contents
Defined in /modules/blocks/nginx.nix.
This block sets up a Nginx instance.
It complements the upstream nixpkgs with some authentication and debugging improvements as shows in the Usage section.
JSON access logging is enabled with the shb.nginx.accessLog option:
{
shb.nginx.accessLog = true;
}
Looking at the systemd logs (journalctl -fu nginx) will show for example:
nginx[969]: server nginx:
{
"remote_addr":"192.168.1.1",
"remote_user":"-",
"time_local":"29/Dec/2025:14:22:41 +0000",
"request":"POST /api/firstfactor HTTP/2.0",
"request_length":"264",
"server_name":"auth_example_com",
"status":"200",
"bytes_sent":"855",
"body_bytes_sent":"60",
"referrer":"-",
"user_agent":"Mozilla/5.0 (X11; Linux x86_64; rv:140.0) Gecko/20100101 Firefox/140.0",
"gzip_ration":"-",
"post":"{\x22username\x22:\x22charlie\x22,\x22password\x22:\x22CharliePassword\x22,\x22keepMeLoggedIn\x22:false,\x22targetURL\x22:\x22https://f.example.com/\x22,\x22requestMethod\x22:null}",
"upstream_addr":"127.0.0.1:9091",
"upstream_status":"200",
"request_time":"0.873",
"upstream_response_time":"0.873",
"upstream_connect_time":"0.001",
"upstream_header_time":"0.872"
}
This will log the body of POST queries so it should only be enabled for debug logging.
Debug logging is enabled with the shb.nginx.debugLog option:
{
shb.nginx.debugLog = true;
}
If enabled, it sets:
error_log stderr warn;
Easy upstream proxy setup is done with the shb.nginx.vhosts.*.upstream option:
{
shb.nginx.vhosts = [
{
domain = "example.com";
subdomain = "mysubdomain";
upstream = "http://127.0.0.1:9090";
}
];
}
This will set also a few headers. Some are shown here and others please see in the nginx module:
Host = $host;
X-Real-IP = $remote_addr;
X-Forwarded-For = $proxy_add_x_forwarded_for;
X-Forwarded-Proto = $scheme;
This module integrates with the SSL Generator Contract
to setup HTTPs with the shb.nginx.vhosts.*.ssl option:
{
shb.nginx.vhosts = [
{
domain = "example.com";
subdomain = "mysubdomain";
ssl = config.shb.certs.certs.letsencrypt.${domain};;
}
];
shb.certs.certs.letsencrypt.${domain} = {
inherit domain;
};
}
For services provided by SelfHostBlocks that do not handle OIDC integration, this block can provide forward authentication which still allows the service to still be protected by an SSO server.
The user could still be required to authenticate to the service itself, although some services can automatically users authorized by Authelia.
Integrating with this block is done with the following code:
shb.<services>.authEndpoint = "https://${config.shb.authelia.subdomain}.${config.shb.authelia.domain}";
Forward authentication is when Nginx talks with the SSO service directly and the user is authenticated before reaching the upstream application.
The SSO service responds with the username, group and more information about the user. This is then forwarded to the upstream application by Nginx.
Note that every request is authenticated this way with the SSO server so it involves more hops than a direct OIDC integration.
{
shb.nginx.vhosts = [
{
domain = "example.com";
subdomain = "mysubdomain";
authEndpoint = "authelia.example.com";
autheliaRules = [
[
# Protect /admin endpoint with 2FA
# and only allow access to admin users.
{
domain = "myapp.example.com";
policy = "two_factor";
subject = [ "group:service_admin" ];
resources = [
"^/admin"
];
}
# Leave /api endpoint open - assumes an API key is used to protect it.
{
domain = "myapp.example.com";
policy = "bypass";
resources = [
"^/api"
];
},
# Protect rest of app with 1FA
# and allow access to normal and admin users.
{
domain = "myapp.example.com";
policy = "one_factor";
subject = ["group:service_user"];
},
]
];
}
];
}
If PHP is used with fastCGI,
extra headers must be added by enabling the shb.nginx.vhosts.*.phpForwardAuth option.
To add extra configuration to a virtual host,
use the shb.nginx.vhosts.*.extraConfig option.
This can be used to add headers, for example:
{
shb.nginx.vhosts = [
{
domain = "example.com";
subdomain = "mysubdomain";
extraConfig = ''
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
'';
}
];
}
shb.nginx.accessLog
Log all requests
Type: boolean
Default:
false
Example:
true
Declared by:
<selfhostblocks/modules/blocks/nginx.nix>
|
shb.nginx.debugLog
Verbose debug of internal. This will print what servers were matched and why.
Type: boolean
Default:
false
Example:
true
Declared by:
<selfhostblocks/modules/blocks/nginx.nix>
|
shb.nginx.vhosts
Endpoints to be protected by authelia.
Type: list of (submodule)
Default:
[ ]
Declared by:
<selfhostblocks/modules/blocks/nginx.nix>
|
shb.nginx.vhosts.*.authEndpoint
Optional auth endpoint for SSO.
Type: null or string
Default:
null
Example:
"https://authelia.example.com"
Declared by:
<selfhostblocks/modules/blocks/nginx.nix>
|
shb.nginx.vhosts.*.autheliaRules
Authelia rule configuration
Type: list of attribute set of anything
Default:
[ ]
Example:
[
# Protect /admin endpoint with 2FA
# and only allow access to admin users.
{
domain = "myapp.example.com";
policy = "two_factor";
subject = [ "group:service_admin" ];
resources = [
"^/admin"
];
}
# Leave /api endpoint open - assumes an API key is used to protect it.
{
domain = "myapp.example.com";
policy = "bypass";
resources = [
"^/api"
];
},
# Protect rest of app with 1FA
# and allow access to normal and admin users.
{
domain = "myapp.example.com";
policy = "one_factor";
subject = ["group:service_user"];
},
]
Declared by:
<selfhostblocks/modules/blocks/nginx.nix>
|
shb.nginx.vhosts.*.domain
Domain of the subdomain.
Type: string
Example:
"mydomain.com"
Declared by:
<selfhostblocks/modules/blocks/nginx.nix>
|
shb.nginx.vhosts.*.extraConfig
Extra config to add to the root / location. Strings separated by newlines.
Type: strings concatenated with ā\nā
Default:
""
Declared by:
<selfhostblocks/modules/blocks/nginx.nix>
|
shb.nginx.vhosts.*.phpForwardAuth
Authelia rule configuration
Type: boolean
Default:
false
Declared by:
<selfhostblocks/modules/blocks/nginx.nix>
|
shb.nginx.vhosts.*.ssl
Path to SSL files
Type: null or (open submodule of anything)
Default:
null
Declared by:
<selfhostblocks/modules/blocks/nginx.nix>
|
shb.nginx.vhosts.*.ssl.paths
Paths where the files for the certificate will be located.
This option is the contract output of the shb.certs.certs SSL block.
Type: open submodule of anything
Declared by:
<selfhostblocks/modules/blocks/nginx.nix>
|
shb.nginx.vhosts.*.ssl.paths.cert
Path to the cert file.
Type: absolute path
Declared by:
<selfhostblocks/modules/blocks/nginx.nix>
|
shb.nginx.vhosts.*.ssl.paths.key
Path to the key file.
Type: absolute path
Declared by:
<selfhostblocks/modules/blocks/nginx.nix>
|
shb.nginx.vhosts.*.ssl.systemdService
Systemd oneshot service used to generate the certificate. Ends with the .service suffix.
Use this if downstream services must wait for the certificates to be generated before starting.
Type: string
Example:
"cert-generator.service"
Declared by:
<selfhostblocks/modules/blocks/nginx.nix>
|
shb.nginx.vhosts.*.subdomain
Subdomain which must be protected.
Type: string
Example:
"subdomain"
Declared by:
<selfhostblocks/modules/blocks/nginx.nix>
|
shb.nginx.vhosts.*.upstream
Upstream url to be protected.
Type: null or string
Default:
null
Example:
"http://127.0.0.1:1234"
Declared by:
<selfhostblocks/modules/blocks/nginx.nix>
|