• Home
  • Exercises 04
  • Server Setup
  • Server Setup

    The questions below are due on Thursday March 09, 2023; 10:00:00 AM.
     
    You are not logged in.

    Please Log In for full access to the web site.
    Note that this link will take you to an external site (https://shimmer.mit.edu) to authenticate, and then you will be redirected back to this page.

    In this (somewhat long) exercise, you'll set up your own server which you can remotely access.

    You will need the following which will be handed out during Lab04:

    • A Raspberry Pi 3
    • A 5V 3A power supply with micro-USB
    • A micro-SD with a headless Rasbpian distribution on it (probably already slotted into your Raspberry Pi)
    • An ethernet cable

    You will also need the following which can be found in lab (Building 38 6th floor). You should set up your Raspberry Pi at one of the desks in lab (to the left as you walk in on the 6th floor) and use the monitors, keyboards, and ethernet cables that are there (you may need to unplug them from the desktop computers).

    • A USB keyboard (at least at first)
    • Some form of HDMI-compatible monitor
    • A HDMI cable

    You'll need to do this exercise in lab (Building 38 6th floor) so that the Raspberry Pi networking will work correctly.

    Getting Started

    Ok first up you need to get your Raspberry Pi going. Put the SD card into its SD slot. Hook it up to a monitor, a keyboard, and plug it into the ethernet. There are tons of ports sitting around lab and most will work for our purposes. Eventually, later on in this page, you'll shove it in a server closet and then just work on it remotely, but before that, you need to do a little setup on it directly.

    First Step

    Terminal ahead! No GUIs! Be ready for typing. Our server will be running essentially Debian which is a pretty standard flavor of GNU/Unix. You will need to have some minimal comfort with terminal commands. As a review/learning resource this site is pretty good.

    Depending on your Debian image, you may or may not get prompted to select a keyboard right away on the first boot-up. If you do get prompmted, select the US-keyboard (if that's what you want). Don't assume "default" means US...it doesn't. It means UK keyboard which is a little different in just enough annoying ways. If it doesn't prompt you, that's ok too...we have an instruction to change it later if needed.

    The machine will boot since you're the first one running it, the first thing that happens should be that it'll prompt you for a username and password. Create one. We would strongly recommend you use your MIT kerberos None. Password can be whatever you want, just don't forget it, since until you make an admin account for us, there's no real way to recover it. This account will have sudo priveleges on the machine, meaning you can do whatever you want with it. Embrace this power, but also be responsible with it.

    Once your account is created, it'll either log you in, or you'll have to log in. After that you'll be in the terminal. First thing to do is to update and upgrade all software on the computer (the starting distribution are usually stable snapshots that can be months old). To do these updates/upgrades first do:

    sudo apt update
    

    This shouldn't take too long. Then do:

    sudo apt upgrade
    

    This will likely take a bit longer and also prompt you with a Y/n, make sure to say Y (for "Yes").

    Nano or Vim or Emacs?

    Your server is "headless" meaning there's no GUI to interact with it. As a result, you'll need to install and work with a terminal-based text editor. There are three big choices. In order from easiest to hardest, I'd say the options are Nano, Emacs, and then Vim. The choice is yours, but I'd encourage you to go towards an easier editor. Quick startup-guides are found for each below.

    In addition, you'll need to install one of these editors on the machine (nano is actually probably already there) by doing sudo apt install nano or sudo apt install emacs or sudo apt install vim depending on your choice. Also feel free to try all three of these and see what you like. They are all unnatural coming from a point-n-click existence, but once you're going they aren't too bad, though vim's modes can be unnatural which is why I suggested nano or emacs first.

    This Keyboard

    If you have not already changed the keyboard type, you should do that here.

    Another thing you might notice is the Raspberry Pi has some weird key-bindings. This is because Raspberry Pi is a UK-based organization so they default to a UK-keyboard. If you're fine with this, then great, but you'll very soon realize you aren't, so we should fix it. To fix this, you'll want to run:

    sudo dpkg-reconfigure keyboard-configuration
    

    And then go through there and select the US keyboard (there are several lists you'll have to cycle through).

    Once done run:

    service keyboard-setup restart
    

    This will only sometimes work, so likely you should also just reboot the computer. Do that with:

    sudo reboot
    

    Wait for the machine to come back up, log in if necessary, and move on.

    Adding an Admin Login

    In order to better help you out with future psets the staff would like to be able to log in to your server, so we'll go through setting up a second user with sudo privileges.

    Run this command to add the 'admin' user to your machine. Set the password to "6900$t@ff", we'll change it later. If it prompts you to enter user information, just hit Enter to leave them blank.

    sudo adduser admin

    Next, to give the staff sudo privileges, we'll add the admin user to the sudo group with this command:

    sudo usermod -aG sudo admin

    To verify that this was completed successfully, run this command and you should see the admin user in the list.

    getent group sudo

    Attaching a Static IP

    Right now your Raspberry Pi is connected to the greater world via the internet. When it joins it, it is assigned a series of temporary identifying numbers which serve as an internet address. With this address, other computers on the global network can target information at it. However since the address is temporary and subject to change, the Raspberry Pi must be the one to initiate contact/exchanges between it and other machines. As a result, the Raspberry Pi is client-only because of its dyamic IP address ("IP" = "Internet Protocol"). For example, the Pi might contact google.com to conduct a query. In the initial request, it also notifies Google of its current temporary address, so when Google responds, it knows where to direct its traffic.

    What we would like is for our Raspberry Pi to be globally accessible to other devices always via a fixed location on the internet, and for this we need to give it a permanent address. The emotional and technical burden of "starting" the conversation, therefore doesn't have to be on the Raspberry Pi's side. Instead it can sit and listen and since its location is known to other devices they can send incoming traffic. This is easier said than done, since there are only so many permanent addresses that can be given out and they are largely tightly regulated. Through some weird historical glitches, MIT is in posession of several million addresses, however, and will gladly give us some for our class. Kinda cool and nice of them when you think about it.

    We've gone ahead and claimed/requested two things for you:

    • A unique IPv4 static IP, which for you is: ERROR
    • A DNS name to associate with that IP address, which for you is ERROR

    Wait, you might say. I'm just reading a generic pset. You say, this value is unique to me, but my friends are also reading this. Well that's true, but I'm using your MIT credentials to drop in the correct info above. So it looks nice. Trust me, the number above is yours.

    The "real" address is the static IP above. This is really what will be used to identify your machine behind the scenes to all other network connected devices in the world. The DNS name, ERROR, is really only for human consumption/readability....a convenient alias, if you will. We have already asked MIT to associate that DNS name with that unique static IP and they then notified the whole world about that. So a computer in Europe can send messages to either ERROR or ERROR and both will get to the affiliated machine1

    Note you can't just do this for any computer anywhere. MIT owns several million IPV4 static IP addresses. I requested them from class for us. The internal network infrastructure of MIT has been prepared ahead of time to know and expect that a device "looking like" your address will get projected to the outside world. Also note that the appropriate bits to expose this IP address to the outside world have been set to work only within the MIT EECS building of 38 and 34. You can't expect this to work in your dorm.

    But we're not there yet. So ok. Ok. How do we set up our Raspberry Pi with a static IP? Well there's a special file you have to modify. It is usually blank/generic when a machine is just getting dynamically allocated addresses. On the Debian-type OS that your Pi is running that is located in the the file found at: /etc/network/interfaces. So you need to edit that file.

    Go and open it up with your text editor of choice. I like vim, but you do you seriously. The command I would run to access this file would be:

    sudo vim /etc/network/interfaces
    

    but

    sudo nano /etc/network/interfaces
    

    and

    sudo emacs /etc/network/interfaces
    

    work too.

    When you get in there, it'll be quite short. This is the standard format for a system that is set up as a dynamic IP system (no fixed name, not known to the greater world with a DNS name).

    Using your text editor, replace the entire file with the text below:

    # interfaces(5) file used by ifup(8) and ifdown(8)
    # Include files from /etc/network/interfaces.d:
    source /etc/network/interfaces.d/*
    
    auto lo
    iface lo inet loopback
    
    auto eth0
    iface eth0 inet static
    	address ERROR
    	netmask 255.255.224.0
    	gateway 18.25.0.1
    	dns-domain mit.edu
    	dns-nameservers 18.0.70.160 18.0.71.151 18.0.72.3
    

    Once done, save your changes and then restart your Raspberry Pi (sudo reboot). After it has come back up, you should be able to "ping" it via the server. Go into a terminal on your laptop and do:

    ping ERROR
    

    and you should get something like this back showing that you're touching it over the network:

    64 bytes from 18.25.3.191: icmp_seq=0 ttl=64 time=6.729 ms
    64 bytes from 18.25.3.191: icmp_seq=1 ttl=64 time=14.310 ms
    

    If not go back and double-check your interfaces file.

    *Check Yourself:*

    Run ifconfig in your terminal. This shows your current network configuration. Under the eth0 interface, you should see the static IP address you set in the /etc/network/interfaces file.

    UFW

    Ok your computer can be "seen" by the whole world! Very cool. However, very dangerous. It is exposed to hackers as well as hackerz so we need to do something about this. Let's set up a firewall.

    Access into and out of a computer on the network goes through communication channels known as "ports". If it helps to think of the ports as individual physical tubes for information, that's the right idea, however in reality, the manifestation of a port is more at the software level.

    Different ports are used for different task traditionally. Regular web traffice (HTTP) goes over port 80. Secure web traffic (HTTPS) goes over port 443. SSH and its relatives go over port 22. And so on.

    A firewall works by blocking access/usage to various ports. Uncomplicated FireWall or "UFW" is a very widely used piece of software for managing firewalls. Let's install it:

    sudo apt install ufw
    

    After that do the following in order to activate it:

    sudo ufw enable
    

    Ok. That's good enough for now.

    SSH-ing In

    In the long-term we're not going to be working directly on this machine. Instead we'll hook it up to the network, shove it in a closet somewhere, and then remotely log in over secure shell (ssh) or one of its variants. In order to do this, we need to install an ssh server. We can do that with:

    sudo apt install openssh-server
    

    Next we need to enable and start the ssh server:

    sudo systemctl enable ssh
    
    sudo service ssh start
    

    Finally we need to let ssh traffic through. Remember how we put that firewall in place? Well it'll block all incoming/outgoing traffic for everything, but we want to selectively let through some stuff. So we'll let through ssh traffic. We can just type:

    sudo ufw allow ssh
    

    And then run

    sudo ufw status
    

    and we can see that it is letting Port 22 (SSH port) through.

    Ok now the real test has arrived. Can you access the Pi remotely? On your laptop, go to a terminal (or shell) and do:

    ssh None@ERROR
    
    `None@ERROR` is of the form [username]@[address], so if you set up your Pi with a username other than your kerb, you should use that here.

    It should prompt you for your password. The same one that you used to log into your Raspberry Pi directly! Enter the password. Assuming it goes through you should find yourself suddenly logged into the Raspberry Pi over the internet.

    Very cool.

    Ok at this point, you can now go and run your server completely headless (unplug the monitor and keyboard) and just shove it in our server closet (office). Now you can remotely access it over ssh! This means that you'll be able to work on your Raspberry Pi and future psets anywhere in the world (including your dorm room so you don't have to physically come to lab). Very nice.

    Nginx and the start of Greater Things

    The last thing we want to do on our Raspberry Pi now is to get Nginx going. Nginx is a reverse proxy service that will allow us to redirect various incoming/outgoing tasks to different processes on our computer. Eventually what we'll let Nginx do is link incoming requests to Python processes that we'll be running. For now, we'll just use it to serve some static web content.

    First install nginx:

    sudo apt install nginx
    

    Then do:

    sudo systemctl enable nginx
    

    and then

    sudo systemctl start nginx
    

    Nginx should be running. If you go and view the file (by using emacs, for example) at /etc/nginx/sites-available/default this is the configuration file for Nginx. Right now all it is doing is "serving" static files located in a particular location (/var/www/html) when any web traffic comes looking on port 80 over HTTP. What this means is we should be able to simply jump in a browser and visit your server at http://ERROR. If you do that, however you'll see that nothing happens and/or your browser hangs.

    Similarly, going back to the previous exercise with the ESP32-C3, it should be targeting this web endpoint over HTTP, and if you investigate it now, you should still see it puking out the following on loop:

    connection failed :/
    wait 0.5 sec...
    

    What is going on? Well, we haven't allowed HTTP traffic through. In order to do that we have to put another hole in our firewall. Do this by running:

    sudo ufw allow http
    

    Now refresh and/or revisit in the browser at: http://ERROR Bada Bing, Bada Boom, you should see some welcome to Nginx stuff showing up. A working HTML web page served over HTTP!

    Now go back to your (hopefully still running ESP32-C3). Check the serial monitor. You should now be seeing the html of the nginx default splash page! Noice.

    <!DOCTYPE html>
    <html>
    <head>
    <title>Welcome to nginx!</title>
    <style>
        body {
            width: 35em;
            margin: 0 auto;
            font-family: Tahoma, Verdana, Arial, sans-serif;
        }
    </style>
    </head>
    <body>
    <h1>Welcome to nginx!</h1>
    <p>If you see this page, the nginx web server is successfully installed and
    working. Further configuration is required.</p>
    
    <p>For online documentation and support please refer to
    <a href="http://nginx.org/">nginx.org</a>.<br/>
    Commercial support is available at
    <a href="http://nginx.com/">nginx.com</a>.</p>
    
    <p><em>Thank you for using nginx.</em></p>
    </body>
    </html>
    

    -->

    This is very good news. It means that you have all the basics of your system working.

    As a final thing, let's change what your basic splash page says. (Don't worry we'll add and route in a lot more stuff in future weeks). But for now on your server cd to /var/www/html.

    In that directory you'll see a file called: index.nginx-debian.html. Rename it to just index.html with:

    sudo mv index.nginx-debian.html index.html
    

    Then go in and edit the file so that the ONLY text is your kerberos, None. Save it and revisit it in the browser. You should see just "None" in regular unformatted serif font that browsers default to.

    Also check your ESP32-C3. In its serial monitor it should just be printing your kerberos on repeat. Extremely cool.

    Just to make sure you really have done this, run the checker below which will look at your server and make sure it gets back what we expect (specifically that you are just returning your kerberos). I don't care what you put in the box, but the question will fire a request to your server endpoint to make sure you did what you should.

    When you're done with all the exercises in Ex04, leave your Raspberry Pi with it's power supply in the conference room by EDS (the one we've been doing design reviews in) labelled with your kerb. We'll throw it in a server closet for you!

    If this is all working, you're good to go. You now have two computational devices that can talk to one another from anywhere in the world, provided they are connected to the internet. This is not hyperbole. You could go to Australia, and assuming you have good internet, you could totally talk to your Raspberry Pi up here at MIT. Your Pi is now a "server" aka the "cloud".