Dynamic DNS + tunnelbroker MikroTik script for HE.net (Hurricane Electric)

5 09 2013

 

Note: Tested on MikroTik 6.2

/system script
add name=he-dns policy=ftp,read,write,policy,test,winbox,api source=”# Update Hurricane Electric DDNS IPv4 address\r\
\n\r\
\n#make sure previousip is initialized with a value (0.0.0.0) before the script is first run\r\
\n:global previousip\r\
\n\r\
\n:local ddnshost \”DYNAMIC_HOSTNAME\”\r\
\n:local key \”KEY\”\r\
\n:local updatehost \”dyn.dns.he.net\”\r\
\n:local WANinterface \”WAN_INTERFACE_NAME\”\r\
\n:local outputfile \”he-dns.txt\”\r\
\n\r\
\n# Internal processing below…\r\
\n# ———————————-\r\
\n:local currentip\r\
\n\r\
\n# Get WAN interface IP address\r\
\n:set currentip [/ip address get [/ip address find interface=\$WANinterface] address]\r\
\n:set currentip [:pick [:tostr \$currentip] 0 [:find [:tostr \$currentip] \”/\”]]\r\
\n:log info (\”previous ip = \”.\$previousip.\”, current ip = \”.\$currentip)\r\
\n\r\
\n:if ([:len \$currentip] = 0) do={\r\
\n :log error (\”Could not get IP for interface \” . \$WANinterface)\r\
\n :error (\”Could not get IP for interface \” . \$WANinterface)\r\
\n}\r\
\n\r\
\n:if (\$currentip != \$previousip) do={\r\
\n :log info (\”Updating DDNS IPv4 address\” . \” Client IPv4 address to new IP \” . \$currentip . \”…\”)\r\
\n\r\
\n /tool fetch mode=http user=\$ddnshost password=\$key url=\”http://\$updatehost/nic/update\\\?hostname=\$ddnshost&myip=\$currentip\” \\\r\
\ndst-path=\$outputfile\r\
\n\r\
\n :log info ([/file get \$outputfile contents])\r\
\n /file remove \$outputfile\r\
\n :set previousip \$currentip\r\
\n} else={\r\
\n :log info (\”IP has not changed, no update necessary\”)\r\
\n}”
add name=he-tunnelbroker policy=ftp,read,write,policy,test,winbox,api source=”# Update Hurricane Electric tunnelbroker IPv4 address\r\
\n\r\
\n#make sure previousip is initialized with a value (0.0.0.0) before the script is first run\r\
\n:global previousip\r\
\n\r\
\n:local tunnelid \”TUNNEL_ID\”\r\
\n:local tunnelinterface \”TUN_INTERFACE_NAME\”\r\
\n:local user \”USERNAME_TUNNELBROKER\”\r\
\n:local pass \”PASSWORD_TUNNELBROKER\”\r\
\n:local updatehost \”ipv4.tunnelbroker.net\”\r\
\n:local WANinterface \”WAN_INTERFACE_NAME\”\r\
\n:local outputfile \”he-tunnelbroker.txt\”\r\
\n\r\
\n# Internal processing below…\r\
\n# ———————————-\r\
\n:local currentip\r\
\n\r\
\n# Get WAN interface IP address\r\
\n:set currentip [/ip address get [/ip address find interface=\$WANinterface] address]\r\
\n:set currentip [:pick [:tostr \$currentip] 0 [:find [:tostr \$currentip] \”/\”]]\r\
\n:log info (\”previous ip = \”.\$previousip.\”, current ip = \”.\$currentip)\r\
\n\r\
\n:if ([:len \$currentip] = 0) do={\r\
\n :log error (\”Could not get IP for interface \” . \$WANinterface)\r\
\n :error (\”Could not get IP for interface \” . \$WANinterface)\r\
\n}\r\
\n\r\
\n:if (\$currentip != \$previousip) do={\r\
\n :log info (\”Updating tunnelbroker client IPv4 address to new IP \” . \$currentip . \”…\”)\r\
\n\r\
\n /tool fetch mode=https user=\$user password=\$pass url=\”https://\$updatehost/nic/update\\\?hostname=\$tunnelid&myip=\$currentip\” \\\r\
\ndst-path=\$outputfile\r\
\n\r\
\n /interface 6to4 set \$tunnelinterface local-address=\$currentip\r\
\n\r\
\n :log info ([/file get \$outputfile contents])\r\
\n /file remove \$outputfile\r\
\n :set previousip \$currentip\r\
\n} else={\r\
\n :log info (\”IP has not changed, no update necessary\”)\r\
\n}”

Initialize previousip with the following command in the Terminal:

:global previous “0.0.0.0″

References:



iptables mangle and NAT notes, etc.

5 06 2010

PREROUTING in nat table: DNAT, REDIRECT
POSTROUTING in nat table: SNAT/MASQUERADE

PREROUTING in mangle table: alter routing (e.g. source-based routing)
FORWARD in mangle table: traffic shaping for tc (flowid)

In MikroTik RouterOS, /ip firewall nat:
srcnat chain = PREROUTING
dstnat chain = POSTROUTING

/ip firewall mangle:
prerouting chain = global-in
forward chain = global-out (support NAT traffic shaping, higher load on router)

Update: I used to think that global-in literally means global input, while global-out literally means global output.  Apparently I was mistaken.  The parent queues MUST be matched to the right parent, either global-in, global-out, global-total, or one of the network interfaces depending on the mangle rules.  Top-most queue parent (global-in, global-out, global-total) doesn’t decide whether it’s up/down.  The mangle rules do the direction decision trick, whether a packet is incoming/download or outgoing/upload.  This makes perfect sense now! (doh)  I kept wondering why half of my queues (download queues’ top-most parent was global-in) weren’t working, when all my mangle rules were in forward chain.  Obviously they wouldn’t, because global-in marks both direction in prerouting chain.

Update 2: mangle: download rules first then upload rules. global-in, connection mark: prerouting; packet mark: prerouting. global-out, connection mark: forward, packet mark: postrouting.

 

This didn’t make sense until I read the URL listed below under References.  Silly me!  Assumption is the root of most, if not all, problems indeed.

References:
http://wiki.ispadmin.eu/index.php/Documentation/Mikrotik_guide#.22Global-in.22_vs._.22global-out.22_setup



MikroTik simple script to update ZoneEdit Dynamic DNS

22 04 2010

I have a MikroTik router (RouterOS v4.x) with an ADSL connection at work, unfortunately it comes with dynamic public IP address.  I need to connect to my office workstation or simply the MikroTik router from home or elsewhere but I need to know its latest IP address all the time, so I decided to use ZoneEdit’s Dynamic DNS service.

Add a new script to the MikroTik router (replace those in bold):

  • /system script add name=zoneedit-dyndns source=”/tool fetch url=\”http://dynamic.zoneedit.com/auth/dynamic.html\?host=dyndns.example.com&dnsto=127.0.0.1\” user=ZEUser password=ZEPass keep-result=no\r\n/delay 30\r\n/tool fetch url=\”http://dynamic.zoneedit.com/auth/dynamic.html\?host=dyndns.example.com\” user=ZEUser password=ZEPass keep-result=no” policy=read

Test the script by running it manually:

  • /system script run zoneedit-dyndns

If it shows 2 lines of “status: finished”, then the script works properly.

Schedule the script to run regularly (in this case, every 10 minutes):

  • /system scheduler add name=”zoneedit-dyndns” interval=10m on-event=”/system script run zoneedit-dyndns” policy=read,test

Why does it require 2 “fetch” commands to update?  I think there is a bug in ZoneEdit’s Dynamic DNS updater, so it needs to be forced. The new dynamic DNS change entry has to be significantly different from the previous dynamic DNS entry before the ZoneEdit backend would really update it.

Thanks, ZoneEdit!



Reset MikroTik to default factory configuration

17 06 2008

Current MikroTik RouterBOARDs do not have a reset button (if you find a button on your RouterBOARD, it’s not the reset-to-factory-default button) to get it reset to the default factory configuration. User guides for each RouterBOARD, which MikroTik provides on routerboard.com, define the identifier and location of the reset mechanism. Hint: look for a distinct hole on the RouterBOARD and short-circuit it.

I will post some pictures when I get the time chance.

To reset RouterOS to the default configuration, execute the command /system reset-configuration. That should do the job. It will do a backup of the current configuration prior to the reset (how convenient!), in case you change your mind and possibly prevent accidental resets.



MikroTik RouterOS Interface Bonding

5 01 2008

I have two separate Metro Ethernet links (via fiber optic) from the datacenter to the NOC. Each link is 10Mbps. I need to utilize both links (bonding) and make sure sure that if one of the links goes down (redundancy), I won’t lose half of my packets. Bonding and redundancy are my goals.

Initially I tried Cisco Catalyst’s EtherChannel feature to accommodate this need since I learned about EtherChannel when I was doing my CNAP. Unfortunately EtherChannel cannot fit in this scenario due to my Metro Ethernet provider’s network setup. They use Cisco Catalyst 3750 switches to aggregate customers links from each POP to their headquarters. My first attempt was to establish trunk mode EtherChannel (802.1q) with Cisco Catalyst 2950 on one side and Cisco Catalyst Express 500 on the other side. Later I noticed that this is not doable since trunking requires MTU size to be larger than 1500 (1504) when my provider strictly limits MTU size to 1500 and negotiation between my 2 switches to establish trunking wouldn’t work since my switches’ BPDU packets are “intercepted” by my provider’s switches. Basically my Cisco switches were trying to establish a VLAN trunk with my provider’s directly connected switches when my switches are  supposed to be negotiating to each other.

I consulted a few experienced people including an employee of the provider, and they told me to use access mode EtherChannel instead of the trunk mode EtherChannel. This is not possible with Cisco Catalyst Express 500, which only offers trunk mode EtherChannel. I bought a Cisco Catalyst 2960 to replace the Cisco Catalyst Express 500 hoping that access mode EtherChannel would work, it didn’t. Even if it did work, it wouldn’t be aware of link state changes since my switches do not connect directly to the fiber cables. There is a fiber-to-ethernet bridge for each side of each link, so my switches will always detect both links as always up as long as the bridges are up.

Since link states cannot be used as a measurement in this scenario, I had to find another way. MikroTik RouterOS offers not only bonding feature, but fail-over mechanism too! The fail-over mechanism uses ARP packets to detect link failures, it is far from perfect but at least it works.

I will add examples later, but for now have a look at this. Hopefully I will discuss EoIP and EoIP over PPTP too.

References:
http://www.mikrotik.com/testdocs/ros/3.0/interface/bonding.php



PPPoE Server HOWTO for MikroTik RouterOS 2.9

29 05 2007

If you wish to run a PPPoE server, MikroTik RouterOS provides a convenient way to set one up in a few minutes (with built-in traffic shaping feature too!). Previously I used Fedora Core for my PPPoE servers, but I couldn’t find a working solution to keep ghost PPPoE sessions from bogging down my Linux server. I tried MikroTik DOM with RouterOS to replace my Linux-powered PPPoE servers, so far the results are very good.

Below is a mini guide that may be able to help you get your PPPoE server running in a few minutes using RouterOS.

First, make sure that your RouterOS server’s WAN connectivity has been properly configured. Remember that you need at least 2 network interface cards (NICs). This guide assumes that both NICs are ethernet — ether1 and ether2. If you haven’t set anything up on the new system, let me help you with the checklist: (based on my experience, the following issues are the most common)

  • Make sure that the Internet-facing NIC has an IP address assigned on it and the default gateway is set (/ip route add gateway=…)
  • If NAT is used, ensure that src-nat/masquerade firewall rule has been added (/ip firewall nat …) and it is working properly

Once you have verified the server’s connectivity, create a PPP profile (/ppp profile add name=”pppoe-profile” local-address=10.1.1.1 dns-server=… rate-limit=128k/128k). Every user account that uses this profile will get 128Kbps upload and download limit. If you wish to have different types of accounts (for example some customers pay for 256Kbps), create a new PPP profile (change the rate-limit attribute).

Next, create a user account assigned to the new PPP profile (/ppp secret add name=”andryan” password=”test” service=pppoe profile=”pppoe-profile” remote-address=10.1.1.2). When this user logs in successfully, this user gets assigned 10.1.1.2. To dynamically assign IP addresses, there is an example here.

Finally, create a PPPoE server instance (/interface pppoe-server server add service-name=”pppoe1″ interface=ether2 one-session-per-host=yes default-profile=”pppoe-profile”) and enable it. Now your RouterOS PPPoE server is ready to answer PPPoE requests and authenticate your PPPoE clients. :)

Good luck!

References:
http://www.mikrotik.com/testdocs/ros/2.9/interface/pppoe.php



MikroTik RouterOS — BGP

4 05 2007

I have always wanted to learn about BGP. This time I got the honor chance to implement BGP for an ISP. This ISP has its own AS number and a /21 IP address block. This BGP setup is pretty simple because I’m only using 1 PC (with 3 ethernet cards and a MikroTik’s level 4 DOM) to interconnect with an Internet Exchange (IX) — NiCE — and a transit ISP (another transit will be added soon).

In MikroTik RouterOS version 2.9.42, BGP features are available for level 3 and above. You also need to enable routing-test package if you want more flexibility (BGP filtering features). The routing package, as of this version, only allows basic BGP features. I’m sure this will change later when they release RouterOS v3. Once you have enabled routing-test package, you will see new options (Routing – Filters in winbox, or /routing filters on CLI). This is very important when you have to peer with 2 or more ASes (specifically an IX and a transit which is not interested in getting IX’s routes for obvious reasons).

Since I have never configured BGP before, I caused a major problem when routes from each peer goes to another peer when they shouldn’t! I didn’t place any filter for BGP advertisements my BGP router sends to its peers. My transit ISP received the IX’s routes and the IX received full Internet routes feed my BGP router gets from the transit ISP. BGP is an exterior distance-vector routing protocol, it picks its best path by comparing the AS path lengths of every route it has. Advertising the whole Internet BGP feed to the local IX caused other ISPs’ routers participating in the IX to discover a shorter path of international routes going via my BGP router so the routers chose this new shorter path instead and outgoing traffic of these ISPs started to flow via my transit ISP! On the other hand, advertising IX routes to my transit was not a big problem since the path will be farther for their customers anyway, having to go via my BGP router first (that’s one AS further for the transit ISP’s customers to reach the IX routes, so BGP will not select it).

Fortunately I was able to spot the error immediately and placed BGP routing filters to include only my /21 IP block in the advertisements my BGP router sends to both the IX and transit. I also added an incoming BGP filter to discard a default route my transit IP includes in its BGP feed. This default route is not required since I get full BGP feed that is unfiltered.

Useful links:
http://www.mikrotik.com/testdocs/ros/2.9/routing/bgp.php
http://www.mikrotik.com/testdocs/ros/2.9/routing/filter.php
http://wiki.mikrotik.com/wiki/BGP_Case_Studies_1 — Route filters examples
http://wiki.mikrotik.com/wiki/Using_scope_and_target-scope_attributes — Important! Make sure that BGP neighbors are reachable via static routes for dynamic routes to be active (in the case of multihop BGP neighbors)
http://wiki.mikrotik.com/wiki/BGP_soft_reconfiguration_alternatives_in_RouterOS
Cisco’s BGP Reference