Deployment guide

Apache Subversion Svn

Videos

Overview: Apache Subversion (SVN) on Azure: overview (watch on YouTube)

Launch and log in: Apache Subversion (SVN) on Azure: launch and log in (watch on YouTube)

Deep Dive: Apache Subversion (SVN) on Azure: deep dive (watch on YouTube)

Overview

Apache Subversion (SVN) is the enterprise centralized version-control system from the Apache Software Foundation. It keeps a single authoritative repository with a complete, ordered history of every change. Teams check out a working copy, commit revisions, branch and tag, and roll back to any earlier state.

History and access control live on the server rather than in every clone. This makes Subversion a natural fit for large binary assets, fine-grained path-based permissions, and organizations that want one governed source of truth.

This image serves one repository over HTTPS through Apache httpd and mod_dav_svn at /svn/repo. A self-signed TLS certificate and HTTP Basic Auth secure access, and a dedicated repository user (SecureAnyCloud) gets a strong password that is generated uniquely on first boot. There is no anonymous read or write, so every operation requires authentication.

What you get:

  • Apache Subversion 1.14 (Apache-2.0) served over HTTPS by Apache httpd 2.4 and mod_dav_svn
  • One FSFS repository at /srv/svn/repo, created empty and ready to commit
  • A per-VM repository user, SecureAnyCloud, whose password is generated on first boot, with 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), with no anonymous access
  • An unauthenticated /healthz endpoint for load-balancer and probe checks
  • 24/7 SecureAnyCloud support

Prerequisites

  • An active Azure subscription.
  • An SSH key pair.
  • A VNet and subnet in the target region.
  • Standard_B2s (2 vCPU / 4 GiB RAM) is a good starting size.
  • NSG inbound rules that 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, and search the Marketplace for Apache Subversion by SecureAnyCloud. Select Create.

On the Basics tab, 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 choose Review + create and Create.

Step 2 - Deploy from the Azure CLI

Alternatively, create the VM with the Azure CLI:

# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:apachesubversionsvn-ubuntu-24-04:default:latest
az vm create \
  --resource-group <your-rg> \
  --name svn \
  --image sac1647283583153:apachesubversionsvn-ubuntu-24-04:default:latest \
  --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

Connect over SSH with your key:

ssh azureuser@<vm-public-ip>

Step 4 - Confirm Subversion is installed and serving

Apache serves the repository over HTTPS. It listens on :80 (landing page and redirect) and :443 (repository).

Check the service, the Subversion version, the listeners and the repository:

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

Step 5 - Retrieve your per-VM repository credentials

The repository user is SecureAnyCloud. Its password is generated uniquely on this VM's first boot and written to a root-only file. Read the file over SSH:

sudo cat /root/svn-credentials.txt

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

Issue the certificate for your public address

First boot puts the address Azure reports into the TLS certificate and the credentials file. With a Standard SKU public IP, which is the Azure default and the --public-ip-sku Standard in Step 2, the current image records the VM's private address (10.0.0.x).

In that case SVN_URL points at an address you cannot reach. Subversion clients at the public IP report a certificate hostname mismatch on top of the self-signed warning (curl --cacert fails with error 60). Check the address:

sudo grep '^SVN_URL=' /root/svn-credentials.txt

If it shows a 10. address, issue a new certificate for the public IP on the VM. Azure's instance metadata service reports the public IP to the VM itself, and nothing leaves the VM:

PUBLIC_IP=$(curl -s -H Metadata:true 'http://169.254.169.254/metadata/loadbalancer?api-version=2020-10-01' | grep -o '"frontendIpAddress":"[^"]*"' | head -1 | cut -d'"' -f4)
PRIV=$(hostname -I | awk '{print $1}'); echo "public $PUBLIC_IP, private $PRIV"
sudo openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \
  -keyout /etc/ssl/sac/sac.key -out /etc/ssl/sac/sac.crt \
  -subj "/C=GB/O=sac/CN=$PUBLIC_IP" \
  -addext "subjectAltName=IP:127.0.0.1,IP:$PRIV,IP:$PUBLIC_IP"
sudo chmod 0600 /etc/ssl/sac/sac.key
sudo sed -i "s/\b$PRIV\b/$PUBLIC_IP/g" /root/svn-credentials.txt
sudo systemctl reload apache2

The certificate carries IP entries only. The svn client matches an IP address in the URL against the certificate's common name, and it ignores IP entries whenever a DNS entry is present.

For a DNS name, set PUBLIC_IP to the name and write DNS:$PUBLIC_IP in place of IP:$PUBLIC_IP. Your credentials do not change.

The certificate is still self-signed. Accept it once, or trust it on each workstation with the ssl-authority-files setting in the Subversion servers file, until you install a CA-signed one (Step 10).

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 sac:wrong-password https://127.0.0.1/svn/repo/
curl -ks -o /dev/null -w 'per-VM credentials : HTTP %{http_code}\n' -u "sac:$SVN_PASS" https://127.0.0.1/svn/repo/

The output is 401, 401, then 200. This proves that anonymous and wrong-password access are refused and only the per-VM credentials succeed.

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. Everything runs over HTTPS with your per-VM credentials.

The first-boot certificate is self-signed, so 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 sac --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 sac" > "$WORK/repo/$NOTE" svn add $T "$WORK/repo/$NOTE" svn commit $T --username sac --password "$SVN_PASS" -m "Add $NOTE" "$WORK/repo" svn log $T --username sac --password "$SVN_PASS" "$WORK/repo" rm -rf "$WORK"

From a workstation, run svn checkout https://<vm-ip>/svn/repo --username SecureAnyCloud instead. Enter the password when prompted, and accept the self-signed certificate the first time.

Step 8 - How the credentials are protected

There is no default password. The SecureAnyCloud user's password is generated per VM on first boot and stored bcrypt-hashed in Apache's AuthUserFile. The plaintext is written only to a root-owned 0600 file and 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/(sac:\$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.

Step 9 - Add repository users

Each repository user is an entry in Apache's AuthUserFile. Add another user and enter their password when prompted. They can then check out and commit exactly like sac:

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-sac-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. This 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 SecureAnyCloud image comes with 24/7 support. Email sales@secureanycloud.com or visit secureanycloud.com for documentation and assistance.

Deploy on Azure

Launch Apache Subversion (SVN) 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