Deployment guide

TCExam 17.3.1

Overview

TCExam is a free and open-source computer-based assessment (CBA) platform for schools, universities, training providers and certification bodies. You build a question bank (modules, subjects and questions of several types, with images and other media) and assemble tests that draw questions from it. You then schedule the tests for groups of candidates, deliver them in a browser, and review results, statistics and PDF reports.

This guide covers launching and using TCExam 17.3.1 on Ubuntu 24.04 from SecureAnyCloud on Amazon EC2. It is one version of the SecureAnyCloud Hardened Moodle & E-Learning Platforms AMIs listing on AWS Marketplace. You select it as the software version when you subscribe and launch. The listing's guide hub describes the other learning platforms in the listing.

TCExam is free software distributed under the GNU Affero General Public License v3.0 or later. The TCExam name and logo are trademarks of Tecnick.com LTD. SecureAnyCloud is not affiliated with, endorsed by or sponsored by Tecnick.com LTD. This image packages the unmodified upstream release together with SecureAnyCloud's provisioning, hardening and support.

What you get:

  • TCExam 17.3.1 in /var/www/tcexam, with its PDF fonts pre-built
  • PHP 8.3 (PHP-FPM) behind nginx at https://<instance-address>/. Port 80 only redirects to HTTPS.
  • A local MariaDB 10.11 database, bound to 127.0.0.1, which TCExam reaches over the local socket with no password
  • A per-instance administrator password, application salt and HTTPS certificate, all generated on first boot. No default, shared or published credential ships in the image.
  • A small sample question bank and a Sample Quiz, so you can see a working test straight away. You can edit or delete them.
  • 24/7 SecureAnyCloud support

Security posture

  • No default login. Upstream TCExam seeds the administrator admin with the password 1234. On this image, the database does not exist until first boot, and first boot replaces that password with a unique per-instance one before the web tier is reachable. nginx and PHP-FPM stay stopped behind a bootstrap gate until the database is built, the password is rotated and admin / 1234 (and other guessable passwords) are proven refused.
  • No database password. TCExam connects to MariaDB as the system user www-data over the local socket (MariaDB unix_socket authentication), so there is no database password in the image or on any instance. MariaDB listens only on 127.0.0.1.
  • Per-instance application salt. TCExam signs result-access and CSRF tokens with K_RANDOM_SECURITY. The image ships TCExam's stock value, with which TCExam fails closed, and first boot writes a unique value for this instance.
  • The image ships un-bootstrapped. The captured image contains an empty MariaDB datadir. First boot creates the tcexam database from TCExam's own schema files plus the sample bank. The web and command-line installers (install/) are removed from the image.
  • Self-registration and password reset are off. Upstream TCExam enables self-registration and e-mail password reset. This image turns both off, so a fresh instance never lets strangers create accounts. Enable them deliberately when you need them (Step 10).
  • Uploads never execute. TCExam 17.3 stores uploaded question media in cache/. nginx serves that directory as passive content, exactly as TCExam's own cache/.htaccess describes for Apache. Any script (.php, .phtml, .phar, .cgi, .py and so on) is refused with 403 and never runs. HTML, XML, JavaScript and SVG files are sent as downloads, and every response carries X-Content-Type-Options: nosniff and a sandboxing Content-Security-Policy. TCExam itself also rejects script uploads and SVG files that contain scripts.
  • Only TCExam's pages run. nginx executes only the TCExam entry points under /admin/code/ and /public/code/. Configuration, libraries, vendor/, logs and backups cannot be fetched over the web.
  • HTTPS from first boot, host from configuration. nginx serves TCExam on port 443 with a per-instance self-signed certificate, and port 80 returns a 301 redirect to HTTPS. TCExam's base URL (K_PATH_HOST, used for every link it builds) is set from configuration (your DNS name, or the EC2 public name), never from a browser's Host header. Requests for any other host name are refused.
  • Client IP from the socket. TCExam keys sessions, test IP restrictions and test logs on the client address. nginx gives PHP the real connecting address and drops client-supplied X-Forwarded-For, X-Real-IP, Client-IP and Forwarded headers.
  • No instance metadata access for the application. systemd denies nginx, PHP-FPM, MariaDB and the first-boot unit access to the EC2 metadata endpoint (169.254.169.254).
  • Audited PHP libraries. Upstream ships no composer.lock, so SecureAnyCloud resolved one, audited it (no known advisories) and installs exactly that set. The build fails if the installed libraries differ from the audited lock or if composer audit reports anything. The TCPDF demo signing certificate and its private key are removed (PDF signing is off by default).
1

Launch from AWS Marketplace

Subscribe to the Hardened Moodle & E-Learning Platforms AMIs listing, choose TCExam 17.3.1 on Ubuntu 24.04 as the software version, and launch.

The recommended instance type is m5.large (2 vCPU, 8 GiB). For large simultaneous exam sessions, choose a bigger instance.

In the security group, open TCP 22 (SSH, your own address only), TCP 80 and TCP 443. Do not open port 3306, because MariaDB is loopback only.

2

Launch from the AWS CLI

aws ec2 run-instances \
  --image-id <ami-id-from-the-listing> \
  --instance-type m5.large \
  --key-name <your-key> \
  --security-group-ids sg-xxxxxxxx \
  --subnet-id subnet-xxxxxxxx \
  --associate-public-ip-address \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=tcexam}]'

First boot builds the database and provisions the per-instance credentials. Allow a minute or two before the site responds.

3

Connect over SSH

OS variant SSH login user

Ubuntu 24.04 ubuntu

ssh -i /path/to/your-key.pem ubuntu@<instance-address>
4

Retrieve your credentials

First boot writes the per-instance administrator password to a root-only file. Read the file:

sudo cat /root/tcexam-credentials.txt

The file lists the administration and candidate URLs, the administrator user (admin) and its per-instance password:

TCEXAM_ADMIN_URL=https://ec2-44-206-235-9.compute-1.amazonaws.com/admin/code/ TCEXAM_PUBLIC_URL=https://ec2-44-206-235-9.compute-1.amazonaws.com/public/code/ TCEXAM_ADMIN_USER=admin TCEXAM_ADMIN_PASSWORD=<TCEXAM_ADMIN_PASSWORD>
5

Verify the services

systemctl is-active mariadb php8.3-fpm nginx curl -sk -o /dev/null -w '%{http_code}\n' https://127.0.0.1/admin/code/index.php

The output shows active three times and 200. Only ports 22, 80 and 443 listen beyond loopback. MariaDB is on 127.0.0.1:3306, and the other listeners are the local DNS resolver. Confirm the listeners:

ss -tlnH | awk '{print $4}' | sort -u
0.0.0.0:22 0.0.0.0:443 0.0.0.0:80 127.0.0.1:3306 127.0.0.53%lo:53 127.0.0.54:53 [::]:22 [::]:443 [::]:80
6

Sign in to the administration area

Open https://<instance-address>/admin/code/ in a browser. The certificate is self-signed per instance, so accept the browser warning or install your own certificate (Step 9).

Sign in as admin with the password from Step 4, then change the password under users.

7

Build questions and tests

TCExam organizes content as modules, topics (subjects) and questions, all under the modules menu. The image ships a General Knowledge topic with three single-choice questions and a Sample Quiz that draws all three. Open tests to see how a test selects questions, sets its duration and score, and limits who can take it (user groups, IP ranges, dates).

The modules menu also lists the question bank. You can add questions by hand, attach images and audio, or import whole topics from TCExam XML or TSV files (the import page under modules).

Create candidate accounts under users (or import them from CSV/XML), put them in a group, and add that group to the test.

8

Take a test as a candidate

Candidates sign in at https://<instance-address>/public/code/. They see the tests open to their groups, start one, answer the questions and, if the test allows it, see their results. The administrator account belongs to the default group, so it is offered the Sample Quiz.

Results, statistics and PDF reports are under tests (results) in the administration area. Candidates see their own results under results in the candidate area.

9

Use your own hostname and certificate

Point a DNS A record at the instance, ideally an Elastic IP. Then pin the name so that TCExam's links and the certificate use it:

sudo tcexam-set-hostname exams.example.edu

This command rewrites nginx's server_name, the certificate's subject alternative names and TCExam's K_PATH_HOST, and reloads nginx and PHP-FPM. To go back to the EC2 public name, run sudo tcexam-set-hostname --auto.

To use a CA-issued certificate (for example from Let's Encrypt), install your key and certificate at /etc/ssl/tcexam/tcexam.key and /etc/ssl/tcexam/tcexam.crt. Delete /etc/ssl/tcexam/tcexam.crt.sac-san so the per-boot certificate manager leaves your certificate alone, and then run sudo systemctl reload nginx.

10

Enabling self-registration or password reset (opt-in)

Both features are off by default. Password reset sends e-mail, so configure outbound mail first (Step 11). To enable a feature, edit the shared configuration and set its constant to true. Locate the constants:

sudo grep -n "K_USRREG_ENABLED'" /var/www/tcexam/shared/config/tce_user_registration.php
sudo grep -n "K_PASSWORD_RESET'" /var/www/tcexam/shared/config/tce_config.php

For example, run sudo sed -i "s/define('K_USRREG_ENABLED', false);/define('K_USRREG_ENABLED', true);/" /var/www/tcexam/shared/config/tce_user_registration.php, and then sudo systemctl reload php8.3-fpm. Self-registration lets anyone on the internet create a candidate account, so enable it only behind your own access controls.

11

Outbound e-mail

TCExam sends registration and password-reset mail with PHPMailer. The image has no local mail server. Set your SMTP relay in /var/www/tcexam/shared/config/tce_email_config.php (host, port, user, password and sender address), and then reload PHP-FPM.

12

Server components

Component Version Notes

TCExam 17.3.1 /var/www/tcexam, AGPL-3.0-or-later

nginx 1.24 (Ubuntu 24.04) TLS on 443, 80 redirects to HTTPS

PHP 8.3 (FPM) unix socket, not a TCP port

MariaDB 10.11 127.0.0.1 only, unix_socket authentication

13

Filesystem layout

  • Application: /var/www/tcexam (root-owned and read-only to the web server, except cache/, admin/backup/ and the two log/ directories)
  • Configuration: /var/www/tcexam/shared/config/
  • Uploaded media: /var/www/tcexam/cache/
  • Credentials: /root/tcexam-credentials.txt
  • TLS key and certificate: /etc/ssl/tcexam/
14

Managing the services

sudo systemctl restart mariadb php8.3-fpm nginx systemctl is-active mariadb php8.3-fpm nginx
15

Backups

Back up the database and the uploaded media. The database uses socket authentication, so run the dump as root on the instance and keep the files private:

sudo mariadb-dump --protocol=socket -uroot --single-transaction tcexam | sudo tee /root/tcexam-backup.sql > /dev/null
sudo tar czf /root/tcexam-cache.tgz -C /var/www/tcexam cache
sudo chmod 600 /root/tcexam-backup.sql /root/tcexam-cache.tgz

Copy both files off the instance. To restore, create the database with CHARACTER SET utf8mb3 COLLATE utf8mb3_unicode_ci (the character set TCExam's schema uses), load the SQL into it, and unpack cache/.

16

Troubleshooting

  • Site not responding: check systemctl status tcexam-firstboot.service. If first boot failed, the web tier stays stopped by design.
  • Certificate warning: this is expected with the per-instance self-signed certificate. Install your own certificate (Step 9).
  • Logs: see sudo journalctl -u nginx -u php8.3-fpm -u mariadb -u tcexam-firstboot and /var/www/tcexam/admin/log/.
17

Security recommendations

  • Restrict SSH (port 22) to your own address.
  • Change the administrator password after your first sign-in, and keep /root/tcexam-credentials.txt private.
  • Keep self-registration off unless you need it (Step 10).
  • Install a CA-issued certificate and pin your hostname (Step 9).
  • Unattended-upgrades applies OS security updates automatically. Reboot to load a new kernel.
18

Support and licensing

TCExam is free software distributed under the GNU Affero General Public License v3.0 or later. The license text ships at /var/www/tcexam/LICENSE. If you modify TCExam and offer it to users over a network, the AGPL requires you to offer them your modified source.

SecureAnyCloud provides the image, its hardening and 24/7 support for the packaging. The TCExam name and logo are trademarks of Tecnick.com LTD. SecureAnyCloud is not affiliated with or endorsed by Tecnick.com LTD.

Deploy on AWS

Launch TCExam 17.3.1 on Ubuntu 24.04 on AWS with 24/7 support from SecureAnyCloud.

View on Marketplace

Need Help?

Our support team is available 24/7.

sales@secureanycloud.com

Deploy on AWS