colima icon indicating copy to clipboard operation
colima copied to clipboard

AAAA records not resolved in containers with `network.address=true` on dual-stack macOS host

Open stek29 opened this issue 10 months ago • 3 comments

Description

when using network.address=true vmType=vz (and getting vzNAT network), the containers and the colima vm are able to reach dual-stack networks. however, DNS still does not resolve IPv6 records.

initially I've thought that the issue was caused by hostResolver.ipv6 not being set – but turns out I was wrong. leaving my original assumption for history, see https://github.com/abiosoft/colima/issues/1275#issuecomment-2682333806 for correct info.

original issue description -- was incorrect

currently hostResolver.ipv6 is never set: https://github.com/abiosoft/colima/blob/e79883bde6581b8ab0db8d0c63103cf4b1e89f8a/environment/vm/lima/yaml.go#L72-L81

however, it's possible to get a somewhat working IPv6 network in container with:

network:
  address: true

docker:
  fixed-cidr-v6: SOME-RANDOM-ULA-CIDR::/48
  ipv6: true

but the DNS won't resolve AAAA records since hostResolver.ipv6 property is not set in the lima config.

would be great to allow setting it from the network settings, or to even set it to true automatically if network.address is set to true in Colima spec.

stek29 avatar Feb 21 '25 16:02 stek29

I've ended up going for an ugly workaround for now until this issue is resolved:

#!/usr/bin/env bash
# this is a ugly workaround for https://github.com/abiosoft/colima/issues/1275
# put this in your PATH before the original limactl, for example, in ~/bin/limactl

set -euo pipefail

# Get absolute path of this script to avoid recursion
SCRIPT_PATH="$(realpath "${BASH_SOURCE[0]}")"

# Get the first limactl in path skipping this script itself
ORIGINAL_LIMACTL=$(which -a limactl | while read -r candidate; do
    if [[ "$(realpath "$candidate")" != "$SCRIPT_PATH" ]]; then
        echo "$candidate"
        break
    fi
done)

# check if found and is exacutable
if [[ ! -x "${ORIGINAL_LIMACTL}" ]]; then
    echo "limactl not found" >&2
    exit 1
fi

# check if yq is installed
if ! command -v yq &>/dev/null; then
    echo "yq not found" >&2
    exit 1
fi

# if being run for colima and it's a 'start' command with profile name,
# and if that profile has a vzNAT network in it, then set hostResolver.ipv6 to true
if [[ "${LIMA_HOME:-}" =~ \.colima/_lima$ && "${1:-}" == "start" && -n "${2:-}" ]]; then
    profile_name="$2"
    yaml_path="${LIMA_HOME}/${profile_name}/lima.yaml"
    if [[ -f "$yaml_path" ]] && yq e '.networks[] | select(.vzNAT == true) | length > 0' "$yaml_path" &>/dev/null; then
        echo "[limactl-ipv6-wrapper] patching hostResolver.ipv6 to true" >&2
        yq -i e '.hostResolver.ipv6 |= true' "$yaml_path"
    fi
fi

exec "${ORIGINAL_LIMACTL}" "$@"

but this proves that setting the value should be enough

maybe changing the default isn't the safest option, but allowing the end user to configure this through the Colima settings seems like a good idea to me.

stek29 avatar Feb 21 '25 18:02 stek29

The config was not available in Lima initially, must've been introduced more recently.

abiosoft avatar Feb 21 '25 21:02 abiosoft

sorry, looks like it was just a coincidence and the hostResolver.ipv6 isn't really needed for the IPv6 to work.

main issue was caused by colima passing two networks for the lima machine, which led to Lima VM getting a DNS server on eth0 via cloud-init (which is an user-v2 net with IPv4 only – so this DNS does not resolve AAAA records at all), and a DNS server on col0 via DHCP (which is an vzNAT net with IPv4/IPv6 dual stack – so this DNS does resolve AAAA records correctly).

so the VM boots with DNS addresses from two interfaces in the systemd-resolved, and their order is seemingly random – which means that on colima restart there's a chance of systemd-resolved resolving AAAA records correctly (if dns from col0 goes first), or not resolving AAAA (if dns from eth0 goes first).

so the easiest way to get a working IPv6 on macOS with colima with working DNS is:

vmType: vz
network:
  address: true
provision:
  - mode: system
    script: resolvectl dns eth0 ''

maybe it would be a good idea not to enable DNS on eth0 if network.address is set?

stek29 avatar Feb 25 '25 15:02 stek29