Ubuntu setup - page 1
Once you have your VPS and the DNS is setup (see the Slicehost dns setup article) we can concentrate on setting up the Operating System.
In this Ubuntu setup guide, we already have a basic Ubuntu image installed by the nice folks at Slicehost or the lovely folks at your VPS provider.
Let's get on, update and secure it.
We'll start with the basics of adding a new user, updating the Ubuntu OS, basic security (SSH configuration and iptables) along with an optimised mysql/ruby-on-rails stack with postfix and subversion.
We'll install screen so we don't have to worry if the connection drops. We'll also create several personal rc files for our convenience.
All code that you will be inputting will be shown in fancy boxes and, for the most part, you can simply copy/paste the code as is. However, some need adjusting to use your IP address and your passwords.
Note:
This also works on other VPSs. It is aimed specifically at a Slicehost VPS but I have used it and tested it on other VPS providers. The only difference is that your OS image may not have some of the base programmes, so if I say 'wget this-remote-file', you may need to install wget first.
let's go:
On your LOCAL computer, edit the SSH known_hosts file and remove any entries that point to your VPS IP address. If this is a brand new VPS then you will not need to do this, but an OS reinstall will result in a different signature.
nano ~/.ssh/known_hosts
If you are not using Linux on your LOCAL computer, the location of the known_hosts file will differ. Please refer to your own OS for details of where this file is kept.
As soon as you have your IP address and password for your VPS login via SSH:
ssh root@YOURIPADDRESS
Now we're logged in to the VPS, immediately change your root password
passwd
Add an admin user (I've used the name paul here but any name will do).
adduser -m paul
As paul is our main administration user (we don't normally log in as root!) he needs to be able to sudo (Super User privileges) so we give those permissions via the visudo command:
visudo
At the end of the file add:
paul ALL=(ALL) ALL
Now we'll create two directories. One in our root user folder and one in our new made paul user folder. These 'hidden' directories (did you note the period (.) at the beginning of the folder name?) will hold the public SSH key so we won't have to enter our SSH password every time we log in.
mkdir /root/.ssh && mkdir /home/paul/.ssh
Now we need to copy (using secure copy) the public key from our LOCAL computer to the VPS. On my LOCAL machine, I have the user onion setup, so I would enter:
scp -2 /home/onion/.ssh/id_rsa.pub root@YOURIPADDRESS:/root/.ssh/authorized_keys
Remember to adjust the path to wherever your OS keeps the public key. This is the only time you'll need to enter the SSH password as the file we just copied over will authorise us to SSH in without it. If you are concerned about security (and passwordless logins are far more secure than using passwords), then here is a nice ssh tricks article.
Now we need to configure SSH to make it more secure.
nano /etc/ssh/sshd_config
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
X11Forwarding no
UsePAM no
UseDNS no
AllowUsers paul
Now we're going to do a bit of copying and changing permissions of some files. This is all so that we can log in without passwords later on and not worry about who can see what. There are a few lines shown below (each line is a separate command), but each one is fairly self explanatory.
Overall, we're going to copy the authorized_keys file from root into paul's .ssh folder. Then change the permissions so it's not available to everyone. (Having said that, permissions are not that important as it is the public key, but we don't want anyone writing to the file).
cp /root/.ssh/authorized_keys /home/paul/.ssh/authorized_keys
chown -R paul:paul /home/paul/.ssh
chmod go-w /root/
chmod 700 /root/.ssh
chmod 600 /root/.ssh/authorized_keys
chmod go-w /home/paul/
chmod 700 /home/paul/.ssh
chmod 600 /home/paul/.ssh/authorized_keys
Right, now we have the basics of logging in and security done. Next thing is to set up our iptables so we have a more secure installation. We're going to have four ports open: ssh, http, https and a port for our Litespeed Server GUI.
We're going to create two files, /etc/iptables.up.rules and /etc/iptables.test.rules. One will be the 'permanent' set of rules and one will be the temporary (test) set of rules.
Let's save any existing rules to /etc/iptables.up.rules:
iptables-save > /etc/iptables.up.rules
Now let's see what's running at the moment:
iptables -L
You will see 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. One theory is that if there are no services running then it doesn't matter. I disagree. If connections to unused (and popular) ports are blocked or dropped, then the vast majority of script kiddies will move on to another machine where ports are accepting connections. It takes two minutes to set up a firewall - is it really worth not doing?
Let's assume you've decided that you want a firewall. Lets create the file /etc/iptables.test.rules and add some rules to it.
nano /etc/iptables.test.rules
Look at this example iptables configuration file. You must change the configuration to include your full user connection details. This configuration allows connections to ports 80 and 443 (the standard web server ports) from anyone (which is a good thing, we want people to see our websites!) but only allows connections from the specified IP to the SSH port and to the Litespeed GUI.
So not only do we use non-standard ports for ssh, passwordless logins, no root login, we also only allow connections to the two administration ports (ssh and Litespeed admin) from one specific user.
Not bad, eh?
NOTICE!
If you do not have a static IP then do not setup specific users in the iptables file.
The example file above is in fairly clear sections. Have a careful look at the ssh section, it only allows a connection from one trusted user and drops the rest. So even if someone did know the ssh port we were using it won't accept connections from them. If (somehow!) somebody connects to the ssh port, there is an additional 1 minute lock for every incorrect login attempt. That's as well as not allowing password login at all. The user must have our private key.
You will begin to see the pattern of the iptables configuration file. It isn't complicated and it is very flexible and you can change and add ports as you see fit.
What's the litespeed admin port all about? The web server we will setup later on uses a particular port for administration and configuration. We'll setup the port later when we install the server, but for now, we are just defining the firewall rules.
Good. Defined your rules? Then lets apply those rules to our server:
iptables-restore < /etc/iptables.test.rules
Let's see if there is any difference:
iptables -L
Notice the change? (If there is no change in the output, you did something wrong. Try again from the start). Have a look at the rules and see exactly what is being accepted, rejected and dropped.
Once you are happy with your /etc/iptables.test.rules file and are happy with the output of iptables -L, it's time to save our rules permanently:
iptables-save > /etc/iptables.up.rules
Now we need to ensure that the iptables rules are applied when we reboot the server. At the moment, the changes will be lost and it will go back to allowing everything from everywhere.
Open the file /etc/network/interfaces
nano /etc/network/interfaces
Add a single line (shown below) just after 'iface lo inet loopback':
...
auto lo
iface lo inet loopback
pre-up iptables-restore < /etc/iptables.up.rules
# The primary network interface
...
As you can see, this line will restore the iptables rules from the /etc/iptables.up.rules file. Simple but effective.
Now we have our firewall humming along and we've set the ssh configuration. Now we need to test it. Reload ssh so it uses the new ports and configurations:
/etc/init.d/ssh reload
Don't logout yet...
On your LOCAL computer, open a new terminal and try and login using the administration user (in this case, paul) to the new port number you configured in the sshd_config file and allowed to be open in the iptables configuration:
ssh -p 30000 paul@YOURIPADDRESS
The reason we use a new terminal is that if you can't login you will still have the working connection to try and fix any errors. Slicehost also has the excellent ajax console so if it all goes horribly wrong, you can log into your VPS from the Slicehost management area.
If all goes well you should login without a password to a plain terminal:
paul@yourvpsname:~$
Success!
We now know that the firewall works, the ssh_config works and we can login from the defined location.
Let's move on to page 2 which includes updating the install and installing some base programmes.
PickledOnion.
Digg it |
del.icio.us |
reddit |
StumbleUpon

Subscribe to Feed
Article Comments:
dayo 01 Jul, 2007
Nice. One thing that struck me though was that you have not defined a password for Paul. What gives if one wants to login from another machine?
Thanks
PickledOnion 01 Jul, 2007
Hi dayo,
I have deleted your duplicate comment.
The password is set when you create the user paul. When you issue the command:
adduser -m paulpart of the procedure will ask for a password. Did this not happen when you added the user? Thanks, PickledOnion.dayo 24 Jul, 2007
Hi
On Centos adduser -m paul does not ask for a password after.
However, one can use the -p flag together with the encrypted version of the password from crypt.
Best way is to just create with "adduser -m paul" 7 then sort out the password with "passwrd paul" afterwards.
PickledOnion 25 Jul, 2007
Dayo,
Thanks for the tip but I must stress that this tutorial is not meant for CentOS - it is specifically aimed at Ubuntu LTS.
In fact I would recommend you do not use this Ubuntu tutorial with any other OS - as you noted there are differences between how commands work and also in where some libraries, etc are placed.
Trying to follow this with another OS may not only lead to frustration but could well lead to security issues as well.
I don't want to discourage you, but as I say, this tutorial is only meant to address Ubuntu.
Thanks, PickledOnion.