Starbeamrainbowlabs

Stardust
Blog


Archive

Mailing List Articles Atom Feed Comments Atom Feed Twitter

Tag Cloud

3d account algorithms announcement archives arduino artificial intelligence assembly async audio bash batch blog bookmarklet booting c sharp c++ challenge chrome os code codepen coding conundrums coding conundrums evolved command line compiling css dailyprogrammer debugging demystification distributed computing downtime embedded systems encryption es6 features event experiment external first impressions future game github github gist graphics hardware meetup holiday html html5 html5 canvas interfaces internet io.js jabber javascript js bin labs learning library linux low level lua maintenance network networking node.js operating systems performance photos php pixelbot portable privacy programming problems project projects prolog protocol pseudo 3d python reddit reference release releases resource review rust secrets security series list server servers software sorting source code control svg technical terminal textures three thing game three.js tool tutorial twitter ubuntu university update upgrade version control visual web website windows windows 10 xmpp

The HTTPS version of my website is insecure? Nonsense!

A chrome privacy warning.

I'm still rather ill, but I wanted to post about an issue I've just had with my website. Upon visting my website in the latest version of chrome beta (57 as of the time of typing), I discovered that chrome had decided that the connection was 'insecure'. It didn't tell me precisely what the problem was (even in the developer tools :-) - why would I possibly need to know that? - only that it considered it insecure.

After googling around a bit, I didn't find any specific articles on the subject - their recent move to start considering regular http connections insecure is swamping all the relevant articles in the search results I suspect.

The big clue came when I discovered that one of my subdomains that uses a letsencrypt works as expected. You see, the main website actually used a StartSSL certificate. My running theory is that even though my certificate was an SHA2 cerrtificate, chrome decided that it was not trustworthy as there was an SHA1 certificate in the trust chain somewhere.

The fix: Replace all my existing StartSSL certificates with Let's Encrypt ones. It seems to have fixed the issue for now. I also discovered that Let's Encrypt certificates can also be used in mail servers (i.e. SMTP and IMAP) too - so I don't have to go and fiddle about with finding an alternative certificate provider.

In future, it would certainly be helpful if Google actually told people precisely what they were going to do before they do it....!

Was this useful? Could it be improved? Would you like a Let's encrypt tutorial? Let me know in the comments below!

Fancy message of the day over SSH

Since my time to sit down for a good chunk of time and write some code has been extremely limited as of late, I've been playing around with a few smaller projects. One of those is a fancy message of the day when you log into a remote machine (in my case the server this website is hosted on!), and I thought I'd share it here.

My take on a fancy SSH message of the day.

The default message shown at the top when you login via ssh is actually generated by something called update-motd, and is generated from a set of scripts in /etc/update-motd.d. By customising these scripts, we can do almost anything we like!

To start off with, I disabled the execution of all the scripts in the directory (sudo chmod -x /etc/update-motd.d/*), and created a subfolder to store the script in that actually generated the system information (sudo mkdir /etc/update-motd.d/parts). Here's the script I wrote to generate the system information:

#!/usr/bin/env bash

. /etc/lsb-release

LOAD=$(cat /proc/loadavg | cut -d' ' -f 2);

CPU_COUNT=$(cat /proc/cpuinfo | grep -i "core id" | uniq | wc -l);
THREAD_COUNT=$(cat /proc/cpuinfo | grep -i "core id" | wc -l);

APT_UPDATE_DETAILS="$(/usr/lib/update-notifier/apt-check --human-readable | fold -w 40 -s)"

IPV4_ADDRESS=$(dig +short myip.opendns.com A @resolver1.opendns.com)
IPV6_ADDRESS=$(dig +short myip.opendns.com AAAA @2620:0:ccc::2);

LAST_LOGIN=$(last -1 | head -n 1 | awk '{ print $1,"at",$4,$5,$6,$7,"from",$3 }');

REBOOT_REQUIRED=$(/usr/lib/update-notifier/update-motd-reboot-required);

echo 
echo Welcome to $(hostname)
echo "  running ${DISTRIB_DESCRIPTION}"
echo 
echo Kernel: $(uname -r)
echo Uptime: $(uptime --pretty | sed -e 's/up //')
echo Load: ${LOAD}
echo 
echo IPs: ${IPV4_ADDRESS}, ${IPV6_ADDRESS}
echo 
echo "${APT_UPDATE_DETAILS}"
echo 
echo "${REBOOT_REQUIRED}"
#echo 
#echo Last login: ${LAST_LOGIN}

exit 0

Basically, I collect a bunch of information from random places on my system (several of which were taken from the existing scripts in /etc/update-motd.d/) and re-output them in a different format.

Then, I converted an image of my favicon logo with the brilliant catimg by posva to a set of unicode characters and sent that to a file (catimg -w 35 image.png >/etc/update-motd.d/sbrl-logo.txt) - you could alternatively use some ascii art from the internet (e.g. this site). Once done, I put the two together with the following script directly in my /etc/update-motd.d/ folder:

#!/usr/bin/env bash

### Settings ###
TMP_FILENAME=/run/sysinfo.txt

#/etc/update-motd.d/parts/sysinfo

################

/etc/update-motd.d/parts/sysinfo >$TMP_FILENAME

### Output ###
echo 
pr -mtJ /etc/update-motd.d/sbrl-logo.txt $TMP_FILENAME

##############

### Cleanup ###
rm $TMP_FILENAME

###############

Finally, I manually cleared and regenerated the message of of the day with sudo update-motd, giving the result you see at the top of this blog post. I also made sure to re-enable the execution of the other scripts I didn't use in my fancy motd so as to not miss out on their notifications.

If you're interested, I've generated an archive of my final /etc/update-motd.d folder (minus my logo in text format), which you can find here: 20170203-Fancy-Motd.7z.

Can you do better? Got a cool enhancement of your own? Post about it below!

I now have a public website status page!

My new status page! Just recently Uptime Robot (the awesome service that I use to monitor my server's uptime) have released a new feature: Public status pages! Status pages appear to be free (for now), so I've gone and set one up. Now all of you can see what's up with my website if it's down.

They even allow you to point a (sub)domain at it too. I did this too, so you can visit my status page at status.starbeamrainbowlabs.com.

Server migration!

The Kimsufi logo

I've been watching Kimsufi's server page for what feels like absolutely ages now, waiting to get my hands on an ultra-cheap €4.99 per month (excluding VAT of course) KS-1 dedicated server. Unfortunately I've never been quite fast enough, so yesterday I decided that enough was enough and went ahead and bought a KS-2B at €9.99 per month (again excluding VAT). After all is said and done it works out to about £8.39 per month, which, for 2 cores / 4 threads, 4GB RAM, and a 40GB SSD, is an absolute bargain in my eyes.

I've been busy moving things across and it's going well, but I haven't finished yet - I still have the web server and the mail server to set up. I'm also looking at using the Hiawatha webserver instead of Nginx. Hiawatha is a security-first and easy to configure web server. Apparently it's also lightweight, but we'll see about that...! Nginx's config files have been annoying me for a while now, so I think that it's high time I tried something different.

Public Service Announcement: Web Server Switch

Hello again - Today's post is a public service announcement instead of the usual ES6 post. Hopefully that will be coming out on Thursday.

This website is now powered by a new piece of web server software: Nginx (pronounced engine-x). Ever since I started this website, I have been using lighttpd. While lighttpd has been my favourite web server software for ages (mainly because of the flexible configuration file syntax, the light footprint, and the speed), it seems that development of lighttpd's core codebase has been moving too slowly for me. Lighttpd, while fast and light, has been missing several features that I would rather like to have - and no release date for the next has been announced yet either.

Nginx, on the other hand, is much more feature-complete. It will support HTTP/2 by the end of 2015, and has a slew of other features to play around with. While, it's configuration files are kind of a pain (it only matches against one location block per request), I feel that Nginx is a better solution for this website in the long run. If development resumes on lighttpd, perhaps I will move back to it - but only if I am sure that development will actually continue.

So the switch has been made! Please notify me if you notice any issues and/or problems with the new setup and I will fix them as soon as I can.

Upgrading to Ubuntu 15.04 Vivid Vervet

Hello!

Yesterday you probably noticed some downtime. This is because I was upgradting this server's operating system from Ubuntu 14.10 to Ubuntu 15.04! Since I noticed a few things that you should watch out for when upgrading, I thought that I would make a post about it.

For the most part the upgrade went smoothly, but I did hit a few snags. Firstly, if you have got any custom ppas set up for apt-get, you will want to make a list of them (they are located in /etc/apt/sources.list.d) because the upgrade will annoyingly disable them all :( It's not too much trouble to fix but it is annoying.

Secondly, there are two new mime types that have been added /etc/mime.types. If you have made any customisations to this file (I have added text/x-markdown), then you will want to make a note of them and re-add them afterwards. Don't forget to restart your http servers after changing it!

There are some changes that require the ssh daemon to be stopped, so make sure you don't do the upgrade over ssh.

You will get asked which interfaces DCHPv6 should listen on / send requests to. If you use your linux box as a router and have it handing out IP addresses, then you will need to take note of which interfaces you have on your box and which one is which.

By far the biggest problem for me though was the switch from upstart to systemd. This server is hosted by OVH under one of their VPS hosting plans (which are great by the way!), which means that it is virtualised using OpenVZ. It also means that I can't choose my kernel :( I suspect that this is the reason that I can't use systemd, though if anyone has any other ideas, I would love to hears them - leave them in the comments below. When it has finished the upgrade, it couldn't reboot, instead telling me that it couldn't find an alternative telinit implementation to spawn. The solution to this is simple though (don't forget to run as root):

apt-get install upstart
apt-get remove systemd
apt-get install upstart-sysv

The last package in the above (upstart-sysv) should be install automatically, but you should make sure that it is installed - it is the package that prevents it from automatically trying to switch you back to systemd at the next available opportunity.

I hope this post is useful! If you do find it helpful, please leave a comment. If people seem to like it I might start posting full upgrade guides.

Fighting Spam on your blog

Since I have written my own blog script from scratch, I have learnt a lot about how spambots spam my site in order to implement measures to stop them. This post is a compilation of all the methods that I have discovered so far.

Currently I have yet to rate the effectiveness of each of these measures since at the time of writing this post I have only just finished rewiring the commenting script so that I can 'measure' the effectiveness of each of the methods described below.

Method 1: Honeypots

If you don't take either an email address or a web address on your blog, try adding a email or website field and hiding it via CSS. The more complex, indirect, and obscure the CSS you hide it with, the better. Just make sure that is actually hidden.

This blog uses a hidden website field along with a warning for users who see it due to poor browser support.

Method 2: No super long comments

This isn't really a proper method, but I found that spam comment on my blog were generally really long. So I am imposing a 2000 character limit on comments. If people have more to say, then they can reply to their own comment, and use service like pastebin or hastebin for code.

Method 3: Keys

This is the really important one. I was finding that while the above 2 methods were stopping some of the spam, I was getting some smart spambots with chrome/firefox-like user agent strings that I can only summarise knew how to tell whether a from control was hidden or not by reading the CSS or my website.

The hidden key field is basically a timestamp of when page was served to the user by the server. In it's simplest form, it can just be the output of PHP's time() function.

In this blog, however, the timestamp is run through a number of different functions, such as base64_encode() and strrev(). Pick a few string manipulation functions that are reversible.

This timestamp can then be analysed by the server. If the timestamp is too far in the past (say 24 hours old), or under 10 seconds old, then the comment is rejected. Spambots will either fetch and cache your page for longer than 24 hours, or they will fetch your page and post a comment immediately. As soon as I set this blog to reject comments posted within 10 seconds of loading the page, I haven't had a single spam comment :)

Summary

So there you go: 2 1/2 methods to banish spam on your blog - for now. The real secret here to log as much information about your commenters as possible (in my case I have been capturing the contents of $_POST, $_GET, and $_SERVER) and working your way through it comparing the requests of legitimate commenters and spammers. The above are simply exploits of the differences I found (with some help from Google). If you can think of any more tricks, please post a comment below!

Securing a Linux Server Part 1: Firewall

Welcome to a new tutorial series, where I will show you what I have learnt so far about making sure that your linux server (and desktop too!) are secure so that nobody can get in (easily) and assume control.

Disclaimer: This tutorial series will not cover everything, and should not be taken to. There probably will be some mistakes in this post too. Check other guides online or consult a professional to make sure that your machine is secure. Please suggest improvements or point out mistakes in the comments.

To start this tutorial session off, I will talk about firewalls. Firewalls control how data is allowed to travel in and out of your computer. In Ubuntu, a firewall called ufw, the 'uncomplicated firewall' is already present. It acts as a nice frontend to iptables, which I find to be difficult to understand and use. We will be using that as our firewall.

I have done an asciinema recording on a virtual machine of this whole process:

Enabling the firewall

Ufw by default allows all outgoing connections and denys all incoming connections. This means that if you are using ssh to connect to your server, you will need to open the appropriate ports first before enabling ufw. Do that like this:

~$ sudo ufw allow 22/tcp

Ufw will automatically configure iptables to allow incoming connections on port 22 that use tcp. I will talk more about allowing and denying different connections later.

Just in case ufw blocks your ssh connection and you are unable to get back in, you can use another program called at to schedule the disabling of the ufw so that you can get back in again. If you don't have it installed, you can install it with sudo apt-get install at.

~$ sudo at -vM now +10 minutes
ufw disable
^D

Where ^D stands for CTRL + D. Now that you have it set such that ufw will disable itself in 10 minutes time, we go ahead and turn ufw on:

~$ sudo ufw enable

It will warn you that this may disrupt any existing ssh connections you have open. Reply yes to this. Once it have been enabled successfully, you should check that you can still ssh into your server (if that is the method that you are using to control it). If yes, great! If not, ufw will disable itself in 10 minutes and then you can try again.

Now that we have ufw enabled, we can cancel the at job we created to disable ufw. Type sudo atq to list the jobs you have schedules, and sudo atrm <number> to remove it, where <number> is the number of the jobs that you want to delete.

You may also want to cheeck the status of ufw to make sure that it is enabled, or to get a list of the rules that are currently in force. You can do that like this:

~$ sudo ufw status
Status: active

To                         Action      From
--                         ------      ----
80/tcp                     ALLOW       Anywhere
80/tcp (v6)                ALLOW       Anywhere

Allowing connections

Allowing connections through the firewall is easy. Simply type something like this:

~$ sudo ufw allow 80/tcp

Ufw will automatically configure iptables, in this example, to allow all connections on port 80 that use tcp. It will also configure it appropriately for both ipv4 and ipv6. Replace 80 with the port number you want to allow, and tcp with udp if needed. Ufw also understands several protocol names, and can configure itself accordingly:

~$ sudo ufw allow http
~$ sudo ufw allow imap

Denying connections

Denying all connections on a given port is very similar., Simply type something like this:

~$ sudo ufw deny 4722/tcp

The above would deny all tcp connections on port 4722.

You can also prevent a particular ip from gaining access to your server:

~$ sudo ufw deny from 123.123.123.123

The above would block all packets from the ip address 123.123.123.123. It works with IPv6 addresses too:

~$ sudo ufw deny from 2607:f8b0:4003:c05::65

The above would block all packets from the ip address 2607:f8b0:4003:c05::65, which just happens to belong to Google.

Port Ranges

You can open a range of ports with a colon:

~$ sudo ufw allow 60000:61000/udp

The above will allow udp connections on any port in the range 60,000 - 61,000 (the ports used for mosh).

Deleting Rules

Deleting rules can be done like this:

~$ sudo ufw delete allow 4724/tcp

The above would delete the rule(s) allowing tcp connections on port 4724.

Summary

In this post, I have shown you how to activate and configure a simple firewall that is bundled with Ubuntu. Next time, I will talk about securing you ssh daemon.

If you spotted a mistake in this post, have a suggestion, or are having trouble following along, please leave a comment below.

Other useful posts

These posts helped me to understand and use the uncomplicated firewall:

Friday Afternoon Downtime

Midafternoon today, starbeamrainbowlabs.com was down. The reason for this is unclear, but it seems that this site's hosting provider, OVH, was doing some maintenance. The site was down for 29 minutes.

Lessons Learned

Get your server to notify you during the shutdown / startup sequences

Using a service like Uptime Robot is great to monitor your website's uptime, but it is a much better idea to have your server send you an email when your server goes down. That way you will know whether the server got a chance to shut down correctly or not.

Backup often, and before / after major changes

You should take a backup (preferably automated) often - I have a scritp set to do this every week - but you should also backup before and after any major changes that you make.

Art by Mythdael