是否可以为 http 流量设置 SSH 密钥之类的东西,以便浏览器必须具有匹配的密钥才能访问?
答案1
你正在寻找的东西叫做相互 SSL 身份验证。
对于通常部署的 Web 服务器来说阿帕奇,以及通常部署的 SSL/TLS 实现开放式SSL,步骤如下:
与 一起分发的是一个方便的脚本openssl
,CA.sh
可以完成大部分工作。它的位置是特定于分布的。在 Debian 及其衍生版本中,您可以使用以下方式找到它:
# apt-file search CA.sh
openssl: /usr/lib/ssl/misc/CA.sh
RedHat 及其衍生品的(近似)等价物是:
# yum provides */CA
1:openssl-1.0.1e-4.fc18.x86_64 : Utilities from the general purpose cryptography library with TLS implementation
Repo : @updates
Matched from:
Filename : /etc/pki/tls/misc/CA
这是一个非常简单的 bash 脚本,可以简化管理 CA 所需的目录结构的创建(这在[ CA_default ]
openssl.cnf 部分中进行了描述)。我建议您使用它并查看代码以了解它实际上在做什么。
# ./CA.sh -help
usage: ./CA.sh -newcert|-newreq|-newreq-nodes|-newca|-sign|-verify
该脚本将使用 openssl.cnf 中提供的默认值,并且/或者您可以提供一个配置文件作为openssl $command
使用-config
开关的参数(如果不使用CA.sh
.该文件的位置openssl.cnf
也是特定于发行版的,您可以使用上面相同的命令来查找它。您想要的就是openssl
包装中提供的。
您可能需要修改以下部分:
[ CA_default ]
default_days = 365 # how long to certify for
default_crl_days= 30 # how long before next CRL
[ req ]
default_bits = 2048
[ req_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_default = AU
countryName_min = 2
countryName_max = 2
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = Some-State
localityName = Locality Name (eg, city)
0.organizationName = Organization Name (eg, company)
0.organizationName_default = Internet Widgits Pty Ltd
#1.organizationName = Second Organization Name (eg, company)
#1.organizationName_default = World Wide Web Pty Ltd
organizationalUnitName = Organizational Unit Name (eg, section)
#organizationalUnitName_default =
commonName = Common Name (e.g. server FQDN or YOUR name)
commonName_max = 64
emailAddress = Email Address
emailAddress_max = 64
- 生成CA
进行编辑openssl.cnf
以满足您的需求后,您可以生成 CA 证书。根据您是否需要由公认的第三方 CA 签署此 CA,您可以生成自签名 CA 或 CSR 以提交签名。
./CA.sh -newca
系统会以交互方式提示您提出一些问题,默认值将显示在方括号之间。您将在此处认出您修改的选项openssl.cnf
。
- 为服务器生成证书
您可以使用相同的脚本为服务器创建证书请求:
./CA.sh -newreq
再次,系统会提示你问几个问题,最重要的是证书的 Common Name,它必须与服务器 IP 的 DNS 可解析名称匹配(或者你可以使用其他方式,例如/etc/hosts
,不推荐,很难维护和扩展)
您将获得的是证书签名请求(简称CSR)。这将由您之前创建的证书颁发机构 (CA) 签名。
./CA.sh -sign
- 为客户端生成证书
重复创建 CSR 并让 CA 对其进行签名的步骤。执行此操作时,请密切注意如何填写“公用名称”、“组织”和“组织单位”字段,因为随后需要这些字段来配置服务器。
将客户端证书与其各自的私钥和 CA 证书一起分发的一种巧妙方法是使用 p12 捆绑包:
openssl pkcs12 -export -in Certificates/client.pem -inkey client.key -certfile CA.pem -out clientcert.p12
- 配置服务器
假设您所指的服务器是 Apache Web 服务器。获得服务器证书后,您可以配置适当的VHOST
内容来提供将受相互 SSL 身份验证保护的任何内容。一个例子就是phpmyadmin
虚拟主机。这是在 Apache 2.4 服务器上运行的,因此请不要按原样使用它,并仔细检查和测试它以适应您的需求。
Listen 443 https
<VirtualHost 120.120.120.120:443>
DocumentRoot "/srv/www/html"
ServerAdmin [email protected]
SSLCACertificateFile /etc/pki/CA/cacert.pem
SSLCertificateFile /etc/pki/tls/private/company.com/newcert.pem
SSLCertificateKeyFile /etc/pki/tls/private/company.com/newkey.pem
SSLCARevocationCheck chain
SSLCARevocationFile /etc/pki/CA/crl/crl.pem
SSLEngine on
SSLStrictSNIVHostCheck on
SSLVerifyClient require
SSLVerifyDepth 5
ServerName phpmyadmin.company.com
RewriteEngine on
RewriteCond %{REMOTE_ADDR} !^127\.0\.0\.1$
RewriteCond %{HTTPS} !=on
RewriteRule . - [F]
ErrorLog "|/usr/sbin/rotatelogs -L /var/log/httpd/foo/error.log -f /var/log/httpd/foo/error.log.%Y%m%d 86400"
CustomLog "|/usr/sbin/rotatelogs -L /var/log/httpd/foo/access.log -f /var/log/httpd/foo/access.log.%Y%m%d 86400" logstash_json
<Directory /usr/share/bar/>
Require ssl
Require ssl-verify-client
SSLRequireSSL
SSLOptions +FakeBasicAuth +StrictRequire
SSLRequire %{SSL_CIPHER_USEKEYSIZE} >= 256
SSLRequire %{SSL_CLIENT_S_DN_O} eq "Awesome Company" \
and %{SSL_CLIENT_S_DN_OU} eq "Development" \
and %{SSL_CLIENT_S_DN_CN} in {"John Doe", "Jane Doe"}
SSLRenegBufferSize 131072
</Directory>
</VirtualHost>
您可以根据需要使用任意数量的每个目录访问控制,重要的是显示的客户端证书必须符合指令所施加的限制SSLRequire
,即它们必须匹配组织、组织单位和通用名称条件(或其他条件)您认为合适的证书字段)。这些字段取自客户端证书。
- 生成证书吊销列表
为了能够撤销对客户端证书的访问,您需要生成 CRL。执行此操作的命令(前提是您位于 CA 目录结构的顶部):
openssl ca -config /path/to/openssl.cnf -gencrl -out crl/crl.pem
然后,您可以根据需要使用以下方式撤销客户端证书:
openssl ca -config /path/to/openssl.cnf -revoke clientcert.pem
参考:
答案2
是的,它称为“客户端证书身份验证”,通常与智能卡等一起使用。
良好运行可能会很复杂,具体取决于您想要的产品是什么。