I’ve always wanted to create my own website, so during winter break, I decided to do just that. I could have gone about it the smart way by hosting on a cloud provider like AWS or the like.

I decide to do it the hard way and run my own webserver. I technically succeed. Here is what I did.

The exact procedure might differ between operating systems, but the overall structure is the same.

Materials

Hardware

The essential hardware to get started includes:

  • Any SBC with Ethernet/USB access running some flavor of Linux
    • I used the Le Potato, since Raspberry Pis cost an arm, a leg and my soul, but feel free to use whatever SBC you like
    • I also used Armbian since I’m already familiar with Debian-based Linux flavors
  • a microSD card with the correct adapter
    • by adapter, I mean a normal SD card with a port for the microSD card. This probably comes with the microSD, but for completeness I’m explicitly mentioning this.
    • For the read speed, you want a Class 10 or better (this is a pretty low benchmark in the year 2022) If you have direct access to your router’s Ethernet ports, then you all you need is an Ethernet cable.

If you don’t have direct access to your router, then you will need

  • a Wifi dongle like this (either 2.4 GHz or 5 GHz depending on your network) if your SBC doesn’t have innate internet access.
  • any compatible keyboard
  • any compatible monitor that can be connected to your SBC (typically HDMI ports works)

Startup Software

You need a variety of software in order to even get the SBC to turn on, let along act as a webserver. Luckily, all the required/useful software is free! You’ll need:

  • An image of the os (Ubuntu 20.04), which can be found right here; download the CLI version. There are also images for other knock-off Raspberry Pi boards.
  • 7Zip, or other decompressing software. You need this extract the .xy file.
  • Balena Etcher, which is a cross-platform etcher that is used to burn the os onto the microSD.
  • AngryIPScanner, which pings all the addresses on your LAN and return all the living connections.
  • Once Armbian is setup and you can access the SBC, the rest of the software can be installed via the command line.

Twofold Path

There are two ways of going about setting up the server, depending on the hardware you have.

Ethernet

Let’s start with the ideal case: you have direct Ethernet access to your router. This gives you the best speed and is the least annoying to setup.

  1. Use Etcher in order to burn and verify the Armbian image. Don’t forget to extract the image first.

  2. Safely eject the SD card once the validation is done

  3. Plug in the microSD to the SBC

  4. Power it on. Look for the verification signal (SBC dependent. for the LePotato, the green light is solid and the blue light blinks). Give it a couple of minutes since the first boot might be slow.

  5. Plug in the Ethernet cable between the router and the SBC. Give it a couple of second to assign an IP address to the server.

  6. Run AngryIP Scanner across your LAN, click on Hostname to Sort By Hostname, then look for your server (for LePotato, the default is potato.local). Take note of the IP address.

    • In the event that your internet provider anonymizes all connections, you will need to plug in the keyboard and monitor, then jump to Step 8.
  7. Open any command line application and type in

     ssh [User]@[Ip-address]
    

    Where User is name of the root account and Ip-address is the server IP address. For LePotato, User is root. If all goes well, you should get a message asking if you are sure that you want to connect. Type ‘yes’ and hit Enter.

  8. You should get prompted for the password (Password is 1234 for LePotato). You then need to set the root password (doesn’t matter since root will be disabled), choose your bash shell (doesn’t matter which), choose your username and password (these are actually important, so don’t forget them), and choose your language, time zone, and region. Proceed to Securing the Server.

Wireless Setup

In order to connect to wifi, the server needs some tweaking in its configuration files. Assuming that you have the peripherals, then this is relatively straight forward to do.

  1. Use Etcher in order to burn and verify the Armbian image. Don’t forget to extract the image first.

  2. Safely eject the SD card once the validation is done

  3. Plug in the microSD, keyboard and monitor to the SBC, as well as the Wifi dongle if needed

  4. Power it on. Look for the verification signal (SBC dependent. for the LePotato, the green light is solid and the blue light blinks). Give it a couple of minutes since the first boot might be slow.

  5. Follow the start up sequence by inputting a root password, a admin username and password.

  6. You should get prompted here to set up wireless since Armbian detected no Internet connection. Agree, and you will be taken to a GUI wireless setup. You can navigate with the arrow keys and enter.

  7. Look for your wifi network and select it. You will get prompted with the password; input it, then press enter.

  8. Make sure that there is a * next to your network. If you highlight your network, then you should see “<Deactivate>” on the right hand side. This means that you are connected.

  9. Navigate to “<Quit>” at the bottom by pressing right and down. Then hit Enter.

  10. You will get prompted for your time zone,language and region preferences like in Step 8 of Ethernet. Fill those out.

  11. Once you are logged in as root, type in

    ping google.com
    

    What this does is pass packets back and forth between the server and google. This is a good test to see if you actually are connected to your LAN. If you don’t get any errors and you should get a continuous stream that consists of lines like

    64 bytes from [server_info]: icmp_seq=[#] ttl=[#] time=[#] ms
    

    Hit Ctrl+C to stop pinging.

  12. Type in

    hostname -I
    

    and take note of the ip address.

  13. Proceed to Securing the Server.

Securing the Server

So you’re in your server. Now you need to setup secure access to the server.

SSH

  1. Type

     su [User]
    

    To switch to the admin account

  2. From your home directory, type

     sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config_backup
    

    You’ll need to input the admin password. This command makes a backup of the defaults incase anything goes wrong (good practice whenever you are screwing around with configurations).

  3. Type in

     sudo nano /etc/ssh/sshd_config 
    

    and change/add the following lines:

    • PermitRootLogin yes -> PermitRootLogin no
    • Uncomment and change the following lines
      • PasswordAuthentication yes -> PasswordAuthentication no
      • PermitEmptyPasswords no
      • Port 22 -> Port # (This is optional. A bit unnecessary)

    Save and exit the file.

  4. On your original computer that you used to SSH into the server, open up another terminal and type in

     ssh-keygen
    

    This create a public private keypair that enables authentication without a password

    • you can save the keys wherever you want, although /home/[User]/.ssh/ is a good standard location.
    • You can also include a passphrase as well, although optional
  5. You then can use ssh-copy-id to transfer the public key over:

     ssh-copy-id -i [location] [user]@[ip-address]
    

    where [location] is where you saved the public key (the files ends with .pub)

    • You will be prompted for the admin password
  6. Run the following

     eval `ssh-agent`
     ssh-add [location]
    

    where [location] is where you saved the private key (should be same directory as public, but no .pub file type)

  7. Run the following on the server:

     service ssh restart
    

If all goes well, you should be able to SSH into the server without a password. In addition, the only computers that can access the server are ones that have the correct private key.

UFW

UFW is a simple firewall that can dictate which connections are allowed into and out of the server. It should come preinstalled in most linux distros.

Run the following commands:

    apt-get update && apt-get upgrade -y
    sudo apt install ufw -y
    sudo ufw default deny incoming
    sudo ufw default allow outgoing

This installs ufw if it is not already present, denys all incoming traffic and allows all outgoing traffic. Now, we need to add the rules that enable SSH and HTTP requests from the outside:

    sudo ufw allow [port]/tcp
    sudo ufw allow 80/tcp
    sudo ufw allow 443/tcp

Where [port] is the port that SSH goes to (defaults to 22 is you didn’t change this). 80 and 443 are HTTP and HTTPS requests respectively. Eventually, you will need to add an SSL certificate to have a valid https connection, which will be covered in part 2.

You can then start ufw with:

    sudo ufw enable

and you can check the rules with:

    sudo ufw status

an easy way to remove moves is by typing:

    sudo ufw status numbered

and then inputting

    sudo ufw delete [#]

where # is the rule number.

ufw can be turned off by

    sudo ufw disable

Fail2Ban

Fail2Ban is a service that can help prevent DDOS attacks, amongst other things. Linode.com has a good tutorial on how to install and configure Fail2Ban.

Just installing Fail2Ban

    apt-get install fail2ban

and not messing with the defaults is probably good enough for a small personal webserver since you’ve already disabled password login and enabled key authentication. Fail2ban only servers to deter invalid users from throttling the server. If you want to mess with the default settings, be my guest.

Apache

At this point, we need to download the software needed to actually serve webpages to the internet. Apache2 is a commonly used webserver that can be downloaded from the command line. Digital Ocean has a good tutorial on how to get apache2 up and running.

The essentials are:

  • Download apache2:

      sudo apt update
      sudo apt install apache2
    
  • Since you have already configured ufw, run

      sudo systemctl status apache2
    

to check if apache is running. Hit Ctrl-C to escape. Now enter your private ip address of the server (run hostname -I) into the web browser to check if everything works. If you can access the default apache webpage, then it works!

Connecting to the Internet (AKA Punching a Hole in your Router)

You now have a secure running webserver. It doesn’t do much since it’s nobody can access your webpage. In order allow others to see your site, you need to open Port 80 and Port 443 to allow HTTP and HTTPS requests to your server.

This process is an extremely router-dependent. The best you can you is search

    "your router model" Port Forwarding 

and try to figure it out as best as you can. To check if you did it correctly, you can you an online port checker tool such as PortChecker.co.

  • If you want to be able to SSH into your server, you can also open Port 22 (or whatever port you opened for your SSH connection).
    • If you did not properly secure your server with public-private key encryption, ufw and Fail2Ban, then don’t do this because you will get inundated with bots trying to ssh into your server.

Connecting a NoIP Domain to your Public IP address

Now that the Internet can access the contents of your server, you need to supply a domain name to your public IP address. A free way of doing this is with NoIP.com.

  • Go to NoIp.com and signup for an account.

  • Create a hostname

    • Select DNS Host as the Record type
    • Select hostname that is available
    • Provide your public IP address (You can find out what your public iP address by searching “What is My IP address?”)
  • You can test if the connection work by pinging your hostname

    • NOTE: It might takes some time for the domain name to get associated with your IP address
  • If you set up ssh, you should be able to login via

      ssh username@noipdomain -i privatekey_loc
    

Conclusion

You now have a functioning website. You can change the displayed content by editing the index.html file at

/var/www/html

As for why this setup eventually failed for me, it has to do with logistics.

  • The internet at my house is not particularly stable
  • If the power ever goes out (which it does semi-regularly where I live), then I have no way of restarting the server remotely

In the future, I place on self hosting. but until then, I worked around this issue by hosted this website on Github Pages.

Update

I managed to put this site on an 10 year old laptop my family had lying around. I will talk about this soon.