restic Rest Server
Overview
Rest Server is an open-source, high-performance HTTP server that implements restic's REST backend protocol. This image turns a virtual machine and its dedicated data disk into a self-hosted backup repository server in your own Azure subscription. Point any restic client at it over HTTPS to read and write backup repositories, just as you would against any restic remote.
Rest Server 0.14.0 runs as a single static binary under systemd as an unprivileged restic user. It is a headless service with no web interface, so you operate it with the restic client from the machines you back up.
What you get:
- Rest Server 0.14.0 from the official release, run under systemd as the unprivileged
resticuser (rest-server.service) - An HTTPS REST endpoint on port 443, terminated by an nginx reverse proxy with a self-signed certificate generated per virtual machine on first boot. Rest Server itself binds to loopback only.
- Repository data stored on a dedicated data disk mounted at
/var/lib/restic - No anonymous access. Rest Server can be run with
--no-auth, which serves an open repository server. This image never does. It runs with--htpasswd-fileand--private-repos, so every request needs HTTP Basic authentication against a bcrypt htpasswd file, and each user is confined to their own repository namespace. - A unique username and password generated on the first boot of every VM, written to the htpasswd file and recorded in
/root/rest-server-info.txt(mode 0600, root only). No two instances share a credential. - Credentials documented in
/root/rest-server-info.txt(0600), with--htpasswd-fileand--private-reposso every request is authenticated and confined to its own namespace - A service that refuses to start until a credential is present, so an unauthenticated or wrong-password request is rejected with HTTP 401
Prerequisites
- An active Azure subscription, an SSH public key, and a VNet with a subnet in the target region
- A subscription to the Rest Server listing on Azure Marketplace
- Network security group rules that allow TCP 22 (admin) and TCP 443 (the HTTPS REST endpoint) from the client networks that back up to the server. Port 80 answers with a redirect to HTTPS and serves an unauthenticated
/healthzload balancer probe. - The restic client installed on the machines you want to back up, from
https://restic.netor your OS package manager. Rest Server is the destination, and restic is the client that talks to it.
Recommended virtual machine size: Standard_B2s (2 vCPU, 4 GB RAM) is ample for development and small production workloads. For higher throughput or capacity, choose a larger size or attach a larger data disk.
Deploy from the Azure Portal
Launch the image from the Azure Marketplace listing. Choose your resource group, region, size (Standard_B2s or larger) and SSH key. Attach the offer's data disk, and open ports 22 and 443 in the network security group.
To deploy with the Azure CLI instead, run:
RG="rest-server-prod"; LOCATION="eastus"; VM_NAME="rest-server1" IMAGE_URN="sac1647283583153:restic-rest-server-ubuntu-24-04:default:latest" SSH_KEY="$(cat ~/.ssh/id_rsa.pub)" az group create --name "$RG" --location "$LOCATION"
# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:restic-rest-server-ubuntu-24-04:default:latest
az vm create \
--resource-group "$RG" --name "$VM_NAME" \
--image "$IMAGE_URN" \
--size Standard_B2s \
--admin-username azureuser \
--ssh-key-values "$SSH_KEY" \
--public-ip-sku Standard
az vm open-port --resource-group "$RG" --name "$VM_NAME" --port 443 --priority 1001
az vm open-port --resource-group "$RG" --name "$VM_NAME" --port 22 --priority 1002Retrieve your per-VM credentials
On first boot, the VM generates a unique username and password and writes them to a root-only file. SSH in as azureuser and read the file:
sudo cat /root/rest-server-info.txtThe file contains REST_SERVER_USER, REST_SERVER_PASSWORD, REST_SERVER_URL (the HTTPS endpoint using this VM's public IP) and REST_SERVER_REPO (a ready-to-use restic repository string). These credentials are unique to this VM and are not part of the image. Keep the file secret.
Verify the service is running
Confirm that the services are active and check the network listeners. Rest Server binds to loopback (127.0.0.1:8000), and nginx binds the public HTTPS endpoint on 0.0.0.0:443:
sudo systemctl start rest-server.service nginx.service systemctl is-active rest-server.service nginx.service /opt/rest-server/rest-server --version ss -tlnH | grep -E ':8000|:443'Back up and restore with restic
The restic client talks to this server over HTTPS. The endpoint is an IP address with a self-signed certificate, so use --insecure-tls or trust the certificate (see below).
The following block runs a quick self-test on the VM. It installs a restic client, reads the VM's own credentials, and runs a full round trip against the local endpoint: initialise a repository, back up a file, list the snapshot, then restore the file and print its contents.
curl -fsSL -o /tmp/restic.bz2 https://github.com/restic/restic/releases/download/v0.18.0/restic_0.18.0_linux_amd64.bz2 bunzip2 -f /tmp/restic.bz2 && chmod +x /tmp/restic
U=$(sudo grep '^REST_SERVER_USER=' /root/rest-server-info.txt | cut -d= -f2-)
P=$(sudo grep '^REST_SERVER_PASSWORD=' /root/rest-server-info.txt | cut -d= -f2-)
export RESTIC_REPOSITORY="rest:https://$U:$P@127.0.0.1/restic/demo"
export RESTIC_PASSWORD="choose-a-strong-repository-encryption-password" echo "hello from sac" > /tmp/demo.txt /tmp/restic --insecure-tls init /tmp/restic --insecure-tls backup /tmp/demo.txt /tmp/restic --insecure-tls snapshots /tmp/restic --insecure-tls restore latest --target /tmp/restored cat /tmp/restored/tmp/demo.txtThe RESTIC_PASSWORD above is the repository encryption password that you choose. It encrypts the backup data and is separate from the REST_SERVER_PASSWORD that authenticates you to the server. Keep both safe, because backups cannot be decrypted without the repository password.
Authentication is enforced
There is no anonymous access. A request with no credentials, and a request with the wrong password, are both rejected with HTTP 401. Run the following to see it:
curl -ks -o /dev/null -w 'no credentials: HTTP %{http_code}\n' https://127.0.0.1/restic/
U=$(sudo grep '^REST_SERVER_USER=' /root/rest-server-info.txt | cut -d= -f2-)
curl -ks -o /dev/null -w 'wrong password: HTTP %{http_code}\n' -u "$U:wrong-password" https://127.0.0.1/restic/
curl -ks -o /dev/null -w 'correct password: HTTP %{http_code}\n' \
-u "$U:$(sudo grep '^REST_SERVER_PASSWORD=' /root/rest-server-info.txt | cut -d= -f2-)" https://127.0.0.1/restic/Security posture and where your data lives
The credentials file is root-only (0600), the server runs with --htpasswd-file and --private-repos, and repository data lives on the dedicated data disk mounted at /var/lib/restic. Confirm all three:
sudo stat -c '%n %a %U:%G' /root/rest-server-info.txt systemctl show rest-server.service -p ExecStart --value | grep -o -- '--htpasswd-file[^ ]* --private-repos' df -h /var/lib/restic | tail -1Connecting from a remote client
On a machine you want to back up, install the restic client and point it at this VM's public endpoint with your username and password. Use path-style URLs in which the first path element is your username, because private repositories confine each user to their own namespace:
export RESTIC_REPOSITORY='rest:https://<your-username>:<your-password>@<vm-ip>/restic/laptop'
export RESTIC_PASSWORD='choose-a-strong-repository-encryption-password' restic --insecure-tls init restic --insecure-tls backup ~/Documents restic --insecure-tls snapshotsReplace <vm-ip> with the VM public IP (see REST_SERVER_URL in /root/rest-server-info.txt). Replace <your-username> and <your-password> with the values from that file. You can create as many named repositories under your namespace as you like, for example .../restic/laptop and .../restic/server1.
Using the TLS certificate
The certificate is self-signed and generated per virtual machine on first boot. Its subject alternative names include the VM public IP, the hostname and 127.0.0.1. For quick testing, pass --insecure-tls.
For production, choose one of two options. Distribute the certificate at /etc/nginx/tls/rest-server.crt to your clients as a trusted CA, then drop --insecure-tls. Or place the appliance behind a load balancer or reverse proxy with a certificate issued by a public CA for your own domain, and point clients at that hostname.
Adding users and rotating passwords
Credentials live in the bcrypt htpasswd file /etc/rest-server/.htpasswd. Add a user or change a password with htpasswd, update /root/rest-server-info.txt to match, and restart the service. This example rotates the restic user's password to a value you supply:
sudo htpasswd -B /etc/rest-server/.htpasswd restic <new-password>
sudo sed -i "s|^REST_SERVER_PASSWORD=.*|REST_SERVER_PASSWORD=<new-password>|" /root/rest-server-info.txt
sudo systemctl restart rest-server.service echo "password rotated"To add a second user, run sudo htpasswd -B /etc/rest-server/.htpasswd <new-username> and restart the service. Because the server runs with --private-repos, that user can access only repositories under their own namespace.
Hardening: append only repositories
For ransomware-resistant backups, run the server in append-only mode. Clients can then create and read snapshots, but they cannot delete or overwrite existing data.
Add --append-only to the ExecStart line in /etc/systemd/system/rest-server.service (via sudo systemctl edit --full rest-server.service) and restart the service. An administrator with direct disk access must then prune repositories out of band.
Managing the service
systemctl status rest-server.service nginx.service --no-pager sudo journalctl -u rest-server.service -n 50 --no-pagerThe server restarts automatically on failure and starts on boot. Repository data persists on the data disk across restarts and reboots.
Troubleshooting
restic reports 401 Unauthorized: confirm the client is using the exact username and password from /root/rest-server-info.txt, and that the first path element of the repository URL matches your username.
restic reports a certificate error: the certificate is self-signed. Trust /etc/nginx/tls/rest-server.crt, use --insecure-tls for testing, or front the appliance with a public CA certificate as described above.
A client cannot connect: confirm the Network Security Group allows TCP 443 from the client network, and that systemctl is-active rest-server.service nginx.service reports active.
Support
Every SecureAnyCloud deployment includes 24/7 support. Contact the SecureAnyCloud team for help with configuration, retention policies, scaling or integration.
Deploy on Azure
Launch Rest Server 0.14.0 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
Overview
Rest Server is the open-source, high-performance HTTP server that implements the restic REST backend protocol. This image turns an EC2 instance into a self-hosted, authenticated backup repository server in your own AWS account. Point any restic client at it over HTTPS to read and write encrypted backup repositories. Because it speaks the standard restic REST protocol, existing restic clients and automation work unchanged.
What you get:
- Rest Server 0.14.0, installed from the official upstream release and verified against its published SHA256 checksum at build time
- An HTTP REST API backend with no web console. The server itself binds to the loopback interface only.
- nginx as the single network-facing surface, terminating TLS on port 443 and fronting the entire backend with HTTP basic authentication, so the server is never an open, anonymous repository
- Unbuffered request streaming with no size cap in nginx, because restic uploads large pack files
- A dedicated, independently resizable EBS data volume mounted at
/var/lib/restic, separate from the operating system disk, so your backups have room to grow
Secure by default: per instance credentials
Rest Server can run with authentication disabled, which would make it an open, anonymous repository server. This image never runs it that way, and nothing secret is part of the image. It runs with --htpasswd-file and --private-repos, so every request needs HTTP basic authentication against a bcrypt password file, and each user is confined to their own repository namespace.
On the first boot of every instance, the rest-server-firstboot service does the following:
- Resolves the instance public IP through the EC2 Instance Metadata Service (IMDSv2)
- Generates a unique self-signed TLS certificate whose subject alternative names cover the instance public IP, its hostname and
127.0.0.1 - Generates a unique restic username and password and writes the bcrypt
htpasswdfile - Writes the credentials, the HTTPS endpoint URL and a ready-to-paste restic repository example to
/root/rest-server-aws-credentials.txt(mode0600, root only)
Every instance therefore gets its own certificate and its own password. rest-server.service requires the first-boot credential generator, so it can never start without a per-instance credential. Unauthenticated requests are rejected with 401.
Prerequisites
Before you deploy this image, you need:
- An Amazon Web Services account where you can launch EC2 instances
- IAM permissions to launch instances, create security groups and subscribe to AWS Marketplace products
- An EC2 key pair in the target Region for SSH access to the instance
- A VPC and subnet in the target Region, with a security group that allows inbound port 22 (SSH) from your management network and inbound port 443 (HTTPS) from the machines that back up to the server
- The AWS CLI (version 2) installed locally, if you deploy from the command line
Launch the instance from the AWS Marketplace
Sign in to the AWS Management Console, open the EC2 service, and select Launch instance. Under Application and OS Images, choose AWS Marketplace AMIs and search for Rest Server for restic. Select the SecureAnyCloud listing, choose Select, then choose Continue on the subscription summary.
Pick an instance type of m5.large or larger. Choose your EC2 key pair under Key pair (login). Under Network settings, select your VPC and subnet, then create or select a security group that opens port 22 from your management network and port 443 from the machines that back up to the server.
Leave the root volume at the default size or larger. The repository store lives on a separate data volume that is provisioned automatically.
Select Launch instance. First-boot initialisation takes a few seconds after the instance state becomes Running and the status checks pass.
Launch the instance from the AWS CLI
Run the following block to launch an instance from the SecureAnyCloud Rest Server Marketplace AMI into an existing subnet and security group.
Replace <ami-id> with the AMI ID shown on the Marketplace listing and <key-name> with your EC2 key pair name. Replace <subnet-id> with your subnet ID and <security-group-id> with a security group that opens port 22 and port 443.
aws ec2 run-instances \
--image-id <ami-id> \
--instance-type m5.large \
--key-name <key-name> \
--subnet-id <subnet-id> \
--security-group-ids <security-group-id> \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=rest-server}]'When the instance reaches the Running state and its status checks pass, note its public IP address or DNS name. You can find both in the EC2 console or with aws ec2 describe-instances.
Connect to your instance
Connect over SSH with your key pair. The login user for Ubuntu 24.04 is ubuntu.
ssh -i /path/to/your-key.pem ubuntu@<public-ip>Retrieve the per-instance credentials
The unique username and password generated on first boot are in a root-only file. Read it with sudo:
sudo cat /root/rest-server-aws-credentials.txtThe file contains:
REST_SERVER_USERandREST_SERVER_PASSWORD: the restic username and password for this instanceREST_SERVER_URL: the HTTPS endpoint,https://<instance-public-ip>/REST_SERVER_REPO: a ready-to-paste restic repository prefix
Keep this file secret. It holds the credentials for your backup repository server.
Confirm the server is running
Rest Server runs as a systemd service bound to 127.0.0.1:8000 only. nginx terminates TLS on port 443 as the single network-facing surface. Confirm that both services are active and that rest-server listens on loopback only:
systemctl is-active rest-server.service nginx.service
sudo ss -ltnp | grep -E ':8000|:443|:80 ' cat /opt/rest-server/VERSIONrest-server listens on 127.0.0.1:8000 and never on a public interface, while nginx owns ports 443 and 80. This keeps the server from ever being an open, anonymous repository.
Verify the authentication boundary
nginx fronts the entire REST backend with HTTP basic authentication, so an unauthenticated request is rejected. An unauthenticated /healthz probe is available for load balancers. Run the following to confirm the boundary:
# no credentials -> 401 Unauthorized (the server is never open)
curl -sk -o /dev/null -w '%{http_code}\n' https://127.0.0.1/restic/
# a wrong password is also rejected -> 401
curl -sk -u restic:wrong-password -o /dev/null -w '%{http_code}\n' https://127.0.0.1/restic/
# unauthenticated load-balancer liveness probe -> 200
curl -sk -o /dev/null -w '%{http_code}\n' https://127.0.0.1/healthzBack up to the server with restic
On any machine that has the restic client installed, point restic at this instance and run a normal backup. The TLS certificate is self-signed per instance, so either copy the instance's certificate from /etc/nginx/tls/rest-server.crt and trust it, or pass --insecure-tls.
Use the username and password from your credentials file, and choose a strong repository encryption password of your own.
# from your own machine, using the per instance credentials export RESTIC_REPOSITORY="rest:https://restic:<REST_SERVER_PASSWORD>@<public-ip>/restic/myrepo" export RESTIC_PASSWORD="choose-a-strong-repository-encryption-password" restic --insecure-tls init restic --insecure-tls backup /path/to/data restic --insecure-tls snapshotsrestic init creates the repository under your user's namespace on the data volume. restic backup uploads deduplicated, encrypted data, and restic snapshots lists what has been stored. Because the server runs with --private-repos, the restic user can access only repositories under its own namespace (rest:https://restic:...@<host>/restic/<repo>).
The repository store is on the dedicated data volume. To see where your backups live and how much room remains, run:
df -h /var/lib/resticTo roll the server out across a fleet, distribute the certificate and the per-instance credentials to the machines that back up to it. For production, replace the self-signed certificate with one signed by your own certificate authority or a public CA for your domain. Add further restic users with htpasswd.
Configuration and data layout
Path Purpose
/opt/rest-server/rest-server The Rest Server binary
/var/lib/restic The repository store, on the dedicated data volume
/etc/rest-server/.htpasswd The per instance bcrypt password file
/etc/systemd/system/rest-server.service The systemd unit (loopback bind, --htpasswd-file, --private-repos)
/etc/nginx/sites-available/sac-rest-server The nginx reverse proxy and TLS configuration
/etc/nginx/tls/rest-server.crt and rest-server.key The per instance self signed certificate and key
/root/rest-server-aws-credentials.txt The generated per instance credentials (mode 0600)
To add a restic user or rotate a password, update /etc/rest-server/.htpasswd with htpasswd -B and run sudo systemctl restart rest-server.service. To change the TLS certificate, replace the files under /etc/nginx/tls and run sudo systemctl reload nginx.
Support
SecureAnyCloud supports this Rest Server image 24/7. Contact sales@secureanycloud.com for help with:
- Deployment, and pointing restic clients at the server from workstations, servers and CI
- Repository and namespace layout, and append-only and private repository patterns
- Credential rotation and adding users
- nginx TLS with your own domain and certificate
- Data volume sizing and Rest Server version upgrades
Critical issues receive a one-hour average response time.
Rest Server and restic are trademarks of their respective owners. This is a repackaged open-source software product with additional charges for SecureAnyCloud support services.
Deploy on AWS
Launch Rest Server for restic on AWS with 24/7 support from SecureAnyCloud.
View on Marketplace
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com