migrate haproxy -> nginx

This commit is contained in:
nyanloutre 2020-04-08 12:45:36 +02:00
parent f86ef0518d
commit 2da8af253d
6 changed files with 169 additions and 314 deletions

View file

@ -90,7 +90,7 @@ in
};
firewall = {
allowedTCPPorts = [ ];
allowedTCPPorts = [ 80 443 ];
allowedUDPPorts = [ ];
interfaces.eno2 = {
allowedTCPPorts = [

View file

@ -24,9 +24,7 @@ in
{
imports = [
../../services/haproxy-acme.nix
../../services/mail-server.nix
../../services/site-max.nix
../../services/auto-pr.nix
../../services/python-ci.nix
../../services/sdtdserver.nix

View file

@ -2,88 +2,147 @@
with lib;
#### VHost table ####
# 10000 riot.nyanlout.re
# 10001 factorio.nyanlout.re
# 10002 minecraft.nyanlout.re
# 10003 nyanlout.re
# 10004 musique-meyenheim.fr
# 10005 social.nyanlout.re
# 10006 pgmanage.nyanlout.re
# 10007 maxspiegel.fr
####
let
domaine = "nyanlout.re";
nginxSsoAuth = pkgs.writeText "nginx-sso_auth.inc" ''
# Protect this location using the auth_request
auth_request /sso-auth;
jellyfin_backend = ''
http-request set-header X-Forwarded-Port %[dst_port]
http-request add-header X-Forwarded-Proto https if { ssl_fc }
'';
sonarr_acl = ''
acl API path_beg /api
'';
sonarr_auth = ''
!AUTH_OK !API
# Redirect the user to the login page when they are not logged in
error_page 401 = @error401;
location /sso-auth {
# Do not allow requests from outside
internal;
# Access /auth endpoint to query login state
proxy_pass http://127.0.0.1:${toString(config.services.nginx.sso.configuration.listen.port)}/auth;
# Do not forward the request body (nginx-sso does not care about it)
proxy_pass_request_body off;
proxy_set_header Content-Length "";
# Set custom information for ACL matching: Each one is available as
# a field for matching: X-Host = x-host, ...
proxy_set_header X-Origin-URI $request_uri;
proxy_set_header X-Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# If the user is lead to /logout redirect them to the logout endpoint
# of ngninx-sso which then will redirect the user to / on the current host
location /sso-logout {
return 302 https://login.nyanlout.re/logout?go=$scheme://$http_host/;
}
# Define where to send the user to login and specify how to get back
location @error401 {
return 302 https://login.nyanlout.re/login?go=$scheme://$http_host$request_uri;
}
'';
nginxGetFirstLocalPort = vh: (findFirst (x: x.addr == "127.0.0.1") (throw "No local port found") config.services.nginx.virtualHosts.${vh}.listen).port;
nginxSimpleReverse = rport: {
enableACME = true;
forceSSL = true;
locations."/" = {
proxyPass = "http://127.0.0.1:${toString(rport)}/";
};
};
nginxAuthReverse = rport: {
enableACME = true;
forceSSL = true;
extraConfig = ''
include ${nginxSsoAuth};
'';
locations."/" = {
proxyPass = "http://127.0.0.1:${toString(rport)}/";
extraConfig = ''
auth_request_set $cookie $upstream_http_set_cookie;
add_header Set-Cookie $cookie;
'';
};
};
in
{
security.acme = {
email = "paul@nyanlout.re";
acceptTerms = true;
};
services = {
haproxy-acme = {
enable = true;
domaine = domaine;
services = {
"grafana.${domaine}" = { ip = "127.0.0.1"; port = config.services.grafana.port; auth = true; };
"emby.${domaine}" = { ip = "127.0.0.1"; port = 8096; auth = false; extraBackend = jellyfin_backend; };
"radarr.${domaine}" = { ip = "127.0.0.1"; port = 7878; auth = true; extraAcls = sonarr_acl; aclBool = sonarr_auth; };
"sonarr.${domaine}" = { ip = "127.0.0.1"; port = 8989; auth = true; extraAcls = sonarr_acl; aclBool = sonarr_auth; };
"transmission.${domaine}" = { ip = "127.0.0.1"; port = config.services.transmission.port; auth = true; };
"syncthing.${domaine}" = { ip = "127.0.0.1"; port = 8384; auth = true; };
"jackett.${domaine}" = { ip = "127.0.0.1"; port = 9117; auth = true; };
"searx.${domaine}" = { ip = "127.0.0.1"; port = 8888; auth = false; };
"riot.${domaine}" = { ip = "127.0.0.1"; port = nginxGetFirstLocalPort "riot.nyanlout.re"; auth = false; };
"matrix.${domaine}" = { ip = "127.0.0.1"; port = 8008; auth = false; };
"pgmanage.${domaine}" = { ip = "127.0.0.1"; port = config.services.pgmanage.port; auth = true; };
"gitea.${domaine}" = { ip = "127.0.0.1"; port = config.services.gitea.httpPort; auth = false; };
"ci.${domaine}" = { ip = "127.0.0.1"; port = 52350; auth = false; };
"factorio.${domaine}" = { ip = "127.0.0.1"; port = nginxGetFirstLocalPort "factorio.nyanlout.re"; auth = false; };
"airsonic.${domaine}" = { ip = "127.0.0.1"; port = 4040; auth = false; };
"${domaine}" = { ip = "127.0.0.1"; port = nginxGetFirstLocalPort "nyanlout.re"; auth = false; };
"musique-meyenheim.fr" = { ip = "127.0.0.1"; port = nginxGetFirstLocalPort "musique-meyenheim.fr"; auth = false; };
"minecraft.${domaine}" = { ip = "127.0.0.1"; port = nginxGetFirstLocalPort "minecraft.nyanlout.re"; auth = false; };
};
};
searx.enable = true;
nginx = {
enable = true;
recommendedGzipSettings = true;
recommendedOptimisation = true;
recommendedProxySettings = true;
appendHttpConfig = ''
set_real_ip_from 127.0.0.1;
real_ip_header X-Forwarded-For;
recommendedTlsSettings = true;
commonHttpConfig = ''
map $scheme $hsts_header {
https "max-age=31536000; includeSubdomains; preload";
}
add_header Strict-Transport-Security $hsts_header;
add_header Referrer-Policy origin-when-cross-origin;
error_page 500 502 503 504 https://nyanlout.re/errorpages/50x.html;
'';
sso = {
enable = true;
environmentFile = "/mnt/secrets/nginx-sso.env";
configuration = {
listen = {
addr = "127.0.0.1";
port = 8082;
};
login = {
title = "LoutreOS login";
default_method = "simple";
hide_mfa_field = true;
names.simple = "Username / Password";
};
cookie = {
domain = ".nyanlout.re";
secure = true;
};
audit_log = {
targets = [ "fd://stdout" ];
events = [ "access_denied" "login_success" "login_failure" "logout" ];
};
providers.simple = {
enable_basic_auth = true;
users = {
paul = "$2y$10$RMqeJF/hUasXZ5/SLKAu4uKKp6ac6qXCaRu4OY/fIN6ZYucDXzqYm";
};
groups = {
admins = [ "paul" ];
};
};
acl = {
rule_sets = [
{
rules = [ { field = "x-host"; regexp = ".*"; } ];
allow = [ "@admins" ];
}
];
};
};
};
virtualHosts = {
"riot.nyanlout.re" = {
listen = [ { addr = "127.0.0.1"; port = 10000; } ];
locations = { "/" = { root = pkgs.riot-web; }; };
};
"factorio.nyanlout.re" = {
listen = [ { addr = "127.0.0.1"; port = 10001; } ];
locations = { "/" = { root = "/var/www/factorio"; }; };
};
"minecraft.nyanlout.re" = {
listen = [ { addr = "127.0.0.1"; port = 10002; } ];
locations = { "/" = { root = "/var/www/minecraft-overviewer"; }; };
};
"nyanlout.re" = {
listen = [ { addr = "127.0.0.1"; port = 10003; } ];
default = true;
enableACME = true;
forceSSL = true;
locations = {
"/" = {
alias = "/var/www/site-perso/";
};
"/errorpages/" = {
alias = "/var/www/errorpages/";
};
"/.well-known/openpgpkey/" = {
alias = "/var/lib/gnupg/wks/nyanlout.re";
extraConfig = ''
@ -92,8 +151,24 @@ in
};
};
};
"riot.nyanlout.re" = {
enableACME = true;
forceSSL = true;
locations = { "/" = { root = pkgs.riot-web; }; };
};
"factorio.nyanlout.re" = {
enableACME = true;
forceSSL = true;
locations = { "/" = { root = "/var/www/factorio"; }; };
};
"minecraft.nyanlout.re" = {
enableACME = true;
forceSSL = true;
locations = { "/" = { root = "/var/www/minecraft-overviewer"; }; };
};
"musique-meyenheim.fr" = {
listen = [ { addr = "127.0.0.1"; port = 10004; } ];
enableACME = true;
forceSSL = true;
locations = {
"/" = {
proxyPass = "http://unix:/run/site-musique.sock";
@ -106,6 +181,33 @@ in
};
};
};
"maxspiegel.fr" = {
enableACME = true;
forceSSL = true;
locations."/" = {
root = "/run/python-ci/nyanloutre/site-max";
};
};
"login.nyanlout.re" = {
enableACME = true;
forceSSL = true;
locations."/" = {
proxyPass = "http://127.0.0.1:${toString(config.services.nginx.sso.configuration.listen.port)}/";
};
};
"grafana.nyanlout.re" = nginxAuthReverse config.services.grafana.port;
"transmission.nyanlout.re" = nginxAuthReverse config.services.transmission.port;
"radarr.nyanlout.re" = nginxAuthReverse 7878;
"sonarr.nyanlout.re" = nginxAuthReverse 8989;
"syncthing.nyanlout.re" = nginxAuthReverse 8384;
"jackett.nyanlout.re" = nginxAuthReverse 9117;
"pgmanage.nyanlout.re" = nginxAuthReverse config.services.pgmanage.port;
"matrix.nyanlout.re" = nginxSimpleReverse 8008;
"airsonic.nyanlout.re" = nginxSimpleReverse 4040;
"emby.nyanlout.re" = nginxSimpleReverse 8096;
"ci.nyanlout.re" = nginxSimpleReverse 52350;
"gitea.nyanlout.re" = nginxSimpleReverse config.services.gitea.httpPort;
};
};
@ -140,12 +242,6 @@ in
};
python-ci.enable = true;
site-max = {
enable = true;
port = 10007;
domaine = "maxspiegel.fr";
};
};
systemd.services.site-musique = let