Skip to content

Commit 3f67969

Browse files
committed
Add DNS server to host-agent to use native host resolver
This is is required to correctly resolve hostnames while using conditional forwarding (split-DNS) when connected to a VPN. The hostagent must be compiled with CGO_ENABLED=1 to use the native resolver. Signed-off-by: Jan Dubois <jan.dubois@suse.com>
1 parent f56f620 commit 3f67969

File tree

17 files changed

+233
-50
lines changed

17 files changed

+233
-50
lines changed

Makefile

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ PACKAGE := github.com/lima-vm/lima
1111
VERSION=$(shell git describe --match 'v[0-9]*' --dirty='.m' --always --tags)
1212
VERSION_TRIMMED := $(VERSION:v%=%)
1313

14-
GO_BUILD := CGO_ENABLED=0 $(GO) build -ldflags="-s -w -X $(PACKAGE)/pkg/version.Version=$(VERSION)"
14+
GO_BUILD := $(GO) build -ldflags="-s -w -X $(PACKAGE)/pkg/version.Version=$(VERSION)"
1515

1616
.PHONY: all
1717
all: binaries
@@ -39,16 +39,18 @@ _output/bin/nerdctl.lima:
3939

4040
.PHONY: _output/bin/limactl
4141
_output/bin/limactl:
42-
$(GO_BUILD) -o $@ ./cmd/limactl
42+
# The hostagent must be compiled with CGO_ENABLED=1 so that net.LookupIP() in the DNS server
43+
# calls the native resolver library and not the simplistic version in the Go library.
44+
CGO_ENABLED=1 $(GO_BUILD) -o $@ ./cmd/limactl
4345

4446
.PHONY: _output/share/lima/lima-guestagent.Linux-x86_64
4547
_output/share/lima/lima-guestagent.Linux-x86_64:
46-
GOOS=linux GOARCH=amd64 $(GO_BUILD) -o $@ ./cmd/lima-guestagent
48+
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 $(GO_BUILD) -o $@ ./cmd/lima-guestagent
4749
chmod 644 $@
4850

4951
.PHONY: _output/share/lima/lima-guestagent.Linux-aarch64
5052
_output/share/lima/lima-guestagent.Linux-aarch64:
51-
GOOS=linux GOARCH=arm64 $(GO_BUILD) -o $@ ./cmd/lima-guestagent
53+
GOOS=linux GOARCH=arm64 CGO_ENABLED=0 $(GO_BUILD) -o $@ ./cmd/lima-guestagent
5254
chmod 644 $@
5355

5456
.PHONY: install

docs/network.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@ The loopback addresses of the host is `192.168.5.2` and is accessible from the g
2020

2121
The DNS.
2222

23+
If `useHostResolver` in `lima.yaml` is true, then the hostagent is going to run a DNS server over udp, using the same socket number as `ssh.localPort`. This server does a local lookup using the native host resolver, so will deal correctly with VPN configurations and split-DNS setups, as well a mDNS (for this the hostagent has to be compiled with `CGO_ENABLED=1`).
24+
25+
This udp port is then forwarded via iptables rules to `192.168.5.3:53`, overriding the DNS provided by QEMU via slirp.
26+
27+
During initial cloud-init bootstrap, `iptables` may not yet be installed. In that case the repo server is determined using the slirp DNS. After `iptables` has been installed, the forwarding rule is applied, switching over to the hostagent DNS.
28+
29+
If `useHostResoler` is false, then DNS servers can be configured manually in `lima.yaml` via the `dns` setting. If that list is empty, then Lima will either use the slirp DNS (on Linux), or the nameservers from the `en0` host interface (on macOS).
30+
2331
## `vde_vmnet` (192.168.105.0/24)
2432

2533
[`vde_vmnet`](https://github.com/lima-vm/vde_vmnet) is required for adding another guest IP that is accessible from

examples/alpine.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
images:
2-
- location: https://github.com/lima-vm/alpine-lima/releases/download/v0.1.4/alpine-lima-std-3.13.5-x86_64.iso
2+
- location: https://github.com/lima-vm/alpine-lima/releases/download/v0.1.5/alpine-lima-std-3.13.5-x86_64.iso
33
arch: "x86_64"
4-
digest: "sha512:ef627d902645744ab9f62cfe9f741f84c9d544b36da113aef9410489db8d2430b9c37581c5958b4d7fc64dfb5267f4147a376a747cca053c8c43c65fc68474e0"
4+
digest: "sha512:7b5c6f3691b88293cf94091c1d74629ee3227a5f5548d24497309d00f91338800d315d4a907b6c45a10d1a6ceb2bb7dc5b8a72d9be2e251f6979886ae0bf1274"
55

66
mounts:
77
- location: "~"

go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ require (
1616
github.com/lima-vm/sshocker v0.2.2
1717
github.com/mattn/go-isatty v0.0.14
1818
github.com/mattn/go-shellwords v1.0.12
19+
github.com/miekg/dns v1.1.43
1920
github.com/norouter/norouter v0.6.4
2021
github.com/nxadm/tail v1.4.8
2122
github.com/opencontainers/go-digest v1.0.0
@@ -46,6 +47,7 @@ require (
4647
github.com/rivo/uniseg v0.2.0 // indirect
4748
github.com/spf13/pflag v1.0.5 // indirect
4849
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 // indirect
50+
golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d // indirect
4951
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
5052
golang.org/x/term v0.0.0-20210503060354-a79de5458b56 // indirect
5153
golang.org/x/text v0.3.6 // indirect

go.sum

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -580,6 +580,7 @@ github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1f
580580
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
581581
github.com/mibk/dupl v1.0.0/go.mod h1:pCr4pNxxIbFGvtyCOi0c7LVjmV6duhKWV+ex5vh38ME=
582582
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
583+
github.com/miekg/dns v1.1.43 h1:JKfpVSCB84vrAmHzyrsxB5NAr5kLoMXZArPSw7Qlgyg=
583584
github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4=
584585
github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
585586
github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4=

pkg/cidata/cidata.TEMPLATE.d/boot/30-install-packages.sh

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,14 @@ update_fuse_conf() {
1010
fi
1111
}
1212

13+
INSTALL_IPTABLES=0
14+
if [ "${LIMA_CIDATA_CONTAINERD_SYSTEM}" = 1 ] || [ "${LIMA_CIDATA_CONTAINERD_USER}" = 1 ]; then
15+
INSTALL_IPTABLES=1
16+
fi
17+
if [ "${LIMA_CIDATA_UDP_DNS_LOCAL_PORT}" -ne 0 ]; then
18+
INSTALL_IPTABLES=1
19+
fi
20+
1321
# Install minimum dependencies
1422
if command -v apt-get >/dev/null 2>&1; then
1523
DEBIAN_FRONTEND=noninteractive
@@ -20,7 +28,7 @@ if command -v apt-get >/dev/null 2>&1; then
2028
apt-get install -y sshfs
2129
fi
2230
fi
23-
if [ "${LIMA_CIDATA_CONTAINERD_SYSTEM}" = 1 ] || [ "${LIMA_CIDATA_CONTAINERD_USER}" = 1 ]; then
31+
if [ "${INSTALL_IPTABLES}" = 1 ]; then
2432
if [ ! -e /usr/sbin/iptables ]; then
2533
apt-get install -y iptables
2634
fi
@@ -36,7 +44,7 @@ elif command -v dnf >/dev/null 2>&1; then
3644
dnf install -y fuse-sshfs
3745
fi
3846
fi
39-
if [ "${LIMA_CIDATA_CONTAINERD_SYSTEM}" = 1 ] || [ "${LIMA_CIDATA_CONTAINERD_USER}" = 1 ]; then
47+
if [ "${INSTALL_IPTABLES}" = 1 ]; then
4048
if [ ! -e /usr/sbin/iptables ]; then
4149
dnf install -y iptables
4250
fi
@@ -63,7 +71,7 @@ elif command -v zypper >/dev/null 2>&1; then
6371
zypper install -y sshfs
6472
fi
6573
fi
66-
if [ "${LIMA_CIDATA_CONTAINERD_SYSTEM}" = 1 ] || [ "${LIMA_CIDATA_CONTAINERD_USER}" = 1 ]; then
74+
if [ "${INSTALL_IPTABLES}" = 1 ]; then
6775
if [ ! -e /usr/sbin/iptables ]; then
6876
zypper install -y iptables
6977
fi
@@ -80,6 +88,17 @@ elif command -v apk >/dev/null 2>&1; then
8088
apk add sshfs
8189
fi
8290
fi
91+
if [ "${INSTALL_IPTABLES}" = 1 ]; then
92+
if ! command -v iptables >/dev/null 2>&1; then
93+
apk update
94+
apk add iptables
95+
fi
96+
fi
97+
fi
98+
99+
if [ "${LIMA_CIDATA_UDP_DNS_LOCAL_PORT}" -ne 0 ]; then
100+
# Try to setup iptables rule again, in case we just installed iptables
101+
"${LIMA_CIDATA_MNT}/boot/07-host-dns-setup.sh"
83102
fi
84103

85104
# update_fuse_conf has to be called after installing all the packages,

pkg/cidata/cidata.TEMPLATE.d/lima.env

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,6 @@ LIMA_CIDATA_CONTAINERD_SYSTEM=1
1414
{{- else}}
1515
LIMA_CIDATA_CONTAINERD_SYSTEM=
1616
{{- end}}
17-
LIMA_CIDATA_SLIRP_GATEWAY={{ .SlirpGateway }}
17+
LIMA_CIDATA_SLIRP_DNS={{.SlirpDNS}}
18+
LIMA_CIDATA_SLIRP_GATEWAY={{.SlirpGateway}}
19+
LIMA_CIDATA_UDP_DNS_LOCAL_PORT={{.UDPDNSLocalPort}}

pkg/cidata/cidata.TEMPLATE.d/user-data

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,5 +42,4 @@ resolv_conf:
4242
{{- range $ns := $.DNSAddresses }}
4343
- {{$ns}}
4444
{{- end }}
45-
- {{.SlirpDNS}}
4645
{{- end }}

pkg/cidata/cidata.go

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -90,13 +90,13 @@ func GenerateISO9660(instDir, name string, y *limayaml.LimaYAML) error {
9090
return err
9191
}
9292
args := TemplateArgs{
93-
Name: name,
94-
User: u.Username,
95-
UID: uid,
96-
Containerd: Containerd{System: *y.Containerd.System, User: *y.Containerd.User},
97-
SlirpNICName: qemu.SlirpNICName,
98-
SlirpGateway: qemu.SlirpGateway,
99-
SlirpDNS: qemu.SlirpDNS,
93+
Name: name,
94+
User: u.Username,
95+
UID: uid,
96+
Containerd: Containerd{System: *y.Containerd.System, User: *y.Containerd.User},
97+
SlirpNICName: qemu.SlirpNICName,
98+
SlirpGateway: qemu.SlirpGateway,
99+
SlirpDNS: qemu.SlirpDNS,
100100
}
101101

102102
// change instance id on every boot so network config will be processed again
@@ -131,7 +131,10 @@ func GenerateISO9660(instDir, name string, y *limayaml.LimaYAML) error {
131131
if err != nil {
132132
return err
133133
}
134-
if len(y.DNS) > 0 {
134+
if *y.UseHostResolver {
135+
args.UDPDNSLocalPort = y.SSH.LocalPort
136+
args.DNSAddresses = append(args.DNSAddresses, qemu.SlirpDNS)
137+
} else if len(y.DNS) > 0 {
135138
for _, addr := range y.DNS {
136139
args.DNSAddresses = append(args.DNSAddresses, addr.String())
137140
}

pkg/cidata/template.go

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -28,19 +28,20 @@ type Network struct {
2828
Interface string
2929
}
3030
type TemplateArgs struct {
31-
Name string // instance name
32-
IID string // instance id
33-
User string // user name
34-
UID int
35-
SSHPubKeys []string
36-
Mounts []string // abs path, accessible by the User
37-
Containerd Containerd
38-
Networks []Network
39-
SlirpNICName string
40-
SlirpGateway string
41-
SlirpDNS string
42-
Env map[string]string
43-
DNSAddresses []string
31+
Name string // instance name
32+
IID string // instance id
33+
User string // user name
34+
UID int
35+
SSHPubKeys []string
36+
Mounts []string // abs path, accessible by the User
37+
Containerd Containerd
38+
Networks []Network
39+
SlirpNICName string
40+
SlirpGateway string
41+
SlirpDNS string
42+
UDPDNSLocalPort int
43+
Env map[string]string
44+
DNSAddresses []string
4445
}
4546

4647
func ValidateTemplateArgs(args TemplateArgs) error {

0 commit comments

Comments
 (0)