OpenEduCat 19.0.1.0
Overview
OpenEduCat is an open-source student information and school management application built on the Odoo 19 Community framework. It covers the academic lifecycle: admissions and applicants, student and guardian records, programs, courses, batches and subjects, attendance, assignments, exams and results, timetables, fees, a parent portal and a library. OpenEduCat and Odoo Community are licensed under the GNU Lesser General Public License version 3 (LGPL 3.0).
This guide covers OpenEduCat 19.0.1.0 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 choose it as the software version when you subscribe and launch. The listing's guide hub describes the other learning platforms.
The image ships with the database already created and every OpenEduCat module installed, so you can sign in and start working. No student, guardian, admission or fee records are seeded. School records are yours to enter.
What you get:
- OpenEduCat 19.0.1.0 (pinned commit of the 19.0 branch) on Odoo 19.0 Community from the official Odoo APT repository. The exact Odoo build is recorded in
/etc/sac/openeducat-versions, and theodoopackage is held - The OpenEduCat suite: Core, Admission, Assignment, Attendance, Activity, Classroom, Exam, Facility, Fees, Library, Parent portal and Timetable
- HTTPS from first boot: nginx serves the site on port 443 with a certificate created on your instance's first boot, and port 80 redirects to HTTPS. Odoo itself listens on
127.0.0.1:8069only - PostgreSQL 16 on localhost only. Odoo connects over the local socket with peer authentication, so there is no database password
- One Odoo database named
openeducat, with the database manager and database selector disabled openeducat-firstboot.service, which runs before Odoo may start and creates your instance's Odoo master password, Administrator password and Odoo signing secretopeneducat-set-hostname, which moves the site to your own DNS name- wkhtmltopdf for PDF reports, and a functional self-test
Default user: ubuntu. Architecture: x86_64. Root volume: 20 GiB gp3.
Security posture
- No default login. A stock Odoo install signs in as
admin/admin. This image rejects that login. The Administrator password, the Odoo master password and Odoo'sdatabase.secret(the key that signs sessions, CSRF tokens and sign-up and reset links) are created on each instance's first boot. None of them is in the image, and no two instances share one. The database has no password to steal: Odoo reaches PostgreSQL over the local socket as theodoosystem user (peer authentication), and theodoodatabase role has no password, so it cannot log in over the network at all. - Fails closed. Odoo and nginx start only after first boot has finished, and Odoo refuses to start without a non-trivial master password. If first boot cannot finish, the site stays down rather than open.
- Only nginx faces the network. The listening ports are exactly 22, 80 and 443. Odoo (8069) and PostgreSQL (5432) listen on localhost only. The image's mDNS responder (avahi, pulled in by a dependency) is masked.
- The site address comes from configuration, never from the request. First boot reads it from
/etc/sac/openeducat-hostnameor the EC2 instance metadata service (IMDSv2). nginx answers only that name, drops any other Host and passes Odoo the configured name.web.base.urlis frozen, so a request cannot rewrite the links in emails and reports. - Real client addresses. nginx overwrites
X-Forwarded-ForandX-Real-IPwith the connecting address, so a forged header cannot make a remote caller look local. - Cross-origin requests refused. A state-changing request or WebSocket upgrade that carries another site's
Originis refused by nginx before it reaches Odoo. - No instance metadata access for the application. Odoo can be asked to fetch URLs (attachments, link previews, image and website imports). For that reason,
odoo.service,nginx.serviceand PostgreSQL are blocked from reaching the instance metadata service (169.254.169.254 and fd00:ec2::254). Only the first-boot unit reads it, for the site address. - IMDSv2 required. The AMI is registered with
ImdsSupport v2.0, so instances launched from it refuse token-less (IMDSv1) metadata requests. - Key-only SSH. Password and keyboard-interactive logins, root login and X11 forwarding are turned off in
/etc/ssh/sshd_config.d/00-sac.conf. You sign in asubuntuwith your EC2 key pair. - Per-instance identity. SSH host keys, the machine ID, the site certificate and PostgreSQL's TLS key are generated fresh on every instance.
Prerequisites
Before you deploy, make sure you have:
- An AWS account where you can subscribe to AWS Marketplace products and launch EC2 instances
- An EC2 key pair in the target Region
- A VPC and subnet, with a public IP address on the instance if your users reach it over the internet
- A security group that allows
22/tcpfrom your management network, and80/tcpand443/tcpfrom your users' networks. No other port is needed. Do not open 5432 or 8069
Recommended instance type: m5.large (2 vCPU, 8 GiB RAM). It comfortably serves a single school or small institution. Use m5.xlarge or larger for a large student body or heavy concurrent use.
Launch from AWS Marketplace
- Open the Hardened Moodle & E-Learning Platforms AMIs listing by SecureAnyCloud, choose View purchase options, then subscribe.
- Choose Continue to Configuration. Under Software version, choose
OpenEduCat 19.0.1.0 on Ubuntu 24.04. Pick your Region, then choose Continue to Launch. - Under Choose Action, select Launch through EC2.
- Set the instance type to m5.large and choose your key pair. Use the seller's security group settings (ports 22, 80 and 443), and narrow port 22 to your management network.
- Launch the instance. First boot finishes within two to three minutes.
Launch from the AWS CLI
Run the following commands from your workstation. Replace <ami-id> with the AMI ID shown for the OpenEduCat 19.0.1.0 on Ubuntu 24.04 software version on the listing's launch page. Use your own VPC, subnet, key pair and address ranges.
aws ec2 create-security-group --group-name openeducat-sg \
--description "OpenEduCat" --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=openeducat}]'
aws ec2 describe-instances --instance-ids <instance-id> \
--query "Reservations[].Instances[].[PublicDnsName,PublicIpAddress]" --output textConnect over SSH
Connect to the instance with your EC2 key pair.
ssh -i <key.pem> ubuntu@<public-dns>The login user is ubuntu.
Retrieve your credentials
Read the credentials file. First boot writes your instance's credentials to this root-only file:
sudo cat /root/openeducat-credentials.txtThe file looks like this (your values differ):
OPENEDUCAT_URL=https://ec2-203-0-113-10.compute-1.amazonaws.com/web/login OPENEDUCAT_ADMIN_LOGIN=admin OPENEDUCAT_ADMIN_PASSWORD=<generated-per-instance> OPENEDUCAT_MASTER_PASSWORD=<generated-per-instance>OPENEDUCAT_URL is the site address. First boot takes it from /etc/sac/openeducat-hostname if that file exists. Otherwise it takes it from IMDSv2: the instance's public DNS name, else its public IPv4 address, else its private IPv4 address.
There is no database password. Odoo connects to PostgreSQL over the local socket as the odoo system user (peer authentication). If you keep credentials centrally, copy them into AWS Secrets Manager.
Verify the services
Check that the services are running and the first-boot marker exists:
systemctl is-active odoo nginx postgresql@16-main ls /var/lib/sac/data/openeducat-firstboot.doneAll three services print active, and the first-boot marker exists. First boot runs once, so after a reboot its unit shows as skipped, which is expected.
Only ports 22, 80 and 443 listen on a public address. Odoo (8069) and PostgreSQL (5432) are on localhost:
sudo ss -Hltn | awk '{print $4}' | sort -uOdoo's health endpoint on localhost and the HTTPS front end on the configured name both answer 200:
curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:8069/web/health
SITE=$(cat /var/lib/sac/data/openeducat-current-hostname)
curl -sk -o /dev/null -w "%{http_code}\n" --resolve "${SITE}:443:127.0.0.1" "https://${SITE}/web/login"Port 80 redirects to HTTPS on the same name:
SITE=$(cat /var/lib/sac/data/openeducat-current-hostname)
curl -s -o /dev/null -w "%{http_code} %{redirect_url}\n" --resolve "${SITE}:80:127.0.0.1" "http://${SITE}/web/login"Odoo talks to PostgreSQL over the local socket, and no database role has a password. The first query prints 0. The second lists Odoo's database sessions, all with an empty client address (the socket):
sudo -u postgres psql -tAc "SELECT count(*) FROM pg_authid WHERE rolpassword IS NOT NULL;"
sudo -u postgres psql -tAc "SELECT usename, datname, coalesce(host(client_addr), 'socket') FROM pg_stat_activity WHERE usename = 'odoo';"Confirm that every OpenEduCat module is installed:
sudo -u postgres psql -d openeducat -tAc \
"SELECT name || ' ' || state FROM ir_module_module WHERE name LIKE 'openeducat%' ORDER BY name;"The application cannot reach the instance metadata service. The following commands run the same request from inside odoo.service and from your shell. The first prints 000 (blocked) and the second prints 200:
CG=$(systemctl show -p ControlGroup --value odoo.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/tokenSign in
- Open the
OPENEDUCAT_URLfrom Step 4 in a browser. Plainhttp://redirects to HTTPS. - Accept the browser warning on your first visit. The certificate is self-signed and unique to your instance. Alternatively, install a trusted certificate (Step 8).
- Enter admin as the email and the
OPENEDUCAT_ADMIN_PASSWORDvalue, then choose Log in.
You land in the Odoo backend. The app switcher (the grid icon, top left) lists the OpenEduCat apps alongside the Odoo apps they build on.
The site answers only on its configured name, and a request that names any other host is dropped. Browse to the OPENEDUCAT_URL address or to the name you set in Step 7.
Use your own hostname
Odoo builds the links in emails, the parent portal and reports from web.base.url, which this image sets from configuration and freezes.
To serve the site on your own DNS name, point a DNS record (for example in Amazon Route 53) at the instance's public IP. An Elastic IP keeps the address stable. Then run this on the instance:
sudo openeducat-set-hostname school.example.orgThe helper writes the name to /etc/sac/openeducat-hostname and sets web.base.url to https://school.example.org. It rewrites the nginx server_name and the cross-origin guard, issues a new self-signed certificate for the name, updates OPENEDUCAT_URL in the credentials file, and restarts Odoo and nginx.
An instance without an Elastic IP gets a new public DNS name when it is stopped and started. Run the helper again with the new name so that links and the certificate follow it.
Install a trusted certificate
The site certificate is /etc/ssl/openeducat/openeducat.crt and its key is /etc/ssl/openeducat/openeducat.key (mode 600, root).
To use Let's Encrypt, first set your DNS name (Step 7) and open port 80 to the internet. Then run:
sudo apt-get install -y certbot
sudo certbot certonly --standalone -d school.example.org \
--pre-hook "systemctl stop nginx" --post-hook "systemctl start nginx" \
--deploy-hook "install -m 644 \$RENEWED_LINEAGE/fullchain.pem /etc/ssl/openeducat/openeducat.crt && install -m 600 \$RENEWED_LINEAGE/privkey.pem /etc/ssl/openeducat/openeducat.key"certbot keeps the hooks for every renewal. Running openeducat-set-hostname again replaces the certificate with a self-signed one, so run sudo certbot renew --force-renewal afterwards.
To use a certificate from another authority, copy the full chain and key to the same two paths, then run sudo systemctl reload nginx.
Add your first students and courses
- Open Students from the app switcher and choose New. Enter the first name, last name and email, then save.
- Under SIS > Configuration > Program Level, create a program level (for example, Undergraduate).
- Under SIS > Configuration > Programs, create a program at that level.
- Under SIS > Configuration > Courses, create courses in the program, each with a short unique code.
- Open a student and use the Course Details tab to enrol the student in a course.
Admissions, attendance, exams and the library
- Admissions: use admission registers and the applicant workflow.
- Time Table and Class Attendances: schedule sessions and record attendance per session.
- Assignments and Exams: set assignments with due dates, and manage exam sessions, marksheets and results.
- Library: catalogue media, issue and return items, and print library cards.
- Parents: give guardians portal access to their child's record.
Each app works the same way. New creates a record, and the app's Configuration menu holds the master data: academic years, terms, departments, subjects, batches, classrooms and fee terms.
Server components
Component Version Notes
OpenEduCat 19.0.1.0 (commit 8738c4a, 19.0 branch) github.com/openeducat/openeducat_erp, LGPL 3.0
Odoo Community 19.0 nightly build recorded in /etc/sac/openeducat-versions Official Odoo APT repository; package held
nginx Ubuntu 24.04 package TLS front end on 80/443
PostgreSQL 16 localhost only; peer authentication over the local socket, no password
Python 3.12 Ubuntu 24.04 system Python
wkhtmltopdf Ubuntu 24.04 package PDF reports
cat /etc/sac/openeducat-versions odoo --versionFilesystem layout
Path Purpose
/etc/odoo/odoo.conf Odoo configuration (mode 640, root:odoo)
/etc/nginx/sites-available/openeducat.conf nginx site, written by openeducat-apply-hostname
/etc/ssl/openeducat/ Site certificate and key
/etc/sac/openeducat-hostname Your configured site name (created by openeducat-set-hostname)
/var/lib/odoo/filestore/openeducat/ Odoo filestore (attachments)
/opt/openeducat/addons-src OpenEduCat modules (pinned commit)
/var/log/odoo/odoo-server.log Odoo server log
/root/openeducat-credentials.txt Your credentials (mode 600, root)
/var/log/openeducat-firstboot.log First boot log
/var/lib/sac/data/openeducat-firstboot.done First boot marker; Odoo and nginx start only when it exists
Managing the services
Check the state of the services:
systemctl status odoo nginx --no-pager -n 0
sudo tail -n 20 /var/log/odoo/odoo-server.logRestart Odoo with sudo systemctl restart odoo and reload nginx with sudo systemctl reload nginx.
The Amazon CloudWatch agent can ship /var/log/odoo/odoo-server.log and /var/log/nginx/*.log to CloudWatch Logs.
Backups
Dump the database as the odoo system user (peer authentication over the local socket, no password). Keep the filestore with the dump:
sudo -u odoo pg_dump -F c -d openeducat > ~/openeducat-$(date +%Y%m%d).dump
sudo tar -czf ~/openeducat-filestore-$(date +%Y%m%d).tar.gz -C /var/lib/odoo/filestore openeducatCopy both to an Amazon S3 bucket or another durable destination. For a simple whole-instance backup, take EBS snapshots of the root volume:
aws ec2 create-snapshot --volume-id <volume-id> --description "openeducat $(date +%F)"Troubleshooting
The browser cannot connect, or the connection is dropped. Browse to the configured name (cat /var/lib/sac/data/openeducat-current-hostname). Other host names are dropped by design. Check that ports 80 and 443 are open in the security group.
Odoo or nginx is not running after launch. Both start only after first boot completes. Check the marker and the first-boot unit:
ls -la /var/lib/sac/data/openeducat-firstboot.done
sudo tail -n 20 /var/log/openeducat-firstboot.logIf the marker is missing, first boot did not finish, for example because the metadata service was unreachable. Fix the cause, then run first boot again:
sudo systemctl restart openeducat-firstboot
sudo systemctl start odoo nginxConfirm that OpenEduCat itself works. Run the self-test, which creates a course, reads it back and deletes it:
sudo /usr/local/sbin/openeducat-selftest.sh | tail -n 1It prints OPENEDUCAT_SELFTEST_OK.
Security recommendations
- Keep port 22 limited to your management network.
- Keep the database manager disabled (
dbfilter = ^openeducat$,list_db = False), and back up withpg_dump(Step 14). - Change the Administrator password under Settings > Users & Companies > Users if you share it with anyone.
To rotate the Odoo master password, run:
NEW_PW=$(openssl rand -hex 24)
sudo sed -i "s|^admin_passwd = .*|admin_passwd = ${NEW_PW}|" /etc/odoo/odoo.conf
sudo systemctl restart odooThe odoo database role has no password and is reachable only over the local socket from the odoo system user. Keep it that way. If a reporting or backup tool must connect over the network, create a separate read-only role with its own password rather than giving odoo one. Do not open port 5432 in the security group.
Apply Ubuntu security updates regularly (sudo apt-get update && sudo apt-get upgrade). The odoo package is held, so an upgrade never replaces Odoo underneath the installed modules.
To move to a newer Odoo 19.0 build, take a backup first. Then run sudo apt-mark unhold odoo && sudo apt-get install odoo. Update the modules with sudo -u odoo odoo --config=/etc/odoo/odoo.conf -d openeducat -u all --stop-after-init, then restart Odoo.
Support and licensing
OpenEduCat and Odoo Community Edition are licensed under the GNU Lesser General Public License version 3 (LGPL 3.0). You are responsible for the data protection of the student records you enter. OpenEduCat and Odoo are trademarks of their respective owners. SecureAnyCloud is not affiliated with or endorsed by OpenEduCat Inc. or Odoo S.A.
SecureAnyCloud provides 24/7 technical support by email and live chat at sales@secureanycloud.com. Every product in this listing is on the Hardened Moodle & E-Learning Platforms AMIs guide hub.
Deploy on AWS
Launch OpenEduCat 19.0.1.0 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