start using Eon's ACME interface for provisioning certificates

+7 -7
flake.lock
···
]
},
"locked": {
-
"lastModified": 1717252989,
-
"narHash": "sha256-qMvd1PloCsNLI9Rk584UQXoJKDxdE+TDlIVc0Is33cQ=",
+
"lastModified": 1718115151,
+
"narHash": "sha256-ZRAqW9RixSTJjzGFQb7vvf95p1ns6WPmpxJQg/r4AYY=",
"owner": "RyanGibb",
"repo": "eilean-nix",
-
"rev": "f1cab2428cf6272b763cc2322b47631214454b78",
+
"rev": "b354949aac308b77d742c5a6321eac53508ab700",
"type": "github"
},
"original": {
"owner": "RyanGibb",
-
"ref": "main",
+
"ref": "eon-acme",
"repo": "eilean-nix",
"type": "github"
}
···
"opam-repository": "opam-repository"
},
"locked": {
-
"lastModified": 1717328982,
-
"narHash": "sha256-+zR2cuBSyunBxqkW15KACPyicaotG4w/o78gvtBT1s8=",
+
"lastModified": 1718122335,
+
"narHash": "sha256-ooeplCUj5dY2KT840ecFtR+iDq1V2iB5rDsFqjbdFSs=",
"owner": "RyanGibb",
"repo": "eon",
-
"rev": "14906ebc2de360df26b45eb4224093ac00502761",
+
"rev": "87b7ec1cd6cb7dc0f950d8d37a91845465780faf",
"type": "github"
},
"original": {
+2 -1
flake.nix
···
deploy-rs.url = "github:serokell/deploy-rs";
nix-on-droid.url = "github:nix-community/nix-on-droid/release-23.11";
eon.url = "github:RyanGibb/eon";
-
eilean.url = "github:RyanGibb/eilean-nix/main";
+
eilean.url = "github:RyanGibb/eilean-nix/eon-acme";
ryan-website.url = "git+ssh://git@github.com/RyanGibb/website.git";
alec-website.url = "github:alexanderhthompson/website";
fn06-website.url = "github:RyanGibb/fn06";
···
# uncomment for cross compilation (https://github.com/NixOS/nix/issues/3843)
#buildPlatform.system = "cpu-os";
};
+
security.acme-eon.acceptTerms = true;
})
home-manager.nixosModule
eilean.nixosModules.default
+3 -9
hosts/duck/default.nix
···
{ pkgs, config, lib, eilean, eon, ... }:
{
-
imports = [
-
./hardware-configuration.nix
-
eon.nixosModules.default
-
eon.nixosModules.acme
-
];
+
imports = [ ./hardware-configuration.nix ];
custom = {
enable = true;
···
services = {
eon = {
enable = lib.mkForce true;
-
package = eon.defaultPackage.${config.nixpkgs.hostPlatform.system};
# TODO make this zonefile derivation a config parameter `services.eilean.services.dns.zonefile`
# TODO add module in eilean for eon
zoneFiles = [
···
}/cl.freumh.org"
];
logLevel = 1;
-
application = "cap";
+
application = "capd";
capnpAddress = "cl.freumh.org";
#prod = false;
};
···
security.acme-eon = {
acceptTerms = true;
-
package = eon.defaultPackage.${config.nixpkgs.hostPlatform.system};
defaults.email = "${config.custom.username}@${config.networking.domain}";
nginxCerts = [ config.networking.domain ];
-
defaults.capFile = "/var/lib/acme-eon/root.cap";
+
defaults.capFile = "/var/lib/eon/caps/domain/cl.freumh.org.cap";
};
services.nginx = {
+20 -4
hosts/elephant/services.nix
···
custom = {
nix-cache = {
enable = true;
-
domain = "nix-cache";
+
domain = "nix-cache.vpn.freumh.org";
};
};
+
age.secrets."eon-vpn.freumh.org.cap" = {
+
file = ../../secrets/eon-vpn.freumh.org.cap.age;
+
mode = "770";
+
owner = "eon";
+
group = "eon";
+
};
+
security.acme-eon = {
+
defaults.capFile = config.age.secrets."eon-vpn.freumh.org.cap".path;
+
nginxCerts = [
+
"nix-cache.vpn.freumh.org"
+
"jellyfin.vpn.freumh.org"
+
"transmission.vpn.freumh.org"
+
];
+
};
+
services.nginx = {
+
#requires = [ "tailscaled.service" ];
virtualHosts = {
-
"nix-cache" = { listenAddresses = [ "100.64.0.9" ]; };
-
"jellyfin" = {
+
"nix-cache.vpn.freumh.org" = { listenAddresses = [ "100.64.0.9" ]; };
+
"jellyfin.vpn.freumh.org" = {
listenAddresses = [ "100.64.0.9" ];
locations."/" = {
proxyPass = ''
···
proxyWebsockets = true;
};
};
-
"transmission" = {
+
"transmission.vpn.freumh.org" = {
listenAddresses = [ "100.64.0.9" ];
locations."/" = {
proxyPass = ''
+17 -5
hosts/owl/default.nix
···
-
{ pkgs, config, lib, eilean, patrick-nixos, ... }@inputs:
+
{ pkgs, config, lib, eon, patrick-nixos, ... }@inputs:
{
imports = [
···
../../modules/fn06-website.nix
];
-
security.acme = {
-
defaults.email = "${config.custom.username}@${config.networking.domain}";
+
age.secrets.eon-capnp = {
+
file = ../../secrets/eon-capnp.age;
+
mode = "770";
+
owner = "eon";
+
group = "eon";
+
};
+
services.eon.capnpSecretKeyFile = config.age.secrets.eon-capnp.path;
+
services.eon.prod = false;
+
+
security.acme-eon = {
acceptTerms = true;
+
package = eon.defaultPackage.${config.nixpkgs.hostPlatform.system};
+
defaults.email = "${config.custom.username}@${config.networking.domain}";
+
defaults.capFile = "/var/lib/eon/caps/domain/freumh.org.cap";
};
eilean = {
username = config.custom.username;
serverIpv4 = "135.181.100.27";
serverIpv6 = "2a01:4f9:c011:87ad:0:0:0:0";
+
acme-eon = true;
};
networking.domain = lib.mkDefault "freumh.org";
eilean.publicInterface = "enp1s0";
···
basicAuthFile = config.age.secrets.website-phd.path;
};
};
+
+
security.acme-eon.nginxCerts = [ "capybara.fn06.org" "shrew.freumh.org" ];
services.nginx.virtualHosts."capybara.fn06.org" = {
forceSSL = true;
-
enableACME = true;
locations."/" = {
proxyPass = ''
http://100.64.0.10:8123
···
};
services.nginx.virtualHosts."shrew.freumh.org" = {
forceSSL = true;
-
enableACME = true;
locations."/" = {
# need to specify ip or there's a bootstrap problem with headscale
proxyPass = ''
+15 -11
modules/alec-website.nix
···
};
config = mkIf cfg.enable {
+
security.acme-eon.nginxCerts = [ cfg.domain ];
+
security.acme-eon.certs.${cfg.domain}.extraDomainNames =
+
[ "www.${cfg.domain}" ];
+
services.nginx = {
enable = true;
virtualHosts = {
"${cfg.domain}" = {
forceSSL = true;
-
enableACME = true;
root =
"${alec-website.packages.${pkgs.stdenv.hostPlatform.system}.default}";
locations."/var/".extraConfig = ''
···
access_log /var/log/nginx/${cfg.domain}.log;
'';
};
-
"www.${cfg.domain}" = {
-
forceSSL = true;
-
useACMEHost = cfg.domain;
-
extraConfig = ''
-
return 301 https://${cfg.domain}$request_uri;
-
'';
-
};
+
"www.${cfg.domain}" =
+
let certDir = config.security.acme-eon.certs.${cfg.domain}.directory;
+
in {
+
forceSSL = true;
+
sslCertificate = "${certDir}/fullchain.pem";
+
sslCertificateKey = "${certDir}/key.pem";
+
sslTrustedCertificate = "${certDir}/chain.pem";
+
extraConfig = ''
+
return 301 https://${cfg.domain}$request_uri;
+
'';
+
};
};
};
-
-
security.acme.certs."${cfg.domain}".extraDomainNames =
-
[ "www.${cfg.domain}" ];
eilean.services.dns.zones.${cfg.zone}.records = [
{
+1 -1
modules/colour-guesser.nix
···
};
config = lib.mkIf cfg.enable {
+
security.acme-eon.nginxCerts = [ cfg.domain ];
services.nginx = {
enable = true;
recommendedProxySettings = true;
virtualHosts."${cfg.domain}" = {
forceSSL = true;
-
enableACME = true;
root =
"${colour-guesser.packages.${pkgs.stdenv.hostPlatform.system}.default}";
};
+15 -11
modules/fn06-website.nix
···
};
config = mkIf cfg.enable {
+
security.acme-eon.nginxCerts = [ cfg.domain ];
+
security.acme-eon.certs.${cfg.domain}.extraDomainNames =
+
[ "www.${cfg.domain}" ];
+
services.nginx = {
enable = true;
virtualHosts = {
"${cfg.domain}" = {
forceSSL = true;
-
enableACME = true;
root =
"${fn06-website.packages.${pkgs.stdenv.hostPlatform.system}.default}";
locations."/var/".extraConfig = ''
···
access_log /var/log/nginx/${cfg.domain}.log;
'';
};
-
"www.${cfg.domain}" = {
-
addSSL = true;
-
useACMEHost = cfg.domain;
-
extraConfig = ''
-
return 301 $scheme://${cfg.domain}$request_uri;
-
'';
-
};
+
"www.${cfg.domain}" =
+
let certDir = config.security.acme-eon.certs.${cfg.domain}.directory;
+
in {
+
forceSSL = true;
+
sslCertificate = "${certDir}/fullchain.pem";
+
sslCertificateKey = "${certDir}/key.pem";
+
sslTrustedCertificate = "${certDir}/chain.pem";
+
extraConfig = ''
+
return 301 https://${cfg.domain}$request_uri;
+
'';
+
};
};
};
-
-
security.acme.certs."${cfg.domain}".extraDomainNames =
-
[ "www.${cfg.domain}" ];
};
}
+2 -1
modules/freumh.nix
···
group = "php";
};
users.groups.php = { };
+
+
security.acme-eon.nginxCerts = [ config.networking.domain ];
services.nginx = {
enable = true;
virtualHosts."${config.networking.domain}" = {
-
enableACME = true;
forceSSL = true;
locations."/root" = let
random-root = pkgs.writeScript "random-root.php" ''
+1
modules/nix-cache.nix
···
services.nginx = {
enable = true;
virtualHosts.${cfg.nix-cache.domain} = {
+
forceSSL = true;
locations."/".extraConfig = ''
proxy_pass http://localhost:${
toString config.services.nix-serve.port
+1 -2
modules/rmfakecloud.nix
···
mailserver.loginAccounts."misc@${domain}".aliases =
[ "remarkable@${domain}" ];
-
# nginx handles letsencrypt
+
security.acme-eon.nginxCerts = [ cfg.domain ];
services.nginx = {
enable = true;
recommendedProxySettings = true;
···
clientMaxBodySize = "100M";
virtualHosts."${cfg.domain}" = {
forceSSL = true;
-
enableACME = true;
locations."/".proxyPass = ''
http://localhost:${builtins.toString cfg.port}
'';
+15 -11
modules/ryan-website.nix
···
};
config = mkIf cfg.enable {
+
security.acme-eon.nginxCerts = [ cfg.domain ];
+
security.acme-eon.certs.${cfg.domain}.extraDomainNames =
+
[ "www.${cfg.domain}" ];
+
services.nginx = {
enable = true;
virtualHosts = {
"${cfg.domain}" = {
forceSSL = true;
-
enableACME = true;
root =
"${ryan-website.packages.${pkgs.stdenv.hostPlatform.system}.default}";
locations."/teapot".extraConfig = ''
···
access_log /var/log/nginx/${cfg.domain}.log;
'';
};
-
"www.${cfg.domain}" = {
-
forceSSL = true;
-
useACMEHost = cfg.domain;
-
extraConfig = ''
-
return 301 https://${cfg.domain}$request_uri;
-
'';
-
};
+
"www.${cfg.domain}" =
+
let certDir = config.security.acme-eon.certs.${cfg.domain}.directory;
+
in {
+
forceSSL = true;
+
sslCertificate = "${certDir}/fullchain.pem";
+
sslCertificateKey = "${certDir}/key.pem";
+
sslTrustedCertificate = "${certDir}/chain.pem";
+
extraConfig = ''
+
return 301 https://${cfg.domain}$request_uri;
+
'';
+
};
};
};
-
-
security.acme.certs."${cfg.domain}".extraDomainNames =
-
[ "www.${cfg.domain}" ];
eilean.services.dns.zones.${cfg.zone}.records = [
{
+4 -3
modules/use-nix-cache.nix
···
settings = {
substituters = [
"https://cache.nixos.org?priority=100"
-
"http://nix-cache?priority=10"
+
"https://nix-cache.vpn.freumh.org?priority=10"
+
];
+
trusted-public-keys = [
+
"nix-cache.vpn.freumh.org:Go6ACovVBhR4P6Ug3DsE0p0DIRQtkIBHui1DGM7qK5c="
];
-
trusted-public-keys =
-
[ "nix-cache:Go6ACovVBhR4P6Ug3DsE0p0DIRQtkIBHui1DGM7qK5c=" ];
};
};
};
secrets/eon-capnp.age

This is a binary file and will not be displayed.

+8
secrets/eon-vpn.freumh.org.cap.age
···
+
age-encryption.org/v1
+
-> ssh-ed25519 2wDnOw hfRIc1k6R2zsMOwhlrXETwhD4SvhvygZwziRqqX+eFc
+
VOudzuyYYNMJeBOTtky7rtwUmQ07j/ZGgifykSLLkf8
+
-> ssh-ed25519 hFxbYA YW2zopuilo/OyygdjXB9D+Xe8fi5Gt8J6pl8gCuxLVM
+
SX7B7a3qYe5x8djofgZtvLfTBF2WqWUH2ZXGyACv3Kk
+
--- fIJfMEx1XyrzmDkWEpcf0/kqlq8ZXFBJEhWISniWgpE
+
��^4����X-���!bǦ��2�M�fl��Q�ƺ크[ Ar���
+
7���t/�q1?�{i�cd:�TAo3W�zdHuDq��r��P���d�StM��9Se#BC^1w��Z�}��#�1njD �u�(�$�)������<8PۚF{x��q��:v �7
+2
secrets/secrets.nix
···
"restic-repo.age".publicKeys = user ++ [ elephant ];
"nextcloud.age".publicKeys = user ++ [ elephant ];
"headscale.age".publicKeys = user ++ [ owl ];
+
"eon-capnp.age".publicKeys = user ++ [ owl ];
+
"eon-vpn.freumh.org.cap.age".publicKeys = user ++ [ elephant ];
}