refactor: streamline all websites into one folder

This commit is contained in:
Rouven Seifert 2024-03-12 11:49:01 +01:00
parent 71fdea75be
commit b429e6468f
Signed by: rouven.seifert
GPG key ID: B95E8FE6B11C4D09
12 changed files with 17 additions and 11 deletions

15
modules/web/default.nix Normal file
View file

@ -0,0 +1,15 @@
{ ... }:
{
imports = [
./ifsrde.nix
./ese.nix
./infoscreen.nix
./kpp.nix
./nightline.nix
./fsrewsp.nix
./manual.nix
./sharepic.nix
./userdir.nix
./ftp.nix
];
}

78
modules/web/ese.nix Normal file
View file

@ -0,0 +1,78 @@
{ config, pkgs, ... }:
let
domain = "ese.${config.networking.domain}";
cms-domain = "directus-ese.${config.networking.domain}";
in
{
sops.secrets."directus_env" = { };
environment.systemPackages = [ pkgs.nodejs_21 ];
virtualisation.oci-containers = {
backend = "docker";
containers.directus-ese = {
image = "directus/directus:latest";
volumes = [
"/srv/web/directus-ese/uploads:/directus/uploads"
"/srv/web/directus-ese/database:/directus/database"
];
ports = [ "127.0.0.1:8055:8055" ];
extraOptions = [ "--network=host" ];
environment = {
"DB_CLIENT" = "pg";
"DB_HOST" = "localhost";
"DB_PORT" = "5432";
"DB_DATABASE" = "directus_ese";
"DB_USER" = "directus_ese";
};
environmentFiles = [
config.sops.secrets."directus_env".path
];
};
};
services.postgresql = {
enable = true;
ensureUsers = [
{
name = "directus_ese";
ensureDBOwnership = true;
}
];
ensureDatabases = [ "directus_ese" ];
};
services.nginx = {
virtualHosts."${cms-domain}" = {
enableACME = true;
forceSSL = true;
locations."/" = {
extraConfig = ''
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization';
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization';
'';
proxyPass = "http://127.0.0.1:8055";
};
};
virtualHosts."${domain}" = {
enableACME = true;
forceSSL = true;
locations."= /" = {
return = "301 /2023/";
};
locations."/" = {
root = "/srv/web/ese/served";
tryFiles = "$uri $uri/ =404";
};
};
};
}

71
modules/web/fsrewsp.nix Normal file
View file

@ -0,0 +1,71 @@
{ pkgs, config, lib, ... }:
let
domain = "fsrewsp.de";
user = "fsrewsp";
group = "fsrewsp";
in
{
users.users.${user} = {
group = group;
isSystemUser = true;
};
users.groups.${group} = { };
users.users.nginx = {
extraGroups = [ group ];
};
services.phpfpm.pools.fsrewsp = {
user = "fsrewsp";
group = "fsrewsp";
settings = {
"listen.owner" = config.services.nginx.user;
"pm" = "dynamic";
"pm.max_children" = 32;
"pm.max_requests" = 500;
"pm.start_servers" = 2;
"pm.min_spare_servers" = 2;
"pm.max_spare_servers" = 5;
"php_admin_value[error_log]" = "stderr";
"php_admin_flag[log_errors]" = true;
"catch_workers_output" = true;
};
phpEnv."PATH" = lib.makeBinPath [ pkgs.php ];
};
services.nginx.enable = true;
services.nginx = {
virtualHosts."${domain}" = {
addSSL = true;
enableACME = true;
root = "/srv/web/fsrewsp";
extraConfig = ''
index index.php index.html;
'';
locations = {
"/" = {
tryFiles = "$uri $uri/ /index.php?$args";
};
"~ \.php$" = {
extraConfig = ''
try_files $uri =404;
fastcgi_pass unix:${config.services.phpfpm.pools.fsrewsp.socket};
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_index index.php;
include ${pkgs.nginx}/conf/fastcgi_params;
include ${pkgs.nginx}/conf/fastcgi.conf;
fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
'';
};
"~ \.log$".return = "403";
"~ ^/\.user\.ini".return = "403";
"~* \.(js|css|png|jpg|jpeg|gif|ico)$".extraConfig = ''
expires max;
log_not_found off;
'';
};
};
};
}

39
modules/web/ftp.nix Normal file
View file

@ -0,0 +1,39 @@
{ config, pkgs, ... }:
let
domain = "ftp.${config.networking.domain}";
in
{
services.nginx.additionalModules = [ pkgs.nginxModules.fancyindex ];
services.nginx.virtualHosts."${domain}" = {
enableACME = true;
forceSSL = true;
root = "/srv/ftp";
extraConfig = ''
fancyindex on;
fancyindex_exact_size off;
error_page 403 /403.html;
'';
locations."~/(klausuren|uebungen|skripte|abschlussarbeiten)".extraConfig = ''
allow 141.30.0.0/16;
allow 141.76.0.0/16;
deny all;
'';
locations."~ /komplexpruef".extraConfig = ''
default_type text/plain;
'';
locations."=/403.html" = {
root = pkgs.writeTextDir "403.html" ''
<html>
<head>
<title>403 Forbidden</title>
</head>
<body>
<center><h1>403 Forbidden</h1></center>
<center>Dieser Ordner ist nur aus dem Uni-Netz zug&aumlnglich.</center>
<center>This directory is only accessible from the TUD network.</center>
</body>
</html>
'';
};
};
}

78
modules/web/ifsrde.nix Normal file
View file

@ -0,0 +1,78 @@
{ config, pkgs, lib, ... }:
let
user = "fsr-web";
group = "fsr-web";
in
{
users.users.${user} = {
group = group;
isSystemUser = true;
};
users.groups.${group} = { };
services.phpfpm.pools.ifsrde = {
user = user;
group = group;
settings = {
"listen.owner" = config.services.nginx.user;
"pm" = "dynamic";
"pm.max_children" = 32;
"pm.max_requests" = 500;
"pm.start_servers" = 2;
"pm.min_spare_servers" = 2;
"pm.max_spare_servers" = 5;
"php_admin_value[error_log]" = "stderr";
"php_admin_flag[log_errors]" = true;
"catch_workers_output" = true;
};
phpEnv."PATH" = lib.makeBinPath [ pkgs.php ];
};
services.nginx = {
virtualHosts."www.${config.networking.domain}" = {
enableACME = true;
forceSSL = true;
locations."/".return = "301 $scheme://ifsr.de$request_uri";
};
virtualHosts."${config.networking.domain}" = {
enableACME = true;
forceSSL = true;
root = "/srv/web/ifsrde";
extraConfig = ''
index index.html index.php;
'';
locations = {
"/" = {
tryFiles = "$uri $uri/ /index.php?$query_string";
};
"~ \.php$" = {
extraConfig = ''
try_files $uri =404;
fastcgi_pass unix:${config.services.phpfpm.pools.ifsrde.socket};
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_index index.php;
include ${pkgs.nginx}/conf/fastcgi_params;
include ${pkgs.nginx}/conf/fastcgi.conf;
fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
'';
};
"~ ^/cmd(/?[^\\n|\\r]*)$".return = "301 https://pad.ifsr.de$1";
"/bbb".return = "301 https://bbb.tu-dresden.de/b/fsr-58o-tmf-yy6";
"/kpp".return = "301 https://kpp.ifsr.de";
# security
"~* /(\.git|cache|bin|logs|backup|tests)/.*$".return = "403";
# deny running scripts inside core system folders
"~* /(system|vendor)/.*\.(txt|xml|md|html|json|yaml|yml|php|pl|py|cgi|twig|sh|bat)$".return = "403";
# deny running scripts inside user folder
"~* /user/.*\.(txt|md|json|yaml|yml|php|pl|py|cgi|twig|sh|bat)$".return = "403";
# deny access to specific files in the root folder
"~ /(LICENSE\.txt|composer\.lock|composer\.json|nginx\.conf|web\.config|htaccess\.txt|\.htaccess)".return = "403";
## End - Security
};
};
};
}

View file

@ -0,0 +1,14 @@
{ config, ... }:
let
domain = "infoscreen.${config.networking.domain}";
in
{
services.nginx = {
enable = true;
virtualHosts."${domain}" = {
addSSL = true;
enableACME = true;
root = "/srv/web/infoscreen/dist";
};
};
}

15
modules/web/kpp.nix Normal file
View file

@ -0,0 +1,15 @@
{ config, ... }:
let
domain = "kpp.${config.networking.domain}";
in
{
services.kpp = {
enable = true;
hostName = domain;
};
services.nginx.virtualHosts."${domain}" = {
enableACME = true;
forceSSL = true;
};
}

16
modules/web/manual.nix Normal file
View file

@ -0,0 +1,16 @@
{ config, ... }:
let
domain = "manual.${config.networking.domain}";
in
{
services.ese-manual = {
enable = true;
hostName = domain;
};
services.nginx = {
virtualHosts."${domain}" = {
addSSL = true;
enableACME = true;
};
};
}

68
modules/web/nightline.nix Normal file
View file

@ -0,0 +1,68 @@
{ pkgs, config, lib, ... }:
let
domain = "nightline-dresden.de";
user = "nightline";
group = "nightline";
in
{
users.users.${user} = {
group = group;
isSystemUser = true;
};
users.users.nginx = {
extraGroups = [ group ];
};
users.groups.${group} = { };
services.phpfpm.pools.nightline = {
user = "nightline";
group = "nightline";
settings = {
"listen.owner" = config.services.nginx.user;
"pm" = "dynamic";
"pm.max_children" = 32;
"pm.max_requests" = 500;
"pm.start_servers" = 2;
"pm.min_spare_servers" = 2;
"pm.max_spare_servers" = 5;
"php_admin_value[error_log]" = "stderr";
"php_admin_flag[log_errors]" = true;
"catch_workers_output" = true;
};
phpEnv."PATH" = lib.makeBinPath [ pkgs.php ];
};
services.nginx = {
virtualHosts."${domain}" = {
addSSL = true;
enableACME = true;
root = "/srv/web/nightline";
extraConfig = ''
index index.php index.html;
'';
locations = {
"/" = {
tryFiles = "$uri $uri/ /index.php?$args";
};
"~ \.php$" = {
extraConfig = ''
try_files $uri =404;
fastcgi_pass unix:${config.services.phpfpm.pools.nightline.socket};
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_index index.php;
include ${pkgs.nginx}/conf/fastcgi_params;
include ${pkgs.nginx}/conf/fastcgi.conf;
fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
'';
};
"~ \.log$".return = "403";
"~ ^/\.user\.ini".return = "403";
"~* \.(js|css|png|jpg|jpeg|gif|ico)$".extraConfig = ''
expires max;
log_not_found off;
'';
};
};
};
}

62
modules/web/sharepic.nix Normal file
View file

@ -0,0 +1,62 @@
{ pkgs, config, lib, ... }:
let
domain = "sharepic.${config.networking.domain}";
user = "sharepic";
group = "sharepic";
in
{
users.users.${user} = {
group = group;
isSystemUser = true;
};
users.groups.${group} = { };
services.phpfpm.pools.sharepic = {
user = "sharepic";
group = "sharepic";
settings = {
"listen.owner" = config.services.nginx.user;
"pm" = "dynamic";
"pm.max_children" = 32;
"pm.max_requests" = 500;
"pm.start_servers" = 2;
"pm.min_spare_servers" = 2;
"pm.max_spare_servers" = 5;
"php_admin_value[error_log]" = "stderr";
"php_admin_flag[log_errors]" = true;
"catch_workers_output" = true;
};
phpEnv."PATH" = lib.makeBinPath [ pkgs.php ];
};
services.nginx = {
enable = true;
virtualHosts."${domain}" = {
addSSL = true;
enableACME = true;
root = "/srv/web/sharepic";
extraConfig = ''
index index.php index.html;
'';
locations = {
"/" = {
tryFiles = "$uri $uri/ =404";
};
"~ \.php$" = {
extraConfig = ''
try_files $uri =404;
fastcgi_pass unix:${config.services.phpfpm.pools.sharepic.socket};
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_index index.php;
include ${pkgs.nginx}/conf/fastcgi_params;
include ${pkgs.nginx}/conf/fastcgi.conf;
fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
'';
};
"/data".return = "403";
};
};
};
}

84
modules/web/userdir.nix Normal file
View file

@ -0,0 +1,84 @@
{ config, pkgs, ... }:
let
domain = "users.${config.networking.domain}";
port = 8083;
apacheUser = config.services.httpd.user;
in
{
# home directory setup
systemd.tmpfiles.rules = [
"d /etc/skel"
];
environment.extraInit = /*sh*/ ''
if [[ "$HOME" != "/" && "$UID" != 0 ]]; then
umask 002
# home dir: apache may traverse only, creation mode is rw(x)------
setfacl -m u:${apacheUser}:x,d:u::rwx,d:g::-,d:o::- $HOME
mkdir -p $HOME/public_html
# public_html dir: apache and $USER have rwx on everything inside
setfacl -m u:${apacheUser}:rwx,d:u:${apacheUser}:rwx,d:u:''${USER}:rwx $HOME/public_html
fi
'';
services.httpd = {
enable = true;
enablePHP = true;
maxClients = 10;
mpm = "prefork";
extraModules = [ "userdir" ];
virtualHosts.${domain} = {
extraConfig = ''
UserDir disabled root
UserDir /home/users/*/public_html/
<Directory "/home/users/*/public_html">
Options -Indexes +MultiViews +SymLinksIfOwnerMatch +IncludesNoExec
DirectoryIndex index.php index.html
AllowOverride FileInfo AuthConfig Limit Indexes Options=Indexes
<Limit GET POST OPTIONS>
Require all granted
</Limit>
<LimitExcept GET POST OPTIONS>
Require all denied
</LimitExcept>
</Directory>
'';
listen = [{
ip = "127.0.0.1";
inherit port;
}];
};
phpPackage = pkgs.php.buildEnv {
extraConfig = ''
display_errors=0
post_max_size = 40M
upload_max_filesize = 40M
'';
};
};
services.nginx.virtualHosts.${domain} = {
enableACME = true;
forceSSL = true;
locations."/" = {
proxyPass = "http://localhost:${toString port}";
extraConfig = ''
proxy_intercept_errors on;
error_page 403 404 =404 /404.html;
client_max_body_size 40M;
'';
};
locations."/robots.txt" = {
extraConfig = ''
add_header Content-Type text/plain;
return 200 "User-agent: *\nDisallow: /\n";
'';
};
};
}