Applications AWS

Foswiki 2.1.11 on AWS User Guide

| Product: Foswiki 2.1.11 on Ubuntu 24.04 on AWS

Overview

This guide covers launching and using the Foswiki 2.1.11 on Ubuntu 24.04 AMI from cloudimg on Amazon EC2. It is one version of the cloudimg BookStack, CMS, Blogs and Wikis listing on AWS Marketplace; you pick it as the software version when you subscribe and launch.

Foswiki is a free and open source structured wiki written in Perl: every page is a topic written in wiki markup and kept with its full revision history, organised in webs, with access rules per web and per topic, forms, searches and macros for building small applications inside the wiki. It is used for engineering documentation, knowledge bases, requirement registers and intranets. Foswiki keeps its content in plain files, so there is no database to run.

The cloudimg image adds:

  • No account and no content from the image build. The data volume ships empty. Your instance's first boot copies Foswiki's own release webs (Main, System, Sandbox, Trash and the TWiki compatibility web) onto it, unchanged, and creates one administrator, WikiAdmin, with a password generated on your instance. No topic, revision, session, attachment or log from the image build is on your instance.
  • Secrets of your instance's own. The WikiAdmin password, the credential for the configure console and the HTTPS key are generated on your instance's first boot. Passwords are stored as bcrypt hashes and never passed on a command line.
  • The configure console behind two locks. configure (Foswiki's settings console) and its API (/bin/jsonrpc) first ask for an HTTP credential unique to your instance, and then Foswiki only lets WikiAdmin in. The shared "internal admin" login is switched off. Foswiki's configuration file is written in full when the image is built, so Foswiki never falls back to its unauthenticated setup mode.
  • HTTPS from the first boot. nginx serves Foswiki on port 443 with a certificate generated on your instance's first boot. Port 80 redirects to HTTPS.
  • Closed by default. Self-registration is off, so WikiAdmin is the only account until you add one. Anyone who can reach the site can read the public webs (Main, System, Sandbox), and only signed-in users can edit.
  • A rate-limited login, in one place. Only the sign in page (/bin/login, also reachable as /bin/logon) accepts a user name and password. Upstream Foswiki also signs a session in from a password sent to any page that needs a signed-in user; this image switches that off. nginx limits every request to the sign in page, and to the pages that check a password themselves (password change), to 6 a minute from one address after a burst of 10, however the request is written. The other pages that need a signed-in user are limited to 30 a minute, and reading the wiki to 120 a minute, which normal browsing never reaches. Every limit uses the address of the connection, never a header a client sends, and a password in an X-Authorization header is not accepted.
  • Attachments are never executed and always checked. Only Foswiki's own skin and script files (/pub/System/) are served directly. Every other attachment goes through Foswiki, which applies the web's and topic's view rules first. Attachments are sent with nosniff and a sandboxing content security policy. Only passive types (images, PDF, fonts, audio and video) open in the browser; anything else, SVG and HTML included, is sent as a download. Foswiki also renames uploaded HTML, PHP, Perl (.pl and .pm), Python and CGI files to .txt.
  • No outbound connections. Foswiki's update reporter (which sends your installed extension list to foswiki.org from the administrator's browser) and its online extension installer are off, and including remote URLs in a topic is off. Foswiki, nginx and first boot are blocked from the instance metadata service. The AMI requires IMDSv2.
  • The host name comes from configuration. Foswiki builds links from the name you set (your instance's public DNS name by default), never from the name a request claims. nginx drops requests for host names the instance does not serve.
  • Hardened defaults. The Foswiki code and its configuration belong to root and are read only to Foswiki. Foswiki's FastCGI processes listen on the loopback address only, and nginx passes them only Foswiki's own scripts. Ubuntu 24.04 LTS was fully patched at build time, with unattended security upgrades switched on.

What is on the image: Foswiki 2.1.11 (the official release, checksum verified, with its bundled plugins, PatternSkin, NatEdit and the TinyMCE editor; the unused jQuery 3.7.1 and 4.0.0 copies are removed, and Foswiki keeps its supported default jQuery 2.2.4), Perl 5.38, nginx 1.24, Ubuntu 24.04 LTS, cloud-init and the AWS Systems Manager agent. The wiki data is on a separate 30 GiB EBS volume mounted at /var/lib/foswiki.

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), TCP 443 (Foswiki) and TCP 80 (redirects to HTTPS) from the networks that should reach them. Keep 22 to your own networks. Open 443 to your readers for a public wiki, or only to your team for an internal one.

Step 1: Launch the instance

In the AWS Marketplace listing choose Continue to Subscribe, then Continue to Configuration. Pick Foswiki 2.1.11 on Ubuntu 24.04 as the software version and choose your Region, then Launch through EC2. Choose m5.large, your key pair and a security group as above. Keep the second volume (the wiki data) in the launch settings; you can make it larger there.

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

Step 2: Connect to your instance

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

Step 3: Check the services

First boot takes a few seconds. After it, nginx, Foswiki and the first boot unit are active:

systemctl is-active nginx foswiki foswiki-firstboot
active
active
active

nginx serves ports 80 and 443, and Foswiki's FastCGI processes listen on the loopback address only. The only open ports are 22, 80 and 443:

sudo ss -tlnp | awk 'NR==1 || /nginx|sshd|foswiki/' | awk '{print $1, $4, $6}' | sed -E 's/,pid=[0-9]+,fd=[0-9]+//g'
State Local Peer
LISTEN 0.0.0.0:443 users:(("nginx"),("nginx"),("nginx"))
LISTEN 127.0.0.1:9000 users:(("foswiki-fcgi"),("foswiki-fcgi"),("foswiki-fcgi"),("foswiki-fcgi-pm"))
LISTEN 0.0.0.0:22 users:(("sshd"),("systemd"))
LISTEN 0.0.0.0:80 users:(("nginx"),("nginx"),("nginx"))
LISTEN [::]:443 users:(("nginx"),("nginx"),("nginx"))
LISTEN [::]:22 users:(("sshd"),("systemd"))
LISTEN [::]:80 users:(("nginx"),("nginx"),("nginx"))

The Foswiki release (with the checksum of the release download), the Perl and nginx versions and the data volume:

grep -m1 "version->declare" /opt/foswiki/lib/Foswiki.pm
head -2 /usr/share/doc/foswiki/RELEASE
perl -e 'print "perl $^V\n"'
nginx -v 2>&1
findmnt -no TARGET,FSTYPE,SIZE /var/lib/foswiki
    use version 0.77; $VERSION = version->declare('v2.1.11');
Foswiki 2.1.11 (FoswikiRelease02x01x11)
sha256 3a490eb460db4ca69d73dfe44c7984889552e5313eff60162760e80e66e5eba6
perl v5.38.2
nginx version: nginx/1.24.0 (Ubuntu)
/var/lib/foswiki ext4   29.4G

Step 4: Get your sign-in details

The credentials file holds the address Foswiki is served as (your instance's public DNS name by default), the sign in page, the WikiAdmin password and the configure console credential, all generated on this instance. Show it with:

sudo cat /root/foswiki-credentials.txt
FOSWIKI_URL=https://ec2-<public-ip-dashed>.<region>.compute.amazonaws.com/bin/view/Main/WebHome
FOSWIKI_LOGIN_URL=https://ec2-<public-ip-dashed>.<region>.compute.amazonaws.com/bin/login
FOSWIKI_ADMIN_USER=WikiAdmin
FOSWIKI_ADMIN_PASSWORD=<24 letters and digits>

FOSWIKI_CONFIGURE_URL=https://ec2-<public-ip-dashed>.<region>.compute.amazonaws.com/bin/configure
FOSWIKI_CONFIGURE_USER=configure
FOSWIKI_CONFIGURE_PASSWORD=<24 letters and digits>

Step 5: Sign in

Open FOSWIKI_LOGIN_URL in your browser. The certificate is self signed (generated on your instance), so accept the browser warning once, or install your own certificate (Step 10). Sign in as WikiAdmin with FOSWIKI_ADMIN_PASSWORD:

The Foswiki sign in page served over HTTPS

After you sign in, Foswiki shows the home page of the Main web, with your name in the top bar and the webs in the left bar:

The Foswiki Main web home page with WikiAdmin signed in

Step 6: Create and edit topics

Open the Sandbox web (a web for trying things out), choose Create New Topic, give it a name in WikiWord style (for example MeetingNotes) and write it in Foswiki's markup or with the editor's toolbar. Save keeps a new revision every time:

Editing a Sandbox topic in Foswiki's NatEdit editor

History on a topic lists every revision with its author and date and shows the differences between any two of them:

The revision history of a topic, comparing revision 2 with revision 1

The image ships a self-test that proves the whole path a browser takes: HTTPS, the sign in form, creating, rendering, revising and comparing a topic in Sandbox (it deletes its test topic again), and the locks described above. Run it at any time:

sudo /usr/local/sbin/foswiki-selftest.sh
SELFTEST_OK

Step 7: Users and access

Self-registration is off. To add an account, give it a WikiName (for example JaneSmith), an e-mail address and a password of at least 12 characters, passed on stdin so it never appears in your shell history or the process list:

read -rs PW && printf '%s\n' "$PW" | sudo foswiki-set-password --user JaneSmith --email jane@example.com --stdin; unset PW

The same command with an existing WikiName sets a new password for it. To let people register themselves (for example on a private network), turn registration on (see Step 9 for how settings are changed) and restart Foswiki:

sudo perl /opt/foswiki/tools/configure -set '{Register}{EnableNewUserRegistration}=1' -save
sudo systemctl restart foswiki

Access rules live in topics: a web's WebPreferences topic takes settings such as * Set ALLOWWEBVIEW = AdminGroup or * Set ALLOWWEBCHANGE = Main.JaneSmith, and a single topic takes ALLOWTOPICVIEW and ALLOWTOPICCHANGE in its own text. Attachments follow the same rules: a file attached to a topic in a restricted web is not readable by anyone the web excludes, even with its direct address. (Signed out, opening such a file downloads Foswiki's sign in page instead of the file; sign in first.) To make someone an administrator, add their WikiName to Main.AdminGroup while signed in as WikiAdmin.

Step 8: Security checks

Port 80 sends browsers to HTTPS, and the health endpoint answers for load balancer checks. The configure console and its API refuse a request without the configure credential. Foswiki's configuration, password file, scripts and tools cannot be reached, and a request for an unknown host name gets no answer:

H=$(sed -n 's/^set \$fw_host "\(.*\)";$/\1/p' /etc/nginx/foswiki-host.conf)
curl -s -o /dev/null -w 'port 80: %{http_code} -> %{redirect_url}\n' --resolve "$H:80:127.0.0.1" "http://$H/bin/view/Main/WebHome"
curl -sk --resolve "$H:443:127.0.0.1" "https://$H/healthz"
for p in /bin/configure /bin/jsonrpc; do
  curl -sk -o /dev/null -w "$p without the configure credential: %{http_code}\n" --resolve "$H:443:127.0.0.1" "https://$H$p"
done
for p in /lib/LocalSite.cfg /data/.htpasswd /bin/foswiki.fcgi /tools/configure /working/; do
  curl -sk -o /dev/null -w "$p: %{http_code}\n" --resolve "$H:443:127.0.0.1" "https://$H$p"
done
curl -s -o /dev/null -w 'unknown host name: %{http_code}\n' -H 'Host: example.com' http://127.0.0.1/ || true
port 80: 301 -> https://ec2-<public-ip-dashed>.<region>.compute.amazonaws.com/bin/view/Main/WebHome
ok
/bin/configure without the configure credential: 401
/bin/jsonrpc without the configure credential: 401
/lib/LocalSite.cfg: 404
/data/.htpasswd: 404
/bin/foswiki.fcgi: 404
/tools/configure: 404
/working/: 404
unknown host name: 000

(000 means nginx closed the connection without an answer.) The credentials file is readable by root only, and the configuration and the configure credential by root and the web server's group. The wiki data belongs to the web server, and the code belongs to root:

sudo stat -c '%a %U:%G %n' /root/foswiki-credentials.txt /opt/foswiki/lib/LocalSite.cfg /etc/nginx/foswiki-configure.htpasswd /var/lib/foswiki/data/.htpasswd /var/lib/foswiki/data /var/lib/foswiki/pub /var/lib/foswiki/working /opt/foswiki/bin/view
600 root:root /root/foswiki-credentials.txt
640 root:www-data /opt/foswiki/lib/LocalSite.cfg
640 root:www-data /etc/nginx/foswiki-configure.htpasswd
640 www-data:www-data /var/lib/foswiki/data/.htpasswd
750 www-data:www-data /var/lib/foswiki/data
750 www-data:www-data /var/lib/foswiki/pub
750 www-data:www-data /var/lib/foswiki/working
755 root:root /opt/foswiki/bin/view

Foswiki, nginx and first boot are blocked from the instance metadata service:

systemctl show -p IPAddressDeny foswiki nginx foswiki-firstboot
IPAddressDeny=fd00:ec2::254/128 168.63.129.16/32 169.254.169.254/32

IPAddressDeny=fd00:ec2::254/128 168.63.129.16/32 169.254.169.254/32

IPAddressDeny=fd00:ec2::254/128 168.63.129.16/32 169.254.169.254/32

Step 9: The configure console and settings

Open FOSWIKI_CONFIGURE_URL. Your browser first asks for the HTTP credential: enter FOSWIKI_CONFIGURE_USER and FOSWIKI_CONFIGURE_PASSWORD from Step 4. Then sign in as WikiAdmin if you have not already. Use the console to review every setting and to run its checks.

The Foswiki code and its configuration file /opt/foswiki/lib/LocalSite.cfg belong to root and are read only to the web server by design, so the web console cannot save changes. Change a setting as root with Foswiki's own command line configure, then restart Foswiki. For example, to send e-mail (notifications, password resets) through your SMTP relay:

sudo perl /opt/foswiki/tools/configure -set '{EnableEmail}=1' -set '{SMTP}{MAILHOST}=smtp.example.com' \
  -set '{WebMasterEmail}=wiki@example.com' -save
sudo systemctl restart foswiki

The console's Mail section lists the other mail settings (authentication, TLS); set them the same way. Foswiki's online extension installer is off in this image, so the wiki never fetches code from the internet. To add an extension, download it from foswiki.org yourself, check it, and install it as root following its documentation.

Step 10: Your own DNS name and certificate

Point a DNS record at the instance, then set the name Foswiki is served as. This mints a new self signed certificate for the name and updates nginx, Foswiki's {DefaultUrlHost} (used in every link and redirect) and the addresses in /root/foswiki-credentials.txt. It then restarts Foswiki and keeps the name across reboots:

sudo foswiki-set-hostname <your-domain>

To use a certificate from your own certificate authority instead, copy it over the generated pair and reload nginx (running foswiki-set-hostname again replaces it with a self signed one):

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

Once browsers trust the certificate you can also add an HSTS header (add_header Strict-Transport-Security "max-age=31536000" always;) to /etc/nginx/snippets/cloudimg-foswiki-headers.conf. The image does not send one: browsers ignore HSTS from a site whose certificate they do not trust.

Step 11: Passwords

foswiki-set-password gives WikiAdmin a new random password with Foswiki's own password manager and records it in /root/foswiki-credentials.txt. Run it without arguments, or pass your own password (12 to 128 characters, no spaces or colons) on stdin:

sudo foswiki-set-password
read -rs PW && printf '%s\n' "$PW" | sudo foswiki-set-password --stdin; unset PW

To change the configure console credential, write a new bcrypt entry (htpasswd prompts for the password):

sudo htpasswd -B /etc/nginx/foswiki-configure.htpasswd configure

Step 12: Your data, backups and upgrades

Everything Foswiki writes is on the data volume:

Folder Contents
/var/lib/foswiki/data Topics, their revision histories (<Topic>,pfv) and the password file .htpasswd
/var/lib/foswiki/pub Attachments, and the System web's skin and script files
/var/lib/foswiki/working Sessions and temporary files
/var/lib/foswiki/logs Foswiki's event and error logs

Back up by taking EBS snapshots of the data volume, together with /opt/foswiki/lib/LocalSite.cfg (your settings). An untouched copy of the release webs is kept at /opt/foswiki-dist.

Upgrades. Foswiki publishes releases at https://github.com/foswiki/distro/releases and security alerts at https://foswiki.org/Support/SecurityAlerts. Snapshot the instance and read the release's upgrade notes. Then replace the code under /opt/foswiki as root, keeping lib/LocalSite.cfg, and restart Foswiki. The content on the data volume is kept.

Step 13: Server components

Component Path
Foswiki code (root owned) /opt/foswiki
Configuration /opt/foswiki/lib/LocalSite.cfg
Untouched release webs (copied onto the data volume at first boot) /opt/foswiki-dist
Wiki data /var/lib/foswiki (its own EBS volume)
FastCGI service foswiki.service (127.0.0.1:9000)
nginx site and request limits /etc/nginx/sites-available/cloudimg-foswiki, /etc/nginx/conf.d/cloudimg-foswiki-guard.conf
configure console credential /etc/nginx/foswiki-configure.htpasswd
Certificate and key /etc/nginx/ssl/
First boot script /usr/local/sbin/foswiki-firstboot.sh
Helpers /usr/local/sbin/foswiki-set-hostname, foswiki-set-password, foswiki-selftest.sh
Licence, release manifest and third-party notice /usr/share/doc/foswiki/
Credentials /root/foswiki-credentials.txt (mode 0600)

Step 14: Security recommendations

  • Allow port 22 in the security group from your own networks only.
  • Keep the WikiAdmin password and the configure credential secret, and rotate them if they may have been shared (Step 11). Give each person their own account (Step 7).
  • Think before turning self-registration on for a wiki on the internet (Step 7).
  • Use your own DNS name and a certificate your browsers trust (Step 10).
  • Keep Foswiki on its newest release (Step 12), and install only extensions you trust: an extension is Perl code that runs with Foswiki's rights.
  • Keep the operating system patched. Unattended security upgrades are on, and sudo apt-get update && sudo apt-get upgrade applies everything else. Some of the Perl modules Foswiki needs (CGI::Session, Crypt::Eksblowfish, Crypt::PasswdMD5, Email::MIME, FCGI::ProcManager and File::Copy::Recursive) come from Ubuntu's universe repository. sudo pro security-status --esm-apps shows whether Ubuntu Pro (ESM Apps) has security updates for them; none were pending when the image was built.
  • Snapshot the data volume regularly (Step 12).

Support and licensing

Foswiki is free software under the GNU General Public License version 2 or later (the licence is at /opt/foswiki/LICENSE). The bundled components carry their own free licences, listed in /usr/share/doc/foswiki/NOTICE-cloudimg.txt: TinyMCE (LGPL 2.1), jQuery and its plugins (MIT), the FamFamFam icons (CC BY 2.5) and Font Awesome (SIL OFL and MIT). There is no per user or per CPU licence fee. This image installs the unmodified upstream release (without the unused jQuery 3.7.1 and 4.0.0 copies) plus the cloudimg configuration described above. The AMI price covers cloudimg's hardening, first boot setup and support.

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