23 Jul 2013

A Beginner's Comprehensive Guide to Ubuntu Server Setup

  • Sections covered in this guide:
    • Background
    • Best Practises
    • Connecting to your server
    • Hosts
    • Hostname
    • Timezone
    • New User
Preamble, skip if you don't want to read any preliminary background information. The guide is designed not to just get you on your way with a server set up (as most other tutorials strive to do), it is also designed to help you understand why these things are being done. Before following this or any other guide, make sure you fully understand the commands you are about to run before running them or you may cause damage to your system. Some commands can be specially crafted and look innocent. In this guide, I will show you how to create a user account that should be used instead of root. Then we will give the account the capability to use sudo so we can run any commands that require elevated privileges.

*Extra information: Ubuntu, like many other Linux distributions, is designed as a multi-user system that is built around privileges. For example, certain users can be given the capability to run or access things that other users cannot - all in a hierarchical model. The 'root' account is the 'God' account. Be careful with this account. It is capable of wiping the drive of the system while the system is running, unlike Windows. We will avoid logging in as root and instead focus on elevating to 'root privileges' when we need to do something that requires more privileges than our standard account. Following this method helps prevent typing mistakes (if we read over what we wrote) and prevents people who have seen us type our log in use it for malicious tasks.*

There are only a few things in life that come easy. Installing software packages in Linux is one of them - usually. If you're new, you are probably under the impression that terror lies ahead in using the command-line. Luckily for you, common packages are installed from repositories, most of which your system is already configured to access.

So, what is a repository? Well, good question. Think of your server has a house within an ecosystem of resources, like a city. Your house is connected to 'repositories' like the supermarket, for food. It is connected to Costco for everything else. Common items, packages, are found in these repositories. The connection takes place by roads, which in our case here, is our SSH session. When you want a package, you can run a simple one-line command that will fetch it and install it on your system - like a phone call to Costco that leads to a delivery. There are many repositories, some enabled by default. In this case, Costco is one of the two.

Now that we know our server will  fetch packages, it's good to know something else you may not be aware of if you are coming from Windows. Installing something on your machine, such as Apache, will install a network of dependencies. Dependencies are little components, applications, or libraries required to make up the whole Apache install. Running an install command for a one could result in hundreds of dependencies that need to be installed to complete your request - such as installing the Gnome interface on a server (don't ever do that).

Repositories may store different versions of packages for different systems. Package managers are configured for the corresponding repository and the package manager is 'smart' enough to use what it needs. For example, some software is compiled for Ubuntu 12.04 32-bit and has separate compiled versions for 64-bit system (you'll likely see 'amd64' in the package name for these).

When you run the install command, the appropriate version should be selected for your system, unless you add a third-party repository or you specifically choose a version to install). It should be noted that 32-bit systems cannot install 64-bit packages but 64-bit can install 32-bit.

Enough preamble.


For the purpose of this tutorial, I'm going to assume you are using either a dedicated or virtual server and that you have root access to this system. The tutorial will also assume you are starting from a standard, fresh install of 12.04LTS, such as you would find from an Ubuntu.com download (Amazon's images may have some modifications).

First things first. There are some best practises you should understand before beginning your foray. On a server:

  1. Use root only when you need root privileges (http://askubuntu.com/a/16179). Server admins are not vigilantes (well, not always) and should take this seriously. There will come a time that you agree.
  2. Install only what you need to (the more you have running, the greater the attack vectors at an attacker's disposal. And they will find you)
  3. Stick to an LTS release (Long Term Support - it will be supported longer and will therefore be more robust down the line)
  4. Avoid new server releases for production machines if you need stability and security. Not that there's anything wrong with the integrity of the development team or their releases, but you should want to have a tested and patched system.
  5. Avoid graphical interfaces (For one, you'll learn your server better if you interact with it through the CLI - command line interface. Secondly, tons of packages will need to be installed that you won't require and are arguably going to be your worst security decision. Thirdly, graphical interfaces are not optimized for servers. Fourth, most, if not all server tools will not have a graphical interface.)
  6. You do not enter the '$' that is shown before each command. It is simply there to let you know you will be typing at the prompt.

Connecting to Your Server

If you are using Windows, you will need a tool such as PuTTY or KiTTY to connect to your server. If you are using Mac or Linux, you can use the built-in Terminal emulator and run a command to connect to the server. I am going to create the user 'john' and use johnghawi.com as the host (server address). You will need to use your own domain name or the server's IP address.

*For the first log in, you will likely need to use your root log in (user is root) unless an account was created for you. For commands, do not type the $ at the beginning.

Windows:

Protocol: SFTP/SSH
Username: root
Host: johnghawi.com
Port: 22

Linux/OSX:


$ ssh root@johnghawi.com

In the above command, we do not add the port because 22 is the default port. If you change your default ssh port to something like 50, you will need to specify it as shown below:


$ ssh -p 50 root@johnghawi.com

You will then be prompted for authentication to connect to your server. As this is your first time connecting to it from that system, accept it. The purpose of this notification is to make you aware of any man-in-the-middle attacks.

The next prompt will be for your password, enter it. You should be given a quick summary screen and a prompt waiting for a command. The next step is to patch the server with any updates. If you are logged in as root, you do not need to have 'sudo' in the command, but I will leave it in there for future reference.


$ sudo apt-get update
$ sudo apt-get upgrade


The first command updates those repositories I mentioned earlier. The next step applies necessary updates. The 'upgrade' command will not move you between server releases (12.04 to 13.04) unless you apply the -d switch. If you do not wish to have the patches applied directly, you can modify the second command by appending -y at the end (sudo apt-get upgrade -y).

This process may take some time depending on your server and the number of updates.

*TIP: You can concatenate two commands by adding && in-between. For example:


$ sudo apt-get update && sudo apt-get upgrade


*Note that you must add sudo before the second command (if not root). The importance of using the && operator is that if the first command fails for any reason (such as a spelling error), the second line will never run. Every concatenated command will only run if the command before it passes (or returns TRUE).


Hostname

Ubuntu reads the hostname from /etc/hostname file. You can find the system hostname by typing 'hostname' at the prompt.


$ hostname johnny


The above command will change the hostname to johnny until the next server reboot.

To change the hostname and have it persist across reboots, we need to edit the /etc/hostname file.

Since the file is in the /etc directory, we would need to elevate to superuser privileges if we are not currently logged in as root. If you are following this tutorial, you should still be logged in as root.

Check your current hostname:

$ hostname


*If you get an error, you likely do not have the 'net-tools' package installed. Run this command first:

$ apt-get install net-tools -y


Permanently changing your hostname is more useful. Do this by opening the /etc/hostname file in nano, a simple CLI text editor:

$ nano /etc/hostname


I would put johnghawi.com and you could put your domain. The hostname does not need to be a Fully Qualified Domain Name (FQDN) but it should be something unique. The hostname can be used to differentiate between servers using names like panther and tiger.

Ubuntu then uses /etc/init.d/hostname.sh to set the hostname at boot from  /etc/hostname. Essentially, Ubuntu will set the hostname at EACH boot time from the  /etc/hostname file using the hostname.sh script in /etc/init.d. If you are a little lost, simply follow the steps and do not worry much as this is a one-time setting we are making.

We can reboot the server or run the script for the hostname to take effect. Then type hostname to see that the new hostname from the /etc/hostname file has taken effect.


$ /etc/init.d/hostname.sh start

$ hostname


Getting to Know the HOSTS File

We now need to configure the /etc/hosts file. In the event that a DNS server is unavailable - or better yet, let's understand what happens when an application running on the server needs a path to another host. A DNS server typically acts as a dictionary look-up to that translates hostnames (johnghawi.com) to their corresponding IP addresses. But before our server looks to the DNS, it checks the /etc/hosts file to see if any resolutions are first defined there. Upon opening this file (you can use nano), you will notice two entries. 127.0.0.1 is set to localhost and 127.0.1.1 is set to Ubuntu. The latter was placed by Debian to support Gnome applications. If your system has a permanent IP, you can use that instead. Using a domain, you should add your domain and static IP, which is required for SSL.

If set by default in /etc/host.conf, the /etc/hosts file allows us to specify static addresses to be resolved, overriding DNS look-ups. It is important to note that addresses defined in the /etc/hosts file will cause your server to not bother querying BIND/DNS if it finds a relevant entry in the /etc/hosts file. Your server will do is query the /etc/hosts file to see if it should bother going to the DNS. If it finds the resolution in the /etc/hosts file, querying the DNS is skipped.

The /etc/hosts file will look very simple for our set up. Let's open the file:


$ nano /etc/hosts


The first thing that you might notice is the alignment of the headers does not align with the content:

IPAddress     Hostname    Alias                             
127.0.0.1          localhost              blog.johnghawi.com
74.125.142.121     blog.johnghawi.com     johnserver
74.125.142.121     webmail.johnghawi.com  johnserver
74.125.142.122     files.johnghawi.com    johnfiles

Let's take a minute to realize what the above table is telling us. At first, it may seem straight forward before it gets confusing. To keep things simple, you may find it easier to approach this table from right to left.

The Alias column on the right is a name for the server, useful when referencing locally on the network. In that case, johnserver maps to hostname blog.johnghawi.com and webmail.johnghawi.com and both resolve to the same IP Address. Next, johnfiles refers to the files.johnghawi.com hostname, which may just be accessible through another of the same server's interface.

Configure your server according to the table above. More than likely, if you are following this tutorial you may only need the first two lines, with the second one being just your domain and no subdomain.

The last step is to either restart your server or the service itself using:


$ /etc/rc.d/init.d/network restart



Timezone

It is a good idea to set the timezone of the system. You may wish to either use the local timezone or the timezone of the majority of your users. The correct timezone may be useful for reading logs.


$ dpkg-reconfigure tzdata


New User

As promised, we will add a new user to the server. We will have two accounts enabled on the system, calling the second user 'john'. The 'root' account (full privileges) and the 'john' account (limited privileges). When using the command line, let's say as the user we're about to create, john, you can switch to another user that exists on the system, such as 'alice' by running $ su alice and entering Alice's password. The su command stands for Substitute User. Alternatively, John does not have to switch Alice's account, he can elevate by using the sudo command (SuperUser Do), which allows john to execute commands given his elevated security clearance, if granted. John will use his own password to elevate. . Let's create 'john':


$ adduser john


Answer the lines accordingly and press enter to use the default, if presented with any. The next step is critical. Its purpose is to give our 'john' account the privilege to elevate by using the 'sudo' command (as you may have seen above). Type $ man usermod to learn what each switch does. Remember, commands are case sensitive; -g != -G.

$ usermod -a -G sudo john

Now we test to make sure we can log in as 'john'. Log out with $ logout or reboot with $ reboot

Use the instructions above to log in using the account name you just created. Type $ sudo nano at the prompt, enter your password, and see if nano opens.  If successful, your new account is set up and has sudo capability. You should start using the new account by default.

Congratulations, your new server is successfully set up! I will be adding Part 2 and linking to it from this article in a week or so outlining steps to harden your server from common attacks.

5 Jun 2013

An Introduction to Users and Groups in Ubuntu

Disclaimer

This is a post you should read fully and understand before blindly following any commands as you can easily strip superuser access if you do not understand what you are doing. In fact, I recommend researching these topics outside of this post to get a better grasp of this area. You can learn more about any command by adding 'man' before it at the terminal. At the very least, ask questions!


Let's Begin

A UID is an entity that can possess ownership of files. A user is a human-readable format for a user id.

Users can belong to more than one supplementary group but each user must belong to one (and only one) primary group.

A group can have many users and group membership provides privileges to shares and resources to users of that group.

To add the user john:
 
$ sudo adduser john
Along with creating the user 'john', the group 'john' will be created as well.

To create the user john and place in the existing group teachers without creating the 'john' group, run:
 
$ sudo adduser john --ingroup teachers

To change a user's primary group, run the command:
 
$ sudo usermod -g group user

You can add the user john to the supplementary groups student and employee with:
 
$ sudo usermod -a -G student,employee john
Note: It is important to pay attention to two things. The -G switch is capital and there is no whitespace between group names. The command line interface (CLI) is very specific to capitalization and format so take care to always be precise.

Running the command without the -a switch will remove the user from any other groups. The -a switch allows you to retain the user's existing groups. Example: without -a, if the user was a member of the group 'teacher' before running the command, he will be removed from the teacher group after the command has successfully executed. That will be the case by running the command that changes the user's primary group. The problem is, if this is your user, you can strip away your superuser rights with that command, so make sure you test this on a non-production system first.

Check your users and ids

You can run $ id to print the logged in user's id and group membership on the screen. Optionally, you can specify which user to print by adding that user as a second argument to the id command.

Running id on my system, I get:
 
john@flare:~$ id
uid=1000(john) gid=1000(john) groups=1000(john),4(adm),27(sudo),30(dip),46(plugdev),118(lpadmin)

Let's understand the information we were returned:
uid=1000(john)
gid=1000(john)
groups=1000(john),4(adm),27(sudo),30(dip)....

My username is john and my userid is 1000. The primary group (gid) that I belong to is also known as john. My user also belongs to the secondary groups: adm, sudo, dip, and so on.

But what are the numbers beside the secondary groups? 
I'm glad you asked. The numbers are reserved id spaces. I use Ubuntu on my laptop. Ubuntu starts human user ids at 1000 (some other distros start at 500). The underlying idea is to give services enough id space to choose their own unique id without interfering with human user ids.

To take a more in-depth look at the users and their information on your system, head to the terminal and type (exit with CTRL+X):
$ nano /etc/passwd
$ nano /etc/group

Each is a text file on your system that your operating system uses to store a list of users and groups. In the group file, you may see your username appended to some of the lines, letting you know the user is a member of that group. In the passwd file, you'll see the username, userid, user's primary group, and the user's home directory.

For more information

To learn more about the command you wish to use (such as usermod), enter man usermod at the terminal to get the manual. If you are using an elevated (such as root) user, you can omit 'sudo' from the commands.

Coming up next: chmod and chown

30 May 2013

Disabling IPv6 on Ubuntu Server 12.04

A few months ago, I was sad to learn that Fail2Ban does not protect against IPv6 traffic. If your web traffic only operates on IPv4, then you have nothing to worry about. That is, unless you have the IPv6 stack enabled and don't need it.

Luckily, I came across a great little post from webupd8.org that I've summarized below (should the post ever be removed). In either case, this post is for anyone wishing to disable IPv6 on their Ubuntu server.

1. Check if the IPv6 stack is enabled. The stack is enabled if the return is 0.

$ cat /proc/sys/net/ipv6/conf/all/disable_ipv6

2. Elevate to root and open your /etc/sysctl.conf file in nano.

$ sudo nano /etc/sysctl.conf

3. Paste the following at the end of the sysctl.conf:

#disable ipv6
net.ipv6.conf.all.disable_ipv6 = 1    
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1     

4. Reboot and perform step 1. If you find the return to still be 0, head over to the webupd8 link above to see the other methods they have listed.