# ACME/SSL We have our own letsencrypt-like service (ca.r) for internal certificates on the retiolum network. ## Overview The `ca.r` is a self-hosted ACME CA using step-ca that issues certificates for `.r` and `.w` domains on the retiolum network. This allows services to use proper TLS certificates without relying on public certificate authorities. ## Trust the CA (Using Retiolum Module - Recommended) The easiest way to trust the ca.r certificates is using the retiolum CA module: ```nix # flake.nix { inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; retiolum.url = "github:Mic92/retiolum"; }; outputs = { self, nixpkgs, retiolum }: { nixosConfigurations.myhost = nixpkgs.lib.nixosSystem { modules = [ retiolum.nixosModules.ca { # This makes your system trust the Krebs CA certificates retiolum.ca = { trustIntermediate = true; # Trust intermediate CA for .r and .w domains (default) trustRoot = false; # Optionally trust root CA (default: false) acmeURL = "https://ca.r/acme/acme/directory"; # ACME server URL }; } ]; }; }; } ``` ### Manual Trust (Alternative) ```nix security.pki.certificateFiles = [(pkgs.fetchurl { url = "http://ca.r/ca.crt"; hash = "sha256-un5GmMplOmBgKMDhu7YcUJC0R6JFYhZgSeExOPkLs6A="; })]; ``` ## Getting Certificates from ca.r ### Basic nginx configuration ```nix services.nginx.virtualHosts."myservice.r" = { enableACME = true; forceSSL = true; locations."/" = { proxyPass = "http://localhost:8080"; }; }; security.acme.certs."myservice.r".server = "https://ca.r/acme/acme/directory"; # Don't forget to open firewall ports networking.firewall.allowedTCPPorts = [ 80 443 ]; ``` ### For services needing direct certificate access ```nix security.acme.certs."myservice.r" = { server = "https://ca.r/acme/acme/directory"; group = "myservice"; # Allow service to read certificate postRun = "systemctl restart myservice.service"; # Restart on renewal }; services.myservice = { enable = true; tlsCert = "/var/lib/acme/myservice.r/fullchain.pem"; tlsKey = "/var/lib/acme/myservice.r/key.pem"; }; ``` ## Using config.retiolum.ca.acmeURL If you're using the retiolum module, you can reference the ACME URL directly: ```nix security.acme.certs."myservice.r" = { server = config.retiolum.ca.acmeURL; }; ``` ## Certificate Details Certificates issued by ca.r: - Valid for 90 days - Automatically renewed when less than 30 days remain - Issued by "Krebs Intermediate CA" - Only work for `.r` and `.w` domains (enforced by name constraints) - Use ECDSA P-256 keys by default ## Troubleshooting ### Account Does Not Exist Error If you see: `acme: error: 400 :: urn:ietf:params:acme:error:accountDoesNotExist` 1. Stop the service: `sudo systemctl stop acme-myservice.r.timer acme-myservice.r.service` 2. Clean state: `sudo rm -rf /var/lib/acme/myservice.r /var/lib/acme/.lego/accounts/*/ca.r*` 3. Restart: `sudo systemctl start acme-myservice.r.service` ### Certificate Expired If certificates show old dates after renewal: 1. Stop services: `sudo systemctl stop acme-myservice.r.timer acme-myservice.r.service` 2. Clean all state: `sudo rm -rf /var/lib/acme/myservice.r /var/lib/acme/.lego/myservice.r` 3. Restart: `sudo systemctl start acme-myservice.r.service && sudo systemctl start acme-myservice.r.timer` ### Checking Certificate Status ```bash # List all ACME timers systemctl list-timers "*acme*" --all # Check for failed services systemctl list-units --failed "*acme*" # Verify certificate echo | openssl s_client -connect myservice.r:443 -servername myservice.r 2>/dev/null | openssl x509 -noout -dates -issuer ```