Name Last Update
demo Loading commit data...
perguntations Loading commit data...
.gitignore Loading commit data...
BUGS.md Loading commit data...
LICENSE Loading commit data...
MANIFEST.in Loading commit data...
README.md Loading commit data...
package-lock.json Loading commit data...
package.json Loading commit data...
setup.py Loading commit data...

README.md

README

  1. Installation
  2. Running a demo
  3. Troubleshooting

1. 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.

sudo apt install python3 python3-pip npm   # debian, ubuntu, mint, ...
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:

[global]
user=yes

[list]
format=columns

The file is in ~/.config/pip/ in Linux/FreeBSD and ~/Library/Application Support/pip/pip.conf in MacOS.


2. Installation

Download and install (USERNAME is your account on bitbucket):

git clone https://USERNAME@bitbucket.org/USERNAME/perguntations.git
cd perguntations
npm install
pip3 install .

The command npm installs the javascript libraries and pip3 installs the python webserver. This will also automatically install the python dependencies required.


3 Setup

The server will run an https server and requires valid certificates. To generate certificates, there are two possibilities: public server with static IP address or a private server on a local network.

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 case).

mkdir -p ~/.local/share/certs

Selfsigned certificates

Self-signed certificates are not certified by a recognised authority and browsers will complain that the certificate is not trusted.

cd ~/.local/share/certs
openssl req -x509 -newkey rsa:4096 -keyout privkey.pem -out cert.pem -days 365 -nodes

LetsEncript (FreeBSD)

Generating certificates for a public server (FreeBSD) requires a registered domain with fixed IP.

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:

chmod 400 cert.pem privkey.pem

Certificate renewals can be done as follows:

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.


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:

cd demo

initdb students.csv             # initialize from a CSV file
initdb --admin                  # only adds the administrator account
initdb --add 123 "Asterix Gaules"  # add one student

mkdir ans                       # directory where the student tests are saved

$EDITOR test-tutorial.yaml      # edit test configuration

perguntations --help            # get help
perguntations tutorial.yaml     # run demo test

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. The administrator is redirected to the administration page that shows all the students and their state.

  1. Authorize students by clicking the checkboxes.
  2. Open a different browser at http://127.0.0.1:8443/ and login as one of the authorized students. Answer the questions and submit.

The server can be stoped from the terminal with ^C.

Running on lower ports 80 or 443

Ports 80 and 443 are reserved for the root user and and this software should NOT be run as root. Instead, the firewall should be configured to forward tcp traffic from port 443 to 8443 where the server is listening. The details depend on the operating system.

debian:

FIXME: Untested

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"

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