为OpenVPN生成证书

1 前言

OpenVPN使用TLS协议对通信加密。TLS使用证书鉴别通信的另一方是否可信,并使用证书内的公钥及对应的私钥进行加解密。本文说明如何给OpenVPN生成证书。

操作系统:Windows 10 64bit(其它Windows版本操作方法类似)

软件:OpenVPN 2.4.6

2 操作

2.1 安装OpenVPN

Windows版OpenVPN自带生成证书所需的工具及相应的批处理,但默认不会安装。因此,在安装时需要勾选“EasyRSA 2 Certificate  Management Scripts”这个选项。其默认的安装目录是C:\Program Files\OpenVPN,生成证书的工作,要在以管理员身份运行的命令提示符下,切换到C:\Program Files\OpenVPN\easy-rsa进行。

2.2 准备工作

需要做一些准备工作,才可以生成证书。

  1. 用记事本打开openssl-1.0.0.cnf,把default_md=md5这一行,等号(=)后面的值改为sha256。这样会生成签名算法为sha256的证书。签名算法是sh1的证书已经被认为不安全了,md5就更不应该使用。OpenVPN 2.4.6的默认值已经是sha256,这里不需要再修改了。
    default_md=sha256
  2. 打开命令提示符,切换到C:\Program Files\OpenVPN\easy-rsa目录(后面一切命令,皆以此为前提),执行init-config.bat。这会生成一个用以初始化环境变量的批处理vars.bat。
    cd "\Program Files\OpenVPN\easy-rsa"
    init-config
  3. 打开vars.bat,把set KEY_SIZE=1024这一行的1024,改成2048。这一行设定密钥长度,默认的长度1024,已经被认为是不安全的了。OpenVPN 2.4.6的默认KEY_SIZE已经是4096,这里不需要再修改了。
    set KEY_SIZE=2048
  4. 提供证书中包含的默认信息。COUNTRY,国家;PROVINCE,省份;CITY,城市;ORG,组织;EMAIL,电邮地址;CN,一般名称(common name);NAME,名称;OU,组织单位(organization unit)。修改好后保存。
    set KEY_COUNTRY=US
    set KEY_PROVINCE=CA
    set KEY_CITY=SanFrancisco
    set KEY_ORG=OpenVPN
    set KEY_EMAIL=mail@host.domain
    set KEY_CN=changeme
    set KEY_NAME=changeme
    set KEY_OU=changeme
  5. 初始化环境变量、删除以前的证书(如果有)并新建存放证书的keys目录(如果没有)。
    vars
    clean-all

2.3 生成证书

OpenVPN需要用到的证书见下表。除dh.pem,其它都是成对生成的,即一个证书对应一个密钥。

文件名使用者目的是否需保密
ca.crt服务器+所有客户端根CA证书
ca.key只在给密钥签名的机器上需要根CA密钥
dh{n}.pem只有服务器需要Diffie Hellman参数
server.crt只有服务器需要服务器证书
server.key只有服务器需要服务器密钥
client1.crt只有客户端1需要客户端1证书
client1.key只有客户端1需要客户端1密钥
client2.crt只有客户端2需要客户端2证书
client2.key只有客户端2需要客户端2密钥
  1. 生成CA证书。
    build-ca

    生成过程中命令行显示的内容见下。斜体部分是在询问证书的信息。直接回车,表示使用方括号([])中的默认内容(修改默认内容的方法见2.2节第iv步)。如果默认内容不对,可以手动输入。对于证书来说,最重要的一般是Common Name。OpenVPN可根据Common Name识别不同的客户端,并对其区别对待。

    C:\Program Files\OpenVPN\easy-rsa>build-ca
    WARNING: can't open config file: /etc/ssl/openssl.cnf
    Loading 'screen' into random state - done
    Generating a 2048 bit RSA private key
    ......................+++
    ....................................+++
    writing new private key to 'keys\ca.key'
    -----
    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) [US]:
    State or Province Name (full name) [CA]:
    Locality Name (eg, city) [SanFrancisco]:
    Organization Name (eg, company) [OpenVPN]:caibaoz.com
    Organizational Unit Name (eg, section) [changeme]:n/a
    Common Name (eg, your name or your server's hostname) [changeme]:caibaoz_CA
    Name [changeme]:caibaoz_CA
    Email Address [mail@host.domain]:
  2. 生成Diffie Hellman参数。命令很短,但需要的时间可能会比较长,耐心等待。
    build-dh

    生成过程中命令行显示的内容见下。

    C:\Program Files\OpenVPN\easy-rsa>build-dh
    WARNING: can't open config file: /etc/ssl/openssl.cnf
    Loading 'screen' into random state - done
    Generating DH parameters, 2048 bit long safe prime, generator 2
    This is going to take a long time
    .........................+....................+.................................
    ................................................................................
    (中间都是.和+,从略)
    ............................................................+.............+.....
    ............................................................+.+.................
    ++*++*
  3. 生成服务器证书,<machine-name>处用你希望使用的名称代替。
    build-key-server <machine-name>

    生成过程中命令行显示的内容见下。第一个斜体部分(两行)可提供证书密钥的密码及公司名称。公司名称本就是可选的;至于密码,有没有密码都不会影响服务端与客户端之间的通信,配置上也没有区别。第二个和第三个斜体部分输入字母y回车即可。

    C:\Program Files\OpenVPN\easy-rsa>build-key-server caobaoz_srv
    WARNING: can't open config file: /etc/ssl/openssl.cnf
    Loading 'screen' into random state - done
    Generating a 2048 bit RSA private key
    .............+++
    .............+++
    writing new private key to 'keys\caobaoz_srv.key'
    -----
    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) [US]:
    State or Province Name (full name) [CA]:
    Locality Name (eg, city) [SanFrancisco]:
    Organization Name (eg, company) [OpenVPN]:caibaoz.com
    Organizational Unit Name (eg, section) [changeme]:n/a
    Common Name (eg, your name or your server's hostname) [changeme]:caibaoz_srv
    Name [changeme]:caibaoz_srv
    Email Address [mail@host.domain]:
    
    Please enter the following 'extra' attributes
    to be sent with your certificate request
    A challenge password []:
    An optional company name []:
    WARNING: can't open config file: /etc/ssl/openssl.cnf
    Using configuration from C:\Program Files\OpenVPN\easy-rsa\openssl-1.0.0.cnf
    Loading 'screen' into random state - done
    Check that the request matches the signature
    Signature ok
    The Subject's Distinguished Name is as follows
    countryName :PRINTABLE:'US'
    stateOrProvinceName :PRINTABLE:'CA'
    localityName :PRINTABLE:'SanFrancisco'
    organizationName :PRINTABLE:'caibaoz.com'
    organizationalUnitName:PRINTABLE:'n/a'
    commonName :T61STRING:'caibaoz_srv'
    name :T61STRING:'caibaoz_srv'
    emailAddress :IA5STRING:'mail@host.domain'
    Certificate is to be certified until Dec 26 14:16:39 2024 GMT (3650 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
  4. 生成客户端证书,<machine-name>处用你希望使用的名称代替。我们这里只为一个客户端生成证书。注意OpenVPN是根据证书的Common Name识别不同的客户端,服务端在未设置duplicate-cn选项的情况下,一个证书只允许一个客户端连接。因此,如果需要为多个客户端生成证书,证书的Common Name不能相同。
    build-key <machine-name>

    生成过程中命令行显示的内容见下。需要注意的地方与生成服务器证书类似,不再重复。再一次强调,不同的客户端证书,Common Name不能相同;客户端证书的Common Name也不能与服务端证书相同。服务端可通过Common Name识别不同的客户端,针对各个客户端做出不同的设置。

    C:\Program Files\OpenVPN\easy-rsa>build-key caibaoz_cli1
    WARNING: can't open config file: /etc/ssl/openssl.cnf
    Loading 'screen' into random state - done
    Generating a 2048 bit RSA private key
    ..............+++
    ............+++
    writing new private key to 'keys\caibaoz_cli1.key'
    -----
    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) [US]:
    State or Province Name (full name) [CA]:
    Locality Name (eg, city) [SanFrancisco]:
    Organization Name (eg, company) [OpenVPN]:caibaoz.com
    Organizational Unit Name (eg, section) [changeme]:n/a
    Common Name (eg, your name or your server's hostname) [changeme]:caibaoz_cli1
    Name [changeme]:caibaoz_cli1
    Email Address [mail@host.domain]:
    
    Please enter the following 'extra' attributes
    to be sent with your certificate request
    A challenge password []:
    An optional company name []:
    WARNING: can't open config file: /etc/ssl/openssl.cnf
    Using configuration from C:\Program Files\OpenVPN\easy-rsa\openssl-1.0.0.cnf
    Loading 'screen' into random state - done
    Check that the request matches the signature
    Signature ok
    The Subject's Distinguished Name is as follows
    countryName :PRINTABLE:'US'
    stateOrProvinceName :PRINTABLE:'CA'
    localityName :PRINTABLE:'SanFrancisco'
    organizationName :PRINTABLE:'caibaoz.com'
    organizationalUnitName:PRINTABLE:'n/a'
    commonName :T61STRING:'caibaoz_cli1'
    name :T61STRING:'caibaoz_cli1'
    emailAddress :IA5STRING:'mail@host.domain'
    Certificate is to be certified until Dec 26 14:30:54 2024 GMT (3650 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

3 tls-auth密钥

tls-auth参数给所有的SSL/TLS握手packet添加了额外的HMAC签名,用来验证完整性。没有正确的HMAC签名的任何UDP packet会被直接丢弃,不做进一步处理。tls-auth HMAC签名在SSL/TLS的安全特性之上又添加了一层额外的安全性。它可以防止:

  • 对OpenVPN UDP端口的DoS攻击或洪水攻击。
  • 判断服务器哪个端口处于监听状态的端口扫描。
  • SSL/TLS实现中的缓冲区溢出薄弱点。
  • 从未授权机器发起的SSL/TLS握手(由于这些握手最终会失败,tls-auth可以在更早的时间点切断它们)。

在命令提示符下,运行下面命令:

C:\Program Files\OpenVPN\bin\openvpn --genkey --secret ta.key

4 参考文档

4.1 OpenVPN HOWTO

4.2 C:\Program Files\OpenVPN\easy-rsa\README.txt

4.3 Change OpenSSL Default Signature Algorithm

5 更新记录

5.1 2017年6月24日

  1. 更新“1 前言”中的操作系统版本及软件版本
  2. 更新“2.2 准备工作”的一些描述,加入生成sha256证书的方法
  3. 更新“2.3 生成证书”中的一些描述
  4. 更新“3 tls-auth密钥”中的命令
  5. 添加一条参考文档

5.2 2019年1月12日

  1. 更新“1 前言”中的操作系统版本及软件版本
  2. 更新截图
  3. 使用删除线删除 “2.2 准备工作” 里一些过时的内容
  4. 其它一些细节的更新

点击量:2071

发表评论

电子邮件地址不会被公开。 必填项已用*标注

6 + 19 =