Skip to main content

Using Experimental Lighthouse DNS with Nebula

warning

Lighthouse DNS in nebula is experimental and should not be considered to be a robust solution. For details, see the limitations listed below.

Nebula comes with built-in DNS server support via Lighthouse hosts.

Lighthouse DNS can generate DNS records based on dynamic nebula hosts, useful if you are spinning up new nebula hosts on demand.

Prerequisites

This guide assumes you already have a working Lighthouse and at least one other host communicating with it. If you haven't setup a Nebula network yet, check out the Quick Start guide.

You'll then want to set up the lighthouse as a DNS server for the other two hosts. This can be either the public static lighthouse IP or the private nebula IP depending on the Lighthouse's configuration.

Configuration

First, spin up a lighthouse and 2 hosts. Then add

lighthouse:
serve_dns: true
dns:
host: '[::]'
port: 53

to your lighthouses's Nebula config. By setting lighthouse.dns.host to [::], nebula will bind to all interfaces including both the public and nebula IP. Binding to only the nebula IP, for example lighthouse.dns.host: 10.0.0.1 will ensure the DNS is only accessible to hosts that are allowed to contact the lighthouse via nebula.

note

Only Lighthouses should have lighthouse.serve_dns enabled, as DNS info is collected when hosts report to the lighthouse. Nebula will not honor the option if enabled on a non-lighthouse host.

Next, add a firewall rule in your lighthouse config that enables UDP on port 53 (or the port specified in lighthouse.dns.port) for all hosts you want to be able to query DNS on the lighthouse. For example to allow any host on the nebula network:

firewall:
inbound:
- port: 53
proto: udp
group: any

Testing

Then you can run dig against it to test! For example, I made a host named lighthouse as my lighthouse with nebula IP 100.100.0.1 and alice-laptop with nebula IP 100.100.0.2 as my host, and I set up my lighthouse with the above config / firewall rule.

dig @100.100.0.1 +short alice-laptop A
100.100.0.2

I can also query the TXT record for the nebula IP for certificate info. Each piece of info is delivered within quotes and as a "Key: Value" format.

dig @100.100.0.1 +short "100.100.0.2" TXT
"Name: alice-laptop" "Ips: [100.100.0.2/22]" "Subnets []" "Groups [role:Laptop]" "NotBefore 2022-12-06 21:34:25 +0000 UTC" "NotAFter 2024-05-13 17:37:27 +0000 UTC" "PublicKey 2c4828672fef1306124df94eb0fecd753e462e1bd4107f866f4e1a463550eb1b" "IsCA false" "Issuer 5b568aedaa5d97746e870f01a356ba474cf3251c0e743499ec668f93efa77f51"

If I then host a server on [::]:3000 (ex, by creating an index.html file and then running python3 -m http.server 3000 on a *nix host) on alice-laptop and set up a firewall rule that allows this to be accessed from bob-laptop, I can request it with curl using the custom DNS resolver. (In a production environment, you may choose to configure the system resolver.)

curl --dns-servers "100.100.0.1" http://alice-laptop:3000
<div>hello i am a website</div>

Limitations

  • The built-in DNS server will only respond to queries for known Nebula hosts and will not make upstream queries to a secondary DNS server (e.g. for supporting both internal DNS and public DNS.)
  • A host's hostname is restricted to the name in its certificate.
  • There is no way to register additional hostnames (e.g. additional CNAMEs for a given Nebula host, or additional A records for managing non-Nebula hosts.)
  • Duplicate names in certificates will result in non-stable answers from the DNS server.
  • If the name in the Nebula certificate is not a valid hostname, Lighthouse DNS will return an empty result.

Hostname Validity

Please input a hostname to validate

Alternatives

An alternative approach to DNS would be to point public DNS records at private nebula IP addresses. For example, you can create a public DNS A record pointing to 10.0.0.23 for your private team wiki. While this does make your internal IP address visible to the internet, only users on your nebula network will be able to access it.

Q&A

  • How do hostnames turn into DNS host names?
    • If the hostname is a valid DNS name, it will be resolved by the Lighthouse DNS resolver.
  • Do Lighthouse DNS queries support Unicode?
    • DNS only supports ASCII, but has support for Unicode via punycode, for example:
      # `alice-xn--3s8h` = `alice-💻` in punycode.
      dig @100.100.0.1 +short alice-xn--3s8h A
      100.100.0.2
      Nebula supports full unicode strings in the host name, but for hosts to be discovered via Lighthouse DNS, they must conform to the DNS spec. https://www.punycoder.com/ is a useful tool for conversion.
  • Are the domain names resolved with case sensitivity?
    • No, Nebula is compliant with RFC 1035 since version 1.7.0.
  • How do duplicate hostnames get resolved?
    • In nebula, a node's IP address is the only identifier that MUST be globally unique. Therefore, it's possible to have two hosts with the same certificate name, but different IP addresses. Unfortunately, this can cause inconsistent results when querying for these hosts' hostname as the DNS query is ambiguous. The lighthouse will return the nebula IP of whichever host it has most recently performed a handshake with.
  • How does the lighthouse learn about hosts?
    • Hosts connect to the lighthouse as they normally do, and in doing so the lighthouse learns about their cert. Due to this fact, the lighthouse can only answer questions about hosts it has seen since last start.
  • Can the lighthouse resolve its own name?
    • As of nebula v1.6.1, no, the lighthouse only responds about hosts it has handshaked with, it never handshakes with itself. slackhq/nebula/issues/271 is tracking this feature.