Change your DNS servers on a MikroTik RouterBoard based on tunnel status_

June 18, 2015 @21:18
This post has been restored from an archived copy. Links may have changed or be broken.

I have lately started using MikroTik RouterBoards for various remote sites on my network. Mostly the RB951Ui-2HnD as they are inexpensive, powerful, and an all-in-one remote access solution. I typically only route prefixes for my network and networks I have direct VPN links to, but there are a few sites where I don't trust the local Internet provider and will route everything via the VPN.

In either case the RouterBoard acts as a DNS client for my internal DNS servers so I can utilize split horizon DNS and private only zones.

This turns a VPN tunnel failure into essentially a loss of Internet connectivity to the clients associated to the endpoint. To mitigate this I wrote the following script that will automatically change to public DNS servers if the VPN tunnel is down restoring basic Internet connectivity to clients.

#
# (c) 2015 Matthew J. Ernisse <mernisse @ub3rgeek.net>,
# All Rights Reserved
#
# Redistribution and use in source and binary forms,
# with or without modification, are permitted provided
# that the following conditions are met:
#
#     * Redistributions of source code must retain the
#       above copyright notice, this list of conditions
#       and the following disclaimer.
#     * Redistributions in binary form must reproduce
#       the above copyright notice, this list of conditions
#       and the following disclaimer in the documentation
#       and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Watch the status of a tunnel interface and in the event
# it is down, set the DNS servers to be public.  Otherwise
# use private DNS servers.
#

# Begin Configuration
:local pubServers "4.2.2.1,4.2.2.2"
:local tunInt "ipip1"
:local vpnServers "xxx.xxx.xxx.xxx,yyy.yyy.yyy.yyy"


# End Configuration

:local vpnStatus
:local curDns

:set $vpnStatus [/interface ipip get $tunInt running]

#
# mangle DNS server list into format acceptable for the
# ip dns set command
#

:foreach srv in=[/ip dns get servers] do={
:if ( [:len $curDns] = 0 ) do={
:set $curDns $srv
} else={
:set $curDns ( $curDns . "," . $srv )
}
}

#
# Change DNS servers ( only if they need to be )
#

:if ( $vpnStatus != true ) do={
:if ( $curDns != $pubServers ) do {
/ip dns set servers $pubServers
/ip dns cache flush
:log info "VPN down, set DNS servers to $pubServers"
}
} else={
:if ( $curDns != $vpnServers ) do={
/ip dns set servers $vpnServers
/ip dns cache flush
:log info "VPN up, set DNS servers to $vpnServers"
}
}
Subscribe via RSS. Send me a comment.