Preface
When running independent servers (such as Hetzner, OVH), we often run into a pain point: the data center only gives you a /64 or /56 IPv6 block, but the gateway strictly binds to a physical MAC address. If you want to spin up sub-machines (LXC/KVM) inside the host machine, the IPv6 packets sent from the sub-machines’ virtual MAC will be dropped directly by the gateway.
Today, through NDP Responder (NDP Proxy) technology, we’ll manually implement an industrial-grade solution that lets subnet devices “disguise” themselves for internet access.
I. Core Principle: Why Do We Need an NDP Proxy?
In IPv4, we’re used to using NAT. But in the world of IPv6, we advocate for end-to-end communication. Normally, when an external gateway looks for a certain IPv6 address, it sends a Neighbor Solicitation.
- Problem: The virtual machines inside the host machine aren’t directly connected to the data center switch, so they can’t receive this request; even if they did receive it, their reply (containing the virtual MAC) would be intercepted by the data center switch’s firewall.
- Solution: We run a proxy program on the host machine. It listens on the physical network card, and when it discovers someone asking about a virtual machine’s IP, it preemptively answers: “This IP is with me, please send the packet to my physical MAC.” After the host machine receives the packet, it forwards it to the virtual machine according to the internal routing table.
II. Environment Preparation
- Host Machine: Debian/Ubuntu (this example uses a Proxmox environment)
- Tool:
ndpresponder(a lightweight tool written in Go, which fits your learning direction perfectly) - Network Topology:
- Physical network card:
ens3(connected to the external network) - Virtual bridge:
vmbr1(connected to internal containers)
III. Detailed Steps
1. Enable Kernel Forwarding
First, the Linux kernel must be allowed to let IPv6 packets “travel” between different network cards.
Modify /etc/sysctl.conf:
# Enable IPv6 forwarding on all interfacesnet.ipv6.conf.all.forwarding=1# Allow receiving router advertisementsnet.ipv6.conf.ens3.accept_ra=2# Enable NDP proxy supportnet.ipv6.conf.all.proxy_ndp=1Run sysctl -p to apply.
2. Configure Network Interfaces (/etc/network/interfaces)
We need to define two “pools,” one external and one internal.
# External main bridgeauto vmbr0iface vmbr0 inet6 static address 2a01:4f8:xxx:113a/80 # Your main IP gateway fe80::1 # Data center gateway
# Internal subnet bridge (for virtual machines)auto vmbr1iface vmbr1 inet6 static address 2a01:4f8:xxx:10e0::1/96 bridge-ports none bridge-stp off3. Deploy NDP Responder
We’ll run the program in a Systemd daemon.
Create the file /etc/systemd/system/ndpresponder.service:
[Unit]Description=NDP Responder for LXC SubnetAfter=network.target
[Service]# -i: the external interface to listen on# -n: the internal subnet to proxyExecStart=/usr/sbin/ndpresponder -i vmbr0 -n 2a01:4f8:xxx:10e0::/96Restart=always
[Install]WantedBy=multi-user.targetStart the service: systemctl enable --now ndpresponder.
IV. Verification and Debugging
As developers, we must learn to read logs. Observe journalctl -u ndpresponder -f:
Found Gateway: Found the data center gateway… RESPOND: who-has
...:10e0:1010:3tellfe80::...
When you see the word RESPOND, it means the host machine has successfully “impersonated” the virtual machine and completed the neighbor discovery handshake.
V. Architectural Reflection (Student Perspective)
From the perspective of Go language development, what inspiration does this technology bring us?
- Decoupling: NDP Proxy essentially acts as a transparent adapter between the link layer (L2) and the network layer (L3).
- Concurrency Model: Tools like
ndprespondertypically use Go’spcaplibrary or raw sockets to listen to traffic. This requires extremely high processing efficiency and is an excellent case for learning how Go handles high-performance network streams. - Industrial Standards: This configuration pattern (Map First, Code Follows) conforms to the IEP collaboration protocol we discussed earlier—first plan the network topology (Map), then proceed with service deployment (Code).
Conclusion
IPv6 is no longer a mysterious black box. By understanding the NDP protocol and manually configuring the proxy, we have not only solved the data center internet access problem, but also gained a deeper understanding of the routing essence of the modern internet.
