Similar from my previous guide https://forum.dd-wrt.com/phpBB2/viewtopic.php?t=320733 I have now added PBR for transmission using wireguard I did this using the PBR field in the webgui adding "192.168.168.168" and adding to transmissions settings.json
Code:
"bind-address-ipv4": "192.168.168.168",
. To enable that ip I use the command
Code:
ip addr add 192.168.168.168 dev oet1
which adds it to the wireguard tunnel dev oet1 this from memory also sets up the routing for it. I also used
Code:
ip route flush cache
which refreshes the routing but I am not sure if it's needed. I put it all in a routeup.sh script with other stuff.
Code:
#!/bin/sh
ip addr add 192.168.168.168 dev oet1
ip route flush cache
sleep 20
transmissiond --config-dir /opt/transmission/config
sleep is needed to bypass transmission being shutdown for some reason. I load the transmission binary and don't use the service because the service messes up my settings.json, hopefully that is fixed soon.
I also have a routedown.sh script
Code:
#!/bin/sh
killall transmissiond
this kills the transmission process just to be extra sure it doesn't run outside the wireguard tunnel.
I only need the one ip on the dev, I just remember reading it creates a route for it though it doesn't show on the routing table, maybe I am wrong. It won't work without both the PBR and that though.
Thanks I will give them a read when I get a chance.
I have portforwarding working now, wow was it confusing with all nonworking scripts out there. I will post the code when I have everything cleaned up and implemented better.
Given this needs scripting a gui option is not of much use.
I am done with the scripts for now as they work well. Could always be improved and may need to be with some logic for errors or a single settings file. If some one out there wants to improve it please do.
The packages needed I think are coreutils-base64 , jq and transmission-remote .
There is 3 script files connect.sh , portforward.sh and portforwardbind.sh. You need to place them in the same directory for them to work I used /opt/wireguard/. You also need the PIA certificate at https://www.privateinternetaccess.com/openvpn/ca.rsa.4096.crt in the same dir.
The scripts have variables in them you need to configure, like you PIA username and pass but also the wireguard server, and things like your transmission username and pass etc. They have good commenting so have a read.
I am also using a cron job, startup script and wireguard route up script, but first to the main scripts.
The scripts are interdependent, using each other particularly for generating settings. Use the pastebins to get them to avoid wrong formatting.
First is connect.sh https://pastebin.com/dcMyBK8u this will setup a wireguard tunnel automatically putting the settings into nvram and restarting the tunnel but also create a config file to do so, finally it will run the portforward script giving you a port all setup in transmissions and routed etc. I does it all in one hit. You can use it to quickly change server.
Code:
#!/bin/sh
#locate all scripts connect.sh portforward.sh portforardbind.sh and ca.rsa.4096.crt in one folder, I used /opt/wireguard/
#sets script dir as working dir
cd "$(dirname "$0")"
# download here https://www.privateinternetaccess.com/openvpn/ca.rsa.4096.crt
PIA_CERT="ca.rsa.4096.crt"
# Enter your PIA Account details
PIA_USER='p1111111'
PIA_PASS='12341234'
# Enter your wireguard PIA server details find them at https://serverlist.piaservers.net/vpninfo/servers/v6 search for the country or city you want to connect to and look for the 'wg' which stands for wireguard. Here is an example "wg": [{"ip": "188.126.89.149", "cn": "helsinki403"} replace below with the ones you want
PIA_SERVER_IP='188.126.89.149'
echo $PIA_SERVER_IP>PIA_SERVER_IP
PIA_WG_CN='helsinki403'
echo $PIA_WG_CN>PIA_WG_CN
#gets a pia token
GET_TOKEN=$(curl -s -u "$PIA_USER:$PIA_PASS" \
"https://privateinternetaccess.com/gtoken/generateToken")
if [ "$(echo $GET_TOKEN | jq -r '.status')" != "OK" ]; then
echo
echo -e "Could not authenticate with the login credentials provided check them or try another pia server as it may be blocking you"
echo
exit
fi
PIA_TOKEN=$(echo $GET_TOKEN | jq -r '.token')
echo $PIA_TOKEN>PIA_TOKEN || exit 1
# Create ephemeral wireguard keys, that we don't need to be saved to disk.
PRIVKEY="$(wg genkey)"
PUBKEY="$(echo $PRIVKEY | wg pubkey)"
# Authenticate via the PIA WireGuard RESTful API.
# This will return a JSON with data required for authentication.
# The certificate is required to verify the identity of the VPN server.
# In case you didn't clone the entire repo, get the certificate from:
# https://github.com/pia-foss/manual-connections/blob/master/ca.rsa.4096.crt this file needs to be in the same dir as this script
# In case you want to troubleshoot the script, replace -s with -v.
echo Trying to connect to the PIA WireGuard API on $PIA_SERVER_IP...
PIA_WG_JSON="$(curl -s -G --connect-to $PIA_WG_CN::$PIA_SERVER_IP: --cacert $PIA_CERT --data-urlencode pt=$PIA_TOKEN --data-urlencode pubkey=$PUBKEY https://$PIA_WG_CN:1337/addKey)"
export PIA_WG_JSON
echo $PIA_WG_JSON>./PIA_WG_JSON
# Creates the WireGuard config based on the JSON received from the API
# This uses a PersistentKeepalive of 25 seconds to keep the NAT active
# on firewalls. You can remove that line if your network does not
# require it.
echo -n "Trying to write PIA WIREGUARD CONFIG FILE..."
echo
DNSSERVER="$(echo $PIA_WG_JSON | jq -r '.dns_servers[0]')"
LISTENPORT=$(echo $PIA_WG_JSON | jq -r '.server_port')
ADDRESS=$(echo $PIA_WG_JSON | jq -r '.peer_ip')
PUBLICKEY=$(echo $PIA_WG_JSON | jq -r '.server_key')
echo "
[Interface]
PrivateKey = $PRIVKEY
ListenPort = $LISTENPORT
Address = $ADDRESS
DNS = $DNSSERVER
[Peer]
PublicKey = $PUBLICKEY
AllowedIPs = 0.0.0.0/0
Endpoint = $PIA_SERVER_IP:$LISTENPORT
PersistentKeepalive = 25
">./PIA_WIREGUARD_CONFIG.conf || exit 1
echo -n "Trying to set wireguard nvram variables..."
echo
#Puts settings directly into routers nvram
nvram set oet1_private=$PRIVKEY
nvram set oet1_port=$LISTENPORT
nvram set oet1_ipaddrmask=$ADDRESS
nvram set oet1_dns=$DNSSERVER
nvram set oet1_peerkey0=$PUBLICKEY
nvram set oet1_aip="0.0.0.0/0"
nvram set oet1_rem0=$PIA_SERVER_IP
nvram set oet1_peerport0=$LISTENPORT
nvram set oet1_ka0="25"
#other nvram settings
#mtu needed to solve webpage timeout issues
nvram set oet1_mtu="1420"
#saves settings in router
nvram commit
#restarts wireguard tunnel with new settings
ip link set oet1 down
ip link set oet1 up
/etc/config/eop-tunnel.prewall >/dev/null 2>&1
/etc/config/eop-tunnel.firewall >/dev/null 2>&1
#runs portforward script
sleep 5
./portforward.sh
Next is portforward.sh https://pastebin.com/GJafHTY1 this will get you a new port and can be run at any time after you first run connect.sh which gets settings it needs. It then runs portforwardbind.sh
Code:
#!/bin/sh
#sets script dir as working dir
cd "$(dirname "$0")"
PIA_CERT="ca.rsa.4096.crt"
PIA_TOKEN=$(cat PIA_TOKEN)
PIA_SERVER_IP=$(cat PIA_SERVER_IP)
PIA_WG_CN=$(cat PIA_WG_CN)
echo $PF_SIG
#various files are generated which are needed to run portforwardbind.sh
echo $PF_SIG>PF_SIG
PF_PAYLOAD_RAW="$(echo $PF_SIG | jq -r '.payload')"
echo $PF_PAYLOAD_RAW>PF_PAYLOAD_RAW
PF_PAYLOAD="$(echo $PF_PAYLOAD_RAW | base64 -d )"
echo $PF_PAYLOAD
#unworking expiry function
#PF_TOKEN_EXPIRY_RAW=$(echo $PF_PAYLOAD | jq -r .expires_at)
#PF_TOKEN_EXPIRY=$(date --date="$PF_TOKEN_EXPIRY_RAW" +%s)
PF_GETSIGNATURE=$(echo $PF_SIG | jq -r .signature)
echo $PF_GETSIGNATURE>PF_GETSIGNATURE
#pulls the assigned port
PF_PORT=$(echo $PF_PAYLOAD | jq -r .port)
echo $PF_PORT
echo $PF_PORT>PF_PORT
./portforwardbind.sh
This is portforwardbind.sh https://pastebin.com/qQksrn3c . It 'binds' the port to your wireguard tunnel but also sets up the routing and firewall. It needs to be run every 15 mins or you will lose the port. ( Ask PIA lol)
Code:
#!/bin/sh
#sets script dir as working dir
cd "$(dirname "$0")"
PIA_CERT="ca.rsa.4096.crt"
PIA_TOKEN=$(cat PIA_TOKEN)
PIA_SERVER_IP=$(cat PIA_SERVER_IP)
PIA_WG_CN=$(cat PIA_WG_CN)
PF_PAYLOAD_RAW=$(cat PF_PAYLOAD_RAW)
PF_GETSIGNATURE=$(cat PF_GETSIGNATURE)
PF_PORT=$(cat PF_PORT)
#binds the port to your wireguard tunnel. This needs to be done at least every 15mins or the you will loose the port, Setup a cron job with '*/14 * * * * root /opt/wireguard/portforwardbind.sh' or where ever you put the scripts
PF_BIND="$(curl --interface oet1 --CAcert $PIA_CERT --get --silent --show-error --retry 5 --retry-delay 1 --max-time 2 --data-urlencode payload=$PF_PAYLOAD_RAW --data-urlencode signature=$PF_GETSIGNATURE --resolve $PIA_WG_CN:19999:$PIA_SERVER_IP https://$PIA_WG_CN:19999/bindPort)"
echo $PF_BIND
#sets up routing for port to our transmission ip bind 192.168.168.168
iptables -t nat -I PREROUTING -p tcp --dport $PF_PORT -j DNAT --to 192.168.168.168
iptables -t nat -I PREROUTING -p udp --dport $PF_PORT -j DNAT --to 192.168.168.168
#allows port through firewall
iptables -I INPUT -i oet1 -p tcp -d 192.168.168.168 --dport $PF_PORT -j ACCEPT
iptables -I INPUT -i oet1 -p udp -d 192.168.168.168 --dport $PF_PORT -j ACCEPT
#updates transmission with port need package 'opkg install transmission-remote' enter you transmission username and pass if used
transmission-remote -n username:pass -p $PF_PORT
#unused code to edit transmission settings file with port
#sed -i 's/.*peer-port.*/ "peer-port": "'$PF_PORT'",/' /opt/transmission/config/settings.json
I run portforwardbind.sh every 14mins to be safe with a cron job
#used for entware services if you have them
#/opt/etc/init.d/rc.unslung start
transmissiond --config-dir /opt/transmission/config
sleep 5
/opt/wireguard/portforwardbind.sh
It gets run after transmission loads because it uses transmission-remote to change the port. There is commented out code in portforwardbind.sh to edit transmission settings.json file with the port if you want.
You will have noticed maybe ip 192.168.168.168. I bind transmission to this in it's settings.json (make sure to edit it with transmission stopped or it will wipe over the setting when it stop.)
Code:
"bind-address-ipv4": "192.168.168.168",
this prevents transmission from leaking because that ip is only routed over the wireguard tunnel. To do that I have a wireguard route up script routeup.sh https://pastebin.com/yNC6Ys2L
Code:
#!/bin/sh
#sets script dir as working dir
cd "$(dirname "$0")"
#gives the ip we bind transmission to the wireguard tunnel device so it works.
ip addr add 192.168.168.168 dev oet1
#runs script to bind port but also setup firewall for port wireguard wipes the firewall rules when it restarts blocking the port.
./portforwardbind.sh
The last thing it needs is that ip 192.168.168.168 added to the wireguard PBR. You will also notice the portforwardbind.sh is run as well, because these ip and iptable commands need to be run when the tunnel goes up because their settings get wiped out when wireguard restarts.
Inside is files to copy from for cron and startup in the webgui.
I am using connect.sh to renew the internal ip and port everytime the router starts. I have the router set to restart once a day. I see a potential to connect a user to a port, so this helps with that.