How to bulk add an ssh key to multiple servers

If you need to add a colleague’s ssh key to multiple servers that share a similar name, you can do it with a simple one liner. In this post I will show you how.

Assuming the servers you need to add they key to are called:

And your colleagues key is in a file called

To add to a list of consecutive servers, use:

for i in {1..10}; do ssh-copy-id -i root@server$; done

If you wanted to list specific servers, you could use:

for i in {1,4,7,10}; do ssh-copy-id -i root@server$; done

You can then check it worked with the following: (replace colleagues-key-comment with the comment that identifies their public key):

for i in {1..14}; do echo server$i; ssh root@server$ cat /root/.ssh/authorized_keys | grep colleagues-key-comment; done

Raspberry Pi #8 First Photoshoot

I came home from work this evening to find a small brown parcel containing a Raspberry Pi beta board that I had won in an ebay auction earlier this week. It was a charity auction with all the proceeds go to supporting the Raspberry Pi foundation whose aim is to promote computer science and electronics at the school level. I think this is an admirable aim – computer science has enabled me to run my own business, and I feel passionately that we should improve the teaching of it in schools.

The production boards should be going on sale in the next few months for £16 / £25 each depending on the model you choose. For those of you who are looking forward to ordering your own, I have taken some photos of it against my iPhone so you can get a better idea of the size for yourselves.

The first thing that strikes you about the Raspberry Pi board is how small it is. I had seen pictures of it online, but I’m sure it looked bigger! It’s great to see how far computing has evolved since I got my first BBC Model B computer approximately 25 years ago.

You can see the full size Raspberry Pi board diagram here.

Although these boards were designed for schools, I think they will transform the world of computing in myriad other ways. A few years ago the OLTP foundation set out to build a $100 laptop. 2012 marks the beginning of the $20 desktop.

What is the Raspberry Pi?

The Raspberry Pi board is effectively an entire computer on a credit card size board. Like a cut down Mac Mini, all you need is a keyboard and a monitor and you can run a full Linux desktop operating system like Fedora or Debian. It’ll even play Quake 3 and full 1080p films!

Re-using these photos

I’m releasing all these photos under the Creative commons attribution license:

Creative Commons License
Raspberry Pi Beta Board #8 Photos by Paul Maunders is licensed under a Creative Commons Attribution 2.0 UK: England & Wales License.

Raspberry Pi Beta Boards Raise Over £16,000 in ebay auctions

The Raspberry Pi Beta Board auctions have now finished, raising a total of £16,336 for the Raspberry Pi Charity.

  • The lowest winning bid was £930 for board 9
  • The highest winning bid was £3,500 for board 1

You can view the full spreadsheet here.

How to deploy Zimbra ZCS Open Source Edition on Amazon EC2

This guide should help you deploy Zimbra ZCS 7.1.3_GA on an Ubuntu 10.04 instance with Amazon EC2.


1) Ensure you have set up Amazon EC2 CLI scripts …

Download tools from here

Generate certificates in the security credentials section of AWS control panel

Set up environment variables in your .bash_profile (using your key paths, and your preferred EC2 region)

export EC2_PRIVATE_KEY=/path/to/ec2-private-key.pem
export EC2_CERT=/path/to/ec2-cert.pem
export EC2_URL=

2) Ensure you have imported your public ssh key (replace paul-public-key with whatever label you want to use)

for r in us-east-1 us-west-1 ap-southeast-1 eu-west-1; do ec2-import-keypair --region $r paul-public-key --public-key-file ~/.ssh/ ; done

3) Setup an elastic IP, and then create DNS entries for your mail server, that point to that IP. Let’s assume you are going to call your mail server, you will need records in’s zone for:

mail1 CNAME
mail1 MX 10 mail1

Where xxx-xxx-xxx-xxx is your elastic IP. For other domains, you can then point their MX records to

4) Setup a security group for your Zimbra server with the desired ports open (25,80,443, 110, 143, 389, 443, 993, 995, 7071, 7110, 7995, 7143, 7993 etc… ).

ec2-create-group "Zimbra ZCS" -d "Zimbra Collaboration Suite Group"
ec2-authorize "Zimbra ZCS" -P icmp -t -1:-1
ec2-authorize "Zimbra ZCS" -P tcp -p 22
ec2-authorize "Zimbra ZCS" -P tcp -p 25
ec2-authorize "Zimbra ZCS" -P tcp -p 80
ec2-authorize "Zimbra ZCS" -P tcp -p 7071


1) Launch a new instance. Replace paul-public-key with the name of your public key (this will need to have been imported into AWS previously). The -g switch refers to your security group. We are using 100GB as the main disk size, as by default they are too small for a Zimbra installation.

// This will launch a new launch instance of Ubuntu 10.04 LTS
ec2-run-instances -t m1.large -g "Zimbra ZCS" -k paul-public-key -b "/dev/sda1=:100:false" ami-cc0e3cb8 --region eu-west-1

2) SSH in and resize the filesystem to the full disk size. Run ec2-describe instances to find your new instance’s IP address, then ssh in to it and resize the file system.

ssh ubuntu@your-instance-public-ip
sudo su -
resize2fs /dev/sda1

3) Assign the elastic IP you chose earlier

// Check your instances ID
// Associate the address to the instance
ec2-associate-address ELASTIC_IP_ADDRESS -i INSTANCE_ID

4) Set up hostname on the system

echo '' > /etc/hostname
echo ' mail1' >> /etc/hosts

Then check it works with..

hostname --fqdn

IMPORTANT: The commands above specify as the IP for the system’s hostname in /etc/hosts. You need all 3 fields listed in /etc/hosts (eg. mail1) – otherwise LDAP install fails as it tries to connect to resolved elastic IP. In addition, use a CNAME for the public DNS MX records hostname instead of A record, then when it is resolved internally, it should get a local IP, which should assist postfix with LMTP lookups. If you don’t do this you will get issues – – A crude fix is to open port 7025 in the security group, but the CNAME is better.
4) Download Zimbra

cd /root/ 
mkdir zimbra
cd zimbra
// Download the appropriate version for your Linux distribution (and architecture, e.g. 64 bit)
tar -xvzf zcs-7.1.3_GA_3346.UBUNTU10_64.20110928134610.tgz

5) Install dependencies

apt-get install libperl5.10 sysstat sqlite3

6) Install Zimbra (this takes about 10-15 minutes)


Keep all default settings and proceed with install

When it complains “DNS ERROR – none of the MX records for resolve to this host” say No to change domain name.

Set password… at menu (make a note of it).

Apply changes.

You can login to the web interface with:

p: whatever you set in the install script

Try sending a test e-mail to – you should be able to log in to the web interface and view it.

References: – Ubuntu Image List – Zimbra Downloads


Setting up SnomONE PBX on Centos 5.5

I’ve been looking at the new SnomONE PBX tonight, and have set up a test installation on a virtual machine. I couldn’t see any instructions in their manual for installing on Linux, so I thought I’d blog about the steps I took as it might help someone else!

1. Install Centos 5.5 x86_64 system.

2. SSH into system, and download SnomONE Centos 64 bit version installer from Snom.

cd /root/

3. Make the installation script executable:

chmod +x

4. Run the installer script without any arguments to check the integrity of the file:


5. Run the installer in install mode

./ install

6. Setup firewall rules

echo '
# Generated by iptables-save v1.3.5 on Thu Oct 14 23:11:41 2010
:OUTPUT ACCEPT [11875:1171187]
:RH-Firewall-1-INPUT - [0:0]
-A INPUT -j RH-Firewall-1-INPUT
-A FORWARD -j RH-Firewall-1-INPUT
-A RH-Firewall-1-INPUT -i lo -j ACCEPT
-A RH-Firewall-1-INPUT -p icmp -m icmp --icmp-type any -j ACCEPT
-A RH-Firewall-1-INPUT -p esp -j ACCEPT
-A RH-Firewall-1-INPUT -p ah -j ACCEPT
-A RH-Firewall-1-INPUT -d -p udp -m udp --dport 5353 -j ACCEPT
-A RH-Firewall-1-INPUT -p udp -m udp --dport 631 -j ACCEPT
-A RH-Firewall-1-INPUT -p tcp -m tcp --dport 631 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A RH-Firewall-1-INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
# SnomOne Rules
# Web
-A RH-Firewall-1-INPUT -p tcp --dport 80 -j ACCEPT
-A RH-Firewall-1-INPUT -p tcp --dport 443 -j ACCEPT
-A RH-Firewall-1-INPUT -p udp --dport 5060 -j ACCEPT
-A RH-Firewall-1-INPUT -p tcp --dport 5060 -j ACCEPT
-A RH-Firewall-1-INPUT -p udp --dport 5061 -j ACCEPT
-A RH-Firewall-1-INPUT -p tcp --dport 5061 -j ACCEPT
# RTP Media Stream
-A RH-Firewall-1-INPUT -p udp --dport 49152:64512 -j ACCEPT
-A RH-Firewall-1-INPUT -p udp --dport 161 -j ACCEPT
-A RH-Firewall-1-INPUT -p udp --dport 69 -j ACCEPT
-A RH-Firewall-1-INPUT -j REJECT --reject-with icmp-host-prohibited
# Completed on Thu Oct 14 23:11:41 2010' > /root/snom-firewall.txt
iptables-restore < /root/snom-firewall.txt
service iptables save

6. Access the admin interface in your web browser…. http://ipaddress-of-centos-box/

Trixbox blue screen after probing video card

I was experiencing an error during an installation of Trixbox whereby it would lock up with a blue screen after the keyboard language selection / probing video card steps. Initially I thought it was a faulty CD, but after burning 3 copies with 2 computers, I would get the same problem every time.

This thread had some more info, but in the end I fixed it by disabling the machines secondary hard drive.

Creating a Virtual Host with Webmin

These instructions apply to Webmin version 1.450
  1. Create a folder where you wish to store your sites files. 
    • You can do this in the Others > File Manager section. 
    • We typically use something like: /sites/
  2. Setup the vhost.
    • Click on Servers > Apache Web Server in the left hand menu.
    • Click the “create virtual host” tab.
    • You can leave most settings as their default values, but you should fill out the following:
      • Port: Generally, you’ll want to use port 80.
      • Document Root: This is folder where you site’s files will be stored. Pick the folder you created in step 1.
      • Server name: This is just your site’s domain name, e.g. (leave out the www.)
    • Click “Create Now”
  3. Add a server alias for 
    • Click on the “Existing Virtual Hosts” tab in Servers > Apache Web Server.
    • Click the virtual server you just created.
    • Click on “Networking and Addresses”
    • In the “Alternate Virtual Server Names” box, add any additional server aliases you want to use for this site, such as
    • Press “Save”.
  4. Click “Apply Changes” to get Webmin to restart Apache.

    A script to reset the MySQL root password

    It’s a pain if you ever forget your MySQL root password. Fortunately it’s a fairly straightforward process to reset it, here’s how:

    pkill -9 mysqld;
    echo "UPDATE mysql.user SET Password=PASSWORD('MyNewPass') WHERE User='root';
    FLUSH PRIVILEGES;" > /tmp/reset-pass.sql
    mysqld_safe --init-file=/tmp/reset-pass.sql &
    sleep 10
    pkill -9 mysqld;

    A bash script to reset the mysql root password

    To make the process easier, I’ve wrapped these commands up in a script and put it on our open source respository here: script

    Update: This script has been improved with Andy’s suggestion in the comments,  which is a simpler and more secure method.

    killall -15 mysqld
    read -s -p 'Enter a new root password: ' MYSQL_ROOT_PASSWORD
    echo "UPDATE mysql.user SET Password=PASSWORD('$MYSQL_ROOT_PASSWORD') WHERE User='root';" | mysqld --bootstrap