forked from nyanloutre/nixos-config
311 lines
9.9 KiB
Nix
311 lines
9.9 KiB
Nix
{ config, lib, pkgs, ... }:
|
|
|
|
with lib;
|
|
|
|
let
|
|
nginxSsoAuth = pkgs.writeText "nginx-sso_auth.inc" ''
|
|
# Protect this location using the auth_request
|
|
auth_request /sso-auth;
|
|
|
|
# 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;
|
|
}
|
|
'';
|
|
in
|
|
{
|
|
security.acme = {
|
|
email = "paul@nyanlout.re";
|
|
acceptTerms = true;
|
|
};
|
|
|
|
services = {
|
|
nginx = {
|
|
enable = true;
|
|
package = pkgs.nginx.override {
|
|
modules = with pkgs.nginxModules; [ rtmp ];
|
|
};
|
|
recommendedGzipSettings = true;
|
|
recommendedOptimisation = true;
|
|
recommendedProxySettings = true;
|
|
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 = let
|
|
base = locations: {
|
|
inherit locations;
|
|
forceSSL = true;
|
|
enableACME = true;
|
|
};
|
|
simpleReverse = rport: base {
|
|
"/" = {
|
|
proxyPass = "http://127.0.0.1:${toString(rport)}/";
|
|
};
|
|
};
|
|
authReverse = rport: base {
|
|
"/" = {
|
|
proxyPass = "http://127.0.0.1:${toString(rport)}/";
|
|
extraConfig = ''
|
|
auth_request_set $cookie $upstream_http_set_cookie;
|
|
add_header Set-Cookie $cookie;
|
|
'';
|
|
};
|
|
} // {
|
|
extraConfig = ''
|
|
include ${nginxSsoAuth};
|
|
'';
|
|
};
|
|
in {
|
|
"nyanlout.re" = base {
|
|
"/" = {
|
|
alias = "/var/www/site-perso/";
|
|
};
|
|
"/errorpages/" = {
|
|
alias = "/var/www/errorpages/";
|
|
};
|
|
"/.well-known/openpgpkey/" = {
|
|
alias = "/var/lib/gnupg/wks/nyanlout.re";
|
|
extraConfig = ''
|
|
add_header Access-Control-Allow-Origin * always;
|
|
'';
|
|
};
|
|
} // { default = true; };
|
|
"riot.nyanlout.re" = base { "/" = { root = pkgs.riot-web; }; };
|
|
"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/";
|
|
};
|
|
};
|
|
"maxspiegel.fr" = base { "/" = { root = "/run/python-ci/nyanloutre/site-max"; }; };
|
|
"stream.nyanlout.re" = base {
|
|
"/" = {
|
|
root = "/var/www/hls/";
|
|
extraConfig = ''
|
|
add_header Cache-Control no-cache;
|
|
add_header Access-Control-Allow-Origin *;
|
|
'';
|
|
};
|
|
};
|
|
"login.nyanlout.re" = simpleReverse config.services.nginx.sso.configuration.listen.port;
|
|
"grafana.nyanlout.re" = authReverse config.services.grafana.port;
|
|
"transmission.nyanlout.re" = authReverse config.services.transmission.port;
|
|
"radarr.nyanlout.re" = authReverse 7878;
|
|
"sonarr.nyanlout.re" = authReverse 8989;
|
|
"syncthing.nyanlout.re" = authReverse 8384;
|
|
"jackett.nyanlout.re" = authReverse 9117;
|
|
"pgmanage.nyanlout.re" = authReverse config.services.pgmanage.port;
|
|
"matrix.nyanlout.re" = simpleReverse 8008;
|
|
"airsonic.nyanlout.re" = simpleReverse 4040;
|
|
"emby.nyanlout.re" = simpleReverse 8096;
|
|
"ci.nyanlout.re" = simpleReverse 52350;
|
|
"gitea.nyanlout.re" = simpleReverse config.services.gitea.httpPort;
|
|
};
|
|
appendConfig = let
|
|
rootLocation = config.services.nginx.virtualHosts."stream.nyanlout.re".locations."/".root;
|
|
in ''
|
|
rtmp {
|
|
server {
|
|
listen 1935;
|
|
|
|
application live {
|
|
live on;
|
|
|
|
exec_push ${pkgs.ffmpeg}/bin/ffmpeg -i rtmp://localhost/$app/$name -async 1 -vsync -1
|
|
-c:v libx264 -c:a aac -b:v 768k -b:a 96k -vf "scale=720:trunc(ow/a/2)*2" -tune zerolatency -preset ultrafast -crf 28 -f flv rtmp://localhost/show/$name_mid
|
|
-c:v libx264 -c:a aac -b:v 1024k -b:a 128k -vf "scale=960:trunc(ow/a/2)*2" -tune zerolatency -preset ultrafast -crf 28 -f flv rtmp://localhost/show/$name_high
|
|
-c copy -f flv rtmp://localhost/show/$name_src 2>>${rootLocation}/ffmpeg-$name.log;
|
|
}
|
|
|
|
application show {
|
|
live on;
|
|
hls on;
|
|
|
|
hls_path ${rootLocation};
|
|
hls_fragment 3s;
|
|
hls_playlist_length 60s;
|
|
|
|
hls_variant _mid BANDWIDTH=448000; # Medium bitrate, SD resolution
|
|
hls_variant _high BANDWIDTH=1152000; # High bitrate, higher-than-SD resolution
|
|
hls_variant _src BANDWIDTH=4096000; # Source bitrate, source resolution
|
|
}
|
|
}
|
|
}
|
|
'';
|
|
};
|
|
|
|
postgresql = {
|
|
enable = true;
|
|
extraConfig = ''
|
|
full_page_writes = off
|
|
'';
|
|
};
|
|
|
|
pgmanage = {
|
|
enable = true;
|
|
port = 10006;
|
|
connections = {
|
|
localhost = "hostaddr=127.0.0.1 port=5432 dbname=postgres";
|
|
};
|
|
};
|
|
|
|
gitea = {
|
|
enable = true;
|
|
cookieSecure = true;
|
|
httpPort = 3001;
|
|
rootUrl = "https://gitea.nyanlout.re/";
|
|
database = {
|
|
type = "postgres";
|
|
port = 5432;
|
|
passwordFile = "/var/lib/gitea/custom/conf/database_password";
|
|
};
|
|
log.level = "Warn";
|
|
extraConfig = ''
|
|
[ui]
|
|
DEFAULT_THEME = arc-green
|
|
|
|
[service]
|
|
DISABLE_REGISTRATION = true
|
|
'';
|
|
};
|
|
|
|
python-ci.enable = true;
|
|
|
|
mastodon = {
|
|
enable = true;
|
|
localDomain = "social.nyanlout.re";
|
|
configureNginx = true;
|
|
extraConfig = {
|
|
SMTP_AUTH_METHOD = "none";
|
|
SMTP_OPENSSL_VERIFY_MODE = "none";
|
|
};
|
|
smtp = {
|
|
fromAddress = "social@nyanlout.re";
|
|
user = "social@nyanlout.re";
|
|
authenticate = false;
|
|
};
|
|
mediaPruneTimer = true;
|
|
};
|
|
};
|
|
|
|
systemd.services.site-musique = let
|
|
djangoEnv =(pkgs.python3.withPackages (ps: with ps; [ gunicorn django_2_2 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" ];
|
|
};
|
|
}
|