nixos-config/systems/LoutreOS/web.nix

375 lines
11 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
nginxSimpleReverse = rport: {
enableACME = true;
forceSSL = true;
locations."/" = {
proxyPass = "http://127.0.0.1:${toString(rport)}/";
2019-11-01 15:24:50 +01:00
};
2020-04-08 12:45:36 +02:00
};
2019-11-01 15:24:50 +01:00
2020-04-08 12:45:36 +02:00
nginxAuthReverse = rport: {
enableACME = true;
forceSSL = true;
2019-11-01 15:24:50 +01:00
2020-04-08 12:45:36 +02:00
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 = {
2019-11-01 15:24:50 +01:00
nginx = {
enable = true;
2020-04-08 12:48:42 +02:00
package = pkgs.nginx.override {
modules = with pkgs.nginxModules; [ rtmp ];
};
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;
error_page 500 502 503 504 https://nyanlout.re/errorpages/50x.html;
2020-03-02 23:20:17 +01:00
'';
2020-04-08 12:45:36 +02:00
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" ];
}
];
};
2019-11-02 13:53:53 +01:00
};
2020-04-08 12:45:36 +02:00
};
virtualHosts = {
2020-03-02 23:20:17 +01:00
"nyanlout.re" = {
2020-04-08 12:45:36 +02:00
default = true;
enableACME = true;
forceSSL = true;
2020-03-02 23:20:17 +01:00
locations = {
"/" = {
alias = "/var/www/site-perso/";
};
2020-04-08 12:45:36 +02:00
"/errorpages/" = {
alias = "/var/www/errorpages/";
};
2020-03-02 23:20:17 +01:00
"/.well-known/openpgpkey/" = {
alias = "/var/lib/gnupg/wks/nyanlout.re";
extraConfig = ''
add_header Access-Control-Allow-Origin * always;
'';
};
};
2019-11-01 15:24:50 +01:00
};
2020-04-08 12:45:36 +02:00
"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" = {
2020-04-08 12:45:36 +02:00
enableACME = true;
forceSSL = true;
locations = {
"/" = {
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:45:36 +02:00
"maxspiegel.fr" = {
enableACME = true;
forceSSL = true;
locations."/" = {
root = "/run/python-ci/nyanloutre/site-max";
};
};
2020-04-08 12:49:45 +02:00
"social.nyanlout.re" = {
enableACME = true;
forceSSL = true;
root = "${config.services.mastodon.package}/public/";
locations."/system/".alias = "/var/lib/mastodon/public-system/";
locations."/" = {
tryFiles = "$uri @proxy";
};
locations."@proxy" = {
proxyPass = "http://127.0.0.1:${toString(config.services.mastodon.webPort)}";
proxyWebsockets = true;
extraConfig = ''
proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
'';
};
locations."/api/v1/streaming/" = {
proxyPass = "http://127.0.0.1:${toString(config.services.mastodon.streamingPort)}/";
proxyWebsockets = true;
extraConfig = ''
proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
'';
};
};
2020-04-08 12:48:42 +02:00
"stream.nyanlout.re" = {
enableACME = true;
forceSSL = true;
root = "/var/www/hls/";
locations."/" = {
extraConfig = ''
add_header Cache-Control no-cache;
add_header Access-Control-Allow-Origin *;
'';
};
};
2020-04-08 12:45:36 +02:00
"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;
2019-11-01 15:24:50 +01:00
};
2020-04-08 12:48:42 +02:00
appendConfig = ''
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>>${config.services.nginx.virtualHosts."stream.nyanlout.re".root}/ffmpeg-$name.log;
}
application show {
live on;
hls on;
hls_path ${config.services.nginx.virtualHosts."stream.nyanlout.re".root};
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
}
}
}
'';
2019-11-01 15:24:50 +01:00
};
2020-04-08 12:53:53 +02:00
postgresql = {
enable = true;
extraConfig = ''
full_page_writes = off
'';
};
2019-11-01 15:24:50 +01:00
pgmanage = {
enable = true;
2020-03-02 23:20:17 +01:00
port = 10006;
2019-11-01 15:24:50 +01:00
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;
2020-04-08 12:49:45 +02:00
mastodon = {
enable = true;
localDomain = "social.nyanlout.re";
extraConfig = {
SMTP_AUTH_METHOD = "none";
SMTP_OPENSSL_VERIFY_MODE = "none";
};
smtp = {
fromAddress = "social@nyanlout.re";
user = "social@nyanlout.re";
authenticate = false;
};
mediaPruneTimer = true;
};
2019-11-01 15:24:50 +01:00
};
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" ];
};
2019-11-01 15:24:50 +01:00
}