Apache Subversion 配置参数详解

逐项详解 Apache Subversion 1.14 服务端与客户端配置参数,覆盖 svnserve.conf 五个通用参数、passwd 与 authz 授权文件、svnserve 启动参数、Apache dav_svn 指令、客户端 config/servers 默认值与凭据缓存,并给出生产模板与生效验证回显,全部实测。

Apache SubversionApache Subversion2026/10/12

Apache Subversion 配置参数详解

目标:逐项讲清 Apache Subversion 1.14 的配置体系——svnserve 模式的 svnserve.conf/passwd/authz 与服务启动参数、Apache WebDAV 模式的 dav_svn 指令、客户端 ~/.subversion 的 config/servers 默认值——每项参数给出默认值、修改方式与实测生效验证。以下内容均在 Ubuntu 22.04.5 + Subversion 1.14.1 环境实测。

一、环境信息

  • 操作系统:Ubuntu 22.04.5 LTS(x86_64)
  • Apache Subversion:1.14.1-3ubuntu0.22.04.1(apt)
  • Apache HTTP Server:2.4.52-1ubuntu4.24(WebDAV 模式)
  • 版本库:/srv/svn/repo1(FSFS 格式)
  • 服务形态:svnserve(systemd 单元 svnserve.service,监听 3690)+ Apache mod_dav_svn(监听 80)
  • 演示账号:admin / root,密码 q1w2e3r4

二、前置条件

  • 已按《Apache Subversion 安装指南》完成 subversion、subversion-tools 安装,且至少启用 svnserve 或 Apache dav_svn 之一。
  • 已存在一个版本库(本文以 /srv/svn/repo1 为例)。
  • root 权限;修改服务端配置后需要重启对应服务(见第三节)。

三、参数查看与修改方式

3.1 配置参数分布

层级文件/位置生效范围
版本库服务参数<版本库>/conf/svnserve.conf仅该版本库的 svnserve 访问行为
用户口令<版本库>/conf/passwd(或 password-db 指向的文件)svnserve 认证
路径授权<版本库>/conf/authz(或 authz-db 指向的文件;WebDAV 模式为 AuthzSVNAccessFile)svn:// 与 http:// 共用格式
svnserve 进程systemd 单元 ExecStart(或命令行)监听地址/端口/根目录等
Apache 指令/etc/apache2/mods-enabled/dav_svn.conf全部 WebDAV 访问
客户端全局/etc/subversion/config、/etc/subversion/servers本机所有用户的 svn 客户端
客户端个人/.subversion/config、/.subversion/servers当前用户 svn 客户端
凭据缓存~/.subversion/auth/(目录树)已保存的用户名口令

查看各文件默认内容的方法(默认文件几乎全为注释,注释里就是参数说明):

grep -vE "^#|^$" /srv/svn/repo1/conf/svnserve.conf   # 查看生效行
grep -E "^# ?(store-passwords|store-auth-creds)" /etc/subversion/config

3.2 修改与生效方式

  • svnserve 模式:改 conf 文件后执行 systemctl restart svnserve(svnserve 无 reload 机制,进程读取的是启动时与每次连接时的库内配置,改进程参数必须重启)。
  • Apache WebDAV 模式:改 dav_svn.conf 后先 apachectl configtest 校验,再 systemctl restart apache2。
  • 客户端参数:直接编辑 config/servers,下一条 svn 命令即生效,无需重启任何进程。
  • 授权正确性可离线校验:svnauthz accessof --username admin --path / /etc/svn/authz,实测回显 rw。

四、参数总览

参数所在位置默认值作用
anon-accesssvnserve.conf [general]read匿名用户访问级别
auth-accesssvnserve.conf [general]write认证用户访问级别
password-dbsvnserve.conf [general]passwd用户口令文件
authz-dbsvnserve.conf [general]未启用路径授权文件
realmsvnserve.conf [general]未启用认证域名称(凭据缓存关联键)
-r/--rootsvnserve 启动参数未限制服务根目录,URL 里相对此路径
--listen-portsvnserve 启动参数3690监听端口
--listen-hostsvnserve 启动参数所有地址监听地址
-c/--compressionsvnserve 启动参数5网络传输压缩级别 0-9
-M/--memory-cache-sizesvnserve 启动参数16(MB)FSFS 内存缓存大小
DAV svndav_svn.conf必写声明该 Location 为 SVN 服务
SVNPath / SVNParentPathdav_svn.conf二选一单库路径 / 多库父目录
AuthUserFiledav_svn.conf无htpasswd 口令文件
AuthzSVNAccessFiledav_svn.conf无路径级授权文件
Require valid-userdav_svn.conf无强制认证
store-passwordsconfigno是否明文缓存口令
store-auth-credsconfigno是否缓存认证凭据
http-timeoutservers60(秒)HTTP 请求超时
http-compressionserversautoHTTP 传输压缩

五、核心参数分类详解

5.1 svnserve.conf 通用段([general])

本机实测生效配置(anon-access 关闭匿名、启用口令文件与授权文件):

[general]
anon-access = none
auth-access = write
password-db = passwd
authz-db = authz
realm = repo1

逐项说明:

参数取值默认实测行为
anon-accessnone / read / writeread设为 none 后,不带凭据的检出立刻被拒:svn: E170001: Can't get username or password(实测回显)
auth-accessnone / read / writewrite认证后的最大权限;生产建议 write 并配合 authz-db 收敛
password-db文件名passwd相对路径相对本文件所在 conf 目录;也可写绝对路径让多库共用一份
authz-db文件名未启用启用后进入路径级授权(见 5.2);未启用时只按 auth-access 控制整体读写
realm字符串未启用客户端凭据缓存按 realm 归档;svn auth 实测显示 Authentication realm: <svn://127.0.0.1:3690> repo1

💡 多库共用账号的惯用做法:password-db、authz-db 写绝对路径指向同一份文件(如 /srv/svn/passwd、/srv/svn/authz),realm 保持每库唯一。

5.2 passwd 与 authz 文件

passwd 文件([users] 段一行一个 用户 = 口令,实测内容):

[users]
admin = q1w2e3r4

authz 文件(分组 + 路径段,实测内容):

[groups]
dev = admin

[/]
@dev = rw
* =

语法要点:

  • [/] 是相对 svnserve -r 根目录(或 SVNParentPath)的路径;单库(SVNPath / realm 内)也支持 [repo1:/] 形式以库名开头,实测两种写法并存有效。
  • @dev 引用 [groups] 里定义的组;admin 直接引用用户;* 匹配所有用户(含匿名)。
  • 权限只有 r、rw、空(无权限)三档;空值可显式写 * =。
  • 校验命令与实测回显:
# svnauthz accessof --username admin --path / /srv/svn/authz
rw

⚠️ authz 按"最长匹配路径优先"取规则;[/] 的规则不会向下累加合并,务必在每一段里写全所需权限。

5.3 svnserve 服务启动参数

本机 systemd 单元实测内容:

[Unit]
Description=Subversion protocol daemon (svnserve)
After=network.target

[Service]
Type=simple
ExecStart=/usr/bin/svnserve --daemon --foreground --root /srv/svn
Restart=on-failure
User=svn
Group=svn

[Install]
WantedBy=multi-user.target

常用参数(取自 svnserve --help 实测输出,默认值均来自其标注):

参数默认值说明
-d [--daemon]-守护进程模式
--foreground-前台运行,配合 systemd Type=simple 必用(与 -d 同用时前台生效)
-r [--root] ARG未限制对外暴露的根目录;设 /srv/svn 后 URL 为 svn://host/repo1,未设则需带全路径
--listen-port ARG3690监听端口
--listen-host ARG所有地址监听指定 IP 或主机名
-R [--read-only]关闭强制整体只读,覆盖库内配置
--config-file ARG-集中指定 svnserve.conf(可指向库外公共文件)
-c [--compression] ARG5传输压缩级别 0-9
-M [--memory-cache-size] ARG16(MB)FSFS/FSX 内存缓存,0 为动态大小

生效验证(systemctl status 与端口):

# systemctl status svnserve --no-pager -l
● svnserve.service - Subversion protocol daemon (svnserve)
     Loaded: loaded (/etc/systemd/system/svnserve.service; enabled; vendor preset: enabled)
     Active: active (running) since Mon 2026-10-12 00:47:42 UTC; 1s ago
   Main PID: 4026 (svnserve)
      Tasks: 1 (limit: 5753)
     Memory: 1.0M
        CPU: 6ms
     CGroup: /system.slice/svnserve.service
             └─4026 /usr/bin/svnserve --daemon --foreground --root /srv/svn

# netstat -tlnp | grep 3690
tcp        0      0 0.0.0.0:3690            0.0.0.0:*               LISTEN      4026/svnserve

5.4 Apache dav_svn 指令

本机 /etc/apache2/mods-enabled/dav_svn.conf 实测生效内容:

<Location /svn>
    DAV svn
    SVNParentPath /srv/svn
    AuthType Basic
    AuthName "Subversion Repository"
    AuthUserFile /etc/svn/svn.htpasswd
    AuthzSVNAccessFile /etc/svn/authz
    Require valid-user
</Location>

逐项说明:

指令说明实测行为
DAV svn声明 Location 由 mod_dav_svn 处理缺失时 /svn 被当作普通路径 404
SVNParentPath /srv/svn多库父目录,URL 为 http://host/svn/<库名>curl 认证后返回库列表 HTML 索引;与 SVNPath 二选一
SVNPath /srv/svn/repo1单库模式,URL 直接映射该库单库部署时用,URL 不再含库名
AuthType Basic + AuthNameBasic 认证与提示域401 响应实测携带 WWW-Authenticate: Basic realm="Subversion Repository"
AuthUserFile /etc/svn/svn.htpasswdhtpasswd 生成的口令文件生成命令 htpasswd -cb /etc/svn/svn.htpasswd admin q1w2e3r4
AuthzSVNAccessFile /etc/svn/authz启用 mod_authz_svn 路径级授权文件格式与 5.2 相同,可跨库写 [repo1:/] 段
Require valid-user所有请求强制认证匿名请求实测 401

需要 Apache 以写权限访问版本库:Apache 运行用户为 www-data,将其加入版本库属主组并开组写权限(本机实测命令):

usermod -aG svn www-data
chown -R svn:svn /srv/svn/repo1
chmod -R g+rwX /srv/svn/repo1

配置修改后先校验再重启:

# apachectl configtest
Syntax OK
# systemctl restart apache2

💡 configtest 出现 AH00558: Could not reliably determine the server's fully qualified domain name 时不影响功能,属全局 ServerName 未设置;写入 conf-available/servername.conf 并 a2enconf 后消除。

5.5 客户端参数(~/.subversion 与 /etc/subversion)

首次执行 svn 命令后,客户端会在用户家目录生成 ~/.subversion/(实测含 README.txt、auth、config、servers 四项)。系统级默认文件在 /etc/subversion/(config、servers),全部参数以注释形式提供默认值,实测默认值:

# grep -E "^# ?(password-stores|store-passwords|store-auth-creds)" /etc/subversion/config
# password-stores = gpg-agent,gnome-keyring,kwallet
# store-passwords = no
# store-auth-creds = no

# grep -E "^# ?(http-timeout|http-compression)" /etc/subversion/servers
# http-timeout = 60
# http-compression = auto

常用客户端参数:

参数文件默认值说明
store-auth-credsconfigno是否把用户名/口令缓存到 ~/.subversion/auth
store-passwordsconfigno配合 store-auth-creds 控制口令是否明文落盘
password-storesconfiggpg-agent,gnome-keyring,kwallet凭据存储后端列表
http-timeoutservers60(秒)HTTP 类访问超时
http-compressionserversauto是否压缩 HTTP 传输

查看与清理已缓存凭据的实测回显:

# svn auth --username admin --password q1w2e3r4 --non-interactive
------------------------------------------------------------------------
Credential kind: svn.simple
Authentication realm: <http://127.0.0.1:80> Subversion Repository
Username: admin

------------------------------------------------------------------------
Credential kind: svn.simple
Authentication realm: <svn://127.0.0.1:3690> repo1
Username: admin

💡 realm 与 URL 共同决定缓存条目归属:svnserve 模式 realm 改名后旧缓存即失配,客户端会重新索要账号,这也是排障时"强制重新认证"的常用手段。

六、生产配置模板

6.1 svnserve 模式模板(适用:4 核 8GB 内存、千兆内网、10-50 人团队、库总量 100GB 以内)

# /srv/svn/repo1/conf/svnserve.conf
[general]
anon-access = none
auth-access = write
password-db = /srv/svn/passwd
authz-db = /srv/svn/authz
realm = repo1
# /srv/svn/passwd(多库共用)
[users]
admin = q1w2e3r4
# /srv/svn/authz(多库共用)
[groups]
dev = admin

[/]
@dev = rw
* =

[repo1:/trunk]
@dev = rw
# /etc/systemd/system/svnserve.service 的 [Service] 关键行
ExecStart=/usr/bin/svnserve --daemon --foreground --root /srv/svn --listen-host 0.0.0.0 --listen-port 3690 -M 64
Restart=on-failure
User=svn
Group=svn

模板说明:账号文件集中到 /srv/svn 便于多库共用;-M 64 把 FSFS 缓存从默认 16MB 提到 64MB,适配 8GB 内存下多库并发;生产务必保留 anon-access = none。

6.2 Apache WebDAV 模板(适用:需要浏览器浏览、HTTPS 与 LDAP/统一账号体系接入的场景)

<Location /svn>
    DAV svn
    SVNParentPath /srv/svn
    AuthType Basic
    AuthName "Subversion Repository"
    AuthUserFile /etc/svn/svn.htpasswd
    AuthzSVNAccessFile /etc/svn/authz
    Require valid-user
</Location>

配套:htpasswd -cb /etc/svn/svn.htpasswd admin q1w2e3r4;authz 同 6.1;上线前 apachectl configtest 必须 Syntax OK,再 systemctl restart apache2。

七、常见问题(FAQ)

Q1:改了 svnserve.conf / passwd / authz 不生效?

svnserve 模式下口令与授权按连接读取,改动即对"新连接"生效,已建立的连接不受影响;而改了进程参数(--listen-port 等)必须 systemctl restart svnserve。验证办法:重新 checkout 一条新连接看是否要求认证。WebDAV 模式改 dav_svn.conf 后必须 restart apache2。

Q2:svn: E170001: Can't get username or password 与 E170001: Authentication error from server: Password incorrect 分别是什么问题?

前者是匿名访问被拒(anon-access = none 且未带凭据),后者是账号存在但口令错误(实测回显见安装指南第七章)。解决:前者补 --username admin --password q1w2e3r4,后者核对 passwd 文件或重置口令。

Q3:authz 配置后仍能访问不该访问的路径?

按最长匹配路径取规则,且 * 会覆盖匿名语义:[/] 段写了 @dev = rw 但没写 * = 时,其他用户继承的是 svnserve.conf 的 anon-access 默认 read,等于全库可读。解决:每段显式写 * =(无权限)或 * = r,并用 svnauthz accessof --username 某用户 --path /目标路径 /srv/svn/authz 逐条核验(实测该命令输出 rw 或空)。

Q4:WebDAV 模式 401 后输入正确账号仍反复要求认证?

常见原因:AuthUserFile 路径写错或 htpasswd 文件对 Apache 不可读;realm 值改动后客户端缓存的凭据失配。解决:ls -l 核对文件与属主,必要时删除客户端 ~/.subversion/auth 下对应条目(或用 svn auth 列出后清理)重试。

Q5:svnserve 监听正常但远程连不上?

排查顺序:netstat 确认 0.0.0.0:3690 监听(实测回显见 5.3)→ 服务器防火墙放行 3690/tcp → --listen-host 是否误绑了内网地址 → authz 是否把来源用户写成了无权限(表现为连接成功但访问被拒,用 5.2 的 svnauthz accessof 核验)。

八、参考链接