Set up clan-internal web services with HTTPS on a custom top-level domain (e.g. https://dashboard.c), accessible only within your Clan network and secured with SSL certificates that all machines trust automatically.
By combining the coredns and certificates Clan services, you can:
.c)https://api.c, https://dashboard.c)The setup uses two Clan services working together:
https://service.c.c domains, the query is forwarded to your Clan's CoreDNS server. All
other domains will be resolved as usual.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.
The CoreDNS service has two roles:
server: Runs the DNS server for your custom TLDdefault: Makes machines use the DNS server for TLD resolution and allows exposing servicesAdd this to your inventory:
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.XXX.XXX";
tld = "c";
};
# Machine hosting services (e.g. ca.c and admin.c)
roles.default.machines.web-server.settings = {
ip = "192.168.XXX.XXX";
services = [ "ca" "admin" ];
};
};
};
}; The certificates service also has two roles:
ca: Sets up the certificate authority on a serverdefault: Makes machines trust the CA and allows them to request certificatesAdd this to your inventory:
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";
};
# Add default role to all machines to trust the CA
roles.default.tags = [ "all" ];
};
};
}; Here's a complete working example:
inventory = {
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.XXX.XXX";
tld = "c";
};
# Machine hosting https://ca.c (CA for SSL)
roles.default.machines.caserver.settings = {
ip = "192.168.XXX.XXX";
services = [ "ca" ];
};
# Machine hosting https://blub.c (internal web service)
roles.default.machines.webserver.settings = {
ip = "192.168.XXX.XXX";
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" ];
};
};
}; DNS resolution can be tested with:
# 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.
# On the DNS server machine
systemctl status coredns # Check if the right nameservers are configured
cat /etc/resolv.conf
systemctl status systemd-resolved # Query the DNS server directly
dig @192.168.XXX.XXX ca.c # On the CA machine
systemctl status step-ca
systemctl status nginx # Test certificate trust
curl -v https://ca.c
openssl s_client -connect ca.c:443 -verify_return_error # View ACME certificates
ls /var/lib/acme/
journalctl -u acme-ca.c.service