Debian Setup
- Published: March 12, 2010
- | Updated: September 14, 2011
- —
- Debian
Throughout this manual, we’re using nano which is a rather simple text editor. When you find the time, you should try out GNU Emacs and Vim as they are the only real editors out there. They both have a very steep learning curve, but once you get rolling with either of them, you’ll see that it was worth it.
Both editors are shipped with very good documentation and tutorials. In GNU Emacs, hit C-h t (hold down the control key, while it is down, press “h”, release the control key and press “t”). In Vim, make sure the package “Vim” is installed (by default only vim-common and vim-tiny is installed on the server, and these packages lack the tutorial). Then type “vimtutor”, and follow along.
We also recommend the following books: Learning GNU Emacs and Learning the vi and Vim Editors.
Log in
As soon as you’ve got the IP address and root password for your VPS you can log in via SSH:
me@workstation:~$ ssh root@123.4.56.123
Change the root password
example:~# passwd
Add a user
Debian is a multi-user environment. You should not do your everyday work using the root account. It is more than poor practice, it is dangerous. Root is for administrative tasks. Instead, we’ll add a normal, non-root user account through the adduser program. When running the command you’ll be asked some questions concerning the new user. It is up to you how much you fill out, but you should provide a full name at least.
Let’s go ahead and create a new user now. We’ll call him demo, but any name will do.
example:~# adduser demo
This initial setup is the only time you would need to log in as root. To administrate the VPS we need to give the main account super user privileges, so we can complete such tasks through a normal user account. For that, we need to install the sudo package
example:~# aptitude install sudo
To add a user as a sudo user (a “sudoer”), the visudo command must be run as root. visudo copies the /etc/sudoers file to be edited to a temporary file, edits it with an editor, and subsequently runs a sanity check on the input. If it passes, the temporary file overwrites the original with the correct permissions.
example:~# visudo
In the user privilege section add your user name below root
demo ALL=(ALL) ALL
So that the section now looks like
# User privilege specification
root ALL=(ALL) ALL
demo ALL=(ALL) ALL
The part after the user name gives you full root privileges when you precede a command with sudo.
SSH
Secure Shell (SSH) is a network protocol that allows data to be exchanged over a secure channel between two computers. Encryption provides confidentiality and integrity of data. SSH uses public-key cryptography to authenticate the remote computer and allow the remote computer to authenticate the user if necessary.
SSH is typically used to log into a remote machine and execute commands, but it also supports tunneling, forwarding arbitrary TCP ports and X11 connections. File transfer can be accomplished using the associated SFTP or SCP protocols.
An SSH server listens on the standard TCP port 22 by default. An SSH client program is typically used for establishing connections to an sshd daemon accepting remote connections. Both are commonly present on most modern operating systems.
OpenSSH
OpenSSH (OpenBSD Secure Shell) is a set of computer programs providing encrypted communication sessions over a computer network using the ssh protocol. It was created as an open source alternative to the proprietary Secure Shell software suite offered by SSH Communications Security. It is being developed as part of the OpenBSD project.
OpenSSH is sometimes confused with OpenSSL, but the projects have different purposes and are developed by different teams. The similar name is drawn only from similar goals.
SSH Keys
A very effective way of securing SSH access to your VPS is to use SSH Keys. With these keys you can easily connect to a server, or multiple servers, without having to enter a password for each system.
The keys consist of a public and a private key. The public key is placed on the server, and the private key is placed on your computer. In the image below, the client is the system you type directly on, such as a laptop or desktop system. The server is anything connected to from the client.

Installing OpenSSH locally
Check if you have OpenSSH installed on your computer
me@workstation:~$ ssh -V
If you get something similar to
me@workstation:~$ ssh -V
OpenSSH_5.1p1 Debian-5, OpenSSL 0.9.8g 19 Oct 2007
Then you are good to go, and can skip to the next section.
If you don’t already have OpenSSH installed, that is, you get something like
me@workstation:~$ ssh -V
-bash: ssh: command not found
Then you can install it with
me@workstation:~$ sudo aptitude install openssh
At least if you are on a Debian system.
Generating SSH Keys
When OpenSSH is installed it’s time to create the keys we need. The RSA key pair must be generated on your computer. The public portion of this key will reside on the servers being connected to, while the private portion needs to remain on a secure local area on your computer system. The default is ~/.ssh/id_rsa.
The keys can then be generated by running the ssh-keygen command. It will prompt you for a location which you should leave as the default. The important part here is the passphrase, though. Do not use your account password, and do not leave the passphrase empty. Not setting a passphrase means that anyone who gets hold of your key can use it.
Time to create the keys on your computer
me@workstation:~$ ssh-keygen -t rsa
We just generated a 2048 bit long public/private RSA (-t rsa) key pair with the ssh-keygen command.
In ~/.ssh you’ll now find two files: id_rsa and id_rsa.pub. The pub file holds the public key, which is the file that is placed on your VPS. The other file (id_rsa) is your private key. Never show, give away, transfer the file over the network, or keep the file on a public computer.
Using keychain
Keychain manages one or more private keys. When initialized it will ask for the passphrase for the private key(s) and store it. That way, your private key is password protected but you won’t have to enter the password over and over again.
Install keychain on your computer
me@workstation:~$ sudo aptitude install keychain
Edit ~/.bashrc
me@workstation:~$ nano ~/.bashrc
Add the following to the file
eval `keychain --eval --nogui -Q -q id_rsa`
Close your shell and open it again. Keychain should come up and ask for the passphrase of your private key(s) if it’s the first run.
There are other alternatives to keychain. ssh-agent and x11-ssh-askpass, for example. And, several desktop environments have their own solution. The GNOME desktop, for instance, use the GNOME Keyring which can be used as an SSH agent. The goal remains the same, though. That is, to remember the passphrase so you don’t have to type it repeatedly throughout the day.
Copying the keys to the remote server
Now that we have generated the keys, we need to copy the public key to the remote server. We’ll do this with scp (secure copy). The scp man page says that it “copies files between hosts on a network. It uses ssh for data transfer, and uses the same authentication and provides the same security as ssh”.
Issue the following command on your computer
me@workstation:~$ scp ~/.ssh/id_rsa.pub demo@123.4.56.123:
Note the colon at the end of the command below. It means that the file will be copied to the user’s home directory.
Next up is to create the ~/.ssh directory and concatenate the key we just copied to the authorized_keys file on the server. We also need to sort out a few permissions.
Since we’re already logged on the server as root, we’ll switch to the demo account first, then issue the necessary commands:
example:~# su - demo
Then as the user demo
demo@server:~$ mkdir ~/.ssh
demo@server:~$ cat ~/id_rsa.pub >> ~/.ssh/authorized_keys
demo@server:~$ chmod 700 ~/.ssh/
demo@server:~$ chmod 600 ~/.ssh/authorized_keys
demo@server:~$ rm ~/id_rsa.pub
demo@server:~$ exit
Configuring SSH
Let’s change some of the default SSH configuration to make it more secure. Edit the file /etc/ssh/sshd_config
example:~# nano /etc/ssh/sshd_config
Then replace its contents with the following:
# Package generated configuration file
# See the sshd(8) manpage for details
# What ports, IPs and protocols we listen for
Port 30000
# Use these options to restrict which interfaces/protocols sshd will bind to
#ListenAddress ::
#ListenAddress 0.0.0.0
Protocol 2
# HostKeys for protocol version 2
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_dsa_key
#Privilege Separation is turned on for security
UsePrivilegeSeparation yes
# Lifetime and size of ephemeral version 1 server key
KeyRegenerationInterval 3600
ServerKeyBits 768
# Logging
SyslogFacility AUTH
LogLevel INFO
# Authentication:
LoginGraceTime 120
PermitRootLogin no
StrictModes yes
AllowGroups ssh-users
RSAAuthentication yes
PubkeyAuthentication yes
#AuthorizedKeysFile %h/.ssh/authorized_keys
# Don't read the user's ~/.rhosts and ~/.shosts files
IgnoreRhosts yes
# For this to work you will also need host keys in /etc/ssh_known_hosts
RhostsRSAAuthentication no
# similar for protocol version 2
HostbasedAuthentication no
# Uncomment if you don't trust ~/.ssh/known_hosts for RhostsRSAAuthentication
#IgnoreUserKnownHosts yes
# To enable empty passwords, change to yes (NOT RECOMMENDED)
PermitEmptyPasswords no
# Change to yes to enable challenge-response passwords (beware issues with
# some PAM modules and threads)
ChallengeResponseAuthentication no
# Change to no to disable tunnelling clear text passwords
PasswordAuthentication no
# Kerberos options
#KerberosAuthentication no
#KerberosGetAFSToken no
#KerberosOrLocalPasswd yes
#KerberosTicketCleanup yes
# GSSAPI options
#GSSAPIAuthentication no
#GSSAPICleanupCredentials yes
X11Forwarding no
X11DisplayOffset 10
PrintMotd no
PrintLastLog yes
TCPKeepAlive yes
#UseLogin no
#MaxStartups 10:30:60
#Banner /etc/issue.net
# Allow client to pass locale environment variables
AcceptEnv LANG LC_*
Subsystem sftp /usr/lib/openssh/sftp-server
UsePAM no
UseDNS no
We changed the following in /etc/ssh/sshd_config on the server
Port 30000 # change this to a port number of your choosing
PermitRootLogin no # turn off root login
PasswordAuthentication no # we use keys instead of passwords
AllowGroups ssh-users # only allow ssh login for group members of ssh-users
X11Forwarding no # don't allow X11 forwarding
UsePAM no # turn off the Pluggable Authentication Module
UseDNS no # don't look up remote host to check host name
The AllowGroups ssh-users means that anyone wanting to use ssh must be a member of this group. Since the group doesn’t exist, we need to create it
example:~# groupadd ssh-users
And then we need to add our main user to the group
example:~# usermod -a -G ssh-users demo
Hosts access
To further restrict access to the server, we’ll set up access based on hosts. Edit /etc/hosts.allow on the server and add your IP address to the file if you’re on a static IP address. If not, you need to add your Internet Service Provider’s IP subnet.
This file will only allow login access to certain IP addresses, so it’s important to get the IP range right or you will lock yourself out of the server. You may want to add an IP address that you know won’t change. If you are a student, having the IP address of your school or University is a good idea.
Open /etc/hosts.allow with
example:~# nano /etc/hosts.allow
Then add your IP address or IP range to the file
# /etc/hosts.allow: list of hosts that are allowed to access the system.
# See the manual pages hosts_access(5) and hosts_options(5).
#
# Example: ALL: LOCAL @some_netgroup
# ALL: .foobar.edu EXCEPT terminalserver.foobar.edu
#
# If you're going to protect the portmapper use the name "portmap" for the
# daemon name. Remember that you can only use the keyword "ALL" and IP
# addresses (NOT host or domain names) for the portmapper, as well as for
# rpc.mountd (the NFS mount daemon). See portmap(8) and rpc.mountd(8)
# for further information.
#
ALL: 20.200.0.0/255.255.0.0
Alright, we’ve now said that everyone coming from the IP range 20.200.0.0 can log in, but we have not yet restricted the access. To do that we need to edit the /etc/hosts.deny and disallow access to everyone but the IP address(es) listed in the allow file.
Edit the file /etc/hosts.deny on the server and change the last line
example:~# nano /etc/hosts.deny
Then change the last line to
# /etc/hosts.deny: list of hosts that are _not_ allowed to access the system.
# See the manual pages hosts_access(5) and hosts_options(5).
#
# Example: ALL: some.host.name, .some.domain
# ALL EXCEPT in.fingerd: other.host.name, .other.domain
#
# If you're going to protect the portmapper use the name "portmap" for the
# daemon name. Remember that you can only use the keyword "ALL" and IP
# addresses (NOT host or domain names) for the portmapper, as well as for
# rpc.mountd (the NFS mount daemon). See portmap(8) and rpc.mountd(8)
# for further information.
#
# The PARANOID wildcard matches any host whose name does not match its
# address.
# You may wish to enable this to ensure any programs that don't
# validate looked up hostnames still leave understandable logs. In past
# versions of Debian this has been the default.
ALL: ALL
iptables
We’re going to install and setup iptables to secure the VPS further. iptables is a tool for administrating the built-in firewall capabilities of the Linux kernel.
Let’s have a look at the currently active rules
example:~# iptables -L
You’ll get the following output
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
At the moment, our VPS is accepting anything from anyone on any port and allowing anything to happen. But, we’re going to do something about that. We’ll set it up so that only three ports are open: ssh, http and https.
First we’ll create a file that will hold our rules for testing purposes. Edit /etc/iptables.test.rules
example:~# nano /etc/iptables.test.rules
Then fill it with the following rules
*filter
# Allows all loopback (lo0) traffic and drop all traffic to 127/8 that doesn't use lo0
-A INPUT -i lo -j ACCEPT
-A INPUT ! -i lo -d 127.0.0.0/8 -j REJECT
# Accepts all established inbound connections
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Allows all outbound traffic
# You can modify this to only allow certain traffic
-A OUTPUT -j ACCEPT
# Allows HTTP and HTTPS connections from anywhere (the normal ports for websites)
-A INPUT -p tcp --dport 80 -j ACCEPT
-A INPUT -p tcp --dport 443 -j ACCEPT
# Allows SSH connections
-A INPUT -p tcp -m state --state NEW --dport 30000 -j ACCEPT
# Allow imaps
#-A INPUT -p tcp --dport 993 -j ACCEPT
# Allow ping
-A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT
# log iptables denied calls
-A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7
# Reject all other inbound - default deny unless explicitly allowed policy
-A INPUT -j REJECT
-A FORWARD -j REJECT
COMMIT
Save the file, and load the rules with
example:~# iptables-restore < /etc/iptables.test.rules
Check that the rules were loaded successfully with
example:~# iptables -L
The output should now be
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all -- anywhere anywhere
REJECT all -- anywhere loopback/8 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
Save the rules permanently
example:~# iptables-save > /etc/iptables.up.rules
Our iptables rules will get lost when we reboot the server. After a reboot, we’ll go back to allowing everything from everywhere. Let’s address that by making sure our rules are applied when we reboot the server.
Edit /etc/network/interfaces
example:~# nano /etc/network/interfaces
Add the line below “iface lo inet loopback”
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).
# The loopback network interface
auto lo
iface lo inet loopback
pre-up iptables-restore < /etc/iptables.up.rules
# The primary network interface
(...)
Testing
Time to check if everything works. Reload ssh on the server so it uses the new ports and configurations
example:~# /etc/init.d/ssh reload
Do not log out. If this doesn’t work, we have effectively locked ourself out from the server. But by keeping the connection alive in another terminal, we can fix things on the server in case it doesn’t work.
Switch to a terminal on your local computer, then try to log in. You need to change the port number (30000) to the port you’re using, and you also need to change the IP address.
me@workstation:~$ ssh -p 30000 demo@123.4.4.123
If all goes well, you should login without a password to a plain terminal on your VPS.
SSH configuration tips
Your SSH session will automatically time out if it is idle. To keep the connection active, edit the file ~/.ssh/config on your local computer
me@workstation:~$ nano ~/.ssh/config
Add the following
ServerAliveInterval 180
This will send a keep alive signal to the server every 3 minutes.
One other handy tip is related to server login. When you log in to the server you would typically write
me@workstation:~$ ssh -p 30000 demo@123.4.4.123
But, we can shorten it to
me@workstation:~$ ssh example
To do that, edit your ~/.ssh/config file on your local computer
me@workstation:~$ nano ~/.ssh/config
Add the following
Host example
Port 30000
HostName 123.4.4.123
User demo
You’ll now be able to log on with ssh example.
Setting locales and timezone
Locales is “a framework to switch between multiple languages and allow users to user their language, country, characters, collation order etc.” Set your preferred locales by issuing the following command
demo@server:~$ sudo dpkg-reconfigure locales
When that’s done, we’ll just go ahead and set the timezone as well
demo@server:~$ sudo dpkg-reconfigure tzdata
Package management with aptitude
aptitude is a text-based interface to the Debian GNU/Linux package system. With it, you can view the list of packages available, and perform package management tasks such as installing, upgrading, and removing packages.
A package manager keeps track of what software is installed on the computer, and allows you to easily install new software, upgrade software to newer versions, or remove software that you previously installed.
As the name suggests, package managers deal with packages. That is, collections of files that are bundled together and can be installed and removed as a group.
A lot of the time, a package is just a particular program. For example, the network traffic monitor vnstat is contained in the Debian package of the same name. It is common, however, for programs to consist of several interrelated packages. This is the case with the gimp image editor. It consists not only of the gimp package, but also of the gimp-data package. In addition, several optional add-on packages are also available. It is also possible for several small, related programs to be contained in a single package, like the fileutils package. The fileutils package contains several common Unix commands, such as ls, cp, and so forth.
The job of a package manager, like aptitude, is to present an interface which assist users in managing the collection of packages installed on the computer. aptitude provides such an interface by building on the apt package management system.
The Advanced Packaging Tool (apt)
Being able to install and remove packages is great, but the basic software for doing this (known as dpkg) does exactly that and nothing more. This is fine if you download one or two packages by hand, but quickly becomes cumbersome when you are trying to manage a large number of packages.
When a package requires software you haven’t yet installed, you have to download the newly required software by hand. If you later decide to remove said package, these extra packages will linger on your system, consuming disk space, unless you manually remove them. All of this manual labor is a tedious chore, and so most package management systems come with software which takes care of some or all of it for you.
apt works by keeping a list of the packages that can be downloaded from Debian on your system. This list is used to find packages that need to be upgraded. In addition it is also used to install new packages.
apt solves many dependency problems automatically. When you choose to install a package, it will find any additional required packages and install those as well.
When working with a package manager based on apt, such as aptitude, you will typically perform three basic tasks. You will update the list of packages that are available by downloading new lists fromt he Debian servers, you will select which packages should be installed, upgraded, or removed, and finally, you will commit your selections by actually performing the installations, removals and so forth.
Update and upgrade the system with aptitude
The first thing to do is to modify the /etc/apt/sources.list file. The file specifies which packages can be obtained.
demo@server:~$ sudo nano /etc/apt/sources.list
The bare minimum is
deb http://ftp.de.debian.org/debian/ squeeze main
deb-src http://ftp.de.debian.org/debian/ squeeze main
deb http://security.debian.org/ squeeze/updates main
deb-src http://security.debian.org/ squeeze/updates main
Or you can replace the content with the following which has a lot more repositories
deb http://ftp.de.debian.org/debian/ squeeze main contrib non-free
deb-src http://ftp.de.debian.org/debian/ squeeze main contrib non-free
deb http://security.debian.org/ squeeze/updates main contrib non-free
deb-src http://security.debian.org/ squeeze/updates main contrib non-free
Next is to update the list of packages
demo@server:~$ sudo aptitude update
Then upgrade the packages
demo@server:~$ sudo aptitude safe-upgrade
You need to do this regularly to keep your server up-to-date. It is a good idea to join the debian-security-announce mailing list as well.
Some useful aptitude commands
# search for <package name>
aptitude search <package name>
# list installed <package name>
aptitude search <package name>|grep \^i
# search for "gcc" in the description field
aptitude search '~dgcc'
# install <package name>
sudo aptitude install <package name>
# remove <package name>
sudo aptitude remove <package name>
