Skip to content

Instantly share code, notes, and snippets.

@natesales
Last active July 24, 2020 04:28
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save natesales/115f5d3fba2734dc93a166a12d7a2812 to your computer and use it in GitHub Desktop.
Save natesales/115f5d3fba2734dc93a166a12d7a2812 to your computer and use it in GitHub Desktop.
OPP-WG Example Specification

OPP-WG

OPP-WG is a standard for remote peering for routing between AMPRNet allocations and the Internet.

Warning

OPP-WG is in alpha and is likely unstable and contains errors. Make sure to look over the example configs before deploying anything in your network.

Comparison to OPP-IPSEC

OPP-WG and OPP-IPSEC both accomplish largely the same result, but have a few key differences. OPP-WG is based Wireguard and OPP-IPSEC is based on IPsec. Wireguard has a lot of potential and was recently merged into the Linux kernel so eventually it should be supported out of the box on most distros. Unfortunately Wireguard doesn't support disabling encryption on the tunnel, so OPP-WG is not FCC Part 97 compliant and therefore cannot be used over RF. If you would like to peer with HamWAN over radio, please use OPP-IPSEC.

Configuration on Linux

This example covers OPP-WG configuration for Debian 10.

Install Wireguard and BIRD

You're free to use any BGP daemon you like, but for this example we'll be using BIRD2.

echo "deb http://deb.debian.org/debian sid main" | sudo tee /etc/apt/sources.list.d/sid.list
sudo apt update
sudo apt install -y wireguard bird2
Generate a Wireguard keypair

Here we generate a private key, compute the public key, and store them at /etc/wireguard/publickey and /etc/wireguard/privatekey respectively.

umask 077; wg genkey | sudo tee /etc/wireguard/privatekey | wg pubkey | sudo tee /etc/wireguard/publickey
Configure the Wireguard tunnel

Open /etc/wireguard/wg0.conf with your favorite text editor and edit the following information:

  • PRIVATE_KEY is your private key, located in /etc/wireguard/privatekey

Then contact your OPP provider and substitute their information accordingly:

  • OPP_PUBLIC_KEY is the OPP-WG provider's public key. (iHpquu78hbgy57i7878wNl8kM=)
  • PEERING_IP is the unique IP address assigned to you by your OPP-WG provider. (44.25.XXX.2/24)
  • OPP_NETWORK is the OPP-WG provider's peering network. (44.25.XXX.0/24)
  • OPP_TUNNEL_HOST should be the OPP-WG provider's tunnel server IP/port. (44.26.XXX.1:51820)
[Interface]
PrivateKey = PRIVATE_KEY
Address = PEERING_IP
 
[Peer]
PublicKey = OPP_PUBLIC_KEY
AllowedIPs = OPP_NETWORK
Endpoint = OPP_TUNNEL_HOST
PersistentKeepalive = 20
Configure the the BGP session

Open /etc/bird/bird.conf and delete the example configuration, replacing with the following:

  • PEERING_IP is the unique IP address assigned to you by your OPP-WG provider. (44.25.XXX.2)
  • OPP_PEERING_IP is the OPP-WG provider's peering address. (44.26.XXX.1)
  • YOUR_44NET is your assigned AMPRNet allocation. (44.xxx.xxx.0/24)
log syslog all;

router id PEERING_IP;

protocol device {};
protocol direct { ipv4; }

protocol kernel {
  ipv4;
  scan time 10;
}

protocol static LOCAL {
  ipv4;
  route YOUR_44NET reject;
}

protocol bgp opp {
  local PEERING_IP as 65511;
  neighbor OPP_PEERING_IP as 65511;

  ipv4 {
    import all;
    export where net ~ (YOUR_44NET);
 };
}
Start Wireguard and BIRD

Finally, start Wireguard and BIRD and enable on system startup.

sudo systemctl start bird
sudo systemctl enable bird
sudo systemctl start wg-quick@wg0
sudo systemctl enable wg-quick@wg0
Verification

The first thing to check is that your Wireguard tunnel is up and traffic is flowing. You can run sudo wg to show your Wireguard interfaces. If the keypairs look correct then try pinging your OPP_PEERING_IP. If you can't ping that address, then there's something wrong with the tunnel or your OPP provider's setup. If that address is reachable, then make sure your BGP session has established.

~ sudo birdc show protocols    
BIRD 2.0.7 ready.
Name       Proto      Table      State  Since         Info
device1    Device     ---        up     15:51:27.966  
direct1    Direct     ---        up     15:51:27.966  
kernel1    Kernel     master4    up     15:51:27.966  
LOCAL      Static     master4    up     15:51:27.966  
opp        BGP        ---        up     15:51:31.805  Established

If your OPP protocol isn't established, make sure you can connect to OPP_PEERING_IP over TCP. Try connecting to OPP_PEERING_IP with port 179 (The BGP port). If not, something might be up with your firewall. If your BGP session is established, check whether you are sending your AMPRNet route(s) by running sudo birdc show route protocol opp. If you see your AMPRNet routes marked as unicast (not unreachable or something else) then you're likely exporting the routes correctly.

Provider Implementation

First install Wireguard and BIRD, and generate a Wireguard keypair. Then create /etc/wireguard/wg0.conf with the following interface config:

[Interface]
Address = YOUR_PEERING_IP/24
SaveConfig = true
ListenPort = 51820
PrivateKey = YOUR_PRIVATE_KEY
Table = off

The BIRD config is fairly straightforward, with route reflector clients and a eBGP session to the upstream router. (Or multiple routers!)

log syslog all;

router id YOUR_PEERING_ADDRESS;

protocol device {};
protocol direct { ipv4; }

protocol kernel {
  scan time 10;
  ipv4 {
    import none;
    export all;
  };
}

You'll also want to configure an eBGP session to your edge router importing a full table and exporting the peer ranges. The edge router should strip the private AS from the AS_PATH at the beginning of the import filter. (bgp_path.delete(65511);)

To add a new peer, add a Wireguard peer by appending to the wg0.conf file:

[Peer]
PublicKey = PEER_PUBLIC_KEY
AllowedIPs = 0.0.0.0/0

The filtering will take place in the BGP import filter, so we'll allow everything here.

And configure the BGP session in BIRD:

protocol bgp PEER_CALLSIGN {
  local YOUR_PEERING_ADDRESS as 65511;
  neighbor PEER_ADDRESS as 65511;
  rr client;

  ipv4 {
    import where (net ~ [
        PEER_44NET_ALLOCATION
    ]);
    export all;
  };
}

You can also use this script to simply the update process. Make sure to update YOUR_PEERING_ADDRESS prior to use:

#!/bin/bash

if [ "$#" -le 3 ]; then
  echo "Usage: ./add.sh <Public Key> <Peer IP> <Callsign> <Prefix list>"
  echo "Example: ./add.sh Eha7a6ajY^Jhy6JgY= 192.168.10.2 CALL 44.x.x.0/24 44.x.x.0/24"
  exit
fi

public_key=$1
peer_ip=$2
callsign=$3

sudo wg set wg0 peer $public_key allowed-ips 0.0.0.0/0

sudo tee -a /etc/bird/bird.conf > /dev/null <<EOT
protocol bgp $callsign {
  local YOUR_PEERING_ADDRESS as 65511;
  neighbor $peer_ip as 65511;
  description "$callsign $public_key";
  rr client;

  ipv4 {
    import limit $(($#-3)) action disable;
    import where (net ~ [
$(printf "       %s,\n" "${@:4}" | sed '$s/,$//')
    ]);
    export all;
  };
}
EOT

sudo birdc configure

echo "Added $callsign@$peer_ip key $public_key"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment