目标
在同一台主机建立站点并访问,自建CA为该站颁发证书,使得在火狐浏览器访问该站时锁标识为绿色。
前提
- 已安装 apache 和 openssl
- ubuntu 自带 apache 和 openssl
- 可使用以下命令查看二者的版本,若需更新查看该链接
apache2 -version
openssl version
- 本文使用 apache 2.2.22 和 openssl 1.0.1
实现
使用OpenSSL自建CA
注意,本阶段操作均在普通用户权限下进行。
1.1 创建工作环境
cd && mkdir -p myCA/signedcerts && mkdir myCA/private && cd myCA
1.2 创建证书数据库
echo '01' > serial && touch index.txt
1.3 创建 ca 配置文件
sudo nano ~/myCA/caconfig.cnf
其内容如下:
# My sample caconfig.cnf file.
#
# Default configuration to use when one is
not provided on the command line.
#
[ ca ]
default_ca = local_ca
#
#
# Default location of directories and files
needed to generate certificates.
#
[ local_ca ]
dir = /home/<username>/myCA
certificate = $dir/cacert.pem
database = $dir/index.txt
new_certs_dir = $dir/signedcerts
private_key = $dir/private/cakey.pem
serial = $dir/serial
#
#
# Default expiration and encryption policies
for certificates.
#
default_crl_days = 365
default_days = 1825
default_md = sha1
#
policy = local_ca_policy
x509_extensions = local_ca_extensions
#
#
# Copy extensions specified in the
certificate request
#
copy_extensions = copy
#
#
# Default policy to use when generating
server certificates. The following
# fields must be defined in the server
certificate.
#
[ local_ca_policy ]
commonName = supplied
stateOrProvinceName = supplied
countryName = supplied
emailAddress = supplied
organizationName = supplied
organizationalUnitName = supplied
#
#
# x509 extensions to use when generating
server certificates.
#
[ local_ca_extensions ]
basicConstraints = CA:false
#
#
# The default root certificate generation
policy.
#
[ req ]
default_bits = 2048
default_keyfile =
/home/<username>/myCA/private/cakey.pem
default_md = sha1
#
prompt = no
distinguished_name =
root_ca_distinguished_name
x509_extensions = root_ca_extensions
#
#
# Root Certificate Authority distinguished
name. Change these fields to match
# your local environment!
#
[ root_ca_distinguished_name ]
commonName = MyOwn Root
Certificate Authority
stateOrProvinceName = NC
countryName = US
emailAddress =
[email protected]
organizationName = Trade Show Hell
organizationalUnitName = IT Department
#
[ root_ca_extensions ]
basicConstraints = CA:true
注意:
- [ local_ca ] 和 [ req ] 下 /home/<username> 的 <username> 必须修改为 myCA 文件夹的上级文件夹。
- [ root_ca_distinguished_name ] 下的信息可根据需要修改,其中 countryName 最多包含2个字符。
生成CA根证书以及公私钥对
2.1 设置环境变量
export OPENSSL_CONF=~/myCA/caconfig.cnf
注意:本阶段所有操作均在普通用户的权限下,如果使用 root 权限,则该路径需要修改为 /myCA/caconfig.cnf 的全路径,否则报错。
2.2 生成CA证书以及公私钥对
openssl req -x509 -newkey rsa:2048 -out cacert.pem -outform PEM -days 1825
显示如下:
Generating a 2048 bit RSA private key
.................................+++
.................................................................................................+++
writing new private key to '/home/bshumate/myCA/private/cakey.pem'
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----
密码不可过短,否则报错。
其中:
- ~/myCA/cacert.pem 为 CA public certificate
- ~/myCA/private/cakey.pem 为 CA private key
颁发证书
3.1 新建 ~/myCA/exampleserver.cnf,内容如下:
#
# exampleserver.cnf
#
[ req ]
prompt = no
distinguished_name = server_distinguished_name
req_extensions = v3_req
[ server_distinguished_name ]
commonName = tradeshowhell.com
stateOrProvinceName = NC
countryName = US
emailAddress = [email protected]
organizationName = My Organization Name
organizationalUnitName = Subunit of My Large Organization
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names
[ alt_names ]
DNS.0 = tradeshowhell.com
DNS.1 = alt.tradeshowhell.com
由于本文为实现在同一台主机建立站点并访问,因此将其修改为:
#
# exampleserver.cnf
#
[ req ]
prompt = no
distinguished_name = server_distinguished_name
req_extensions = v3_req
[ server_distinguished_name ]
commonName = localhost
stateOrProvinceName = NC
countryName = US
emailAddress = farsight@localhost
organizationName = My Organization Name
organizationalUnitName = Subunit of My Large Organization
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
# subjectAltName = @alt_names
[ alt_names ]
# DNS.0 = tradeshowhell.com
# DNS.1 = alt.tradeshowhell.com
3.2 设置环境变量
export OPENSSL_CONF=~/myCA/exampleserver.cnf
3.3 生成站点证书以及公私钥对
openssl req -newkey rsa:1024 -keyout tempkey.pem -keyform PEM -out tempreq.pem -outform PEM
显示如下:
Generating a 1024 bit RSA private key
...++++++
...............++++++
writing new private key to 'tempkey.pem'
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----
3.4 将 temporary private key 翻译为 unencrypted key
openssl rsa < tempkey.pem > server_key.pem
使用 CA 的钥匙为站点的证书签名
4.1 设置环境变量
export OPENSSL_CONF=~/myCA/caconfig.cnf
4.2 签名
openssl ca -in tempreq.pem -out server_crt.pem
显示如下:
Using configuration from /home/bshumate/myCA/caconfig.cnf
Enter pass phrase for /home/bshumate/myCA/private/cakey.pem:
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
commonName :PRINTABLE:'tradeshowhell.com'
stateOrProvinceName :PRINTABLE:'NC'
countryName :PRINTABLE:'US'
emailAddress :IA5STRING:'[email protected]'
organizationName :PRINTABLE:'Trade Show Hell'
organizationalUnitName:PRINTABLE:'Black Ops'
Certificate is to be certified until Jan 4 21:50:08 2011 GMT (1825 days)
Sign the certificate? [y/n]:y
1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
其中:
- server_crt.pem 为 Server application certificate file
- server_key.pem 为 Server application key file
建立站点并进行测试
新建ssl配置文件
sudo nano /etc/apache2/sites-available/lab-ssl.conf
内容如下:
<IfModule mod_ssl.c>
<VirtualHost _default_:443>
ServerAdmin webmaster@localhost
DocumentRoot /var/www/lab
# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
# error, crit, alert, emerg.
# It is also possible to configure the loglevel for particular
# modules, e.g.
#LogLevel info ssl:warn
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
# For most configuration files from conf-available/, which are
# enabled or disabled at a global level, it is possible to
# include a line for only one particular virtual host. For example the
# following line enables the CGI configuration for this host only
# after it has been globally disabled with "a2disconf".
#Include conf-available/serve-cgi-bin.conf
# SSL Engine Switch:
# Enable/Disable SSL for this virtual host.
SSLEngine on
# A self-signed (snakeoil) certificate can be created by installing
# the ssl-cert package. See
# /usr/share/doc/apache2/README.Debian.gz for more info.
# If both key and certificate are stored in the same file, only the
# SSLCertificateFile directive is needed.
#SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem
#SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
SSLCertificateFile /home/farsight/myCA/server_crt.pem
SSLCertificateKeyFile /home/farsight/myCA/server_key.pem
# Server Certificate Chain:
# Point SSLCertificateChainFile at a file containing the
# concatenation of PEM encoded CA certificates which form the
# certificate chain for the server certificate. Alternatively
# the referenced file can be the same as SSLCertificateFile
# when the CA certificates are directly appended to the server
# certificate for convinience.
#SSLCertificateChainFile /etc/apache2/ssl.crt/server-ca.crt
# Certificate Authority (CA):
# Set the CA certificate verification path where to find CA
# certificates for client authentication or alternatively one
# huge file containing all of them (file must be PEM encoded)
# Note: Inside SSLCACertificatePath you need hash symlinks
# to point to the certificate files. Use the provided
# Makefile to update the hash symlinks after changes.
#SSLCACertificatePath /etc/ssl/certs/
#SSLCACertificateFile /etc/apache2/ssl.crt/ca-bundle.crt
# Certificate Revocation Lists (CRL):
# Set the CA revocation path where to find CA CRLs for client
# authentication or alternatively one huge file containing all
# of them (file must be PEM encoded)
# Note: Inside SSLCARevocationPath you need hash symlinks
# to point to the certificate files. Use the provided
# Makefile to update the hash symlinks after changes.
#SSLCARevocationPath /etc/apache2/ssl.crl/
#SSLCARevocationFile /etc/apache2/ssl.crl/ca-bundle.crl
# Client Authentication (Type):
# Client certificate verification type and depth. Types are
# none, optional, require and optional_no_ca. Depth is a
# number which specifies how deeply to verify the certificate
# issuer chain before deciding the certificate is not valid.
#SSLVerifyClient require
#SSLVerifyDepth 10
# SSL Engine Options:
# Set various options for the SSL engine.
# o FakeBasicAuth:
# Translate the client X.509 into a Basic Authorisation. This means that
# the standard Auth/DBMAuth methods can be used for access control. The
# user name is the `one line' version of the client's X.509 certificate.
# Note that no password is obtained from the user. Every entry in the user
# file needs this password: `xxj31ZMTZzkVA'.
# o ExportCertData:
# This exports two additional environment variables: SSL_CLIENT_CERT and
# SSL_SERVER_CERT. These contain the PEM-encoded certificates of the
# server (always existing) and the client (only existing when client
# authentication is used). This can be used to import the certificates
# into CGI scripts.
# o StdEnvVars:
# This exports the standard SSL/TLS related `SSL_*' environment variables.
# Per default this exportation is switched off for performance reasons,
# because the extraction step is an expensive operation and is usually
# useless for serving static content. So one usually enables the
# exportation for CGI and SSI requests only.
# o OptRenegotiate:
# This enables optimized SSL connection renegotiation handling when SSL
# directives are used in per-directory context.
#SSLOptions +FakeBasicAuth +ExportCertData +StrictRequire
<FilesMatch "\.(cgi|shtml|phtml|php)$">
SSLOptions +StdEnvVars
</FilesMatch>
<Directory /usr/lib/cgi-bin>
SSLOptions +StdEnvVars
</Directory>
# SSL Protocol Adjustments:
# The safe and default but still SSL/TLS standard compliant shutdown
# approach is that mod_ssl sends the close notify alert but doesn't wait for
# the close notify alert from client. When you need a different shutdown
# approach you can use one of the following variables:
# o ssl-unclean-shutdown:
# This forces an unclean shutdown when the connection is closed, i.e. no
# SSL close notify alert is send or allowed to received. This violates
# the SSL/TLS standard but is needed for some brain-dead browsers. Use
# this when you receive I/O errors because of the standard approach where
# mod_ssl sends the close notify alert.
# o ssl-accurate-shutdown:
# This forces an accurate shutdown when the connection is closed, i.e. a
# SSL close notify alert is send and mod_ssl waits for the close notify
# alert of the client. This is 100% SSL/TLS standard compliant, but in
# practice often causes hanging connections with brain-dead browsers. Use
# this only for browsers where you know that their SSL implementation
# works correctly.
# Notice: Most problems of broken clients are also related to the HTTP
# keep-alive facility, so you usually additionally want to disable
# keep-alive for those clients, too. Use variable "nokeepalive" for this.
# Similarly, one has to force some clients to use HTTP/1.0 to workaround
# their broken HTTP/1.1 implementation. Use variables "downgrade-1.0" and
# "force-response-1.0" for this.
# BrowserMatch "MSIE [2-6]" \
# nokeepalive ssl-unclean-shutdown \
# downgrade-1.0 force-response-1.0
</VirtualHost>
</IfModule>
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
启动ssl服务
a2ensite # 选择lab-ssl
a2enmod ssl
将CA证书导入浏览器
注意:选择 cacert.pem 而非 .crt
测试
在浏览器地址栏输入 https://localhost
注意:输入 https 而非 http
显示如下:
参考链接:
ubuntu 的官方帮助文档,https://help.ubuntu.com/community/OpenSSL#SSL_Certificates