summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMel <mel@rnrd.eu>2025-04-16 12:49:53 +0200
committerMel <mel@rnrd.eu>2025-04-16 12:49:53 +0200
commit5e1a9f0179c0beb73b63140a3ee20c4acb04fcc4 (patch)
treee2d3c83e761dc2bec056d81c268bc500ad148a6c
parent6c9f992808b6cf8b079f4c8cfa5625de1e624618 (diff)
downloadnetwork-5e1a9f0179c0beb73b63140a3ee20c4acb04fcc4.tar.zst
network-5e1a9f0179c0beb73b63140a3ee20c4acb04fcc4.zip
Move WWW configuration into foundation module, and make it configurable
Signed-off-by: Mel <mel@rnrd.eu>
-rw-r--r--machines/fourmi/default.nix12
-rw-r--r--modules/foundation/default.nix1
-rw-r--r--modules/foundation/www/default.nix130
-rw-r--r--modules/foundation/www/tailnet.nix (renamed from modules/www/tailnet.nix)75
-rw-r--r--modules/www/default.nix105
5 files changed, 183 insertions, 140 deletions
diff --git a/machines/fourmi/default.nix b/machines/fourmi/default.nix
index 780838d..1d53631 100644
--- a/machines/fourmi/default.nix
+++ b/machines/fourmi/default.nix
@@ -8,8 +8,16 @@
./devices.nix
];
- foundation.monitoring = {
- client.enable = false;
+ foundation = {
+ www = {
+ enable = true;
+ public = false;
+ tailnet = true;
+ };
+
+ monitoring = {
+ client.enable = false;
+ };
};
# extra packages for dealing with the device
diff --git a/modules/foundation/default.nix b/modules/foundation/default.nix
index 62c6f85..fcf1225 100644
--- a/modules/foundation/default.nix
+++ b/modules/foundation/default.nix
@@ -4,5 +4,6 @@
imports = [
./services.nix
./monitoring
+ ./www
];
}
diff --git a/modules/foundation/www/default.nix b/modules/foundation/www/default.nix
new file mode 100644
index 0000000..2e2b662
--- /dev/null
+++ b/modules/foundation/www/default.nix
@@ -0,0 +1,130 @@
+{
+ me,
+ config,
+ pkgs,
+ lib,
+ util,
+ ...
+}:
+
+let
+ inherit (lib)
+ mergeAttrsList
+ mkIf
+ mkEnableOption
+ mkOption
+ ;
+ inherit (config.age) secrets;
+
+ cfg = config.foundation.www;
+
+ rnrdUrl = if me.is.renard then "rnrd.eu" else "${me.name}.rnrd.eu";
+
+ default-page-index = pkgs.substituteAll {
+ src = ../../../assets/base.html;
+ env.me = util.titleCase me.name;
+ };
+
+ default-page = pkgs.linkFarm "www-base" {
+ "index.html" = default-page-index;
+ "favicon.png" = ../../../assets/favicon.png;
+ };
+
+ certificate = domain: {
+ ${domain} = {
+ domain = "*.${domain}";
+ extraDomainNames = [ domain ];
+
+ dnsProvider = "cloudflare";
+ credentialFiles = {
+ CLOUDFLARE_DNS_API_TOKEN_FILE = secrets.cloudflare-dns.path;
+ };
+ };
+ };
+
+ defaultHost = domain: certificate: base: log: {
+ default = true;
+ serverName = domain;
+ forceSSL = true;
+ useACMEHost = certificate;
+
+ root = base;
+ extraConfig = ''
+ access_log /var/log/nginx/${log}.access.log json_combined;
+ '';
+ };
+
+in
+{
+ imports = [ ./tailnet.nix ];
+
+ options.foundation.www = {
+ enable = mkEnableOption "www server";
+ public = mkEnableOption "public access through rnrd.eu url";
+
+ defaultPage = mkOption {
+ type = lib.types.package;
+ default = default-page;
+ };
+ };
+
+ config = mkIf cfg.enable {
+ age.secrets = {
+ cloudflare-dns.file = ../../../secrets/cloudflare-dns.age;
+ };
+
+ security.acme = {
+ acceptTerms = true;
+ # causes issues with tailscale certificates
+ preliminarySelfsigned = false;
+ defaults = {
+ email = "mel@rnrd.eu";
+ # our certificates are really only used with Nginx
+ group = config.services.nginx.group;
+ reloadServices = [ "nginx.service" ];
+ };
+
+ # yes, we generate both certificates, even if they are not
+ # used by every machine, but as long as it doesn't cause
+ # any problems... :)
+ certs = mergeAttrsList [
+ (certificate "rnrd.eu")
+ (certificate "rnrd.fyi")
+ ];
+ };
+
+ services.nginx = {
+ enable = true;
+ recommendedGzipSettings = true;
+ recommendedOptimisation = true;
+ recommendedProxySettings = true;
+ recommendedTlsSettings = true;
+
+ statusPage = true;
+
+ commonHttpConfig = ''
+ log_format json_combined escape=json '{'
+ '"time_local":"$time_local",'
+ '"remote_addr":"$remote_addr",'
+ '"remote_user":"$remote_user",'
+ '"request":"$request",'
+ '"status": "$status",'
+ '"body_bytes_sent":"$body_bytes_sent",'
+ '"request_length":"$request_length",'
+ '"request_time":"$request_time",'
+ '"http_referrer":"$http_referer",'
+ '"http_user_agent":"$http_user_agent",'
+ '"upstream_response_time":"$upstream_response_time",'
+ '"upstream_addr":"$upstream_addr",'
+ '"upstream_status":"$upstream_status"'
+ '}';
+ access_log /var/log/nginx/access.log json_combined;
+ error_log /var/log/nginx/error.log warn;
+ '';
+
+ virtualHosts = {
+ base = mkIf cfg.public (defaultHost rnrdUrl "rnrd.eu" cfg.defaultPage "base");
+ };
+ };
+ };
+}
diff --git a/modules/www/tailnet.nix b/modules/foundation/www/tailnet.nix
index 56cfbf4..ff2410c 100644
--- a/modules/www/tailnet.nix
+++ b/modules/foundation/www/tailnet.nix
@@ -11,6 +11,8 @@
}:
let
+ cfg = config.foundation.www;
+
rnrdInternalUrl = if me.is.renard then "rnrd.fyi" else "${me.name}.rnrd.fyi";
oneWeekInSeconds = 7 * 24 * 60 * 60;
@@ -70,43 +72,50 @@ let
in
{
- # overwrite default acme behaviour with tailscale
- systemd.services."acme-${me.tailscale.domain}" = {
- after = [ "tailscaled.service" ];
- requires = [ "tailscaled.service" ];
- serviceConfig = {
- ExecStart = lib.mkForce "+${tailscaleRenewScript}";
- };
+ options.foundation.www = {
+ tailnet = lib.mkEnableOption "tailnet internal host";
};
- # tailnet internal vhost
- services.nginx.virtualHosts = {
- # mostly superceded
- tailnet = {
- forceSSL = true;
- enableACME = true;
- serverName = me.tailscale.domain;
- listenAddresses = [ me.tailscale.ip ];
- # point to the default page, for now!
- locations."/" = {
- alias = "${config.services.nginx.virtualHosts.base.root}/";
+ config =
+ lib.mkIf (cfg.enable && cfg.tailnet) {
+ # overwrite default acme behaviour with tailscale
+ systemd.services."acme-${me.tailscale.domain}" = {
+ after = [ "tailscaled.service" ];
+ requires = [ "tailscaled.service" ];
+ serviceConfig = {
+ ExecStart = lib.mkForce "+${tailscaleRenewScript}";
+ };
};
- extraConfig = ''
- access_log /var/log/nginx/tailnet.access.log json_combined;
- '';
- };
- # default page for the `rnrd.fyi` internal domain
- ${rnrdInternalUrl} = {
- useACMEHost = "rnrd.fyi";
- forceSSL = true;
- listenAddresses = [ me.tailscale.ip ];
- locations."/" = {
- alias = "${config.services.nginx.virtualHosts.base.root}/";
+ # tailnet internal vhost
+ services.nginx.virtualHosts = {
+ # mostly superceded
+ tailnet = {
+ forceSSL = true;
+ enableACME = true;
+ serverName = me.tailscale.domain;
+ listenAddresses = [ me.tailscale.ip ];
+ # point to the default page, for now!
+ locations."/" = {
+ alias = "${cfg.defaultPage}/";
+ };
+ extraConfig = ''
+ access_log /var/log/nginx/tailnet.access.log json_combined;
+ '';
+ };
+
+ # default page for the `rnrd.fyi` internal domain
+ ${rnrdInternalUrl} = {
+ useACMEHost = "rnrd.fyi";
+ forceSSL = true;
+ listenAddresses = [ me.tailscale.ip ];
+ locations."/" = {
+ alias = "${cfg.defaultPage}/";
+ };
+ extraConfig = ''
+ access_log /var/log/nginx/tailnet.access.log json_combined;
+ '';
+ };
};
- extraConfig = ''
- access_log /var/log/nginx/tailnet.access.log json_combined;
- '';
};
- };
}
diff --git a/modules/www/default.nix b/modules/www/default.nix
deleted file mode 100644
index ecc9b66..0000000
--- a/modules/www/default.nix
+++ /dev/null
@@ -1,105 +0,0 @@
-{
- me,
- config,
- pkgs,
- lib,
- util,
- ...
-}:
-
-let
- inherit (lib) mergeAttrsList;
- inherit (config.age) secrets;
-
- rnrdUrl = if me.is.renard then "rnrd.eu" else "${me.name}.rnrd.eu";
-
- base-index = pkgs.substituteAll {
- src = ../../assets/base.html;
- env.me = util.titleCase me.name;
- };
-
- base = pkgs.linkFarm "www-base" {
- "index.html" = base-index;
- "favicon.png" = ../../assets/favicon.png;
- };
-
- certificate = domain: {
- ${domain} = {
- domain = "*.${domain}";
- extraDomainNames = [ domain ];
-
- dnsProvider = "cloudflare";
- credentialFiles = {
- CLOUDFLARE_DNS_API_TOKEN_FILE = secrets.cloudflare-dns.path;
- };
- };
- };
-in
-{
- imports = [ ./tailnet.nix ];
-
- age.secrets = {
- cloudflare-dns.file = ../../secrets/cloudflare-dns.age;
- };
-
- security.acme = {
- acceptTerms = true;
- # causes issues with tailscale certificates
- preliminarySelfsigned = false;
- defaults = {
- email = "mel@rnrd.eu";
- # our certificates are really only used with Nginx
- group = config.services.nginx.group;
- reloadServices = [ "nginx.service" ];
- };
-
- certs = mergeAttrsList [
- (certificate "rnrd.eu")
- (certificate "rnrd.fyi")
- ];
- };
-
- services.nginx = {
- enable = true;
- recommendedGzipSettings = true;
- recommendedOptimisation = true;
- recommendedProxySettings = true;
- recommendedTlsSettings = true;
-
- statusPage = true;
-
- commonHttpConfig = ''
- log_format json_combined escape=json '{'
- '"time_local":"$time_local",'
- '"remote_addr":"$remote_addr",'
- '"remote_user":"$remote_user",'
- '"request":"$request",'
- '"status": "$status",'
- '"body_bytes_sent":"$body_bytes_sent",'
- '"request_length":"$request_length",'
- '"request_time":"$request_time",'
- '"http_referrer":"$http_referer",'
- '"http_user_agent":"$http_user_agent",'
- '"upstream_response_time":"$upstream_response_time",'
- '"upstream_addr":"$upstream_addr",'
- '"upstream_status":"$upstream_status"'
- '}';
- access_log /var/log/nginx/access.log json_combined;
- error_log /var/log/nginx/error.log warn;
- '';
-
- virtualHosts = {
- base = {
- default = true;
- serverName = rnrdUrl;
- forceSSL = true;
- useACMEHost = "rnrd.eu";
-
- root = base;
- extraConfig = ''
- access_log /var/log/nginx/base.access.log json_combined;
- '';
- };
- };
- };
-}