Moodle 5.2.4
Overview
Moodle is the world's most widely used open-source learning management system (LMS). It provides courses, activities (assignments, quizzes, forums, workshops, H5P content and more), enrolment, gradebooks, completion tracking, badges and reports, and is used by schools, universities and companies.
This image packages the official Moodle 5.2.4 release on Ubuntu 24.04 for Amazon EC2, together with SecureAnyCloud's provisioning, hardening and support. It is one version of the SecureAnyCloud 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.
What you get:
- Moodle 5.2.4 (Build: 20261005) in
/var/www/moodle, with the document root at/var/www/moodle/publicand data in/var/www/moodledata - nginx and PHP 8.3 (PHP-FPM, OPcache) at
https://<instance-address>/. Port 80 only redirects to HTTPS - PostgreSQL 16 on the same instance, reachable only through its local Unix socket (no TCP listener) and with no database password
- Moodle's scheduled tasks (
admin/cli/cron.php) run every minute from a systemd timer - A per-instance administrator password and HTTPS certificate, and the whole Moodle site, created on first boot. No default, shared or published credential ships in the image
- 24/7 SecureAnyCloud support
Moodle is free software distributed under the GNU General Public License v3 or later. Moodle is a registered trademark of Moodle Pty Ltd. SecureAnyCloud is not affiliated with, endorsed by, or sponsored by Moodle Pty Ltd.
Security posture
- No default login, no shipped site. The image contains Moodle's code and an empty database server. On first boot,
moodle-firstboot.servicecreates the database and installs the site with Moodle's own command-line installer, using an administrator password generated for this instance. Every per-site value Moodle creates (site identifier, keys, password hashes) is therefore unique to your instance. nginx and PHP-FPM stay stopped until first boot has finished, and the web installer (/install.php) is refused at all times. - No database password. Moodle connects to PostgreSQL as the operating-system user
www-dataover the local socket with PostgreSQL peer authentication. No PostgreSQL role has a password, and PostgreSQL does not listen on any TCP port. - Internet-facing features are off. Email-based self-registration, the guest login button, web services and the Moodle mobile app endpoint are off on a new site. Turn on only what you need (Step 9).
- Server-side requests cannot reach the instance metadata service. Moodle's own block list for server-side fetches (Site administration > General > Security > HTTP security) includes the private ranges,
169.254.169.254and169.254.0.0/16. In addition, systemd denies nginx, PHP-FPM, PostgreSQL, Moodle cron and the first-boot units access to the EC2 metadata endpoint. - Updated bundled libraries. Moodle 5.2.4 bundles Guzzle 7.10.0, PSR-7 2.8.0, JMESPath 2.8.0 and FPDI 2.6.4, which have published advisories (including a Guzzle host-check bypass). Following Moodle's own update procedure, this image replaces them with the fixed releases Guzzle 7.16.1, PSR-7 2.13.2, Guzzle Promises 2.6.0, JMESPath 2.9.2 and FPDI 2.6.9. TinyMCE and PrismJS carry Moodle's own security backports (MSA-26-0045).
- HTTPS from first boot, address from configuration. nginx serves Moodle on port 443 with a per-instance self-signed certificate, and port 80 returns a 301 redirect to HTTPS. Moodle's site address (
$CFG->wwwroot) is set from configuration (your DNS name, or the EC2 public name), never from a browser'sHostheader. Requests for any other host name are dropped. - Client IP from the socket. Moodle's login lockout and logs use the real connecting address. nginx drops client-supplied
X-Forwarded-For,X-Real-IP,Client-IPandForwardedheaders, and Moodle is configured to trust onlyREMOTE_ADDR. - Uploads stay out of the web root. Uploaded files live in
/var/www/moodledata, outside the document root, and are served only through Moodle's permission checks. The code tree is read-only to the web server. - Hardened base. Key-only SSH with root login and X11 forwarding off, fully patched Ubuntu 24.04 at build time, and the PHP 8.3 build that fixes CVE-2026-109618 and CVE-2026-109619.
Known residual advisories (not reachable in Moodle). Moodle 5.2.4 also bundles PhpSpreadsheet 5.2.0, OTPHP 11.3.0, the AWS SDK for PHP 3.369.22, Slim 4.15.1 and php-jwt 6.11.1. They have published advisories in code paths that Moodle does not use:
- Moodle only writes spreadsheets, and every PhpSpreadsheet advisory is in a reader or the HTML writer.
- Moodle only generates TOTP secrets, and the OTPHP advisories are in parsing provisioning URIs.
- Moodle never uses the AWS CloudFront signer.
- Moodle renders Slim errors with its own renderer.
- The php-jwt finding is rated low.
These libraries are fixed when Moodle updates them upstream.
Launch from AWS Marketplace
Subscribe to the Hardened Moodle & E-Learning Platforms AMIs listing, choose Moodle 5.2.4 on Ubuntu 24.04 as the software version, and launch.
The recommended instance type is m5.large (2 vCPU, 8 GiB) for a pilot or a few hundred users. Choose a larger instance for heavier use.
In the security group, open TCP 22 (SSH, your own address only), TCP 80 and TCP 443. Do not open 5432, because PostgreSQL has no network listener.
The root volume is 12 GiB. Course files grow in /var/www/moodledata, so give the instance a bigger root volume at launch if you expect many uploads.
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 \
--block-device-mappings 'DeviceName=/dev/sda1,Ebs={VolumeSize=40,VolumeType=gp3}' \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=moodle}]'First boot creates the database, installs the site and provisions the per-instance credentials. Wait about three minutes before the site answers.
Connect over SSH
OS variant SSH login user
Ubuntu 24.04 ubuntu
ssh -i /path/to/your-key.pem ubuntu@<instance-address>The login banner shows the site address and the location of the credentials file.
Retrieve your credentials
First boot writes the per-instance administrator password to a root-only file. Read it with:
sudo cat /root/moodle-credentials.txtThe file gives the site address, the administrator user admin and its per-instance password (shown here as <redacted>):
moodle.url=https://ec2-100-59-14-14.compute-1.amazonaws.com/ moodle.admin.user=admin moodle.admin.pass=<redacted>There is no database password. Moodle reaches PostgreSQL as the system user www-data through the local socket.
Sign in
Browse to the moodle.url address. The certificate is self-signed for this instance, so your browser shows a warning the first time. Accept it, or install your own certificate (Step 7). Sign in as admin with the password from the credentials file.
After you sign in, you land on the dashboard:
Change the administrator password straight away. Open your user menu, then choose Preferences > Change password. Set the administrator's real email address under Edit profile.
Check the services
sudo moodle-set-hostname --show systemctl is-active nginx php8.3-fpm postgresql@16-main moodle-cron.timer curl -sk -o /dev/null -w '%{http_code}\n' https://127.0.0.1/login/index.php
sudo -u www-data php /var/www/moodle/admin/cli/cfg.php --name=releaseExpected output on a healthy instance:
https://ec2-100-59-14-14.compute-1.amazonaws.com/ (automatic: EC2 instance address) active active active active 200 5.2.4 (Build: 20261005)Moodle cron runs every minute from moodle-cron.timer as www-data. To check the timer, run:
systemctl list-timers moodle-cron.timer --no-pagerUse your own domain name and certificate
Point a DNS record at the instance. An Elastic IP keeps the address stable. Then pin Moodle to that name:
sudo moodle-set-hostname lms.example.comThis writes $CFG->wwwroot = 'https://lms.example.com' into /var/www/moodle/config.php, makes nginx answer that name, issues a new self-signed certificate for it and purges Moodle's caches. Run sudo moodle-set-hostname --auto to return to the EC2 address. Without a pinned name, the site follows a public address that changes after a stop and start on the next boot.
To use a certificate from a public authority, replace /etc/ssl/moodle/moodle.crt (full chain) and /etc/ssl/moodle/moodle.key (mode 0600, owner root), then reload nginx. For example, with Let's Encrypt:
sudo apt-get install -y certbot
sudo certbot certonly --webroot -w /var/www/moodle/public -d lms.example.com
sudo ln -sf /etc/letsencrypt/live/lms.example.com/fullchain.pem /etc/ssl/moodle/moodle.crt
sudo ln -sf /etc/letsencrypt/live/lms.example.com/privkey.pem /etc/ssl/moodle/moodle.key
sudo systemctl reload nginxCreate your first course
Go to Site administration > Courses > Manage courses and categories > Create new course. Give the course a full and a short name and save it. Then add activities with Edit mode switched on.
Everything else, including users, authentication, plugins, appearance, the site name and the front page, is under Site administration:
Set the outgoing mail server under Site administration > Server > Email > Outgoing mail configuration, so that notifications and password-reset emails are delivered. Amazon SES works well.
Turn on the features you need
These features are deliberately off on a new site. Turn on only what you need:
- Self-registration: open Site administration > Plugins > Authentication > Manage authentication. Under Self registration, choose Email-based self-registration. This needs working outgoing email.
- Guest access: open Site administration > Plugins > Authentication > Manage authentication. Set Guest login button to Show.
- The Moodle mobile app: open Site administration > General > Mobile app > Mobile settings and enable web services for mobile devices.
- Web services for integrations: open Site administration > General > Advanced features and enable web services. Then follow Site administration > Server > Web services > Overview.
Back up and restore
Moodle's state is the PostgreSQL database plus /var/www/moodledata and config.php. To take a consistent backup, run:
sudo install -d -m 0700 /root/moodle-backup
sudo -u postgres pg_dump --format=custom moodle | sudo tee /root/moodle-backup/moodle-db.dump >/dev/null
sudo tar -C /var/www -czf /root/moodle-backup/moodledata.tar.gz moodledata
sudo cp /var/www/moodle/config.php /root/moodle-backup/
sudo ls -lh /root/moodle-backup/Copy the backup off the instance, for example to Amazon S3, or use EBS snapshots of the volume.
To restore onto a fresh instance of this image, put the site in maintenance mode, then load the dump and the data directory:
sudo -u www-data php /var/www/moodle/admin/cli/maintenance.php --enable sudo systemctl stop moodle-cron.timer php8.3-fpm
sudo -u postgres dropdb moodle
sudo -u postgres createdb --owner=www-data --encoding=UTF8 --template=template0 moodle
sudo cat /path/to/moodle-db.dump | sudo -u postgres pg_restore --no-owner --role=www-data -d moodle
sudo tar -C /var/www -xzf /path/to/moodledata.tar.gz
sudo systemctl start php8.3-fpm moodle-cron.timer
sudo -u www-data php /var/www/moodle/admin/cli/maintenance.php --disableYou can also back up individual courses with Moodle course backups, under Course administration > Backup.
Updates
Ubuntu security updates install automatically (unattended-upgrades).
To update Moodle itself, replace the code with a newer release and run sudo -u www-data php /var/www/moodle/admin/cli/upgrade.php. Take a backup first and follow Moodle's upgrade notes for the target release.
To reset a forgotten administrator password from the shell, run sudo -u www-data php /var/www/moodle/admin/cli/reset_password.php and answer its prompts. Never put a password on a command line.
Troubleshooting
- The site does not answer after launch. First boot takes about three minutes. Check
sudo journalctl -u moodle-firstboot.service --no-pager. - "Incorrect access detected" or redirects to the wrong address. The site address is pinned to one name. Run
sudo moodle-set-hostname --show, thensudo moodle-set-hostname <your-name>or--auto. - Cron warnings on the Notifications page. Check
systemctl list-timers moodle-cron.timerandsudo journalctl -u moodle-cron.service --no-pager | tail. - Files and logs. nginx logs are in
/var/log/nginx/, PHP-FPM logs are injournalctl -u php8.3-fpm, and PostgreSQL logs are in/var/log/postgresql/.
Support
SecureAnyCloud provides 24/7 technical support for this image by email and live chat: sales@secureanycloud.com.
Every product in this listing is covered on the Hardened Moodle & E-Learning Platforms AMIs guide hub.
Deploy on AWS
Launch Moodle 5.2.4 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