Thursday, March 6, 2014

L2TP VPN with 2 Mikrotik

VPN (any type) between 2 Mikrotik routers and no static IP addresses

VPN is very useful when you have a dislocated office, but it requires that at least one location has static IP addresses. Below is the script that allows you to establish a VPN link even if you don't have static IP addresses on any location. This example shows this using L2TP VPN but it works on any VPN type. (With minor changes of course) Network layout for this example:
Example network layout


Server side

On the server side we first create an user who will connect to the server: (Be sure to set a complex password and a longer username)
/ppp secret add caller-id="" comment="Some description" disabled=no limit-bytes-in=0 \
limit-bytes-out=0 local-address=10.0.16.9 name=ka password=ka profile=default \
remote-address=10.0.16.10 routes="" service=l2tp
Then we create a L2TP server interface for the created user:
/interface l2tp-server add disabled=no name=l2tp-ka user=ka
Creating the server interface is not nececery for all this to work since the ROS will dynamicly create the interface each time the user authenticates, but will ease creation of firewall rules.
Enable the server:
/interface l2tp-server server set authentication=pap,chap,mschap1,mschap2 \
default-profile=default-encryption enabled=yes max-mru=1460 max-mtu=1460 mrru=disabled
Add a route to the client side network:
/ip route add comment=Ka disabled=no distance=1 dst-address=10.1.16.0/28 gateway=10.0.16.10 \
scope=30 target-scope=10
Don't forget to change the dst-address to your IP range on the client side

Here is where you have to take a break from this script and read this script. Since you don't have any static IP addresses, you will need a dynamic DNS on the serve side. Once you have configured the ChangeIP.org script from the link, proceed to the client side configuration.


Client side

Create a l2tp client interface to connect to the server. Change IP_OF_L2TP_SERVER to an IP address of your server side router.
/interface l2tp-client add add-default-route=no allow=pap,chap,mschap1,mschap2 \
connect-to=IP_OF_L2TP_SERVER dial-on-demand=no disabled=no max-mru=1460 \
max-mtu=1460 mrru=disabled name=l2tp-BL password=ka profile=default-encryption user=ka
Add a route to the server side network:
/ip route add disabled=no distance=1 dst-address=10.0.0.0/24 gateway=10.0.16.9 scope=30 \
target-scope=10
Don't forget to change the dst-address to your IP range on the server side
Now to make the link work after one of the IP addresses change.

First add a script named 'SetL2TP' and with the following code:
:global newr1 [:resolve hostname.changeip.org]
/int l2tp-client set l2tp-BL connect-to=$newr1
:log info "SetL2TPscript:Changing IP"
When executed, this will resolve the new IP to the ChangeIP.org hostname you have set on the server side.
Then add a scheduler that will execute the above script every 60 seconds (make sure the schedular is now disabled):
/system scheduler add disabled=yes interval=1m name=SetL2TP on-event="system script run SetL2TP" \
policy=read,write,test start-time=startup
Experiment with this interval. You don't want too short an interval because you might get an IP from cache and not be able to reconnect for a longer time.
Now add two scripts that enable and disable the scheduler above. Just paste these two lines on the MT terminal:
/system script add name=EnaSched_1 policy=ftp,reboot,read,write,policy,test,winbox,password,sniff \
source="sys sched ena SetL2TP"
/system script add name=DisaSched_1 policy=ftp,reboot,read,write,policy,test,winbox,password,sniff \
source="sys sched disa SetL2TP"
Finally, create a netwatch that checks if server side is avaliable:
/tool netwatch add disabled=no down-script=EnaSched_1 host=10.0.16.9 interval=15s timeout=1s \
up-script=DisaSched_1

Wednesday, March 5, 2014

Dynamic DNS

# No-IP automatic Dynamic DNS update

#--------------- Change Values in this section to match your setup ------------------

# No-IP User account info

:local noipuser "ggg@gmail.com"

:local noippass "xxxxxx"

# Set the hostname or label of network to be updated.

# Hostnames with spaces are unsupported. Replace the value in the quotations below with your host names.

# To specify multiple hosts, separate them with commas.

:local noiphost "xxxxx.no-ip.biz"

# Change to the name of interface that gets the dynamic IP address

:local inetinterface "WAN"

#------------------------------------------------------------------------------------

# No more changes need

:global previousIP

:if ([/interface get $inetinterface value-name=running]) do={

# Get the current IP on the interface

   :local currentIP [/ip address get [find interface="$inetinterface" disabled=no] address]

# Strip the net mask off the IP address

   :for i from=( [:len $currentIP] - 1) to=0 do={

       :if ( [:pick $currentIP $i] = "/") do={

           :set currentIP [:pick $currentIP 0 $i]

       }

   }

   :if ($currentIP != $previousIP) do={

       :log info "No-IP: Current IP $currentIP is not equal to previous IP, update needed"

       :set previousIP $currentIP

# The update URL. Note the "\3F" is hex for question mark (?). Required since ? is a special character in commands.

       :local url "http://dynupdate.no-ip.com/nic/update\3Fmyip=$currentIP"

       :local noiphostarray

       :set noiphostarray [:toarray $noiphost]

       :foreach host in=$noiphostarray do={

           :log info "No-IP: Sending update for $host"

           /tool fetch url=($url . "&hostname=$host") user=$noipuser password=$noippass mode=http dst-path=("no-ip_ddns_update-" . $host . ".txt")

           :log info "No-IP: Host $host updated on No-IP with IP $currentIP"

       }

   }  else={

       :log info "No-IP: Previous IP $previousIP is equal to current IP, no update needed"

   }

} else={

   :log info "No-IP: $inetinterface is not currently running, so therefore will not update."

}