This is a basic collection of things I do when setting up a new headless ubuntu machine as a webserver. Following the steps below should give you a reasonable secure server with HTTP/2 support (including ALPN in chrome) and the fast NGINX server. I am happy to add things so leave a comment.
After creating the server (droplet on DigitalOcean) log in with
ssh root@[IP ADDRESS]
Once inside the machine set a password for root:
passwd
Update your package manager:
apt-get update
apt-get upgrade
apt-get dist-upgrade
Install fail2ban:
apt-get install fail2ban
Install vim:
apt-get install vim vim-scripts vim-doc vim-latexsuite vim-gui-common vim-gnome vim-gtk
Create a new user:
useradd deploy
mkdir /home/deploy
mkdir /home/deploy/.ssh
chmod 700 /home/deploy/.ssh
Give the new user a sudo password:
passwd deploy
Add your ssh key:
vim /home/deploy/.ssh/authorized_keys #add your public ssh key here, copy your public ssh key from your local with: `pbcopy < ~/.ssh/id_rsa.pub`, create a new one with `ssh-keygen -t rsa`
chmod 400 /home/deploy/.ssh/authorized_keys #permissions
chown deploy:deploy /home/deploy -R #owner
And add the user to the superuser group
visudo
Add into the file:
root ALL=(ALL) ALL
deploy ALL=(ALL) ALL
Disable root login and password authentication
vim /etc/ssh/sshd_config
Edit:
PermitRootLogin no
PasswordAuthentication no
AllowUsers deploy@(your-ip) deploy@(another-ip-if-any) #you can even whitelist IPs from where you connect from (optional)
Restart the ssh service
service ssh restart
Now test your login with the new user in a new shell:
ssh deploy@[ID ADDRESS]
Install unattended-upgrades
sudo apt-get install unattended-upgrades
Edit what is updated:
sudo vim /etc/apt/apt.conf.d/10periodic
Modify so you have:
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Download-Upgradeable-Packages "1";
APT::Periodic::AutocleanInterval "7";
APT::Periodic::Unattended-Upgrade "1";
and specify what upgrades should be done:
sudo vim /etc/apt/apt.conf.d/50unattended-upgrades
The default here is often fine:
Unattended-Upgrade::Allowed-Origins {
"${distro_id}:${distro_codename}-security";
};
Now install logwatch:
(This will typically install postfix and ask you about your mail setup)
sudo apt-get install logwatch
Now edit what to do with the logs. I usually have them send to my email to sort them into a folder there:
sudo vim /etc/cron.daily/00logwatch
Modify so you have something like (change [email protected]
to your email):
/usr/sbin/logwatch --output mail --mailto [email protected] --detail high
I like to disable /run/shm
read/write privileges as they are not needed in a headless server:
sudo vim /etc/fstab
And add the following line:
none /run/shm tmpfs defaults,ro 0 0
Install rootkit detection with RKHunter and CHKRootKit:
sudo apt-get install rkhunter chkrootkit
Configure CHKRootKit:
sudo vim /etc/chkrootkit.conf
Modify so you have:
RUN_DAILY="true"
To run RKHunter execute the following command as often as you update apt-get
:
sudo rkhunter --update
(This will update it’s database and performe a check)
I like to change the shell to bash as that’s what I like.
sudo apt-get install csh
sudo chsh -s /bin/bash deploy
(see after reconnect)
First make sure you have IPv6 enabled:
sudo vim /etc/default/ufw
It should say:
IPV6=yes
Then make sure you are not locked out:
sudo ufw allow ssh
I would also usually do:
sudo ufw allow https
sudo ufw allow http
sudo ufw allow ftp
Then enable the firewall:
sudo ufw enable
And to make sure you have everything enabled and no useless ports open:
sudo ufw status
To reload the firewall you can:
sudo ufw reload
And to see the log you do:
sudo grep UFW /var/log/syslog
To set your correct timezone:
sudo dpkg-reconfigure tzdata
Install the time protocol daemon
sudo apt-get install ntp
Now as we all have moved to SSD servers we don’t need this anymore. :)
For legacy reasons:
get memory with `free -m`
sudo fallocate -l 1G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
sudo sh -c 'echo "/swapfile none swap sw 0 0" >> /etc/fstab'
sudo apt-get install vsftpd
Edit the config:
sudo vim /etc/vsftpd.conf
Modify so you have:
anonymous_enable=NO
write_enable=YES
And restart your service:
sudo service vsftpd restart
(connection via SFTP)
Install git if it isn’t already:
sudo apt-get install git
And set your account:
git config --global user.name "Your Name"
git config --global user.email "[email protected]"
Install node and NPM:
sudo apt-get install nodejs
sudo apt-get install npm
Because there was a name clash in the package manager we have to add a symlink to get the node
namespace working:
sudo ln -s /usr/bin/nodejs /usr/bin/node
Install your server of choice. NGINX is what I like:
sudo apt-get install nginx
For HTTP/2 to be supported you will need to check the version of NGINX and openSSL:
nginx -v
openssl version
NGINX needs to be at least 1.9.5 or above and OpenSSL needs to be at least 1.0.2 or above (for ALPN to work in chrome).
Create a symlink to get to your html folder quickly and give permission:
sudo ln -s /var/www/html/ /www
sudo chown deploy:deploy /var/www/html/ -R
And edit the NGINX config:
sudo vim /etc/nginx/sites-available/default
To delete a page in vim
just type :1,$d
in the command prompt. I usually write the config locally and then just past it into vim. So: copy content, open file in vim, do :1,$d
to delete contents, type i
to set vim into insert mode, paste.
(I’ve attached my basic config that works for me below, note that this config assumes SSL and the cypher below)
To create a strong cypher:
sudo mkdir /etc/nginx/ssl/
sudo openssl dhparam -out /etc/nginx/ssl/dhparam.pem 4096
(This takes some time)
Restart the server with the new config:
sudo nginx -s reload
Install letsencrypt because we want to add SSL to our website to secure our users right?
cd /home/deploy/
git clone https://github.com/letsencrypt/letsencrypt
cd letsencrypt
./letsencrypt-auto --help
./letsencrypt-auto
If you are running NGINX and the loader is broken (as it is currently as of May 2016) run:
./letsencrypt-auto certonly --server https://acme-v01.api.letsencrypt.org/directory
Set up auto renewal. Open crontab:
sudo crontab -e
And add the two following lines:
SHELL=/bin/bash # I like bash
# add timestamp to your log file for easier parsing
29 2 * * 1 date >> /var/log/letsencrypt-renewal.log 2>&1
# runs every Monday at 2:30AM, output is saved to /var/log/letsencrypt-renewal.log
30 2 * * 1 /home/deploy/letsencrypt/letsencrypt-auto renew --webroot-path /www/ >> /var/log/letsencrypt-renewal.log 2>&1
# restart the server 2:35AM
35 2 * * 1 /etc/init.d/nginx restart >> /var/log/letsencrypt-renewal.log 2>&1
# empty line at the end so cron doesn’t ignore the last command
This will try to renew your certs every Monday night and reload NGINX while saving the log into /var/log/letsencrypt-renewal.log
. (Check your log if you have issues with vim /var/log/letsencrypt-renewal.log
)
Now test your SSL certs via: