World of networks

TP-Link's Idea of Security

Illustration

My wired network finally got too big for a single router so I decided to get myself a switch.

I realistically needed the dumbest switch there is - just 4 gigabit ports and I would be happy. Thus my eyes were immediately drawn to TP-Link SG105 at $20 on Amazon. However, for only $10 more I noted one could get SG105E. The exactly same switch but with a basic manageability features.

Both switches look exactly the same in their steel shell. They are well built and my impression is they can take a beating. You can get inside the chassis by simply undoing two screws and you will see a really simple board. Based on the components, I don’t think you can get much over 1 Gbps on its bus and thus forget about actually reaching maximum speed when all ports are in use - acceptable compromise for home I guess. I would say 9V power supply is the only thing that actually looks cheap. Fortunately, switch works without any noticeable issues on much more common 12V too (albeit you probably forfeit warranty if you do that).

So, what do you get for extra money? Well, you get DSCP, a QoS priority system nobody seems to use in general and definitely not intended for home network. There is also rate limiting with a storm control. Probably not often needed at home but can be quite useful for troubleshooting naughty device.

Further more you get support for up to 32 VLANs - quite nice if your home network needs a bit of separation. Lastly you will also find more “enterprisey” features like port mirroring and link aggregation. Never figured why you need something like this on 5-port switch but I guess it doesn’t hurt to have them.

The most useful feature, and the reason I decided to give extra tenner was the GUI. From GUI you can easily see if your cable is connected, whether packets are flowing, and are there any transmission errors. Usually home switches and routers have ugly interface so I was ready for that. What I wasn’t ready for is abysmal security.

Let’s start with a good thing - you can change user name. Security-wise, that is probably the best thing you can do in your network to escape 95% automated attacks. Yes, this won’t help much if someone is “out to get you” but most script kiddies will be thwarted. And that’s as far as security goes for this device.

To start with, your password is restricted to English alphabet, digits, and underscore (_) sign. Restricting the length and character set is not significant just because it lowers number of combinations your password can take. I am sure you are using password manager and even these weak rules should give you years of good sleep if password is hashed.

But, if they used hashed passwords in the first place, they wouldn’t need character set restrictions. These restrictions are almost always a signal your password is saved in a clear-text. Combined with the login screen allowing for infinite number of guesses at unthrottled speed, and you have the whole security tumbling down.

But don’t worry anybody will brute force this device. Nope - there is no need as you can simply snoop all communication as there is no support for HTTPS. Everything you do on its web interface is for everybody to see. They didn’t even bother to do a simple digest authentication. Nope, all is sent in clear text.

For $20 it is hard not to recommend base model of this switch. It is sturdy, cheap, and reasonably performant. Unfortunately, for only $10 more you can get a device performing the same base function but with a woefully insecure user interface.

I would stick with unmanaged model.

Configuring Classless Static Route Option

If you want to push routes to your client, the easiest way to do so would be adding a classless static route (DHCP option 121) as defined in RFC 3442. Every router has their way of setting these but usually they have one thing in common - you must do so manually. And yes, if you make a single mistake, your Internet connectivity will be lost.

Issue of easy entry has bothered me for long enough to actually do something about it. Below find classless static route option calculator. Just enter routes you want and you will get their hexadecimal representations.

NetworkGateway
Default
DHCP option 121:
OpenSense/Ubiquiti notation:
Mikrotik code:

[2019-12-13: Updated script to have default route first (workaround for Ubuntu 19.10 Server).] [2020-12-26: Added OpenSense/Ubiquiti notation.] [2022-07-22: Fixed to allow for /32 network.]

Let's Encrypt on Linode CentOS 7

Having your web server running on Linode is just a first step. No installation is complete without HTTPS. So I turned to Let’s encrypt and official Certbot instructions.

Albeit, it was not meant to be. Official procedure always resulted in No package certbot-apache available error. So I went with slightly alternate approach:

yum install -y epel-release
yum install -y certbot-apache

Assuming your httpd.conf contains something like this

<VirtualHost *:80>
    ServerName ^^www.example.com^^
    ServerAlias ^^example.com^^
    DocumentRoot "/var/www/html/"
</VirtualHost>

All you need is to run certbot for the first time. Of course, do try staging environment first:

certbot --apache -d ^^example.com^^ -d ^^www.example.com^^ --staging

This will create file at /etc/httpd/conf/httpd-le-ssl.conf that will have your SSL configuration. If you prefer to have all your configuration visible together, you can go ahead and copy it back into httpd.conf with the following result:

<VirtualHost *:443>
    ServerName ^^www.example.com^^
    ServerAlias ^^example.com^^
    DocumentRoot "/var/www/html/"
    Include /etc/letsencrypt/options-ssl-apache.conf
    SSLCertificateFile /etc/letsencrypt/live/^^example.com^^/cert.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/^^example.com^^/privkey.pem
    SSLCertificateChainFile /etc/letsencrypt/live/^^example.com^^/chain.pem
</VirtualHost>

Once you are happy with configuration (remember we are using the staging configuration at this time), you can get a proper production certificate. I personally don’t like my httpd.conf touched so I like to go with alternative “webroot” verification. As our staging certificate is fairly new, we need to force renewal.

certbot certonly --cert-name ^^example.com^^ --webroot --webroot-path /var/www/html/ --post-hook "apachectl graceful" --force-renew

To keep certificate up-to-date, we need to add following line that will attempt recertification twice a day (as recommended):

42 7,19 * * * certbot renew --cert-name ^^example.com^^ --webroot --webroot-path /var/www/html/ --post-hook "apachectl graceful"

Now you can enjoy your encrypted website in its full glory.

Internal Domain Name

Illustration

For the longest time anything was a good internal domain name. Yes, obviously you avoided .com, .net, .org, and other usual suspects but anything else was quite OK. While some people did go distance on this, most of networks sort-of settled on .local or .lan. And all was nice and dandy.

However, lately two things have happened lately to mess with fairy tale. First was of course that ICANN smarties decided to create a zillion new top-level domains. And then there was Apple and their kidnapping of .local suffix for the purpose of mDNS.

Just like that people found Apple devices no longer playing nicely on .local domain and all other domains got big on-sale sign with a potential for collision down the road. There was an RFC with a few reserved domain names but neither one of those actually fits the local LAN setup. And yes, there were some attempts at properly reserving the few most common domains (e.g., .lan, .home, .corp, …) but that RFC never went anywhere.

And ICANN did try to sell all three most common local names already but found itself in a bit of a bind due to a high usage of these domains in households and companies alike. Just imagine a mess some company’s network could be in if .corp gets delegated and someone buys login.corp domain. While ICANN has slowed process a bit for the most conflicting domains due to the security report, spammers are pushing to get those domains on market.

As a general rule, the only sure way not to have your domain clash with newly introduced spam domains is actually to buy your own domain. Even if you don’t want to ever have a website, you need to get a domain. I find this solution annoyance and a mini money grab at best. However, this seems to be the only sure way spammers won’t get to resolve your DNS requests. That is until you forget to renew the domain.

I personally have settled on .home for now for my own network. Based on the DNS query stats for the undelegated domains, it is among top 3 most abused domains and thus it is unlikely it will be sold for use as top domain without many feathers being ruffled. That should allow me enough time for the migration to some other domain.

Adding Domain Search Option to Mikrotik DHCP

Illustration

I already wrote about using Mikrotik’s DNS to resolve a short name lookup in Windows. And there I noted that domain-name DHCP option seemingly has no effect on Linux. Well, let me introduce you to domain search option.

Most of the Linux/Unix based operating systems, whether it is Linux, FreeBSD, or MacOS support arguably a more proper way to define which domain we are referring to when using a single word host name.

To define suffix for domain search, just add option 119:

/ip dhcp-server option
add name="domain-search-option" code=119 value="'^^example^^'"

And of course add this option to DHCP network:

/ip dhcp-server network
set 1 dhcp-option=domain-search-option

PS: And no, you cannot use this instead of domain-name. Windows clients only support domain-name while Linux/Mac only supports domain-search option.

Using Mikrotik DHCP to Disable NetBIOS Over TCP/IP

If your network is a bit too chatty and you decide to go without NetBIOS, that is easy to do if you have Windows Server. A click or two will get you there. Fortunately, if you have your DHCP server on Mikrotik, it is not much more difficult.

First we need to create Microsoft Disable NetBIOS Option itself:

/ip dhcp-server option
add code=43 name=microsoft-disable-netbios-option value=0x010400000002

And then we simply assign it to given DHCP network:

/ip dhcp-server network
set 1 dhcp-option=microsoft-disable-netbios-option

To verify, simply use ipconfig on windows computer:

ipconfig /all
 …
   NetBIOS over Tcpip. . . . . . . . : Disabled

PS: Do note that really old client computers (e.g. Windows 2000) will have issues with network browsing.

Whitelisting on CAPsMAN

I love Mikrotik’s CAPsMAN. A beautiful way to control and automatically provision wireless interfaces over multiple Mikrotik routers.

It is not perfect - one of the more annoying absences is the default channel list (albeit you can create your own channels) and lack of the whitelisting for the AP clients. Unlike with the standard Mikrotik interface, you cannot simply make configuration where registrations would be disabled by default.

However, there is one nice trick you can do. Under CAPsMANConfigurations adjust VLAN Mode to use tags and set VLAN ID to some unused number (my favorite is 4094). This will cause all wireless traffic using that configuration to be tagged with otherwise unconfigured number. In effect we are blackholing all the traffic with that VLAN ID.

Now under CAPsMANAccess List you can add any allowed client with VLAN Mode set to “no tag” (or, if you are using VLANs, to a configured VLAN ID). This will override setting from the configuration and thus only devices explicitly listed will have their packets processed.

I admit, it is not as flexible as rejecting registration but absence of any communication is usually a good signal that one needs to move to another network.

PS: Whitelisting AP clients doesn’t necessarily improve your security. Do not rely on it as a security feature.

Creating Mikrotik's VPN Certificates With OpenSSL

What would be use of having your own certificate authority if one couldn’t use it to create Mikrotik-compatible OpenVPN or SSTP certificates?

Since we are our own CA we always start with creation of certificate signing request. For server certificate just take care CN matches whatever external domain you will be using to access your router (important for SSTP). All other values fill (or leave blank/default) at will:

openssl req -new -key server.key -sha256 -out server.csr
 Country Name (2 letter code) [AU]: .
 State or Province Name (full name) [Some-State]: .
 Locality Name (eg, city) []: .
 Organization Name (eg, company) [Internet Widgits Pty Ltd]: .
 Organizational Unit Name (eg, section) []: .
 Common Name (e.g. server FQDN or YOUR name []: *.example.com
 Email Address []:`` ^^.^^

Well, now we can use this request against a CA to get ourselves a sweet signature. For my case, I have a ghetto CA setup so all signing will be done in a single albeit a bit long line. Notice I manually specify the key usage - important for OpenVPN:

openssl x509 -req -CA ca.cer -CAkey ca.key -set_serial 0x$(openssl rand -hex 16) -days 3650 -extfile &lt;(echo -e "keyUsage=digitalSignature,keyEncipherment\nextendedKeyUsage=serverAuth") -in server.csr -out server.cer

A few password prompts later and we have ourselves a signed server certificate.

Now we need to repeat these steps with a slight modification if a client certificate is needed too. Essentially the only difference is in key usage and common name:

openssl req -new -key client.key -sha256 -out client.csr
 Country Name (2 letter code) [AU]: .
 State or Province Name (full name) [Some-State]: .
 Locality Name (eg, city) []: .
 Organization Name (eg, company) [Internet Widgits Pty Ltd]: .
 Organizational Unit Name (eg, section) []: .
 Common Name (e.g. server FQDN or YOUR name []: client.example.com
 Email Address []: .
openssl x509 -req -CA ca.cer -CAkey ca.key -set_serial 0x$(openssl rand -hex 16) -days 3650 -extfile &lt;(echo -e "extendedKeyUsage=clientAuth") -in client.csr -out client.cer

Once done and copied to router, on Mikrotik we only need to import CA, server and client certificate along with server’s private key:

/certificate import
 passphrase: ***********************************
      certificates-imported: 3
      private-keys-imported: 1
             files-imported: 3
        decryption-failures: 0
   keys-with-no-certificate: 0

Once imported we only need to adjust VPN server setup in PPP menu on Mikrotik and configure our clients as discussed in previous posts (OpenVPN/SSTP).

Mikrotik Configuration Backup

For start, I will assume that SSH user with appropriate rights is already configured as described in one previous blog post. From there getting Mikrotik’s configuration is easy:

ssh backup@192.168.88.1 "/export"

However, there are a few things wrong with it. First of all, all lines end with CRLF instead of more conventional LF (at least in the world of Linux/Unix). Fortunately this is easily fixed:

ssh backup@192.168.88.1 "/export" | tr -d '\r'

Next you will notice that exported config has a line continuation character (\) on its longer lines. While this is nice for viewing config, if we are to automatically process result with diff it is better to have each configuration line on its own. Getting Mikrotik to stop wrapping lines under all terminals is pretty much impossible, even using the +t4200w trick. However, sed can do wonders with enough cryptic code:

ssh backup@192.168.88.1 "/export" \
  | tr -d '\r' \
  | awk '{sub(/^ +/, "", $0); if (sub(/\\$/,"")) printf "%s", $0; else print $0}'

And finally, you might notice there is a time on top of the exported script. This, usually a handy information, will cause any automatic diff to always find a difference. So, removing it is in order:

ssh backup@192.168.88.1 "/export" \
  | tr -d '\r' \
  | awk '{sub(/^ +/, "", $0); if (sub(/\\$/,"")) printf "%s", $0; else print $0}' \
  | sed "s/^#.* by RouterOS/# RouterOS/"

With this we have a nice, repeatable, and diff-friendly configuration exported.

PS: If you are wondering why I am not using dos2unix, it is because I wanted code to run on NAS4Free that has quite restricted command line.

Cleaning Chrome DNS Cache

Illustration

While playing with Mikrotik’s DNS I accidentally made a regular expression statement overly broad. Error was clear: I had “ana” in the DNS Rexexp field instead of “^ana$”. What this simple error did was to resolve everything with ana in the name to the machine on local network. I noticed that when I tried to access http://anandtech.com and got a timeout.

I fixed the erroneous entry and all was good when I checked it manually with nslookup. However, I still couldn’t access the web site. Interestingly, if I tried using Internet Explorer instead of my favorite Chrome, access worked. Yep, Chrome has its own internal DNS cache.

Cleaning Chrome’s cache is reasonably easy. Only thing needed is a visit to chrome://net-internals/#dns and hitting the Clear host cache button. However, my local erroneous address was back as soon as I tried accessing the site again.

Interestingly Windows themselves have also cached the incorrect IP address. Chrome using Windows API to resolve DNS name was catching the wrong one. Internet Explorer was unaffected as it made DNS query directly. Curious choices. :)

Cleaning Windows cache involved getting to elevated prompt. My favorite way is hitting Win+X and selecting Command Prompt (Admin) from the menu. Once in the prompt, we just execute:

ipconfig /flushdns
 Windows IP Configuration
 Successfully flushed the DNS Resolver Cache.

With this (and clearing Chrome’s cache again) I could browse anandtech.com again.

PS: For curious, Mikrotik supports extended POSIX regular expressions.