CPSC 441, Fall 2018
Lab 4: Web Serving from your Virtual Machine

On Monday, September 24, the class meets in Rosenberg 009 for our fourth lab. The web server from Lab 3 is not due until next Monday.

For Lab 4, you will not turn in anything. I will check your work by accessing your virtual machine. However, the work should be done by next Monday at the same time that you turn in your web server program.

There are two required tasks for this lab: Create and install a self-signed certificate for the Apache2 web server on your virtual machine, and set up your own web server to run as a daemon on your virtual machine. This lab writeup contains more information than you will need to do the lab. The extra information should help you learn more about being a Linux sysadmin.

Because of the test next week and Spring Break the week after, the next lab will be in three weeks.

Self-Signed Certificate for HTTPS

Your virtual machine is running an Apache2 web server program. In order for that server to handle https connections, it needs a security "certificate." A certificate contains information about the server and is "signed" by a certificate authority such as Verisign. Web browsers come with a set of certificate authorities whose signatures they will accept. To get a normal certificate, you have to generate a certificate request, send it to a certificate authority to be signed, and configure the server to use the certificate. Getting a certificate signed can be expensive, but it is also possible to use a "self-signed certificate". Web browsers will not automatically accept self-signed certificates, but will let you access the site if you go through some security warnings. Self-signed certificates can be used within an organization as long as the users understand what is going on.

After googling for "Ubuntu 16.04 apache self-signed certificate" and looking at some of the results, I found the following howto and was able to follow it to install a self-signed certificate on my virtual machine:

https://www.techrepublic.com/article/how-to-create-a-self-signed-certificate-to-be-used-for-apache2/

You should read this guide and follow the instructions to install a self-signed certificate for your own Apache2 web server. For the most part, you can copy-and-paste the necessary commands directly from the article, but note that

There is still the question of how to edit the file... The vim command-line editor is installed, but it will seem strange if you haven't used it. (Here is a quick guide: You can use arrow keys to move around in the file. To make any changes, you have to go into INSERT mode, by pressing the "I" key. In INSERT mode, you can type, and you can still move around with the arrow keys. Press "ESC" to get out of INSERT mode. This puts you back into the default COMMAND mode. To finish, you must be in COMMAND mode: type :wq to save the file and quit; to quit without saving the changes that you have made, type :q! instead.) If you gave the command apt install xorg nedit from Lab 2, you installed the GUI text editor nedit on your VM. Nedit is an old but light-weight text editor that works OK when used through a network connection. To use it, you need to ssh to your VM using ssh -X instead of plain ssh. (That's an upper case X in the command option.) The "-X" option on ssh makes it possible to use GUI applications remotely, as long as both sides of the connection have the Unix windowing software installed; that's what the "xorg" is in the above apt install command.

When you access your site in Firefox using an HTTPS URL like https://172.21.6.XX, you will get a scary message that "Your connection is not secure." Click "Advanced," and you will see that the problem is given as "MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT", which just means that the connection wants to use a self-signed certificate, as expected. Click "Add Exception", then click "Confirm security exception", and you should get to your web site. (The process for accessing the site in Chrome is similar, but the warnings are even more scary.)

About Daemons

A daemon is a program that run independently of any logged-in user. Server programs, such as a web server, usually run as daemons that are started automatically when the server boots up. The question is, how can a program be run when there is no user to run it. We'll look at three possibilities.

First, the at command can be used to schedule a list of one or more commands to be executed by the system at some specified time. This scheduled job will run with the privileges of the user who gave the at command, but that user doesn't have to be logged in when the job runs. In particular, if you enter the command at now, you can then type in a list of commands on subsequent lines, terminated with Control-D. The commands will be executed as an independent job, starting immediately. When that job terminates, the system will want to email the output of the job to you. Since we don't have email set up on our servers, you should probably only use at to run a job that has no output.

Second, it is possible to run a command on the command line in such a way that the process will not be terminated when you log out (as most of your ongoing processes are). You do co that using nohup. In this case, any output from the command will be written to a file named nohup.out. The format is

nohup  <command>  &

The "&" at the end is required. It makes the command run "in the background", in parallel with your login session. Without it, the command would still be terminated when you log out and your session ends.

Third, Linux has a rather complicated "init" system that determines what programs are run at start up. (The files used by this system are in the directory /etc/init.d, if you are interested. Each file in that directory is a script that controls some daemon program or other resource, such as networking.) This is the correct way to control daemons, but there is an older technique that still works in many versions of Linux, including the one used on your server.

To have some commands be executed at boot, you can put the commands in the file rc.local. This file is a way of running commands at boot without writing a proper init system script. You can edit this file and add a command. Use a & at the end of the command to make sure that the rc.local script itself does not run forever. I do not know where the output from rc.local goes.

The rc.local script runs as root, that is, with full privileges. It might be better to run the command as a different user. This can be done with the su command. The root user can use su to run a command as some other user. The format is

su  -c "<command>"  <user> &

If a non-root user uses the su command, they will be asked for the user's password.


What about output from the command? You would like to have it in some convenient place. For example, the log files from the Apache server that is already running on your server can be found in /var/log/apache2. But suppose you have a program that writes to standard input and/or standard error, and you would prefer to send the output to a file. You can do that with output redirection. Let's say doSomething is a command and you want to send its output to out.txt. If you run the command with

doSomething  >  out.txt

then output that normally goes to standard output will go to out.txt instead. The previous content of the file, if any, will be deleted. If you would like to append the output to the file, run the command with

doSomething  >>  out.txt

If you also want to direct standard error output to the same file, use

doSomething  &>  out.txt

to replace the contents of the file or

doSomething  &>>  out.txt

to append to the file. If you simply want to discard the output, you can use /dev/null instead of out.txt. (There is also input redirection, which uses < instead of >.)


You might also be wondering how you can ever stop a program that is running as a daemon. The solution is to use the kill command. Every process has a process ID number. You can view all processes with the command

ps aux

The process IDs are in the second column. Once you know the process ID, you can definitively kill it using the command kill -9. For example if the process ID is 7834, you can kill it using

kill  -9  7834

If you omit the "-9", you are sending a request to the process to terminate cleanly, but it might not work, and it won't work for a process started with nohup. Adding the "-9" kills the process without giving it a chance to refuse or to clean up.

A Daemon on your VM

By next Monday, the web server that you write for Lab 3 should be running as a daemon on your virtual machine, so that it can be accessed at any time. It should use my graphicsbook, or some other reasonably complicated web site, as the directory that holds its files. You can use any of the three techniques discussed above to start the daemon. It is not required that the daemon be started at boot time; it just has to be running when I check for it.

The command that you need to use to run the program depends on a lot of things. For me, the following command worked (but it has to be all on one line):

java -cp /home/eck/WebServer.jar websrv.WebServer 
                /var/www/html/graphicsbook &>> /home/eck/weblog.txt

I stored my program in a non-executable jar file. It could also be in an executable jar file or even in individual class files. Note that Eclipse can make a jar file of your web server for you; if you do not know how to do this, see Section 6.7.4 in my Javanotes.

You will need to copy your program to your virtual machine. An easy way to do that is with scp. The scp command copies files through the ssh protocol. For example, to copy WebServer.jar into my home directory on my virtual machine, I would use

scp WebServer.jar eck@172.21.6.30:

The ":" in the second argument is essential, because it tells scp that this is a remote location rather than a local file. To copy a directory, you have to add the option "-r" to the command. To copy to a remote location other than your home directory, you can add a path to the second argument, after the ":". For example, to copy a directory named websrv into a directory named /var/www on the server, connecting to the server as the root user:

scp -r websrv root@172.21.6.30:/var/www