Deployment guide

OliveTin

Overview

OliveTin gives you a clean web interface of buttons, where each button runs one predefined shell command that an administrator has approved in advance. Instead of handing people SSH access to run ad hoc commands, you define a curated set of actions in a single YAML file. Users click to run them and watch the live output stream back to the page.

It is a natural fit for home labs and operations teams who want to let less technical users, or their future selves, safely trigger routine jobs from a browser or a phone. Examples include restarting a service, checking disk space, pinging a host or kicking off a backup.

Because every button is a real shell command running on the server, the entire value of OliveTin depends on it being locked down. An OliveTin that is reachable without authentication is, in effect, remote command execution. The SecureAnyCloud image is built around that fact and ships OliveTin 3000.17.1 as a single static Go binary on a hardened Ubuntu 24.04 LTS base, patched at build time and managed by systemd.

What you get:

  • OliveTin 3000.17.1, the official release, running as a dedicated non-root olivetin system user, managed by systemd.
  • An nginx reverse proxy on port 443 that terminates TLS with a self-signed certificate regenerated per VM at first boot and enforces HTTP Basic Auth. Port 80 redirects to HTTPS, and an unauthenticated /healthz probe serves load balancers. This proxy is the only network-facing surface.
  • OliveTin bound to the loopback interface only (127.0.0.1:1337), never exposed to the network.
  • A per-VM administrator password generated on first boot and recorded in a root-only file, with no shipped default login.
  • A small set of safe, non-destructive default actions: check disk usage, show memory, show uptime, ping a host from a fixed allow list, and restart a demo service through a narrowly scoped sudo rule.
  • 24/7 SecureAnyCloud support.

OliveTin is free and open-source software licensed under the GNU Affero General Public License version 3.

Prerequisites

  • An Azure subscription and either the Azure portal or the Azure CLI (az).
  • An SSH key pair to administer the VM.
  • A network security group that allows inbound TCP 443 (and 80 for the HTTPS redirect) from the clients that need the web interface, plus TCP 22 from your admin location.

Step 1 - Deploy from the Azure Marketplace

Find the SecureAnyCloud OliveTin on Ubuntu 24.04 LTS offering in the Azure Marketplace. Choose the recommended Standard_B2s size, attach the VM to your virtual network, and allow inbound TCP 443 and 22. OliveTin is a tiny Go binary and runs comfortably on Standard_B2s.

Step 2 - Deploy from the Azure CLI

The commands below create a resource group, the VM from the SecureAnyCloud image, and inbound rules for HTTPS and the HTTPS redirect. Replace the image URN or plan details with the ones shown on the Marketplace listing page.

az group create --name olivetin-rg --location uksouth
# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:olivetin-ubuntu-24-04:default:latest
az vm create \
  --resource-group olivetin-rg \
  --name olivetin \
  --image sac1647283583153:olivetin-ubuntu-24-04:default:latest \
  --size Standard_B2s \
  --admin-username azureuser \
  --generate-ssh-keys \
  --public-ip-sku Standard
az vm open-port --resource-group olivetin-rg --name olivetin --port 443 --priority 900
az vm open-port --resource-group olivetin-rg --name olivetin --port 80 --priority 910
# When the VM is running, note its public IP address:
az vm show -d --resource-group olivetin-rg --name olivetin --query publicIps -o tsv

Step 3 - Confirm the services are running

SSH in as azureuser and confirm that the command runner, the reverse proxy and the first-boot job are healthy. nginx serves OliveTin by proxying to the OliveTin binary on the loopback interface, and a one-shot first-boot service generates the per-VM secrets.

systemctl is-active olivetin nginx olivetin-firstboot.service

Expected output. The first-boot service reports active once it has completed on the first boot of the VM:

active active active

Confirm the pinned version that shipped:

cat /opt/olivetin/VERSION

Step 4 - Confirm the network shape

OliveTin binds to the loopback interface only. nginx, listening on ports 80 and 443, is the sole network-facing surface and reverse-proxies to it. Confirm the listeners:

ss -tln | grep -E ':1337|:80 |:443 '

You will see OliveTin on 127.0.0.1:1337 (loopback only) and nginx on 0.0.0.0:80 and 0.0.0.0:443.

Step 5 - Retrieve the per-VM administrator password

Every VM generates its own administrator password on first boot. It writes the password into the nginx HTTP Basic Auth file and records the login details in a root-only file. Read the file over SSH:

sudo cat /root/olivetin-credentials.txt

You will see the web URL, the administrator user (admin) and the generated password. These values are unique to your VM. The file is mode 0600 and owned by root.

Step 6 - Confirm authentication is enforced

The reverse proxy refuses unauthenticated requests and serves OliveTin only to a caller that passes HTTP Basic Auth. The unauthenticated /healthz probe is the one exception, provided for load balancers. Confirm all three behaviors:

curl -sk -o /dev/null -w 'anonymous: %{http_code}\n' https://127.0.0.1/
curl -sk -o /dev/null -w 'authenticated: %{http_code}\n' -u '<OLIVETIN_ADMIN_USER>:<OLIVETIN_ADMIN_PASSWORD>' https://127.0.0.1/
curl -sk -o /dev/null -w 'healthz: %{http_code}\n' https://127.0.0.1/healthz

An unauthenticated request is refused with 401, an authenticated request returns 200, and the health probe returns 200 without a login:

anonymous: 401 authenticated: 200 healthz: 200

Step 7 - Sign in to the web UI

Browse to your VM over HTTPS. The image ships a self-signed certificate generated per VM, so your browser warns once. Accept the warning, or place your own certificate in front for production.

https://<your-vm-public-ip>/

Your browser prompts for HTTP Basic Auth. Enter admin and the password from the credentials file. You land on the OliveTin Actions dashboard, which shows the shipped safe actions as buttons.

Step 8 - Run an action

Select any action button to run its command. OliveTin executes the predefined command on the server and streams the output back into an execution dialog. Select Check disk usage and you will see the real df output, with the execution marked Completed.

Every execution is recorded. Open the Logs view to see the history of who ran what and when, with each entry linking to its full output.

Step 9 - Trigger an action from the API

OliveTin exposes the same actions over a simple JSON API, so you can drive them from scripts, cron or another service. Authenticate with the same HTTP Basic Auth credential. This command triggers the check_disk action and waits for its output:

curl -sk -u '<OLIVETIN_ADMIN_USER>:<OLIVETIN_ADMIN_PASSWORD>' \
  -H 'Content-Type: application/json' \
  -d '{"actionId":"check_disk"}' \
  https://127.0.0.1/api/olivetin.api.v1.OliveTinApiService/StartActionAndWait

The response is a JSON logEntry containing the command exitCode and its output. Actions that take arguments receive them as an array, for example the shipped ping_host action:

curl -sk -u '<OLIVETIN_ADMIN_USER>:<OLIVETIN_ADMIN_PASSWORD>' \
  -H 'Content-Type: application/json' \
  -d '{"actionId":"ping_host","arguments":[{"name":"host","value":"1.1.1.1"}]}' \
  https://127.0.0.1/api/olivetin.api.v1.OliveTinApiService/StartActionAndWait

Step 10 - Add your own actions

Actions are defined in /etc/OliveTin/config.yaml. Each action gives a title, a stable id used by the API, and the shell command to run. Every action is a real shell command run on the server, so add actions with care. Constrain any argument to a fixed list of choices rather than accepting free-form input, keep destructive commands off the appliance, and never widen the reverse proxy authentication.

A minimal safe action looks like this:

actions: - title: Show running containers id: docker_ps shell: docker ps icon: box onclick: execution-dialog timeout: 15

OliveTin runs as the unprivileged olivetin user. If an action genuinely needs elevated privileges, grant exactly that one command through a narrow rule in /etc/sudoers.d/, as the shipped Restart demo service action does, rather than running OliveTin as root. After editing the config, restart the service so that OliveTin reloads it:

sudo systemctl restart olivetin

Use the Diagnostics view to confirm the running configuration and generate a support report.

Security model - no default login

The SecureAnyCloud image ships with no known credentials. Before the image is captured, the HTTP Basic Auth file is emptied and the credentials file is reset so that it holds no real credential.

On the first boot of every VM, a one-shot first-boot service performs these steps:

  • It regenerates the self-signed TLS certificate.
  • It generates a fresh random administrator password and writes it into the nginx Basic Auth file as a bcrypt hash.
  • It proves end to end that an unauthenticated request is refused, an authenticated request succeeds, and a shipped action executes and returns its output.
  • It records the login in the root-only credentials file.

The design uses defense in depth. The OliveTin binary is bound to loopback and is never reachable from the network directly. nginx is the only public surface, and it forwards the authenticated identity to OliveTin as a request header that a client cannot spoof. OliveTin is configured to deny any request that is not an authenticated administrator, so even a request that reached the loopback port without going through nginx would be refused.

To rotate the administrator password at any time, run:

sudo htpasswd -B /etc/nginx/olivetin.htpasswd admin

Corresponding source (AGPL-3.0)

OliveTin is distributed under the GNU Affero General Public License version 3. The complete corresponding source for the version in this image is published by the OliveTin project at github.com/OliveTin/OliveTin, and the exact release and its sha256 digest are recorded on the VM at /opt/olivetin/VERSION. The SecureAnyCloud image adds only configuration and an nginx reverse proxy; it does not modify the OliveTin source.

Support

Every SecureAnyCloud deployment is paired with this guide and backed by 24/7 SecureAnyCloud support. For questions about running OliveTin on Azure, contact the SecureAnyCloud team.

Deploy on Azure

Launch OliveTin on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.

View this image

Need Help?

Our support team is available 24/7.

sales@secureanycloud.com

Deploy on Azure