Ubuntu Maverick Setup - part 1

Your Ubuntu Maverick Slice will be a bare-bones install when it's created. We need to connect via SSH and secure it as soon as possible.

Your new slice

These two articles will take you from a 'barebones' Ubuntu 10.10 (Maverick Meerkat) Slice to a secured and up-to-date Slice ready for your server software (or whatever you use the Slice for). Not only that, you will have a better understanding of what is going on and, more importantly, why it's going on.

This first part will walk you through setting up a new user and securing login access to your slice.

For convenience when we refer to running a command on your local workstation we will give the command as it would be entered into a Mac or Linux terminal window. For Windows you should be able to adapt the command based on the context. For instance, if you're told to edit a file as part of a step, you would use a text editor like NotePad instead of running the "nano" command.

Intro to SSH

SSH stands for "secure shell". It's a protocol that encrypts data that gets sent back and forth through its connection, making it much harder for someone to intercept that traffic and scan it for passwords or sensitive information. In these articles we'll have you using SSH to connect to your slice to run most administrative commands.

If you're running a Linux desktop, you'll be able to run the ssh commands we list here by using them in a terminal window.

If you're running Mac OS X you'll also be able to run the ssh commands in a terminal window. You can open a terminal by running the 'Terminal' application that was installed with your system.

On Windows you won't have command-line access to SSH by default, so you'll need to download a client. We recommend a program named PuTTY, both because it works well and because it's free. You might also want a nice interface for running scp (which uses the SSH protocol to transmit files over an encrypted connection). We recommend another free program, WinSCP, though there are other options like FileZilla that also work well.

First login

As soon as you have your IP address and password for your Slice, login via SSH:

ssh root@

As mentioned earlier, on a Windows machine you'll need to run an SSH client like PuTTY in order to make the connection.

If you rebuilt your Slice, you may get a message informing you that the 'remote host identification has changed'.

When you log into a Slice via SSH, one of the security features is matching the remote host with known keys. When you rebuild a Slice, the remote host key changes. As such, your computer thinks there is something dodgy going on.

All you need to do is remove the older entry for the Slice IP. On your LOCAL computer, edit the SSH known_hosts file and remove any entries that point to your Slice IP address.

nano ~/.ssh/known_hosts

If you are not using Linux or a Mac on your LOCAL computer, the location of the known_hosts file will differ depending on the program you are using. You'll need to refer to the documentation for that program for details. For example, PuTTY stores its known hosts in the following registry entry:


User administration

Now we're logged in to the VPS, immediately change your root password:


Apart from this initial setup, you should never log in as the root user. It's safer and more secure to create a new administrative user and use the 'sudo' command from that user. Having to use sudo to run superuser commands can help prevent some potentially system-breaking accidents, and it also means that any root-level commands run through sudo will be logged to '/var/log/secure' if later review is needed.

To make managing administrative access to your slice easier let's create a group, 'wheel', that will contain users with sudo privileges. To make the group, run:

/usr/sbin/groupadd wheel

With the group ready, let's issue the 'visudo' command to edit the sudo configuration:


The visudo command runs a default editor, and will check the configuration for any syntax errors before saving it. The default editor for Ubuntu is 'nano'.

Scroll down to the bottom of the file. Add the following two lines to the end of the file:

## Allows people in group wheel to run all commands
%wheel  ALL=(ALL)       ALL

Save and exit the file, and sudo is all set. Members of the 'wheel' group will now have full sudo privileges.

NOTE: Some users will find that while working in the nano editor, the backspace/delete key works backwards, deleting characters in front of the cursor rather than behind it. This can be resolved by editing the '/etc/nanorc' file (with nano, for example) and either uncommenting or adding the line:

set rebinddelete

The corrected behavior will take effect after the file has been saved and nano has been opened again.

Add a new user

Time to create a new administrative user (I've used the name demo here but any name will do).

/usr/sbin/adduser demo

You will be asked to set a password for the new user. The values for Full Name and the rest can be left blank.

Since you'll want to use this user instead of 'root' to manage your system, it will need to be able to use the sudo command. We've already granted that permission to the 'wheel' group, so we just need to add the new user to 'wheel':

/usr/sbin/usermod -a -G wheel demo

SSH keygen

One feature of SSH is the ability to require users to use, instead of a password, a "key pair" for authentication. Under this approach a user generates a public and private key pair on their workstation and then uploads the public half of the key pair to the server. When they go to connect later the server tries to match up its public key with the user's private key in order to authenticate the connection.

Using a key pair with SSH is good security policy, which is why we'll walk you through the process here. A password can be guessed through sheer brute force (running a program to try different character combinations until it gets a match), but a key pair is vastly more complex. It is almost impossible to crack a key pair with a brute force approach.

Note that using a public/private key pair is impractical if you need to log in to your slice from a workstation that is shared with other users. While you can copy the private key to another workstation, putting that key on a shared workstation would defeat the purpose of the key pair's security. In that environment continuing to use a password for SSH access would make sense.

The first step to using key pair authentication is to create a folder to hold your keys. On your LOCAL workstation:

mkdir ~/.ssh

That's assuming you use Linux or a Mac and the folder does not exist. For Windows users we have a separate article on key generation using Puttygen.

To create the ssh keys, on your LOCAL workstation enter:

ssh-keygen -t rsa

If you do not want your key to require a passphrase when used then just press enter when prompted.

That created two files in the .ssh directory: id_rsa and id_rsa.pub. The pub file holds the public key. This is the file that is placed on the Slice.

The other file is your private key. Never share this file with someone else or store it on a public computer.

SSH copy

Now we need to get the public key file onto the Slice.

We'll use the 'scp' command for this as it is an easy and secure means of transferring files.

Still on your LOCAL workstation enter this command, substituting your new username and the IP address of your slice:

scp ~/.ssh/id_rsa.pub demo@

When prompted, enter the your user password. When that's done you should see scp copy the file to your user's home directory.

On a Windows machine you'll want to use a third-party client like WinSCP, using the information above to make the connection.

SSH Permissions

OK, so now we've created the public/private keys and we've copied the public key onto the Slice.

Now we need to sort out a few permissions for the ssh key.

On your Slice, create a directory called .ssh in your home directory and move the pub key into it:

mkdir ~demo/.ssh
mv ~demo/id_rsa.pub ~demo/.ssh/authorized_keys

If you haven't run into it before, that squiggly character is the 'tilde', and it's usually in the upper-left of your keyboard. In the Linux shell it can be used as a reference to a user's home directory. Using '~' by itself refers to the current user's home directory, while using it like we did above, '~demo', refers to the home directory of user 'demo'. It's a handy shortcut to know.

Now we can set the correct permissions on the key:

chown -R demo:demo ~demo/.ssh
chmod 700 ~demo/.ssh
chmod 600 ~demo/.ssh/authorized_keys

Again, replace the 'demo' user and group above with the name of the user you created.

Additional users

If you need to add more users to your system, now or after you finish this initial setup, you can just run through the steps above again for each user.

If the user doesn't need to have administrative privileges, skip the part where you add the user to the 'wheel' group.

If the user will be accessed from the same workstation as your administrative user, you can re-use the same public SSH key for the new user.

SSH config

Next we'll change the default SSH configuration to make it more secure:

nano /etc/ssh/sshd_config

You can use this ssh configuration as an example.

The main things to change (or check) are:

Port 30000                           <--- change to a port of your choosing
Protocol 2
PermitRootLogin no
PasswordAuthentication no
UseDNS no
AllowUsers demo

NOTE: The port number can readily be any integer between 1025 and 65536 (inclusive), but should be noted for reference later when any additional listening processes are setup, as it will be important to avoid conflicts.

If you need to allow remote logins for more than one user, add the additional users to the 'AllowUsers' setting separated by spaces.

The labels are fairly self explanatory, but the main security changes to make are to move ssh from the default port of 22 to one of your choosing (we use 30000 in the example), turn off remote root logins, and define which users can log in remotely.

PasswordAuthentication has been turned off because we setup the public/private key earlier. Do note that if you intend to access your slice from different computers you may want leave PasswordAuthentication set to 'yes'. Only use the private key on a secure workstation.

Note that we haven't enabled the new settings — we will restart SSH in a moment, but first we need to create a simple firewall using iptables.


Right, now we have the basics of logging in and securing SSH done.

Next thing is to set up our iptables (firewall) so we have a more secure installation. It's possible to skip this step, or to disable iptables entirely, but we recommend that if you follow the Slicehost tutorials, you set up iptables with our default rules. It's a good hindrance to would-be intruders. Furthermore, the comments in the file you'll create can help you remember why you made a particular change later, and you can use the examples there to take some of the headache out of figuring out what new rule to add and where.

The default rules

Let's have a look at the default iptables rules:

/sbin/iptables -L

Remember that if you come back to this part of the tutorial as a non-root user later, you'll need to put a 'sudo' in front of the iptables command to make it work.

The default setup will output something similar to this:

Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

As you can see, we are accepting anything from anyone on any port and allowing anything to happen.

When we're done, the output of that command should look something like this:

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
ACCEPT     all  --  anywhere             anywhere            
REJECT     all  --  anywhere            reject-with icmp-port-unreachable 
ACCEPT     all  --  anywhere             anywhere            state RELATED,ESTABLISHED 
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:www 
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:https 
ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:30000 
ACCEPT     icmp --  anywhere             anywhere            icmp echo-request 
LOG        all  --  anywhere             anywhere            limit: avg 5/min burst 5 LOG level debug prefix `iptables denied: ' 
REJECT     all  --  anywhere             anywhere            reject-with icmp-port-unreachable 

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         
REJECT     all  --  anywhere             anywhere            reject-with icmp-port-unreachable 

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         
ACCEPT     all  --  anywhere             anywhere

There's too much there to go into much detail in this article, but the basics to pay attention to when you skim those firewall rules are 'ACCEPT', 'REJECT', 'INPUT', and 'OUTPUT'. Fortunately those are reasonably understandable in context. Rules can refer to incoming traffic ('INPUT') or outgoing traffic ('OUTPUT'), and they can describe whether to 'ACCEPT' or 'REJECT' the described connections. The rest of it determines the sort of traffic being controlled, like what port or packet type it's looking for.

Roll your own

Now to set up those iptables rules we want. If the output of 'iptables -L' wasn't an empty ruleset, or if you just want to be thorough, you'll want to flush the current rules from memory:

/sbin/iptables -F

We can now set up our own rules that allow local connections and keep established connections (which is how the root SSH connection on port 22 will still work when we apply the SSH port changes and apply the new iptables rules).

We'll also open port 80 and port 443 (the normal HTTP and HTTPS ports) and, of course, allow connections to our custom SSH port. Then we'll allow pings to the Slice and, effectively, reject all other attempts to connect to a port.

To make it easier to keep track of the rules you want iptables to use and to change them later, let's create a file to store them:

nano /etc/iptables.up.rules

Now check out our example iptables rules file. Copy and paste those rules into your new file, and edit the rules however you see fit. The comments should help you decide what to change. In particular, make sure you change the line opening port 30000 to whatever you chose as your custom ssh port.

The lines opening ports for a web server should provide a good template for opening ports for other services you may add to your slice later.

If you want more complex firewall rules (restricting outbound traffic as well as inbound, for example), you might do well to research iptables more after you're done with this basic setup.

Once you're happy with your iptables rules, save the file.

Implement your rules

To tell iptables to use your new rules, run the command:

/sbin/iptables-restore < /etc/iptables.up.rules

That will read in the custom rules from the file you just created. You can confirm that it worked by checking the rules again:

/sbin/iptables -L

See the difference between the first time we entered that command and now? Again, have a look at each line of the output and see where it marries up with the rules we entered earlier.

Although the rules are up and running, they are only active for the current session. If the Slice were to be rebooted they would be lost.

As such, let's ensure they are restored on a Slice reboot. We'll add a small script that the system will run when your network interfaces are started. Create the file by running:

nano /etc/network/if-pre-up.d/iptables

Add the following lines to the new file:

/sbin/iptables-restore < /etc/iptables.up.rules

Save your changes, and then make the new script executable:

chmod +x /etc/network/if-pre-up.d/iptables

That should ensure that whenever your network interfaces are brought up (usually just at boot time), the firewall will be too.

Editing iptables later

You can repeat these steps if you decide you've made a mistake, or if you want to change any rules later. Just edit the rules file you created, flush the current rules from memory, then restore the edited rules.

The commands you'd use (without all the commentary) are:

nano /etc/iptables.up.rules
/sbin/iptables -F
/sbin/iptables-restore < /etc/iptables.up.rules

Good work surviving the iptables setup.

Note that if you decide to use a control panel type of program like virtualmin that can manage your firewall rules you'll want to either not use that part of the control panel, or remove what we've been using to manipulate iptables. A similar choice would have to be made if you look into using another method of managing firewall rules, like UFW or Shorewall. Having two processes controlling iptables rules can lead to some real conflict. If you find an alternative, just be sure that you choose it alone or that you go back to using /etc/iptables.up.rules exclusively.


Reload sshd

Now we have our basic firewall humming along and we've set the ssh configuration. Time to test it. Reload ssh so it uses the new ports and configurations:

/etc/init.d/ssh reload

Don't logout as root yet...

Logging in with the new user

On your LOCAL computer, open a new terminal and log in using the administrative user (in this case, demo) to the port number you configured in the sshd_config file (for our example, 30000):

ssh -p 30000 demo@

The reason we use a new terminal is that if you can't login you will still have the working root connection to try and fix any errors.

Slicehost also has an excellent ajax console so if it all goes horribly wrong, you can log into your slice from the Slicehost management area.

You should be greeted with a plain terminal prompt like this:

[demo@yourvpsname ~]$


We now know that the firewall and sshd_config work and we can log in.

Let's move on to part 2 which includes updating the install and installing some base programs.

  • -- Jered

Article Comments:

Tim commented Mon Nov 29 19:45:25 UTC 2010:


I'm going through this for the first time and noticed some things.

in the SSH config section, I didn't see the following lines. I just added them to the bottom of the file and it seems to work. Is this the correct thing to do?

UseDNS no AllowUsers demo

Thanks for reading! -Tim

Jered commented Mon Nov 29 22:06:22 UTC 2010:

Yes, Tim, it's okay to add those lines to the bottom. The "UseDNS no" line just tells SSH it doesn't need to look up the DNS entries for connecting clients (which would eat up system resources if it did). The "AllowUsers demo" line tells SSH to only allow the user "demo" to connect to the slice.

Tim commented Mon Dec 06 19:16:30 UTC 2010:

Thanks Jered. So, if I set AllowUsers demo will this disable the ability to login as root too via ssh?

If so, is this generally a good idea? I tried using the webconsole to login as root but it's a little laggy. I'd rather just use a terminal.

Many thanks!

Jered commented Wed Dec 08 15:33:34 UTC 2010:

The root logins are actually controlled by a different SSH directive, the "PermitRootLogin no" entry. It's usually a good idea to disable root logins via SSH as an extra measure against intrusion. So long as you have sudo access on demo you don't really need to be able to ssh directly as root anyway.

leoc commented Fri Jan 07 00:04:45 UTC 2011:

Wouldn't it be better to use Maverick's iptables-persistent package (sudo aptitude install iptables-persistent) to load iptables rules at startup? iptables-persistent uses /etc/iptables/rules.

Jered commented Fri Jan 07 21:52:18 UTC 2011:

While iptables-persistent is a promising package, it's also very simple and incomplete right now. It does indeed just read from a rules file at boot time. The trouble is that there's not a save option or a status or anything like that. So if an admin wants to use iptables-persistent they still need to know how to edit the file or save their rules somewhere, since the script won't do that for them.

Honestly, since the goal here is to help people set up their server and then maintain it, for now it's more helpful to leave them handling the file creation, editing, and restoring themselves. It also doesn't hurt that this approach works on just about any distribution with slight modification, so switching distros wouldn't involve much of a learning curve when setting up iptables again.

Day Barr commented Tue Jan 11 08:08:21 UTC 2011:

By default, Ubuntu 10.10 already comes with a group that gives members full sudo privileges. It's called sudo, as you can see when editing the config file using visudo. So why would you also want to add a wheel group for this purpose? Is it just because this is more conventional across different unices / linux distros?

Jered commented Tue Jan 11 15:45:26 UTC 2011:

I admit, Day, that is the reason for using wheel. It makes the Ubuntu setup consistent with the setup articles we use for other distributions. Thus it's easier for us to maintain the same style of setup across those articles, and theoretically admins will run into fewer discrepancies to adapt to if they decide to switch distributions later.

You can of course just use the sudo group on Ubuntu instead without hurting anything.

Luke commented Thu Mar 03 09:12:04 UTC 2011:

Worked great on geeksoup.net! Appreciate the article.

Random commented Mon Apr 18 20:00:06 UTC 2011:

Are you sure iptables exists by default on Maverick? It didn't here. So I had to do "aptitude install iptables" to get it. Weird...

Jered commented Mon Apr 18 22:55:39 UTC 2011:

That is odd, Random. Our default build includes iptables, and I'd expect it to be standard in any barebones Ubuntu install. Maybe /sbin wasn't in your $PATH, so it couldn't find it as just "iptables"?

Zan-The-Man commented Sun May 15 00:12:00 UTC 2011:

This is a great tutorial. Thank you so much for posting. I had one challenge getting my localhost to scp into the root dir of my slice, but other than that, worked great! Thank you

Z commented Thu May 19 03:58:46 UTC 2011:

I seem to be getting an error when trying to implement my iptables. Can anyone help? When running iptables-restore I'm getting the error "iptables-restore: line 47 failed" but line 47 is COMMIT ... what could it be?

Jered commented Mon May 23 16:08:49 UTC 2011:

I can't say for sure with that much information, but you might email support@slicehost.com with more details to see if one of the techs can help you. You might also take a look at these articles on iptables.

Toord commented Wed May 25 13:23:13 UTC 2011:

I hope for the sake of all things holy (including Mackerels) that RackSpace will migrate all these awesome tutorial/articles to their knowledge base. One of the reasons I'm still a customer of Slicehost is the user-driven help. Without it, might as well find myself a vps at Linode or something.

Jered commented Wed May 25 15:55:42 UTC 2011:

We will be migrating articles over, definitely. There are still details to be hammered out regarding how we'll handle redundant articles, stuff like that, but the plan is to preserve them on the Rackspace knowledge center.

koun fermonfrr commented Mon Jul 18 11:07:44 UTC 2011:

cool setup (Y) I hope for the sake of all things holy (including Mackerels) that RackSpace will migrate all these awesome tutorial/articles to their knowledge base. One of the reasons I'm still a customer of Slicehost is the user-driven help. Without it, might as well find myself a vps at Linode or something.

Jered commented Mon Jul 25 20:53:01 UTC 2011:

Thanks Koun. The articles will get ported over (some have been already) to Rackspace's new Knowledge Center site. They're still working on the presentation, but the goal is to serve the same purpose as the Slicehost article repository has.

Michael commented Sun Aug 14 18:50:13 UTC 2011:

Hello, Thanks for the tutorial. I have just installed a new slice and followed the steps religiously. When I am trying to log in with the new user, I keep getting

Agent admitted failure to sign using the key. I can however enter the password for the new user and after that everything is fine. Do I have to be concerned about this message? Thanks

Jered commented Tue Aug 16 19:21:06 UTC 2011:

Hi Michael, the error message you see is the result of your ssh client trying to make a connection using your ssh keypair and failing. That can happen if the public key is a little off on the server (a missing character maybe, I do that sometimes). The "agent" is what ssh uses to authenticate the keys.

So you shouldn't have any problems connecting the way it's set up now, but if you troubleshoot the ssh keys a bit then you'll know when you get it right when it stops complaining, and lets you log in without entering the user password.

cinewiki commented Mon Feb 27 07:17:41 UTC 2012:

very usefull tutorial.

Want to comment?

(not made public)


(use plain text or Markdown syntax)