Skip to content

Commit 6234f0c

Browse files
committed
add dns/sshd configuration handling for lighthouse nodes
1 parent 7cc7b94 commit 6234f0c

File tree

5 files changed

+188
-0
lines changed

5 files changed

+188
-0
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ This project uses [Semantic Versioning](https://semver.org/) - MAJOR.MINOR.PATCH
44

55
# Changelog
66

7+
## 1.0.1 (2026-03-14)
8+
9+
- Added configuration handling for the built in lighthouse DNS server
10+
- Added configuration handling for the built in lighthouse SSHD server
11+
712
## 1.0.0 (2026-03-05)
813

914
- Initial release of saltext-nebula

WIP/saltext-nebula-patch.zip

14.8 KB
Binary file not shown.

docs/topics/pillar-configuration.md

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,56 @@ base:
174174
- nebula.databases
175175
```
176176

177+
## Lighthouse DNS
178+
179+
Lighthouses can serve DNS for the Nebula network, allowing hosts to resolve
180+
each other by name. Configure `serve_dns` and the `dns` bind address under
181+
the host entry:
182+
183+
```yaml
184+
nebula:
185+
hosts:
186+
lighthouse01:
187+
ip: "10.10.10.1/24"
188+
is_lighthouse: true
189+
serve_dns: true
190+
dns:
191+
host: "0.0.0.0" # bind to all interfaces; use nebula IP to restrict to overlay only
192+
port: 53 # use a non-privileged port like 5353 if not running as root
193+
```
194+
195+
`serve_dns` is silently ignored for non-lighthouse hosts. Remember to open
196+
the chosen port in the host's inbound firewall rules and in your OS-level
197+
firewall (iptables, nftables, ufw, etc.).
198+
199+
## Nebula SSH Server
200+
201+
Nebula includes a built-in SSH server for management access that operates
202+
independently of the OS SSH daemon. It is disabled by default and only emitted
203+
in the generated config when `enabled: true` is set:
204+
205+
```yaml
206+
nebula:
207+
hosts:
208+
myhost:
209+
ip: "10.10.10.50/24"
210+
sshd:
211+
enabled: true
212+
listen: "127.0.0.1:22" # address:port for the nebula sshd to bind
213+
host_key: "/etc/nebula/ssh_host_ed25519_key" # omit to use this default
214+
authorized_users:
215+
- user: alice
216+
keys:
217+
- 'ssh-ed25519 AAAA...'
218+
# Optional: also accept nebula CA-signed SSH certificates
219+
authorized_nebula_certificate_authorities:
220+
- 'ssh-ed25519 AAAA...'
221+
```
222+
223+
When `host_key` is omitted it defaults to `<config_dir>/ssh_host_ed25519_key`.
224+
The key file must be generated separately (e.g. `ssh-keygen -t ed25519 -f
225+
/etc/nebula/ssh_host_ed25519_key -N ""`).
226+
177227
## Advanced Configuration Options
178228

179229
### Unsafe Routes

src/saltext/nebula/modules/nebula.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,16 @@ def build_config(minion_id=None):
624624
if host_config.get("calculated_remotes"):
625625
lh_config["calculated_remotes"] = host_config["calculated_remotes"]
626626

627+
# serve_dns / dns: lighthouse-only
628+
if is_lighthouse and host_config.get("serve_dns"):
629+
lh_config["serve_dns"] = True
630+
dns_cfg = host_config.get("dns", {})
631+
if dns_cfg:
632+
lh_config["dns"] = {
633+
"host": dns_cfg.get("host", "0.0.0.0"),
634+
"port": dns_cfg.get("port", 53),
635+
}
636+
627637
config["lighthouse"] = lh_config
628638

629639
# --- Listen ---
@@ -658,6 +668,25 @@ def build_config(minion_id=None):
658668
"timestamp_format": "2006-01-02T15:04:05Z07:00",
659669
}
660670

671+
# --- SSHD (optional, host-level) ---
672+
sshd_cfg = host_config.get("sshd", {})
673+
if sshd_cfg.get("enabled"):
674+
sshd = {
675+
"enabled": True,
676+
"listen": sshd_cfg.get("listen", "127.0.0.1:22"),
677+
"host_key": sshd_cfg.get(
678+
"host_key",
679+
f"{paths['config_dir']}{_sep()}ssh_host_ed25519_key",
680+
),
681+
}
682+
if sshd_cfg.get("authorized_users"):
683+
sshd["authorized_users"] = sshd_cfg["authorized_users"]
684+
if sshd_cfg.get("authorized_nebula_certificate_authorities"):
685+
sshd["authorized_nebula_certificate_authorities"] = sshd_cfg[
686+
"authorized_nebula_certificate_authorities"
687+
]
688+
config["sshd"] = sshd
689+
661690
# --- Firewall ---
662691
# Common defaults
663692
common_fw = nebula_pillar.get("firewall", {})

tests/unit/test_modules_nebula.py

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,110 @@ def test_static_host_map(self):
413413
assert "172.25.0.1" in config["static_host_map"]
414414
assert config["static_host_map"]["172.25.0.1"] == ["1.2.3.4:4242"]
415415

416+
def test_lighthouse_serve_dns(self):
417+
"""Lighthouse with serve_dns emits serve_dns and dns block inside lighthouse config."""
418+
nebula_mod.__pillar__["nebula"]["hosts"]["testhost"]["is_lighthouse"] = True
419+
nebula_mod.__pillar__["nebula"]["hosts"]["testhost"]["serve_dns"] = True
420+
nebula_mod.__pillar__["nebula"]["hosts"]["testhost"]["dns"] = {
421+
"host": "172.25.0.2",
422+
"port": 5353,
423+
}
424+
with patch.object(
425+
nebula_mod,
426+
"detect_paths",
427+
return_value={
428+
"ca_file": "/etc/nebula/ca.crt",
429+
"cert_file": "/etc/nebula/testhost.crt",
430+
"key_file": "/etc/nebula/testhost.key",
431+
"config_dir": "/etc/nebula",
432+
},
433+
):
434+
config = nebula_mod.build_config()
435+
436+
assert config["lighthouse"]["serve_dns"] is True
437+
assert config["lighthouse"]["dns"]["host"] == "172.25.0.2"
438+
assert config["lighthouse"]["dns"]["port"] == 5353
439+
440+
def test_serve_dns_omitted_on_non_lighthouse(self):
441+
"""serve_dns is not emitted for regular nodes even if set in pillar."""
442+
nebula_mod.__pillar__["nebula"]["hosts"]["testhost"]["serve_dns"] = True
443+
with patch.object(
444+
nebula_mod,
445+
"detect_paths",
446+
return_value={
447+
"ca_file": "/etc/nebula/ca.crt",
448+
"cert_file": "/etc/nebula/testhost.crt",
449+
"key_file": "/etc/nebula/testhost.key",
450+
"config_dir": "/etc/nebula",
451+
},
452+
):
453+
config = nebula_mod.build_config()
454+
455+
assert "serve_dns" not in config["lighthouse"]
456+
assert "dns" not in config["lighthouse"]
457+
458+
def test_sshd_enabled(self):
459+
"""sshd block is built correctly from pillar."""
460+
nebula_mod.__pillar__["nebula"]["hosts"]["testhost"]["sshd"] = {
461+
"enabled": True,
462+
"listen": "127.0.0.1:20022",
463+
"host_key": "/etc/nebula/testhost_host",
464+
"authorized_users": [{"user": "alice", "keys": ["ssh-ed25519 AAAA..."]}],
465+
}
466+
with patch.object(
467+
nebula_mod,
468+
"detect_paths",
469+
return_value={
470+
"ca_file": "/etc/nebula/ca.crt",
471+
"cert_file": "/etc/nebula/testhost.crt",
472+
"key_file": "/etc/nebula/testhost.key",
473+
"config_dir": "/etc/nebula",
474+
},
475+
):
476+
config = nebula_mod.build_config()
477+
478+
assert "sshd" in config
479+
assert config["sshd"]["enabled"] is True
480+
assert config["sshd"]["listen"] == "127.0.0.1:20022"
481+
assert config["sshd"]["host_key"] == "/etc/nebula/testhost_host"
482+
assert config["sshd"]["authorized_users"][0]["user"] == "alice"
483+
484+
def test_sshd_default_host_key(self):
485+
"""sshd host_key defaults to config_dir/ssh_host_ed25519_key."""
486+
nebula_mod.__pillar__["nebula"]["hosts"]["testhost"]["sshd"] = {
487+
"enabled": True,
488+
"listen": "127.0.0.1:22",
489+
}
490+
with patch.object(
491+
nebula_mod,
492+
"detect_paths",
493+
return_value={
494+
"ca_file": "/etc/nebula/ca.crt",
495+
"cert_file": "/etc/nebula/testhost.crt",
496+
"key_file": "/etc/nebula/testhost.key",
497+
"config_dir": "/etc/nebula",
498+
},
499+
):
500+
config = nebula_mod.build_config()
501+
502+
assert config["sshd"]["host_key"] == "/etc/nebula/ssh_host_ed25519_key"
503+
504+
def test_sshd_absent_when_not_configured(self):
505+
"""sshd key is not emitted when not in pillar."""
506+
with patch.object(
507+
nebula_mod,
508+
"detect_paths",
509+
return_value={
510+
"ca_file": "/etc/nebula/ca.crt",
511+
"cert_file": "/etc/nebula/testhost.crt",
512+
"key_file": "/etc/nebula/testhost.key",
513+
"config_dir": "/etc/nebula",
514+
},
515+
):
516+
config = nebula_mod.build_config()
517+
518+
assert "sshd" not in config
519+
416520

417521
# ---------------------------------------------------------------------------
418522
# backup_config / rollback_config

0 commit comments

Comments
 (0)