使用Lego进行证书的申请和更新

news2024/9/23 7:33:07

姊妹篇: 使用Let’s Encrypt 申请通配符证书


关于acme 协议


ACME是自动证书管理环境(Automatic Certificate Management Environment)的缩写,是一个由IETF(Internet Engineering Task Force)制定的协议标准,用于自动化证书颁发和管理。ACME协议的主要目的是使得证书颁发过程自动化、安全化和可扩展化,同时减少人工干预的成本和风险。

ACME协议的核心是证书颁发机构(CA)和客户端之间的交互过程。客户端可以是一个Web服务器、一个容器或者一个操作系统。客户端使用ACME协议与CA通信,申请证书、更新证书或者撤销证书。

ACME协议使用了基于HTTP的RESTful API协议,支持多种验证方式,包括HTTP验证、DNS验证和TLS-SNI验证。其中,HTTP验证是最常用的验证方式。

ACME协议的流程如下:

  1. 客户端向CA发送证书请求,并提供验证信息。

  2. CA验证客户端提供的信息,如果验证通过,则向客户端颁发一个签名证书。

  3. 客户端使用签名证书进行加密通信。

  4. 客户端定期更新证书,以保证证书的有效性。

ACME协议的实现需要CA和客户端双方的支持,目前已经有很多主流的CA和客户端支持ACME协议,例如Let’s Encrypt、Certbot、ACME.sh等。

以Let’s Encr域名如何支持https访问ypt为例,Let’s Encrypt是一个免费的证书颁发机构,它支持ACME协议,并提供了Certbot客户端工具,可以自动化地申请、更新和管理SSL证书。Certbot客户端工具可以通过命令行工具或者Web界面进行操作。

Certbot客户端工具的实现原理如下:

  1. 客户端向Let’s Encrypt发送证书请求,并提供验证信息。

  2. Let’s Encrypt验证客户端提供的信息,如果验证通过,则向客户端颁发一个签名证书。

  3. Certbot客户端工具将签名证书部署到Web服务器上,并自动配置SSL证书。

  4. Certbot客户端工具定期更新证书,以保证证书的有效性。

ACME协议使得SSL证书的颁发和管理变得自动化、安全化和可扩展化,让网站管理员不再需要手动申请和更新SSL证书,从而节省了时间和精力。

自动证书管理环境(ACME)

自动证书更新环境

更多可参考 acme自动证书管理系统

几种工具


基于ACME协议自动更新证书的工具 大致可以分成两类,一类是是独立的,脱离于项目,一般是一个命令行工具,或者shell脚本,如Certbot(python实现),acme.sh, mkcert(这个只能制作本地信任的证书,对localhost可用, 作者是给Go密码学库做了很多贡献的意大利开发者FiloSottile)


图片来源

另一类是和项目集成在一起,可以在项目中,依据逻辑等判断,进行相应操作,以Go语言为例, 比较知名的如 certmagic(Caddy下面的一个项目)

CertMagic是一个用于Go程序的自动HTTPS库,可完全管理TLS证书的签发和更新。通过添加一行代码,你的Go应用程序即可安全地通过TLS提供服务,无需处理证书。与其他Go的ACME客户端库相比,CertMagic支持完整的ACME功能集,并在成熟性和可靠性方面领先。该库具有全自动证书管理、一行代码实现HTTPS服务器、对系统几乎所有方面的完全控制等特点。它支持多个证书颁发机构,解决了HTTP、TLS-ALPN和DNS等常见ACME挑战,并具有强大的错误处理、分布式挑战解决等功能。 CertMagic可以与任何符合ACME规范RFC 8555的证书颁发机构一起使用,支持通配符证书、OCSP stapling等功能,适用于Mac、Windows、Linux、BSD、Android等多平台。

Caddy 源码阅读

CertMagic源码分析 » 1 -Cermagic整体结构

这篇内容介绍了一个名为CertMagic的Go语言库,用于实现自动化的HTTPS证书管理。CertMagic是Caddy Web服务器使用的库,它提供了简单而强大的TLS自动化功能。通过在Go应用程序中添加一行代码,即可实现安全的HTTPS服务,无需手动处理证书。与其他Go语言ACME客户端库相比,CertMagic是最成熟、稳健和强大的集成之一,支持完整的ACME功能。该库具有自动化证书管理、支持多个证书颁发机构、解决常见ACME挑战、高效的分布式管理等特点。CertMagic支持使用Let’s Encrypt进行自动HTTPS,并提供了丰富的功能和配置选项,适用于各种TLS需求。


关于 Lego


本篇重点介绍兼具二者功能Lego—既能作为工具使用,又可作为项目进行集成


通过 Lego 工具获取 HTTPS 证书

Lego和Let’s Encrypt 官方推荐的certbot,以及acme.sh都是差不多功用的东西, 只不过Lego是Go实现的,最终编译成一个二进制文件。除此还可以集成到Go项目中,可根据项目业务逻辑进行证书更新的操作


安装


从github上wget tar包,解压,得到二进制文件


wget -c https://github.com/go-acme/lego/releases/download/v4.14.2/lego_v4.14.2_linux_amd64.tar.gz
tar -zxvf lego_v4.14.2_linux_amd64.tar.gz
rm lego_v4.14.2_linux_amd64.tar.gz
chmod +x lego
// 把二进制文件移动到任意path路径下

lego -h 输出帮助信息


Lego作为命令行工具离线使用



lego 可以直接使用命令行,和cerebot,acme.sh一样

acme 协议一般有两种方式验证: http 和 dns 验证

其中 http方式需要侵入Nginx;

所以如果域名在自己手中,一般优先使用DNS方式。 需要在域名解析商那里新增TXT记录用来验证该域名属于你( 另外域名服务商一般提供key和secret,可以自动化验证)

这里有每一个DNS厂商获取凭证的说明

以阿里云为例:(阿里云提供的是全局的ALICLOUD_ACCESS_KEY和ALICLOUD_SECRET_KEY,如果授权了,能够操作全部资源)

访问控制 > 用户 > 新建用户

登陆名: dns
显示名: dns
访问方式: 编程式访问

创建后,添加权限: AliyunDNSFullAccess

最终得到 AccessKey ID、AccessKeySecret 两个字符串,务必保存好key和secret

用 Lego 实现 Let‘s Encrypt HTTPS 通配符证书

ALICLOUD_ACCESS_KEY=your_key \
ALICLOUD_SECRET_KEY=your_secret \
./lego --email your_mail@gmail.com --dns alidns --domains *.your_domain.com run


DNS Challenge 方式 手动更新:

# --renew-hook="sudo  /usr/sbin/nginx -s reload",表示更新证书成功后执行的命令,即重启nginx


ALICLOUD_ACCESS_KEY=your_key \
ALICLOUD_SECRET_KEY=your_secret \
lego --email="your_mail@gmail.com" --domains="*.wode.tech"  --dns="alidns" renew --days=30 --renew-hook="sudo  /usr/sbin/nginx -s reload"

新申请的证书有效期为90天。 低于30天时才能更新证书


DNS Challenge 方式 自动更新:


可以配置定时任务,自动更新~

autorenew.sh:

#!/bin/sh

ALICLOUD_ACCESS_KEY=your_key \
ALICLOUD_SECRET_KEY=your_secret \
lego --email="your_mail@gmail.com" --domains="*.wode.tech"  --dns="alidns" renew --days=30 --renew-hook="sudo  /usr/sbin/nginx -s reload"

配置定时任务,每天执行一次


(如果DNS服务商是dnspod: 使用lego签发Let’s Encrypt的证书)


HTTP Challenge 方式 手动更新:


某些场景下,无法使用DNS Challenge的方式进行验证(比如这个域名aaa.com在别人手里,只是通过Cname指向了我们的一个域名bbb.com; 这时我们其实可以为aaa.com申请&维护证书,是不是有点颠覆之前的认知…), 就必须使用HTTP Challenge的方式, 会向Nginx里写入一段配置

(但是 泛域名证书只能通过DNS验证)

没有证书之前:

# 此命令会占用80端口
lego --email="your_email@163.com" --domains="www.your_domain.com" --http run

# 如果80端口已经占用请此命令;(还需要在nginx里新增配置,不然会如下图报错)

lego --email="your_email@163.com" --domains="www.your_domain.com" --http --http.port :8080 run

# 如果80端口被nginx占用了,可以在nginx.conf配置文件中的http块的server块中添加如下配置。
location /.well-known/acme-challenge {
    proxy_pass http://127.0.0.1:8080;
    proxy_set_header Host $host;
}


体验下来确实可以…都没有去碰 my_domain.com 这个域名的DNS解析


HTTP Challenge 方式 自动更新:


lego --email="your_mail@163.com" --domains="www.your_domain.com" --http --http.port :8080 renew --days 30

现在还没到能更新的时间

也可以写成脚本,配置为定时任务,每天执行一次~


Lego使用HTTP或DNS生成SSL通配符证书


Let’s Encrypt

HTTP验证的方式,不支持申请泛域名证书(例如 *.your_domain.tech),而是一个特定的二级域名证书,可以一次申请多个

通配符证书只能通过 DNS challenge 生成,因为这样才能保证你是这个域名的完全拥有者;

如果是HTTP的方式,别人比如123.aaa.com cname过来,我就能申请其域名的通配符证书的话,把他整个aaa.com都能影响了,显然不合理

所谓的通配符,也只是通配同级, 比如 *.world.com, 只是对任意的xxx.world.com有效,对于其一级域名world.co, 三级域名a.b.world.com 都是无效的~


另外有可能使用或更新https证书后,浏览器还是显示不安全, 这很有可能是该网站有请求其他http的静态资源导致的…

部署SSL后,为何网站还是显示不安全?


这篇是把lego集成进脚本使用 使用 lego 申请 let’s encrypt 证书

Lego使用HTTP或DNS生成SSL通配符证书

使用lego申请Let’s Encrypt通配符证书



Lego集成到Go项目中使用


如果想集成进Go项目里,也提供了在Go代码中使用的方式

以下代码参考自 免费!让Https证书不再成为烦恼

package get_certificate_from_lego
 
import (
    "crypto"
    "crypto/ecdsa"
    "crypto/elliptic"
    "crypto/rand"
 
    "github.com/go-acme/lego/v4/certcrypto"
    "github.com/go-acme/lego/v4/certificate"
    "github.com/go-acme/lego/v4/challenge/http01"
    "github.com/go-acme/lego/v4/challenge/tlsalpn01"
    "github.com/go-acme/lego/v4/lego"
    "github.com/go-acme/lego/v4/registration"
)
 
const (
    EmailStr  = "your_mail@163.com" // 修改为自己的电子邮件
    OneDomain = "www.your_domain.com"  // 修改为自己的域名
)
 
type MyUser struct {
    Email        string
    Registration *registration.Resource
    key          crypto.PrivateKey
}
 
func (u *MyUser) GetEmail() string {
    return u.Email
}
func (u MyUser) GetRegistration() *registration.Resource {
    return u.Registration
}
func (u *MyUser) GetPrivateKey() crypto.PrivateKey {
    return u.key
}
 
func GetCertificateFromLego() (*certificate.Resource, error) {
    // 创建myUser用户对象。新对象需要email和私钥才能启动,私钥需自己生成
    privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
    if err != nil {
        return nil, err
    }
 
    myUser := MyUser{
        Email: EmailStr,
        key:   privateKey,
    }
 
    config := lego.NewConfig(&myUser)
 
    // 此处配置密钥的类型和密钥申请的地址,记得上线后替换成 lego.LEDirectoryProduction ,测试环境下就用 lego.LEDirectoryStaging
    config.CADirURL = lego.LEDirectoryStaging
    config.Certificate.KeyType = certcrypto.RSA2048
 
    // 创建一个client与CA服务器通信
    client, err := lego.NewClient(config)
    if err != nil {
        return nil, err
    }
 
    // 此处需要进行申请证书的chanlldge,必须监听80和443端口,这样才能让Let's Encrypt访问到我们的服务器
    err = client.Challenge.SetHTTP01Provider(http01.NewProviderServer("", "80"))
    if err != nil {
        return nil, err
    }
    err = client.Challenge.SetTLSALPN01Provider(tlsalpn01.NewProviderServer("", "443"))
    if err != nil {
        return nil, err
    }
 
    // 把这个客户端注册,传递给myUser用户里
    reg, err := client.Registration.Register(registration.RegisterOptions{TermsOfServiceAgreed: true})
    if err != nil {
        return nil, err
    }
    myUser.Registration = reg
 
    request := certificate.ObtainRequest{
        Domains: []string{OneDomain}, // 这里如果有多个,就写多个就好了,可以是多个域名
        Bundle:  true,                // 这里如果是true,将把颁发者证书一起返回,也就是返回里面certificates.IssuerCertificate
    }
    // 开始申请证书
    certificates, err := client.Certificate.Obtain(request)
    if err != nil {
        return nil, err
    }
    // 申请完了后,里面会带有证书的PrivateKey Certificate,都为[]byte格式,需要存储的自行转为string即可
    return certificates, nil
}
 
// 如果要进行续订,可将certificates, err := client.Certificate.Obtain(request)替换为certificates, err := client.Certificate.Renew(request)
// renew里面的参数就很简单了,第一个参数就是第一次申请返回的指针的值certificates,第二个参数bundle上面已经讲过传true即可,后面两个参数一个传false,一个传空字符串""即可。开启PAC自动配置

package main
import (
    "crypto/tls"
    "crypto/x509"
    "fmt"
    "log"
 
    "server/get_certificate_from_lego"
)
func main(){
    cs, err := get_certificate_from_lego.GetCertificateFromLego()
    if err != nil {
        log.Fatalln("obtains certificate:", err)
    }
    ca, err := tls.X509KeyPair(cs.Certificate, cs.PrivateKey)
    if err != nil {
        log.Fatalln(err)
    }
    if ca.Leaf, err = x509.ParseCertificate(ca.Certificate[0]); err != nil {
        log.Fatalln(err)
    }
    fmt.Println(ca.Leaf)
}

更多相关资料:

go用lego获取ssl证书

go用lego获取ssl证书

dcert

lego-certmgr 一款使用 lego 生成域名证书的代理服务


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1922559.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

gd32F470串口重定义

c代码: /** Author: Bleaach008* Date: 2024-07-10 17:31:01* LastEditTime: 2024-07-11 09:42:06* FilePath: \MDK-ARMd:\Code\GD32\GD01_UART\MyApplication\Public.c* Description:** Copyright (c) 2024 by 008, All Rights Reserved.*/ /* Includes ----------…

QFileDialog的简单了解

ps:写了点垃圾(哈哈哈) 现在感觉Qt库应该是调用了Windows提供的这块的接口了。 它继承自QDialog 这是Windows自己的文件夹 这是两者的对比图: 通过看QFileDialog的源码,来分析它是怎么实现这样的效果的。 源码组成…

面试篇-Java-5+设计模式

文章目录 前言一、你知道工厂方法模式吗1.1 你有使用过简单工厂模式吗1.2 你有使用过简单工厂方法模式吗1.3 你有使用过抽象工厂方法模式吗1.4 你有使用过策略模式吗 二、你们项目中是怎么使用设计模式的呢2.1 策略模式 工厂模式 实现不同的方式的登录2.1.1 定义一个登录的接口…

SCI一区级 | Matlab实现NGO-CNN-LSTM-Mutilhead-Attention多变量时间序列预测

SCI一区级 | Matlab实现NGO-CNN-LSTM-Mutilhead-Attention多变量时间序列预测 目录 SCI一区级 | Matlab实现NGO-CNN-LSTM-Mutilhead-Attention多变量时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.Matlab实现NGO-CNN-LSTM-Mutilhead-Attention北方苍鹰算…

怎么用PPT录制微课?详细步骤解析!

随着信息技术的不断发展,微课作为一种新型的教学形式,因其短小精悍、针对性强等特点,在教育领域得到了广泛的应用。而PPT作为一款常用的演示工具,不仅可以用来制作课件,还可以利用其内置的录屏功能或结合专业的录屏软件…

【机器学习】Exam4

实现线性不可分logistic逻辑回归 我们目前所学的都是线性回归,例如 y w 1 x 1 w 2 x 2 b y w_1x_1w_2x_2b yw1​x1​w2​x2​b 用肉眼来看数据集的话不难发现,线性回归没有用了,那么根据课程所学,我们是不是可以增加 x 3 x…

有必要把共享服务器升级到VPS吗?

根据自己的需求来选择是否升级,虚拟专用服务器 (VPS) 是一种托管解决方案,它以低得多的成本提供专用服务器的大部分功能。使用 VPS,您的虚拟服务器将与在其上运行的其他虚拟服务器共享硬件服务器的资源。但是,与传统的共享托管&am…

# Redis 入门到精通(一)数据类型(4)

Redis 入门到精通(一)数据类型(4) 一、redis 数据类型–sorted_set实现时效性任务管理 1、sorted_set 类型数据操作的注意事项 score 保存的数据存储空间是64位,如果是整数范围是-9007199254740992~9007199254740992…

内网对抗-基石框架篇域树林域森林架构信任关系多域成员层级信息收集环境搭建

知识点: 1、基石框架篇-域树&域林架构-权限控制-用户和网络 2、基石框架篇-域树&域林架构-环境搭建-准备和加入 3、基石框架篇-域树&域林架构-信息收集-手工和工具1、工作组(局域网) 将不同的计算机按照功能分别列入不同的工作组。想要访问某个部门的…

PostgreSQL 怎样处理数据仓库中维度表和事实表的关联性能?

文章目录 PostgreSQL 中维度表和事实表关联性能的处理 PostgreSQL 中维度表和事实表关联性能的处理 在数据仓库的领域中,PostgreSQL 作为一款强大的关系型数据库管理系统,对于处理维度表和事实表的关联性能是一个关键的问题。维度表和事实表的关联是数据…

基于B站视频评论的文本分析,采用包括文本聚类分析、LDA主题分析、网络语义分析

研究主题 本研究旨在通过对B站视频评论数据进行文本分析,揭示用户评论的主题、情感倾向和语义结构,助力商业决策。主要技术手段包括Python爬虫、LDA主题分析、聚类分析和语义网络分析。首先,利用Python爬虫采集大量评论数据并进行预处理。运…

Hadoop3:动态扩容之新增一台机器的初始化工作

一、需求描述 给Hadoop集群动态扩容一个节点 那么,这个节点是全新的,我们需要做哪些准备工作,才能将它融入集群了? 二、初始化配置 1、修改IP和hostname vim /etc/sysconfig/network-scripts/ifcfg-ens33 vim /etc/hostname2、…

激活交通运输创新活力 推进户外安全指数——北三车载终端TD3D:准确追踪 应急救援

根据交通运输部办公厅发布《关于充分发挥全国道路货运车辆公共监管与服务平台作用支撑行业高质量发展的意见》(下称《意见》)。《意见》提出,要持续拓展货运平台服务功能,加快推动北斗终端应用。 《意见》提出,加快单…

【eNSP模拟实验】单臂路由实现VLAN间通信

实验需求 如下图所示,辅导员办公室需要访问处在不同vlan的学生管理服务器的文件,那么如何实现两台终端相互通信呢?我们可以使用单臂路由的方式来实现。 单臂路由(router-on-a-stick)是指在路由器的一个接口上通过配置…

Hadoop-25 Sqoop迁移 增量数据导入 CDC 变化数据捕获 差量同步数据 触发器 快照 日志

章节内容 上节我们完成了如下的内容: Sqoop MySQL迁移到HiveSqoop Hive迁移数据到MySQL编写脚本进行数据导入导出测试 背景介绍 这里是三台公网云服务器,每台 2C4G,搭建一个Hadoop的学习环境,供我学习。 之前已经在 VM 虚拟机…

某某会员小程序后端性能优化

背景 某某会员小程序后台提供开放平台能力,为三方油站提供会员积分、优惠劵等api。当用户在油站加油,油站收银会调用我们系统为用户发放积分、优惠劵等。用户反馈慢,三方调用发放积分接口性能极低,耗时30s; 接口情况…

短视频SEO矩阵系统:源码开发与部署全攻略

在数字化时代,短视频已成为人们获取信息、娱乐休闲的重要方式。随着短视频平台的兴起,如何让自己的内容在众多视频中脱颖而出,成为每个创作者和内容运营者关注的焦点。本文将为您深入解析短视频SEO矩阵系统的源码开发与部署,助您在…

【原创教程】埃斯顿机器人:弯管机推力解决方式(上)

现的功能及应用的场合 本项目为弯管机设备改造工程,在不破坏设备原有的功能的情况下通过只更换设备原来的永宏PLC,使弯管机能够与埃斯顿机器人进行信号交互,通过机器人对弯管机进行上料、下料动作,即节约了人工成本,又提高了生产效率。 本文所述内容为“弯管机推力”的解决…

【设计模式】装饰模式

设计模式 【设计模式】工厂方法模式【设计模式】抽象工厂模式【设计模式】单例模式【设计模式】策略模式【设计模式】观察者模式【设计模式】装饰模式 一、介绍 装饰模式是一种结构型设计模式,它允许你通过将对象和对象装饰器分离来扩展对象的功能。装饰模式是一种动…

虚拟机vmware网络设置

一、网络分类 打开vmware workstation网络编辑器可以知道有三种网络类型,分别是:桥接模式、nat模式、仅主机模式。 1、桥接模式 桥接模式是将主机网卡与虚拟机虚拟的网卡利用虚拟网桥进行通信。在桥接的作用下, 类似于把物理主机虚拟为一个交换机, 所有设…