Deployment guide

Stud.IP LMS 6.1.2

Overview

This guide covers launching and using Stud.IP 6.1.2 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 pick it as the software version when you subscribe and launch. The listing's guide hub describes the other learning platforms in the listing.

Stud.IP is a free, open-source learning management system and campus-management platform used by universities, colleges and schools. One web application covers courses and seminars, enrolment and participant management, a personal desktop, files and document folders, forums, wikis, blubber (activity streams) and the Courseware authoring and lesson tool. It also covers schedules and room planning, news, polls, messaging and e-mail, and an administration area for institutions, users and system configuration.

Stud.IP is published under the GNU General Public License version 2 or later. Stud.IP is a trademark of its respective owner. SecureAnyCloud is not affiliated with, endorsed by, or sponsored by the Stud.IP e.V. project. This image packages the upstream open-source release together with SecureAnyCloud's provisioning, hardening and support.

What you get:

  • Stud.IP 6.1.2, served from /usr/local/studip (only the public/ directory is the web root)
  • PHP 8.3 (PHP-FPM) behind nginx, reachable at https://<instance-address>/. Port 80 only ever redirects to HTTPS and serves no content of its own
  • A local MariaDB 10.11 database, bound to 127.0.0.1 only
  • A per-instance administrator password and HTTPS certificate generated on first boot. No default, shared or published credential ships in the image
  • A database and schema created on the instance's first boot. Stud.IP's browser setup wizard is removed from the image, so there is no route for a stranger to claim your installation
  • Self-registration, password-request-by-user and plugin upload off by default (opt-in below)
  • Password reset and notification links that always point at this instance's own address, never at a hostname supplied by a browser
  • No demo or sample data, so you start from a clean system
  • 24/7 SecureAnyCloud support

Security posture

  • No default login. Stud.IP ships a well-known super-administrator, root@studip, whose stock password is testing. On this image that account does not exist until first boot. First boot immediately rotates it to a unique per-instance password before the web tier is ever reachable. The web tier stays stopped behind a bootstrap gate until the database is built, the password is rotated, and root@studip / testing (and other guessable passwords) are proven refused.
  • No database password at all. The application connects to MariaDB as the system user www-data over the local socket (MariaDB unix_socket authentication). There is no database password in the image or on any instance. MariaDB's root@localhost also uses socket authentication with no stored password, and MariaDB listens only on 127.0.0.1.
  • The image ships un-bootstrapped. The captured image contains an empty MariaDB datadir: no Stud.IP database, no application account and no schema. First boot creates them from Stud.IP's own schema files. The setup wizard (public/install.php, public/web_migrate.php) is deleted from the image. nginx executes only the named Stud.IP front controllers, and any other .php URL (an upload, a guessed path) is refused with 404.
  • HTTPS from first boot. nginx serves Stud.IP on port 443 with a per-instance self-signed certificate generated on the instance. Port 80 returns a 301 redirect to https://<configured host>/. A request whose Host is not one of this instance's own names is refused.
  • Host from configuration, never the request. The served name comes from an operator-set file or the EC2 instance metadata. Stud.IP's base URL (ABSOLUTE_URI_STUDIP) is the base of every absolute link and of password-reset and notification e-mail links. It is always this instance's own address and can never be poisoned by a forged Host header.
  • Client IP from the socket. nginx hands PHP the real connecting address and blanks client-supplied X-Forwarded-For / X-Real-IP / Client-IP / Forwarded headers.
  • No metadata access for the application. systemd denies nginx, PHP-FPM, MariaDB, the cron worker and the first-boot unit access to the EC2 instance metadata endpoint (169.254.169.254). An SSRF in the application therefore cannot reach instance credentials.
  • Internet-open features off by default. Upstream Stud.IP enables self-registration (ENABLE_SELF_REGISTRATION), user-initiated password-request mail (ENABLE_REQUEST_NEW_PASSWORD_BY_USER) and plugin upload. This image turns all three off, so a fresh instance never exposes account creation or plugin upload to the internet. Enable them deliberately when you need them (see Step 11).
  • Mitigated residual: CVE-2024-4367 (PDF.js). Stud.IP 6.1.2 bundles pdfjs-dist 2.16.105, which is affected by CVE-2024-4367 (GHSA-wgrm-67xf-hhpq). A malicious PDF opened in a Courseware Document block could run JavaScript in the site origin. The upstream fix (pdfjs-dist >= 4.2.67) is a major version that Stud.IP 6.1/6.2 does not yet take. This image applies Mozilla's published mitigation flag: the bundled PDF.js build defaults isEvalSupported to false at every entry point, so the exploit's eval/Function path is closed. The build is pinned by SHA-256 so the shipped file cannot drift, and the image ships an enforced Content-Security-Policy (object-src 'none', base-uri 'self', frame-ancestors 'self'). A normal PDF still renders in Courseware, and the exploit PDF does not execute. The residual lifts when Stud.IP ships pdfjs-dist >= 4.2.67.
  • PDF JavaScript is switched off in the PDF viewer. Stud.IP's PDF tools (a file's PDF-Werkzeuge action) open the bundled PDF.js viewer (@studip/pdfjs-studip 5.3.54) on this site's own address. That viewer would run JavaScript embedded in a PDF (pop-up dialogs such as app.alert, form scripts, PDF actions) for whoever opens the file. nginx answers the viewer's scripting sandbox (assets/javascripts/pdfjs/build/pdf.sandbox.mjs and its .map; any URL containing pdf.sandbox) with 404, so a PDF's JavaScript never runs. Viewing, searching, zooming, printing and annotating PDFs are unaffected. Form fields still display, but their scripts (calculations, validation) do nothing. The files on disk are unchanged, and /usr/share/doc/studip/SOURCE.txt lists every change this image makes to upstream Stud.IP. nginx also serves .mjs files as JavaScript (/etc/nginx/conf.d/sac-mjs-mime.conf), which the viewer needs to start.
  • Re-enabling PDF scripting (not recommended). Anyone who can upload a PDF could then show script dialogs, for example a fake password prompt, in other users' sessions. To re-enable it, remove every include /etc/nginx/sac/studip-pdfjs-sandbox.conf; line from /etc/nginx/sites-available/studip, then run sudo nginx -t && sudo systemctl reload nginx.
  • Vendored library fixes. Stud.IP 6.1.2's composer.json pins exact versions of several PHP libraries with published advisories. This image overrides each to its fixed release on the same major line: phpoffice/phpspreadsheet 5.10.0, phpseclib/phpseclib 3.0.57, guzzlehttp/guzzle 7.15.2, guzzlehttp/psr7 2.13.2, spomky-labs/otphp 11.4.3, slim/slim 4.15.2, symfony/process 6.4.33, symfony/yaml 6.4.45 and psy/psysh 0.12.19. composer audit verifies them at build time.
  • Other bundled front-end libraries. The pre-built front end also vendors jsPDF 2.5.2, axios 0.21.4, lodash 4.17.21, DOMPurify 2.5.8, nanoid 3.3.11, MathJax 2.7.6 and CKEditor 43.2.0. Their known advisories are not reachable in Stud.IP's usage. jsPDF is used only for client-side report export with no addJS/AcroForm path. axios runs only the browser XHR adapter. lodash is called only with static templates. DOMPurify is pulled in by an unused jsPDF path. nanoid is called with a fixed size. MathJax's ReDoS is a client-side self-DoS. CKEditor XSS needs an authenticated editor. They are named here for transparency and clear when Stud.IP rebuilds its front end.
1

Launch from AWS Marketplace

Subscribe to the Hardened Moodle & E-Learning Platforms AMIs listing. Choose Stud.IP LMS 6.1.2 on Ubuntu 24.04 as the software version, and launch.

The recommended instance type is m5.large (2 vCPU, 8 GiB) or larger for production. Stud.IP, PHP-FPM and MariaDB run comfortably in 8 GiB.

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

2

Launch from the AWS CLI

# Replace the AMI id with the one shown on the listing in your region, and set your key, subnet and security group.
aws ec2 run-instances \
  --image-id ami-xxxxxxxxxxxxxxxxx \
  --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":20,"VolumeType":"gp3"}}]' \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=studip}]'

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

3

Connect over SSH

Connect as the ubuntu user, which is the SSH login user on the Ubuntu 24.04 variant:

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

Retrieve your credentials

The per-instance administrator password is written to a root-only file on first boot:

sudo cat /root/studip-credentials.txt

The file gives the sign-in URL, the administrator username (root@studip) and its per-instance password. The database needs no password (socket authentication).

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/dispatch.php/login

The output shows active three times and 200 for the login page. Only ports 22, 80 and 443 listen beyond loopback. Confirm it:

ss -tlnH | awk '{print $4}' | sort -u
6

Sign in

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

Sign in as root@studip with the password from Step 4. On first sign-in, Stud.IP asks you to accept the terms of use and to change the password. Choose a new one.

After sign-in, Stud.IP opens your personal desktop. The interface language follows the browser. Switch it under your profile settings:

7

Set up your institution

As root@studip (the system administrator), open the Admin area. Create your institution, add faculties and institutes, create user accounts (lecturers, tutors, students), and create your first course.

Stud.IP's own help covers the campus workflow. Nothing in this image changes it.

8

The background worker

Stud.IP's scheduled tasks (notifications, cleanups, digests) run from a systemd timer. The timer calls cli/studip cronjobs:worker every minute as www-data. It is enabled automatically after first boot, so you do not need to add a cron entry. Check it:

systemctl status studip-cron.timer
9

Why the setup wizard is gone

Stud.IP's browser installer would let any visitor initialise the database and seize the administrator account. This image builds the database from the command line on first boot and deletes public/install.php and public/web_migrate.php. nginx also refuses any other .php URL. There is nothing to re-run and nothing for a stranger to claim.

10

Use your own hostname and certificate

Point a DNS A record at the instance. Then pin the name, so Stud.IP's links and certificate use it:

sudo studip-set-hostname lms.example.edu

This rewrites nginx's server_name, the certificate's subject-alternative names and Stud.IP's base URL, and reloads nginx. To go back to the EC2 public name/IP, run sudo studip-set-hostname --auto.

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

11

Enabling self-registration, password reset and plugin upload (opt-in)

These features are off by default. Turn them on deliberately when your deployment needs them:

  • Self-registration and user password-request mail are configuration flags. In Admin > System > Configuration, set ENABLE_SELF_REGISTRATION and/or ENABLE_REQUEST_NEW_PASSWORD_BY_USER to 1. Alternatively, set them from the command line:
# enable self-registration (example; review before enabling in production)
sudo mariadb --protocol=socket -uroot studip \
  -e "UPDATE config SET value='1' WHERE field='ENABLE_SELF_REGISTRATION';"
  • Plugin upload is disabled in config/config_local.inc.php ($PLUGINS_UPLOAD_ENABLE = false;). To allow a root administrator to upload plugin packages, set it to true and reload PHP-FPM. Enable it only on a trusted, access-controlled deployment.
12

Outbound email

Stud.IP sends notification and password-reset mail through the host's mail transport. Configure a relay or SMTP host in config/config_local.inc.php ($MAIL_TRANSPORT, $MAIL_HOST_NAME), following Stud.IP's documentation. Then reload PHP-FPM.

13

Server components

  • Stud.IP 6.1.2: installed at /usr/local/studip, with public/ as the only web root
  • nginx (Ubuntu 24.04 package): TLS on 443, and port 80 sends a 301 redirect to HTTPS
  • PHP 8.3 (FPM): listens on a unix socket, not a TCP port
  • MariaDB 10.11: bound to 127.0.0.1 only, with unix_socket authentication
14

Filesystem layout

  • Application: /usr/local/studip (root-owned; only data/, public/pictures and public/plugins_packages are writable by www-data)
  • Local config: /usr/local/studip/config/config_local.inc.php
  • Source and changes to upstream: /usr/share/doc/studip/SOURCE.txt
  • Credentials: /root/studip-credentials.txt
  • TLS key and certificate: /etc/ssl/studip/
15

Managing the services

sudo systemctl restart nginx php8.3-fpm mariadb
sudo systemctl status studip-cron.timer
16

Backups

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

sudo mariadb-dump --protocol=socket -uroot --single-transaction studip > studip-backup.sql
sudo tar czf studip-data.tgz -C /usr/local/studip data chmod 600 studip-backup.sql studip-data.tgz

Store both copies off the instance. To restore, load the SQL into the studip database and unpack data/.

17

Troubleshooting

  • Site not answering. Check systemctl status studip-firstboot.service, because first boot builds the database. 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 (Step 10).
  • Logs. Run sudo journalctl -u nginx -u php8.3-fpm -u mariadb -u studip-firstboot.
18

Security recommendations

  • Restrict SSH (port 22) to your own address.
  • Keep self-registration and plugin upload off unless you need them (Step 11).
  • Install a CA-issued certificate and pin your hostname (Step 10).
  • Apply OS security updates (unattended-upgrades is enabled), and reboot for a new kernel.
  • Keep /root/studip-credentials.txt private, and change the administrator password after first sign-in.
19

Support and licensing

Stud.IP is licensed under the GNU General Public License version 2 or later. The full text ships at /usr/local/studip/COPYING.

SecureAnyCloud provides the image, its hardening and 24/7 support for the packaging. Stud.IP itself is community open-source software. Stud.IP is a trademark of its respective owner, and SecureAnyCloud is not affiliated with or endorsed by the Stud.IP project.

Deploy on AWS

Launch Stud.IP LMS 6.1.2 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