VisualSVN自签SSL证书导致svn客户端coredump或不能永久接受证书

VisualSVN Server 自签 OpenSSL 证 书bug 导致 Linux、AIX 的 svn 客户端 coredump 或不能永久接受证书。

VisualSVN 默认使用 https 协议访问 svn 库,早在 2012 年初的 VisualSVN Server 2.5 就曾出现过 ssl 证书的 bug,导致 Linux 的 svn 客户端不能连上 Windows 的 VisualSVN 服务器。

英文错误信息如下:

1
2
svn: OPTIONS of 'https://192.168.100.59/svn/repo': SSL handshake failed: SSL error:
Key usage violation in certificate has been detected. (https://192.168.100.59)

中文错误信息如下:

1
2
svn: 方法 OPTIONS 失败于 “https://192.168.100.59/svn/repo”: SSL handshake failed: SSL 错误:
在证书中检测到违规的密钥用法。 (https://192.168.100.59)

错误原因是 Windows 使用的证书 Linux 不能识别。改正方法是修改服务器上 VisualSVN 使用的证书为第三方产生的证书,以便 Windows 和 Linux 都能识别。

官方解决如下:
https://www.visualsvn.com/support/topic/00056/
需要导入注册表信息并重新生产证书。
1. Add the following registry value to the Windows registry:
for 32-bit system:

1
2
[HKEY_LOCAL_MACHINE\SOFTWARE\VisualSVN\VisualSVN Server]
"CreateGnuTLSCompatibleCertificate"=dword:00000001

for 64-bit system:

1
2
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\VisualSVN\VisualSVN Server]
"CreateGnuTLSCompatibleCertificate"=dword:00000001

2. Start VisualSVN Server Manager.
3. Go to Action | Properties | Certificate.
4. Click Change certificate… and follow the wizard instructions to generate a new self-signed certificate.

The certificate will be generated without the ‘Key Usage’ extension and will be compatible both with GnuTLS and OpenSSL.

再次执行 svn ls,会提示证书生成者不受信赖的警告,选择永久接受即可。


但是!!!在2016年底出的 VisualSVN Server 3.5.6 版本依然有证书问题。

我使用的 AIX 7.1 系统,因为 ibm 网站出的 subversion-1.9.4-1.aix6.1.ppc.rpm 只能用 svn、file 协议,不带 https/http,又不想折腾编译,于是安装了 oss4aix、perzl.org 网站编译的 subversion 版本,测试了多个版本,除了 subversion 1.6.x 能正常使用,1.7.x、1.8.x 的版本 checkout 一个 https 的库,能连服务器,但总在最后证书验证后出错 Segmentation fault(coredump) 异常退出,根本找不到原因。

我需要新版本的 svn 客户端,这样就不会在每个文件夹下都生成 .svn 目录,能找到的最新版本为 oss4aix 网站的 subversion-1.8.10-2.aix5.3.ppc.rpm,安装后,我尝试从依赖库入手解决问题。既然是在证书验证部分报错,先替换 openssl 版本,没解决。

又想到 svn 1.8 之后用 serf 代替 neon 访问 https/http,我尝试更新安装serf-1.2.1-2.aix5.1.ppc.rpm 后,svn 客户端不再 Segmentation fault(coredump) 异常退出,可以检出文件了,但证书只能临时接受,无法永久保存,每次 svn update、svn list 都要提示一次证书错误信息,很心烦。

但也确认了 subversion 1.8.x 奔溃原因和 serf 版本有关。

网上搜到一句说“该错误是自签名证书在 subversion 1.8.8 中生成新类型的错误的结果,该错误在 1.3.4 之前的 serf 版本中未正确处理。”

用chrome 浏览器打开 https://192.168.100.59/svn/repo 也会提示“服务器的证书与网址不相符”,在VisualSVN 里重新生成证书问题依旧。

结合以前的证书bug,因此我认为根本原因还是 VisualSVN 的证书问题。

国外论坛也有无法永久保存证书的问题,但只是提出 Fix the certificate chain on the server,并没明确解决方法及根本原因。
Subversion Server SSL certificate verification failed: and other reason(s)
http://stackoverflow.com/questions/22108914/subversion-server-ssl-certificate-verification-failed-and-other-reasons

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$ svn update
Updating '.':
Error validating server certificate for 'https://192.168.100.59:443':
- The certificate is not issued by a trusted authority. Use the
fingerprint to validate the certificate manually!
- The certificate hostname does not match.
Certificate information:
- Hostname: 571458-tools1
- Valid: from Feb 28 23:57:35 2014 GMT until Feb 26 23:57:35 2024 GMT
- Issuer:
- Fingerprint: 55:3E:55:FD:4D:40:A4:1E:8A:1E:27:71:DD:D4:ED:8B:A3:9A:1D:EC
(R)eject, accept (t)emporarily or accept (p)ermanently? p
Error validating server certificate for 'https://192.168.100.59:443':
- The certificate has an unknown error.
Certificate information:
- Hostname: 571458-tools1
- Valid: from Feb 28 23:57:35 2014 GMT until Feb 26 23:57:35 2024 GMT
- Issuer:
- Fingerprint: 55:3E:55:FD:4D:40:A4:1E:8A:1E:27:71:DD:D4:ED:8B:A3:9A:1D:EC
(R)eject or accept (t)emporarily? t
(credentials dialogue)
At revision 46.

分析出原因,于是我在 AIX/Linux 下用 openssl 重新生成证书,问题解决!

生成证书的命令(脚本):
https://github.com/michaelliao/itranswarp.js/blob/master/conf/ssl/gencert.sh

1
2
3
4
5
6
7
8
9
#!/bin/sh
# create self-signed server certificate:
# 密钥长度改为2048位
DOMAIN=192.168.100.59
openssl genrsa -des3 -out $DOMAIN.key 2048
openssl req -new -subj /C=CN/ST=GuangDong/L=Zhuhai/O=oicu/OU=oicu/CN=$DOMAIN -key $DOMAIN.key -out $DOMAIN.csr
mv $DOMAIN.key $DOMAIN.origin.key
openssl rsa -in $DOMAIN.origin.key -out $DOMAIN.key
openssl x509 -req -days 3650 -in $DOMAIN.csr -signkey $DOMAIN.key -out $DOMAIN.crt

http://www.liaoxuefeng.com/article/0014189023237367e8d42829de24b6eaf893ca47df4fb5e000
为HTTPS准备的证书需要注意,创建的签名请求的CN必须与域名完全一致,否则无法通过浏览器验证。

最后把 crt 文件和无密码的 key 文件复制到 Windows 系统,修改 VisualSVN 自带的 apache 设置 conf/httpd.conf 文件:

1
2
3
4
5
ServerName "192.168.100.59:443"
# SSLCertificateFile certs/server.pem
# SSLCertificateKeyFile certs/server.pem
SSLCertificateFile certs/192.168.100.59.crt
SSLCertificateKeyFile certs/192.168.100.59.key

后记:
因为出错信息不同,我是在其他平台用 openssl 重新生成证书解决,后来才搜索到本文前部分的问题,尝试了改注册表后用 VisualSVN 重新生成 server.pem 证书的方法也能同样解决,这个方法较为简单不用改 httpd.conf 文件,只是 chrome 访问依旧会提示“服务器的证书与网址不相符”。