Friday, 29 June 2012

Hetzner Review

I recently found the Hetzner market ( which is a great idea for any hosting company to have implemented! Basically they auction used hardware dedicated servers, this has great benefits for both them and the consumer...

However to me it goes further than just getting a dedicated server at a great price, besides helping the environment out by not sending another server's hardware to the local dump, one has to face the facts that the average dedicated server rarely runs at maximum capacity, if even close to that... mostly because you pay for the latest server hardware, eg. Xeon but your only going to run a small mobile app from it...

Through the years I've worked on so many dedicated servers with load averages of less than 0 while running on i5, i7 or quad core Xeon processors, simply a complete waste of resources and one of the reasons we move so many to cloud based hosting.

The used servers available from Hetzner are great, to me simply having a 1GHz cpu on a server is enough to run my web server, e-mail server, application server, and database server... Being able to choose a server which won't be a complete waste in your specific environment and being charged accordingly is what makes this solution so awesome if your not interested in cloud based solutions.

Hetzner is well known to me locally in South Africa, they have been around for many years and I often see an advert for them in local media. Their technical support people have always answered the phone and are always willing to help 24/7, certain other departments are available during office hours only as per the usual hosting company setup.

Their network is nice and fast (seem to be using Juniper for their routing equipment), they provide your server with 5TB on 100 Mbps before dropping the speed to 10 Mbps (which can be restored at a nominal fee per additional TB  of usage).

The control panel for servers is definitely one of the more mature ones and allows one to easily assign additional IP addresses, eg. IPv6 in a few clicks. Reverse DNS and traffic graphs are just as simple, overall the control panel is great, I would however really appreciate more control over the billing periods for a service, eg. paying 3 months at a time or paying invoices manually if preferred etc but that can be arranged with billing so definitely a minor thing...

I ordered a server with two drives, especially with a used server I figured in case on goes redundancy may just save the day... The Samsung drives each show 50930 power on hours, quite a few but expected, unlike providers I've used in the past which offer premium servers I found to have similar power on hour hard drives...

The server is delivered in rescue mode, at first I was wondering how this would go... to sum it all up, brilliantly! The rescue mode allows you to install and configure your server remotely (and can be entered into from the control panel), the system which is then installed has been configured to work 100% and looks good, even the repo's in Ubuntu are configured to use local mirrors on the Hetzner network.

Overall I would not hesitate to recommend Hetzner to anyone looking for a new or used server,  to admit the truth at first I was skeptical of them but they have proved to be one of the best providers I have encountered so far, in fact I requested the billing department to renew my server for the next 12 months!

Monday, 25 June 2012

Linux C forking, threading, iterative and polling server...

Recently Linux Journal published a really great article by Martin Kalin about server concurrency. For the first time I was able to read about and see the code (all in c) for all the different server types without hours of searching Google with often fruitless results...

The article can be found at:

Martin's homepage:

You can also find a very detailed socket programming guide called "Beej's Guide to Network Programming" at:

I also did a few abusive rough no meaning benchmarks on the servers, I tried to do 50K requests as fast as my local system would allow, the results:

Total of 18631 requests completed in 6.33 seconds - second run completed without error...

Total of 47408 requests completed in 6.34 seconds - second run completed without error...

Threading server:
Total of 15102 requests completed in 3.23 seconds - first run broke the server with a  "Bad file descriptor" error

Total of 49175 requests completed - the first 50K broke the server, second run just outputs "Bad file descriptor"

 I would personally go for the Iterative server, it's simple and works a charm! Thank you to Martin for contributing the article!

Wednesday, 20 June 2012


I'm busy working on The NOC (, basically The NOC allows you to monitor any key/value pair sent to it, this allows you to use our existing software scripts (or eg. Android application) to monitor your servers/devices or to create your own scripts to monitor pretty much anything. You can then track the data and take actions based on your criteria, eg. if a servers disk reaches 99% send me a message. The multivalue idea comes from the MultiValue database's that have been around for many years (one we know of has been around since 1965) and the more recent NoSQL type databases although we are sticking to open source relational databases for backend data for the time being.

The NOC site has been developed in JQuery Mobile to be ready for both the desktop and mobile world with a Android and Linux probe (why does that word always sound so wrong) available.

I'm hoping to release the first version soon, it will be free and available to everyone with non-core paid modules like custom branding to help keep the "lights on".  If you have anything you would like to see in a monitoring like application please drop a comment and I'll see if I can add it!

MySQL ordering by a specific fields values...

I often get requests after completing reports for all sorts of interesting ways to sort the required data, one of these requests came in the form of sort a field based on the fields values in a given order, eg:

Status field can be 'New','Old','Replaced','Discarded'', by default an order by in MySQL on the field should return them in a alphabetically sorted way, to change this one can use the "order by field()" syntax:

order by field(Status, 'Old','Replaced','Discarded','New')

Very cool feature but unfortunately not always common knowledge, hopefully it saves someone else a bit of time!

Tuesday, 19 June 2012

Linux CUPS terminal printer quick cheatsheet

Adding a new printer without a PPD:  
  • lpadmin -p printer_name -E -v socket://
1. Finding an existing PPD for your printer if required:
  • lpinfo --make-and-model 'LaserJet 3390' -m
2. Copy the require line up to the first space, eg from above command:
  •     Output: gutenprint.5.2://hp-lj_3390/expert HP LaserJet 3390 - CUPS
  •     Used for -m: gutenprint.5.2://hp-lj_3390/expert
3. Adding a new printer with above ppd: 
  • lpadmin -p printer_name -E -v smb://user:pass@ -m gutenprint.5.2://hp-lj_3390/expert
Adding a new printer with a specific ppd: 
  • lpadmin -p printer_name -E -v serial:/dev/ttyS0?baud=115200 -m MyPrinter.ppd
Adding Location (-L) and Description (-D): 
  • lpadmin -p printer_name -L "13th floor" -D "Konica Minolta C250"
Setting printer as default: 
  • lpoptions -d printer_name
Printing a file eg. /etc/hosts: 
  • lpr -P printer_name /etc/hosts
Remove the printer from the system: 
  • lpadmin -x printer_name
View printer state and job list:
  • lpq -P printer_name
View status information for jobs for a specific printer: 
  • lpstat -P printer_name
Purge all jobs for a specific printer: 
  • lprm - -P printer_name
Enabling a stopped printer: 
  • cupsenable printer_name
Disabling a printer: 
  • cupsdisable printer_name
Some of the lpadmin -v types:
  • serial:/dev/ttyS0 (can add baud, eg: serial:/dev/ttyS0?baud=115200)
  • parallel:/dev/lp0
  • smb://user:pass@host/share
  • ipp://host:port/printer_name
  • lpd://host/printer

Monday, 18 June 2012

Varnish IPv4 and IPv6 mini-tutorial

I recently added IPv6 to the ONMS.Net server and wanted to configure Varnish to cache pages on both specific IPv4 and IPv6 addresses. Searching the topic didn't return any clear cut answers, so here goes for all of you that need a specific answer:

pkill varnishd
sleep 2
varnishd -a IPv4:80,[IPv4]:80 -b [IPv4 or IPv6]:8080 -s malloc,128M


The Varnish listen on option or -a can be given multiple addresses, so we add IPv4 and IPv6 addresses using: -a IPv4:Port,[IPv6]:Port

The backend server option or -b can be either an IPv4 or IPv6, in my case I take IPv4 and IPv6 requests and send them to the web server listening on IPv6 since were moving to IPv6 in any case.

The above command should run however you may want to tweak the other Varnish parameters for your specific setup...

Hope this helps someone!

Monday, 11 June 2012

Samsung Hard Drives

If you ever wondered, Samsung drives are truly reliable, added to my list alongside Seagate:

Model Family:     SAMSUNG SpinPoint P80 SD
Device Model:     SAMSUNG HD160JJ
Power on hours:   50485 hours (5.75 years)

I found another one while repairing a system we received from a car scrapyard, the drive was covered in dust (oil like dust due to the nature of the business) but in perfect working condition...

I'm pretty sure they have built the same quality into the Samsung Galaxy SIII, having seen the amount of work they put into adding their own features to the Android OS they are definitely ranked as one of the top IT companies in my mind!

Sunday, 10 June 2012

Java SSL threaded echo server

I'm busy playing around with Java and put together the following SSL server, the client side needs to be SSL enabled too. Currently it echo's back everything received in the thread handling the client...

To create the keystore: keytool -genkey -keystore KeyStoreName -keyalg RSA

To compile the source code: javac SSL.javac

To run the server: java SSL

To debug add:

File contents:


class ClientHandler implements Runnable {

 SSLSocket socket;
 ClientHandler (SSLSocket socket) {
  this.socket = socket;
  Thread thread = new Thread(this);

 public void run() {
  System.out.println("Client be served:");
  try {
   BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
   PrintWriter out = new PrintWriter(socket.getOutputStream());
   String inputLine, outputLine;
   while ((inputLine = in.readLine()) != null) {
    outputLine = inputLine;
   System.out.println("Client disconnected");           
  } catch(Exception e) {
   System.out.println("Error encountered -> "+e);
public class SSLserver {
 public static void main(String[] args) {
  try {
   SSLServerSocketFactory sslserversocketfactory = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
   SSLServerSocket sslserversocket = (SSLServerSocket) sslserversocketfactory.createServerSocket(443);//Port, we chose the default for https

   //Configure the ciphers/protocols to use
   //String [] ciphers = new String [] { "SSL_RSA_WITH_DES_CBC_SHA" };//If you wish to limit ciphers
   String [] protocols = new String [] { "SSLv3" };


    SSLSocket client = (SSLSocket) sslserversocket.accept();
    new ClientHandler(client);
  } catch(Exception e) {
   System.out.println("Error encountered -> "+e);