I wanted to share my configuration here including a script for setting up port forwarding through the VPN, in case anyone wants to setup this as well:
Note:
It seems PIA does not officially support IPsec IKE2 for anything except their iOS app. At least this is what I could find about it in some Reddit comments from them. But so far it seems to work fine on ROS with 6.45.1 - however I do not have long term experience with it yet.
Basic config:
Code: Select all
# basic IPsec fast track exception
/ip firewall mangle add action=mark-connection chain=forward ipsec-policy=out,ipsec new-connection-mark=ipsec
/ip firewall mangle add action=mark-connection chain=forward ipsec-policy=in,ipsec new-connection-mark=ipsec
/ip firewall filter add action=fasttrack-connection chain=forward connection-mark=!ipsec connection-state=established,related
# import GoDaddy Root CA from https://ssl-ccp.godaddy.com/repository/gdroot-g2.crt
/certificate import file-name=gdroot-g2.crt
# this address list is used to select which clients on the network connect
# to the internet through the VPN
/ip firewall address-list add address=A.B.C.D list=ipsec-pia
# ipsec config
/ip ipsec mode-config add name=pia responder=no src-address-list=ipsec-pia
/ip ipsec policy group add name=pia
/ip ipsec profile add dh-group=modp2048 enc-algorithm=aes-128 hash-algorithm=sha256 name=pia
/ip ipsec peer add address="de-frankfurt.privateinternetaccess.com" exchange-mode=ike2 name=pia profile=pia
/ip ipsec proposal add enc-algorithms=aes-128-cbc name=pia pfs-group=none
/ip ipsec policy add dst-address=0.0.0.0/0 group=pia proposal=pia src-address=0.0.0.0/0 template=yes
# user/password for this can be generated in the PIA account portal (section "PPTP/L2TP/SOCKS Username and Password")
/ip ipsec identity add auth-method=eap certificate="" eap-methods=eap-mschapv2 generate-policy=port-strict mode-config=pia password=ABCD peer=pia policy-template-group=pia remote-id=fqdn:*.privateinternetaccess.com username=l2tpUserFromPia
The IPsec peer is configured with a domain name. ROS checks regularly if the IP address of this domain changes and restarts the IPsec peer if this is the case.
As PIA does load-balancing on a DNS level, the IP address changes on nearly every lookup. This causes ROS to restart the connection to a different peer every few minutes.
I wanted to set up port-forwarding with a script anyway, so i put the DNS lookup in there and configured the IPsec peer with a fixed IP:
Code: Select all
:local piaClientId "random SHA256 hash (lowercase, without any dashes or spaces)";
:local piaHostName "de-frankfurt.privateinternetaccess.com";
:local piaHostIp [:resolve $piaHostName];
:local piaInternalIp;
:local forwardedPort;
:local portForwardTarget A.B.C.D;
:log info "PIA: connecting to server $piaHostName ($piaHostIp)."
# set peer ip
/ip ipsec peer set pia address=$piaHostIp;
# wait for IPsec connection to establish
:do {
:delay 3
:local ruleId [/ip firewall nat find dynamic action=src-nat src-address-list="ipsec-pia" comment="ipsec mode-config"];
:if ($ruleId != "") do={
:set piaInternalIp [/ip firewall nat get $ruleId to-address];
}
} while=( [:typeof $piaInternalIp] = "nothing" );
:log info "PIA: internal IP is $piaInternalIp."
# request port forward (needs to happen in the first 2min after connection is established)
:local wanInterface [/ip route get [find pref-src=$piaInternalIp] gateway];
:local routeId [/ip route add distance=1 dst-address=209.222.18.222 gateway=$wanInterface pref-src=$piaInternalIp];
:local result [/tool fetch url="http://209.222.18.222:2000/\?client_id=$piaClientId" as-value output=user];
/ip route remove $routeId;
:if ($result->"status" = "finished") do={
:local data ($result->"data");
:if ($data ~ "\\{\"port\":[0-9]+\\}") do={
:set forwardedPort [:pick $data 8 ([:len $data] - 1)];
:log info "PIA: forwarded port is $forwardedPort."
} else={
:error "PIA: unexpected port forward response $data"
}
} else={
:error "PIA: failed to configure port forwarding"
}
# configure dst-nat
/ip firewall nat remove [find action=dst-nat chain=dstnat to-addresses=$portForwardTarget comment="PIA: port forward"];
/ip firewall nat add action=dst-nat chain=dstnat dst-address=$piaInternalIp dst-port=$forwardedPort protocol=tcp to-addresses=$portForwardTarget to-ports=$forwardedPort comment="PIA: port forward";
/ip firewall nat add action=dst-nat chain=dstnat dst-address=$piaInternalIp dst-port=$forwardedPort protocol=udp to-addresses=$portForwardTarget to-ports=$forwardedPort comment="PIA: port forward";
(this is my first ROS script, feedback is appreciated)
There is one thing I wanted to do where I could not find a nice solution:
I want to block clients from the address list "ipsec-pia" from accessing the internet without going through IPsec. Right now, if the IPsec connection stops for some reason, the dynamic src-nat rule is removed and the connections get routed to the normal WAN connection. My plan was to create a fallback rule that would drop packets if they are not going through IPsec:
Code: Select all
/ip firewall filter add action=drop chain=forward ipsec-policy=out,none out-interface-list=WAN src-address-list=ipsec-pia