Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!


Shells Virtual Desktop
BMail.ag - Secure Email Service
Server.net
CPLicense.net
VPS Server
Buy VPN
Vultr
VMs for AI
HostDare
ReliableSite White-Label Dedicated Hosting for Resellers
InterServer VPS
BMail.ag - Secure Email Service
Best VPN
High-Performance Bare Metal Server Solutions
Karvl.com
Server Mania Cloud Hosting
DataWagon Hosting
AlphaVPS Hosting
Evoxt.com
Clouvider
VPS Hosting with NVMe
Residential IPs in the US & 4G Mobile Proxies in EU & US with Unlimited Bandwidth
ReliableSite White-Label Dedicated Hosting for Resellers
Rabisu - Hosting Solutions
Shells Virtual Desktop
New on LowEndTalk? Please Register and read our Community Rules.

All new Registrations are manually reviewed and approved, so a short delay after registration may occur before your account becomes active.

Setting up a NAT64 server on a cheap dual-stack LXC VPS with just 256MB memory

Hey there, LowEndTalks community! First post here - let me share something cool I figured out.

IPv4 addresses are expensive these days, while IPv6-only hosting is dirt cheap. The problem? Many sites still only work on IPv4, making IPv6-only setups kind of limited. That's where NAT64 comes in! It's like a universal translator between IPv6 and IPv4 with minimal complexity and resource overhead.

I've got this whole setup running smoothly on a tiny 256MB LXC VPS that costs me about $2/year. Talk about stretching your hosting dollars!

Prerequisites

You'll need:

  • A dual-stack VPS (has both IPv4 and IPv6)
  • Root access
  • Basic networking knowledge (or good copy-paste skills!)
  • Linux installed (I'll show examples for Alpine, Debian/Ubuntu, and RHEL/CentOS)

Step 1: Find Your IPv6 Subnet

Run this command to see what you're working with:

ip -6 route

You'll see something like:
2001:db8:1234::/64 dev eth0 proto kernel metric 256 pref medium

This shows your /64 subnet and network interface. Make note of it!

Step 2: Choose a /96 Prefix for IPv4 Mapping

Pick a /96 prefix from your subnet for mapping IPv4 addresses. If your subnet is 2001:db8:1234::/64, you might use:

2001:db8:1234:64:ff9b::/96

This format uses 96 bits for the IPv6 prefix and 32 bits for embedding IPv4 addresses.

Step 3: Add a Local Route

Tell your system to treat the prefix as local:

ip -6 route add local 2001:db8:1234:64:ff9b::/96 dev lo

Step 4: Set Up NDP Proxy

This lets your server answer neighbor discovery requests for your NAT64 prefix.

For Alpine:

# Install npd6
apk add npd6

# Configure npd6
cat > /etc/npd6.conf <<EOF
prefix=2001:db8:1234:64:ff9b::  # your chosen prefix
interface=eth0
ralogging=off
listtype=none
listlogging=off
collectTargets=100
linkOption=false
ignoreLocal=true
routerNA=true
maxHops=255
pollErrorLimit=20
EOF

# Start service
rc-update add npd6
service npd6 start

For Debian/Ubuntu:

# Install ndppd
apt install ndppd

# Configure ndppd
cat > /etc/ndppd.conf <<EOF
proxy eth0 {
  rule 2001:db8:1234:64:ff9b::/96 {
    static
  }
}
EOF

# Start service
systemctl enable ndppd
systemctl start ndppd

For RHEL/CentOS:

# Install ndppd
dnf install ndppd

# Configure same as Debian
# Then start service
systemctl enable ndppd
systemctl start ndppd

Remember to replace 2001:db8:1234:64:ff9b:: and eth0 with your actual values!

Step 5: Test Local Route Setup

Verify with a ping:

ping -6 2001:db8:1234:64:ff9b::1234

If you run into problems, check your firewall first, e.g. loopback traffic is accepted and ICMPv6 is enabled.

YMMV: Some cloud providers impose limitation on traffic over any ip. Oracle Cloud for example filters out traffic with IPv6 addresses are not bound to VNIC.

Comments

  • Step 6: Install and Run NAT64

    Download nat64 file from this minimalistic NAT64 server or build from source (can't attach link for whatever reason)

    Configure iptables to redirect traffic:

    ip6tables -t mangle -A PREROUTING -d 2001:db8:1234:64:ff9b::/96 -p tcp -j TPROXY --on-port=8888 --on-ip=::1
    

    Run the server:

    /path/to/nat64
    
  • Step 7: Set Up DNS64

    You have two deployment options for DNS64:

    1. Server-side DNS64: You can run both DNS64 and NAT64 on your dual-stack server. This is simpler to set up but gives you less control over traffic routing.

    2. Client-side DNS64: You run DNS64 on your IPv6-only client machines and just the NAT64 on your dual-stack server. This approach is generally preferred as it provides:

      • Faster DNS resolution (local DNS queries)
      • Full control over which traffic goes through NAT64
      • The ability to selectively route only certain domains through NAT64

    For client-side DNS64, you would install and configure Unbound on your client machines instead, pointing to your NAT64 server's prefix.

    Install Unbound:

    # Debian/Ubuntu
    apt install unbound
    
    # Alpine
    apk add unbound
    
    # RHEL/CentOS
    dnf install unbound
    

    Configure DNS64:

    cat > /etc/unbound/unbound.conf.d/dns64.conf <<EOF
    server:
      module-config: "dns64 iterator"
      dns64-prefix: 2001:db8:1234:64:ff9b::/96
      do-not-query-localhost: yes
    
    forward-zone:
      name: "."
      forward-addr: 1.1.1.1@53
      forward-addr: 8.8.8.8@53
    EOF
    

    Replace 2001:db8:1234:64:ff9b::/96 with your actual NAT64 prefix, and adjust the forward-addr to your preferred DNS servers.

    Restart Unbound and configure DNS:

    systemctl restart unbound
    echo "nameserver ::1" > /etc/resolv.conf
    
  • Step 8: Run NAT64 as a Service

    For systemd systems:

    cat > /etc/systemd/system/nat64.service <<EOF
    [Unit]
    Description=NAT64 Server
    After=network.target
    
    [Service]
    ExecStart=/path/to/nat64 -p 8888
    Restart=always
    
    [Install]
    WantedBy=multi-user.target
    EOF
    
    systemctl enable nat64
    systemctl start nat64
    

    For Alpine with OpenRC:

    cat > /etc/init.d/nat64 <<EOF
    #!/sbin/openrc-run
    
    command=/path/to/nat64
    command_args="-p 8888"
    pidfile=/run/nat64.pid
    
    depend() {
      need net
      after network
    }
    
    start() {
      ebegin "Starting NAT64"
      start-stop-daemon --start --make-pidfile --pidfile \${pidfile} --background --exec \${command} -- \${command_args}
      eend \$?
    }
    EOF
    
    chmod +x /etc/init.d/nat64
    rc-update add nat64 default
    service nat64 start
    
  • Step 9: Make Configuration Permanent

    Create startup scripts to persist your settings across reboots.

    For Alpine:

    cat > /etc/local.d/nat64-setup.start <<EOF
    #!/bin/sh
    ip -6 route add local 2001:db8:1234:64:ff9b::/96 dev lo
    ip6tables -t mangle -A PREROUTING -d 2001:db8:1234:64:ff9b::/96 -p tcp -j TPROXY --on-port=8888 --on-ip=::1
    EOF
    
    chmod +x /etc/local.d/nat64-setup.start
    

    For Debian/Ubuntu:

    cat > /etc/network/if-up.d/nat64-setup <<EOF
    #!/bin/sh
    ip -6 route add local 2001:db8:1234:64:ff9b::/96 dev lo
    ip6tables -t mangle -A PREROUTING -d 2001:db8:1234:64:ff9b::/96 -p tcp -j TPROXY --on-port=8888 --on-ip=::1
    EOF
    
    chmod +x /etc/network/if-up.d/nat64-setup
    
  • Verify Your Setup

    Test with:

    ping -6 ipv4.google.com
    

    or try to curl with ipv6 http://ipv4only.me

    If those work, you're golden!

  • Conclusion - Profit!

    You've now got a working NAT64 gateway on a dirt-cheap VPS! This lets you:

    • Run services on budget IPv6-only VPS plans (we're talking $1-2/year cheap!)
    • Access IPv4-only services from IPv6-only networks
    • Save serious cash while getting full internet access

    The whole setup runs on even the tiniest containers with minimal resources. Combine this with a cheap IPv6 VPS plan, and you're saving serious money while still getting full internet access.

    Questions? Drop 'em in the comments!

  • Thanks for this! I was looking to set up a NAT64+DNS64 server this weekend so this came at the perfect time.

  • ailiceailice Member
    edited March 2025

    Tutorial so crystal-clear even have alpine version, is so chef kiss

Sign In or Register to comment.