Deployment guide

MicroBin 2.1.0

Overview

MicroBin is a small, self-hosted pastebin and file-sharing web application. Your team pastes text such as code, configuration, notes and logs (with syntax highlighting), uploads files, shortens URLs and makes QR codes, then shares the link. Pastes can expire after a set time or after a number of reads, can be unlisted, and can be encrypted on the server with a password or in the browser before they are sent. Everything stays on your own instance in your own VPC.

Upstream MicroBin listens on plain HTTP, lets anyone create pastes and upload files, lists every public paste, and ships with the admin login admin / m1cr0b1n. This SecureAnyCloud image, MicroBin 2.1.0 on Ubuntu 24.04, changes all of that. It is one version of the SecureAnyCloud documents, forms and scheduling listing on AWS Marketplace, and you choose it as the software version when you subscribe and launch.

What you get:

  • HTTPS from the first boot. nginx serves MicroBin on port 443 with a certificate generated on your instance's first boot. Port 80 redirects to HTTPS. MicroBin itself listens on 127.0.0.1:8080 only.
  • Two passwords unique to your instance. The uploader password is needed to create a paste or upload a file, so the instance is not an open file host for the internet. The admin password opens the /admin panel and is needed to delete a paste. Both are generated on first boot and written to /root/microbin-credentials.txt (root only). The upstream default admin login is refused. Anyone you give a paste's link can read it, which is what a pastebin is for.
  • No public paste list. Unlisted, server-encrypted ("private") and browser-encrypted ("secret") pastes, burn after reading, and a 24 hour default expiry are supported.
  • Fail closed. MicroBin and nginx refuse to start until first boot has generated the certificate and both passwords, so the app is never served with a default or empty login.
  • Hardened. Requests for host names the instance does not serve are dropped. The client address nginx passes on is always the real one (a forged X-Forwarded-For is overwritten). Cross-site form posts are refused, and admin logins and deletes are rate limited. MicroBin runs as its own user in a systemd sandbox. MicroBin and nginx are blocked from the instance metadata service, the AMI requires IMDSv2, and telemetry and update checks are off.
  • Your data on its own disk. Pastes, uploaded files and MicroBin's database live on a separate 32 GiB EBS volume mounted at /var/lib/microbin, which you can resize or snapshot on its own.
  • The official release, verified. The MicroBin 2.1.0 release binary is checked against a pinned SHA-256 checksum before it is installed. The image is fully patched Ubuntu 24.04 LTS with unattended security upgrades on.
  • Image contents: MicroBin 2.1.0 (the official static release binary in /usr/local/bin/microbin, license in /usr/share/doc/microbin), nginx, Ubuntu 24.04 LTS, cloud-init and the AWS Systems Manager agent.
  • Defaults: 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 (MicroBin) and TCP 80 (redirects to HTTPS). Open 22 from your own networks only. Open 443 and 80 to the people you share pastes with.
1

Launch the instance

In the AWS Marketplace listing, choose Continue to Subscribe, then Continue to Configuration. Pick MicroBin 2.1.0 on Ubuntu 24.04 as the software version, choose your Region, then choose Launch through EC2. Select m5.large, your key pair and a security group as described above.

The AMI brings two volumes: the 8 GiB root volume and the 32 GiB data volume for /var/lib/microbin. Increase the data volume at launch if you expect large uploads.

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

Connect to your instance

Version SSH user

MicroBin 2.1.0 on Ubuntu 24.04 ubuntu

ssh -i <your-key.pem> ubuntu@<public-ip>
3

Check the services

First boot generates the certificate and the passwords, then starts MicroBin and nginx. Check the first boot service:

systemctl is-active microbin nginx microbin-firstboot
sudo test -f /var/lib/sac/data/microbin-firstboot.done && echo FIRSTBOOT_DONE

Confirm that all three units are active and the first boot marker is present:

active active active FIRSTBOOT_DONE

Confirm that only SSH and nginx listen on the network. MicroBin listens on loopback only, behind nginx:

sudo ss -lntp | awk 'NR>1 {print $4, $6}' | 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:8080 users:(("microbin",...)) 127.0.0.53%lo:53 users:(("systemd-resolve",...)) 127.0.0.54:53 users:(("systemd-resolve",...)) [::]:22 users:(("sshd",...),("systemd",...)) [::]:443 users:(("nginx",...),("nginx",...),("nginx",...)) [::]:80 users:(("nginx",...),("nginx",...),("nginx",...))
4

Get your URL and passwords

sudo cat /root/microbin-credentials.txt

Only root can read this file. It holds the URL, the admin login and the uploader password of this instance:

# MicroBin 2.1.0 - generated on first boot by microbin-firstboot.service
# These credentials are unique to this instance; none was baked into the image. Keep this file secret. MICROBIN_URL=https://ec2-<public-ip-dashed>.<region>.compute.amazonaws.com/ MICROBIN_ADMIN_URL=https://ec2-<public-ip-dashed>.<region>.compute.amazonaws.com/admin MICROBIN_ADMIN_USERNAME=admin MICROBIN_ADMIN_PASSWORD=<MICROBIN_ADMIN_PASSWORD> MICROBIN_UPLOADER_PASSWORD=<MICROBIN_UPLOADER_PASSWORD>
#
# Open MICROBIN_URL in a browser (self-signed certificate minted on this instance's first boot; port 80 # redirects to https). Creating a paste or uploading a file needs MICROBIN_UPLOADER_PASSWORD. Anyone you # give a paste's link can read it. The admin panel (MICROBIN_ADMIN_URL) and deleting a paste need the
# admin username and password.
# New admin password:
sudo microbin-set-password --admin
# New uploader password:
sudo microbin-set-password --uploader
# Change the name it serves as:
sudo microbin-set-hostname <your-dns-name>
# User guide: https://secureanycloud.com/stacks/microbin-2-1-0/

The URL uses the instance's public DNS name from EC2 instance metadata. The links and QR codes MicroBin shows are built from that configured name, never from the request. The certificate also names the public and private IP addresses, so https://<public-ip>/ works too. To serve MicroBin under your own DNS name, see Step 9.

Give the uploader password to the people who should be able to create pastes. Keep the admin password for whoever looks after the instance.

5

Create a paste

Open the MICROBIN_URL in your browser. The certificate is self-signed, so your browser asks you to confirm it the first time. You can also install your own certificate (Step 9).

Type or paste your text into Content. Choose how long the paste should live (Expiration), whether it should disappear after a number of reads (Burn After), the Syntax for highlighting and the Privacy level. Enter the uploader password next to Save, then select Save.

MicroBin opens the new paste at a link made of three animal names, such as /upload/monkey-bee-fish. Copy URL copies the link to share, Raw Text Content gives the plain text (handy for curl), and QR shows a QR code of the link.

To share a file, select Select or drop file attachment, or drop the file on the page, before you save. Files up to 256 MB are accepted, and recipients download them with Download.

6

Private and secret pastes

The Privacy list offers four levels:

Privacy What it does

Public Anyone with the link can read it. There is no public list of pastes on this image.

Unlisted Behaves the same as Public here, because no list is shown.

Private Encrypted on the server with the password you type in Password. Readers need the link and the password.

Secret Encrypted in your browser before it is sent, so the server stores only ciphertext. Readers need the link and the password.

Someone who opens a private paste is asked for its password first. With the right password, the paste opens.

7

The admin panel

Open the MICROBIN_ADMIN_URL and sign in as admin with the admin password. The panel lists every paste with its expiry, size and type, and lets you remove any of them.

The panel shows "Version 2.0.4". This is a display string that upstream did not update in the 2.1.0 release. The binary is 2.1.0 (microbin --version, Step 11).

Deleting a paste with the Remove link, on a paste or in the panel, asks for the admin username and password in a browser login box. Upstream MicroBin lets anyone holding a public link delete the paste. On this image, only the admin can.

8

Check the security posture from the command line

Run these checks from the instance. Port 80 redirects to HTTPS. There is no paste list, and the list URL redirects to the home page. An upload without the uploader password is refused. A request for a host name the instance does not serve is dropped without an answer.

H=$(sudo grep '^MICROBIN_URL=' /root/microbin-credentials.txt | sed -E 's#^MICROBIN_URL=https://([^/]+)/.*#\1#')
curl -s -o /dev/null -w 'http:// -> %{http_code} %{redirect_url}\n' --resolve "$H:80:127.0.0.1" "http://$H/"
curl -sk -o /dev/null -w 'home page -> HTTP %{http_code}\n' --resolve "$H:443:127.0.0.1" "https://$H/"
curl -sk -o /dev/null -w 'paste list -> %{http_code} %{redirect_url}\n' --resolve "$H:443:127.0.0.1" "https://$H/list"
curl -sk -o /dev/null -w 'upload without password -> %{http_code} %{redirect_url}\n' --resolve "$H:443:127.0.0.1" -H "Origin: https://$H" -F content=test "https://$H/upload"
curl -sk -o /dev/null -w 'unknown host -> %{http_code}\n' --resolve "evil.example:443:127.0.0.1" "https://evil.example/" || true
http:// -> 301 https://ec2-<public-ip-dashed>.<region>.compute.amazonaws.com/ home page -> HTTP 200 paste list -> 302 https://ec2-<public-ip-dashed>.<region>.compute.amazonaws.com/ upload without password -> 302 https://ec2-<public-ip-dashed>.<region>.compute.amazonaws.com/incorrect unknown host -> 000

000 means nginx closed the connection without answering, which is how it treats any host name it does not serve.

With the uploader password, a paste is created and can be read back as plain text. Deleting it needs the admin login. The passwords are passed to curl on standard input, so they never appear in the process list or your shell history:

sudo bash -c ' F=/root/microbin-credentials.txt U=$(grep "^MICROBIN_UPLOADER_PASSWORD=" $F | cut -d= -f2-) A=$(grep "^MICROBIN_ADMIN_PASSWORD=" $F | cut -d= -f2-) H=$(grep "^MICROBIN_URL=" $F | sed -E "s#^MICROBIN_URL=https://([^/]+)/.*#\1#") R="--resolve $H:443:127.0.0.1" L=$(printf "form = \"content=Hello from MicroBin on AWS\"\nform = \"expiration=1hour\"\nform = \"uploader_password=%s\"\n" "$U" \
  | curl -K - -sk $R -H "Origin: https://$H" -o /dev/null -w "%{redirect_url}" "https://$H/upload") echo "new paste -> $L" ID=${L##*/upload/} curl -sk $R "https://$H/raw/$ID"; echo curl -sk $R -o /dev/null -w "delete without admin login -> HTTP %{http_code}\n" "https://$H/remove/$ID" printf "user = \"admin:%s\"\n" "$A" | curl -K - -sk $R -o /dev/null -w "delete with admin login -> HTTP %{http_code}\n" "https://$H/remove/$ID" curl -sk $R -o /dev/null -w "paste after delete -> HTTP %{http_code}\n" "https://$H/raw/$ID" '
new paste -> https://ec2-<public-ip-dashed>.<region>.compute.amazonaws.com/upload/<three-animal-names> Hello from MicroBin on AWS delete without admin login -> HTTP 401 delete with admin login -> HTTP 302 paste after delete -> HTTP 404

The passwords live in two root-only files: the credentials note and /etc/microbin/secrets.env, which systemd hands to MicroBin as its environment. nginx keeps only a SHA-512 crypt hash of the admin password for deletes:

sudo stat -c '%a %U:%G %n' /root/microbin-credentials.txt /etc/microbin/secrets.env /etc/nginx/.microbin-htpasswd /etc/microbin/microbin.env
sudo sed -E 's/=.*/=<value>/' /etc/microbin/secrets.env
600 root:root /root/microbin-credentials.txt 600 root:root /etc/microbin/secrets.env 640 root:www-data /etc/nginx/.microbin-htpasswd 644 root:root /etc/microbin/microbin.env MICROBIN_ADMIN_USERNAME=<value> MICROBIN_ADMIN_PASSWORD=<value> MICROBIN_UPLOADER_PASSWORD=<value>

The certificate was generated on this instance and names its own addresses. Inspect it:

H=$(sudo grep '^MICROBIN_URL=' /root/microbin-credentials.txt | sed -E 's#^MICROBIN_URL=https://([^/]+)/.*#\1#')
echo | openssl s_client -connect 127.0.0.1:443 -servername "$H" 2>/dev/null | openssl x509 -noout -subject -ext subjectAltName
subject=CN = ec2-<public-ip-dashed>.<region>.compute.amazonaws.com, O = sac X509v3 Subject Alternative Name: DNS:ec2-<public-ip-dashed>.<region>.compute.amazonaws.com, IP Address:<public-ip>, IP Address:<private-ip>, IP Address:127.0.0.1, DNS:localhost

MicroBin and nginx cannot reach the instance metadata service. MicroBin runs as its own user with the passwords from a root-only file, and it will not start until first boot has finished and both passwords are in place:

systemctl show microbin nginx -p Id -p IPAddressDeny
systemctl cat microbin | grep -E '^(ExecStartPre|ExecStart|EnvironmentFile|User)='
IPAddressDeny=169.254.169.254/32 168.63.129.16/32 fd00:ec2::254/128 Id=microbin.service IPAddressDeny=169.254.169.254/32 168.63.129.16/32 fd00:ec2::254/128 Id=nginx.service User=microbin EnvironmentFile=/etc/microbin/microbin.env EnvironmentFile=/etc/microbin/host.env EnvironmentFile=/etc/microbin/secrets.env ExecStartPre=/usr/bin/test -f /var/lib/sac/data/microbin-firstboot.done ExecStartPre=+/usr/local/sbin/microbin-auth-guard ExecStart=/usr/local/bin/microbin --json-db --no-listing --readonly --private --encryption-client-side --encryption-server-side --enable-burn-after --highlightsyntax --qr --disable-telemetry --disable-update-checking

The flags on the ExecStart line are the MicroBin features this image turns on. --readonly together with the uploader password makes uploads password-protected. To change a feature, run sudo systemctl edit --full microbin, then sudo systemctl restart microbin.

9

Your own DNS name and certificate

Point a DNS record at the instance, then set the name that MicroBin is served as. This command creates a new self-signed certificate for the name and updates nginx, MicroBin's links and the URL in the credentials file. It also restarts MicroBin and keeps the name across reboots:

sudo microbin-set-hostname <your-domain>

To use a certificate from your own certificate authority instead, copy it over the generated pair and reload nginx. Running microbin-set-hostname again replaces it with a self-signed certificate.

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

Change the passwords

Run microbin-set-password to generate a new random admin password (--admin, the default) or uploader password (--uploader). The command writes it to /etc/microbin/secrets.env and /root/microbin-credentials.txt, updates nginx's hash of the admin password and restarts MicroBin:

sudo microbin-set-password --uploader

To choose a password yourself, pass it on standard input. printf is a shell builtin, so the password never appears in the process list. Start the line with a space so most shells keep it out of your history. Passwords are 12 to 128 characters from A-Z a-z 0-9 . _ ~ @ % + = , -:

printf '%s\n' '<new-password>' | sudo microbin-set-password --admin --stdin
11

Data, backups and server components

Pastes, uploaded files and MicroBin's JSON database live on the data volume:

df -h /var/lib/microbin | sed 1d grep /var/lib/microbin /etc/fstab | sed -E 's/UUID=[0-9a-f-]+/UUID=<uuid>/' microbin --version nginx -v 2>&1
/dev/nvme1n1 32G 40K 30G 1% /var/lib/microbin UUID=<uuid> /var/lib/microbin ext4 defaults,nofail 0 2 microbin 2.1.0 nginx version: nginx/1.24.0 (Ubuntu)

To back up MicroBin, take an EBS snapshot of the data volume, or copy /var/lib/microbin while microbin is stopped. To give it more room, grow the volume in the EC2 console and run sudo resize2fs on its device.

Component Path

MicroBin binary /usr/local/bin/microbin

License and source note /usr/share/doc/microbin/

Settings /etc/microbin/microbin.env

Public URL (set by microbin-set-hostname) /etc/microbin/host.env

Passwords (set by microbin-set-password) /etc/microbin/secrets.env (mode 0600)

Data: database, uploads /var/lib/microbin (its own EBS volume)

nginx site /etc/nginx/sites-available/sac-microbin

Delete login file /etc/nginx/.microbin-htpasswd (SHA-512 crypt)

Certificate and key /etc/ssl/microbin/

First boot script /usr/local/sbin/microbin-firstboot.sh

Credentials /root/microbin-credentials.txt (mode 0600)

12

Security recommendations

  • Allow port 22 in the security group from your own networks only, and ports 443 and 80 only to the people you share pastes with.
  • Give the uploader password only to people who should create pastes. Rotate both passwords if they may have leaked (Step 10).
  • Use your own DNS name and a certificate your clients trust (Step 9).
  • Use Private or Secret for anything sensitive, and set short expiries.
  • Keep the operating system patched. Unattended security upgrades are on, and sudo apt-get update && sudo apt-get upgrade applies everything else.

Support and licensing

MicroBin is open source under the BSD 3-Clause License, with no per-user or per-CPU license fee. The license is in /usr/share/doc/microbin/. SecureAnyCloud is not affiliated with or endorsed by the MicroBin project. 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

Deploy on AWS

Launch MicroBin 2.1.0 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

Deploy on AWS