信安实验一:自建CA搭建https
信安实验一:自建HTTPS
本机环境:Ubuntu 20.04.1,apache2 2.4.41,openssl 1.1.1f
自建CA
创建相应文件夹
- 创建根目录存放CA信息:
mkdir -p myCA
- 子目录保存签名证书的副本:
mkdir -p myCA/signedcerts
- 子目录保存私钥:
mkdir -p myCA/private
配置文件
- 在
myCA
下配置相关参数:echo '01'>serial && touch index.txt
-
touch
命令用于修改文件或者目录的时间属性,包括访问时间和修改时间,若文件不存在,系统会建立一个新的文件。我们平时用得最多的是通过touch创建一个空文件,实际上通过touch命令可以修改文件的atime、mtime,所以文件的真实访问时间和修改时间是可以被修改 -
echo
如果我们使用>重定向运算符,则如果文件不存在,则会创建新文件。如果文件存在,则删除原先的所有内容,然后将来自echo的输出添加到文件的开头。 -
echo
如果我们使用>>重定向运算符,则如果文件不存在,则会创建新文件。如果文件存在,则不会删除原先的所有内容,然后来自echo的输出将添加到文件的末尾。
- 创建文件:
vim ~/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 # 这里要将username替换为你的用户名
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 = SHA256
#
policy = local_ca_policy
x509_extensions = local_ca_extensions
#
#
# 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 ]
subjectAltName = DNS:localhost
basicConstraints = CA:false
nsCertType = server
#
#
# The default root certificate generation policy.
#
[ req ]
default_bits = 2048
default_keyfile = /home/<username>/myCA/private/cakey.pem # 这里要将username替换为你的用户名
default_md = SHA256
#
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 # CA机构名
stateOrProvinceName = JS # CA所在省份
countryName = CN # CA所在国家(仅限2个字符)
emailAddress = XXXX@XXX.com # 邮箱
organizationName = XXX #
organizationalUnitName = XXX #
#
[ root_ca_extensions ]
basicConstraints = CA:true
生成CA根证书和密钥
若无,则安装openssl:sudo apt-get install openssl
export OPENSSL_CONF=~/myCA/caconfig.cnf #该命令用于给环境变量 OPENSSL_CONF赋值为caconfig.cnf。
openssl req -x509 -newkey rsa:2048 -out cacert.pem -outform PEM -days 1825 #生成 CA 根证书和密钥
- req的基本功能主要有两个:生成证书请求和生成自签名证书。其他还有一些校验、查看请求文件等功能,示例会简单说明下。参数说明如下:
- [new/x509]
- 当使用-new选取的时候,说明是要生成证书请求,当使用x509选项的时候,说明是要生成自签名证书。
- [/key/newkey/keyout]
- key和newkey是互斥的,key是指定已有的密钥文件,而newkey是指在生成证书请求或者自签名证书的时候自动生成密钥,然后生成的密钥名称有keyout参数指定。
- 当指定newkey选项时,后面指定rsa:bits说明产生rsa密钥,位数由bits指定。指定dsa:file说明产生dsa密钥,file是指生成dsa密钥的参数文件(由dsaparam生成)
- [in/out/inform/outform/keyform]
- in选项指定证书请求文件,当查看证书请求内容或者生成自签名证书的时候使用
- out选项指定证书请求或者自签名证书文件名,或者公钥文件名(当使用pubkey选项时用到),以及其他一些输出信息。
- inform、outform、keyform分别指定了in、out、key选项指定的文件格式,默认是PEM格式。
- [config]
- 参数文件,默认是/etc/ssl/openssl.cnf根据系统不同位置不同。该文件包含生成req时的参数,当在命令行没有指定时,则采用该文件中的默认值。
创建服务器公私密钥
- 生成服务器配置文件exampleserver.cnf :
vim ~/myCA/exampleserver.cnf
写入内容:
#
# exampleserver.cnf
#
[ req ]
prompt = no
distinguished_name = server_distinguished_name
[ server_distinguished_name ]
commonName = localhost # 服务器域名
stateOrProvinceName = JS # 服务器所在省份
countryName = CN # 服务器所在国家(仅限2个字符)
emailAddress = XXXX@XXX.com # 邮箱
organizationName = XXX #
organizationalUnitName = XXX #
- 生成服务器证书和密钥
export OPENSSL_CONF=~/myCA/exampleserver.cnf #该命令设置环境变量 OPENSSL_CONF,使得 openssl 更换配置文件。
openssl req -newkey rsa:2048 -keyout tempkey.pem -keyform PEM -out tempreq.pem -outform PEM #生成证书和密钥
- 临时私钥改名
-
将临时私钥转换为 unencrypted key,即秘钥不加密状态:
openssl rsa -in tempkey.pem -out server_key.pem
-
加密,直接改名:
mv tempkey.pem server_key.pem
两者的区别是,第二种需要在服务器启动时输入私钥的密码短语,否则会导致服务器启动失败,但第二种安全性高于第一种,可以更好的保护秘钥。
使用 CA key 对服务器证书签名
- 签名:
export OPENSSL_CONF=~/myCA/caconfig.cnf
openssl ca -in tempreq.pem -out server_crt.pem #得到签名后的服务器证书
- 删除临时证书和密钥:
rm -f tempkey.pem && rm -f tempreq.pem
使用Apache搭建HTTPS
安装并配置apache
- 检查有无apache
- 安装apache2:
sudo apt-get install apache2
- apache2目录说明:
- 默认站点在 /var/www/
- 配置文件在 /etc/apache2/
- 日志在 /var/log/apache/
- 启动脚本是 /etc/init.d/apache2 start/stop/restart
- etc/apache2下的文件夹与文件
- apache2.conf:Apache的主要配置文件,包含全局配置。
- envvars:Apache2环境变量设置。
- ports.conf:配置Apache监听的端口。
- mods-available:这个目录包含模块和模块配置文件,不是所有的模块都有配置文件。
- mods-enabled:持有/etc/apache2/mods-available目录下文件的链接,当该目录下有一个模块文件和其配置文件,那么Apache重启后该模块将生效。
- sites-available:这个目录包含Apache虚拟主机的配置文件。虚拟主机允许Apache配置多个站点并为每个站点配置不同的参数。后面下面配置的时候会配置80端口的http重定向为443的https。
- sites-enabled:持有/etc/apache2/sites-available目录下文件的链接。当Apache重启后,该目录中包含的站点将会被激活。
apache配置
- 建立ssl配置文件,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/username/myCA/server_crt.pem #把username改为自己的用户名
SSLCertificateKeyFile /home/username/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
- 创建/var/www/lab并在其之下配置网页信息:
lab.html
- 也许需要建立软连接:
sudo ln -s /etc/apache2/sites-available/lab-ssl.conf /etc/apache2/sites-enabled/lab-ssl.conf
- 在apache2.conf加入:
ServerName localhost:80
AddDefaultCharset UTF-8
启动服务
- 启动apache:
/etc/init.d/apache2 start
- 开启ssl:
sudo a2enmod ssl
- 在目录/etc/apache2/sites-available下开启站点配置:
sudo a2ensite lab-ssl.conf
- 相关语法说明:
- 开启某个模块使用 $ a2enmod 禁用某个模块使用 $ a2dismod
- a2ensite/a2dissite命令开启或关闭一个站点配置
- a2enconf/a2disconf 命令启用或关闭一个配置文件
- 重启服务:
systemctl reload apache2
- 在浏览器中导入CA证书
- 在浏览器中浏览网页
遇到的一些问题以及解决方法
1.开启站点时站点不存在
root@song-virtual-machine:/etc/apache2/sites-available# a2ensite lab
ERROR: Site lab does not exist!
- 站点配置文件需要以.conf结尾
- 目录:/etc/apache2/sites-available
- 有无和/etc/apache2/sites-enabled目录中配置文件建立相应软连接
2.重启apache出错(在没有语法错误的情况下)
关闭所有站点以及ssl,重新按顺序启动服务
3.浏览器https连接出错
错误如下:
Unable to connect
An error occurred during a connection to localhost.
The site could be temporarily unavailable or too busy. Try again in a few moments.
If you are unable to load any pages, check your computer’s network connection.
If your computer or network is protected by a firewall or proxy, make sure that Firefox is permitted to access the web.
Secure Connection Failed
An error occurred during a connection to localhost. SSL received a record that exceeded the maximum permissible length.
Error code: SSL_ERROR_RX_RECORD_TOO_LONG
The page you are trying to view cannot be shown because the authenticity of the received data could not be verified.
Please contact the website owners to inform them of this problem.
- 没有开启SSL或者站点
- 服务器的证书和密钥太短: rsa:2048可以, rsa:1024可能太短。太短需要重新生成服务器证书以及密钥并签名。