factorisation reverse proxy

merge-requests/18/head
korenstin 2025-06-23 23:50:10 +02:00
parent 5d99a7fea1
commit f553309944
6 changed files with 389 additions and 98 deletions

View File

@ -22,6 +22,10 @@ Serveur Matrix, bridge IRC <-> Matrix et interface admin pour synapse, accessibl
Serveur redlib (client WEB alternatif pour Reddit), accessible à <https://redite.crans.org>. Serveur redlib (client WEB alternatif pour Reddit), accessible à <https://redite.crans.org>.
## reverseproxy
Serveur qui héberge un reverseproxy et une instance de anubis.
## two ## two
Serveur NixOS de test. Vous pouvez vous en servir comme base pour la configuration d'une nouvelle machine. Serveur NixOS de test. Vous pouvez vous en servir comme base pour la configuration d'une nouvelle machine.

View File

@ -1,15 +1,70 @@
{ ... }: { pkgs, ... }:
let
anubisBotsMirror = pkgs.writeText "anubis_bots_mirror.yaml" ''
- name: whitelist-crans
action: ALLOW
remote_addresses:
- 185.230.79.0/22
- 2a0c:700::/32
- 46.105.102.188/32
- 2001:41d0:2:d5bc::/128
- name: no-user-agent-string
action: DENY
expression: userAgent == ""
- name: ban-gpt
user_agent_regex: ".*gpt.*"
action: DENY
- name: ban-bot
user_agent_regex: ".*(b|B)ot.*"
action: DENY
- name: ban-WebKit
action: DENY
expression:
all:
- userAgent.startsWith("Mozilla")
- userAgent.matches("AppleWebKit")
- userAgent.matches("Safari")
- userAgent.matches("Chrome")
- name: ban-Barkrowler
user_agent_regex: ".*Barkrowler.*"
action: DENY
'';
anubisMirror = pkgs.writeText "anubis_mirror.json" ''
{ {
"bots": [
{
"import": "${anubisBotsMirror}"
},
{
"name": "allow-repo",
"path_regex": "^...*",
"action": "ALLOW"
},
{
"name": "deny-other",
"path_regex": ".*",
"action": "ALLOW"
}
]
}
'';
in {
services.anubis = { services.anubis = {
instances."muraille" = { instances."mirror" = {
enable = true; enable = true;
settings = { settings = {
BIND_NETWORK = "tcp"; BIND_NETWORK = "tcp";
BIND = "127.0.0.1:7777"; BIND = "127.0.0.1:7779";
TARGET = "http://localhost:8888"; TARGET = "http://localhost:8890";
COOKIE_DOMAIN = "crans.org"; COOKIE_DOMAIN = "crans.org";
REDIRECT_DOMAINS = "install-party.crans.org,mediawiki.crans.org,wiki.crans.org"; REDIRECT_DOMAINS = "eclat.crans.org,mirror.crans.org";
POLICY_FNAME = "${anubisMirror}";
}; };
}; };
}; };

View File

@ -1,10 +1,87 @@
{ ... }: { pkgs, ... }:
let
antibot = pkgs.writeText "antibot.yaml"
''
- name: whitelist-crans
action: ALLOW
remote_addresses:
- 185.230.79.0/22
- 2a0c:700::/32
- 46.105.102.188/32
- 2001:41d0:2:d5bc::/128
- name: no-user-agent-string
action: DENY
expression: userAgent == ""
- name: ban-gpt
user_agent_regex: ".*gpt.*"
action: DENY
- name: ban-bot
user_agent_regex: ".*(b|B)ot.*"
action: DENY
- name: ban-WebKit
action: CHALLENGE
expression:
all:
- userAgent.startsWith("Mozilla")
- userAgent.matches("AppleWebKit")
- userAgent.matches("Safari")
- userAgent.matches("Chrome")
- name: ban-Barkrowler
user_agent_regex: ".*Barkrowler.*"
action: DENY
'';
anubisChallenge = pkgs.writeText "anubis_challenge.json"
''
{ {
"bots": [
{
"import": "${antibot}"
},
{
"name": "challenge-other",
"path_regex": "^*",
"action": "CHALLENGE"
}
]
}
'';
anubisMirrors = pkgs.writeText "anubis_mirrors.json"
''
{
"bots": [
{
"import": "${antibot}"
},
{
"name": "deny-other",
"path_regex": ".*cdimage-.*",
"action": "ALLOW"
},
{
"name": "allow-repo",
"path_regex": "^...*",
"action": "ALLOW"
},
{
"name": "deny-other",
"path_regex": ".*",
"action": "CHALLENGE"
}
]
}
'';
in {
imports = [ imports = [
./anubis.nix
./hardware-configuration.nix ./hardware-configuration.nix
./networking.nix ./networking.nix
./anubis.nix
./reverseproxy.nix ./reverseproxy.nix
]; ];
@ -12,6 +89,8 @@
networking.hostName = "reverseproxy"; networking.hostName = "reverseproxy";
boot.loader.grub.devices = [ "/dev/sda" ]; boot.loader.grub.devices = [ "/dev/sda" ];
users.users."nginx".home = "/var/lib/nginx";
crans = { crans = {
enable = true; enable = true;
@ -27,6 +106,51 @@
resticClient.when = "03:42"; resticClient.when = "03:42";
reverseProxy = {
enable = true;
virtualHosts = {
"eclats" = {
anubisConfig = "${anubisMirrors}";
target = "172.16.10.104";
};
"install-party" = {
anubisConfig = "${anubisChallenge}";
target = "/var/www/install-party.crans.org";
serverAliases = [
"i-p"
"adopteunmanchot"
"adopteunpingouin"
];
};
"mediawiki" = {
anubisConfig = "${anubisChallenge}";
target = "172.16.10.144";
serverAliases = [
"mediakiwi"
];
};
"mirrors" = {
anubisConfig = "${anubisMirrors}";
target = "172.16.10.104";
};
"perso" = {
anubisConfig = "${anubisChallenge}";
target = "172.16.10.31";
serverAliases = [
"clubs"
];
};
"wiki" = {
anubisConfig = "${anubisChallenge}";
target = "172.16.10.161";
serverAliases = [
"wikipedia"
];
};
};
};
services = { services = {
acme.enable = true; acme.enable = true;
}; };

View File

@ -1,100 +1,53 @@
{ config, ... }: { config, ... }:
{ {
users.users."nginx".home = "/var/lib/nginx"; services.nginx.virtualHosts = {
# redirection eclat
"eclat.crans.fr" = {
rejectSSL = true;
serverAliases = [
"eclat.crans.eu"
];
extraConfig = ''
return 301 http://eclat.crans.org$request_uri;
'';
};
services.nginx = { # redirection mirror
enable = true; "mirror.crans.fr" = {
virtualHosts = rejectSSL = true;
let anubisConf = [ serverAliases = [
"mirror.crans.eu"
];
extraConfig = ''
return 301 http://mirror.crans.org$request_uri;
'';
};
# redirection anubis mirrors
"anubis-mirror" = {
rejectSSL = true;
locations."/" = {
proxyPass = "http://${config.services.anubis.instances."mirror".settings.BIND}";
};
serverName = "mirror.crans.org";
serverAliases = [
"eclat.crans.org"
];
};
# mirror
"mirror.crans.org" = {
locations."/".proxyPass = "http://172.16.10.104";
listen = [
{ {
addr = "localhost"; addr = "localhost";
port = 8888; port = 8890;
} }
]; ];
in {
# redirection install-party
"install-party.crans.fr" = {
enableACME = true;
forceSSL = true;
serverAliases = [ serverAliases = [
"i-p.crans.org" "eclat.crans.org"
"adopteunmanchot.crans.org"
"adopteunpingouin.crans.org"
"i-p.crans.fr"
"adopteunmanchot.crans.fr"
"adopteunpingouin.crans.fr"
"i-p.crans.eu"
"install-party.crans.eu"
"adopteunmanchot.crans.eu"
"adopteunpingouin.crans.eu"
]; ];
extraConfig = ''
return 301 https://install-party.crans.org$request_uri;
'';
};
# redirection mediawiki
"mediawiki.crans.fr" = {
enableACME = true;
forceSSL = true;
serverAliases = [
"mediakiwi.crans.org"
"mediakiwi.crans.fr"
"mediakiwi.crans.eu"
"mediawiki.crans.eu"
];
extraConfig = ''
return 301 https://mediawiki.crans.org$request_uri;
'';
};
# redirection wiki
"wiki.crans.fr" = {
enableACME = true;
forceSSL = true;
serverAliases = [
"wikipedia.crans.org"
"wikipedia.crans.fr"
"wikipedia.crans.eu"
"wiki.crans.eu"
];
extraConfig = ''
return 301 https://wiki.crans.org$request_uri;
'';
};
# redirection anubis
"anubis" = {
enableACME = true;
forceSSL = true;
locations."/" = {
proxyPass = "http://${config.services.anubis.instances."muraille".settings.BIND}";
};
serverName = "install-party.crans.org";
serverAliases = [
"mediawiki.crans.org"
"wiki.crans.org"
];
};
# install-party
"install-party.crans.org" = {
root = "/var/www/install-party.crans.org";
listen = anubisConf;
};
# mediawiki
"mediawiki.crans.org" = {
locations."/".proxyPass = "http://172.16.10.144";
listen = anubisConf;
};
# wiki
"wiki.crans.org" = {
locations."/".proxyPass = "http://172.16.10.161";
listen = anubisConf;
};
}; };
}; };
} }

View File

@ -6,5 +6,6 @@
./coturn.nix ./coturn.nix
./nginx.nix ./nginx.nix
./restic.nix ./restic.nix
./reverseproxy.nix
]; ];
} }

View File

@ -0,0 +1,154 @@
{ pkgs, lib, config, ... }:
let
cfg = config.crans.reverseProxy;
allowAll = pkgs.writeText "allow_all.json"
''
{
"bots": [
{
"name": "allow_all",
"path_regex": ".*",
"action": "ALLOW"
}
]
}
'';
inherit (lib)
cartesianProduct
literalExpression
mapAttrs
mapAttrs'
mkEnableOption
mkIf
mkOption
nameValuePair
substring
types
;
in
{
options.crans.reverseProxy = {
enable = mkEnableOption "Configuration du reverseproxy.";
virtualHosts = mkOption {
type = types.attrsOf (
types.submodule {
options = {
serverAliases = mkOption {
type = types.listOf types.str;
default = [ ];
example = [
"everything"
"voyager"
];
description = ''
Déclaration des alias.
'';
};
target = mkOption {
type = types.str;
default = "";
description = ''
Indique la destination. Il peut s'agir du chemin vers des fichiers statiques.
'';
example = "172.16.10.128:8000";
};
anubisConfig = mkOption {
type = types.str;
default = "";
description = ''
Chemin du fichier de configuration
'';
example = "/var/www/anubis.conf";
};
};
}
);
default = {};
example = literalExpression ''
{
"framadate" = {
host = "176.16.10.128:8000";
serverAliases = [
"everything"
"voyager"
]
};
};
'';
description = "Déclaration des machines.";
};
};
config.services = mkIf cfg.enable {
anubis.instances = mapAttrs (
vhostName: vhostConfig: {
enable = true;
settings = {
BIND_NETWORK = "unix";
TARGET = "unix:/run/nginx/nginx-${vhostName}.sock";
COOKIE_DOMAIN = "crans.org";
REDIRECT_DOMAINS = "${vhostName}.crans.org";
POLICY_FNAME =
if (vhostConfig.anubisConfig == "")
then allowAll
else vhostConfig.anubisConfig;
};
}
) cfg.virtualHosts;
nginx =
let
domaines = [
"crans.org"
"crans.fr"
"crans.eu"
];
redirectConfig = mapAttrs (
vhostName: vhostConfig: {
locations = mkIf ((substring 0 1 vhostConfig.target) != "/") {
"/".proxyPass = "http://${vhostConfig.target}";
};
root = mkIf ((substring 0 1 vhostConfig.target) == "/") vhostConfig.target;
listen = [
{ addr = "unix:/run/nginx/nginx-${vhostName}.sock"; }
];
}
) cfg.virtualHosts;
aliasConfig = mapAttrs' (
vhostName: vhostConfig: nameValuePair (vhostName + "-alias") {
enableACME = true;
forceSSL = true;
serverName = "${vhostName}.crans.fr";
serverAliases = let
aliases = cartesianProduct {
name = vhostConfig.serverAliases;
domaine = domaines;
};
in [
"${vhostName}.crans.eu"
] ++ map (value: value.name + "." + value.domaine) aliases;
extraConfig = ''
return 301 https://${vhostName}.crans.org$request_uri;
'';
}
) cfg.virtualHosts;
anubisConfig = mapAttrs' (
vhostName: vhostConfig: nameValuePair (vhostName + "-anubis") {
enableACME = true;
forceSSL = true;
locations."/".proxyPass = "unix:/run/anubis/anubis-${vhostName}.sock";
serverName = "${vhostName}.crans.org";
}
) cfg.virtualHosts;
in {
enable = true;
virtualHosts = redirectConfig // aliasConfig // anubisConfig;
};
};
}