Skip to content

Setting up HTTPS

Natsu Kagami edited this page Jul 27, 2020 · 1 revision

Setting up HTTPS

HTTPS is only supported on version 0.7.0 and up.

Why HTTPS?

Even when you are hosting a local contest, HTTPS provides the needed security for all contestants and yourself from leaking credentials and/or other data (e.g. submitted code). There are just too many ways to break-in and eavesdrop a plain HTTP system.

This is a no-brainer for any valuable contest. In the future, multiple judge clients will require HTTPS.

What are the available options?

There are two ways to set up HTTPS for kjudge:

  • If you are hosting kjudge on a public domain, using an actual certificate should be the best method. You might want to look up Let's Encrypt. Cloudflare's firewalled DNS can also be a simple option.
  • If you are hosting kjudge on a local network, using a self-signed certificate is the best option. kjudge supports both pre-configured certificates and kjudge-managed certificates.
    • kjudge's Docker deployment provides a simple way to do both. Continue to Using a Docker deployment to read on.
    • Self-hosted kjudge instances supports pre-configured certificates. However, they do not generate certificates by themselves, but the repository contains a simple script to perform this task. Continue to Using self-hosted kjudge.

Using a Docker deployment

With kjudge-managed certificates

Set up a natsukagami/kjudge (either full or gcc, version 0.7.0 and up) with the following additional environment variables:

  • Required:
    • HTTPS=generate: tells kjudge to auto-generate certificates and manage them.
    • CERT_ALTNAMES: A list of hosts that kjudge will be listening on, either by IP (as IP:1.2.3.4) or DNS (as DNS:google.com), separated by ,.
      • An example, and the default value, is IP:127.0.0.1,DNS:localhost, which will allow the certificate to be used on the local machine ONLY.
  • Optional:
    • RSA_BITS (default value 4096): Strength of the RSA key.
    • CERT_C (default value JP): Certificate country code
    • CERT_ST (default value Moonland): Certificate State
    • CERT_L (default value Kagamitown): Certificate Locality
    • CERT_O (default value nki inc.): Certificate Organization Name
    • CERT_CN (default value kjudge): Certificate Common name
    • CERT_EMAIL (default value [email protected]): Certificate Email address

Mount the following volumes:

  • Required:
    • /certs: The directory that will contain generated certificates. Without this, you will get new certificate each restart.

kjudge will be listening on ports :80 (to distribute the Root CA) and :443, so you need to expose both of them. Note: it's better to not bind :80 to the actual port 80, so that browsers will use HTTPS by default.

An example of the docker run command would be

docker run -it --rm --privileged \
    -e "HTTPS=generate" \
    -e "CERT_ALTNAMES=IP:127.0.0.1,DNS:localhost,IP:192.168.1.5,DNS:judge" \
    -e "RSA_BITS=8192" \
    -e "CERT_CN=IOI" \
    -e "ADMIN_KEY=secret_ioi_key" \
    -v kjudge:/data \
    -v kjudge_certs:/certs \
    -p 8080:80 -p 443:443 \
    natsukagami/kjudge:latest

You should now be able to access the HTTPS endpoint, for example https://localhost. However, modern browsers should reject the site, because they don't trust the signature issuer. You need to download (and manually verify) the root certificate on every contestant computer, along with your own.

Installing the Generated Root Certificate

The certificate is downloadable from the HTTP endpoint /ca, for example http://localhost:8080/ca.

Upon downloading the root certificate, the methods to install and trust the certificate differs by OS:

If you can access the HTTPS endpoint without warnings, the set up is complete.

Using pre-generated certificates

You would need a folder containing two files:

  • kjudge.crt: The HTTPS certificate
  • kjudge.key: The private key signed by the certificate

Optionally, a root certificate can be provided as root.pem, which, with the ROOT_CA_PORT=80 environment variable set, will enable kjudge to serve the certificate in a HTTP endpoint (see the previous section).

Mount this folder as /certs.

Next, set the following environment variables:

  • Required:
    • HTTPS=preconfigured, which tells kjudge to enable HTTPS and use the existing keys.
  • Optional:
    • ROOT_CA_PORT=80, which enables hosting the root certificate on the /ca HTTP endpoint (see the previous section)

An example set up can be (with the certs placed in /home/nki/certs):

docker run -it --rm --privileged \
    -e "HTTPS=preconfigured" \
    -e "ROOT_CA_PORT=80" \
    -e "ADMIN_KEY=secret_ioi_key" \
    -v kjudge:/data \
    -v /home/nki/certs:/certs \
    -p 8080:80 -p 443:443 \
    natsukagami/kjudge:latest

Using self-hosted kjudge

If you already generated the key and certificate, continue to the -https option.

The generate key script

kjudge's scripts folder contains a script, scripts/gen_cert.sh, that helps generating a certificate without considerable efforts.

It requires openssl.

Check out scripts/gen_certs.sh --help for up-to-date details.

gen_certs.sh [target-dir=.] [-h|--help]
    cert generation environment variables:
        - RSA_BITS      [4096]                         Strength of the RSA key.
        - CERT_C        [JP]                           Certificate country code
        - CERT_ST       [Moonland]                     Certificate State
        - CERT_L        [Kagamitown]                   Certificate Locality
        - CERT_O        [nki inc.]                     Certificate Organization Name
        - CERT_CN       [kjudge]                       Certificate Common name
        - CERT_EMAIL    [[email protected]]               Certificate Email address
        - CERT_ALTNAMES [IP:127.0.0.1,DNS:localhost]   A list of hosts that kjudge will be listening on, either by IP (as 'IP:1.2.3.4') or DNS (as 'DNS:google.com'), separated by ','

The scripts will create the following files:

  • Required by kjudge:
    • kjudge.key: The private key used by kjudge. KEEP PRIVATE.
    • kjudge.crt: The signature of the private key, signed by the root certificate.
  • Optional by kjudge:
    • root.pem: The root certificate, that can be served in the /ca HTTP endpoint.
  • Must keep secret:
    • root.key: The root private key. This can be used to create root.pem and fake the rest!
  • Misc:
    • kjudge.csr: The certificate signing request. Can be removed.
    • .certs_generated: An empty file signaling to the script that it should not override the keys.

The -https option

As with using the Docker version, you need to supply kjudge with the folder containing its private key and certificate.

Run kjudge with the -https option pointing to the cert folder:

ADMIN_KEY=secret_key kjudge -file kjudge.db -port 443 -https /home/nki/certs

The ROOT_CA_PORT environment variable (for the /ca endpoint) is also supported:

# localhost:8080/ca hosts the root CA
ROOT_CA_PORT=8080 ADMIN_KEY=secret_key kjudge -file kjudge.db -port 443 -https /home/nki/certs