AMPRNet IPIP with systemd-networkd
Published on: March 22, 2026
There are many packet radio networks across the world. Some of the larger ones like the German HAMNET can be VPN-ed into, but others can’t. Furthermore, if you, for example, VPN into HAMNET using HamCloud VPN you’ll only have access to HAMNET, not to the Internet and not to other packet radio networks.
This can be circumvented by not connecting to any one network, but to a long-standing mesh of independent packet radio networks. I’m of course referring to AMPRNet, an IPIP overlay network, which is one of the oldest ways people utilize 44net address space. By participating in the IPIP mesh you’ll be able to access the aforementioned HAMNET, HamWAN, and any other network a person or a club made available over the IPIP mesh. You’ll also be able to utilize the same addresses to access the public Internet. Heck, if you decide to host something on the IPIP mesh, it can be made available via HAMNET, HamWAN and the public Internet all at the same time from the same IP address! Additionally, having IPIP connectivity can significantly optimize routing paths for those who announce a prefix over BGP or use 44net Connect. This is because traffic to prefixes not directly announced will skip the UCSD gateway and go directly to whoever is hosting the service, drastically reducing latency and skipping a potential bottleneck.
If you’re curious what services are exclusive to AMPRNet, check out what can be accessed.
Requesting a subnet
First of all, I needed an address allocation. This was easy enough to get. I just went to the ARDC portal, and since I already
had my callsign verified, the only thing I had to do was to visit Network > Request address. I then chose IPIP tunnel mesh as the use case, filled out the form with some
very basic information, and submitted the request. I used IPIP test as the title, and for size I chose /30, giving me enough addresses to set up a local subnet with one router and a PC.
An advantage of requesting a small subnet size was that I had to do almost no justification whatsoever. A description that reads: For exploring the IPIP mesh and seeing how it interconnects with HAMNET which was enough to get the request approvide on the same day. Of course, if you plan to set up a LAN segment with access to IPIP and want to connect more than one PC and a router you’ll need a bigger preifx, feel free to request any size.
Defining a Gateway
While I was waiting for an approval, I continued on to adding a gateway entry. A gateway entry in the portal, not to be confused with AmprGW, is what defines where to route traffic addressed to your subnet. The process of defining a gateway can be completed even before you’re allocated a subnet, therefore I immediately went to Networks > My gateways in order to create a new gateway.
I used my callsign as the description and in the IP field I put the public IP address ISP assigned me: 213.190.26.133. I left the hostname field empty. If you have a dynamic address your best bet is dynamic DNS, alternatively or if you’re behind CG-NAT 44net Connect can be used to obtain a static IPv4 address which can then serve as the gateway IP.
Thankfully, I haven’t had to do any of that since my ISP gave me a static address free of charge.
After receiving a subnet, I went to the previously created gateway and clicked Add New Network, then I selected the newly allocated subnet from the dropdown, left the Find Network field empty and added the nework. At this point the administrative process was done and it was time to set up a Linux machine which will serve as the gateway.
Configuring Linux as a Router
First of all, I have to say that most Linux distros don’t ship with systemd-networkd out of the box. Ubuntu uses netplan, Fedora NetworkManager and Debian is still stuck on ifupdown. The machine I am using is Debian 13 and it was set up to use systemd-networkd before I even started experimenting with IPIP mesh so I won’t write anything about switching from ifupdown or whatever your distro is using to systemd-networkd, but there is an awesome, easy to follow guide consisting of just a few commands specifically for Debian. It boils down to:
sudo apt update
sudo apt install systemd-resolved
sudo mv /etc/network/interfaces /etc/network/interfaces.save
sudo mv /etc/network/interfaces.d /etc/network/interfaces.d.save
sudo systemctl enable systemd-networkd
sudo systemctl enable systemd-resolved
sudo cat > /etc/systemd/network/10-physical.network << EOF
[Match]
Name=enp8s0 # Your interface name
[Network]
Address=192.168.1.20/24
Gateway=192.168.1.1
DNS=192.168.1.1
EOF
sudo reboot
To start, I went into my router and forwarded all IPIP traffic to a machine running Linux (192.168.1.20). In my case the router was a MikroTik box, so this was fairly easy. On a generic home router, adding the machine to DMZ is usually what does the trick.
Then, I created an IPIP interface:
sudo nano /etc/systemd/network/46-ampr_ipip.netdev
[NetDev]
Name=ampr_ipip
Kind=ipip
[Tunnel]
Remote=0.0.0.0 # Important
Local=192.168.1.20
TTL=255
This file creates a tunnel interface that will carry the AMPRNet traffic.
It has Remote set to 0.0.0.0 which is necessary to create a point-to-multipoint tunnel with no single remote end.
Following this, I associated the tunnel with a physical interface that will carry the encapsulated traffic. I also added a second address which devices connecting to the mesh will use as the gateway.
sudo nano /etc/systemd/network/10-physical.network
[Match]
Name=enp8s0 # Your interface name
[Network]
Address=192.168.1.20/24
Gateway=192.168.1.1
DNS=192.168.1.1
Tunnel=ampr_ipip # Added
Address=44.63.3.165/30 # Added, use an address from your allocated subnet
I also had to define the network part of the tunnel configuration:
sudo nano /etc/systemd/network/46-ampr_ipip.network
[Match]
Name=ampr_ipip
[Network]
Address=44.63.3.164/32 # Your assigned subnet, IMPORTANT: use /32 regardless of your allocated size
# A default route for IPIP subnet over the UCSD Gateway
[Route]
Destination=0.0.0.0/0
Gateway=169.228.34.84
GatewayOnLink=yes
Table=45
# Local subnets should be resolved with the default table!
[RoutingPolicyRule]
To=44.63.3.164/30 # Your assigned subnet, use the real allocated subnet size
Table=1
Priority=508
# Local subnets should be resolved with the default table!
[RoutingPolicyRule]
To=192.168.1.0/24 # The normal LAN
Table=1
Priority=509
# Route everything from the IPIP subnet via routing table 45
[RoutingPolicyRule]
From=44.63.3.164/30
To=0.0.0.0/0
Table=45
Priority=510
# Route everything to the IPIP subnet via routing table 45
[RoutingPolicyRule]
To=44.63.3.164/30
From=0.0.0.0/0
Table=45
Priority=511
The first two policies ensure that local subnets (i.e. my own IPIP subnet and my normal LAN) are routed via the main table. The second two policies ensure that everything not locally accessible is encapsulated and sent via IPIP mesh.
Note when using VRFs with policy routing:
The
Priorityshould be less than 1000 in order for the rules to take precedence over the VRF rule (l3mdev-table). If this is not taken care of, custom rules won’t get evaluated.
Lastly, IP forwarding needed to be enabled in order for the machine to act as a router:
sudo nano /etc/sysctl.d/10-ip_forwarding.conf
net.ipv4.ip_forward = 1
net.ipv6.conf.all.forwarding = 1 # Not strictly neccesary, but good to have if you ever decide to do something with IPv6
After all of this, it was time for a reboot:
sudo reboot
There is only one more thing that needs to be configured before I can access the AMPRNet.
That is ampr-ripd, a small daemon that runs in the background and populates the routing table with the latest information on how to reach different network parties.
I installed it inside the /opt directory:
cd /opt
sudo git clone https://git.ampr.org/yo2loj/ampr-ripd.git
cd ampr-ripd
sudo mkdir /var/lib/ampr-ripd
sudo apt install build-essential
sudo make
Then I made a systemd unit file that manages ampr-ripd:
sudo nano /etc/systemd/system/ampr-ripd.service
[Unit]
Description=AMPRNet RIP routing daemon
After=network-online.target
[Service]
# routing table metric
# | IPIP interface | your public IP
ExecStart=/opt/ampr-ripd/ampr-ripd -r -d -t 45 -s -i ampr_ipip -m 40 -a 213.190.26.133
User=root
Group=root
[Install]
WantedBy=multi-user.target
ampr-ripddocs say that the-roption is ignored:Compatibility only (ignored, raw sockets are always used), however, I found that-ris actually required, without it, RIP broadcasts will not be received.
Finally, make ampr-ripd start on boot, then reboot:
sudo systemctl daemon-reload
sudo systemctl enable ampr-ripd
sudo reboot
Configuring clients
At the end, this is how I configured a PC to use the newly setup IPIP gateway:
IP address: 44.63.3.166
Gateway: 44.63.3.165
Subnet mask: 255.255.255.252 # equivalent to /30
DNS: 44.143.40.30 # HAMNET DNS server
Now, to test the connection, I tried pinging various hosts from the PC:
ping 44.143.40.30 # HAMNET DNS Server - only accessible from AMPRNet, inaccessible from the public Internet
ping 44.0.0.1 # UCSD Gateway - bridges AMPRNet and the Internet
ping 9.9.9.9 # A generic Internet host - expected to fail at this point
Fixing Internet access
At this point pinging a generic Internet host is expected to fail. This is because to access the Internet, a DNS record pointing to each PC that needs Internet access must be created. That is done to prevent Internet traffic from flooding hosts on possibly low-bandwidth RF links.
To add a record, I went to the ARDC portal DNS > My subdomains > Request a subdomain. Chose ampr.org as the domain and typed in my callsign as the subdomain. The request was automatically approved the moment it was submitted. Next, I opened up the
subdomain and clicked add a record, set type to A, hostname to ipiptest, left TTL empty and set address to the address of the PC, of course. After the record was created, it took multiple hours before I was able to access the Internet using my AMPRNet address. The important thing was not to turn off or restart the gateway while waiting.
What can be accessed?
What follows is only a small list of services that can be accessed via AMPRNet but not via the public Internet.
- HAMNET
- HAMNET Search engine
- Video conferencing
- Webcams
- DK0MAV HTTP Preview
- DK0MAV RTSP - open in VLC
- DB0FC Wets HTTP Preview
- DB0FC West RTSP - open in VLC
- DB0BI Webcam panel
- ATV RTSP streams
- DB0OL RTSP - open in VLC
- DB0YZ RTSP - open in VLC
- DB0HEX RTSP - open in VLC
- DB0ROB RTSP - open in VLC
- WebSDR
- Weather
- Social
- Maps
- A bigger link list