VLAN tagging on Mikrotik RouterOS 6

Mikrotik doesn’t have quite the same brand recognition as the bigger players in the SOHO networking space, so it’s a bit of a surprise that Mikrotik has some of the most feature-rich network appliances under $200. I’m not aware of anything else that acts a layer-3 switch, provides console access, and has the same granular control for the price.

However, the one and only downside of this is that they hide all of these features in the most counter-intuitive interface possible. There are no less than three unique sections to edit in order to successfully VLAN-tag an interface in the Mikrotik CLI, and it will silently fail if you omit one of them (!).

Ultimately, my goal is to trunk multiple VLANs between my existing Cloud Router switch in my basement to the five-port RB750Gr2 acting as a switch in my office, so I can move my NTP server (and subnet) upstairs next to the window with good GPS reception. In Mikrotik parlance a ‘trunk’ port is an aggregation port a la 802.3ad, so for clarity’s sake the instructions below are for creating dot1Q trunks.

Some notes:
– You should have an existing, working VLAN configuration on the switch.
– I’m using a RB750G configured as a simple switch on the other end, with no VLANs configured.
– CRS-125-24G connecting to RB750Gr2, Mikrotik RouterOS 6.40.1 on both devices

STEP 1: Take a backup!

[admin@MikroTik] /> /system backup save name=crs125-24G_20170817
Saving system configuration
Configuration backup saved

a. Download this backup from the web GUI, in the ‘Files’ section

STEP 2: Configure free interface ‘ether24’ on the Cloud Router switch

a. Using ‘ether24’ as the interface in this example, make a comment so you know what the hell it is in six months.

/interface ethernet comment ether24 comment="upstairs. vlan10 vlan100 vlan123"

b. Ensure ‘network-port’ (default) is set for the port

[admin@MikroTik] /interface ethernet switch port> set ether24 vlan-type=network-port

c. Add egress-vlan-tag tagged-ports entries for ether24

[admin@MikroTik] /> /interface ethernet switch egress-vlan-tag print
Flags: X - disabled, I - invalid, D - dynamic
 #   VLAN-ID TAGGED-PORTS
 0       100 ether1-master
             ether24
             switch1-cpu
 1        10 ether1-master
             ether24
 2       200 ether2
 3       299 ether2
 4       999 ether2
 5       123 ether1-master
 6 D    4095

[admin@MikroTik] /> /interface ethernet switch egress-vlan-tag set numbers=0 tagged-ports=ether1-master,ether24,switch1-cpu
[admin@MikroTik] /> /interface ethernet switch egress-vlan-tag set numbers=1 tagged-ports=ether1-master,ether24
[admin@MikroTik] /> /interface ethernet switch egress-vlan-tag set numbers=5 tagged-ports=ether1-master,ether24
[admin@MikroTik] /> /interface ethernet switch egress-vlan-tag print

Flags: X - disabled, I - invalid, D - dynamic
 #   VLAN-ID TAGGED-PORTS
 0       100 ether1-master
             ether24
             switch1-cpu
 1        10 ether1-master
             ether24
 2       200 ether2
 3       299 ether2
 4       999 ether2
 5       123 ether1-master
             ether24
 6 D    4095

d. Edit the interface to vlan-id mapping. Output looks like this:

[admin@MikroTik] /interface ethernet switch vlan> print
Flags: X - disabled, I - invalid, D - dynamic
 #   VLAN-ID PORTS             SVL LEARN FLOOD INGRESS-MIRROR QOS-GROUP
 0        10 ether1-master     no  yes   no    no             none
             ether14
             ether15
             ether16

Use this command to edit the ‘#’ column in a nano-like editor, and add ‘ether24’ at the end. Ctrl+o to save and quit. Where ‘#’ column is ‘0’:

[admin@MikroTik] /interface ethernet switch vlan> edit 0 ports

Add ether24 to all vlan-ids required, using the above steps.

At this point the Cloud Router switch is ready to trunk via ether24! Now we have to set up the RB750G to accept and de-encapsulate the VLANs.

STEP 3: Configure the RB750G

This part is a bit tricky. I think it’s easiest to dump my working config so you can get an idea of what’s going on, and modify to suit your environment.

Note that I have my RB750G mgmt interface (switch1-cpu) tied to my management VLAN (vlan100), so it requires some magic to get working without a console connection. I set up two IP addresses and used a direct connection from a laptop to the RB750 to configure the second VLAN-enabled mgmt connection. Once you cut over the switch1-cpu port config to ‘secure’ VLAN type, you lose connectivity to the device if your configs are incorrect. Note to self: Get networking devices with a console connection.

Additionally, I stripped out all of the routing configs and reconfigured the ‘interface ethernet’ ports to all utilize ether1 as the master, renaming it from ‘ether1’ to ‘ether1-master’, and renaming ‘ether2-master’ to ‘ether2’.

Take backups often during configuration, as it is easy to lock yourself out without a console connection. If that happens, just restore default configs and restore the last good backup.

# aug/18/2017 23:36:18 by RouterOS 6.40.1
/interface ethernet
set [ find default-name=ether1 ] name=ether1-master
set [ find default-name=ether2 ] master-port=ether1-master
set [ find default-name=ether3 ] master-port=ether1-master
set [ find default-name=ether4 ] master-port=ether1-master
set [ find default-name=ether5 ] master-port=ether1-master
/interface vlan
add interface=ether1-master name=ether1-vlan10 vlan-id=10
add interface=ether1-master name=ether1-vlan100 vlan-id=100
add interface=ether1-master name=ether1-vlan123 vlan-id=123
/interface ethernet switch port
set 0 vlan-header=add-if-missing vlan-mode=secure
set 4 default-vlan-id=10 vlan-header=always-strip vlan-mode=secure
set 5 vlan-mode=secure
/ip hotspot profile
set [ find default=yes ] html-directory=flash/hotspot
/interface ethernet switch vlan
add independent-learning=yes ports=ether1-master,ether5 switch=switch1 vlan-id=10
add independent-learning=yes ports=ether1-master,switch1-cpu switch=switch1 vlan-id=100
add independent-learning=yes ports=ether1-master,ether4 switch=switch1 vlan-id=123
/ip address
add address=10.3.100.5/28 comment=vlan100_mgt interface=ether1-vlan100 network=10.3.100.0
/ip dns
set servers=10.3.100.1
/ip route
add distance=1 gateway=10.3.100.1
/system clock
set time-zone-name=America/Detroit
/system ntp client
set enabled=yes primary-ntp=10.3.123.2

STEP 4: Take final backups

/system backup save

References:
Mikrotik VLAN
My initial VLAN trunk adventure from 2016
802.1q trunking on Mikrotik router/switch (StackExchange)
Cloud Router Switch CRS125-24G-1S
hEX v3 router

Shorewall DDNS script

Since running Shorewall on my APU2c4 running a EL distro, I found myself replicating all of the built-ins that were present in other all-in-one projects such as pfSense or openWRT. Here’s one of my quick scripts to replace some of that functionality. This checks and updates my domain’s DNS from my Shorewall router hourly.

It performs a check of the IP reported by my domain’s resolver against the IP of my default gateway, and updates using the DDNS URL if necessary.

Notes:
– Not tested against IPv6 or complex routing scenarios!
– Place in /etc/cron.d/hourly or /etc/cron.d/daily
– The DDNS_QUERY var is highly dependent on your DDNS provider, adjust as necessary


#!/bin/bash
# Simple Dynamic DNS Script
# - Use-case: UNIX-based server acting as front door router
# - Performs comparison between domain A versus default gw
# - Not tested with IPv6 or complex routing scenarios (dual WAN, etc.)

DOMAIN="YOUR_DOMAIN"
RESOLVER="YOUR_DOMAINS_DNS_RESOLVER" # dig $YOUR_DOMAIN ns

DNSIP=$(dig +short @${RESOLVER} ${DOMAIN}) # get IP address of domain from resolver
WANIP=$(ip route get 1 | awk '{print $NF;exit}') # get IP address of default gateway

DDNS_URL='YOUR_URL'
DDNS_PASS='YOUR_PASS'
DDNS_HOST='YOUR_HOST' # the host record (TLD, '@', etc)
DDNS_QUERY="update?host=${DDNS_HOST}&domain=${DOMAIN}&password=${DDNS_PASS}&ip=${WANIP}"

DNSIP=$(dig +short @${RESOLVER} ${DOMAIN})
WANIP=$(ip route get 1 | awk '{print $NF;exit}')

#echo ${DNSIP}
#echo ${WANIP}

if [ "${DNSIP}" != "${WANIP}" ]; then
curl --silent "${DDNS_URL}/${DDNS_QUERY}" 2>&1 1>/dev/null
fi

Flash BIOS of APU2c4

Updated for March 2017 BIOS

I recently purchased the latest version of the venerable PCEngines APU: the apu2c4.

The coreboot BIOS is still WIP, and the device I received had BIOS version 160307. I need PXE or iPXE support to kickstart CentOS 7.2, and luckily the latest BIOS version available (160311) supports iPXE.

Here is my rough guide to flash the APU2c4 BIOS, using Fedora 23 to make a flash drive.

sudo dnf install syslinux
# insert flash drive; find physical address
lsblk
# assuming flash drive is /dev/sdb
# WARNING CONFIRM LETTER OF FLASH DRIVE DO NOT COPY+PASTE

sudo parted /dev/sdb mklabel msdos
sudo parted /dev/sdb mkpart primary fat16 2048s 2G
sudo mkfs.vfat /dev/sdb1
sudo dd if=/usr/share/syslinux/mbr.bin of=/dev/sdb
sudo syslinux --install /dev/sdb1
sudo parted /dev/sdb set 1 boot on
cd ~; mkdir temp
sudo mount /dev/sdb1 temp/
cd temp/
sudo wget http://pcengines.ch/file/apu2-tinycore6.4.tar.bz2
sudo wget https://www.pcengines.ch/file/apu2_v4.0.7.rom.zip
sudo tar --no-same-owner xvf apu2-tinycore6.4.tar.bz2
sudo unzip apu2_v4.0.7.rom.zip
sudo rm -vf apu2-tinycore6.4.tar.bz2 apu2_v4.0.7.rom.zip
cd ..
sudo umount ./temp

# unplug flash drive from computer
# plug flash drive in to apu
# attach usb keyboard to apu
# power on apu

# press f10
# boot from usb drive
# you may notice some errors about autostart.sh and FAT partition, safe to ignore

lsblk 
NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sdb      8:16   1  14.8G  0 disk 
`-sdb1   8:17   1   1.9G  0 part /media/usbhd-sdb1

cd /media/usbhd-sdb1
flashrom -p internal -w apu2_v4.0.7.rom

# reboot after completion
# power on, press f10, choose iPXE

dhcp
chain http://10.3.2.1/ipxe/boot.ipxe

# proceed with iPXE goodness

Some additional reading and references:
http://www.yeasoft.com/site/article:apup1
http://pcengines.info/forums/?page=post&id=4F6D1B63-9BB7-4743-8FC8-6FF14532884A

APU1C4 serial to usb console

During an upgrade from pfsense 2.1.5 (FreeBSD 8) to pfsense 2.2 (FreeBSD 10), my AMD APU router became unresponsive using tools such as ping and ssh. It required connecting via serial console. Here’s a quick overview.

Model number of the board: PCEnginges APU1C4 T40E
USB to male serial: TRENDnet USB to RS-232 DB9 Serial Converter
Null model cable: DB9 RS232 Serial Null Modem Cable F/F (SCNM9FF)
Build reference: Unpacking and Assembling PC Engines APU

I have an older Lenovo Thinkpad T400 acting as a server running CentOS 7 that provides lightweight services such as DHCP, DNS, and iPXE to my LAN. To gain access to the router’s console, I plugged in the serial converter above to the Thinkpad and attached it to the null-modem cable that was hooked up to the router.

I verified on the laptop that everything was detected via dmesg | tail -10 and ls -l /dev/ttyUSB?, which showed the following:

$ dmesg | tail -25
[4643071.873119] usb 6-2: new full-speed USB device number 2 using uhci_hcd
[4643072.019109] usb 6-2: New USB device found, idVendor=067b, idProduct=2303
[4643072.019119] usb 6-2: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[4643072.019126] usb 6-2: Product: USB-Serial Controller D
[4643072.019131] usb 6-2: Manufacturer: Prolific Technology Inc.
[4643072.128738] usbcore: registered new interface driver pl2303
[4643072.128766] usbserial: USB Serial support registered for pl2303
[4643072.128785] pl2303 6-2:1.0: pl2303 converter detected
[4643072.140519] usb 6-2: pl2303 converter now attached to ttyUSB0

$ ls -l /dev/ttyUSB?
crw-rw----. 1 root dialout 188, 0 Jan 24 17:59 /dev/ttyUSB0

To connect to the console, I used the following command:

screen /dev/ttyUSB0 115200

From there I was able to troubleshoot and debug as necessary on the pfsense shell.

cmd.exe replacement in Windows 7/8

As someone who bounces back and forth between Windows, Mac OS X, and Linux, one of the most consistently frustrating aspects of Windows is the lack of decent terminal emulation support. I’ve always been a fan of the simplicity of cygwin+mintty but it has always been lacking tab functionality along with a few other nice-to-haves – especially when compared with a more evolved terminal emulator in Gnome or OS X. A coworker recently pointed me in the direction of ‘cmder’, a conemu repackage that pre-configures a lot necessary settings to make the user experience more streamlined. cmder-mini is a portable version of the program – all settings and data are confined to the directory it is extracted to. My goal was to configure something lightweight and that rivals mintty, Console2, and ConsoleZ in terms of both usability and features.

Please note the main focus when I use terminal emulation on Windows is connecting from my windows host to a remote UNIX server, so Powershell and cmd.exe integration are not covered here (although they work out of the box). I also don’t care about most basic Linux binaries within Windows, besides the fact that they perform horribly due to the missing fork() functionality. I just need something that supports SSH and bind-utils natively.

https://github.com/bliker/cmder/releases/download/v1.1.1/cmder_mini.zip
http://cygwin.com/setup-x86_64.exe

Requirements:

  • Cygwin with openSSH and bind-utils, cmder-mini zip file

Install cygwin, extract cmder-mini to desired location, open ‘Cmder.bat’, right click on taskbar, ‘Settings’

Default shell of Cygwin bash:

  • Startup -> Tasks: Click ‘+’
  • Name: ‘cygwin-bash’
  • Task Parameters: ‘/dir “C:cygwin64home<user>”‘
  • File Path…: ‘C:cygwin64Cygwin.bat’
  • Startup: Specified Named Task: ‘{cygwin-bash}’

Ctrl+T to create a new tab, select ‘cygwin bash’ as shell, and away you go…

 

cmder

 

### Tab manipulation

* `Ctrl + t` : new tab dialog (maybe you want to open cmd as admin?)
* `Ctrl + w` : close tab
* `Ctrl + alt + number` : fast new tab: `1` – CMD, `2` – Powershell `*` – More to come
* `Alt + enter`: Fullscreen

### Shell

* `Shift + Up` : Traverse up in directory structure (lovely feature!)
* `End, Home, ctrl` : Traversing text with as usual on Windows
* `Ctrl + r` : History search
* `Shift + mouse` : Select and copy text from buffer

 

I’m sure there are tons of other options to configure to make this shinier, but this basic configuration should get anyone looking to connect to a remote host via SSH using tabs (!!!) off to a good start.

Edit: So I discovered that it’s impossible to pin a shortcut to a batch file onto the Windows 7 taskbar.  Here’s a workaround:

  • Right click on ‘Cmder.bat’ and select ‘Send To -> Desktop’
  • On Desktop, right click on ‘Cmder.bat – Shortcut’ and select ‘Properties’
  • Change target to ‘cmd.exe /C “C:pathtoCmder.bat”‘, select ‘OK’ (change name here too if desired)
  • Drag edited shortcut to Taskbar