I have a Mac Mini which I keep connected to the Internet. In this world of DoS attacks and port sniffing, exposing ports to the Internet at large is risky. Yesterday I turned off HTTP (80), which was being used to allow access to mod_dav_svn, and migrated my systems to SVN over SSH. This has the advantage of only requiring the server machine to expose SSH (22).

The setup was quite involved.

Server (Linux)

  1. Setup a new standard user (svuser).
  2. Site your svn directory containing the repositories in ~/svn, either directly or by symlink.
  3. In user's home directory, create .ssh subdirectory.
  4. Create authorized_hosts file under .ssh.
  5. For every user:machine that should have access to the SVN repositories, create an entry of the form:

    command="svnserve -t -r [path_to_repositories]" [key_type] [key] [comment]

    The key type is something like ssh-dss. The key is the client's public key, which looks like a long string of random characters.

  6. Open port 22 on your router's firewall.
  7. Setup port forwarding to send external IP port 22 to internal IP port 22.
  8. Enabled local NAT loopback on your router, if you're using NAT to forward external port 22 to local port 22 on the server. For my Zyxel P-660HWP I had to do that via Telnet.

This spawns a new instance of svnserve each time a user SSHs in. This means that several users can access the server at the same time.

Client (Windows

  1. Generate a public-private key pair. When generating public keys, always use a password.
  2. Add your private key to the authorized_hosts file, as described above.
  3. Run an ssh agent, such as pageant to store your key.
  4. Relocate your local working copies to your new store, using the 'relocate' menu option in TortoiseSVN or 'svn switch --relocate' from the command line. Your new URLs should take the form:
    svn+ssh://[username]@[hostname]/[path]/[name.repo]