diff --git a/docs/README.md b/docs/README.md index 96e420169..180db99e5 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,5 +1,5 @@ # Serve documentation locally ``` -$ nix develop .#docs -c mkdocs serve +nix develop .#docs -c mkdocs serve ``` diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index 51e748387..63e1f68d4 100644 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -66,6 +66,7 @@ nav: - Services: - Introduction to Services: guides/services/introduction-to-services.md - Author Your Own Service: guides/services/community.md + - Internal Services with SSL: guides/internal-ssl-services.md - Vars: - Introduction to Vars: guides/vars/vars-overview.md - Minimal Example: guides/vars/vars-backend.md diff --git a/docs/site/guides/internal-ssl-services.md b/docs/site/guides/internal-ssl-services.md new file mode 100644 index 000000000..eed897b04 --- /dev/null +++ b/docs/site/guides/internal-ssl-services.md @@ -0,0 +1,213 @@ +A common use case you might have is to host services and applications which are +only reachable within your clan. + +This guide explains how to set up such secure, clan-internal web services using +a custom top-level domain (TLD) with SSL certificates. + +Your services will be accessible only within your clan network and secured with +proper SSL certificates that all clan machines trust. + +## Overview + +By combining the `coredns` and `certificates` clan services, you can: + +- Create a custom TLD for your clan (e.g. `.c`) +- Host internal web services accessible via HTTPS (e.g. `https://api.c`, `https://dashboard.c`) +- Automatically provision and trust SSL certificates across all clan machines +- Keep internal services secure and isolated from the public internet + +The setup uses two clan services working together: + +- **coredns service**: Provides DNS resolution for your custom TLD within the clan +- **certificates service**: Creates a certificate authority (CA) and issues SSL certificates for your TLD + +### DNS Resolution Flow + +1. A clan machine tries to access `https://service.c` +2. The machine queries its local DNS resolver (unbound) +3. For `.c` domains, the query is forwarded to your clan's CoreDNS server. All + other domains will be resolved as usual. +4. CoreDNS returns the IP address of the machine hosting the service +5. The machine connects directly to the service over HTTPS +6. The SSL certificate is trusted because all machines trust your clan's CA + +## Step-by-Step Setup + +The following setup assumes you have a VPN (e.g. Zerotier) already running. The +IPs configured in the options below will probably the Zerotier-IPs of the +respective machines. + +### Configure the CoreDNS Service + +The CoreDNS service has two roles: +- `server`: Runs the DNS server for your custom TLD +- `default`: Makes machines use the DNS server for TLD resolution and allows exposing services + +Add this to your inventory: + +```nix +inventory = { + machines = { + dns-server = { }; # Machine that will run the DNS server + web-server = { }; # Machine that will host web services + client = { }; # Any other machines in your clan + }; + + instances = { + coredns = { + + # Add the default role to all machines + roles.default.tags = [ "all" ]; + + # DNS server for the .c TLD + roles.server.machines.dns-server.settings = { + ip = "192.168.1.10"; # IP of your DNS server machine + tld = "c"; + }; + + # Machine hosting services (example: ca.c and admin.c) + roles.default.machines.web-server.settings = { + ip = "192.168.1.20"; # IP of your web server + services = [ "ca" "admin" ]; + }; + }; + }; +}; +``` + +### Configure the Certificates Service + +The certificates service also has two roles: +- `ca`: Sets up the certificate authority on a server +- `default`: Makes machines trust the CA and allows them to request certificates + +Add this to your inventory: + +```nix +inventory = { + instances = { + # ... coredns configuration from above ... + + certificates = { + + # Set up CA for .c domain + roles.ca.machines.dns-server.settings = { + tlds = [ "c" ]; + acmeEmail = "admin@example.com"; # Optional: your email + }; + + # Add default role to all machines to trust the CA + roles.default.tags = [ "all" ]; + }; + }; +}; +``` + +### Complete Example Configuration + +Here's a complete working example: + +```nix +nventory = { + machines = { + caserver = { }; # DNS server + CA + web services + webserver = { }; # Additional web services + client = { }; # Client machine + }; + + instances = { + coredns = { + + # Add the default role to all machines + roles.default.tags = [ "all" ]; + + # DNS server for the .c TLD + roles.server.machines.caserver.settings = { + ip = "192.168.8.5"; + tld = "c"; + }; + + # machine hosting https://ca.c (our CA for SSL) + roles.default.machines.caserver.settings = { + ip = "192.168.8.5"; + services = [ "ca" ]; + }; + + # machine hosting https://blub.c (some internal web-service) + roles.default.machines.webserver.settings = { + ip = "192.168.8.6"; + services = [ "blub" ]; + }; + }; + + # Provide https for the .c top-level domain + certificates = { + + roles.ca.machines.caserver.settings = { + tlds = [ "c" ]; + acmeEmail = "admin@example.com"; + }; + + roles.default.tags = [ "all" ]; + }; + }; +}; +``` + +## Testing Your Configuration + +DNS resolution can be tested with: + +```bash +# On any clan machine, test DNS resolution +nslookup ca.c +nslookup blub.c +``` + +You should also now be able to visit `https://ca.c` to access the certificate authority or visit `https://blub.c` to access your web service. + +## Troubleshooting + +### DNS Resolution Issues + +1. **Check if DNS server is running**: +```bash +# On the DNS server machine +systemctl status coredns +``` + +2. **Verify DNS configuration**: +```bash +# Check if the right nameservers are configured +cat /etc/resolv.conf +systemctl status systemd-resolved +``` + +3. **Test DNS directly**: +```bash +# Query the DNS server directly +dig @192.168.8.5 ca.c +``` + +### Certificate Issues + +1. **Check CA status**: +```bash +# On the CA machine +systemctl status step-ca +systemctl status nginx +``` + +2. **Verify certificate trust**: +```bash +# Test certificate trust +curl -v https://ca.c +openssl s_client -connect ca.c:443 -verify_return_error +``` + +3. **Check ACME configuration**: +```bash +# View ACME certificates +ls /var/lib/acme/ +journalctl -u acme-ca.c.service +```