Sunday, September 1, 2019

Web host set-up with fresh Debian 11 Install

Note: Installation performed on a VPS KVM server

Why install Debian over Ubuntu?  After all Ubuntu is more user friendly and prepackaged with more software. However, disk space is at a premium with the current VPS I'm using.  I chose Debian over Ubuntu because Debian comes bare minimum, not bundled or prepacked with additional software and features like Ubuntu. With Debian I have more control over the software installed making it lighter and faster than Ubuntu.

First update and upgrade

# apt update
# apt upgrade

Install Firewall (ufw)

# apt-get install ufw
Firewall needs to be enabled
# ufw enable
Verify firewall is active
# ufw status verbose
Allow access to port 22
# ufw allow 22
Configure firewall to allow the following additional ports:

  • 80
  • 8080
  • 443
Recheck ufw status
# ufw status verbose
The results should be similar to the following:
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip
To                         Action      From --                         ------      ---- 22                         ALLOW IN    Anywhere 80                         ALLOW IN    Anywhere 8080                       ALLOW IN    Anywhere 443                        ALLOW IN    Anywhere 22 (v6)                    ALLOW IN    Anywhere (v6) 80 (v6)                    ALLOW IN    Anywhere (v6) 8080 (v6)                  ALLOW IN    Anywhere (v6) 443 (v6)                   ALLOW IN    Anywhere (v6)

Set up user

By default sudo is not installed on Debian
# apt install sudo -y
Run visudo to modify sudoers file and add following line into it (if it is missing):

# Allow members of group sudo to execute any command
%sudo   ALL=(ALL:ALL) ALL
# visudo

Add a user

# adduser example_user

Add to sudo group (if new user needs root privileges)

# adduser example_user sudo
Exit then log-in with new credentials.

Secure SSH Log-in Using PuTTY

Fix unable to find host:

Edit host file

$ sudo nano /etc/host

Add the following near the top:

127.0.0.1    actual hostname

Enable firewall for ssh access

$ sudo ufw allow ssh

Configure the server


Backup the sshd_config file
$ sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
Edit the sshd_config file
$ sudo nano /etc/ssh/sshd_config
Uncomment the following lines (remove the 
leading #):

Port 22
PubkeyAuthentication yes
AuthorizedKeysFile      .ssh/authorized_keys .ssh/authorized_keys2

Generate keys with PuTTYgen

  1. Go to Windows Start menu → All Programs → PuTTY→ PuTTYgen
  2. Generate a public/private key pair
    • Parameters (use defaults)
      • Type of key: RSA
      • bits: 2048
    • click Generate
      • Putty uses mouse movements for randomness
      • When key generation is complete enter a passphrase
      • Save public key
      • Save private key
  3. Install public key on server
    • In the users root directory create .ssh folder
      • $ mkdir ~/.ssh
    • Create a new file as follows:
      • $ nano ~/.ssh/authorized_keys
    • Copy/paste the public key created in step 2 in the new file.  The key must be all on one line.
    •  Save the file
  4. Exit

Disable "root" user


Edit the sshd_config file
$ sudo nano /etc/ssh/sshd_config
For security purposes, change PermitRootLogin to no.  Save file. Reboot.

Install Apache2

$ sudo apt update && sudo apt upgrade
$ sudo apt install apache2
Useful apache commands
## Help ##
$ sudo apache2ctl -h

## List active modules ##
$ sudo apache2ctl -M

## Start ##
$ sudo service apache2 start

## Stop ##
sudo service apache2 stop

## Restart ##
sudo service apache2 restart

Verify apache2 is working by visiting http://your_server_ip. You should reach the Apache2 Debian Default Page.

Install PHP

$ sudo apt update && sudo apt upgrade
$ sudo apt install php libapache2-mod-php php-mysql
Move index.php to the front listing of index files apache will will look for when a directory is requested.
$ sudo nano /etc/apache2/mods-enabled/dir.conf

## Then restart Apache ##
$ sudo systemctl restart apache2

## Verify Apache status ##
$ sudo systemctl status apache2 
Verify your php installation by creat a phpinfo file
## create a new file ##
$ sudo nano /var/www/html/info.php

## Add the following text ##
<?php
phpinfo();
?>
Go to http://your_server_ip/info.php

Upgrade to PHP 7.2


Add PPA
$ sudo apt install apt-transport-https lsb-release ca-certificates
$ sudo wget -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg
$ sudo sh -c 'echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list'
$ sudo apt update
Run the following Command
$sudo apachectl -V
If the Server MTM is prefork install PHP 7.2 with the following
$ sudo apt install php7.2 php7.2-common php7.2-cli libapache2-mod-php7.2
Otherwise install PHP 7.2 with the following
$ sudo apt install php7.2 php7.2-common php7.2-cli php7.2-fpms
Review available php modules
$ ls /etc/apache2/mods-available/php*
Review enabled php modules
$ ls /etc/apache2/mods-enabled/php*
To upgrade to PHP 7.2 disable the current enabled module (7.0 in this instance)
$ sudo a2dismod php7.0
Then enable PHP 7.2
$ sudo a2enmod php7.2
Verify the syntax (should say OK)
$ sudo apachectl -t
Restart Apache
$ sudo service apache2 restart
Verify 7.2 is the active module (Note: you can also rerun info.php)
$ ls /etc/apache2/mods-enabled/php*
Remove old php module (7.0 in this case)
sudo apt purge php7.0*

Add Modules to PHP

List specific modules available to your enabled PHP version.  Hit the tab key twice at the end.
$ sudo apt-get install php7.2[tab][tab]
Here's a sample output
php7.2                   php7.2-fpm
php7.2-bcmath            php7.2-fpm-dbgsym
php7.2-bcmath-dbgsym     php7.2-gd
php7.2-bz2               php7.2-gd-dbgsym
php7.2-bz2-dbgsym        php7.2-gmp
php7.2-cgi               php7.2-gmp-dbgsym
php7.2-cgi-dbgsym        php7.2-imap
php7.2-cli               php7.2-imap-dbgsym
php7.2-cli-dbgsym        php7.2-interbase
php7.2-common            php7.2-interbase-dbgsym
php7.2-common-dbgsym     php7.2-intl
php7.2-curl              php7.2-intl-dbgsym
php7.2-curl-dbgsym       php7.2-json
php7.2-dba               php7.2-json-dbgsym
php7.2-dba-dbgsym        php7.2-ldap
php7.2-dev               php7.2-ldap-dbgsym
php7.2-enchant           php7.2-mbstring
php7.2-enchant-dbgsym    php7.2-mbstring-dbgsym
You can add single or multiple modules with the following command
$ sudo apt-get install module_name_1 module_name_2
Here's a good article on the subject.

Install MySQL

Download deb package
$ sudo apt update && sudo apt upgrade
$ wget http://repo.mysql.com/mysql-apt-config_0.8.13-1_all.deb
$ sudo dpkg -i mysql-apt-config_0.8.13-1_all.deb
You will be prompted to select a mysql version. Choose the defaults. Next, Install MySQL
$ sudo apt update
$ sudo apt install mysql-server
You should be prompted to enter a password for root. If you weren't prompted enter the following commands:
$ sudo service mysql stop
$ sudo mkdir /var/run/mysqld; sudo chown mysql /var/run/mysqld
$ sudo mysqld_safe --skip-grant-tables&
You can now log in as root without a password.

Set a password for root
$ sudo mysql --user=root mysql
This will log you into MySQL. If you're using MySQL 5.6 or below enter the following
mysql> update user set Password=PASSWORD('new-password') where user='root';
flush privileges;
If you're using MySQL 5.7 or above enter the following
mysql> update user set authentication_string=PASSWORD('new-password') where user='root';
flush privileges;
From there, quit (kill the running msqld) mysql and start it as normal.

Stop MySQL
$ sudo service mysql stop
Start MySQL (Normal)
$ sudo service mysql start
Kill the temporary mysql safe mode session
$ sudo mysqladmin shutdown
Check the status
$ sudo service mysql status

Set Up Domain (Virtual Host)

Create directory structure:

$ sudo mkdir -p /var/www/your-domain.com/public_html
The above creates directories owned by root.  Change ownership so other users can access.
$ sudo chown -R $USER:$USER /var/www/your-domain.com/public_html
Modify permissions to ensure that read access is permitted to the general web directory and all of the files and folders it contains.
$ sudo chmod -R 755 /var/www
Set up a temporary web page for testing
$ nano /var/www/your-domain.com/public_html/index.html
Add the following contents<
<html>
  <head>
    <title>Welcome!</title>
  </head>
  <body>
    <h1>Welcome to our test page!</h1>
  </body>
</html>

Create New Virtual Host File


Apache comes with a default virtual host file called 000-default.conf.  Copy this file for your domain.
$ sudo cp /etc/apache2/sites-available/000-default.conf /etc/apache2/sites-available/your-domain.com.conf
Open your-domain.conf file just created.
$ sudo nano /etc/apache2/sites-available/your-domain.com.conf
The file contents should look something like this:
<VirtualHost *:80>

        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/html

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

</VirtualHost>
Edit the file with the following changes on red.
<VirtualHost *:80>

        ServerAdmin [email protected]
        ServerName your-domain.com
        ServerAlias www.your-domain.com    
        DocumentRoot /var/www/your-domain.com/public_html

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

</VirtualHost>
Save the file. Create a second copy of the file just edited for https
$ sudo cp /etc/apache2/sites-available/your-domain.com.conf /etc/apache2/sites-available/your-domain.com-ssl.conf
Open your-domain-ssl.conf file just created.
$ sudo nano /etc/apache2/sites-available/your-domain-ssl.com.conf
Change the port from 80 to 443.
<VirtualHost *:443>

        ServerAdmin [email protected]
        ServerName your-domain.com
        ServerAlias www.your-domain.com   
        DocumentRoot /var/www/your-domain.com/public_html

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

</VirtualHost>
Save the file.

Enable the New Virtual Host File


Activate each site as follows:
$ sudo a2ensite your-domain.com.conf
$ sudo a2ensite your-domain-ssl.com.conf
You should get a message that confirms the site was enabled.
Output
Enabling site your-domain.com.
To activate the new configuration, you need to run:
  service apache2 reload
Disable 000-default.conf as follows:
$ sudo a2dissite 000-default.conf
Restart Apache.
$ sudo systemctl restart apache2
The sites are configured.  Verify that you can reach the site.  Note you will not be able to access the https site until you have created a ssl certificate.

Secure Website


You can secure your website with a free Let's Encrypt Certificate. Let's Encrypt Certificate installation was not available on Debian 9.9 by default.  To make it accessible by APT we need to add the backports repository where APT looks for packages.

Install certbot


Open the sources list.
$ sudo nano /etc/apt/sources.list
Add the following to the bottom of the file:
$ deb http://ftp.debian.org/debian stretch-backports main
Perform an update:
$ sudo apt update
Install certbot.  Not the -t option tells apt to search the backports repository.
$ sudo apt install python-certbot-apache -t stretch-backports

SSL installation 


Verify that your your-domain.com.conf file (see Create New Virtual Host File) includes the ServerName line.
$ sudo nano /etc/apache2/sites-available/your-domain.com.conf
## Should Include the following line ##
ServerName your-domain.com;
Check syntax:
$ sudo apache2ctl configtest
Reload apache
$ sudo systemctl reload apache2
Make sure the https port 443 is included in your firewall configuration. See Install Firewall (ufw).

Install certificate:
$ sudo certbot --apache -d your-domain.com -d www.your-domain.com
The Let's Encrypt Certificate is only valid for 90 days.  However the certbot installation includes a cron script that auto renews the certificate 30 days before expiration.  The script is located at /etc/cron.d.  You can test the renewal process by running the following command:
$ sudo certbot renew --dry-run

Email

$ sudo apt install exim4

Set a fully qualified domain name (FQDN) for the server

$ sudo hostnamectl set-hostname mail.your-domain.com

Update /etc/hosts file

$ sudo nano /etc/hosts
Edit the file as follows:
127.0.0.1       mail.your-domain.com localhost
To verify changes relog-in and run the following
hostname -f

Configure Exim4

$ sudo dpkg-reconfigure exim4-config
  1. select Internet Site
  2. system mail name: hostname.domain
  3. IP-addresses to listen on for incoming SMTP connections: default
  4. Other destinations for which mail is accepted: hostname; localhost
  5. Domains to relay mail for: leave blank
  6. Machines to relay mail for: leave blank
  7. Keep number of DNS-queries minimal (Dial-on-Demand)? default (No)
  8. Delivery method for local mail: default (mbox format in /var/mail/)
  9. Split configuration into small files?: default (no)

Check status:

$ sudo systemctl status exim4

Test send email:

$ sudo exim -v [email protected]
From: [email protected]
Subject: Foobar
Text Text Text
Ctl+D to send

Install TLS Certificate


See Secure Website on instructions on installing a Let's Encrypt certificate.  If you already installed a certificate for your website you can append the existing certificate by rerunning the certbot commend with your mail server added at the end. You will be asked if you want to expand your existing certificate.

Install Remote Desktop


Debian includes Gnome desktop by default.  To keep the installation space to a minimum uninstall Gnome.
$ sudo apt purge `dpkg --get-selections | grep gnome | cut -f 1`
$ sudo apt -f install
$ sudo apt purge `dpkg --get-selections | grep deinstall | cut -f 1`
$ sudo apt -f install

Install xfce


Switch to root
$ sudo -i
Use tasksel tool to install desktop environment.
# tasksel
A GUI screen will open.  Select the following then click OK:

  • Debian desktop environment
  • ...xfce
  • SSH Server
Reboot the server

Desktop Remote Login

Add ports 5900 to 5999 to the firewall
$ sudo ufw allow 5900:5999/tcp
$ sudo ufw allow 5900:5999/udp
Install XRDP and TigerVNC server

$ sudo apt-get install xrdp tigervnc-standalone-server
Start and enable XRDP service
$ systemctl start xrdp
$ systemctl enable xrdp
Start a remote desktop session.  Choose Xvnc as the session type.  Log in with your username and password.