My server setup checklist
This is the checklist I follow when I create a new Linux Debian Server. The goal is a safe shared hosting environment where every user can ssh to the server but no user can see the content of another users home folder.
Setup language
You need to setup language if you get error messages like this one
perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
LANGUAGE = "en_US.UTF-8",
LC_ALL = (unset),
LANG = "en_US.UTF-8"
are supported and installed on your system.
perl: warning: Falling back to the standard locale ("C").
Run the following two commands to solve the issue:
locale-gen en_US en_US.UTF-8
dpkg-reconfigure locales
File Permissions
Files should be restricted to the owner only. This must be the case for newly created files. Thus we set an umask that works both locally and over SSH. We also ensure the home folder for the current user, as well as future ones, has those strict permissions.
- In the file
/etc/login.defs
do: umask 077 - In the file
/etc/profile
do: umask 077 - In the file
/etc/pam.d/common-session
do:session optional pam_umask.so umask=077
(you might just need to appendumask=077
at the end of an existing line) - In the file
/etc/adduser.conf
do:DIR_MODE=0700
- run:
chmod -r 700 /home/CURRENTUSER
Login security and Root login security and sudoers
You should not be able to log in as root using password. Instead we use key authentication for root.
Paste your public key into /root/.ssh/authorized_keys
. Try to log in using your key to make sure this works.
passwd -d root
Modify /etc/sudoers
to give your own account full sudo rights. My file looks like this somewhere in the middle:
# User privilege specification
root ALL=(ALL) ALL
UNAME ALL=(ALL) ALL
That is a kinda crude way to do it. On ubuntu the standard way to do is to add the user to the admin group:
sudo adduser USERNAME admin
IP configuration
http://www.go2linux.org/add-second-ip-linux-ubuntu-etc-network-interfaces-709.html
http://www.cyberciti.biz/faq/setting-up-an-network-interfaces-file/
- Make the changes to
/etc/network/interfaces
/etc/init.d/networking restart
Configure mounts and limit disk IO
Please start with reading my guide on how to add storage devices.
If you have loads of RAM available and want to limit disc IO you can tell the kernel to avoid swapping processes out of physical memory for as long as possible:
sudo sysctl vm.swappiness=0
Add/Remove new users
To add a new user use the command: adduser [username]
Note that usage of this command (adduser) is recommended compared to using the more lowlevel command useradd.
To remove a user use the command: userdel -fr [username]
The -fr
part makes sure home folder and other files are delete.
Without it you will have to delete the files using another command.
To list the current users: cat /etc/passwd | cut -d":" -f1
Install web server packages
We install:
- Apache using mod_ruid2 for security reasons and mod macro
- PHP and some must have extenstions
- Postfix
sudo apt-get install apache2
sudo apt-get install libapache2-mod-ruid2
sudo apt-get install libapache2-mod-macro
sudo a2enmod macro proxy_http ssl rewrite
sudo apt-get install php5 php5-gd php5-curl php5-mcrypt php5-json
sudo apt-get install mysql-server mysql-client libapache2-mod-auth-mysql php5-mysql
sudo apt-get install postfix
Configure PHP
Change the following values in /etc/php5/apache2/php.ini
To increase some limits
- upload_max_filesize = 50M
- post_max_size = 50M
- max_execution_time = 300
- memory_limit = 256M
- max_input_vars = 5000
Configure MySQL
We want mysql to use utf8 per default instead of latin1. Find your MySQL configuration file (on most Linux/BSD systems it's /etc/mysql/my.cnf
) and make sure it's got the following statements under the relevant headers. None of these settings should be set per default so just paste them directly under the corresponding header:
[mysqld]
character-set-server=utf8
collation-server=utf8_general_ci
Also make sure you only accept connections from localhost. This is good for security and is the default in Ubuntu 11.10:
[mysqld]
bind-address=127.0.0.1
If you scan your computer from the outside using nmap
you will notice that port 3306
is actually closed from the outside world. With this setting there is no reason to add firewall rules for it.
Restart MySQL and make sure it’s working:
service mysql restart
TODO: query cache size etc.
Configure Apache2
Do you get this message?
apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1 for ServerName
... waiting apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1 for ServerName
We just need to tell apache what the name of the server is. The name of my server is berit
. So I ServerName berit
to /etc/apache2/httpd.conf
:
echo -e "\nServerName berit" | sudo tee --append /etc/apache2/httpd.conf
Upload and update the config files according to this link.
sudo a2dissite 0*
sudo rm /etc/apache2/sites-available/default
sudo rm /etc/apache2/sites-available/default-ssl
sudo a2ensite macrobased
sudo a2enconf macro
sudo service apache2 reload
Configure PHPMyAdmin
Open the file /etc/phpmyadmin/config.inc.php
You may want to hide some system databases from the web interface. To do that you would add a row like this to the middle of the file:
$cfg['Servers'][$i]['hide_db'] = 'information_schema';
$cfg['Servers'][$i]['hide_db'] = '^information_schema|mysql|performance_schema|phpmyadmin|test$';
Add these rows to the end of the file to force SSL and increase the max rows per page:
$cfg['ForceSSL'] = true;
$cfg['MaxRows'] = 1000;
If you want to be able to autologin as root (dangerous but handy on local installations):
$cfg['Servers'][$i]['AllowNoPassword'] = 'true';
$cfg['Servers'][$i]['auth_type'] = 'config';
$cfg['Servers'][$i]['user'] = 'root';
$cfg['Servers'][$i]['password'] = '';
Setting up Backups
I have written a separate guide on how to setup backups for your linux server.