Storage AWS

Cloud Commander 19.21.4 on AWS User Guide

| Product: Cloud Commander 19.21.4 on Ubuntu 24.04 on AWS

Overview

This guide covers launching and using the Cloud Commander 19.21.4 on Ubuntu 24.04 AMI from cloudimg on Amazon EC2. It is one version of the cloudimg file sharing and sync listing on AWS Marketplace; you pick it as the software version when you subscribe and launch.

Cloud Commander is an open source, web based file manager with the classic two panel layout. From any browser you can browse, create, rename, copy, move, delete, pack and extract, upload and download files, and edit text files in the built in editor, without giving anyone SSH or a remote desktop.

The cloudimg image locks Cloud Commander down:

  • HTTPS from the first boot. nginx serves Cloud Commander on port 443 with a certificate generated on your instance's first boot. Port 80 redirects to HTTPS, and requests for a host name the instance does not serve are dropped.
  • A sign in unique to your instance, and no default login. Upstream Cloud Commander ships with authentication off and a published default login. On first boot the image generates a random password for the user admin and writes it to /var/lib/cloudimg/cloudcmd-credentials.txt (root only). Only one way hashes of it are stored in the configuration.
  • Two checks of that sign in. nginx asks for the user name and password on every path before a request reaches Cloud Commander, and Cloud Commander checks the same credential again. Cloud Commander serves its editor components ahead of its own sign in check; the nginx check in front closes that path, so nothing reaches Cloud Commander without the password.
  • The console and terminal are off. Cloud Commander's remote shell features, its settings dialog (which could switch authentication off from the browser), configuration import and export, and Dropbox are switched off, and a check before every start refuses a configuration that turns them back on.
  • Path traversal refused. Encoded slashes, dots and backslashes and .. segments in a path are refused by nginx before they reach Cloud Commander, and Cloud Commander 19.21.4 itself carries the upstream fixes for its archive download route.
  • Nothing else on the network. Cloud Commander listens on 127.0.0.1:8000 only. The security group needs only 22, 80 and 443.
  • No service can reach the metadata service. Cloud Commander and nginx are blocked from the EC2 instance metadata service at the kernel level, and the AMI requires IMDSv2.
  • Cross site protection. Another web site cannot make your signed in browser upload, delete or download an archive of your files, and it cannot open the live connection the file manager uses.
  • Pinned, verified components. Cloud Commander 19.21.4 is installed from a locked dependency tree in which every package is checked against its recorded hash, on the official Node.js 22.23.4 LTS runtime.
  • Fully patched Ubuntu 24.04 LTS at build time, with unattended security upgrades switched on.

What is on the image: Cloud Commander 19.21.4 (/opt/cloudcmd), Node.js 22.23.4 (/opt/nodejs), nginx, Ubuntu 24.04 LTS, cloud-init and the AWS Systems Manager agent. Your files live in /srv/cloudcmd.

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 (Cloud Commander) and TCP 80 (redirects to HTTPS) from your own networks only.

Step 1: Launch the instance

In the AWS Marketplace listing choose Continue to Subscribe, then Continue to Configuration, pick Cloud Commander 19.21.4 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. Your files are stored on the root volume; raise its size under Configure storage if you expect to keep a lot of data (or add a volume later, Step 9).

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

Step 2: Connect to your instance

Version SSH user
Cloud Commander 19.21.4 on Ubuntu 24.04 ubuntu
ssh -i <your-key.pem> ubuntu@<public-ip>

Step 3: Check the services

First boot generates the certificate and the password, then Cloud Commander and nginx start. It takes a few seconds:

systemctl is-active cloudcmd-firstboot cloudcmd-set-host cloudcmd nginx
active
active
active
active

Only SSH (22) and nginx (80, 443) listen on the network. Cloud Commander listens on loopback port 8000, and the other two are Ubuntu's local DNS resolver:

sudo ss -lntp | awk 'NR>1 {print $4}' | sort -u
0.0.0.0:22
0.0.0.0:443
0.0.0.0:80
127.0.0.1:8000
127.0.0.53%lo:53
127.0.0.54:53
[::]:22
[::]:443
[::]:80

If nginx or Cloud Commander is not active, first boot has not finished (or failed, in which case neither starts). Check systemctl status cloudcmd-firstboot and journalctl -u cloudcmd-firstboot.

Step 4: Get your URL and password

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

The file is readable by root only:

# Cloud Commander 19.21.4 on Ubuntu 24.04 - per-instance sign-in (written by cloudcmd-apply-credential, firstboot)
# This credential is unique to this instance; none was baked into the image. Keep this file secret.
CLOUDCMD_URL=https://ec2-<public-ip-dashed>.compute-1.amazonaws.com/
CLOUDCMD_USER=admin
CLOUDCMD_PASS=<CLOUDCMD_PASS>

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. To use your own DNS name, see Step 8.

The built in self test proves the whole chain from the command line: both sign in checks, an upload, download and delete round trip, and the refusals described in this guide:

sudo cloudcmd-selftest
SELFTEST-OK https 301 + /healthz + 401 without or with a wrong password + 401 on an unauthenticated editor-route write + 400 editor-route dot segments + file manager page + upload/download/delete round trip + 403 cross-origin upload + 400 encoded traversal + 404 /deepword/ + 403 cross-origin WebSocket + 444 unknown host

Step 5: Sign in

Open the CLOUDCMD_URL in your browser. The certificate is self signed, so your browser asks you to confirm it the first time. Before you accept it, compare the fingerprint your browser shows with the one on the instance (or install your own certificate, Step 8):

sudo openssl x509 -in /etc/ssl/cloudcmd/cloudcmd.crt -noout -fingerprint -sha256

Your browser then asks for a user name and password: enter admin and the CLOUDCMD_PASS from Step 4. Cloud Commander opens with two panels, both showing the root of your file area, /srv/cloudcmd on the instance.

Cloud Commander's two panel file manager on cloudimg, with folders and files in the left panel and the projects folder open in the right

Step 6: Work with files

The function keys along the bottom (and the same keys on your keyboard) do the common jobs: F3 view, F4 edit, F5 copy and F6 move to the other panel, F7 new folder, F8 delete, F9 the menu. Drag files from your computer onto a panel to upload them; select a file and choose Download in the menu to fetch it.

Copying a file from the left panel into the projects folder open in the right panel

F4 opens a text file in the built in editor. Save with Ctrl+S.

A markdown file open in Cloud Commander's built in editor

The menu (F9, or a right click) also offers rename, pack and extract archives, and sign out.

The Cloud Commander menu with view, edit, rename, delete, pack, extract, download, copy, paste, upload and log out

Cloud Commander also has a REST API, which is handy for scripts. From the instance itself, with curl (the password goes into a private curl config file, never onto the command line):

F=/var/lib/cloudimg/cloudcmd-credentials.txt
H=$(sudo sed -n 's#^CLOUDCMD_URL=https://\([^/]*\)/.*#\1#p' $F)
( umask 077; printf 'user = "admin:%s"\n' "$(sudo sed -n 's/^CLOUDCMD_PASS=//p' $F)" > ~/.cloudcmd-curl )
printf 'Hello from cloudimg.\n' > /tmp/hello.txt
curl -s -K ~/.cloudcmd-curl --resolve "$H:443:127.0.0.1" --cacert /etc/ssl/cloudcmd/cloudcmd.crt -H "Origin: https://$H" -o /dev/null -w 'PUT hello.txt -> HTTP %{http_code}\n' -X PUT --data-binary @/tmp/hello.txt "https://$H/api/v1/fs/hello.txt"
curl -s -K ~/.cloudcmd-curl --resolve "$H:443:127.0.0.1" --cacert /etc/ssl/cloudcmd/cloudcmd.crt "https://$H/api/v1/fs/hello.txt"
curl -s -K ~/.cloudcmd-curl --resolve "$H:443:127.0.0.1" --cacert /etc/ssl/cloudcmd/cloudcmd.crt -H "Origin: https://$H" -o /dev/null -w 'DELETE hello.txt -> HTTP %{http_code}\n' -X DELETE "https://$H/api/v1/fs/hello.txt"
rm -f ~/.cloudcmd-curl /tmp/hello.txt
PUT hello.txt -> HTTP 200
Hello from cloudimg.
DELETE hello.txt -> HTTP 200

A request that changes files is refused with 403 when it carries another web site's Origin (a page elsewhere trying to use your signed in browser). Scripts that send no Origin header, or your instance's own address as in the example, are accepted.

Step 7: Change the password

To replace the password with a new random one (written to the credentials file; the old one stops working at once):

sudo cloudcmd-set-password

To choose your own (16 to 128 printable characters, no spaces, :, " or \), pass it on standard input so it never appears in your shell history or the process list:

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

Your browser may keep offering the old password until you close it or choose Log Out in the menu.

Step 8: Use your own host name and certificate

Point a DNS record at the instance (an Elastic IP keeps the address across stop and start), then tell Cloud Commander its name. This mints a new self signed certificate for that name, updates the nginx host rule and the cross site guards, and keeps the name across reboots:

sudo cloudcmd-set-hostname files.example.com

To use a certificate from a public authority instead, replace /etc/ssl/cloudcmd/cloudcmd.crt (full chain) and /etc/ssl/cloudcmd/cloudcmd.key (mode 0600, owned by root) with your own and run sudo systemctl reload nginx. Running cloudcmd-set-hostname again later would replace them with a new self signed pair.

Without your own name, each boot checks the instance's names: after a stop and start that changed the public address, the next boot issues a new certificate and updates the URL in the credentials file for the new name. Nothing changes on a boot where the names are the same.

Step 9: Where your files live, and backups

Cloud Commander shows /srv/cloudcmd, owned by the cloudcmd service user, and nothing outside it. To keep files on their own EBS volume, attach and format the volume, stop the service, copy the folder over and mount the volume at /srv/cloudcmd (add it to /etc/fstab with nofail), then make sure the mount point is owned by cloudcmd:cloudcmd with mode 0750 and start the service again.

The simplest complete backup is an EBS snapshot (or AWS Backup on the instance). For a file level copy:

sudo tar -czf /root/cloudcmd-files-backup.tar.gz -C /srv cloudcmd

To change which folder Cloud Commander shows, edit "root" in /etc/cloudcmd/.cloudcmd.json (as root) and run sudo systemctl restart cloudcmd. The service can only write inside /srv/cloudcmd, so another root is read only unless you also allow it in the service's ReadWritePaths (sudo systemctl edit cloudcmd).

Step 10: Check persistence and updates

Every service is enabled, so Cloud Commander returns after a reboot or a stop and start, and unattended security upgrades keep the operating system and nginx patched:

systemctl is-enabled cloudcmd cloudcmd-set-host nginx unattended-upgrades
enabled
enabled
enabled
enabled

Security notes

  • No shared secret ships in the image. No password, password hash or TLS key exists until your instance's first boot generates them, and neither nginx nor Cloud Commander starts before that has finished.
  • Two sign in checks. Upstream Cloud Commander 19.21.4 serves its editor components (/edward/, /dword/, /qword/, /deepword/, /fileop/) before its own sign in check, which on a bare installation lets anyone read and write files without the password. On this image nginx requires the password on every path first, so those routes are only reachable after signing in.
  • The remote shells stay off. The console and terminal are disabled in the service's environment as well as its configuration, and the terminal component is not installed at all. The settings dialog is off too, so authentication cannot be changed from the browser.
  • The Monaco editor option is not served. Its bundle carries an older DOMPurify release; the image uses the default editor and answers 404 for /deepword/. Dependencies with known advisories that remain in the tree (a nested file-type and got used only by the editors' own static files and the disabled Dropbox feature) are not reachable as shipped.
  • Cross site requests are refused. Uploads, deletes, archive downloads, sign out and the live connection are refused when they come from another web site. Because of this, and the traversal refusal, a file whose name contains a backslash cannot be opened through the web interface.
  • No access to the metadata service. Cloud Commander and nginx run with a kernel level block on the EC2 instance metadata address.
  • Offline caching needs a trusted certificate. Browsers refuse to install Cloud Commander's offline helper with a self signed certificate; the file manager works normally without it.
  • Restrict 22/tcp to your management network, and 80/443 to the networks that use Cloud Commander.

Architecture summary

Component Detail
Application Cloud Commander 19.21.4 (MIT) on Node.js 22.23.4, /opt/cloudcmd, cloudcmd.service as user cloudcmd, 127.0.0.1:8000
Web server nginx on 443 (HTTPS, per instance certificate in /etc/ssl/cloudcmd), 80 redirects to HTTPS, /healthz for load balancer checks
Files /srv/cloudcmd (the only path the service can write)
Configuration /etc/cloudcmd/.cloudcmd.json (root owned, read only to the service), checked before every start
Credentials /var/lib/cloudimg/cloudcmd-credentials.txt, mode 0600, root only
Helpers cloudcmd-selftest, cloudcmd-set-password, cloudcmd-set-hostname (in /usr/local/sbin)
First boot cloudcmd-firstboot.service; host name and certificate check on every later boot cloudcmd-set-host.service
Ports 22 SSH, 80 redirect, 443 Cloud Commander
Base image Ubuntu 24.04 LTS, fully patched, unattended security upgrades enabled, IMDSv2 required

Support

cloudimg images come with 24/7 support. Email support@cloudimg.co.uk with your AWS account ID and the instance ID. For Cloud Commander itself, see the Cloud Commander project on GitHub and its documentation.