— < 1 min read

I love my prompt, always have and always will. I spend so much of my life in a terminal, usually with half a dozen mini terminals open in each tab. As such I like to tweak it and get it as perfect as possible for my life, needs and even mood.

In the past I’ve had quite a large PS1 that covers multiple lines and gives a lot of information, after having that PS1 in one form or another for some time I decided it was time for a change, to a smaller PS1 that takes up a lot less space.

So here it is, the first image is my standard PS1 when in a git repository, the red @ means a file hasn’t been added to Git, a blue @ means a tracked file has been modified but not stage and finally a green @ means a file is staged …

 — 5 min read

Over the last week I’ve been doing a huge amount of refactoring of Blackhole as well as writing dozens of additional tests. To make Blackhole more testable I needed to make a big change to how the program is launched and controlled.

setup.py scripts vs. entry_points

Whenever I’ve written Python programs that require some kind of command line script I’ve always used distutils’ scripts, this can be seen in blackhole’s setup.py on GitHub or in the three line example below.

scripts=[
    'blackhole/bin/blackhole',
],

In doing so, it allowed me to be lazy and write a lot of prodecural code in the main “binary” which made it pretty much impossible to test. You can also see that on GitHub in the main “binary”.

I’ve noticed that most people who write Python packages that have some kind of command line entry point use distutils …

 — 3 min read

Pelican is a Python-powered static blog generator that processes ReStructuredText and Markdown articles and pages and converts them to HTML. I use Pelican to power this blog.

There is a YouTube RST directive built in to Pelican core but it really shouldn’t exist there.

I submitted a pull request for Pelican core to enable Vimeo videos in articles but that request was declined because it didn’t belong in the core. So I decided I would write it as a plugin instead and while I was doing it, also wrote a plugin for YouTube so that it could be removed from the core.

There is a decent amount of detail in the Pelican documentation on how to write plugins, I’m not going to cover the whole process but I thought I would cover a little of what I did.

Adding an RST directive

Really all we’re doing …

 — 4 min read

Blackhole has always been able to handle unencrypted SMTP and for a long time it’s been able to handle encrypted SMTP via TLSv1.

One thing Blackhole hasn’t been able to do until the 1.7.0 release is handle STARTTLS.

In the past the STARTTLS command would cause Blackhole to return the standard 250 OK response but would continue to operate on unencrypted SMTP.

I wanted to fix this and do it properly, but this meant learning how to do so with Tornado, which itself proved to be tricky. I ended up deciding to go to my local coding spot - the pub and hash it out.

connection_stream

The first thing I had to do was refactor the code that created the instance of tornado.iostream.IOStream and tornado.iostream.SSLIOStream so that it didn’t actually do the ssl wrapping.

def connection_stream(connection):
    """
    Detect which socket the connection …
 — 2 min read

As part of my effort to make Blackhole as useful and usable as possible, I needed to be able to support SSL/TLS enabled connections.

Tornado itself has two built-in IOStreams that help us do the job; the first is the standard IOStream and the second is the SSLIOStream.

With this in mind we simply need to spawn two sockets, by default these listen on port 25 for standard SMTP and port 465 for SSL/TLS encrypted SMTP. With these two sockets bound we’re then very simply able to listen for incoming connections on either socket and use socket.socket.getsockname() to figure out if the connection is to the encrypted or unencrypted socket.

Code

def connection_stream(connection):
    """
    Detect which socket the connection is being made on,
    create and iostream for the connection, wrapping it
    in SSL if connected over the SSL socket.

    The parameter 'connection' is an instance …
 — < 1 min read

I recently wrote an article on using haproxy, SSL and SPDY with nginx backend servers.

This article is a little extra on top of that to explain how to enable statistics for haproxy so you can monitor the backend statuses etc.

Example stats page

Moar stats!

Enabling stats

listen stats :8000
    mode http
    stats enable
    stats hide-version
    stats realm haproxy\ stats
    stats uri /
    stats auth admin:admin

Place the above content in the haproxy configuration file (/etc/haproxy/haproxy.cfg).

Be sure to replace admin:admin with your a proper username and password, username first, password after the colon.

Restart haproxy, and then browse to https://yousite.com:8000.

 — < 1 min read

I have been a frequent audience member of DJUGL for a few years now and spend most of the time asking questions, playing devils advocate and generally being my annoying self.

I have repeatedly said I would do a talk but never got round to it until Jon basically forced me to get round to it.

My talk was on blackhole/blackhole.io and covered several topics including PyPy, SimpleMTA and moved on to talking about spamming and starting work on my honey pot suite called Nectar.

You can find the slides on Speaker Deck, sadly I ran out of time when creating them and although I was promised time to finish them at work, I got busy. So I replaced content with “Taylor Replacements(tm)”.

The event, attendees and other speakers are listen on the Lanyrd event page.

Several people took photos of the event, I don’t remember …

 — 5 min read

I wrote an article last week explaining that I had changed my blog and built my own nginx packages with SPDY built in.

I decided I would take things a little further and poke around with haproxy some more. The initial plan was to compile the latest dev source of haproxy with SSL termination enabled.

In doing so I realised I would lose SPDY support, which upset me a little. After some digging I found that the 1.5-dev branch of haproxy supports npn and thus can handle SPDY.

I tweaked my builds a little more and managed to get haproxy running as an SSL terminating load balancer, with SPDY connections being sent off to my nginx servers with SPDY enabled and all other non-SPDY connections were passed on to an nginx virtual host with SPDY disabled.

Requirements

I have released my haproxy build as a debian file below …

 — 2 min read

I decided to rebuild syslog.tv as pure HTML using RST and Pelican and rebrand it as kura.gg.

In doing so I decided I would go all out and use SPDY and ngx_pagespeed (mod_pagespeed) for fun to see exactly what I could do.

Sadly no version of nginx has been officially released with SPDY or ngx_pagespeed enabled, you can compile nginx from source to enable SPDY so I thought I would go ahead and do it, releasing some Debian packages in the process.

After compiling nginx from the source package available at the Ubuntu PPA, I decided I would go further and compile in ngx_pagespeed.

 — < 1 min read

I spend a LOT of time with tunnels open to multiple machines, connecting directly to PostgreSQL, RabbitMQ and many other services all via SSH.

I have written several helper functions and this is the final version that I created in a small competition with @codeinthehole.

Gist removed. Sorry.

Installation

Simply add the contents to ~/.bashrc

Usage

Usage is pretty simply, just called portforward from the command line, pressing <TAB> as you type in a server name from your ~/.ssh/config file and the same with the port.

portforward sy<TAB>

Will become:

portforward syslog.tv

And finally

portforward syslog.tv 15672
 — < 1 min read

I wrote this little Python program a while ago and now people are starting to email me about it, asking for it to be part of the DenyHosts Debian packages so I figured I’d write a quick article on it.

If you’re like my developers, you’ll find yourself getting banned from servers all the time and have to come speak to someone like me (your sys engineer/admin), or maybe you are an admin and are sick of people banning themselves and want and easy way to unban them.

So give this a try:

https://github.com/kura/denyhosts-unban

From the GitHub page you can download either the tarballs, zipballs or a Debian .deb package. Install it using the instructions in the README and you’re good to go.

Unban

Unbanning is simple, you can either unban a single IP using:

sudo denyhosts-unban 10.0.0.1 …
 — 1 min read

If like me you run in to issue when using OpenJDK, my issues come from it’s memory problems when you’re allocating and using large amounts of memory - mostly for Solr where we’re concerned but obviously I’d switch for other high memory usage instances too.

So without further ado, lets get the installation going.

You’ll need Debian’s “add-apt-repository”, on servers this doesn’t usually come by default so we’ll need to install it.

sudo apt-get install python-software-properties

Next we need to add Java’s PPA.

sudo add-apt-repository ppa:sun-java-community-team/sun-java6

Once this is done we’ll need to update our apt caches and install Java 6.

sudo apt-get install sun-java6-jdk

Now that this is installed we should get the Java version, remember it for future.

java -version

You’ll get something like this

java version "1.6.0_20" OpenJDK Runtime Environment (IcedTea6 1.9 …
 — 3 min read

I have built and released an open-source email server in the past for testing send rates and speeds, this project was called SimpleMTA and is available here.

Recently I have rebuilt this project for an internal project at work using the Tornado framework. Sadly this project as a whole cannot be released but a version of this code will be released in the near future.

Until that is released I have launched a new service called blackhole.io

What is blackhole.io?

blackhole.io is a completely open mail relay that forgets anything that is sent to it, meaning there is no auth requirements and no storage of email data within the service. Literally anyone can send anything to it and have it never get delivered.

You can even send commands out of order, meaning you can call the DATA command without ever using HELO, MAIL FROM or RCPT TO …

 — 3 min read

I’ve recently been toying with my Raspberry Pi mirror including moving it out on to Amazon’s S3. I’ve written an article on how to back up to S3, but that isn’t enough when it comes to serving data from S3.

I needed the ability to RSYNC data from the official Raspberry Pi servers on to mine and then in to S3 and for that I used s3fs and FUSE.

FUSE

You can actually do this successfully without requiring FUSE, just by installing the s3fs binary on to your system, but this only allows the user who mounted to access the mounted bucket and also is not possible via /etc/fstab.

FUSE allows you to implement a filesystem within a userspace program, thus allowing us to give other users access and auto-mount using /etc/fstab.

Installation

Fuse

Installing FUSE is simple

sudo apt-get install fuse-utils

s3fs

We …

 — < 1 min read

24 hours of SSH attacks against a single server, visualised on a world map using Python.

When a country stays lit up for more than 1 tick of the clock in the left hand corner it means that multiple attacks are happening from different IP addresses. An attacker is banned after;

  • 1 failed root login,
  • 3 failed user logins (including invalid users) and
  • 3 failed system logins.
 — 2 min read

I have several servers powering syslog including it’s Raspberry Pi mirror, load balancer and email servers. All of my servers are hosted using Linode in their London data centre and have Linode’s back-up system doing both daily and weekly snapshots.

For the app and database servers I do server-side backups storing each website and it’s database in it’s own folder within /backup in case I require a quick back-up to fix something, rather than the server has died.

This is all well and good but I like having an off-site backup too and for that I use S3

About S3

Amazon’s S3 is pretty cheap and very easy to use. Because only data is going in you don’t pay a transfer fee and the cost of storage is very affordable, you can see a pricing list here.

To do the backup I use a …

 — 2 min read

The unattended-upgrades package used on Debian is based on the one from Ubuntu. It is generally pretty safe in my opinion but I only ever enable it for security upgrades.

Installation

apt-get install unattended-upgrades apticron

unattended-upgrades handles the actual updates, apticron is used for emailing you of available updates - it is not required but I like it.

Configuring unattended-upgrades

Open up /etc/apt/apt.conf.d/50unattended-upgrades and change it to the content below.

APT::Periodic::Enable "1";
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::AutocleanInterval "7";
APT::Periodic::Unattended-Upgrade "1";
Unattended-Upgrade::Mail "**YOUR_EMAIL_HERE**";

// Automatically upgrade packages from these (origin, archive) pairs
Unattended-Upgrade::Allowed-Origins {
    "${distro_id} stable";
    "${distro_id} ${distro_codename}-security";
};

// Automatically reboot *WITHOUT CONFIRMATION* if a
 // the file /var/run/reboot-required is found after the upgrade
 Unattended-Upgrade::Automatic-Reboot "false";

So lets explain the above. As you can see we enable periodic updates, enable update package lists (triggers an apt-get update), enable autoclean …

 — < 1 min read

Installation

To install we need to run the following command:

sudo apt-get install -y sks

Now we build the key database:

sudo sks build

And change the permissions for the sks user:

sudo chown -R debian-sks:debian-sks /var/lib/sks/DB

Next we need to make sks start from init, open up /etc/default/sks in your favourite editor and *initstart* to look like below:

initstart=yes

Now we can start the service with:

sudo /etc/init.d/sks start

Your keyserver will now be up and running on port 11371.

Web interface

We’ll need to create a web folder within sks with the following command:

sudo mkdir -p /var/lib/sks/www/

Change it’s permissions so the sks user can access it.

sudo chown -R debian-sks:debian-sks /var/lib/sks/www

And finally we need create a single HTML file for the interface, I have provided that …

 — 4 min read

Installation

First up we’ll need to install git and some Python tools to get Gitosis installed.

sudo apt-get install -y git-core gitweb python-setuptools

Next we have to clone gitosis from it’s git repository and install it.

cd /tmp
git clone git://eagain.net/gitosis.git
cd gitosis
sudo python setup.py install

Adding your git user

sudo adduser --system --shell /bin/sh --gecos 'git version control' --group --disabled-password --home /home/git git

The above command creates a new system user with /bin/sh as it’s shell with no password and a homedir of /home/git/ and also creates a group with the same name.

Initialising gitosis

You’ll need an SSH key for this, if you have one simply copy the contents of it to your new git server, if you do not have one then you can generate one on your machine using

ssh-keygen

And then …

 — 1 min read

*I would generally not advise using this unless you have skill at debugging why OOM has spawned and also debugging kernel panics after they happen, from logs.*

It is possible to configure your kernel to panic when OOM is spawned, which in itself is not useful but, coupled with a kernel option for auto-rebooting a system when the kernel panics it can be a very useful tool.

Think before implementing this and use at your own risk, I take zero responsibility for you using this.

sudo sysctl vm.panic_on_oom=1
sudo sysctl kernel.panic=X # X is the amount of seconds to wait before rebooting

*DO NOT FORGET TO CHANGE X*

This will inject the changes in to a system that is currently running but will be forgotten on reboot so use the lines below to save permanently.

sudo echo "vm.panic_on_oom=1" >> /etc/sysctl.conf
sudo echo "kernel.panic …
 — 1 min read

Preparation

First we need to make sure we have all the stuff we need to compile mk livestatus and run it

sudo apt-get install make build-essential xinetd ucspi-unix

MK Livestatus

Grab the mk livestatus source from here, currently it’s version 1.1.10p3 but update the commands below to match your version.

wget https://mathias-kettner.de/download/mk-livestatus-1.1.10p3.tar.gz
tar xvzf mk-livestatus-1.1.10p3.tar.gz
cd mk-livestatus-1.1.10p3
./configure
make
sudo make install

Xinetd

Now that it’s compiled we need to write a xinetd config for it, create a new file called /etc/xinetd.d/livestatus and put the following in it

service livestatus {
    type = UNLISTED
    port = 6557
    socket_type = stream
    protocol = tcp
    wait = no
    cps = 100 3
    instances = 500
    per_source = 250
    flags = NODELAY
    user = nagios
    server = /usr/bin/unixcat
    server_args = /var/lib/nagios3/rw/live
    only_from = 127.0.0.1 # modify this to …
 — 2 min read

The point

The whole point of this is to get as much load off of Apache as possible to keep the server running nice and smoothly.

Configuration

The configuration below will mean that nginx will serve basically everything;

  • static files
  • uploaded files and
  • cached content

simply replace the VARIABLES below and everything should be good to go, if copy-pasting from below isn’t working properly you can download a full copy from here.

server {
  listen 80;
  server_name **DOMAIN_HERE**;
  access_log /var/log/nginx/access.**DOMAIN_HERE**.log;

  gzip on;
  gzip_disable msie6; # disable gzip for IE6
  gzip_static on;
  gzip_comp_level 9; # highest level of compression
  gzip_proxied any;
  gzip_types text/plain text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript;

  proxy_redirect off;
  proxy_set_header Host $host;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_pass_header Set-Cookie;root **/PATH/TO/WORDPRESS**;

  # default location, used for the basic proxying
  location / {
    # if we're requesting a file and …
 — 2 min read

Pound is a great little load balancer, it’s fast, opensource and supports SSL termination, which is great!

Install

sudo apt-get install pound

Configuration

The default configuration should be pretty good for most purposes, but feel free to tweak as you require.

HTTP

We’ll first look at load balancing HTTP, in case you don’t want or need HTTPS load balancing.

We’ll need delete all the content within ListenHTTP block, once done it should look like this

ListenHTTP
End

Now we add an address and port to listen on and finally a line to remove an HTTP header

ListenHTTP
    Address 0.0.0.0 # all interfaces
    Port 80
    HeadRemove "X-Forwarded-For"
End

This is a basic configuration, for each backend we want to load balance we’ll need to add a service within that listener.

You’ll notice we’re removing incoming headers called X-Forwarded-For, this is to make …

 — 2 min read

A simple yet effective method for protecting your mail server from spam is to use greylisting. In simple terms, when an email is received the server will temporarily reject it with a 450 response code claiming that the server is busy, the sending server should then attempt to try to deliver at a later point in time, if enough time has passed the recipient server will then accept the incoming mail and whitelist the send address for a period of time.

This is effective because most spam servers are configured not to retry the send whereas real mail servers generally will retry. This sadly does not protect against spam coming from comprised mail servers or accounts like on Hotmail.com.

Installation

sudo apt-get install postgrey

Configuring Postgrey

By default Postgrey runs on 127.0.0.1:60000, which is the local loopback interface so it is not exposed to the …