Developer Tools Azure

Apache Subversion (SVN) on Ubuntu 24.04 on Azure User Guide

| Product: Apache Subversion (SVN) on Ubuntu 24.04 LTS on Azure

Overview

Apache Subversion (SVN) is the enterprise centralised version-control system from the Apache Software Foundation. It keeps a single authoritative repository with a complete, ordered history of every change, and lets teams check out a working copy, commit revisions, branch and tag, and roll back to any earlier state. Because history and access control live on the server rather than in every clone, Subversion remains a natural fit for large binary assets, fine-grained path-based permissions, and organisations that want one governed source of truth.

The cloudimg image serves one repository over HTTPS through Apache httpd and mod_dav_svn at /svn/repo. Access is secured by a self-signed TLS certificate and HTTP Basic Auth, and a dedicated repository user (cloudimg) with a strong password is generated uniquely on first boot. There is no anonymous read or write - every operation requires authentication. Backed by 24/7 cloudimg support.

What is included:

  • Apache Subversion 1.14 (Apache-2.0) served over HTTPS by Apache httpd 2.4 + mod_dav_svn
  • One FSFS repository at /srv/svn/repo, created empty and ready to commit
  • A per-VM repository user cloudimg whose password is generated on first boot (no shared default credential)
  • A per-VM self-signed TLS certificate generated on first boot; swap it for a CA-signed certificate for production
  • Mandatory authentication on every path (Require valid-user) - no anonymous access
  • An unauthenticated /healthz endpoint for load-balancer and probe checks
  • 24/7 cloudimg support

Prerequisites

An active Azure subscription, an SSH key pair, and a VNet + subnet in the target region. Standard_B2s (2 vCPU / 4 GiB RAM) is a good starting point. NSG inbound: allow 22/tcp from your management network for SSH, and 443/tcp from the clients that will access the repository over HTTPS. Port 80/tcp is optional (it serves a landing page and redirects repository requests to HTTPS).

Step 1 - Deploy from the Azure Marketplace

Sign in to the Azure Portal, choose Create a resource, search the Marketplace for Apache Subversion by cloudimg, and select Create. On Basics pick your subscription, resource group, region and size; under Administrator account choose SSH public key and paste your key; under Inbound port rules allow SSH (22) and HTTPS (443). Then Review + create -> Create.

Step 2 - Deploy from the Azure CLI

az vm create \
  --resource-group <your-rg> \
  --name svn \
  --image <marketplace-image-urn> \
  --size Standard_B2s \
  --admin-username azureuser \
  --ssh-key-values ~/.ssh/id_ed25519.pub \
  --vnet-name <your-vnet> --subnet <your-subnet> \
  --public-ip-sku Standard

Open inbound 443/tcp (and 22/tcp for SSH) on the VM's network security group.

Step 3 - Connect to your VM

ssh azureuser@<vm-public-ip>

Step 4 - Confirm Subversion is installed and serving

Apache serves the repository over HTTPS and listens on :80 (landing + redirect) and :443 (repository). Check the service, the Subversion version, the listeners, and that the repository exists:

systemctl is-active apache2
svn --version --quiet
ss -tln | grep -E ':80 |:443 '
sudo ls -ld /srv/svn/repo

Apache active, Subversion version, HTTPS listeners and the repository

Step 5 - Retrieve your per-VM repository credentials

The repository user is cloudimg; its password is generated uniquely on this VM's first boot and written to a root-only file. Read it over SSH:

sudo cat /root/svn-credentials.txt

The file contains SVN_URL, SVN_USERNAME (cloudimg) and SVN_PASSWORD. These credentials are unique to this VM - nothing is baked into the image.

Step 6 - Confirm access requires authentication (secure by default)

Subversion is served behind mandatory HTTP Basic Auth. An anonymous request and a wrong password are both rejected with 401; only the per-VM password authenticates. The commands below read the real password from the credentials file:

SVN_PASS=$(sudo grep '^SVN_PASSWORD=' /root/svn-credentials.txt | cut -d= -f2-)
curl -ks -o /dev/null -w 'anonymous request  : HTTP %{http_code}\n' https://127.0.0.1/svn/repo/
curl -ks -o /dev/null -w 'wrong password     : HTTP %{http_code}\n' -u cloudimg:wrong-password https://127.0.0.1/svn/repo/
curl -ks -o /dev/null -w 'per-VM credentials : HTTP %{http_code}\n' -u "cloudimg:$SVN_PASS" https://127.0.0.1/svn/repo/

You will see 401, 401, then 200 - proof that anonymous and wrong-password access are refused and only the per-VM credentials succeed.

Anonymous and wrong-password requests are rejected 401; the per-VM password returns 200

Step 7 - Check out the repository and commit a change

The repository is empty and ready to use. From an SSH session on the VM, check it out, add a file, and commit - all over HTTPS with your per-VM credentials. Because the first-boot certificate is self-signed, the commands below trust it explicitly with --trust-server-cert-failures:

SVN_PASS=$(sudo grep '^SVN_PASSWORD=' /root/svn-credentials.txt | cut -d= -f2-)
T="--non-interactive --trust-server-cert-failures=unknown-ca,cn-mismatch,expired,not-yet-valid,other --no-auth-cache"
WORK=$(mktemp -d)
svn checkout $T --username cloudimg --password "$SVN_PASS" https://127.0.0.1/svn/repo "$WORK/repo"
NOTE="release-notes-$(date -u +%Y%m%d-%H%M%S).txt"
echo "First commit from cloudimg" > "$WORK/repo/$NOTE"
svn add $T "$WORK/repo/$NOTE"
svn commit $T --username cloudimg --password "$SVN_PASS" -m "Add $NOTE" "$WORK/repo"
svn log $T --username cloudimg --password "$SVN_PASS" "$WORK/repo"
rm -rf "$WORK"

From a workstation you would instead run svn checkout https://<vm-ip>/svn/repo --username cloudimg and enter the password when prompted, accepting the self-signed certificate the first time.

svn checkout, add and commit succeed and the log shows the new revision

Step 8 - How the credentials are protected

There is no default password. The cloudimg user's password is generated per VM on first boot, stored bcrypt-hashed in Apache's AuthUserFile, and the plaintext is written only to a root-owned 0600 file - it never ships inside the image:

sudo stat -c 'file: %n  perms: %a  owner: %U:%G' /root/svn-credentials.txt
sudo stat -c 'file: %n  perms: %a  owner: %U:%G' /etc/apache2/svn.htpasswd
sudo sed -E 's/(cloudimg:\$2[aby]\$[0-9]{2}\$.{6}).*/\1********************/' /etc/apache2/svn.htpasswd

The credentials file is 0600 root:root, the .htpasswd stores a bcrypt hash (not the plaintext), and only root and the Apache worker can read it.

Credentials file is 0600 root only and the .htpasswd stores a bcrypt hash

Step 9 - Add repository users

Each repository user is an entry in Apache's AuthUserFile. Add another user (you will be prompted for their password), then they can check out and commit exactly like cloudimg:

sudo htpasswd -B /etc/apache2/svn.htpasswd alice
sudo systemctl reload apache2

For read-only or per-path permissions, configure mod_authz_svn with an access file (AuthzSVNAccessFile) in the <Location /svn/repo> block of /etc/apache2/sites-available/000-cloudimg-ssl.conf.

Step 10 - Use a CA-signed certificate for production

The first-boot certificate is self-signed, so clients must trust it explicitly. For production, point a DNS name at the VM and install a CA-signed certificate (for example with Certbot), which removes the certificate warning for every client:

sudo apt-get install -y certbot python3-certbot-apache
sudo certbot --apache -d svn.example.com

After Certbot installs the certificate, svn checkout https://svn.example.com/svn/repo works without the --trust-server-cert-failures flag.

Step 11 - Back up the repository

Take a portable dump of the whole repository history at any time. Store the dump off the VM (for example in Azure Blob Storage) as your backup:

sudo svnadmin dump /srv/svn/repo > /tmp/svn-repo-backup.dump
ls -lh /tmp/svn-repo-backup.dump

Restore into a fresh repository with svnadmin load. See the Subversion book for repository administration and hook scripts.

Support

Every cloudimg image comes with 24/7 support. Email support@cloudimg.co.uk or visit cloudimg.co.uk for documentation and assistance.