源码搭建CA服务器,证书可申请、吊销

现在越来越多的项目在设计的过程中会很注重网络安全,银行金融业和监管机构之间一般采用金融城域网专线连接,在链路上面也使用CA数字证书,一般金融业的CA证书都是CFCA颁发,或者使用制定型号的 加密机。本章主要介绍一下CA服务器的搭建、证书的申请和吊销(也可以自己做加密机),后续有时间会写一下关于程序中怎么使用CA证书进行安全校验的。
openssl安装:

先来介绍一下openssl的安装,一般LINUX发行版都会自带openssl工具,裁剪系统中一般自己来编译安装。
我们的编译和测试环境如下:

key1088@key1088-host:$ uname -a
Linux key1088-host 4.4.0-36-generic #55-Ubuntu SMP Thu Aug 11 18:01:55 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux
key1088@key1088-host:
$ gcc --version
gcc (Ubuntu 5.4.0-6ubuntu116.04.2) 5.4.0 20160609
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

1.下载openssl源代码
https://www.openssl.org/

wget https://www.openssl.org/source/openssl-1.1.0.tar.gz

2.编译安装

tar xvf openssl-1.1.0.tar.gz
cd openssl-1.1.0
./config
make

咱们这次就不make install了,就在这个目录下面操作了,需要临时设置一下环境变量
这个版本默认编译出来静态bin文件在apps下面

-rw-rw-r-- 1 key1088 key1088 911 9月 4 13:49 x509.d
-rwxrwxr-x 1 key1088 key1088 680616 9月 4 13:49 openssl
-rwxrwxr-x 1 key1088 key1088 6755 9月 4 13:50 CA.pl
-rwxrwxr-x 1 key1088 key1088 6613 9月 4 13:50 tsget

3.环境变量设置

key1088@key1088-host:/openssl-1.1.0/apps$ ./openssl version
./openssl: error while loading shared libraries: libssl.so.1.1: cannot open shared object file: No such file or directory
key1088@key1088-host:/openssl-1.1.0/apps$ LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$HOME/openssl-1.1.0
key1088@key1088-host:
/openssl-1.1.0/apps$ export LD_LIBRARY_PATH
key1088@key1088-host:/openssl-1.1.0/apps$ ./openssl versionOpenSSL 1.1.0 25 Aug 2016

出现版本号就证明环境变量设置正确,openssl可以用了。

CA服务器证书生成:

CA(Certificate Authority)证书颁发机构主要负责证书的颁发、管理以及归档和吊销。证书内包含了拥有证书者的姓名、地址、电子邮件帐号、公钥、证书有效期、发放证书的CA、CA的数字签名等信息。证书主要有三大功能:加密、签名、身份验证。
所有的操作默认在openssl-1.1.0目录下进行
2.生成CA密钥

mkdir -p CA/private
key1088@key1088-host:/openssl-1.1.0$ (umask 077;./apps/openssl genrsa -out CA/private/cakey.pem 2048)
Generating RSA private key, 2048 bit long modulus
.................................+++
..........+++
unable to write 'random state'
e is 65537 (0x010001)

如果出现这个“unable to write ‘random state’”设置一下环境变量即可

key1088@key1088-host:/openssl-1.1.0$ export RANDFILE=$HOME/.rnd
key1088@key1088-host:
/openssl-1.1.0$ (umask 077;./apps/openssl genrsa -out CA/private/cakey.pem 2048)
Generating RSA private key, 2048 bit long modulus
.................................+++
.....................................................................................+++
e is 65537 (0x010001)

2.生成自签名证书
创建配置文件目录

mkdir etc
cp apps/openssl.cnf etc

为了简化证书制作过程中的输入 修改了etc/openssl.cnf,修改对比内容如下

key1088@key1088-host:~/openssl-1.1.0$ diff etc/openssl.cnf apps/openssl.cnf
42c42
< dir = ./CA # Where everything is kept

dir = ./demoCA # Where everything is kept
129c129
< countryName_default = CN


countryName_default = AU
134c134
< stateOrProvinceName_default = BJ


stateOrProvinceName_default = Some-State
139c139
< 0.organizationName_default = key1088.info


0.organizationName_default = Internet Widgits Pty Ltd
151c151
< emailAddress = key1088@163.com


emailAddress = Email Address

根据密钥生存证书

key1088@key1088-host:~/openssl-1.1.0$ ./apps/openssl req -new -x509 -key CA/private/cakey.pem -out CA/cacert.pem -days 1000 -config etc/openssl.cnf
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [CN]:
State or Province Name (full name) [BJ]:
Locality Name (eg, city) []:
Organization Name (eg, company) [key1088.info]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:key1088
key1088@163.com []:

CA/serial3.生成客户端证书,也称为节点证书。key1088@key1088-host:/openssl-1.1.0$ (umask 077;./apps/openssl genrsa -out CA/client/c01.key 2048)Generating RSA private key, 2048 bit long modulus............+++................................................................................................+++e is 65537 (0x10001)key1088@key1088-host:~/openssl-1.1.0$ ./apps/openssl req -new -key CA/client/c01.key -out CA/client/c01.csr -config etc/openssl.cnfYou are about to be asked to enter information that will be incorporatedinto your certificate request.What you are about to enter is what is called a Distinguished Name or a DN.There are quite a few fields but you can leave some blankFor some fields there will be a default value,If you enter '.', the field will be left blank.">创建CA服务器所需文件

key1088@key1088-host:/openssl-1.1.0$ touch CA/{index.txt,serial}
key1088@key1088-host:
/openssl-1.1.0$ ls -l CA/
总用量 8
-rw-rw-r-- 1 key1088 key1088 1176 9月 4 14:07 cacert.pem
-rw-rw-r-- 1 key1088 key1088 0 9月 4 14:09 index.txt
drwxrwxr-x 2 key1088 key1088 4096 9月 4 13:57 private
-rw-rw-r-- 1 key1088 key1088 0 9月 4 14:09 serial

证书序号开始值设置

key1088@key1088-host:/openssl-1.1.0$ echo "01" > CA/serial

3.生成客户端证书,也称为节点证书。

key1088@key1088-host:/openssl-1.1.0$ (umask 077;./apps/openssl genrsa -out CA/client/c01.key 2048)
Generating RSA private key, 2048 bit long modulus
............+++
................................................................................................+++
e is 65537 (0x10001)
key1088@key1088-host:~/openssl-1.1.0$ ./apps/openssl req -new -key CA/client/c01.key -out CA/client/c01.csr -config etc/openssl.cnf
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.

Country Name (2 letter code) [CN]:
State or Province Name (full name) [BJ]:
Locality Name (eg, city) []:
Organization Name (eg, company) [key1088.info]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:c01 #此处不能和CA中的名称相同
key1088@163.com []:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:1234
An optional company name []:1234

4.部署到CA中

mkdir -p CA/newcerts
key1088@key1088-host:~/openssl-1.1.0$ ./apps/openssl ca -in CA/client/c01.csr -out CA/client/c01.crt -days 1000 -config etc/openssl.cnf
Using configuration from etc/openssl.cnf
Can't open ./CA/index.txt.attr for reading, No such file or directory
140399448418048:error:02001002:system library:fopen:No such file or directory:crypto/bio/bss_file.c:74:fopen('./CA/index.txt.attr','r')
140399448418048:error:2006D080:BIO routines:BIO_new_file:no such file:crypto/bio/bss_file.c:77:
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 1 (0x1)
        Validity
            Not Before: Sep  4 06:58:17 2016 GMT
            Not After : Jun  1 06:58:17 2019 GMT
        Subject:
            countryName               = CN
            stateOrProvinceName       = BJ
            organizationName          = key1088.info
            commonName                = c01
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:FALSE
            Netscape Comment:
                OpenSSL Generated Certificate
            X509v3 Subject Key Identifier:
                AB:F4:CB:4F:13:28:F8:5D:A7:DB:A0:E3:F3:52:86:C1:25:D1:EB:A0
            X509v3 Authority Key Identifier:
                keyid:68:82:F2:71:02:9C:92:00:F4:05:72:30:24:97:6B:80:2E:69:AF:EA
Certificate is to be certified until Jun  1 06:58:17 2019 GMT (1000 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
key1088@key1088-host:~/openssl-1.1.0$ du -a CA/
8	CA/newcerts/01.pem		        #自动生成的PEM文件,按照序号命名
12	CA/newcerts
4	CA/private/cakey.pem
8	CA/private
4	CA/serial
4	CA/serial.old
0	CA/index.txt.old
4	CA/cacert.pem
4	CA/index.txt
8	CA/client/c01.crt			#生成的证书
4	CA/client/c01.key
4	CA/client/c01.csr
20	CA/client
4	CA/index.txt.attr
64	CA/

openssl自带的样例:
openssl-1.1.0/apps/demoCA/下面的内容
5.转换给pfx格式(可选)

key1088@key1088-host:~/openssl-1.1.0$ ./apps/openssl pkcs12 -export -clcerts -in CA/client/c01.crt -inkey CA/client/c01.key -out CA/client/c01.pfx
Enter Export Password:					#12345678
Verifying - Enter Export Password:		#同上

pfx文件包含数字签名证书和私钥,可以进行密钥转移,也可以导入到浏览器中查看。
6.验证证书是否正确

key1088@key1088-host:~/openssl-1.1.0$ ./apps/openssl verify -CAfile CA/cacert.pem  CA/client/c01.crt
CA/client/c01.crt: OK

吊销证书

1.查看客户端证书序号

key1088@key1088-host:~/openssl-1.1.0$ ./apps/openssl x509 -in CA/client/c01.crt -noout -serial -subject
serial=01
subject=C = CN, ST = BJ, O = key1088.info, CN = c01

2.吊销证书

key1088@key1088-host:~/openssl-1.1.0$ ./apps/openssl ca -revoke CA/newcerts/01.pem -config etc/openssl.cnf
Using configuration from etc/openssl.cnf
Revoking Certificate 01.
Data Base Updated

3.生成吊销列表

key1088@key1088-host:~/openssl-1.1.0$ echo "01" > CA/crlnumber
key1088@key1088-host:~/openssl-1.1.0$ ./apps/openssl ca -gencrl -out CA/all.crl -config etc/openssl.cnf
Using configuration from etc/openssl.cnf

4.查看吊销

key1088@key1088-host:~/openssl-1.1.0$ ./apps/openssl crl -in CA/all.crl -noout -text
Certificate Revocation List (CRL):
        Version 2 (0x1)
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: /C=CN/ST=BJ/O=key1088.info/CN=key1088
        Last Update: Sep  4 07:37:17 2016 GMT
        Next Update: Oct  4 07:37:17 2016 GMT
        CRL extensions:
            X509v3 CRL Number:
                1
Revoked Certificates:
    Serial Number: 01
        Revocation Date: Sep  4 07:34:48 2016 GMT
    Signature Algorithm: sha256WithRSAEncryption
         a7:98:6c:8f:77:d2:52:6a:57:eb:27:75:6f:17:eb:3c:30:19:
         78:bb:4f:77:aa:94:74:28:e5:7a:05:38:8d:03:6c:7c:8f:63:
         de:a9:fd:d3:ed:77:70:7d:24:9a:b9:da:42:05:9b:d1:73:92:
         6c:0c:13:88:16:16:d7:e1:4f:6f:62:90:8a:11:b1:c5:b7:80:
         c8:6c:76:e5:d2:eb:a9:f4:ee:da:85:56:9e:f2:97:02:43:ef:
         3d:ea:77:af:5b:f1:ed:4b:39:c7:7e:9c:22:62:91:ee:17:30:
         10:d2:49:82:9a:0d:9c:0c:ad:63:1e:cb:30:33:f0:5f:55:dc:
         b6:6c:70:61:82:ba:e0:d3:98:96:f3:3d:8b:0c:02:0d:fd:ac:
         61:e5:24:46:a0:52:94:05:f4:a9:a8:8b:25:40:db:a4:e5:58:
         4f:bd:37:1d:44:87:f1:3f:f9:06:d5:47:aa:0c:8f:1e:ba:d6:
         99:ef:f7:77:e0:af:05:a3:08:78:06:0f:e2:6a:a4:cd:ac:1a:
         45:d3:18:9a:18:25:ee:c3:7b:66:51:77:52:64:5e:4a:81:9e:
         84:be:16:bc:da:7d:83:7b:49:d1:5a:0f:4f:02:e4:fa:fb:80:
         53:7f:7f:72:02:17:31:25:c6:6e:cc:1e:4f:7e:9c:f4:ae:d1:
         85:a2:6a:d6
key1088@key1088-host:~/openssl-1.1.0$ cat CA/serial
03
key1088@key1088-host:~/openssl-1.1.0$ cat CA/crlnumber
02
key1088@key1088-host:~/openssl-1.1.0$ cat CA/index.txt
R	190601065817Z	160904073448Z	01	unknown	/C=CN/ST=BJ/O=key1088.info/CN=c01
V	190601073145Z		02	unknown	/C=CN/ST=BJ/O=key1088.info/CN=c02
key1088@key1088-host:~/openssl-1.1.0$ cat CA/index.txt.old
V	190601065817Z		01	unknown	/C=CN/ST=BJ/O=key1088.info/CN=c01
V	190601073145Z		02	unknown	/C=CN/ST=BJ/O=key1088.info/CN=c02

5.验证吊销的证书和正常使用的证书

key1088@key1088-host:~/openssl-1.1.0$ ./apps/openssl  verify -crl_check -CRLfile CA/all.crl -CAfile CA/cacert.pem CA/client/c01.crt
C = CN, ST = BJ, O = key1088.info, CN = c01
error 23 at 0 depth lookup: certificate revoked
error CA/client/c01.crt: verification failed

再新生成一个02的证书验证一下,验证结果。
key1088@key1088-host:~/openssl-1.1.0$ ./apps/openssl verify -crl_check -CRLfile CA/all.crl -CAfile CA/cacert.pem CA/client/c02.crt
CA/client/c02.crt: OK
参考文章:
http://www.yunweipai.com/archives/4513.html%20r
http://raymii.org/s/articles/OpenSSL_manually_verify_a_certificate_against_a_CRL.html

dedecms 嵌套dsql

织梦CMS中嵌套查询语句,SetQuery和GetObject传入不同的参数就可以了。

if($keyword != '')
{
    $query2 = "SELECT id,title,typeid FROM `#@__archives` where arcrank>-1 AND ($keyword) ORDER BY id desc limit 0,5";
}
else
{
    $query2 = "SELECT id,title,typeid FROM `#@__archives` where arcrank>-1 ORDER BY id desc limit 0,5";
}
$dsql->SetQuery($query2);
$dsql->Execute(1);
while($row=$dsql->GetObject(1))
{
    $dsql->SetQuery("Select typedir From `#@__arctype` where id='$row->typeid'");
    $dsql->Execute(2);
    $ttrow=$dsql->GetObject(2);
    $tpdir=substr($ttrow->typedir,10);
    $likearticle .= "
  • ".cut_str(ConvertStr($row->title),16)."
  • "; }

    使用Denyhosts防止SSHD和VSFTPD暴力破解

    Denyhosts防止暴力破解主要是根据登录的日志/var/log/secure(centos为例),登录失败次数超过一定的阀值将IP写入/etc/hosts.deny文件中。文件格式如下:

    #服务名称:ip地址
    sshd: 180.97.239.49
    ALL: 180.78.180.186
    

    Denyhosts是专门用于防止SSHD登录,默认也是防止sshd登录的配置;如果想让vsftpd也添加一个安全的墙,需要在配置中添加以下信息,主要是格式化了匹配的正则表达式。

    denyhosts.cfg:
    SSHD_FORMAT_REGEX=.* (sshd.*:|[sshd]|vsftpd.*:) (?P.*)
    USERDEF_FAILED_ENTRY_REGEX=authentication failure.* ruser=(?PS+) rhost=(?PS+)
    BLOCK_SERVICE  = ALL
    

    修改后,需要重启denghosts服务。
    vsftpd如果使用这种机制需要开启tcp_wrappers(默认是开启的)

    tcp_wrappers=YES
    

    dizcuz 不能加载模板问题

    今天帮朋友迁移一个教育网站,在目标主机上面搭建好LNMP后,把网站打包上传,数据库备份上传,把数据库导入,网站文件和目录设置好,还有一些乱七八糟的设置设置。配置弄好后,启动程序,测试一下网站是否和原来的功能是否一致,页面是否都正常,需要和没迁移前保持一样。经过测试,其他的几个模块都没有问题,有一个BBS的模块,使用的dizcuz的程序,版本有些老了,打开首页直接显示模板内容了。看了对应的php是可以解析的,php解析没有问题,再看权限,设置的也合理。最后看了看解析的代码页没有问题,网站的文件都是打包过来的,文件一致性肯定能保证,肯定是环境哪里设置的问题。最好找了半天发现一个php的参数没有修改,原来是short_open_tag = Off,修改为On,重启一下php-fpm,(如果你是apache+php模块,就重启apache),再次访问就正常了。关于这个参数区别如下:

    php.ini
    ; This directive determines whether or not PHP will recognize code between
    ;  tags as PHP source which should be processed as such. It's been
    ; recommended for several years that you not use the short tag "short cut" and
    ; instead to use the full  tag combination. With the wide spread use
    ; of XML and use of these tags by other languages, the server can become easily
    ; confused and end up parsing the wrong code in the wrong context. But because
    ; this short cut has been a feature for such a long time, it's currently still
    ; supported for backwards compatibility, but we recommend you don't use them.
    ; Default Value: On
    ; Development Value: Off
    ; Production Value: Off
    ; http://php.net/short-open-tag
    short_open_tag = On
    

    这种情况也只有迁移的时候会遇到,如果重新安装,discuz检查php参数的时候肯定是报错不通过的。

    Dedecms GBK版本后台系统设置无法输入中文问题

    最近用dedecms搭建了一个简单的站,主要用于测试。发现在后台系统-系统基础参数。很多选项没有办法成功设置中文。
    实际上提交已成功,看数据库dede_sysconfig记录已成功插入,应该属于显示问题。看显示代码

    dede/templets/sys_info.htm:
        echo "{$addstr}";
    

    用于转换html特殊字符,网上查询了一下,是PHP5.4以上版本会有这个问题,必须指定编号类型。需修改为

        echo "{$addstr}";
    

    修改后,再修改系统基础参数就可以显示了。
    因为代码中太多类似的代码了,最好还是降低一下php的版本。

    py2exe error [Errno 2] No such file or directory &amp;#039;MSVCP90.dll&amp;#039;

    使用py2exe生产windows可执行程序时,报错:error: [Errno 2] No such file or directory: ‘MSVCP90.dll’
    原脚本:

    #!/usr/bin/env python
    __author__ = 'key1088'
    __date__ = '15-3-7'
    from distutils.core import  setup
    import py2exe
    setup(console=["overtime.py"])
    

    使用生产命令:

    F:workdirpython1>D:Python27python.exe mysetup.py  py2exe
    running py2exe
    creating F:workdirpython1build
    creating F:workdirpython1buildbdist.win32
    creating F:workdirpython1buildbdist.win32winexe
    creating F:workdirpython1buildbdist.win32winexecollect-2.7
    creating F:workdirpython1buildbdist.win32winexebundle-2.7
    creating F:workdirpython1buildbdist.win32winexetemp
    creating F:workdirpython1dist
    *** searching for required modules ***
    *** parsing results ***
    creating python loader for extension 'unicodedata' (D:Python27DLLsunicodedata.pyd -> unicodedata.pyd)
    creating python loader for extension 'wx._misc_' (D:Python27libsite-packageswx-3.0-mswwx_misc_.pyd -> wx._misc_.pyd)
    creating python loader for extension 'select' (D:Python27DLLsselect.pyd -> select.pyd)
    creating python loader for extension 'wx._windows_' (D:Python27libsite-packageswx-3.0-mswwx_windows_.pyd -> wx._windows_.pyd)
    creating python loader for extension '_hashlib' (D:Python27DLLs_hashlib.pyd -> _hashlib.pyd)
    creating python loader for extension 'wx._gdi_' (D:Python27libsite-packageswx-3.0-mswwx_gdi_.pyd -> wx._gdi_.pyd)
    creating python loader for extension 'wx._controls_' (D:Python27libsite-packageswx-3.0-mswwx_controls_.pyd -> wx._controls_.pyd)
    creating python loader for extension '_sqlite3' (D:Python27DLLs_sqlite3.pyd -> _sqlite3.pyd)
    creating python loader for extension 'bz2' (D:Python27DLLsbz2.pyd -> bz2.pyd)
    creating python loader for extension 'wx._core_' (D:Python27libsite-packageswx-3.0-mswwx_core_.pyd -> wx._core_.pyd)
    *** finding dlls needed ***
    error: [Errno 2] No such file or directory: 'MSVCP90.dll'
    

    修改代码最后一行:

    setup(console=["overtime.py"],options = { "py2exe":{"dll_excludes":["MSVCP90.dll"]}})
    

    生成exe文件成功。
    为了使py2exe打出来的可执行文件不出现中文乱码,每次输出要采用以下格式:print unicode(“中文”,”utf-8”)

    用tcgetattr、tcsetattr实现密码输入框

    在读ptrunnel的代码时,发现一个很好的用法记录一下,可用于密码的输入框,不回显输入内容,可用于很多场景。
    代码如下:

    static int terminal_echo_off(int fd)
    {
    struct termios term;
    if (isatty(fd) == 0)
    {
    #ifdef DEBUG
    printf("the file %i is not a terminaln", fd);
    #endif /* DEBUG */
    return -1;
    }
    if (tcgetattr(fd, &term) < 0)
    {
    #ifdef DEBUG
    perror("tcgetattr: ");
    #endif /* DEBUG */
    return -1;
    }
    term.c_lflag &= ~ECHO;
    if (tcsetattr(fd, TCSANOW, &term) < 0)
    {
    #ifdef DEBUG
    perror("tcsetattr: ");
    #endif /* DEBUG */
    return -1;
    }
    return 0;
    }
    static int terminal_echo_on(int fd)
    {
    struct termios term;
    if (isatty(fd) == 0)
    {
    #ifdef DEBUG
    printf("the file %i is not a terminaln", fd);
    #endif /* DEBUG */
    return -1;
    }
    if (tcgetattr(fd, &term) < 0)
    {
    #ifdef DEBUG
    perror("tcgetattr: ");
    #endif /* DEBUG */
    return -1;
    }
    term.c_lflag |= ECHO;
    if (tcsetattr(fd, TCSANOW, &term) < 0)
    {
    #ifdef DEBUG
    perror("tcsetattr: ");
    #endif /* DEBUG */
    return -1;
    }
    return 0;
    }