nixos-config/systems/LoutreOS/web.nix

430 lines
13 KiB
Nix
Raw Normal View History

2019-11-01 15:24:50 +01:00
{ config, lib, pkgs, ... }:
with lib;
let
2020-04-08 12:45:36 +02:00
nginxSsoAuth = pkgs.writeText "nginx-sso_auth.inc" ''
# Protect this location using the auth_request
auth_request /sso-auth;
2019-11-01 15:24:50 +01:00
2020-04-08 12:45:36 +02:00
# 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;
}
2019-11-01 15:24:50 +01:00
'';
2020-04-08 12:45:36 +02:00
in
{
security.acme = {
2022-07-05 20:41:35 +02:00
defaults.email = "paul@nyanlout.re";
2020-04-08 12:45:36 +02:00
acceptTerms = true;
};
2021-10-11 10:58:02 +02:00
users.groups = {
work = {};
webdav = {};
};
users.users = {
work = {
isSystemUser = true;
group = config.users.groups.work.name;
};
webdav = {
isSystemUser = true;
group = config.users.groups.webdav.name;
};
# wordpress = {
# isSystemUser = true;
# group = config.services.nginx.group;
# };
2020-11-29 12:53:51 +01:00
};
2020-04-08 12:45:36 +02:00
services = {
2021-10-11 10:58:02 +02:00
phpfpm.pools = {
2022-07-05 20:40:48 +02:00
# work = {
# user = config.users.users.work.name;
# phpPackage = pkgs.php.withExtensions ({ all, ... }: with all; [ redis filter ]);
# settings = {
# "listen.owner" = config.services.nginx.user;
# "pm" = "dynamic";
# "pm.max_children" = 75;
# "pm.start_servers" = 10;
# "pm.min_spare_servers" = 5;
# "pm.max_spare_servers" = 20;
# "pm.max_requests" = 500;
# };
# };
2022-09-23 13:38:36 +02:00
# "wordpress-designyourfuture" = {
# user = config.users.users.wordpress.name;
# group = config.services.nginx.group;
# settings = {
# "listen.owner" = config.services.nginx.user;
# "pm" = "dynamic";
# "pm.max_children" = 32;
# "pm.start_servers" = 2;
# "pm.min_spare_servers" = 2;
# "pm.max_spare_servers" = 4;
# "pm.max_requests" = 500;
# };
# };
2022-09-23 13:38:36 +02:00
2021-10-11 10:58:02 +02:00
drive = {
user = config.users.users.webdav.name;
settings = {
"listen.owner" = config.services.nginx.user;
"pm" = "dynamic";
"pm.max_children" = 75;
"pm.start_servers" = 10;
"pm.min_spare_servers" = 5;
"pm.max_spare_servers" = 20;
"pm.max_requests" = 500;
};
phpOptions = ''
output_buffering=off
'';
2020-11-29 12:53:51 +01:00
};
};
2019-11-01 15:24:50 +01:00
nginx = {
enable = true;
2020-04-08 12:48:42 +02:00
package = pkgs.nginx.override {
2021-10-11 10:58:02 +02:00
modules = with pkgs.nginxModules; [ dav moreheaders ];
2020-04-08 12:48:42 +02:00
};
2020-04-08 12:45:36 +02:00
recommendedGzipSettings = true;
recommendedOptimisation = true;
2020-03-02 23:20:17 +01:00
recommendedProxySettings = true;
2020-04-08 12:45:36 +02:00
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;
2020-03-02 23:20:17 +01:00
'';
2020-04-08 12:45:36 +02:00
sso = {
enable = true;
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" ];
}
];
};
2019-11-02 13:53:53 +01:00
};
2020-04-08 12:45:36 +02:00
};
2020-04-08 13:03:01 +02:00
virtualHosts = let
base = locations: {
2021-10-11 10:58:02 +02:00
locations = locations // {
"@maintenance" = {
root = "/var/www/errorpages/";
extraConfig = ''
rewrite ^(.*)$ /50x.html break;
'';
};
};
2020-04-08 13:03:01 +02:00
forceSSL = true;
enableACME = true;
2021-10-11 10:58:02 +02:00
extraConfig = ''
error_page 500 502 503 504 = @maintenance;
'';
2020-04-08 13:03:01 +02:00
};
simpleReverse = rport: base {
"/" = {
proxyPass = "http://127.0.0.1:${toString(rport)}/";
};
};
2021-10-11 10:58:02 +02:00
authReverse = rport: zipAttrsWith (name: vs: if name == "extraConfig" then (concatStrings vs) else elemAt vs 0) [
(base {
"/" = {
proxyPass = "http://127.0.0.1:${toString(rport)}/";
extraConfig = ''
auth_request_set $cookie $upstream_http_set_cookie;
2022-12-30 15:08:20 +01:00
auth_request_set $username $upstream_http_x_username;
proxy_set_header X-WEBAUTH-USER $username;
2021-10-11 10:58:02 +02:00
add_header Set-Cookie $cookie;
'';
};
})
{
2020-04-08 13:03:01 +02:00
extraConfig = ''
2021-10-11 10:58:02 +02:00
include ${nginxSsoAuth};
2020-04-08 13:03:01 +02:00
'';
2021-10-11 10:58:02 +02:00
}
];
2020-04-08 13:03:01 +02:00
in {
2020-04-09 16:28:25 +02:00
"nyanlout.re" = base {
"/" = {
alias = "/var/www/site-perso/";
2020-04-08 12:45:36 +02:00
};
2021-10-11 10:58:02 +02:00
"/maintenance/" = {
2020-04-09 16:28:25 +02:00
alias = "/var/www/errorpages/";
2020-04-08 12:49:45 +02:00
};
2020-04-09 16:28:25 +02:00
"/.well-known/openpgpkey/" = {
alias = "/var/lib/gnupg/wks/nyanlout.re";
2020-04-08 12:49:45 +02:00
extraConfig = ''
2020-04-09 16:28:25 +02:00
add_header Access-Control-Allow-Origin * always;
2020-04-08 12:49:45 +02:00
'';
};
2020-04-09 16:28:25 +02:00
} // { default = true; };
"factorio.nyanlout.re" = base { "/" = { root = "/var/www/factorio"; }; };
"minecraft.nyanlout.re" = base { "/" = { root = "/var/www/minecraft-overviewer"; }; };
"musique-meyenheim.fr" = base {
"/" = {
proxyPass = "http://unix:/run/site-musique.sock";
};
"/static/" = {
alias = "/var/www/site-musique/staticfiles/";
};
"/media/" = {
alias = "/var/www/site-musique/media/";
2020-04-08 12:49:45 +02:00
};
};
2023-02-16 17:30:46 +01:00
"www.musique-meyenheim.fr" = {
enableACME = true;
forceSSL = true;
globalRedirect = "musique-meyenheim.fr";
};
# "maxspiegel.fr" = base { "/" = { root = "/run/python-ci/nyanloutre/site-max"; }; };
2020-04-09 16:28:25 +02:00
"stream.nyanlout.re" = base {
"/" = {
2021-01-06 02:20:58 +01:00
proxyPass = "http://10.30.135.71";
2020-04-08 12:48:42 +02:00
};
};
2020-04-09 16:28:25 +02:00
"login.nyanlout.re" = simpleReverse config.services.nginx.sso.configuration.listen.port;
2022-12-30 15:08:20 +01:00
"grafana.nyanlout.re" = authReverse config.services.grafana.settings.server.http_port;
2021-12-16 19:07:30 +01:00
"transmission.nyanlout.re" = authReverse config.services.transmission.settings.rpc-port;
2020-04-08 13:03:01 +02:00
"radarr.nyanlout.re" = authReverse 7878;
"sonarr.nyanlout.re" = authReverse 8989;
"syncthing.nyanlout.re" = authReverse 8384;
2023-05-18 22:41:11 +02:00
"prowlarr.nyanlout.re" = authReverse 9696;
2020-04-08 13:03:01 +02:00
"matrix.nyanlout.re" = simpleReverse 8008;
2021-10-11 10:58:02 +02:00
"emby.nyanlout.re" = recursiveUpdate (simpleReverse 8096) {
locations."/" = {
proxyWebsockets = true;
};
};
2020-04-08 13:03:01 +02:00
"ci.nyanlout.re" = simpleReverse 52350;
"gitea.nyanlout.re" = simpleReverse config.services.gitea.settings.server.HTTP_PORT;
2021-01-06 02:07:56 +01:00
"musique.nyanlout.re" = simpleReverse config.services.navidrome.settings.Port;
2023-05-18 20:23:02 +02:00
"photo.nyanlout.re" = recursiveUpdate (simpleReverse config.services.photoprism.port) {
2022-12-30 15:08:37 +01:00
locations."/" = {
proxyWebsockets = true;
};
};
2022-06-14 08:27:13 +02:00
"apart.nyanlout.re" = recursiveUpdate (simpleReverse config.services.home-assistant.config.http.server_port) {
2020-08-30 21:16:41 +02:00
locations."/" = {
proxyWebsockets = true;
};
};
2021-10-11 10:58:02 +02:00
# "work.rezom.eu" = base {
# "/" = {
# index = "/_h5ai/public/index.php";
# extraConfig = ''
# dav_ext_methods PROPFIND OPTIONS;
# '';
# };
# "~ ^/(_h5ai/public/index|random).php" = {
# extraConfig = ''
# fastcgi_split_path_info ^(.+\.php)(/.+)$;
# fastcgi_pass unix:${config.services.phpfpm.pools.work.socket};
# include ${pkgs.nginx}/conf/fastcgi_params;
# include ${pkgs.nginx}/conf/fastcgi.conf;
# '';
# };
# } // {
# root = "/mnt/medias/iso_linux";
# extraConfig = ''
# access_log /var/log/nginx/$host.log;
# '';
# };
"drive.nyanlout.re" = base {
2020-11-29 12:53:51 +01:00
"/" = {
2021-10-11 10:58:02 +02:00
index = "/index.php";
2020-11-29 12:53:51 +01:00
extraConfig = ''
fastcgi_split_path_info ^(.+\.php)(/.+)$;
2021-10-11 10:58:02 +02:00
fastcgi_pass unix:${config.services.phpfpm.pools.drive.socket};
2020-11-29 12:53:51 +01:00
include ${pkgs.nginx}/conf/fastcgi_params;
include ${pkgs.nginx}/conf/fastcgi.conf;
2021-10-11 10:58:02 +02:00
client_max_body_size 0;
2020-11-29 12:53:51 +01:00
'';
};
} // {
2021-10-11 10:58:02 +02:00
root = "/mnt/webdav";
};
2021-10-11 10:58:02 +02:00
"rspamd.nyanlout.re" = zipAttrsWith (name: vs: if name == "extraConfig" then (concatStrings vs) else elemAt vs 0) [
(base {
"/" = {
proxyPass = "http://unix:/run/rspamd/worker-controller.sock";
extraConfig = ''
auth_request_set $cookie $upstream_http_set_cookie;
add_header Set-Cookie $cookie;
'';
};
})
{
extraConfig = ''
include ${nginxSsoAuth};
'';
}
];
2022-09-23 13:38:36 +02:00
"designyourfuture.amandoline-creations.fr" = base {
2023-02-16 17:31:01 +01:00
"/".alias = "/var/www/amandoline-designyourfuture/";
};
"amandoline-creations.fr" = base {
"/".alias = "/var/www/amandoline-portfolio/";
};
"www.amandoline-creations.fr" = {
enableACME = true;
forceSSL = true;
globalRedirect = "amandoline-creations.fr";
};
2019-11-01 15:24:50 +01:00
};
};
2020-04-08 12:53:53 +02:00
postgresql = {
enable = true;
2022-07-04 23:39:05 +02:00
package = pkgs.postgresql_14;
2020-11-29 12:51:18 +01:00
settings = {
full_page_writes = false;
};
2020-04-08 12:53:53 +02:00
};
2019-11-01 15:24:50 +01:00
gitea = {
enable = true;
database = {
type = "postgres";
port = 5432;
passwordFile = "/var/lib/gitea/custom/conf/database_password";
};
2020-11-29 12:51:18 +01:00
settings = {
server = {
HTTP_PORT = 3001;
ROOT_URL = "https://gitea.nyanlout.re/";
};
2020-11-29 12:51:18 +01:00
ui.DEFAULT_THEME = "arc-green";
2022-12-30 15:08:20 +01:00
log.LEVEL = "Warn";
service.DISABLE_REGISTRATION = true;
session.COOKIE_SECURE = true;
2020-11-29 12:51:18 +01:00
};
2019-11-01 15:24:50 +01:00
};
python-ci.enable = true;
2022-09-23 13:38:36 +02:00
# mysql = {
# enable = true;
# package = pkgs.mariadb;
# };
2019-11-01 15:24:50 +01:00
};
2020-11-29 12:51:18 +01:00
systemd.services.nginx.serviceConfig = {
2021-10-11 10:58:02 +02:00
ReadWritePaths = [
"/var/www/hls"
"/mnt/webdav"
];
2020-11-29 12:51:18 +01:00
};
2020-11-29 12:53:51 +01:00
systemd.services.phpfpm-work.serviceConfig = {
ReadOnlyPaths = "/mnt/medias/iso_linux";
2021-01-06 02:15:38 +01:00
ReadWritePaths = [
"/mnt/medias/iso_linux/_h5ai"
];
2020-11-29 12:53:51 +01:00
};
systemd.services.site-musique = let
2021-07-28 23:03:34 +02:00
djangoEnv =(pkgs.python3.withPackages (ps: with ps; [ gunicorn django_3 pillow setuptools ]));
in {
description = "Site Django de la musique de Meyenheim";
after = [ "network.target" ];
requires = [ "site-musique.socket" ];
preStart = ''
${djangoEnv}/bin/python manage.py migrate;
${djangoEnv}/bin/python manage.py collectstatic --no-input;
'';
environment = {
DJANGO_SETTINGS_MODULE = "site_musique.settings.prod";
NGINX_DIRECTORY = "/var/www/site-musique";
};
serviceConfig = {
DynamicUser = true;
Group = "nginx";
StateDirectory = "site-musique";
WorkingDirectory = "/var/www/site-musique/";
ReadWritePaths = [ "/var/www/site-musique/staticfiles" "/var/www/site-musique/media" ];
EnvironmentFile = "/mnt/secrets/site-musique.env";
ExecStart = ''${djangoEnv}/bin/gunicorn \
--access-logfile - \
--bind unix:/run/site-musique.sock \
site_musique.wsgi:application
'';
PrivateTmp = true;
};
};
systemd.sockets.site-musique = {
description = "Site Musique socket";
wantedBy = [ "sockets.target" ];
listenStreams = [ "/run/site-musique.sock" ];
};
2021-10-11 10:43:57 +02:00
systemd.services.nginx-sso.serviceConfig.EnvironmentFile = "/mnt/secrets/nginx-sso.env";
2019-11-01 15:24:50 +01:00
}