Applications AWS

Comentario 3.19.0 on AWS User Guide

| Product: Comentario 3.19.0 on Ubuntu 24.04 on AWS

Overview

This guide covers launching and using the Comentario 3.19.0 on Ubuntu 24.04 AMI from cloudimg on Amazon EC2. It is one version of the cloudimg forums and social networks listing on AWS Marketplace; you pick it as the software version when you subscribe and launch.

Comentario is a fast, privacy-focused open source comment server for web pages: a self-hosted alternative to hosted commenting services. You add a short HTML snippet to your site, and Comentario renders a comment thread on every page, with local accounts, moderation, voting, Markdown, RSS feeds, live updates, page view statistics, outbound webhooks, an audit log and a full REST API. One Go service serves the embeddable widget, its API and an Administration UI, and keeps everything in PostgreSQL.

What the cloudimg image adds:

  • No default login. Comentario makes the first account that signs up the instance superuser. On this image that account is created on your instance's first boot, before anything is served, with a password generated on the instance and written to /root/comentario-credentials.txt (root only). The PostgreSQL password and Comentario's server signing key are generated at the same time. The image ships an empty database and no known password.
  • Sign-up closed. Registration of new users in the Administration UI is switched off and users who are not domain owners cannot add domains, so nobody who reaches the instance can create an account on it. You invite users or switch sign-up on yourself. Commenter registration on your own sites is a per-domain setting you control.
  • HTTPS from the first boot. nginx serves Comentario on port 443 with a certificate generated on your instance, port 80 redirects to HTTPS, and requests for a host name the instance does not serve are dropped. Comentario itself listens on 127.0.0.1:8080 only.
  • Fail closed. Comentario and nginx start only after first boot has finished. If it cannot finish, nothing is served.
  • Hardened defaults. Comentario, nginx, PostgreSQL and the first boot service are blocked from the instance metadata service (Comentario fetches page titles, avatars and spam checks from the internet), the AMI requires IMDSv2, Comentario is handed the configured host name and the real client address from the connection (never values a client sends), Comentario refuses state-changing requests from other origins, and nginx also refuses them from a plain http:// origin in front of the Administration UI.
  • Fully patched Ubuntu 24.04 LTS at build time, with unattended security upgrades switched on.

What is on the image: Comentario 3.19.0 (the official package, checksum verified), nginx 1.24 and PostgreSQL 16 (from Ubuntu 24.04), cloud-init and the AWS Systems Manager agent.

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

The Comentario domain page with the HTML snippet to embed and the domain's authentication and comment settings

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, and TCP 443 (Comentario) and TCP 80 (redirects to HTTPS) from the internet, because the comment widget on your sites loads from this instance. Never open 5432 or 8080: PostgreSQL and Comentario listen on the loopback address only.

Step 1: Launch the instance

In the AWS Marketplace listing choose Continue to Subscribe, then Continue to Configuration, pick Comentario 3.19.0 on Ubuntu 24.04 as the software version and your Region, then Launch through EC2. Choose m5.large, your key pair and a security group as above.

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=comentario}]'

First boot takes well under a minute after the instance is running.

Step 2: Connect to your instance

Version SSH user
Comentario 3.19.0 on Ubuntu 24.04 ubuntu
ssh -i <your-key.pem> ubuntu@<public-ip>

Step 3: Check the services

First boot sets the passwords, the signing key and the certificate and creates the owner account, then Comentario and nginx start:

systemctl is-active nginx comentario postgresql@16-main comentario-firstboot
sudo test -f /var/lib/cloudimg/comentario-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 network ports; Comentario and PostgreSQL listen on the loopback address:

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"))
127.0.0.1:5432 users:(("postgres"))
127.0.0.1:8080 users:(("comentario"))
[::]:22 users:(("sshd"),("systemd"))
[::]:443 users:(("nginx"),("nginx"),("nginx"))
[::]:80 users:(("nginx"),("nginx"),("nginx"))

Step 4: Get your URL and password

sudo cat /root/comentario-credentials.txt

The file is readable by root only:

# Comentario 3.19.0 - generated on first boot by comentario-firstboot.service
# These credentials are unique to this instance; none was baked into the image. Keep this file secret.

comentario.url=https://<public-ip>/
comentario.owner.email=admin@comentario.local
comentario.owner.pass=<COMENTARIO_OWNER_PASSWORD>
comentario.db.name=comentario
comentario.db.user=comentario
comentario.db.pass=<COMENTARIO_DB_PASSWORD>

# Sign in at https://<public-ip>/en/auth/login with the owner email and password above. The owner is the
# instance superuser. The certificate is self signed (minted on this instance): accept the browser warning
# once, or install your own. Port 80 redirects to https. Change the name Comentario is served as:
#   sudo comentario-set-hostname <your-dns-name>
# Sign-up in the Administration UI is OFF; turn it on under Administration > Configuration if you want it.
# PostgreSQL listens on 127.0.0.1:5432 only. User guide: https://www.cloudimg.co.uk/guides/comentario-3-19-0-on-ubuntu-24-04-aws/

The URL uses the instance's public IP address from the EC2 instance metadata. The certificate also names the public DNS name and the private IP address. If you stop and start the instance without an Elastic IP, the boot service picks up the new address, issues a new certificate for it and updates Comentario's base URL. To serve Comentario under your own DNS name, which you should do before you embed it in a site, see Step 7.

Step 5: Sign in

Browse to the URL from the credentials file. Your browser warns once about the self signed certificate; accept it (or install your own certificate, Step 7). Sign in with the owner email admin@comentario.local and the password from the credentials file. The Sign up here link on the sign in page leads to a Sign-up closed page until you switch registration on.

The Comentario sign in page with the email and password fields

You land on the dashboard, which summarises users, page views and comments over the last 30 days. The navigation on the left gives you Domains, Users, the Audit log, Configuration and your account. Open your account (Instance Owner) to set your own email address and display name and to change the password.

The Comentario dashboard with the user count, daily views and comments charts

Step 6: Add your site and embed the comments

Choose Domains > New domain, enter the host of the website you want comments on (for example blog.example.com) and a name, and select Create. The domain page shows the snippet to paste into every page that should carry a comment thread:

<script defer src="https://<your-comentario-host>/comentario.js"></script>
<comentario-comments></comentario-comments>

Comentario renders a thread per page URL. Under the domain you moderate Comments, see Pages and Statistics, manage Domain users (moderators) and decide which commenter registration methods are allowed (Edit settings > Authentication): anonymous comments, local accounts or single sign-on. Webhooks on the domain page post comment events to a URL you choose; by default Comentario accepts only https:// targets on public addresses. Federated sign in (GitHub, GitLab, Google and others) needs the provider's keys in /etc/comentario/secrets.yaml; none is configured on this image.

Administration > Configuration > Dynamic holds the instance settings. Enable registration of new users is off on this image; switch it on only if you want anyone to be able to create an account in the Administration UI.

The Comentario dynamic configuration page with Enable registration of new users switched off

The Audit log records sign ins (including failed ones), domain and user changes and other administrative actions, with who did them and when; use Filter to narrow it down.

The Comentario audit log listing sign ins, a failed sign in and the creation of a domain

Set up outbound email (an smtpServer block in /etc/comentario/secrets.yaml, then sudo systemctl restart comentario) so that password resets and reply notifications reach your users.

Step 7: Your own DNS name and certificate

Point a DNS record at the instance (an Elastic IP keeps the address stable), then set the name Comentario is served as. This mints a new self signed certificate for the name, updates nginx and Comentario's base URL (used in the embed snippet, in links and for its origin checks), the URL in /root/comentario-credentials.txt, and keeps the name across reboots:

sudo comentario-set-hostname <your-domain>

Your sites load the widget from this name, so browsers must trust its certificate: install one from a public certificate authority (for example one issued by Let's Encrypt for <your-domain>) over the generated pair and reload nginx (running comentario-set-hostname again replaces it with a self signed one):

sudo install -m 0644 <your-domain>.crt /etc/nginx/ssl/comentario.crt
sudo install -m 0600 <your-domain>.key /etc/nginx/ssl/comentario.key
sudo nginx -t && sudo systemctl reload nginx

Step 8: Security checks

The shipped round trip signs in as the owner with this instance's password over HTTPS, proves a wrong, blank and common password are refused, reads the signed in user, proves the Administration UI refuses a sign-up and that a sign in from another site's origin is refused, and checks that PostgreSQL accepts the application user's password and refuses a wrong one. Credentials are handed to curl and psql in root only temporary files, never on a command line:

sudo bash /usr/local/sbin/comentario-cred-roundtrip.sh
OK per-instance owner signs in over HTTPS (200, superuser); wrong/blank/default passwords refused (401 invalid-credentials); GET /api/user; UI sign-up refused (403 signups-forbidden); cross-origin login refused (403 by the cross-origin check); PostgreSQL app user: right password in, wrong refused

The running instance reports its version, its configured base URL and the closed sign-up settings:

curl -s -H 'Host: localhost' http://127.0.0.1:8080/api/config | jq -c '{version: .staticConfig.version, baseUrl: .staticConfig.baseUrl, signup: (.dynamicConfig | map(select(.key=="auth.signup.enabled" or .key=="operation.newOwner.enabled")) | sort_by(.key) | map({(.key): .value}) | add)}'
{"version":"3.19.0","baseUrl":"https://<public-ip>/","signup":{"auth.signup.enabled":"false","operation.newOwner.enabled":"false"}}

Every service is denied the instance metadata service (and Azure's equivalent address), so a URL Comentario is asked to fetch can never reach your instance credentials:

for u in comentario nginx postgresql@16-main comentario-firstboot; do printf '%s: %s\n' "$u" "$(systemctl show -p IPAddressDeny --value $u.service | tr ' ' '\n' | sort | xargs)"; done
comentario: 168.63.129.16/32 169.254.169.254/32 fd00:ec2::254/128
nginx: 168.63.129.16/32 169.254.169.254/32 fd00:ec2::254/128
postgresql@16-main: 168.63.129.16/32 169.254.169.254/32 fd00:ec2::254/128
comentario-firstboot: 168.63.129.16/32 169.254.169.254/32 fd00:ec2::254/128

The block holds inside the running service. This joins a shell to Comentario's control group and tries to reach the metadata service from there (000 means the connection was refused):

CG=$(systemctl show -p ControlGroup --value comentario.service)
sudo bash -c "echo \$\$ > /sys/fs/cgroup$CG/cgroup.procs; curl -s -m 5 -o /dev/null -w 'metadata from the comentario service: %{http_code}\n' -X PUT -H 'X-aws-ec2-metadata-token-ttl-seconds: 60' http://169.254.169.254/latest/api/token; true"
metadata from the comentario service: 000

Comentario 3.19.0 checks every state-changing request against its own origin (https:// plus the configured host) and refuses requests from other sites; this replaced the cross-site request forgery library of Comentario 3.17 and earlier (CVE-2025-47909). In front of it, nginx also refuses any state-changing request from a plain http:// or null origin before it reaches the Administration UI's API, and accepts WebSocket upgrades only on the embed live-update channel. The first request below comes from another site and is refused by Comentario, the second comes from the plain http:// form of the instance's own host and is refused by nginx:

H=$(sudo sed -n 's#^comentario.url=https://\([^/]*\)/#\1#p' /root/comentario-credentials.txt)
curl -sk --resolve "$H:443:127.0.0.1" -H 'Origin: https://other-site.example' -H 'Content-Type: application/json' -d '{}' "https://$H/api/auth/login" | jq -r .id
curl -sk --resolve "$H:443:127.0.0.1" -H "Origin: http://$H" -H 'Content-Type: application/json' -d '{}' "https://$H/api/auth/login"
xsrf-check-failed
cloudimg: state-changing request from a plain-http origin refused

Step 9: Versions and the command line

dpkg-query -W -f='${Package} ${Version}\n' comentario nginx postgresql-16
id comentario
cat /etc/cloudimg/comentario-release.txt
comentario 3.19.0
nginx 1.24.0-2ubuntu7.18
postgresql-16 16.15-0ubuntu0.24.04.1
uid=997(comentario) gid=987(comentario) groups=987(comentario)
cloudimg: Comentario 3.19.0 (MIT) from gitlab.com/comentario/comentario (package registry), .deb sha256 455b501078da9207d3b8cfa7fae6d4159dc687c312431c9511ac35720e37f9ec; LICENSE sha256 ce3b8dc149745f4095607f25888dd7dd6cd1e585d8761208469bb88ec97cfed9.

Package versions move as Ubuntu publishes security updates. The files that matter:

  • /etc/comentario/comentario.conf: listen address (127.0.0.1:8080), BASE_URL (set by comentario-set-hostname) and other static settings; see the static configuration reference.
  • /etc/comentario/secrets.yaml (owner comentario, mode 0600): the PostgreSQL connection, the server signing key (serverSigningKey), SMTP and identity provider keys.
  • /etc/nginx/sites-available/cloudimg-comentario and /etc/nginx/ssl/: the HTTPS front end and its certificate.
  • journalctl -u comentario shows Comentario's log; restart it with sudo systemctl restart comentario.

Step 10: Changing passwords

Change the owner password in the Administration UI on your account page (Instance Owner), and give each person who manages domains their own account under Users.

To change the PostgreSQL password of the application user, set it in PostgreSQL (you are prompted for it, so it never appears on a command line), put the same value in the password: line of /etc/comentario/secrets.yaml, then restart Comentario:

sudo -u postgres psql -c '\password comentario'
sudo nano /etc/comentario/secrets.yaml
sudo systemctl restart comentario

Step 11: Backup and maintenance

All of Comentario's state (domains, pages, users, comments and settings) is in the comentario PostgreSQL database. Back it up regularly and copy the dump off the instance (for example to Amazon S3):

sudo -u postgres pg_dump -Fc comentario > <backup-dir>/comentario-$(date +%F).dump

Also keep a copy of /etc/comentario/secrets.yaml: the server signing key in it signs email-change confirmations. Ubuntu security updates install automatically. To upgrade Comentario, install a newer release package from the Comentario releases after taking a backup, and restart the service; database migrations run on start. The Administration UI shows a notice when a newer release is available.

Step 12: Security recommendations

  • Serve Comentario under your own DNS name with a publicly trusted certificate before embedding it (Step 7), and keep the security group to 22 from your admin network plus 80 and 443.
  • Set your own email address on the owner account and configure outbound email, so password resets work.
  • Leave Enable registration of new users off unless you need open registration, and choose the commenter sign up methods per domain.
  • Take regular database backups and test a restore.

Support and licensing

Comentario is open source software released under the MIT License (copyright Dmitry Kann and Commento, Inc.); the licence text is installed at /usr/share/doc/comentario/LICENSE. cloudimg provides 24/7 technical support for this image by email and live chat: support@cloudimg.co.uk. For Comentario itself, see the documentation.

Comentario is a trademark of its respective owner. cloudimg is not affiliated with or endorsed by the Comentario project. All other product names are trademarks of their respective owners.