+++ title = "How to deploy a website WITHOUT LibrePages" date = "2022-09-10" description = "Automation services like LibrePages exist to make lives easier but how do you do the same manually, on self-hosted hardware, or in the cloud?" draft=false [taxonomies] tags = ['bare-metal', 'nginx', 'JAMStack', 'lets-encrypt', 'self-hosting'] [extra] author = 'realaravinth' +++ In this ~~blog post~~ tutorial, I'll show you how to deploy a personal website. LibrePages automates everything that is discussed in this tutorial and lets you focus on creating content. Automation is good but knowing how to do it manually using industry standard technologies always helps! We will be using the following technologies to deploy our website: 1. [GNU/Linux server(Debian)](https://debian.org) 2. [Nginx](https://www.nginx.com/) (webs server) 3. [Let's Encrypt](https://letsencrypt.org/) (for HTTPS) Let's get started! ## 1. Setup Debian GNU/Linux We are going to start with a fresh GNU/Linux installation, you could get one from a cloud provider like [Digital Ocean](https://www.digitalocean.com) (not affiliated). ### 1.1) Give your account `sudo` privileges On GNU/Linux systems, the `root` account is the most powerful user account. It is good practice to avoid working as `root` since a careless mistake could wipe the entire system out. `sudo` give the ability to execute commands with `root` capabilities from a lower-privileged account. Let's make our account sudo capable: ```bash su # become root # add `realaravinth`, my account` to `sudo` group to be able to use `sudo` usermod -aG sudo realaravinth # my account is called `realaravinth`, replace it with yours exit $ exit ``` Log out and log back in. ### 1.2) Install and setup firewall(`ufw`) [Uncomplicated Firewall(`ufw`)](https://wiki.ubuntu.com/UncomplicatedFirewall) is a popular firewall that is easy to set up and maintain. For most installations, this should be enough. System administrators use firewalls to open only the ports that they think should receive traffic from external networks. Without it, all ports will be open, causing a security nightmare. We will require standard SSH (22), and the standard web ports (80 and 443). A comprehensive list of services and the list of ports the listen on is available at `/etc/services`. ```bash $ sudo apt update && apt upgrade # update system $ sudo apt install ufw # we are using `ufw` for the firewall $ sudo ufw allow ssh # allow SSH traffic on port 22, required to log into the server $ sudo ufw enable # deploy firewall ``` ### 1.3) Secure SSH SSH allows remote access to our servers over secure, encrypted channels. By default, users can log in with their password using SSH. But password authentication [is susceptible to brute force attacks](https://wiki.archlinux.org/title/OpenSSH#Protecting_against_brute_force_attacks), so we should [disable password logins on our server and only allow public-key authentication only](https://wiki.archlinux.org/title/OpenSSH#Force_public_key_authentication). ### 1.3.1) Generate key pair On your local computer, generate an SSH key pair: ```bash $ ssh-keygen Generating public/private rsa key pair. Enter file in which to save the key (/home/realaravinth/.ssh/id_rsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/realaravinth/.ssh/id_rsa Your public key has been saved in /home/realaravinth/.ssh/id_rsa.pub The key fingerprint is: SHA256:i2DE1b9BQb9DqV0r6O9MfPeVqUwfww1/T8wIXL2Xqdo realaravinth@myserver.com The key's random art image is: +---[RSA 3072]----+ | .. .o. | | . . . .. . . | | o o + o .| | . o* + .+| | o S ooB o+.| | . . . o.. +o*=| | . . . ooo*X| | +=.ooB| | o+E .o| +----[SHA256]-----+ ``` Set a strong password the program prompts for one and save it somewhere safe. Your public key will be at `~/.ssh/id_rsa.pub` and your private key at `~/.ssh/id_rsa`. **Never share the private key with anyone**. ### 1.3.2) Setup public-key authentication We have to copy the public key that we generated in the previous setup onto our server: ```bash $ ssh-copy-id -i ~/.ssh/id_rsa.pub myserver.com /usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/realaravinth/.ssh/id_rsa.pub" /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed /usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys realaravinth@myserver.com's password: Number of key(s) added: 1 Now try logging into the machine, with: "ssh 'myserver.com'" and check to make sure that only the key(s) you wanted were added. ``` ### 1.3.3) Disable SSH password authentication > **NOTE: Verify you can log into your account before proceeding** Now that we have a private-key authentication setup on both the client and the server, let's disable password authentication on the server: Open `/etc/ssh/sshd_config` and add the following lines: ``` PubkeyAuthentication yes PasswordAuthentication no ``` And restart the SSH server: ```bash $ sudo systemctl restart sshd ``` ### 1.3) Install and setup `fail2ban` We will be using [`fail2ban`](https://www.fail2ban.org/wiki/index.php/Main_Page) for intrusion prevention by blacklisting entities (users, bots, etc.) based on failed login attempts. #### 1.3.1) Install `fail2ban` ```bash $ sudo apt install fail2ban ``` #### 1.3.2) Enable `fail2ban` for `sshd` ```yml [sshd] enabled = true ``` #### 1.3.3) Configure `fail2ban` to start on boot ```bash $ sudo systemctl enable fail2ban $ sudo systemctl start fail2ban ``` ### 1.4) Install and setup `nginx` `nginx` is a popular web server that can be used to serve static sites. It is fast, stable, and easy to set up. To install, run the following command: #### 1.4.1) Install `nginx`: ```bash $ sudo apt install nginx ``` #### 1.4.2) Allow web traffic: open ports `80` and `443` Ports `80` is the default for HTTP and `443` for HTTPS. To serve web traffic, we'll have to Configure `ufw` to accept traffic on them: ```bash $ sudo ufw allow 80 # open ports 80 HTTP traffic $ sudo ufw allow 443 # open ports 443 for HTTPS traffic ``` #### 1.4.2) Configure `nginx` to start on boot ```bash $ sudo systemtl enable nginx # automatically start nginx on boot $ sudo systemtl start nginx # start nginx server ``` And verify it works: ```bash $ curl localhost
If you see this page, the nginx web server is successfully installed and working. Further configuration is required.
For online documentation and support please refer to
nginx.org.
Commercial support is available at
nginx.com.
Thank you for using nginx.
``` `nginx` is working! ## 2) Deploy website For this demo, we'll deploy a single file(`index.html`) HTML website. ### 2.1) Install the webpage on the server Edit `/var/www/html/index.html` and add the following HTML to it: ```html