diff options
Diffstat (limited to 'content/blog/2021-03-30-vps-web-server.org')
-rw-r--r-- | content/blog/2021-03-30-vps-web-server.org | 399 |
1 files changed, 399 insertions, 0 deletions
diff --git a/content/blog/2021-03-30-vps-web-server.org b/content/blog/2021-03-30-vps-web-server.org new file mode 100644 index 0000000..d0c1b4f --- /dev/null +++ b/content/blog/2021-03-30-vps-web-server.org @@ -0,0 +1,399 @@ +#+title: How to Set Up a VPS Web Server +#+date: 2021-03-30 +#+description: A beginner's guide to setting up a virtual private server (VPS). +#+filetags: :sysadmin: + +* Shared Hosting vs. VPS +Choosing a place to host a website is one of the most confusing +decisions for beginner web developers. Even for experienced web devs, +choosing between different forms of web hosting can be a daunting +choice. + +First, let's take a look at +[[https://en.wikipedia.org/wiki/Shared_web_hosting_service][shared web +hosting]]. Shared web hosting is a product where you are purchasing a +small piece of a web server that is being shared between many websites. +As a result, the cost of shared hosting is extremely low. You won't have +access to the server itself, which means you can't install your own +software on the server, such as Docker. Usually, you are simply allowed +to connect your domains to the server, set up domain security, and other +small utilities. + +In contrast, a +[[https://en.wikipedia.org/wiki/Virtual_private_server][virtual private +server]] (VPS) is a virtual machine that replicates the environment of +having a dedicated server to yourself. You are able to control the +virtual server's host names, base file system, package manager, etc. +Another great upside of a VPS is that since it's virtual, the company +providing the VPS can dynamically increase the disk size, RAM size, or +number of CPUs at any time. However, the virtual server is still +physically located on a server that is shared between multiple virtual +servers. + +The choice between shared hosting and VPS mostly depends on your skill +level with system administration. If you're comforting working on a +server that is mostly left up to you (or you're willing to learn), then +a VPS is usually a better option. However, shared hosting is a fantastic +option for people who don't want to have to learn how to manage their +server. + +* My Situation +I had used shared hosting for approximately 5 years before trying my +first VPS. I manage a homelab and have had success running a server and +performing typical sysadmin duties, but I was still hesitant to get a +VPS. One fear was that I always struggled to properly set up the +networking part of a server - DNS and hostname configurations were not +my friend. + +As a little bit of background, I originally used +[[https://www.siteground.com][Siteground]] for my initially shared +hosting and stayed on that platform for at least a year. However, the UI +was clunky, and I didn't like how they handled certain technical +aspects, so I switched to [[https://www.namecheap.com][Namecheap]]. +Namecheap was great because it is the service I primarily use for +purchasing domain names, which made it incredibly easy to link them to +my hosting service. However, it was still mediocre shared hosting, and +Namecheap is notorious for not letting you use +[[https://letsencrypt.org][Let's Encrypt]] to obtain free SSL/TLS +certificates; Namecheap wants to make you purchase certificates through +their store. + +Finally, I settled down with [[https://www.iwebfusion.net][iWebFusion]] +for about the last year of my shared hosting. This service was pretty +great, came with free SSL/TLS, and I never had any complaints. + +However, I finally grew tired of not being able to install software on +my own web server. I wanted to be able to try out things like +[[https://postmill.xyz][Postmill]] or [[https://matrix.org][Matrix]]. +This is possible with a VPS, so I decided to grab a new domain name to +try it out. + +* Getting Started: Buying a VPS +The first step to moving over to a VPS is (you guessed it): finding a +VPS provider. For my VPSs, I use [[https://1984hosting.com][1984]] and +prefer their services much more than any alternative, due to their +location (Iceland), their [[https://1984hosting.com/GDPR/][privacy +policy]], their respect for GDPR, and the ability to remain anonymous if +you pay in Bitcoin or Monero. + +[[https://njal.la][Njalla]] is another good, privacy-oriented option for +VPS services. + +You'll have to decide what specifications you want on your VPS. For me, +I only build and deploy low-resource HTML, PHP, and Python websites. +This means I can survive on the smallest VPS: 1 CPU, 1GB of RAM, and +25GB SSD for $5.00 per month. + +As noted above, the great thing about a VPS is you can request your +provider to increase the resources at any time. + +* Configuring DNS Settings +Okay, so now let's get into some actual work that has to be done to get +content moved from a shared host to a VPS. At this point, I'm assuming +you have a shared host with website content that you can still access, +and you've purchased a new VPS and can SSH into that server. + +The first change is minor, but it should be done immediately in order to +get things moving: DNS settings. Go to wherever your DNS settings are +handled. If your shared host also managed your DNS settings, you'll need +to first move that DNS over to your new VPS provider. For me, I route my +DNS through [[https://www.gandi.net][Gandi]]. + +Once you know where your DNS settings are, go ahead and update the =A= +records to match the public IP address of your VPS. For example: + +#+begin_src txt +A example.com xxx.xxx.xxx.xxx +A subdomain xxx.xxx.xxx.xxx +CNAME www example.com. +#+end_src + +If you have any other records that require updates, such as MX or TXT +records for a mail server, be sure to update those accordingly. +Personally, I don't host my own mail server. I route all mail on my +custom domains to [[https://www.migadu.com][Migadu]]. Hosting your own +email server can become complex quickly and is not for beginners. + +DNS changes can take up to 48 hours to propagate, so be sure to give it +some time before assuming you've made an error. + +* Server Updates and Packages +Now that the DNS settings have been changed, let's set up our server +while we wait for the DNS to propagate. First up is to ssh into your +server. If you've signed up with a service like DigitalOcean, you can +add your SSH key to your account and to your VPS droplet so that you +don't need a password in order to SSH. + +#+begin_src sh +ssh root@xxx.xxx.xxx.xxx +#+end_src + +The VPS that is used in this blog post runs Ubuntu 20.04 with an Apache +web server. If you're working on a different operating system (OS) or +want a different web server, such as Nginx, you'll have to use different +commands to set it up. + +First, let's update and upgrade our server. + +*NOTE:* Since we have logged in to the server as =root= for now, we +don't need to use the =sudo= modifier before our commands. + +#+begin_src sh +apt update && apt upgrade -y +#+end_src + +* Create A User Account +While being able to use =root= can be beneficial at times, you shouldn't +use =root= unless you have to. + +So let's set up a new user in our system. The =-m= option below tells +the OS to create a home directory for the new user. + +#+begin_src sh +adduser USERNAME +#+end_src + +Now, create a password for that user. + +#+begin_src sh +passwd USERNAME +#+end_src + +Finally, add the user to the sudoers file, so they can perform +priveleged commands. + +#+begin_src sh +usermod -a -G sudo USERNAME +#+end_src + +If you are using SSH keys and not passwords, you'll need to copy your +SSH key from your local machine to the VPS. If you haven't disabled +password-based SSH yet, the easiest way to do this is =ssh-copy-id= from +your local computer (not from the VPS): + +#+begin_src sh +ssh-copy-id testuser@xxx.xxx.xxx.xxx +#+end_src + +If you've disabled password-based SSH, you'll need to manually copy your +SSH key into the =~/.ssh/authorized_keys= file. + +* Install Software +Our goal here is to host a web server, so the next step is to install +the Apache web server and any other packages we need. + +From this point on, I will be logged in as a user (not =root=) and will +need to use the =sudo= modifier for most commands. + +#+begin_src sh +sudo apt update; sudo apt upgrade -y; sudo apt autoremove -y +sudo apt install apache2 +#+end_src + +If you need other language support, such as PHP, you'll need to install +that too. + +#+begin_src sh +sudo apt install libapache2-mod-php php-dom +sudo a2enmod php +sudo systemctl restart apache2 +#+end_src + +* Website Files & Folders +Next up is to create the directories for the domain(s) we want to be +hosted on this web server. + +#+begin_src sh +cd /var/www +sudo mkdir example.com +#+end_src + +We have a folder for =example.com= now, so let's add an =index.html= +file and put it within a specific =public_html= folder. You don't need +this =public_html= if you don't want it, but it helps with organizing +items related to =example.com= that you don't want to publish to the +internet. + +#+begin_src sh +cd example.com +sudo mkdir public_html && cd public_html +sudo nano index.html +#+end_src + +You can put anything you want in this =index.html= file. If you can't +think of anything, paste this in there: + +#+begin_src html +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="utf-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <title>Hello, world!</title> + </head> + <body> + <h1>Hello, world!</h1> + </body> +</html> +#+end_src + +If you want something to be served at =example.com/page01/file.txt=, +you'll have to create the =page01= directory under the =example.com= +directory. For example: + +#+begin_src sh +cd /var/www/example.com/public_html +sudo mkdir page01 +sudo nano file.txt +#+end_src + +* Apache Configuration +Now, let's set up the files that will tell the server where to find the +files for =example.com=. We will copy the default configuration file and +create our own. + +#+begin_src sh +cd /etc/apache2/sites-available +sudo cp 000-default.conf example.com.conf +sudo nano example.com.conf +#+end_src + +This configuration file will have a few default lines, but you'll need +to edit it to look similar to this (settings may change based on your +personal needs): + +#+begin_src config +<VirtualHost *:80> + ServerAdmin your-email@email-provider.com + ServerName example.com + ServerAlias www.example.com + DocumentRoot /var/www/example.com/public_html + ErrorLog ${APACHE_LOG_DIR}/error.log + CustomLog ${APACHE_LOG_DIR}/access.log combined +</VirtualHost> +#+end_src + +Now, enable the configuration for your new site, disable the default +configuration, and reload the web server. + +#+begin_src sh +sudo a2ensite example.com.conf +sudo a2dissite 000-default.conf +sudo systemctl reload apache2 +#+end_src + +You can always run a test to make sure no errors or warnings are found +in your configuration files. + +#+begin_src sh +sudo apache2ctl configtest +#+end_src + +Now, restart the web server entirely. After this, you should be able to +browse to =http://example.com= and see the HTML content you provided +earlier. Note that SSL/TLS has not been enabled yet, so you won't be +able to use the secure version yet (=https://example.com=). + +#+begin_src sh +sudo systemctl restart apache2 +#+end_src + +You can repeat this for as many websites as you need. Just create the +domain folders in =/var/www/=, add the configuration file, enable the +configuration, and restart =apache2=. + +* SSL/TLS Certificates: Serve Websites Over HTTPS +In order to serve secure content, you'll need to obtain SSL/TLS +certificates. Luckily, there's a free tool called +[[https://certbot.eff.org][Certbot]] that helps us with the process. + +The first step is to install =snapd= and =core= for Ubuntu. + +#+begin_src sh +sudo apt install snapd +sudo snap install core +sudo snap refresh core +#+end_src + +Next, install the =certbot= snap package. + +#+begin_src sh +sudo snap install --classic certbot +#+end_src + +Execute the following command to ensure that the =certbot= command can +be run. + +#+begin_src sh +sudo ln -s /snap/bin/certbot /usr/bin/certbot +#+end_src + +Finally, you can run =certbot= one of two ways: + +1. run it and let it alter your Apache configuration files automatically + to enable HTTPS redirects. +2. run it and only allow it to create certificates. You'll need to + manually alter the config files to enable HTTPS redirects. + +Run certbot and allow automatic config changes: + +#+begin_src sh +sudo certbot --apache +#+end_src + +Run certbot for certificates only and don't allow it to alter config +files: + +#+begin_src sh +sudo certbot certonly --apache +#+end_src + +The Certbot packages on your system come with a cron job or systemd +timer that will renew your certificates automatically before they +expire. You will not need to run Certbot again unless you change your +configuration. You can test automatic renewal for your certificates by +running this command: + +#+begin_src sh +sudo certbot renew --dry-run +#+end_src + +Now, test your domains by going to =https://example.com=. + +* Firewall Security +To enable better security on your server, you'll need to enable a basic +firewall. For Ubuntu, we'll use +[[../secure-your-network-with-the-uncomplicated-firewall/][the +uncomplicated firewall]]. + +Now, add the following rules to the firewall allow SSH, Apache, and +HTTP(S) connections. If you need to, you can enable different ports for +specifics applications, SFTP, etc. + +#+begin_src sh +sudo ufw default deny incoming +sudo ufw default allow outgoing +sudo ufw allow OpenSSH +sudo ufw allow Apache +sudo ufw allow proto tcp from any to any port 80,443 +#+end_src + +Once you've added all the rules you need, enable the firewall. + +#+begin_src sh +sudo ufw enable +#+end_src + +* Troubleshooting +If you run into any issues during your VPS set-up, be sure to walk back +through your actions and make sure you didn't miss any steps. + +Many websites have fantastic guides to setting up various web servers. +This is one of the areas +[[https://www.digitalocean.%20com/community/tutorials][where +DigitalOcean shines]]. For simpler or more Linux-oriented questions, I +suggest using [Linuxize] ([[https://linuxize.com]]). + +If you're getting certain errors (e.g. =500 Internal Server Error=) and +need to debug locally, you can view the =access.log= and =error.log= +files in the =/var/log/apache/= directory. |