# User Manual 1. [Requirements](#requirements) 1. [Installation](#installation) 1. [Setup](#setup) 1. [Running a demo](#running-a-demo) 1. [Running on lower ports](#running-on-lower-ports) 1. [Troubleshooting](#troubleshooting) --- ## Requirements The webserver is a python application that requires `>=python3.6` and `pip` to be installed. `npm` (Node package management) is also necessary to install the javascript libraries. ```bash sudo apt install python3 python3-pip python3-setuptools npm # Ubuntu sudo pkg install python36 py36-sqlite3 py36-pip py36-setuptools npm # FreeBSD sudo port install python37 py37-pip py37-setuptools npm6 # MacOS ``` The file `pip.conf` should be configured to the following: ```ini [global] user=yes [list] format=columns ``` This file is usually in `~/.config/pip/` in Linux and FreeBSD. In MacOS it's in `~/Library/Application Support/pip/`. --- ## Installation Download and install (`USERNAME` is your account on bitbucket): ```bash cd ~ git clone https://USERNAME@bitbucket.org/USERNAME/perguntations.git cd perguntations npm install pip3 install . ``` Here, the repository is installed in the user home directory. You may wish to adjust to somewhere else. The command `npm` installs the javascript libraries and `pip3` installs the python webserver. This will also install any required dependencies. --- ## Setup The server will run a `https` server and requires valid certificates. There are two possibilities to generate the certificates: - public server with static IP address and registered domain name; - private server on a local network isolated from the internet. Certificates must be saved in the `$XDG_DATA_HOME` path if defined in the environment, otherwise in `~/.local/share/certs` (I will assume the latter). ```bash mkdir -p ~/.local/share/certs ``` Self-signed certificates are not certified by a recognised authority and browsers will complain that the certificate is not trusted. That's ok. ```bash cd ~/.local/share/certs openssl req -x509 -newkey rsa:4096 -keyout privkey.pem -out cert.pem -days 365 -nodes ``` To have a true certificate, like the ones issued by LetsEncrypt, the host must have a registered domain name. See instructions for FreeBSD at the end of this page. --- ## Running a demo The directory `demo` in the repository includes a demo test that can be used as a template for your own tests and questions. To run the demonstration test you need to initialize the database using one of the following methods: ```bash cd ~/perguntations/demo initdb students.csv # initialize from a CSV file initdb --admin # only adds the administrator account initdb --add 123 "Asterix Gaules" # add one student ``` This will create or update a `students.db` file that contains a sqlite3 database. The database stores user passwords and grades, but not the actual tests. A test is specified in a single `yaml` file. The demo already includes the `tutorial.yaml` that you can play with. The complete tests submitted by the students are stored in JSON files in the directory defined in `tutorial.yaml` under the option `answers_dir: ans`. We also have to create this directory manually: ```bash mkdir ans # directory where the tests will be saved ``` Start the server and run the `tutorial.yaml` test: ```bash perguntations tutorial.yaml # run demo test ``` Several options are available, run `perguntations --help` for a list. The server listens on port 8443 of all IPs of all network interfaces. Open the browser at `http://127.0.0.1:8443/` and login as user number `0` (administrator) and choose any password you want. The password is defined on first login. After logging in, you will be redirected to the administration page that shows all the students and their current state. 1. Authorize students by clicking the checkboxes. 2. Open a different browser (or exit administrator) at `http://127.0.0.1:8443/` and login as one of the authorized students. Answer the questions and submit. You should get a grade at the end. The server can be stoped from the terminal with `^C`. --- ## Running on lower ports Ports 80 and 443 are reserved for the root user and and this software **should NOT be run as root**. Instead, tcp traffic can be forwarded from port 443 to 8443 where the server is listening. The details depend on the operating system/firewall. ### debian: FIXME: Untested ```.bash iptables -t nat -I PREROUTING -i eth0 -p tcp --dport 443 -j REDIRECT --to-ports 8443 ``` Explanation: - `-t nat` is the table consulted when a packet creates a new connection. - `-I PREROUTING` inserts rules at the head of the chain. - `-p tcp` selected protocol. - `-s 0/0` source network address/mask. - `-i eth0` interface via which the packet was received. - `--dport 443` destination port. - `-j REDIRECT` what to do when packet matches the rule. - `--to-ports 8443` where to redirect the packets. ### FreeBSD and pf Edit `/etc/pf.conf`: ext_if="wlan1" rdr on $ext_if proto tcp from any to any port 80 -> 127.0.0.1 port 8080 rdr on $ext_if proto tcp from any to any port 443 -> 127.0.0.1 port 8443 The `wlan1` should be the name of the network interface. Use `ext_if="vtnet0"` for guest additions under virtual box. Start firewall with `sudo service pf start`. Optionally, to activate pf on boot, edit `rc.conf`: pf_enable="YES" pf_flags="" pf_rules="/etc/pf.conf" # optional logging: pflog_enable="YES" pflog_flags="" pflog_logfile="/var/log/pflog" ## Generating certificates with LetsEncript (FreeBSD) Generating certificates for a public server (FreeBSD) requires a registered domain with fixed IP. ```sh sudo pkg install py27-certbot # FreeBSD sudo service pf stop # disable pf firewall (FreeBSD) sudo certbot certonly --standalone -d www.example.com sudo service pf start # enable pf firewall ``` Certificates are saved in `/usr/local/etc/letsencrypt/live/www.example.com/`. Copy them to the `certs` directory and change permissions: ```sh chmod 400 cert.pem privkey.pem ``` Certificate renewals can be done as follows: ```sh sudo service pf stop # shutdown firewall sudo certbot renew sudo service pf start # start firewall ``` Again, copy certificate files `privkey.pem` and `cert.pem` to the `certs` directory. --- ## Troubleshooting * The server tries to run `python3` so this command must be accessible from user accounts. Currently, the minimum supported python version is 3.6. * If you are getting any `UnicodeEncodeError` type of errors that's because the terminal is not supporting UTF-8. This error may occur when a unicode character is printed to the screen by the server or, when running question generator or correction scripts, a message is piped between the server and the scripts that includes unicode characters. Try running `locale` on the terminal and see if there are any error messages. Solutions: - debian: `sudo dpkg-reconfigure locales` and select your UTF-8 locales. - FreeBSD: edit `~/.login_conf` to use UTF-8, for example: ``` me:\ :charset=UTF-8:\ :lang=en_US.UTF-8: ``` --- ## Contribute ### * Writing questions in yaml format * Testing and reporting bugs * Code review * New features and ideas ### Contacts ### * Miguel BarĂ£o mjsb@uevora.pt