OpenSSL操作指南

    是PEM格式的:

    1. -----BEGIN RSA PRIVATE KEY-----
    2. Proc-Type: 4,ENCRYPTED
    3. DEK-Info: DES-EDE3-CBC,DB98A9512DD7CBCF
    4. yKTM+eoxBvptGrkEixhljqHSuE+ucTh3VqYQsgO6+8Wbh1docbFUKzLKHrferJBH
    5. ...
    6. -----END RSA PRIVATE KEY-----

    虽说文件头尾都标注着RSA PRIVATE KEY,但实际上这个文件里既包括公钥也
    包括私钥genrsa

    生成身份证申请

    以下OpenSSL的req命令以上文中的 server.key 为输
    入,生成一个身份证申请(CSR)文件 server.csr

      这个 CSR 里的公钥是从 server.key 里提取出来的,域名是 localhost
      需要注意的是,如果将来我们启动一个 HTTPS 服务,使用这个 CSR 签署的身份
      证,那么客户端必须可以通过域名 locahost 访问到这个 HTTPS 服务。

      server.csr文件也是PEM格式的,文件头尾标注为 CERTIFICATE REQUEST:

      1. -----BEGIN CERTIFICATE REQUEST-----
      2. MIIC0TCCAbkCAQAwgYsxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTERMA8GA1UE
      3. ...
      4. -----END CERTIFICATE REQUEST-----

      以下OpenSSL的x509命令x509用指定的私钥 server.key
      签署 server.csr,输出身份证 :

      server.crt也是PEM格式的。文件头尾的标记为CERTIFICATE:

      1. -----BEGIN CERTIFICATE-----
      2. MIIDlDCCAnwCCQDQ1UvQyFD7jDANBgkqhkiG9w0BAQsFADCBizELMAkGA1UEBhMC
      3. ...
      4. -----END CERTIFICATE-----

      在这个例子里,用来签署CSR的私钥和 CSR 里的公钥是一对儿。也就是说这是一
      个自签名(self-sign)的例子。

      通常情况下,我们会用一个CA的私钥来签署一个CSR。在这个为 Kubernetes
      apiserver 签署身份证的例子里,apiserver 的身份
      证是用一个自签署的CA的私钥来签署的:

      1. $ openssl genrsa -out ca-key.pem 2048
      2. $ openssl req -x509 -new -nodes -key ca-key.pem -days 10000 -out ca.pem -subj "/CN=kube-ca"
      3. $ openssl genrsa -out apiserver-key.pem 2048
      4. $ openssl req -new -key apiserver-key.pem -out apiserver.csr -subj "/CN=kube-apiserver" -config openssl.cnf
      5. $ openssl x509 -req -in apiserver.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out apiserver.pem -days 365 -extensions v3_req -extfile openssl.cnf

      这个例子里,ca-key.pem是Kubernetes管理员自己创建的CA的私钥(其实是密
      钥对)。第二个命令(openssl req -x509 ...)不经过生成CSR的过程,直接
      输出CA的身份证。注意CA的域名是 kube-ca

      接下来三个命令分别创建 apiserver 的私钥,生成 apiserver 的CSR,以及用
      CA 的private key(ca-key.pem)来签署 apiserver 的身份证。

      HTTPS Server

      现在我们有了 server.key 和 。我们可以写一个HTTPS服务程序,
      它私藏 server.key,同时在与任何客户端程序首轮通信的时候通告自己的身
      份证 server.crt。这里有几点需要注意:

      1. 为了确保“私藏”一个文件,我们需要设置其文件系统访问权限为只有owner可
        sign

        1. chmod 400 server.key
      2. 因为我们在生成 server.csr 的时
        候,指定的域名是 localhost,所以必须确保 HTTPS 程序监听 localhost
        虚拟网卡上的端口 443。上面程序里指定的监听地址是"443",只有端口没
        有标识网卡的IP地址或者域名,那么 ListenAndServerTLS 会让程序监听
        本机所有网卡上的 443 端口。

        1. sudo go run server.go &
      3. 同样的原因,客户端必须通过 localhost 访问我们的 HTTPS 服务。在这
        个例子里,localhost 域名意味着只有本机上执行的客户端才能访问。

      我们可以通过浏览器访问我们的 HTTPS server。但是因为server的身份证是我
      们自签署的,浏览器里没有CA的身份证其中的公钥
      可以验证 server.crt,所以浏览器会提示说它不信任我们的HTTPS服务。但是
      如果用户表示信任,还是可以访问的。

      要想消除浏览器的提示,最简单的办法就是把我们为HTTPS服务自签署的身份证
      加入到浏览器里

      实际上,很多公司的运维团队都会生自命为本公司内部的CA,成一个自签署的身
      份证,加入到公司配发的电脑的操作系统或者浏览器里。而本公司内部的很多网
      路服务(报销系统、人事管理系统、考评系统、各种计算资源上的SSH服务)都
      用这个内部CA来签署。这样用公司的电脑,即可访问这些服务。

      用curl

      类似的,我们可以通过加 -k 参数让 curl 信任我们的HTTPS 服务器:

      1. $ /usr/local/Cellar/curl/7.49.1/bin/curl -k https://localhost
      2. hello, world!

      或者我们可以把我们自签署的身份证告诉 curl,让它用这个身份证验证我们的
      HTTPS 服务:

      1. $ curl --cacert server.crt https://localhost
      2. hello, world!

      请注意,Mac OS X 自带的 openssl 版本太低,不支持 Go 语言 http
      package 里实现的高级加密算法,所以我们得用 Homebrew 安装新版本:

      下一步

      从上面操作可以看出来,TLS的具体操作和 OpenSSL 息息相关。关于OpenSSL的
      更多用法,可以参见esse

      当我们用 OpenSSL 创建了CA身份证并且用CA身份证给相关程序签署了各自的身
      份证之后,我们就可以开工写作和调试这些程序了。在
      里,我们介绍如何用Go语言写HTTPS的server和client。