Jump to content
Not connected, Your IP: 18.224.54.61
Staff

[COMPLETED] WireGuard beta testing available

Recommended Posts

On 11/26/2021 at 6:30 PM, maxhawk said:
Update:
The issue is that OpenVPN uses an MTU=1500 while Wireguard uses MTU=1420. Dropped packets were preventing the proper SSL handshake. My fix is to manually force an MTU=1392 in the machine that's having trouble. The long term fix is to have any machine that connects to this subnet use an MTU of 1392, but that's an issue outside of Wireguard and AirVPN.

I am using WireGuard (kmod) on OPNsense to route my VPN-enabled_VLAN through AirVPN. I have been noticing download and browsing speed issues with this for a while now and yesterday finally found the reason and workaround thanks to your post.

Did you ever solve this in the long term? Any solution that doesn't involve changing the network config of the client devices?

Share this post


Link to post
2 hours ago, TheHellSite said:

I am using WireGuard (kmod) on OPNsense to route my VPN-enabled_VLAN through AirVPN. I have been noticing download and browsing speeds with this for a while now and yesterday finally found the issue and workaround thanks to your post.

Did you ever solve this in the long term? Any solution that doesn't involve changing the network config of the client devices?

Hello!

For your information, the official WireGuard Android user app forces MTU to 1280 bytes (in our Eddie app, we also had to force 1320, although MTU remains customizable in Eddie settings). Higher sizes cause malfunctions, timeouts, line breaks or snail throughput on virtually any device and network we tested, almost surely because there is (often) no room in the frame. Even the Linux client forces 1280 bytes (if it doesn't find anything else in the profile) if our memory is correct. Thus your findings are consistent and hint to the necessity to keep a low MTU size.

Kind regards
 

Share this post


Link to post

With wireguard on pfsense setting each wireguard interface I create to 1420 MTU and MSS seems to result in no problems and good performance. 

Share this post


Link to post
6 hours ago, go558a83nk said:

With wireguard on pfsense setting each wireguard interface I create to 1420 MTU and MSS seems to result in no problems and good performance. 


Hello!

Do you declare an MTU size on the WireGuard conf file? Relevant for this discussion: https://superuser.com/questions/1537638/wireguard-tunnel-slow-and-intermittent

Different networks may require different sizes. This is probably the reason for which WireGuard developers opted for the smallest allowed size in Android, 1280 bytes. Of course if it's possible to set higher sizes the performance will improve.

Kind regards
 

Share this post


Link to post
On 9/23/2022 at 3:45 AM, go558a83nk said:

With wireguard on pfsense setting each wireguard interface I create to 1420 MTU and MSS seems to result in no problems and good performance. 

On 9/23/2022 at 10:03 AM, Staff said:

Do you declare an MTU size on the WireGuard conf file? Relevant for this discussion: https://superuser.com/questions/1537638/wireguard-tunnel-slow-and-intermittent

As OPNsense and pfSense are/where pretty much the same, I am also interested in this!

Looking at pictures of the pfSense WireGuard user interface (VPN --> WireGuard --> Tunnel Configuration) it seems that there is no field which would allow setting an MTU or MSS value for the tunnel.
It looks like you only have the option to set the MTU (and MSS) value in the pfSense interface section.

However on OPNsense there is an extra field (VPN --> WireGuard --> Local --> "Tunnelname") to set the MTU value directly in the WireGuard config but also no field for the MSS value.
In the OPNsense interface section it also of course possible to define the MTU (and MSS) value. The interface section also overwrites any setting configured in the WireGuard tunnel configuration.

Also reading through this tutorial and the linked reddit thread it seems that it is best to just set these values in the interface section of OPNsense/pfSense and not in the tunnel configuration.
I will try this out and report back here.
 

Update

It is best to declare the MTU value at the interface configuration and also in the tunnel configuration. The latter is necessary because each reload of the interface configuration and each reload of the WireGuard package will reapply the MTU value to the interface.
Setting the MTU=1420 and MSS=1420 in the interface configuration of the interface assigned to the WireGuard tunnel and also MTU=1420 in the tunnel configuration resolved both the speed and SSL issues.

 
  1. Note
    I personally have to use MTU=1412 since my WAN requires the use of PPPoE, which adds another 8 byte of overhead that needs to be substracted of the theoretical maximum MTU=1420.
    WireGuard MTU for PPPoE = 1420 - 8 = 1412
    Details see here: https://lists.zx2c4.com/pipermail/wireguard/2017-December/002201.html
     
  2. Note
    Setting the MSS value the same as the MTU value is specific to OPNsense and pfSense! Both firewalls automatically reduce the value entered in the MSS field by 40 bytes.
    On other systems the MSS value has to be entered 40 bytes lower than the MTU value.
    OPNsense / pfSense: MTU entered = actual MTU applied to the interface
    OPNsense / pfSense: MSS entered = MSS entered - 40 bytes = actual MSS applied to the interface

Update 2

The official OPNsense docs now display the correct way of handling MTU/MSS with WireGuard.
https://docs.opnsense.org/manual/how-tos/wireguard-client.html
 

Share this post


Link to post
5 hours ago, Staff said:

Hello!

Do you declare an MTU size on the WireGuard conf file? Relevant for this discussion: https://superuser.com/questions/1537638/wireguard-tunnel-slow-and-intermittent

Different networks may require different sizes. This is probably the reason for which WireGuard developers opted for the smallest allowed size in Android, 1280 bytes. Of course if it's possible to set higher sizes the performance will improve.

Kind regards
 
No, I didn't know that existed.  :)  I'll have to check it out when I get a chance.

Share this post


Link to post
Posted ... (edited)

I was running OpenVPN on my pfSense box to AirVPN for a few years but lately I experienced a lot of speed problems.
Before I could hit around 600mbit (1gb line) but recently I was hitting the 150mbit max...

So I switched to WireGuard and after settings the MTU to 1420 I was getting decent speeds again! Except some websites did not load or were utterly slow.
After reading the comments here from @go558a83nk and @TheHellSite I set the MSS to 1420 also (so MTU + MSS = 1420) and voila problem solved!
This is done on the pfSense Interface, not in the wireguard config.

Getting around 700 - 800mbit on my line and everything is snappy again!
Just wanted to share my 2 cents.

Edited ... by Teng Teng Toa

Share this post


Link to post

I've been running Wiregaurd for the VPN for a while now and I have a question, 
In the config it does separate tables for IP 4 and IP 6, why isn't the inet family used instead? 
From the MAN pages: 

IPV4/IPV6/INET ADDRESS FAMILIES
       The IPv4/IPv6/Inet address families handle IPv4, IPv6 or both types of
       packets. They contain five hooks at different packet processing stages
       in the network stack.
from the command prompt it looks like this for output: 
sudo nft list ruleset
table inet filter {
	chain input {
		type filter hook input priority filter; policy accept;
		iif "lo" accept
		ct state established,related accept
		icmpv6 type { destination-unreachable, packet-too-big, time-exceeded, parameter-problem, echo-request, echo-reply, nd-router-solicit, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert, 148, 149 } accept
		ip6 saddr fe80::/10 icmpv6 type { mld-listener-query, mld-listener-report, mld-listener-done, mld2-listener-report, 151, 152, 153 } accept
		counter packets 242 bytes 43336 drop
	}
}
table ip6 wg-quick-tun0 {
	chain preraw {
		type filter hook prerouting priority raw; policy accept;
		iifname != "tun0" ip6 daddr fd7d:76ee:e68f:a993:6c33:1401:f02c:98a8 fib saddr type != local drop
	}

	chain premangle {
		type filter hook prerouting priority mangle; policy accept;
		meta l4proto udp meta mark set ct mark
	}

	chain postmangle {
		type filter hook postrouting priority mangle; policy accept;
		meta l4proto udp meta mark 0x0000ca6c ct mark set meta mark
	}
}
table ip wg-quick-tun0 {
	chain preraw {
		type filter hook prerouting priority raw; policy accept;
		iifname != "tun0" ip daddr 10.162.132.125 fib saddr type != local drop
	}

	chain premangle {
		type filter hook prerouting priority mangle; policy accept;
		meta l4proto udp meta mark set ct mark
	}

	chain postmangle {
		type filter hook postrouting priority mangle; policy accept;
		meta l4proto udp meta mark 0x0000ca6c ct mark set meta mark
	}
}
I'm just curious as why the inet wasn't used instead of the separate IP Families.   

Daaa Baby Smurf do do do😁

Go_Camping___.jpg

Share this post


Link to post

How can I automatically (from a script) renew my keys to force a new random IP address reassignment (as per WireGuard FAQ)?

In 2020 a member of the AirVPN Team suggested we'd be able to to so in the future:

On 7/30/2020 at 1:38 PM, Clodo said:

We will offer an API to automate the above, letting users write a script that performs HTTPS calls to change local IP address, download updated .conf, and then wg-quick. 


The same feature has been requested here and in this thread:
 
On 11/6/2021 at 11:28 PM, airvpnforumuser said:

It seems renewing the keys does have a minor privacy benefit and is something I'd like to do routinely. At the moment managing keys is only possible via your website and is one of the biggest feature suggestions I'd like to see added to the API (then I can rotate keys freely).


Is this feature on the roadmap?

Share this post


Link to post
On 10/2/2022 at 10:25 PM, Opayq said:
Quote

How can I automatically (from a script) renew my keys to force a new random IP address reassignment (as per WireGuard FAQ)?



In 2020 a member of the AirVPN Team suggested we'd be able to to so in the future:


The same feature has been requested here and in this thread:
 
Is this feature on the roadmap?

Hello!

The feature has not been implemented yet, we're sorry. An impact assessment is beginning in a few days. After that, if everything is fine, we will proceed. We will keep you informed. EDIT 2022-10-06: FEATURE IMPLEMENTED

Kind regards
 

Share this post


Link to post
On 10/6/2022 at 1:05 PM, Staff said:

We're very glad to inform you that the feature has been implemented.


That was quick, awesome! Tested manually and seems to work fine. Will be able to script renewal and config reload thanks to this API. 😁

Share this post


Link to post

Here's the script I wrote (for OpenWrt) to rotate the fixed WireGuard ip address. Run it when you want to reconnect with a new dynamically assigned ip address. It's a workaround for one of these concerns. It relies on BusyBox and uci. Shouldn't be too hard to adapt this script to other Unix platforms.

#!/bin/sh

# USAGE:
# Create two devices via https://airvpn.org/devices/
# Setup WireGuard on the OpenWrt router with this config https://airvpn.org/generator/
# Change the VPN_CLIENT_INTERFACE_NAME variable below to the name of your WireGuard network interface
# Change the DEVICE_NAME_A and DEVICE_NAME_B variables below to match the names of these devices
# Enable and get your API key from https://airvpn.org/apisettings/ and set the API_KEY variable below

# OpenWrt Config
VPN_CLIENT_INTERFACE_NAME='wireguard_client'

# AirVPN Config
API_KEY='aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
DEVICE_NAME_A='OpenWrt1'
DEVICE_NAME_B='OpenWrt2'
SERVER='earth' # to figure out which name to use, go to https://airvpn.org/generator/ and enable API Reference then check value for servers= in the curl example
PORT=1637 # choose 1637 or 47107
KEEPALIVE='25'
IP_LAYER_EXIT='ipv4'
API_URL='https://airvpn.org/api'
UPDATE_CONSTANTS=false # set to true to re-apply constant values

print_exit() {
    echo 'Exiting...' && exit 1
}

# Pass string to look in as first argument and key to look for as second
# Outputs the value if found
get_conf_option() {
    # Find matching line with grep,
    # then extract capture group with sed (-n = don't default to printing each line)
    echo "$1" | grep -m 1 -o -E "^$2\s*=.*$" | sed -n -E 's/^[^=]*=\s*(.*)$/\1/p'
}

# Pass string to look in as first argument
# Pass the device key as second and value as third argument
# Outputs the id if found
get_device_index_by_key_value() {
    # Use grep first since sed won't stop after the first match
    echo "$1" | grep -m 1 -E "^devices\.\d+\.${2}=${3}$" | sed -n -E 's/^devices\.(\d+).*$/\1/p'
}

# Pass string to look in as first argument
# Pass the key as second argument and the device index third
# Outputs the value if found
get_value_by_key_and_index() {
    # Filter data on index and key first, then extract value after last = character
    get_conf_option "$1" "devices.${3}.${2}"
}

# Pass string to look in as first argument
# Outputs the value if found
extract_ip_address() {
    # Does NOT stop after finding n matches, -m n stops after finding all matches on n lines
    # https://stackoverflow.com/a/69833537
    # Use head to only return first match
    echo "$1" | grep -m 1 -o -E '([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})' | head -1
}

# Pass string to validate as first argument, a variable name to echo second
# Exits if string is empty or not in base64 format
validate_base64() {
    # Compare grep result to the passed string itself to reject multi-line strings
    if [ -z "$1" ] || [ "$(echo "$1" | grep -m 1 -o -E '^[A-Za-z0-9+/]{4}*([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$')" != "$1" ]; then
        echo "$2 is not base64: $1" && print_exit
    fi
}

get_devices_data() {
    DATA="$(wget -qO- --post-data="key=$API_KEY&format=text" "$API_URL/devices/")"
}

# Get the devices data from AirVPN API
if ! get_devices_data; then
    # Failure
    echo 'Failed to get devices data from API' && print_exit
fi

# Get the ip address assigned
IP_ADDRESS=$(extract_ip_address "$(uci get "network.$VPN_CLIENT_INTERFACE_NAME.addresses")")
DEVICE_INDEX=

if [ -n "$IP_ADDRESS" ]; then
    echo "Current ip address: $IP_ADDRESS"
    # Find the device with this ip address in the API data
    DEVICE_INDEX=$(get_device_index_by_key_value "$DATA" wireguard_ipv4 "$IP_ADDRESS")
else
    echo 'Could not determine current ip address'
fi

if [ -z "$DEVICE_INDEX" ]; then
    echo 'Falling back to default device'
    DEVICE_INDEX=$(get_device_index_by_key_value "$DATA" name "$DEVICE_NAME_A")
    if [ -z "$DEVICE_INDEX" ]; then
        echo 'Unable to obtain device index' && print_exit
    fi
fi

echo "Current device index: $DEVICE_INDEX"

# Get the name of the current device
NAME=$(get_value_by_key_and_index "$DATA" name "$DEVICE_INDEX")
echo "Current name: $NAME"

DEVICE_ID=$(get_value_by_key_and_index "$DATA" id "$DEVICE_INDEX")
echo "Current ID: $DEVICE_ID"

if [ "$NAME" = "$DEVICE_NAME_A" ]; then
    NEW_DEVICE_NAME="$DEVICE_NAME_B"
elif [ "$NAME" = "$DEVICE_NAME_B" ]; then
    NEW_DEVICE_NAME="$DEVICE_NAME_A"
else
    echo "$NAME does not match one of the options $DEVICE_NAME_A or $DEVICE_NAME_B" && print_exit
fi

echo "Use $NEW_DEVICE_NAME now!"

NEW_DEVICE_INDEX=$(get_device_index_by_key_value "$DATA" name "$NEW_DEVICE_NAME")

if [ -z "$NEW_DEVICE_INDEX" ]; then
    echo 'Unable to obtain new device index' && print_exit
fi

echo "New device index: $NEW_DEVICE_INDEX"

# Wait for new device to be ready, if it isn't yet
TRIES=1
MAX_TRIES=5
while [ "$(get_value_by_key_and_index "$DATA" status "$NEW_DEVICE_INDEX")" != 'ready' ] && [ $TRIES -le $MAX_TRIES ]; do
    echo "Attempt $TRIES: new device config is not yet ready..."
    sleep 10
    get_devices_data

    if [ $TRIES -eq $MAX_TRIES ]; then
        echo 'Timed out waiting for device to be ready...' && print_exit
    fi

    TRIES=$((TRIES + 1))
done

# Get the vpn config file from AirVPN API
if ! CONFIG=$(wget -qO- --post-data="protocols=wireguard_1_udp_$PORT&servers=$SERVER&system=other&device=$NEW_DEVICE_NAME&wireguard_mtu=0&wireguard_persistent_keepalive=$KEEPALIVE&iplayer_exit=$IP_LAYER_EXIT&key=$API_KEY" "$API_URL/generator/"); then
    # Failure
    echo 'Failed to get config file from API' && print_exit
fi

NEW_ADDRESS=$(extract_ip_address "$(get_conf_option "$CONFIG" Address)")
NEW_PRIVATE_KEY=$(get_conf_option "$CONFIG" PrivateKey)
NEW_PRESHARED_KEY=$(get_conf_option "$CONFIG" PresharedKey)

if [ -z "$NEW_ADDRESS" ]; then
    echo 'Could not determine new ip address' && print_exit
fi

echo "New ip address: $NEW_ADDRESS"
validate_base64 "$NEW_PRIVATE_KEY" NEW_PRIVATE_KEY
validate_base64 "$NEW_PRESHARED_KEY" NEW_PRESHARED_KEY

# echo "Set new config..."
uci set "network.$VPN_CLIENT_INTERFACE_NAME.addresses=$NEW_ADDRESS"
uci set "network.$VPN_CLIENT_INTERFACE_NAME.private_key=$NEW_PRIVATE_KEY"
uci set "network.@wireguard_${VPN_CLIENT_INTERFACE_NAME}[0].preshared_key=$NEW_PRESHARED_KEY"

# These values don't change after renewing the config, there should be no need to re-apply them
if [ $UPDATE_CONSTANTS = true ]; then
    NEW_PUBLIC_KEY=$(get_conf_option "$CONFIG" PublicKey)
    NEW_ENDPOINT=$(get_conf_option "$CONFIG" Endpoint)
    NEW_ENDPOINT_HOST=${NEW_ENDPOINT%:*}

    validate_base64 "$NEW_PUBLIC_KEY" NEW_PUBLIC_KEY

    # Check if the port was present
    if [ "$NEW_ENDPOINT_HOST" = "$NEW_ENDPOINT" ]; then
        echo "Incorrectly formatted Endpoint value: $NEW_ENDPOINT" && print_exit
    fi

    if [ -z "$NEW_ENDPOINT_HOST" ]; then
        echo 'Could not determine new endpoint host' && print_exit
    fi

    uci set "network.@wireguard_${VPN_CLIENT_INTERFACE_NAME}[0].public_key=$NEW_PUBLIC_KEY"
    uci set "network.@wireguard_${VPN_CLIENT_INTERFACE_NAME}[0].endpoint_host=$NEW_ENDPOINT_HOST"
    uci set "network.@wireguard_${VPN_CLIENT_INTERFACE_NAME}[0].endpoint_port=$PORT"
    uci set "network.@wireguard_${VPN_CLIENT_INTERFACE_NAME}[0].persistent_keepalive=$KEEPALIVE"
fi

echo "Commit new config..."
uci commit

# echo "Restart WireGuard interface"
ifup "$VPN_CLIENT_INTERFACE_NAME"

# echo "Renew the old device, so it will be fresh and ready to use next time"
wget -qO- --post-data="key=$API_KEY&format=text&action=renew&id=$DEVICE_ID" "$API_URL/devices/"

Share this post


Link to post

a question for staff.

if I am running both OpenVPN and wireguard tunnels.   under client and devices, should I have two keys generated?
I am using the same router for both connections.     it is working,  but I want it to continue working obviously 

 

Share this post


Link to post

Is there a firewall like "Comodo personal firewall" (for windows os), that is able to handle (ie block/permit) wireguard outbound connections ?

Share this post


Link to post

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Security Check
    Play CAPTCHA Audio
    Refresh Image

×
×
  • Create New...