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.
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
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 append ” umask=077″ at the end of an existing line)
- In the file /etc/adduser.conf
- 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
- 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 webserver packages
- Apache using the ITK mpm due to security reasons and mod macro
- PHP and some must have extenstions
sudo apt-get install apache2 apache2-mpm-itk 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 phpmyadmin sudo apt-get install postfix
Change the following values in /etc/php5/apache2/php.ini
To increase some limits
- upload_max_filesize = 50M
- post_max_size = 50M
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:
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.
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 cayitk sudo a2enconf macro sudo service apache2 reload
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 wan’t 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.