Skip to content

Instantly share code, notes, and snippets.

@rahulhaque
Last active July 2, 2022 17:39
Show Gist options
  • Save rahulhaque/2df947f770646ef4d50940b5bb5f96ae to your computer and use it in GitHub Desktop.
Save rahulhaque/2df947f770646ef4d50940b5bb5f96ae to your computer and use it in GitHub Desktop.
CLI Server Setup Guide

Server Configuration Steps (Quickstart)

We all get to work with Linux servers at sometime of our development career. Configuring a newly obtained CLI server (such as - linode, digitalocean, vultr etc.) can be confusing for the new comers as well as one who already knows how to configure one. Here I will try to discuss the steps to go along while configuring a fresh server.

Setup User

If its a new server and you have access to the server as a root user, then you should add a new user which will prevent direct root access.

adduser <username>

Press enter with any information you want to fill out. Then add the user to the root user group with the following command.

usermod -aG sudo,adm,docker <username>

Then set a password for that user with -

passwd <username>

After that disable login as root user to prevent scripted ssh login attempts. Open the sshd_config file with nano /etc/ssh/sshd_config and set the PermitRootLogin to no. This will disable login as root user to your server.

There is one more layer of security we can implement which is disabling the password authentication to the server. Before we disable password authentication, we should generate ssh keys for our client to access the server. To do that, let's generate private and public keys for the client computer (not the server) through which we will access the server. Generate the keys with -

ssh-keygen -b 4096

Enter a passphrase if you think your key might be stolen or you're using shared PC where other users may look into the staff. The above command will create two key files (private) id_rsa and (public) id_rsa.pub in the /home/<user>/.ssh folder.

Transfer the id_rsa.pub key file to your server to access it without typing any password. Easily share the public key with the following command.

ssh-copy-id <your_server_username>@<your_server_ip>

It will ask for your ssh password to copy the key file once. Then you can easily ssh into the server simply by typing

ssh <your_server_username>@<your_server_ip>

Then we can disable password login by editing the sshd_config file with nano /etc/ssh/sshd_config and set the following options -

PasswordAuthentication no
PermitEmptyPasswords no

With that, only the clients authenticated with SSH keys will be able to access the server.

Setup iptables

The first thing you need to do is setup basic iptables rules. It is a command-line firewall utility that uses policy chains to allow or block traffic. Iptables almost always comes pre-installed on any Linux servers. Let's configure iptables for general access.

Run the below command to see current iptables rules by specification.

iptables -S

Above command should return something like this if not made any changes in the iptables.

-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT

If there are other iptables rules rather than those above, we can simple flush the rules to default by iptables -F command.

Now add some basic rules which will allow network loopback, ssh, http and https requests in the server.

sudo iptables -A INPUT -i lo -j ACCEPT
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT
sudo iptables -A INPUT -j DROP

Iptables rules are not persistent. To keep the rules as is after every server restart we need to install iptables-persistent with sudo apt install iptables-persistent. We can backup iptables rules with the command sudo dpkg-reconfigure iptables-persistent. That's all for iptables right now.

References -

Setup UFW

UFW sit at the top of the iptables and provides an easier interface for managing the requests. To check if it is enabled along with which connections are allowed through the firewall, run sudo ufw status. Let's allow some basic and necessary connections.

sudo ufw allow ssh
sudo ufw allow OpenSSH
sudo ufw allow http
sudo ufw allow https

After that, we will start the firewall with sudo ufw enable. We won't need anything more than this unless we have some unique ports to allow from our server.

References -

Setup Fail2ban

Setup and configure fail2ban to protect your server from hackers. This will monitor every ssh login attempt to your server and ban the ones with a set number of wrong attempts within a certain time period defined by you. This will add a reject rule in iptables for all the IPs trying to hack your server automatically. Update server app repositories and install fail2ban in your server.

sudo apt install fail2ban

The above command will install fail2ban as a service which makes it much easier to manage. Fail2ban uses the concept of jail for various network communications. After installing fail2ban, you can find default jail settings in /etc/fail2ban/jail.conf. Default jail configuration holds general rules set for various jail settings. We will be focusing on sshd jail which monitors ssh login attempts. We can edit the default jail.conf file but it is better to create a local configuration file of our own. The default config will set to default if the package is updated. Create a /etc/fail2ban/jail.local file with below configuration.

[DEFAULT]
ignoreip = 127.0.0.1/8 ::1
bantime = -1
maxretry = 3
findtime  = 1h

[sshd]
enabled = true

[nginx-http-auth]
enabled = true

This will configuration will enable two jails along with some default settings.

  • ignoreip: This option enables you to specify IP addresses or hostnames that fail2ban will ignore. To specify multiple addresses, separate them with a space.
  • bantime: This option defines in seconds how long an IP address or host is banned. The default is 600 seconds (10 minutes). Negative value means permanent ban.
  • maxretry: This option defines the number of failures a host is allowed before it is banned.
  • findtime: This option is used together with the maxretry option. If a host exceeds the maxretry setting within the time period specified by the findtime option, it is banned for the length of time specified by the bantime option.

Now save the configuration and restart fail2ban .

sudo service fail2ban restart

That's all. Fail2ban will now keep an eye on intruders and ban them as necessary. You can see newly banned IPs in the iptables rules section.

Below are some useful fail2ban commands for checking its status. The first command will show all the enabled jails details. The second command will show the details of a specific jail.

sudo fail2ban-client status
sudo fail2ban-client status sshd

It is possible that you may also get banned from the server by fail2ban. To unban your IP you must try login from a different IP (use VPN) and unban your actual IP with the command:

sudo fail2ban-client set sshd unbanip <your_ip>

To know more about fail2ban and its commands, here is the official manual.

References -

Setup Server (Apache or Nginx)

Now, install any server you desire to serve the content from your newly obtained server. Most common servers used all over the web are Apache and Nginx. I will put some references that I found most helpful for installing and configuring these.

Apache

Nginx

PHP

Install PHP if you prefer Apache as the server and PHP-FPM if you prefer Nginx as the server.

Add the repository for PHP which is fairly maintained and updated on regular basis.

sudo add-apt-repository ppa:ondrej/php

Then install PHP. Typical Laravel application requires PHP installed with the following modules. I will put them in a single command. Replace the VERSION number as you desire. I am installing for Nginx.

VERSION=7.4
sudo apt install php$VERSION-fpm php$VERSION-intl php$VERSION-xml php$VERSION-bcmath php$VERSION-curl php$VERSION-mbstring php$VERSION-gd php$VERSION-zip php$VERSION-mysql php$VERSION-redis php$VERSION-pgsql php$VERSION-sqlite3 php$VERSION-imagick

Check if PHP is successfully installed with php -v command.

Composer

After installing PHP, we will install Composer for managing PHP dependencies. To quickly install Composer, run the following commands.

php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
sudo php composer-setup.php --install-dir=/usr/bin --filename=composer 
php -r "unlink('composer-setup.php');"

Check if composer is successfully installed with composer -V command.

References -

Setup Database

Every application needs database of some sort. At this stage, we can install any database of our choice and configure them to work with our application. There are so many databases to choose from that it depends entirely on you what you want. In my case I have worked with MySQL, PostgreSQL and MongoDB mostly. I will attach some links to help you install and configure them.

MySQL

Tips: Run mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root --force mysql -p after completing setup to load MySQL database with timezone info. This is necessary if you want to use timezone name for date time conversion, such as - UTC,Asia/Dhaka etc.

PostgreSQL

Redis

MongoDB

Conclusion

This is rundown of steps that will help anyone trying to configure his/her server. Here I have listed all the resources that were helpful in setting up and securing my servers so that you don't have to waste your time on looking for the right blog or sites for the tutorial. In some cases, I have added some detail explanation of my own where I felt like the tutorial might be a little complex and more than what I needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment