Developer Tools AWS

MantisBT 2.28.4 on AWS User Guide

| Product: MantisBT 2.28.4 Bug Tracker on Ubuntu 24.04 on AWS

Overview

This guide covers launching and using the MantisBT 2.28.4 Bug Tracker on Ubuntu 24.04 AMI from cloudimg on Amazon EC2. It is one version of the cloudimg developer and API tools listing on AWS Marketplace; you pick it as the software version when you subscribe and launch.

MantisBT (Mantis Bug Tracker) is a long established open source web based issue tracker. Teams use it to record bugs and feature requests in projects, route them through a configurable workflow (new, feedback, acknowledged, confirmed, assigned, resolved, closed), add custom fields, tags and relationships, save filters, publish a roadmap and change log, and connect other tools through its REST API.

The cloudimg image locks MantisBT down:

  • HTTPS from the first boot. nginx serves MantisBT on port 443 with a certificate generated on your instance's first boot. Port 80 redirects to HTTPS.
  • No default login. A stock MantisBT install creates the account administrator with the password root. On this image the administrator's password is generated on your instance's first boot and written to /var/lib/cloudimg/mantisbt-credentials.txt (root only); the well known root password and a blank password are refused. MantisBT's crypto master salt and the administrator's login cookie string are also generated per instance. Nothing secret is baked into the image.
  • Closed to strangers by default. Self-signup, anonymous access and the e-mail based lost password feature are off until you turn them on, so only accounts an administrator creates can sign in. The web installer and the whole admin/ directory are removed.
  • Your own database, local only. The image ships an empty database directory. On first boot MariaDB initialises it on the separate data volume (/data, 20 GiB by default) and loads MantisBT's schema. MariaDB has no network listener at all, and MantisBT signs in to it over the local socket with operating system (unix_socket) authentication, so there is no database password to leak. The database user can only touch the bugtracker database.
  • The host name comes from configuration, never from the request. MantisBT's base URL is set on first boot from the instance's public DNS name, nginx refuses requests for host names the instance does not serve, and MantisBT always sees the real client address and the configured host, whatever forwarding headers a request carries.
  • Other web sites cannot act with your login. nginx refuses any state changing request (POST and the like) whose browser Origin is not this instance, on top of MantisBT's own form security tokens. The three MantisBT pages that change state on a plain link (switching the default project, saving a filter and signing out) refuse a request that comes from another web site.
  • The web tier cannot reach the instance metadata service. nginx, PHP and MariaDB are blocked at the kernel level from the EC2 instance metadata service (IPv4 and IPv6), so no request, plugin or SQL statement can read the instance's metadata or role credentials. PHP also cannot open remote URLs as files.
  • A pinned, audited release. MantisBT 2.28.4 is installed from the official release archive (checksum pinned) and includes the fixes for every published MantisBT security advisory. The bundled HTTP client libraries were updated to their current releases within the same major version so that none carries a known advisory.
  • Hardened defaults. PHP runs as its own unprivileged user that cannot change MantisBT's code or configuration, keeps login sessions in memory only, and has only the extensions MantisBT needs (the deprecated SOAP API is not served). nginx and PHP refuse to start until first boot has created the database, the certificate and the secrets, and the AMI requires IMDSv2.
  • Fully patched Ubuntu 24.04 LTS at build time, with unattended security upgrades switched on.

What is on the image: MantisBT 2.28.4 (in /var/www/mantisbt, configuration in /etc/mantisbt), MariaDB 10.11, PHP 8.3 (FPM), nginx, Ubuntu 24.04 LTS, cloud-init and the AWS Systems Manager agent.

Default user: ubuntu · Architecture: x86_64 · Recommended instance type: m5.large

Prerequisites

  • An AWS account subscribed to the listing, an EC2 key pair and a VPC subnet.
  • A security group that allows TCP 22 (SSH), TCP 443 (MantisBT) and TCP 80 (redirects to HTTPS) from your own networks only. MantisBT needs no other port: the database is not on the network.

Step 1: Launch the instance

In the AWS Marketplace listing choose Continue to Subscribe, then Continue to Configuration, pick MantisBT 2.28.4 Bug Tracker on Ubuntu 24.04 as the software version and your Region, then Launch through EC2. Choose m5.large, your key pair, a security group as above and a subnet. The AMI has two volumes: the 8 GiB root volume and a 20 GiB data volume for the database (increase it at launch if you expect many attachments, which MantisBT stores in the database).

With the AWS CLI (replace the values in angle brackets):

aws ec2 run-instances --region <region> --image-id <ami-id-from-the-listing> \
  --instance-type m5.large --key-name <your-key-pair> \
  --security-group-ids <your-security-group> --subnet-id <your-subnet> \
  --metadata-options HttpTokens=required,HttpEndpoint=enabled \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=mantisbt}]'

Step 2: Connect to your instance

Version SSH user
MantisBT 2.28.4 Bug Tracker on Ubuntu 24.04 ubuntu
ssh -i <your-key.pem> ubuntu@<public-ip>

Step 3: Check the services

First boot creates the database, the certificate and the secrets, then PHP and nginx start:

systemctl is-active mariadb php8.3-fpm nginx mantisbt-firstboot
sudo test -f /var/lib/cloudimg/mantisbt-firstboot.done && echo FIRSTBOOT_DONE

All four units are active and the first boot marker is present:

active
active
active
active
FIRSTBOOT_DONE

Only SSH and nginx listen on the network. MariaDB has no TCP listener at all and PHP-FPM uses a local socket:

sudo ss -lntp | awk 'NR>1 {print $4, $6}' | grep -v '127.0.0.5' | sed -E 's/,pid=[0-9]+,fd=[0-9]+//g' | sort
0.0.0.0:22 users:(("sshd"),("systemd"))
0.0.0.0:443 users:(("nginx"),("nginx"),("nginx"))
0.0.0.0:80 users:(("nginx"),("nginx"),("nginx"))
[::]:22 users:(("sshd"),("systemd"))
[::]:443 users:(("nginx"),("nginx"),("nginx"))
[::]:80 users:(("nginx"),("nginx"),("nginx"))

Step 4: Get your URL and password

sudo cat /var/lib/cloudimg/mantisbt-credentials.txt

The file is readable by root only and holds the URL, the administrator's user name and this instance's password:

# MantisBT 2.28.4 - generated on first boot by mantisbt-firstboot.service
# These credentials are unique to this instance; none was baked into the image. MantisBT stores only a hash of the
# password. Keep this file secret and change the password after your first sign-in (My Account).

MANTISBT_URL=https://ec2-<public-ip-dashed>.<region>.compute.amazonaws.com/
MANTISBT_ADMIN_USER=administrator
MANTISBT_ADMIN_PASSWORD=<MANTISBT_ADMIN_PASSWORD>
#
# Open MANTISBT_URL in a browser (self-signed certificate minted on this instance's first boot; port 80 redirects to
# https) and sign in. Self-signup, anonymous access and e-mail are OFF; create users under Manage > Manage Users.
# Database: MariaDB 'bugtracker' over the local socket only (no network listener, no database password).
# Self-test:  sudo mantisbt-selftest      Change the served name:  sudo mantisbt-set-hostname <your-dns-name>
# User guide: https://www.cloudimg.co.uk/guides/mantisbt-2-28-4-on-ubuntu-24-04-aws/

The URL uses the instance's public DNS name from EC2 instance metadata. The certificate also names the public and private IP addresses, so https://<public-ip>/ works too (MantisBT then sends you on to the configured name). To serve MantisBT under your own DNS name, see Step 10.

Step 5: Sign in

Open the MANTISBT_URL in your browser. The certificate is self signed, so your browser asks you to confirm it the first time (or install your own certificate, Step 10). Enter administrator, choose Login, enter the password from Step 4 and choose Login again:

The MantisBT 2.28.4 sign-in page on cloudimg, asking for the user name

Then change the password: open the administrator menu at the top right, choose My Account, enter the current password and a new one, and choose Update User.

The image includes a self test. Through nginx it signs the administrator in with MantisBT's real login form, checks that the default password root and a blank password are refused (and clears the failed attempts again so the account is never locked), and checks the security settings:

sudo mantisbt-selftest
SELFTEST-OK https 301 + health + administrator signed in via the login form + default 'root' and blank refused + installer/config/SOAP 404 + signup refused + 403 cross-origin POST + 403 cross-site logout (session kept) + 444 unknown host

Step 6: Create a project and report issues

MantisBT records every issue in a project. As the administrator open Manage, then Projects, choose Create New Project, give it a name (for example Web Shop) and choose Add Project. Pick the project in the project menu at the top right, then choose Report Issue, select a category, write a summary and a description, set the severity and choose Submit Issue.

My View collects the issues assigned to you, the unassigned ones, the ones you reported and recent changes, with a timeline of activity:

MantisBT My View with three issues in the Web Shop project: a Safari checkout bug, a PayPal feature request and a typo

View Issues lists and filters every issue; save a filter to reuse it:

The MantisBT View Issues page listing the three Web Shop issues with their status, category and last update

Open an issue to see and change its status, assignee, severity, tags, relationships and notes:

A MantisBT issue: the major severity Safari checkout bug with its description, status new and the buttons to assign, change status, monitor and close it

Step 7: Add your team

Self-signup is off, so an administrator creates every account: Manage, Users, Create New Account. Enter the user name, real name, e-mail address and access level (viewer, reporter, updater, developer, manager or administrator). Because e-mail is off until you configure it (Step 9), MantisBT asks you for the new user's password on the same form; give it to the user and ask them to change it under My Account. Give each project its own users and access levels under Manage, Projects.

The MantisBT Manage Users page listing the administrator account

MantisBT locks an account after five failed sign-ins in a row; an administrator unlocks it under Manage, Users (the account's page, Reset Password or edit it). The administrator can always be unlocked on the instance:

echo "UPDATE mantis_user_table SET failed_login_count=0 WHERE username='administrator';" | sudo mariadb bugtracker

Step 8: The database

MariaDB runs on the instance with its data on the data volume. It has no network listener (skip_networking), every account signs in with operating system authentication (no passwords anywhere), and MantisBT's database user has privileges on its own database only:

sudo mariadb -N -e "SELECT @@version, @@datadir, @@skip_networking; SELECT CONCAT(User,'@',Host), IF(Priv LIKE '%unix_socket%','unix_socket','-'), IF(COALESCE(JSON_VALUE(Priv,'$.authentication_string'),'') IN ('','invalid'),'no password','PASSWORD') FROM mysql.global_priv ORDER BY 1; SHOW GRANTS FOR 'mantisbt'@'localhost';"
10.11.14-MariaDB-0ubuntu0.24.04.1   /var/lib/mysql/ 1
mantisbt@localhost  unix_socket no password
mariadb.sys@localhost   -   no password
mysql@localhost unix_socket no password
root@localhost  unix_socket no password
GRANT USAGE ON *.* TO `mantisbt`@`localhost` IDENTIFIED VIA unix_socket
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER, CREATE TEMPORARY TABLES, LOCK TABLES ON `bugtracker`.* TO `mantisbt`@`localhost`

(mariadb.sys is MariaDB's locked internal account and cannot sign in. root signs in only as the operating system root user, with sudo mariadb.) The database directory is the data volume:

findmnt -no SOURCE,TARGET,FSTYPE /data
findmnt -no TARGET /var/lib/mysql
df -h --output=size,target /data | tail -1
/dev/nvme1n1 /data  ext4
/var/lib/mysql
  20G /data

To grow it, enlarge the EBS volume in the EC2 console, then run sudo resize2fs on the device that findmnt -no SOURCE /data shows. Attachments are stored in the database, so back it up as one unit. A consistent backup to a directory of your choice:

sudo mkdir -p <backup-dir> && sudo mariadb-dump --single-transaction --routines bugtracker | gzip | sudo tee <backup-dir>/bugtracker-$(date +%F).sql.gz >/dev/null

Keep copies off the instance too, for example in Amazon S3, or take EBS snapshots of the data volume.

Step 9: Turn on e-mail (optional)

E-mail is off, so MantisBT sends no notifications and the lost password link is hidden. To use your own SMTP relay (for example Amazon SES), add these lines to the end of /etc/mantisbt/config_inc.php as root, with your relay's values:

sudo tee -a /etc/mantisbt/config_inc.php >/dev/null <<'EOF'
$g_enable_email_notification = ON;
$g_lost_password_feature     = ON;
$g_send_reset_password       = ON;
$g_phpMailer_method          = PHPMAILER_METHOD_SMTP;
$g_smtp_host                 = 'email-smtp.<region>.amazonaws.com';
$g_smtp_port                 = 587;
$g_smtp_connection_mode      = 'tls';
$g_smtp_username             = '<smtp-user>';
$g_smtp_password             = '<smtp-password>';
$g_from_email                = 'mantisbt@<your-domain>';
$g_webmaster_email           = 'admin@<your-domain>';
EOF

Changes to the configuration apply to the next page you open. Allow outbound TCP 587 from the instance to your relay. Self-signup ($g_allow_signup = ON;) and anonymous access ($g_allow_anonymous_login = ON; with $g_anonymous_account) can be enabled the same way if you want them; leave them off for an internal tracker.

Step 10: Use your own domain and certificate

Point a DNS name at the instance's public IP address (or an Elastic IP), then tell MantisBT to use it. This sets MantisBT's base URL, the names nginx accepts and the guards, and generates a new self signed certificate for the name:

sudo mantisbt-set-hostname mantis.<your-domain>

To use a certificate from a public certificate authority, put the certificate chain in /etc/ssl/mantisbt/mantisbt.crt and its private key in /etc/ssl/mantisbt/mantisbt.key (root only, mode 600) and run sudo systemctl reload nginx. Alternatively put MantisBT behind an Application Load Balancer with an AWS Certificate Manager certificate that forwards to port 443 on the instance.

Step 11: Security notes

The nginx, PHP and MariaDB services are blocked from the instance metadata service:

for u in nginx php8.3-fpm mariadb; do printf '%s ' "$u"; systemctl show -p IPAddressDeny --value "$u" | tr ' ' '\n' | sort | tr '\n' ' '; echo; done
nginx 168.63.129.16/32 169.254.169.254/32 fd00:ec2::254/128 
php8.3-fpm 168.63.129.16/32 169.254.169.254/32 fd00:ec2::254/128 
mariadb 168.63.129.16/32 169.254.169.254/32 fd00:ec2::254/128 

nginx refuses a state changing request that another web site's page sends, and a link from another site to one of the pages that change state on a plain link:

curl -sk -o /dev/null -w '%{http_code}\n' -X POST -H 'Origin: https://evil.example' --data 'username=x' https://localhost/login.php
curl -sk -o /dev/null -w '%{http_code}\n' -H 'Sec-Fetch-Site: cross-site' https://localhost/logout_page.php
curl -sk -o /dev/null -w '%{http_code}\n' https://localhost/admin/install.php
403
403
404

Other notes:

  • Passwords. MantisBT stores the MD5 hash of each password (its standard login method; the alternatives in MantisBT 2.28 are LDAP or HTTP authentication). The administrator password this image generates is a 24 character random string. Ask your users to choose long passwords, or connect MantisBT to your directory with LDAP ($g_login_method = LDAP; and the $g_ldap_* settings).
  • REST API. Create a personal API token under My Account, API Tokens and send it in the Authorization header to https://<your-host>/api/rest/. The SOAP API (deprecated by MantisBT) is not served on this image.
  • Browser libraries. MantisBT 2.28.4 ships jQuery 2.2.4 and Bootstrap 3.4.1, for which public advisories exist with no fix in those major versions. MantisBT serves every page with a Content Security Policy that only allows its own scripts (no inline or third party script), which blocks those script injection paths; the image keeps that policy.
  • Logs and sessions. PHP keeps login sessions in memory (/run/mantisbt-sessions), so a reboot signs everyone out. nginx logs are in /var/log/nginx.

Step 12: Keep it up to date

Ubuntu security updates install automatically. To apply all updates now:

sudo apt-get update && sudo apt-get upgrade -y

MantisBT itself is updated by replacing the release files: download the new release from mantisbt.org, check its checksum, copy it over /var/www/mantisbt keeping /etc/mantisbt, and run MantisBT's database upgrade from the release's admin/ directory, then remove admin/ again. Back up the database first (Step 8). Read the MantisBT release notes before upgrading.

Support and licensing

MantisBT is open source under the GNU General Public License version 2 or later (the MantisBT team and contributors); the licence text is in /usr/share/doc/cloudimg-mantisbt/, and the source code is at github.com/mantisbt/mantisbt. The PHP libraries it bundles are open source under the BSD, LGPL and MIT licences. There is no per user licence fee. The AMI price covers cloudimg's build, hardening, first boot setup and support. MantisBT's own documentation is at mantisbt.org/docs.

  • Email: support@cloudimg.co.uk
  • Website: https://www.cloudimg.co.uk
  • Support: 24/7, with a 24 hour response SLA

The other versions on this listing are on the developer and API tools guide.