- 博客/
httpd+svn服务器部署
本文主要介绍https双向认证httpd + 用户Basic Authorization + svn的部署
安装配置svn#
[root@test] ~$ yum -y install subversion
[root@test] ~$ mkdir /data/repos
创建一个仓库 myhub
[root@test] repos$ svnadmin create /data/repos/myhub
[root@test] repos$ cd /data/repos/myhub
[root@test] myhub$ ls
conf db format hooks locks README.txt
配置svn
[root@test] myhub$ cd conf/
[root@test] conf$ ls
authz passwd svnserve.conf
[root@test] conf$ grep -v "^#\|^$" svnserve.conf
[general]
anon-access = none
auth-access = write
password-db = httpdPasswd
authz-db = authz
realm = myhub
[sasl]
- anon-access: 匿名用户访问仓库的权限,取值范围为 “write”,“read”,“none”
- auth-access:认证用户访问仓库的权限,取值范围为 “write”,“read”,“none”
- password-db: 用户认证密码库文件
- authz-db: 基于路径的访问权限控制的规则库文件
- realm: 登录svn时提示的认证域名称,如果两个仓库使用相同的认证域,那么认证密码库文件应该一致,反之亦然
配置lisa用户有读写权限,并创建认证密码库文件
[root@test] conf$ grep -v "^#\|^$" authz
[aliases]
[groups]
[/]
lisa = rw
[myhub:/]
lisa = rw
[root@test] conf$ htpasswd -c -m httpdPasswd lisa
New password:
Re-type new password:
Adding password for user lisa
启动svn
[root@test] conf$ cat /etc/sysconfig/svnserve
# OPTIONS is used to pass command-line arguments to svnserve.
#
# Specify the repository location in -r parameter:
OPTIONS="-r /data/repos --listen-host 127.0.0.1 --listen-port 3690"
[root@test] conf$ systemctl start svnserve
httpd配置#
安装httpd及模块#
[root@test] ~$ yum install -y httpd mod_ssl mod_dav_svn
[root@test] ~$ httpd -t -D DUMP_MODULES|grep -E "ssl|svn"
ssl_module (shared)
dav_svn_module (shared)
authz_svn_module (shared)
自签名CA根证书#
[root@test] cert$ pwd
/data/cert
# 创建CA根证书私钥
[root@test] cert$ openssl genrsa -out root_ca.key 2048
Generating RSA private key, 2048 bit long modulus
.....................+++
.+++
e is 65537 (0x10001)
[root@test] cert$ cat openssl.cnf
[ req ]
# 证书主体的各属性信息使用的section配置,如通用名(CN)、组织单位(OU)
distinguished_name = req_distinguished_name
# 创建自签名证书请求时,使用扩展section配置
x509_extensions = v3_ca
[req_distinguished_name]
[v3_ca]
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
# basicConstraints 指证书的基本约束(基本限制)扩展字段
# 该证书具备签发其他证书的能力,可以作为CA证书使用
basicConstraints = CA:true
# X509证书签发时使用的v3扩展section配置,For Server
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth, clientAuth
# 证书主体CN别名使用的section配置
subjectAltName = @mysvn
[ mysvn ]
DNS.1 = ffu.com
IP.1 = 192.168.83.127
# X509证书签发时使用的扩展section配置,For Client
[ usr_cert ]
basicConstraints=CA:true
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
# 创建CA根证书
[root@test] cert$ openssl req -x509 -new -nodes -key root_ca.key -subj "/CN=FFU ROOT CA" -days 36500 -config openssl.cnf -out root_ca.crt
[root@test] cert$ openssl x509 -in root_ca.crt -noout -text -certopt no_validity,no_sigdump,no_pubkey,no_serial
Certificate:
Data:
Version: 3 (0x2)
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN=FFU ROOT CA
Subject: CN=FFU ROOT CA
X509v3 extensions:
X509v3 Subject Key Identifier:
X509v3 Authority Key Identifier:
X509v3 Basic Constraints:
CA:TRUE
服务端证书生成#
# 创建服务端证书私钥
[root@test] cert$ openssl genrsa -out server.key 2048
Generating RSA private key, 2048 bit long modulus
......+++
.....+++
e is 65537 (0x10001)
# 创建服务端证书请求文件
[root@test] cert$ openssl req -new -key server.key -out server.csr -config openssl.cnf -subj "/CN=*.mysvn.com"
openssl x509签发#
opessl x509 -req
命令可以签发证书,但是没有维护历史签发证书记录,也不支持吊销证书
# 签发服务器证书
# -extfile openssl.cnf: 指定包含扩展配置的文件名
# -extensions v3_req: 指定使用扩展配置中的v3_req扩展来生成证书
[root@test] cert$ openssl x509 -req -in server.csr -CA root_ca.crt -CAkey root_ca.key -CAcreateserial -out server.crt -days 36500 -extensions v3_req -extfile openssl.cnf
Signature ok
subject=/CN=*.mysvn.com
Getting CA Private Key
[root@test] cert$ openssl x509 -in server.crt -noout -text -certopt no_header,no_version,no_serial,no_signame,no_validity,no_pubkey,no_sigdump,no_aux
Issuer: CN=FFU ROOT CA
Subject: CN=*.mysvn.com
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
X509v3 Key Usage:
Digital Signature, Non Repudiation, Key Encipherment
X509v3 Subject Alternative Name:
DNS:mysvn.com, IP Address:192.168.83.127
openssl ca签发#
openssl ca
命令根据指定配置文件中[ ca ]
的相关配置项,维护本地签发证书的索引数据库,便于管理,也支持吊销证书
openssl.cnf
文件新增配置,如下
[root@test] cert$ mkdir /data/cert/myCA && cd myCA
[root@test] cert$ cat myCA/openssl.cnf
# openss ca命令使用的配置section
[ ca ]
default_ca = CA_default
[ CA_default ]
# 工作目录
dir = .
# 签发证书存放目录
certs = $dir/certs
# 吊销证书列表文件存放目录
crl_dir = $dir/crl
# 签发证书索引数据库
database = $dir/index.txt
# 证书的subject是否保证唯一性
unique_subject = no
# 证书tmp目录,默认文件名为[serialnumber.pem]
new_certs_dir = $dir/newcerts
# CA根证书文件
certificate = $dir/root_ca.crt
# 当前可用的证书序列号
serial = $dir/serial
# 当前可用的吊销证书列表序列号
crlnumber = $dir/crlnumber
# 吊销证书列表文件
crl = $dir/crl.pem
# CA根证书私钥
private_key = $dir/private/root_ca.key
RANDFILE = $dir/private/.rand
# 默认x509扩展的section配置
x509_extensions = usr_cert
name_opt = ca_default
cert_opt = ca_default
# 吊销证书列表使用的扩展的section配置
# Netscape communicator旧版本不支持X.509标准新增的CR V2规范
# crlnumber和crl_extensions需要都注释才是V1 CRL
crl_extensions = crl_ext
# 签发证书默认有效期天数
default_days = 365
# 吊销证书列表默认有效期天数
default_crl_days= 30
# 默认加密算法
default_md = sha256
# 是否对subject的各属性重新排序,建议配置
preserve = no
# subject的各属性设置的策略
policy = policy_anything
# optional 可选设置项
# supplied 必须设置项
[ policy_anything ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
[ req ]
# 证书主体的各属性信息使用的section配置,如通用名(CN)、组织单位(OU)
distinguished_name = req_distinguished_name
# 创建自签名证书请求时,使用扩展section配置
x509_extensions = v3_ca
[req_distinguished_name]
[v3_ca]
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
# basicConstraints 指证书的基本约束(基本限制)扩展字段
# 该证书具备签发其他证书的能力,可以作为CA证书使用
basicConstraints = CA:true
# X509证书签发时使用的v3扩展section配置,For Server
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth, clientAuth
# 证书主体CN别名使用的section配置
subjectAltName = @mysvn
#根据需求配置
[ mysvn ]
DNS.1 = ffu.com
IP.1 = 192.168.83.127
# X509证书签发时使用的扩展section配置,For Client
[ usr_cert ]
basicConstraints=CA:FALSE
#keyUsage = nonRepudiation, digitalSignature, keyEncipherment
#nsComme = "OpenSSL Generated Certificate"
# CRL扩展section配置
[ crl_ext ]
# issuerAltName=issuer:copy
authorityKeyIdentifier=keyid:always
签发证书
[root@test] cert$ cp -r /etc/pki/CA/* myCA/
[root@test] cert$ cp root_ca.crt myCA/
[root@test] cert$ cp root_ca.key myCA/private/
[root@test] cert$ cp server.key myCA/private/
# 生成证书索引数据库文件
[root@test] myCA$ touch index.txt
# 指定第一个签发证书的序列号,十六进制,签发后序列号自动增加
[root@test] myCA$ echo 01 > serial
[root@test] myCA$ openssl req -new -key private/server.key -out server.csr -config openssl.cnf -subj "/CN=*.ffu.com"
# -extensions 使用openssl.cnf中[ v3_req ]section配置
[root@test] myCA$ openssl ca -config openssl.cnf -in server.csr -out certs/server.crt -days 365 -extensions v3_req -batch
Using configuration from openssl.cnf
Check that the request matches the signature
Signature ok
Certificate Details:
Serial Number: 1 (0x1)
Validity
Not Before: Feb 6 07:37:58 2020 GMT
Not After : Feb 5 07:37:58 2021 GMT
Subject:
commonName = *.ffu.com
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
X509v3 Key Usage:
Digital Signature, Non Repudiation, Key Encipherment
X509v3 Subject Alternative Name:
DNS:ffu.com, IP Address:192.168.83.127
Certificate is to be certified until Feb 5 07:37:58 2021 GMT (365 days)
Write out database with 1 new entries
Data Base Updated
# 索引库文件已更新
[root@test] myCA$ cat index.txt
V 210205072251Z 01 unknown /CN=*.ffu.com
# 目录结构
[root@test] myCA$ tree
.
├── certs
│ └── server.crt
├── crl
├── crlnumber
├── index.txt
├── index.txt.attr
├── index.txt.old
├── newcerts
│ └── 01.pem
├── openssl.cnf
├── private
│ ├── root_ca.key
│ └── server.key
├── root_ca.crt
├── serial
├── serial.old
└── server.csr
客户端证书生成#
[root@test] myCA$ openssl genrsa -out private/client.key 2048
Generating RSA private key, 2048 bit long modulus
..................+++
.......................+++
e is 65537 (0x10001)
[root@test] myCA$ openssl req -new -key private/client.key -out client.csr -config openssl.cnf -subj "/CN=svn_client"
[root@test] myCA$ openssl ca -config openssl.cnf -in client.csr -out certs/client.crt -days 365 -batch
Using configuration from openssl.cnf
Check that the request matches the signature
Signature ok
Certificate Details:
Serial Number: 2 (0x2)
Validity
Not Before: Feb 6 07:39:46 2020 GMT
Not After : Feb 5 07:39:46 2021 GMT
Subject:
commonName = svn_client
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
Certificate is to be certified until Feb 5 07:39:46 2021 GMT (365 days)
Write out database with 1 new entries
Data Base Updated
[root@test] myCA$ cat index.txt
V 210205073758Z 01 unknown /CN=*.ffu.com
V 210205073946Z 02 unknown /CN=svn_client
# 创建PKCS12格式的证书文件,需要下发给客户端
[root@test] myCA$ openssl pkcs12 -export -clcerts -in certs/client.crt -inkey private/client.key -out certs/client.p12
Enter Export Password:
Verifying - Enter Export Password:
修改配置#
配置文件/etc/httpd/conf/httpd.conf
# 注释http监听端口
# Listen 80
# 新增一个全局默认ServerName
ServerName 127.0.0.1
# 新增SSLRequireSSL
<Directory />
AllowOverride none
SSLRequireSSL
Require all denied
</Directory>
# 新增
TraceEnable off
ServerSignature Off
ServerTokens Prod
ssl配置
[root@test] repos$ cd /etc/httpd/
[root@test] httpd$ mkdir -p cert/crl
[root@test] httpd$ cd cert/
[root@test] cert$ cp /data/cert/server.key .
[root@test] cert$ cp /data/cert/server.crt .
[root@test] cert$ cp /data/cert/root_ca.crt .
# 配置文件/etc/httpd/conf.d/ssl.conf
# 监听所有网卡
<VirtualHost *:443>
# 虚拟主机匹配的域名
ServerName mysvn.ffu.com
ServerAlias 192.168.83.127:443
# 服务端公私钥
SSLCertificateFile /etc/httpd/cert/server.crt
SSLCertificateKeyFile /etc/httpd/cert/server.key
# 开启客户端证书验证, 按需配置
SSLCACertificateFile /etc/httpd/cert/root_ca.crt
SSLVerifyClient require
SSLVerifyDepth 10
SSLCARevocationCheck chain
SSLCARevocationFile "/etc/httpd/cert/crl/crl.pem"
因为当前httpd版本不支持参数no_crl_for_cert_ok
,可以生成一个不包含吊销证书列表的CRL文件,避免httpd报错
Optional flags available in httpd 2.4.21 or later
openssl.cnf中配置了CRL默认有效期default_crl_days= 30
,需要及时更新crl.pem
并reload httpd服务。如果crl.pem
过期,请求httpd会报错
也可以通过命令行参数-crldays
指定有效期
[root@test] myCA$ openssl ca -gencrl -out crl/crl.pem -config openssl.cnf -crldays 365
[root@test] myCA$ cp crl/crl.pem /etc/httpd/cert/crl/
[root@test] myCA$ openssl crl -in crl/crl.pem -noout -text
Certificate Revocation List (CRL):
Version 2 (0x1)
Signature Algorithm: sha256WithRSAEncryption
Issuer: /CN=FFU ROOT CA
Last Update: Feb 7 06:30:52 2020 GMT
Next Update: Feb 6 06:30:52 2021 GMT
CRL extensions:
X509v3 CRL Number:
1
No Revoked Certificates.
SVN配置文件
[root@test] conf.d$ cat /etc/httpd/conf.d/subversion.conf
<Location />
DAV svn
SVNListParentPath off
SVNParentPath /data/repos/
# Limit write permission to list of valid users.
AuthType Basic
AuthName "Authorization Realm"
#用户认证密码库文件
AuthUserFile /data/repos/myhub/conf/httpdPasswd
AuthzSVNAccessFile /data/repos/myhub/conf/authz
Satisfy all
SVNAutoversioning on
ModMimeUsePathInfo on
Require valid-user
Order Deny,Allow
Allow from 192.168.83.0/24
Deny from all
</Location>
<Location ~ "\.svn">
Order Deny,Allow
Deny from all
</Location>
[root@test] conf.d$ httpd -t
Syntax OK
[root@test] repos$ chown apache:apache /data/repos/myhub -R
[root@test] conf.d$ systemctl start httpd
svn客户端访问#
以下配置适用linux或者macos客户端访问
修改svn客户端配置文件~/.subversion/server
[groups]
myhub = 192.168.83.127
[myhub]
store-ssl-client-cert-pp = yes
# 明文客户端秘钥包密码不保存本地
store-ssl-client-cert-pp-plaintext = no
store-passwords = yes
# 明文用户密码不保存本地
store-plaintext-passwords = no
# 服务器https双向认证时,客户端秘钥包文件
ssl-client-cert-file = /root/.subversion/myhub/client.p12
# 服务器证书的CA
ssl-authority-files = /root/.subversion/myhub/root_ca.crt
[root@node2] ~/.subversion/myhub$ ls
client.p12 root_ca.crt
拉取SVNmyhub
库到本地,第一次登录需要输入密码,如果配置了保存密码,下次登录不需要再次输入
[root@node2] /data$ svn checkout https://192.168.83.127/myhub --username=lisa
“/root/.subversion/myhub/client.p12”的密码:
认证领域: <https://192.168.83.127:443> Authorization Realm
“lisa”的密码:
取出版本 0。
[root@node2] /data$ cd myhub/
[root@node2] /data$ touch test
[root@node2] /data/myhub$ svn status
? test
[root@node2] /data/myhub$ svn add test
A test
[root@node2] /data/myhub$ svn status
A test
[root@node2] /data/myhub$ svn ci -m "add test file"
正在增加 test
传输文件数据.
提交后的版本为 1。
[root@node2] /data/myhub$ svn update
正在升级 '.':
版本 1。
[root@node2] /data/myhub$ svn log
------------------------------------------------------------------------
r1 | lisa | 2020-05-06 21:17:47 +0800 (二, 2020-05-06) | 1 行
add test file
------------------------------------------------------------------------
客户端证书的吊销#
客户端pcks12证书可能会泄露,如果遇到这种情况,需要服务器拒绝其访问。可以通过openssl ca -revoke
命令吊销客户端证书,并更新httpd配置的crl.pem文件
以上文lisa用户的客户端证书为例
吊销旧证书#
[root@test] ~$ cd /data/cert/myCA
[root@test] myCA$ openssl ca -revoke certs/client.crt -config openssl.cnf
Using configuration from openssl.cnf
Revoking Certificate 02.
Data Base Updated
[root@test] myCA$ cat index.txt
V 210205073758Z 01 unknown /CN=*.ffu.com
R 210205073946Z 200207065105Z 02 unknown /CN=svn_client
[root@test] myCA$ openssl ca -gencrl -out crl/crl.pem -config openssl.cnf -crldays 365
Using configuration from openssl.cnf
[root@test] myCA$ openssl crl -in crl/crl.pem -noout -text
Certificate Revocation List (CRL):
Version 2 (0x1)
Signature Algorithm: sha256WithRSAEncryption
Issuer: /CN=FFU ROOT CA
Last Update: Feb 7 06:53:00 2020 GMT
Next Update: Feb 6 06:53:00 2021 GMT
CRL extensions:
X509v3 CRL Number:
2
Revoked Certificates:
Serial Number: 02
Revocation Date: Feb 7 06:51:05 2020 GMT
[root@test] myCA$ cp crl/crl.pem /etc/httpd/cert/crl/
[root@test] myCA$ httpd -t
Syntax OK
[root@test] myCA$ httpd -k graceful
客户端使用旧证书client.p12访问失败
[root@node2] /data/myhub$ svn list
svn: E175002: Unable to connect to a repository at URL 'https://192.168.83.127/myhub'
svn: E175002: 方法 OPTIONS 失败于 “https://192.168.83.127/myhub”: SSL handshake failed: 收到 SSL 警报: 证书已吊销 (https://192.168.83.127)
签发新证书#
[root@test] myCA$ openssl genrsa -out private/new_client.key 2048
Generating RSA private key, 2048 bit long modulus
............................................................................................................+++
...................................+++
e is 65537 (0x10001)
[root@test] myCA$ openssl req -new -key private/new_client.key -out new_client.csr -config openssl.cnf -subj "/CN=svn_client"
[root@test] myCA$ openssl ca -config openssl.cnf -in new_client.csr -out certs/new_client.crt -days 365 -batch
Using configuration from openssl.cnf
Check that the request matches the signature
Signature ok
Certificate Details:
Serial Number: 3 (0x3)
Validity
Not Before: Feb 7 07:02:18 2020 GMT
Not After : Feb 6 07:02:18 2021 GMT
Subject:
commonName = svn_client
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
Certificate is to be certified until Feb 6 07:02:18 2021 GMT (365 days)
Write out database with 1 new entries
Data Base Updated
[root@test] myCA$ openssl pkcs12 -export -clcerts -in certs/new_client.crt -inkey private/new_client.key -out certs/new_client.p12
Enter Export Password:
Verifying - Enter Export Password:
客户端拿到new_client.p12
后访问
[root@node2] ~$ cd ~/.subversion/myhub
root@node2] ~/.subversion/myhub$ mv new_client.p12 client.p12
[root@node2] ~/.subversion/myhub$ cd /data/myhub/
[root@node2] /data/myhub$ svn list
test