Request Tracker 6.0.4
Overview
Request Tracker (RT) is Best Practical's open source ticketing system, used for IT and service desks, security incident response, customer support and any work that arrives as requests. Each request is a ticket in a queue, with its history of correspondence and comments, owners, watchers, priorities, due dates, custom fields, links between tickets, saved searches, dashboards and scrips (rules that act when a ticket changes).
This guide covers the Request Tracker 6.0.4 on Ubuntu 24.04 AMI from SecureAnyCloud on Amazon EC2. It is one version of the SecureAnyCloud help desk, IT service and project management listing on AWS Marketplace. You pick it as the software version when you subscribe and launch.
What you get:
- No stock login. A fresh upstream RT has the user
rootwith thepasswordpassword. On this image that password never exists. First boot creates RT's database with arootpassword unique to your instance, and only that password signs in. - Nothing baked into the image. The image ships no PostgreSQL cluster and no RT secrets. Every instance creates its own database, its own
$SecretKey(which signs RT's forms and session tokens) and its own TLS certificate on first boot. - No database password at all. RT runs under FastCGI as its own system user,
rt. PostgreSQL 16 accepts RT's database role only over the local socket, from processes running asrt(or root), by peer authentication. PostgreSQL has no network listener. - HTTPS from the first boot. nginx serves RT on port 443 with a certificate generated on your instance. Port 80 redirects to HTTPS, and a request for a host name the instance does not serve gets no answer. The session cookie is
SecureandHttpOnly. - Address and name taken from the connection and the configuration. RT is handed the host name you configure, never the
Hostheader a client sends, and it sees and logs the real client address. nginx removes every forwarding header a client could use to pretend to be someone else. - Abuse limits and cross-site protection. The sign-in form, the REST 1.0 and REST 2.0 interfaces, and any request that carries an
Authorizationheader share a limit of 10 a minute per client address. Every other request that sends data (a form post, or anything with a body) is limited to 30 a minute per address, with a burst of 20. That is ample for a person working tickets. RT accepts a user name and password on any of these requests, so the limit bounds password guessing through every page, not only the sign-in form. A user name or password in a URL's query string, and a GET request with a body, are refused outright. The limits use the address the connection comes from, never a header, referrer or cookie a client sends. RT's referrer checks are on, so a link or form on another site cannot act in RT on your users' behalf. - Read-only code and configuration. RT is built into
/opt/rt6, owned by root. Thertuser that runs it cannot change RT's code or its settings. - Metadata access blocked, and an outbound firewall for RT. nginx, RT, PostgreSQL and first boot are blocked from the instance metadata service, so an address an RT user enters gets nothing back from it. The AMI requires IMDSv2. RT's own processes may connect only to public IPv4 addresses: never to the metadata service, to private or reserved ranges, to your VPC's own addresses, or to IPv6. You can let RT reach specific internal addresses, such as a mail relay inside your VPC (Step 9).
- Outgoing mail kept on the instance until you choose a relay. No mail server ships. RT writes the mail it would send (autoreplies and notifications) to files on the instance until you point it at your relay (Step 7).
- Fully patched base. Ubuntu 24.04 LTS is patched at build time, with unattended security upgrades switched on.
What is on the image: Request Tracker 6.0.4 (Best Practical's official release, checksum verified, built from source), plus the Perl modules it needs. Those come from Ubuntu 24.04 or, where Ubuntu's are too old or missing, from checksum-pinned CPAN releases. The image also includes nginx, PostgreSQL 16, Ubuntu 24.04 LTS, cloud-init and the AWS Systems Manager agent. No Ubuntu request-tracker package is used.
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 with a route to the internet (or a private route you use for management).
- A security group that allows TCP 22 (SSH) from your admin network. It must also allow TCP 443 (RT) and TCP 80 (redirects to HTTPS) from the networks your users work from. Your tickets are in RT, so keep 80 and 443 as narrow as you can.
- For email, an SMTP relay such as Amazon SES for the mail RT sends.
Launch the instance
In the AWS Marketplace listing, choose Continue to Subscribe, then Continue to Configuration. Pick Request Tracker 6.0.4 on Ubuntu 24.04 as the software version, choose your Region, and select Launch through EC2.
Choose m5.large (or larger for many users or a large ticket history), your key pair and a security group as described above.
To launch with the AWS CLI instead, 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=request-tracker}]'First boot creates the database. It takes about two minutes after the instance is running.
Connect to your instance
Connect over SSH as the ubuntu user, which is the default user for Request Tracker 6.0.4 on Ubuntu 24.04.
ssh -i <your-key.pem> ubuntu@<public-ip>Check the services
First boot creates the PostgreSQL cluster, RT's database, the secret key, the root password and the certificate. nginx and RT start only after it has finished. Check the services:
systemctl is-active nginx rt-fcgi postgresql@16-main rt-egress-guard rt-firstboot
sudo test -f /var/lib/sac/data/rt-firstboot.done && echo FIRSTBOOT_DONEAll five units should be active, and the first-boot marker should be present. After a later reboot, rt-firstboot shows inactive because it runs only once:
active active active active active FIRSTBOOT_DONEOnly SSH and nginx listen on network ports. PostgreSQL has no network listener at all, and RT's FastCGI workers use a local socket. Confirm it:
sudo ss -lntp | awk 'NR>1 && $4 !~ /^127\.0\.0\.5[34]/ {split($6, p, "\""); print $4, p[2]}' | sort0.0.0.0:22 sshd 0.0.0.0:443 nginx 0.0.0.0:80 nginx [::]:22 sshd [::]:443 nginx [::]:80 nginxGet your URL and password
Print the credentials file as root. It holds your RT URL and the administrator password generated for this instance:
sudo cat /root/request-tracker-credentials.txtOnly root can read the file:
# Request Tracker 6.0.4 - generated on first boot by rt-firstboot.service
# These credentials are unique to this instance; none was baked into the image. Keep this file secret. RT_URL=https://ec2-<public-ip-dashed>.compute-1.amazonaws.com/ RT_ADMIN_USER=root RT_ADMIN_PASSWORD=<RT_ADMIN_PASSWORD>
#
# Open RT_URL in a browser (self-signed certificate minted on this instance's first boot; port 80 redirects to https) # and sign in as root with the password above. Then create your own privileged user and queues (Admin menu). # PostgreSQL 16: unix socket only (no TCP listener, no database password; RT connects as the OS user rt). # Settings: /opt/rt6/etc/RT_SiteConfig.d/ (add 60-local.pm, root:rt 0640; then:
sudo systemctl restart rt-fcgi)
# Outgoing mail is written to /opt/rt6/var/*.mbox until you configure a relay (see the user guide).
# Change the root password:
sudo rt-set-root-password
# Change the name it serves as:
sudo rt-set-hostname <your-dns-name>
# User guide: https://secureanycloud.com/stacks/request-tracker-6-0-4/The URL uses the instance's public DNS name from the EC2 instance metadata. The certificate also names the public and private IP addresses, and nginx answers only to the names in the certificate.
The name is fixed at first boot. If you stop and start the instance without an Elastic IP and its public address changes, run sudo rt-set-hostname with the new name (Step 8). Better still, give the instance an Elastic IP or your own DNS name.
To check the sign-in end to end from the instance itself, run the commands below. They test the HTTPS redirect, an unknown host name being refused, the root password through the real sign-in form, a wrong password being refused, and the stock root/password being refused on both the sign-in form and REST 1.0:
sudo rt-cred-roundtripOK https 301 + unknown Host refused + root sign-in + wrong password refused + stock root/password refused (form and REST 1.0)Sign in
Open the RT_URL in your browser. The certificate is self-signed, so your browser asks you to confirm it the first time. You can install your own certificate in Step 8. Sign in with the user name root and the password from Step 4.
RT opens on your Homepage. It shows the highest-priority tickets you own, the newest unowned tickets, your bookmarked tickets, a Quick ticket creation box, your reminders, the queue list and the dashboards.
Do not work as root. root is RT's superuser. Create a user for yourself (Step 6), give it the rights you need, and keep root for recovery.
If you lose the root password, set a new one from the instance. Without an option, the command generates a random password and writes it to the credentials file. With --stdin, it reads the password you type (24 to 72 letters and digits). Either way, it signs every RT session out:
sudo rt-set-root-password
sudo rt-set-root-password --stdinTickets, queues and users
Create a ticket. Choose Create new ticket at the top of any page, pick a queue, and enter the requestor, subject and message. RT ships with one queue, General.
The ticket opens with its history. Reply writes to the requestor, and Comment adds a note that only staff see. The Actions menu takes, resolves, rejects or links the ticket.
Queues. Create a queue for each team or kind of work under Admin, Queues, Create. Then grant its rights under the queue's Group Rights and User Rights. A queue's Reply Address and Comment Address are the email addresses its mail comes from.
The REST API. RT's REST 2.0 API is at /REST/2.0/. Create an authentication token for the user an integration acts as (the user menu with your initials at the top of the page, then Settings, Auth Tokens). Send the token as Authorization: token <token>.
Requests to the API share the limit of 10 a minute per address with the sign-in form, which suits scripts and light integrations. The limits are in /etc/nginx/conf.d/sac-rt.conf. Put credentials in a header or a POST body, never in the URL, because a query string that names user or pass is refused.
Users. Add each person under Admin, Users, Create. Tick Let this user be granted rights (Privileged) for staff. Unprivileged users are requestors who can use RT's self-service pages. Set each user's password on their user page. Put staff in groups (Admin, Groups) so rights are granted to the group, not to each person.
Outgoing mail stays on the instance until you configure it. No mail server ships. RT is set to write each message it would send to a file under /opt/rt6/var/, named after the RT worker's start time:
sudo find /opt/rt6/var -maxdepth 1 -name '*.mbox' | wc -lA new instance has sent nothing yet. Count the files:
0The count is above 0 once RT has sent an autoreply or notification, for example after you create a ticket in Step 6.
Send through a relay. Install a minimal sendmail replacement such as msmtp-mta. Configure it for your relay in /etc/msmtprc (for Amazon SES: email-smtp.<region>.amazonaws.com, port 587, tls on, and your SES SMTP credentials). Make that file root:rt mode 0640 so only RT can read the credentials. Then tell RT to use it in your own settings file:
sudo apt-get install msmtp-mta
sudo install -o root -g rt -m 0640 /dev/null /opt/rt6/etc/RT_SiteConfig.d/60-local.pm
sudo nano /opt/rt6/etc/RT_SiteConfig.d/60-local.pmSet($MailCommand, 'sendmailpipe'); Set($SendmailPath, '/usr/sbin/sendmail'); Set($CorrespondAddress, 'support@<your-domain>'); Set($CommentAddress, 'support-comment@<your-domain>'); Set($OwnerEmail, 'rt-admin@<your-domain>'); 1;sudo systemctl restart rt-fcgiRT may reach public addresses, so a relay on the internet such as SES works as it is. A relay at a private address (inside your VPC or on premises) must be added to RT's outbound allow-list first (Step 9).
Incoming mail. RT receives mail through its rt-mailgate program. Your mail server or a fetch tool runs it for each message, with the queue, the action (correspond or comment) and the RT URL. Use --ca-file /etc/nginx/ssl/rt.crt while RT has the self-signed certificate.
rt-mailgate posts to RT's REST 1.0 mail gateway, so each message counts against the REST 1.0 limit of 10 a minute per address. For more than that, deliver to RT from a separate host, or ask support how to raise the limit for your mail server's address.
Your own DNS name and certificate
Point a DNS record at the instance. An Elastic IP keeps the address stable. Then set the name RT is served as.
The command below generates a new self-signed certificate for the name and points nginx and RT's $WebDomain at it. It also updates the URL in /root/request-tracker-credentials.txt and keeps the name across reboots:
sudo rt-set-hostname <your-domain>RT's own name ($rtname and $Organization, which appear in ticket subjects and links) is set once at first boot. It does not change with the host name.
To use a certificate from a public or internal certificate authority instead (for example one issued by Let's Encrypt for <your-domain>), copy it over the generated pair and reload nginx. Running rt-set-hostname again replaces it with a self-signed certificate:
sudo install -m 0644 <your-domain>.crt /etc/nginx/ssl/rt.crt
sudo install -m 0600 <your-domain>.key /etc/nginx/ssl/rt.key
sudo nginx -t && sudo systemctl reload nginxWhat RT can connect to
RT connects out to mail relays and to any address a user or administrator puts into RT (for example in a scrip or an external link check). RT's processes run as the rt user, and rt-egress-guard.service loads an nftables table for that user at every boot.
The table lets RT reach public IPv4 addresses and DNS through the local resolver. It refuses the metadata service, loopback, private, shared and reserved IPv4 ranges, the IPv4 blocks of the instance's own VPC (read at every boot) and all IPv6. Inspect the rules:
sudo nft list table inet sac_rt_egress | grep -oE 'comment "sac-[a-z0-9]+"' | uniqcomment "sac-loopback" comment "sac-metadata" comment "sac-metadata6" comment "sac-multicast" comment "sac-allow" comment "sac-allow6" comment "sac-private" comment "sac-vpc" comment "sac-ipv6"To let RT reach an internal address, such as a mail relay inside your VPC, list it in /etc/sac/rt-egress-allow. Use one private IPv4 or IPv6 CIDR per line. Metadata, link-local, loopback and multicast ranges cannot be listed. Then reload the table:
echo '10.0.5.25/32' | sudo tee -a /etc/sac/rt-egress-allow
sudo systemctl reload rt-egress-guardThe table limits only the rt user. To limit what the whole instance connects to, also use its security group or a network ACL.
Security checks
nginx serves only RT. Plain HTTP redirects to HTTPS, and a request for a name the instance does not serve gets no answer at all. RT is handed the configured name even when a client sends another one. Verify this behavior:
H=$(sudo grep '^RT_URL=' /root/request-tracker-credentials.txt | cut -d= -f2- | sed -E 's#https://([^/]+)/#\1#') for p in / /NoAuth/Login.html /REST/1.0/ /.git/config; do curl -sk -o /dev/null -w "%{http_code} $p\n" --resolve "$H:443:127.0.0.1" "https://$H$p" done curl -s -o /dev/null -w 'http:// -> %{http_code}\n' --resolve "$H:80:127.0.0.1" "http://$H/" curl -sk -o /dev/null -w 'unknown host name -> %{http_code}\n' --resolve "other.example:443:127.0.0.1" "https://other.example/" || true200 / 200 /NoAuth/Login.html 200 /REST/1.0/ 404 /.git/config http:// -> 301 unknown host name -> 000Confirm that the stock RT login is refused:
H=$(sudo grep '^RT_URL=' /root/request-tracker-credentials.txt | cut -d= -f2- | sed -E 's#https://([^/]+)/#\1#')
curl -sk --resolve "$H:443:127.0.0.1" -d 'user=root' -d 'pass=password' "https://$H/REST/1.0/" | head -1RT/6.0.4 401 Credentials requiredRT's database role has no password. PostgreSQL accepts it only over the local socket by peer authentication, and PostgreSQL does not listen on the network:
sudo -u postgres psql -At -c "SELECT rolname || ' password set: ' || CASE WHEN rolpassword IS NULL THEN 'no' ELSE 'yes' END FROM pg_authid WHERE rolname = 'rt_user'" -c 'SHOW listen_addresses' -c 'SHOW ssl'rt_user password set: no offThe certificate is generated on this instance and names its own addresses:
H=$(sudo grep '^RT_URL=' /root/request-tracker-credentials.txt | cut -d= -f2- | sed -E 's#https://([^/]+)/#\1#')
echo | openssl s_client -connect 127.0.0.1:443 -servername "$H" 2>/dev/null | openssl x509 -noout -subject -ext subjectAltNamesubject=CN = ec2-<public-ip-dashed>.compute-1.amazonaws.com, O = sac X509v3 Subject Alternative Name: DNS:ec2-<public-ip-dashed>.compute-1.amazonaws.com, IP Address:<public-ip>, IP Address:<private-ip>, IP Address:127.0.0.1, DNS:localhostNone of the services can reach the instance metadata service. systemd prints the addresses in any order, so the command sorts them:
for u in nginx rt-fcgi postgresql@16-main rt-egress-guard rt-firstboot; do echo "$u: $(systemctl show -p IPAddressDeny --value $u | tr ' ' '\n' | sort | paste -sd ' ')" donenginx: 168.63.129.16/32 169.254.169.254/32 192.0.0.0/24 198.18.0.0/15 224.0.0.0/4 240.0.0.0/4 fd00:ec2::254/128 rt-fcgi: 168.63.129.16/32 169.254.169.254/32 192.0.0.0/24 198.18.0.0/15 224.0.0.0/4 240.0.0.0/4 fd00:ec2::254/128 postgresql@16-main: 168.63.129.16/32 169.254.169.254/32 192.0.0.0/24 198.18.0.0/15 224.0.0.0/4 240.0.0.0/4 fd00:ec2::254/128 rt-egress-guard: 168.63.129.16/32 169.254.169.254/32 192.0.0.0/24 198.18.0.0/15 224.0.0.0/4 240.0.0.0/4 fd00:ec2::254/128 rt-firstboot: 168.63.129.16/32 169.254.169.254/32 192.0.0.0/24 198.18.0.0/15 224.0.0.0/4 240.0.0.0/4 fd00:ec2::254/128Backup, storage and maintenance
Everything you enter is in the PostgreSQL database rt6 (/var/lib/postgresql/16/main), including attachments. RT's settings and this instance's secret key are under /opt/rt6/etc. Both are on the root volume, so the simplest backup is an EBS snapshot of that volume.
For a consistent copy while RT is running, run the commands below. Root signs in to the database as RT's role over the socket:
umask 077
sudo pg_dump -U rt_user -Fc rt6 > <backup-dir>/rt6-$(date +%F).dump
sudo tar -C / -czf <backup-dir>/rt6-config-$(date +%F).tar.gz opt/rt6/etcThe dump holds every password hash and ticket, and the settings archive holds the secret key, so store them as carefully as the instance.
To give the database more room, enlarge the root volume in the EC2 console (Volumes, Modify). Ubuntu grows the file system on the next boot. Contact support if you would like help moving the database to its own EBS volume.
RT removes sessions idle for more than 30 days every day (rt-clean-sessions.timer).
New RT releases arrive as new versions of this listing, and support can help you move your data to one. Operating system security updates install automatically. Run sudo apt-get update && sudo apt-get upgrade to apply everything else. nginx, RT and PostgreSQL restart cleanly, and RT keeps all of its data.
Key locations on the instance:
- Request Tracker: /opt/rt6 (owned by root; RT runs as the rt user)
- Settings: /opt/rt6/etc/RT_SiteConfig.pm and /opt/rt6/etc/RT_SiteConfig.d/ (yours: 60-local.pm)
- Secret key: /opt/rt6/etc/RT_SiteConfig.d/90-sac-secrets.pm (root:rt, mode 0640)
- Database: PostgreSQL 16 database rt6 (/var/lib/postgresql/16/main)
- Outgoing mail files: /opt/rt6/var/*.mbox (until you configure a relay)
- nginx site: /etc/nginx/sites-available/sac-rt
- Certificate and key: /etc/nginx/ssl/rt.crt, /etc/nginx/ssl/rt.key
- Services: rt-fcgi.service, rt-egress-guard.service, rt-clean-sessions.timer
- Outbound allow-list: /etc/sac/rt-egress-allow
- Helpers: /usr/local/sbin/rt-set-root-password, rt-set-hostname, rt-cred-roundtrip
- Logs: journalctl -u rt-fcgi
- Credentials: /root/request-tracker-credentials.txt (mode 0600)
- Source: /usr/share/doc/sac-request-tracker/SOURCE.txt
Security recommendations
- Allow port 22 from your admin network only, and ports 80 and 443 only from the networks your users work from.
- Use your own DNS name and a certificate your users' browsers trust (Step 8).
- Create your own privileged user and give rights to groups rather than people. Keep
rootfor recovery, with a password only you hold (Step 5). - Keep RT's outbound allow-list empty unless RT has to reach an internal address (Step 9).
- Keep the operating system patched, and snapshot the root volume regularly.
Support and licensing
Request Tracker is open source under the GNU General Public License version 2, by Best Practical Solutions and its contributors. There is no per-user licence fee.
The image ships RT exactly as released, built from source into /opt/rt6, which holds its complete source. The file /usr/share/doc/sac-request-tracker/SOURCE.txt names the release, its download address and checksum, and the CPAN modules built for it. The AMI price covers SecureAnyCloud's hardening, first-boot setup and support.
- Email: sales@secureanycloud.com
- Website: https://secureanycloud.com
- Support: 24/7, with a 24-hour response SLA
All product and company names are trademarks or registered trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them. Request Tracker and RT are trademarks of Best Practical Solutions, LLC.
Deploy on AWS
Launch Request Tracker 6.0.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