0%

总是有一些场景需要自行签发一系列证书并且让系统信任。如果每次都签发一个新的证书,显然会比较麻烦。所以只需要一个根证书,让系统/浏览器信任这个证书,后续这个根证书签发的证书都是可以被信任的了,非常方便。

整体步骤

  • 创建根证书

创建根证书

创建基础配置文件openssl-ca.cnf并写入基本配置

1
touch openssl-ca.cnf

写入配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
HOME            = .
RANDFILE = $ENV::HOME/.rnd

####################################################################
[ ca ]
default_ca = CA_default # The default ca section

[ CA_default ]

default_days = 365 # How long to certify for
default_crl_days = 30 # How long before next CRL
default_md = sha256 # Use public key default MD
preserve = no # Keep passed DN ordering

x509_extensions = ca_extensions # The extensions to add to the cert

email_in_dn = no # Don't concat the email in the DN
copy_extensions = copy # Required to copy SANs from CSR to cert

####################################################################
[ req ]
default_bits = 4096
default_keyfile = cakey.pem
distinguished_name = ca_distinguished_name
x509_extensions = ca_extensions
string_mask = utf8only

####################################################################
[ ca_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_default = CN

stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = Province

localityName = Locality Name (eg, city)
localityName_default = City

organizationName = Organization Name (eg, company)
organizationName_default = Test CA, Limited

organizationalUnitName = Organizational Unit (eg, division)
organizationalUnitName_default = Server Research Department

commonName = Common Name (e.g. server FQDN or YOUR name)
commonName_default = Test CA

emailAddress = Email Address
emailAddress_default = test@example.com

####################################################################
[ ca_extensions ]

subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always, issuer
basicConstraints = critical, CA:true
keyUsage = keyCertSign, cRLSign

以上内容是签发一个CA证书必需的配置内容,从openssl.cnf文件中提取出来,方便操作。

开始签发证书

1
$ openssl req -x509 -config openssl-ca.cnf -newkey rsa:4096 -sha256 -nodes -out cacert.pem -outform PEM

这里-nodes参数表示不使用des进行加密,可以去掉这个参数,就可以使用密码保护证书了。

创建子证书

创建子证书配置文件openssl-server.cnf并写入配置文件

1
touch openssl-server.cnf

写入配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
HOME            = .
RANDFILE = $ENV::HOME/.rnd

####################################################################
[ req ]
default_bits = 2048
default_keyfile = serverkey.pem
distinguished_name = server_distinguished_name
req_extensions = server_req_extensions
string_mask = utf8only

####################################################################
[ server_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_default = CN

stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = Province

localityName = Locality Name (eg, city)
localityName_default = City

organizationName = Organization Name (eg, company)
organizationName_default = Test Server, Limited

commonName = Common Name (e.g. server FQDN or YOUR name)
commonName_default = Test Server

emailAddress = Email Address
emailAddress_default = test@example.com

####################################################################
[ server_req_extensions ]

subjectKeyIdentifier = hash
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment
subjectAltName = @alternate_names
nsComment = "OpenSSL Generated Certificate"

####################################################################
[ alternate_names ]

DNS.1 = example.com
DNS.2 = www.example.com
DNS.3 = mail.example.com
DNS.4 = ftp.example.com

如果没有域名,在最后的[alternate_names]部分需要明确的标注你当前证书需要部署在的服务器的IP地址。如果部署在本地则应该为:

1
2
3
IP.1 = 127.0.0.1
IP.2 = ::1
IP.3 = 192.168.0.3

然后,使用下面的命令创建服务器子证书

1
openssl req -config openssl-server.cnf -newkey rsa:2048 -sha256 -nodes -out servercert.csr -outform PEM

这个命令会在当前目录生成两个文件,servercert.csr表示给公共根证书认证机构签发认证内容的公共信息,serverkey.pem就是生成的私钥。同样,可以不使用-nodes来给这个证书加密,但是绝大多数数服务器(例如nginx)不支持配置加密的证书。

签发证书

对刚刚的openssl-ca.cnf配置文件追加签发证书的配置信息。

在最后面,增加下面内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
####################################################################
[ signing_policy ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional

####################################################################
[ signing_req ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment

然后,在[CA_default]节中增加以下内容

1
2
3
4
5
6
7
8
9
base_dir      = .
certificate = $base_dir/cacert.pem # The CA certifcate
private_key = $base_dir/cakey.pem # The CA private key
new_certs_dir = $base_dir # Location for new certs after signing
database = $base_dir/index.txt # Database index file
serial = $base_dir/serial.txt # The current serial number

unique_subject = no # Set to 'no' to allow creation of
# several certificates with same subject.

创建数据库索引文件和序列号文件,这两个文件分别配置在上述的database节和serial节中

1
2
touch index.txt
echo '01' > serial.txt

执行签发命令

1
openssl ca -config openssl-ca.cnf -policy signing_policy -extensions signing_req -out servercert.pem -infiles servercert.csr

然后会显示一系列需要签发的内容信息,并让你确认是否对证书进行签发,输入y表示确认签发;之后,会再次确认,再次输入y即可。

此时,你就得到了签发完成的证书文件servercert.pem和私钥文件serverkey.pem

  1. 验证证书内容,可以使用如下命令查看证书内容。

    1
    openssl x509 -in 证书 -text -noout
  2. 验证申请内容,可以使用如下命令。

    1
    openssl req -text -noout -verify -in XXX.csr
  3. 如果需要将证书配置到nginx中,nginx默认需要的是crt格式的证书,可以使用命令将生成的pem证书转为crt格式。

    1
    openssl x509 -text -in servercert.pem -out servercert.crt
  4. 同3,可以将cacert.pem转为cacert.crt以便能够在windows下双击导入,注意导入的时候,需要将证书安装到“受信任的根证书颁发机构”存储目录中。

  5. 在Mac环境下可以使用keychain Access.app管理自定义私钥,也可以使用命令导入

    1
    sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain /path/to/cert/cacert.crt

参考内容

How do you sign a Certificate Signing Request with your Certification Authority?

使用session的httpOnly

修改tomcat配置文件夹下的server.xml文件
tomcat/conf/server.xml,在Host配置节加入如下代码:

1
<Context path="xxx" useHttpOnly="true"/>

说明: xxx代表应用的部署路径

关闭目录浏览功能

修改tomcat配置文件夹下的web.xml文件
tomcat/conf/web.xml如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
<servlet>
<servlet-name>default</servlet-name>
<servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>0</param-value>
</init-param>
<init-param>
<param-name>listings</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>

参数说明

  • debug: 控制消息的显示级别,通常使用0和1,数字越高级别越大。默认是0。
  • listings: 控制是否显示目录下的所有文件。默认false,不显示。
  • readonly: 控制是否是只读,不可被修改的。默认为true,不可修改。

删除所有不需要的功能和文件,如example等

删除不需要的文件夹

tomcatwebapp目录下的所有无用文件夹都删除,包括但不仅包括docs, examples, host-manager, manager, ROOT

删除managerhost-manager功能

修改tomcat配置文件conf/server.xml如下:
删除:

1
2
3
4
5
6
7
8
<GlobalNamingResources>
<Resource name="UserDatabase"
auth="Container"
type="org.apache.catalina.UserDatabase"
description="User database that can be updated and saved"
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
pathname="conf/tomcat-users.xml"/>
</GlobalNamingResources>

删除:

1
<Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/>

删除响应头中版本信息

通常tomcat的响应头信息如下:

需要改掉这些信息防止恶意根据对应版本的漏洞进行攻击。

  1. 进入tomcat的lib目录找到catalina.jar文件

  2. 使用命令unzip catalina.jar,解压jar包得到文件夹META-INForg

  3. 进入org/apache/catalina/util 编辑配置文件ServerInfo.properties

  4. 修改以下字段为你想要的信息

    1
    2
    3
    server.info=server
    server.number=1.0
    server.built=day
  5. 将修改后的信息压缩回jar包

    1
    2
    cd  /tomcat/lib
    jar -uvf catalina.jar org/apache/catalina/util/ServerInfo.properties
  6. 修改/conf/server.xml

    在connector配置节增加server属性

    1
    2
    <Connector xxxxx
    server="Server 1.0"/>
  7. 重启tomcat

对于重复操作,可以有多种不同的方式。

  • record(记录行为)方式
    在normal模式下,使用q开始记录行为,记录完成后,使用q结束记录。
    例如,我想每隔一行删除一个元素:
1
2
3
4
这个是正常的行
删除的行
这个是正常的行
删除的行

需要键入内容

1
q a dd j

重复键入

1
2@a

说明:a是录制的命令的名称,名称可以为所有的小写,大写字母。

环境准备

编译环境

安装make,gcc和g++

1
2
yum -y install gcc automake autoconf libtool make
yum install gcc gcc-c++

安装包

首先,我们需要选定一个源码的安装目录,这里可以是任何目录。本文使用的是/opt/nginx/src

1
2
mkdir -p /opt/nginx/src
cd /opt/nginx/src

pcre,rewrite重写

1
2
3
4
5
6
wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.39.tar.gz
tar -zxvf pcre-xxx.tar.gz
cd pcre-xxx
./configure
make
make install

zlib,gzip压缩

1
2
3
4
5
6
wget http://zlib.net/zlib-1.2.11.tar.gz
tar -zxvf zlib-xxx.tar.gz
cd zlib-xxx
./configure
make
make install

openssl,ssl加密

1
2
3
4
5
6
wget https://www.openssl.org/source/openssl-1.0.2k.tar.gz
tar -zxvf openssl-xxx.tar.gz
cd openssl-xxx
./config
make
make install

nginx

1
2
3
4
5
6
wget http://nginx.org/download/nginx-1.10.3.tar.gz
tar -zxvf nginx-xxx.tar.gz
cd nginx-xxx
./configure --prefix=/opt/nginx --with-http_ssl_module --with-pcre=/opt/nginx/src/pcre-xxx --with-zlib=/opt/nginx/src/zlib-xxx --with-openssl=/opt/nginx/src/openssl-xxx
make
make install

参数说明

  • prefix:安装路径
  • with-http_ssl_module:安装ssl模块
  • with-pcre:编译pcre,该路径为pcre源码所在路径
  • with-zlib:编译zlib,该路径为zlib源码所在路径
  • with-openssl:编译openssl,该路径为openssl源码所在路径

启动

1
/opt/nginx/sbin/nginx

nginx默认监听80端口,使用http://[IP]/进行访问即可

mysql 5.7的数据库安装方式和之前使用是mysql 5.1的安装方式有点不一样,在此特意记录一下。

  1. 下载包

    1
    wget http://mirrors.sohu.com/mysql/MySQL-5.7/mysql-5.7.17-linux-glibc2.5-x86_64.tar.gz
  2. 解压

    1
    2
    tar -zxvf mysql-5.7.12-linux-glibc2.5-x86_64.tar.gz
    mv mysql-5.7.12-linux-glibc2.5-x86_64 /usr/local/mysql
  3. 初始化

    1
    2
    3
    4
    5
    useradd -M -s /sbin/nologin  mysql
    mkdir -p /data/mysql
    chown mysql /data/mysql
    cd /usr/local/mysql
    ./bin/mysqld --initialize --user=mysql --datadir=/data/mysql

    注意,这一步最后一行会有一个提示
    [Note] A temporary password is generated for root@localhost: B*s1i(*,kXwg
    最后面的字符串为root密码。

  4. SSL设置

    1
    ./bin/mysql_ssl_rsa_setup --datadir=/data/mysql
  5. 设置为服务

    1
    2
    3
    4
    5
    6
    cp support-files/my-default.cnf  /etc/my.cnf
    vim /etc/my.cnf //编辑或者修改
    basedir = /usr/local/mysql
    datadir = /data/mysql
    port = 3306
    socket = /tmp/mysql.sock
    1
    2
    3
    4
    5
    cp support-files/mysql.server /etc/init.d/mysqld
    vim /etc/init.d/mysqld
    //编辑或者修改
    basedir=/usr/local/mysql
    datadir=/data/mysql
  6. 启动服务
    service mysqld start

  7. 设置root密码

    1
    2
    3
    使用初始化密码登录
    /usr/local/mysql/bin/mysql -uroot -p'B*s1i(*,kXwg' //进入后直接设置密码
    mysql>set password = password('mypass'); //一定要设置一下新密码

    退出来,再使用新的密码登录就可以了

  8. 修改字符集
    修改my.cnf

    1
    2
    3
    4
    5
    在[mysqld]下添加
    character-set-server=utf8

    在[client]下添加
    default-character-set=utf8

对于忘记初始化密码的情况

还有一种情况,就是不知道初始化密码

1
2
3
4
5
6
7
8
9
vi /etc/my.cnf
在[mysqld]下面增加一行
skip-grant-tables
重启 /etc/init.d/mysqld restart

/usr/local/mysql/bin/mysql -uroot
mysql> update user set authentication_string=password('123333') where user='root';
退出来后,更改my.cnf,去掉刚加的 skip-grant-tables
重启 /etc/init.d/mysqld restart

此就可以使用新的密码了。