Applications AWS

RosarioSIS 13.0.2 on AWS User Guide

| Product: RosarioSIS 13.0.2 on Ubuntu 24.04 on AWS

Overview

This guide covers launching and using RosarioSIS 13.0.2 on Ubuntu 24.04 from cloudimg on Amazon EC2. It is one version of the cloudimg Hardened Moodle & E-Learning Platforms AMIs listing on AWS Marketplace; you pick it as the software version when you subscribe and launch. The other learning platforms in the listing are described on the listing's guide hub.

RosarioSIS is a free and open source student information system for schools: student records and enrolment, scheduling and the course catalogue, the gradebook, report cards and transcripts, attendance, discipline, eligibility, student billing, accounting, food service, school calendars, and a portal for parents and students. RosarioSIS is published under the GNU General Public License version 2. RosarioSIS is a trademark of its respective owner; cloudimg is not affiliated with, endorsed by, or sponsored by it. This image packages the upstream open source release (the GPL core only; none of the commercial add-on modules) together with cloudimg's provisioning, hardening and support.

What is included:

  • RosarioSIS 13.0.2, served from /var/www/rosariosis
  • PHP 8.3 through PHP-FPM behind Apache 2.4, reachable at https://<instance-address>/; port 80 only ever redirects to HTTPS and serves no content of its own
  • A local PostgreSQL 16 database, bound to 127.0.0.1 only and reached by the web application over a Unix socket with peer authentication — there is no database password anywhere
  • A per-instance administrator password and HTTPS certificate, generated on first boot. No default, shared or published credential ships in the image
  • The database is created on the instance from the pristine upstream schema, with the four published default accounts (admin, teacher, parent, student) carrying no password; the administrator receives its per-instance password on first boot, and RosarioSIS's web installer is blocked outright
  • Password-reset and notification links always point at this instance's own address, never at a hostname supplied by a browser
  • 24/7 cloudimg support

Security posture

  • No default login. RosarioSIS's stock schema seeds four accounts whose published password is their own username (admin, teacher, parent, student). On this image those four password hashes are removed from the schema before it is ever loaded, so none of them can sign in. The administrator password is generated on each instance's first boot; no two instances share one, and it is never in the image.
  • No database password at all. PHP-FPM connects to PostgreSQL as the rosariosis role over the local Unix socket using PostgreSQL peer authentication, mapped from the www-data account. The role has no password, so it cannot be used to log in over the network, and there is no database secret in config.inc.php to leak.
  • The web installer is dead. RosarioSIS ships InstallDatabase.php, an unauthenticated endpoint. The database is created from the command line on first boot, and Apache denies InstallDatabase.php and diagnostic.php outright (403), GET and POST alike.
  • Fails closed. Apache and PHP-FPM are held shut by a drop-in until first boot has minted this instance's secrets and certificate, so a half-provisioned instance stays down rather than open.
  • Only the web tier faces the network. The listening set is exactly 22, 80 and 443. PostgreSQL (5432) listens on 127.0.0.1 only, and PHP-FPM is on a Unix socket.
  • Uploads are never executed. Under assets/FileUploads Apache refuses every web-executable extension (.php, .phtml, .phar, .html, .svg, .js, .cgi, .pl, .py, .sh), so a file a user uploads is served as a file and never run (upstream security fix #394, enforced here in the vhost as well).
  • The site address comes from configuration, never from the request. On every boot rosariosis-baseurl.service writes RosarioSIS's $RosarioURL, Apache's server name and the certificate from /etc/cloudimg/rosariosis-hostname if set, otherwise from IMDSv2 (public DNS name, else public IPv4, else private IPv4). Apache answers only that name and refuses any other Host, so a forged Host or X-Forwarded-Host cannot steer the links RosarioSIS builds into reset and notification mail (upstream security fix #396).
  • Real client addresses. mod_remoteip is not loaded and the client-supplied X-Forwarded-For / X-Real-IP / Forwarded headers are stripped, so a forged header cannot make a remote caller look local.
  • No instance metadata access for the web application. RosarioSIS's PHP can be asked to fetch remote URLs, so apache2.service, php8.3-fpm.service and postgresql@16-main.service are blocked from the instance metadata endpoints (169.254.169.254, the Azure wire-server, and the IPv6 and IPv4-mapped forms). Only the first-boot and base-URL units read metadata, once, for the site address.
  • IMDSv2 required. The AMI is registered with ImdsSupport v2.0, so instances refuse token-less (IMDSv1) metadata requests.
  • Key-only SSH. Password and keyboard-interactive logins, root login and X11 forwarding are off in /etc/ssh/sshd_config.d/00-cloudimg.conf; you sign in as ubuntu with your EC2 key pair.
  • Per-instance identity. SSH host keys, the machine id and the HTTPS certificate are all generated fresh on each instance's first boot.
  • Patched at build time. The image is a full apt full-upgrade with all security updates, including PHP 8.3 at the USN-8948-1 build that fixes the "PHP2Shell" RCEs (CVE-2026-109618 / CVE-2026-109619). The bundled JavaScript editor libraries are replaced with current upstream releases (see Security recommendations for the one documented residual).

Step 1: Launch from AWS Marketplace

  1. Open the Hardened Moodle & E-Learning Platforms AMIs listing by cloudimg and choose View purchase options, then subscribe.
  2. Choose Continue to Configuration. Under Software version choose RosarioSIS 13.0.2 on Ubuntu 24.04, pick your Region, and choose Continue to Launch.
  3. Under Choose Action select Launch through EC2.
  4. Set the instance type to m5.large, choose your key pair, and use the seller's security group settings (ports 22, 80 and 443), narrowing port 22 to your management network.
  5. Launch. First boot finishes within two to three minutes.

Step 2: Launch from the AWS CLI

Workstation commands. Replace <ami-id> with the AMI ID shown for the RosarioSIS 13.0.2 on Ubuntu 24.04 software version on the listing's launch page, and use your own VPC, subnet, key pair and address ranges.

aws ec2 create-security-group --group-name rosariosis-sg \
  --description "RosarioSIS" --vpc-id <vpc-id>
aws ec2 authorize-security-group-ingress --group-id <security-group-id> \
  --protocol tcp --port 22 --cidr <your-ip>/32
aws ec2 authorize-security-group-ingress --group-id <security-group-id> \
  --protocol tcp --port 80 --cidr <users-cidr>
aws ec2 authorize-security-group-ingress --group-id <security-group-id> \
  --protocol tcp --port 443 --cidr <users-cidr>

aws ec2 run-instances --image-id <ami-id> --instance-type m5.large \
  --key-name <key-name> --subnet-id <subnet-id> \
  --security-group-ids <security-group-id> --associate-public-ip-address \
  --metadata-options HttpTokens=required \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=rosariosis}]'

aws ec2 describe-instances --instance-ids <instance-id> \
  --query "Reservations[].Instances[].[PublicDnsName,PublicIpAddress]" --output text

Step 3: Connect over SSH

ssh -i <key.pem> ubuntu@<public-dns>

The login user is ubuntu.

Step 4: Retrieve your credentials

First boot writes your instance's credentials to a root-only file:

sudo cat /root/rosariosis-credentials.txt

It looks like this (your values differ):

rosariosis.admin.user=admin
rosariosis.admin.pass=<generated-per-instance>
rosariosis.db.name=rosariosis
rosariosis.db.user=rosariosis
rosariosis.db.auth=peer (no password: PHP-FPM as www-data over the unix socket)

The site address is written to /var/lib/cloudimg/rosariosis-address. First boot takes it from /etc/cloudimg/rosariosis-hostname if that file exists, otherwise from IMDSv2: the instance's public DNS name, else its public IPv4 address, else its private IPv4 address. If you keep credentials centrally, copy the administrator password into AWS Secrets Manager. There is no database password to store.

Step 5: Verify the services

systemctl is-active postgresql@16-main php8.3-fpm apache2 rosariosis-baseurl
ls /var/lib/cloudimg/rosariosis-firstboot.done

All four services print active, and the first-boot marker exists (first boot runs once; after a reboot its unit shows as skipped, which is expected). Only 22, 80 and 443 listen on a public address; PostgreSQL is on localhost:

sudo ss -Hltn | awk '{print $4}' | sort -u

The HTTPS front end answers 200, and port 80 redirects to HTTPS on the same name:

SITE=$(cat /var/lib/cloudimg/rosariosis-address)
curl -sk -o /dev/null -w "%{http_code}\n" "https://${SITE}/index.php"
curl -s  -o /dev/null -w "%{http_code} %{redirect_url}\n" "http://${SITE}/index.php"

The web application reaches PostgreSQL as rosariosis over the local socket with peer authentication, and no database role carries a password:

sudo -u www-data psql -h /var/run/postgresql -U rosariosis -d rosariosis -Atqc "SELECT current_user"
sudo -u postgres psql -Atqc "SELECT count(*) FROM pg_authid WHERE rolpassword IS NOT NULL"

The first prints rosariosis; the second prints 0. The web application cannot reach the instance metadata service. This runs the same request from inside apache2.service and from your shell; the first fails (blocked), the second returns a token:

CG=$(systemctl show -p ControlGroup --value apache2.service)
sudo bash -c "echo \$\$ > /sys/fs/cgroup${CG}/cgroup.procs; exec curl -s -m 5 -o /dev/null -w '%{http_code}\n' -X PUT -H 'X-aws-ec2-metadata-token-ttl-seconds: 60' http://169.254.169.254/latest/api/token"
curl -s -m 5 -o /dev/null -w '%{http_code}\n' -X PUT -H 'X-aws-ec2-metadata-token-ttl-seconds: 60' http://169.254.169.254/latest/api/token

Step 6: Sign in

Browse to https://<instance-address>/ and sign in as admin with the password from /root/rosariosis-credentials.txt. The certificate is self-signed per instance, so your browser warns once; Step 11 installs a trusted certificate. The first sign-in shows RosarioSIS's Confirm Successful Installation screen; change the administrator password there and afterwards from the user menu.

The RosarioSIS sign-in page served over HTTPS

After signing in you land on the RosarioSIS portal:

The RosarioSIS portal after signing in

Step 7: Set up your school

From the administrator account, open School Info to enter your school's name, marking periods and calendar, then Students and Users to add students, staff and parents (individually or by file import), and Scheduling to build the course catalogue and student schedules. The three demo template accounts (teacher, parent, student) ship with no password and cannot sign in until you set one for a real account.

A student's record under Students

A newly added student saved and reopened

Step 8: Why the web installer is blocked

A stock RosarioSIS exposes InstallDatabase.php, an unauthenticated endpoint that still accepts a request while the install is fresh. On this image the database is created from the command line on first boot and Apache denies the installer and the diagnostic page outright: every GET and POST returns 403. You never run the installer.

Step 9: Clear a locked-out account

RosarioSIS locks an account after repeated failed sign-ins. To clear the counter for the administrator from the instance:

sudo -u postgres psql -d rosariosis -c "UPDATE staff SET failed_login=NULL WHERE username='admin';"

Step 10: Use your own hostname

By default the instance serves on its EC2 address. To serve on your own DNS name, point the name at the instance and run:

sudo rosariosis-set-hostname sis.example.com

This rewrites RosarioSIS's $RosarioURL, Apache's server name and the certificate, and persists across reboots. RosarioSIS then answers only that name (plus the instance's own addresses) and builds all reset and notification links from it.

Step 11: Install a trusted certificate

The per-instance certificate is self-signed. Once the instance serves on a public DNS name you control, install a trusted certificate with Certbot:

sudo snap install --classic certbot
sudo certbot --apache -d sis.example.com

Certbot writes the Apache vhost and sets up automatic renewal. Keep 443 reachable from the internet for the HTTP-01 challenge.

Step 12: Outbound email

RosarioSIS sends password-reset and notification mail through the host's mail transport. Configure an SMTP relay (for example Amazon SES with SMTP credentials) and set the notification and error addresses under School Info → System Preferences. Because the site address is pinned to this instance, the links in that mail always point back at your RosarioSIS.

Step 13: Server components

Component Version Notes
RosarioSIS 13.0.2 /var/www/rosariosis, root-owned, read-only to the web server
PHP 8.3 PHP-FPM behind Apache (mpm_event), Unix socket
Apache 2.4 HTTPS vhost + a default reject vhost for unknown Host
PostgreSQL 16 127.0.0.1 only, peer auth over the Unix socket, no password

Step 14: Filesystem layout

Path Purpose
/var/www/rosariosis Application code (read-only to the web server)
/var/www/rosariosis/assets/FileUploads Uploaded files (web-server owned); scripts there are never executed
/var/www/rosariosis/config.inc.php Database connection and $RosarioURL (0640 root:www-data; no password)
/root/rosariosis-credentials.txt Per-instance administrator credential (root only), written on first boot
/etc/cloudimg/rosariosis-hostname Your configured DNS name, if set
/var/lib/cloudimg/rosariosis-address The address currently served

Step 15: Managing the services

sudo systemctl restart apache2 php8.3-fpm   # web tier
sudo systemctl restart postgresql@16-main   # database
sudo journalctl -u apache2 -e               # web logs
sudo journalctl -u rosariosis-firstboot     # first-boot log

Step 16: Backups

Back up the database and the uploads tree:

sudo -u postgres pg_dump --no-owner --no-privileges rosariosis | gzip > /var/backups/rosariosis-$(date +%F).sql.gz
sudo tar czf /var/backups/rosariosis-uploads-$(date +%F).tar.gz -C /var/www/rosariosis assets/FileUploads assets/StudentPhotos assets/UserPhotos

The dump holds your school's records, so make both files root-only straight away with sudo chmod 600 /var/backups/rosariosis-*. Copy them off the instance (for example to Amazon S3) and take EBS snapshots on a schedule. To restore, create an empty rosariosis database owned by the rosariosis role and load the SQL dump, then unpack the uploads archive.

Step 17: Troubleshooting

  • Browser certificate warning: expected until Step 11 installs a trusted certificate.
  • Locked out after failed sign-ins: clear the counter as in Step 9.
  • Site shows the wrong address in emails: set your DNS name with rosariosis-set-hostname (Step 10).
  • Site is down right after launch: first boot has not finished; wait two to three minutes, then check sudo journalctl -u rosariosis-firstboot.

Step 18: Security recommendations

  • Restrict 22/tcp to your management network and front the instance with your own DNS name and a trusted certificate (Steps 10-11).
  • Change the administrator password on the first sign-in and create named staff accounts rather than sharing the administrator.
  • Keep the instance patched: sudo apt update && sudo apt full-upgrade.
  • Known residual advisory. RosarioSIS's rich-text editor is TinyMCE 4.9.11, the last release of the TinyMCE 4.x line. Three cross-site-scripting issues in that line (CVE-2026-47759, CVE-2026-47761, CVE-2026-47762) are fixed only in TinyMCE 5+/7+/8+, which RosarioSIS 13.0.2 does not yet integrate. They require an authenticated teacher to author crafted content that an administrator then opens in the editor, and they are mitigated on this image on three independent layers, so they are not reachable by students, parents or the public:
  • every page that loads the editor sends an enforced Content-Security-Policy (script-src 'self' 'unsafe-eval', with no 'unsafe-inline' and object-src 'none'), which blocks injected inline scripts, javascript: URLs and media-object injection in the browser;
  • RosarioSIS runs server-side HTML sanitisation (xss_clean) on every saved field, which strips scripts, inline event handlers and javascript: URLs; and
  • the rich-text editor is reachable only to teachers and administrators, never to students, parents or unauthenticated visitors.

This build also replaces the bundled DOMPurify 2.3.6 (which carried a critical and several high-severity advisories) with DOMPurify 3.4.17, which has none. The TinyMCE residual is tracked and will be adopted once RosarioSIS integrates a supported TinyMCE major.

Step 19: Support and licensing

RosarioSIS is free software under the GNU General Public License version 2; its source is published upstream. This image ships the GPL core only; none of the commercial add-on modules sold upstream is installed. cloudimg packages the upstream release with the provisioning and hardening described here and provides 24/7 support for this image by email and live chat: support@cloudimg.co.uk.