openssl创建CA证书教程

2023-09-21 15:19:16

配置生成CA证书

总示意图:

(1),通过openssl创建CA证书

  • 第一步:创建一个秘钥,这个便是CA证书的根本,之后所有的东西都来自这个秘钥
# 通过rsa算法生成2048位长度的秘钥
openssl genrsa -out myCA.key 2048
  • 第二步:是通过秘钥加密机构信息形成公钥
# 公钥包含了机构信息,在输入下面的指令之后会有一系列的信息输入,
# 这些信息便是机构信息,公司名称地址什么的
# 这里还有一个过期信息,CA证书也会过期,openssl默认是一个月,这里设置为10年
openssl req -new -x509 -key myCA.key -out myCA.cer -days 3650

执行命令过程如下图所示:

参数名称

参数值

Country Name

国家代码,比如中国就是CN

State or Province Name

省名称

Locality Name

城市名称

Organization Name

机构名称

Organizational Unit Name

机构单位名称

Common Name

重点参数:授权给什么,因为机构是根节点所以是授权给自己

Email Address

邮件地址

(2),创建服务器证书

在得到CA证书之后,需要通过 openssl工具对证书进行转换得到公钥( .crt文件)和密钥( .key文件),无论CA证书是怎么来的到这里之后就没有任何区别了,服务器证书的制作流程相较CA证书要复杂一点点。
  • 第一步:通过openssl工具创建服务器的秘钥
# 通过RSA算法生成长度2048位的秘钥
openssl genrsa -out server.key 2048
  • 第二步:这里是创建一个签名请求
首先 https证书的公钥不同于自定义情况下的加密证书,这里需要安装浏览器标准进行配置,首先 openssl默认的证书版本是V1,V1在支持 https时部分浏览器依旧会认为不安全,所以需要使用V3版本;同时 openssl即便是使用V3版本依旧没有附带V3的 subjectAltName字段数据(这里是证书对应的IP地址或者域名,可以用通配符)。但是这些东西命令行没法指定所以需要配置文件,我这里准备了一个:
创建 openssl.cnf 文件,并添加如下内容:
tsa_policy2 = 1.2.3.4.5.6
tsa_policy3 = 1.2.3.4.5.7
[ ca ]
default_ca = CA_default  # The default ca section
[ CA_default ]
dir  = ./demoCA  # Where everything is kept
certs  = $dir/certs  # Where the issued certs are kept
crl_dir  = $dir/crl  # Where the issued crl are kept
database = $dir/index.txt # database index file.
new_certs_dir = $dir/newcerts  # default place for new certs.
certificate = $dir/cacert.pem  # The CA certificate
serial  = $dir/serial   # The current serial number
crlnumber = $dir/crlnumber # the current crl number
crl  = $dir/crl.pem   # The current CRL
private_key = $dir/private/cakey.pem# The private key
RANDFILE = $dir/private/.rand # private random number file
x509_extensions = usr_cert  # The extentions to add to the cert
name_opt  = ca_default  # Subject Name options
cert_opt  = ca_default  # Certificate field options
default_days = 365   # how long to certify for
default_crl_days= 30   # how long before next CRL
default_md = default  # use public key default MD
preserve = no   # keep passed DN ordering
policy  = policy_match
[ policy_match ]
countryName  = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName  = supplied
emailAddress  = optional
[ policy_anything ]
countryName  = optional
stateOrProvinceName = optional
localityName  = optional
organizationName = optional
organizationalUnitName = optional
commonName  = supplied
emailAddress  = optional
[ req ]
default_bits  = 1024
default_keyfile  = privkey.pem
distinguished_name = req_distinguished_name
attributes  = req_attributes
x509_extensions = v3_ca # The extentions to add to the self signed cert
string_mask = utf8only
req_extensions = v3_req # The extensions to add to a certificate request
[ req_distinguished_name ]
countryName   = Country Name (2 letter code)
countryName_default  = CN
countryName_min   = 2
countryName_max   = 2
stateOrProvinceName  = State or Province Name (full name)
stateOrProvinceName_default = BeiJing
localityName   = Locality Name (eg, city)
0.organizationName  = Organization Name (eg, company)
0.organizationName_default = myca
organizationalUnitName  = Organizational Unit Name (eg, section)
commonName   = Common Name (e.g. server FQDN or YOUR name)
commonName_max   = 64
emailAddress   = Email Address
emailAddress_max  = 64
[ req_attributes ]
challengePassword  = A challenge password
challengePassword_min  = 4
challengePassword_max  = 20
unstructuredName  = An optional company name
[ usr_cert ]
basicConstraints=CA:FALSE
nsCertType = client, email, objsign
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
nsComment   = "OpenSSL Generated Certificate"
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
[ svr_cert ]
basicConstraints=CA:FALSE
nsCertType   = server
keyUsage = nonRepudiation, digitalSignature, keyEncipherment, dataEncipherment, keyAgreement
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
extendedKeyUsage = serverAuth,clientAuth
[ v3_req ]
subjectAltName = @alt_names
# 这里是重点,需要将里面配置为最终服务端需要的域名或者IP
# 这里可以写多个,能够自行添加DNS.X = XXXXXX, 支持通配符
[ alt_names ]
DNS.1 = www.k8s-harbor.com
DNS.2 = k8s-harbor.com
[ v3_ca ]
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
basicConstraints = CA:true
[ crl_ext ]
authorityKeyIdentifier=keyid:always
[ proxy_cert_ext ]
basicConstraints=CA:FALSE
nsComment   = "OpenSSL Generated Certificate"
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo
[ tsa ]
default_tsa = tsa_config1 # the default TSA section
[ tsa_config1 ]
dir  = ./demoCA  # TSA root directory
serial  = $dir/tsaserial # The current serial number (mandatory)
crypto_device = builtin  # OpenSSL engine to use for signing
signer_cert = $dir/tsacert.pem  # The TSA signing certificate
     # (optional)
certs  = $dir/cacert.pem # Certificate chain to include in reply
     # (optional)
signer_key = $dir/private/tsakey.pem # The TSA private key (optional)
default_policy = tsa_policy1  # Policy if request did not specify it
     # (optional)
other_policies = tsa_policy2, tsa_policy3 # acceptable policies (optional)
digests  = md5, sha1  # Acceptable message digests (mandatory)
accuracy = secs:1, millisecs:500, microsecs:100 # (optional)
clock_precision_digits  = 0 # number of digits after dot. (optional)
ordering  = yes # Is ordering defined for timestamps?
    # (optional, default: no)
tsa_name  = yes # Must the TSA name be included in the reply?
    # (optional, default: no)
ess_cert_id_chain = no # Must the ESS cert id chain be included?
    # (optional, default: no)

将上面的配置内容保存为openssl.cnf放到生成的服务器证书文件的目录下(注意:修改alt_names里面的域名或者IP为最终部署需要的地址,支持通配符),然后执行创建签名申请文件即可,执行运行:

注意:在 openssl.conf中一定要加有关的域名,然后生成对应服务器的证书的时候也使用域名就可以实现正常的访问了。
# 和创建CA时一样这里需要输入一堆服务器信息,输入项也是相同的。
# 不过在输入Common Name(CN)最好直接输入服务器的IP地址或者域名。
openssl req -config openssl.cnf -new -out server.req -key server.key 

执行命令过程如下图所示:

  • 第三步:通过CA机构证书对服务器证书进行签名认证
这里服务器的公钥是由CA证书的密钥配对加密来的。
# 这里本质上就是将签名请求文件进行签名最终得到服务器的公钥
openssl x509 -req \
-extfile openssl.cnf \
-extensions v3_req \
-CAkey myCA.key \
-CA myCA.cer \
-days 3650 \
-in server.req \
-out server.cer \
-CAcreateserial -CAserial serial
cer证书转成crt证书,命令如下:
openssl x509 -inform PEM -in server.cer -out server.crt

再将crt证书转成cert证书,命令如下:

openssl x509 -inform PEM -in server.crt -out server.cert

为 harbor 和 docker 颁发证书

(1) 将服务端证书拷贝至 /data/cert/目录下

mkdir -p /data/cert/
cp server.crt /data/cert/
cp server.key /data/cert/

(2) 将 server.crt 文件拷贝到docker的证书目录下,注意替换为自己的域名

mkdir -p /etc/docker/certs.d/www.k8s-harbor.com/
cp server.crt /etc/docker/certs.d/www.k8s-harbor.com/

这里需要注意的是,如果nginx中对https没有使用默认的443端口,修改为其他端口了,则此时的需要创建的目录为:/etc/docker/certs.d/yourdomain.com:port, 或者 /etc/docker/certs.d/harbor_IP:port

(3) 重启docker

systemctl restart docker

修改 harbor.yml 配置文件

修改harbor.yml配置 (位于/usr/local/harbor),开启 https 配置。

如下前面部署 http 模式的时候将https的部分注释了,这里要将 https 的配置放开注释,而且修改证书的文件路径,如下所示
# Configuration file of Harbor

# The IP address or hostname to access admin UI and registry service.
# DO NOT use localhost or 127.0.0.1, because Harbor needs to be accessed by external clients.
hostname: harbor.ninexch.com #更改为本地解析IP的域名

# http related config
http:
  # port for http, default is 80. If https enabled, this port will redirect to https port
  port: 80
# https related config
https: #开启Https
  # https port for harbor, default is 443
  port: 443 #开启端口
  # The path of cert and key files for nginx
  certificate: /data/cert/server.crt #指定SSL公有证书
  private_key: /data/cert/server.key #指定SSL私有证书

然后执行如下命令更新 harbor

# 重新安装(harbor相关容器会被删除,数据正常不会丢失)
./install.sh

# 重新编译配置文件(数据会丢失) -- no use
./prepare
docker-compose down -v
docker-compose up -d

Nginx 配置 https

修改 nginx.conf 配置,增加监听 443 端口的,跳转到harbor的8443端口,此外在这里需要指定证书文件的路径

server {
    listen 443 ssl;
    server_name www.k8s-harbor.com;
     
    ssl_certificate /data/cert/server.crt;
    ssl_certificate_key /data/cert/server.key;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
     
    ssl_session_cache shared:SSL:1m;
    ssl_session_timeout 5m;
 
    location / {
        client_max_body_size 1024M;
        client_body_buffer_size 1024M;
        proxy_redirect off;
        proxy_pass https://172.22.27.162:8443;
         
        proxy_set_header Host $host;
         
        proxy_set_header X-Real-IP $remote_addr;
         
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
     
    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
        root html;
    }
}

然后将 http 的跳转到 https

server {
    listen 80;
    server_name www.k8s-harbor.com;
    return 301 https://www.k8s-harbor.com$request_uri;
}

然后重新加载配置文件

nginx -s reload
此时在浏览器就可以 通过 http://www.k8s-harbor.comhttps://www.k8s-harbor.com 访问,当使用 http://www.k8s-harbor.com 时会发现自动跳转到 https://www.k8s-harbor.com

Nginx 配置可能遇到额问题

注意,如果出现类似如下错误:

nginx: [emerg] unknown directive "ssl_certificate" in /usr/local/nginx/conf/nginx.conf

或者类似如下错误;

error: SSL modules require the OpenSSL library.

说明 nginx 没有安装ssl,此时进入nginx的源码目录,执行如下命令

./configure \
--prefix=/usr/local/nginx \
--with-http_stub_status_module \
--with-http_ssl_module \
--with-openssl=/usr/local/src/openssl-1.1.1o

其中:

  • /usr/local/src/openssl-1.1.1o 目录 为openssl 源码包的解压目录

然后使用 make 编译,注意,不要使用 make install,否则会覆盖

make

然后备份原有的nginx 命令,并将新编译的nginx拷贝的nginx命令所在的目录

# 将原有的命令重命名备份
mv /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bark

# 将新编译的nginx命令拷贝到nginx命令的目录下
cp objs/nginx /usr/local/nginx/sbin/

然后执行 nginx -V ,如下,出现 —with-http_ssl_module 表示安装成功

[root@redrose2100 nginx-1.21.4]# nginx -V
nginx version: nginx/1.21.4
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC)
built with OpenSSL 1.1.1o 3 May 2022
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-openssl=/usr/local/src/openssl-1.1.1o
[root@redrose2100 nginx-1.21.4]#

然后再次执行如下命令重新加载nginx配置

nginx -s reload
更多推荐

STM32F4X UCOSIII 信号量

STM32F4XUCOSIII信号量信号量概念信号量工作机制停车场问题UCOSIII信号量工作机制信号量常用API信号量创建信号量删除释放信号量获取信号量UCOSIII信号量例程在以往的裸机编程中,如果我们需要判断某个事件是否已经发生,通常会使用一个标志位来进行判断,当事件已经发生时,就将该标志位置1,否则就将该标志位

pytorch 入门(一)

本文为🔗小白入门Pytorch内部限免文章参考本文所写记录性文章,请在文章开头注明以下内容,复制粘贴即可⬇️基础版模板⬇️🐳我正在和鲸社区参加“小白入门Pytorch”https://www.heywhale.com/home/activity/detail/64e2ce39e585b8f50bf6c2e7,以下是

frame切换/窗口切换/选择框

frame获取焦点我们操作一个东西就要获得他的焦点才行!!!!例子:fromseleniumimportwebdriverfromselenium.webdriver.common.byimportBywd=webdriver.Chrome()wd.get('https://cdn2.byhy.net/files/se

DevOps与CI/CD常见面试问题汇总

01您能告诉我们DevOps和Agile(敏捷)之间的根本区别吗?答:尽管DevOps与敏捷方法(这是最流行的SDLC[SoftwareDevelopmentLifeCycle]方法之一)有一些相似之处,但两者在软件开发方面都是根本不同的方法。以下是两者之间的各种基本差异:敏捷方法敏捷方法适用于敏捷中的开发同时敏捷方法

分享基于SringBoot足球训练俱乐部系统Python训练打卡系统(源码+调试+lw)

💕💕作者:计算机源码社💕💕个人简介:本人七年开发经验,擅长Java、Python、PHP、.NET、微信小程序、爬虫、大数据等,大家有这一块的问题可以一起交流!💕💕学习资料、程序开发、技术解答、文档报告💕💕如需要源码,可以扫取文章下方二维码联系咨询💕💕JavaWeb项目💕💕微信小程序项目💕💕

一线大厂Redis高并发缓存架构实战与性能优化

多级缓存架构缓存设计缓存穿透缓存穿透是指查询一个根本不存在的数据,缓存层和存储层都不会命中,通常出于容错的考虑,如果从存储层查不到数据则不写入缓存层。缓存穿透将导致不存在的数据每次请求都要到存储层去查询,失去了缓存保护后端存储的意义。造成缓存穿透的基本原因有两个:第一,自身业务代码或者数据出现问题。第二,一些恶意攻击、

SpringMVC之JSON返回及异常处理机制

目录一、JSON处理1.1导入依赖1.2配置Spring-mvc.xml1.3@ResponseBody注解使用​编辑1.4Jackson1.4.1定义1.4.2用途1.4.3用法1.4.4常用注解1.5作用二、统一异常处理2.1为什么要全局异常处理?2.2异常处理思路2.3SpringMVC异常分类2.4综合案例2.

【双系统】忘记Ubuntu登录密码,应该重装系统还是换新电脑?

电脑装的双系统,但是好几个月都用的是服务器,并没有用本地电脑的另一个系统(Ubuntu20.04)。开机不小心选到了Ubuntu,结果却忘记了登录密码。文章目录一、修改登录密码二、删除/解锁秘钥环三、Linux系统的root用户密码问题一、修改登录密码通过以下步骤来重置密码:重启你的电脑。在GRUB加载页面时,按下Sh

.Net IDE智能提示汉化(.Net6、AspNetCore)

先上现成的.net6汉化文件,可以手动下载后参照如何为.NET安装本地化的IntelliSense文件进行安装。或者使用后文的工具进行自动安装。无对照英文在前中文在前汉化内容来自官方在线文档,某些内容可能存在明显的机翻痕迹。上一些效果图:.Net6之前的版本汉化.net6之前的版本,微软官方提供了本地化包,可以在Dow

MQTT Qt 客户端开发记录

1.MQTT介绍MQTT是一种常用的物联网协议。MQTT(MessageQueuingTelemetryTransport)是一种轻量级的发布/订阅通信协议,用于在物联网(IoT)和机器对机器(M2M)通信中传输消息。MQTT协议被设计用于在低带宽和不稳定网络环境下工作,以及在设备和服务器之间实现可靠的通信。MQTT协

什么是媒体邀约?邀请媒体的流程

传媒如春雨,润物细无声,大家好,我是51媒体网胡老师。媒体邀约,简单来说,是企业或组织为了某个特定的事件、活动或新闻,主动邀请媒体进行报道或参与。这个过程旨在确保媒体的出席并进一步传播相关信息,从而达到更广泛的受众。邀请媒体的流程大致可以分为以下几个步骤:媒体媒体宣传的目的:明确为何需要邀请媒体,是为了推广新产品、发布

热文推荐