最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

如何使用工具自動(dòng)監(jiān)測SSL證書有效期并發(fā)送提醒郵件

 更新時(shí)間:2024年10月01日 16:46:31   作者:花酒鋤作田  
本文介紹了如何開發(fā)一個(gè)工具,用于每日檢測SSL證書剩余有效天數(shù)并通過郵件發(fā)送提醒,工具基于命令行,通過SMTP協(xié)議發(fā)送郵件,需配置SMTP連接信息,本文還提供了配置文件樣例及代碼實(shí)現(xiàn),幫助用戶輕松部署和使用該工具

前言

自從云廠商的免費(fèi)ssl證書改成3個(gè)月,而且證書數(shù)量還是20個(gè)之后,自己網(wǎng)站的ssl證書就換成了其它免費(fèi)方案。但是免費(fèi)方案不會(huì)提醒證書過期,所以寫個(gè)工具每天定時(shí)查詢證書剩余有效天數(shù),如果證書即將過期,就發(fā)送郵件提醒。

基本實(shí)現(xiàn)

最基本的代碼功能就是檢測網(wǎng)站ssl證書的有效天數(shù),可以用命令行傳參的方式指定網(wǎng)站域名。

package main

import (
	"crypto/tls"
	"flag"
	"fmt"
	"net"
	"os"
	"sync"
	"time"
)

var (
	port int
	wg   sync.WaitGroup
)

func checkssl(domain string, port int) {
	defer wg.Done()
	host := fmt.Sprintf("%s:%d", domain, port)
	conn, err := tls.DialWithDialer(&net.Dialer{
		Timeout:  time.Second * 5,
		Deadline: time.Now().Add(time.Second * 5),
	}, "tcp", host, &tls.Config{InsecureSkipVerify: true})
	if err != nil {
		fmt.Println(err)
		return
	}
	defer conn.Close()

	stats := conn.ConnectionState()
	certs := stats.PeerCertificates[0]
	localtz, _ := time.LoadLocation("Asia/Shanghai")
	issueTime := certs.NotBefore.In(localtz)
	expireTime := certs.NotAfter.In(localtz)

	today := time.Now().In(localtz)
	dayLeft := int(expireTime.Sub(today).Hours() / 24)
	fmt.Printf("%s, issue time: %v, expire time: %v, days left: %v\n", domain, issueTime, expireTime, dayLeft)
}

func main() {
	flag.IntVar(&port, "p", 443, "port, example: ./checkssl -p 1443 <domain name>")
	flag.Parse()
	positionArgs := flag.Args()
	if len(positionArgs) == 0 {
		fmt.Println("Error: Missing domain name")
		fmt.Println("Usage: ./checkssl <domain name>")
		os.Exit(1)
	}

	wg.Add(len(positionArgs))
	for _, arg := range positionArgs {
		go checkssl(arg, port)
	}
	wg.Wait()
}

使用示例

# 1. 編譯
go build
# 2. 命令行傳參的方式指定域名
./check-ssl baidu.com ithome.com qq.com

# 輸出
baidu.com, issue time: 2024-01-30 08:00:00 +0800 CST, expire time: 2025-03-02 07:59:59 +0800 CST, days left: 187
ithome.com, issue time: 2024-01-22 08:00:00 +0800 CST, expire time: 2025-02-22 07:59:59 +0800 CST, days left: 179
qq.com, issue time: 2024-06-04 08:00:00 +0800 CST, expire time: 2025-06-11 07:59:59 +0800 CST, days left: 288

完善功能

需要完善的功能主要是發(fā)送郵件,這里使用SMTP協(xié)議來發(fā)送郵件。如果跟我一樣用的是163郵箱,則需要先去獲取一個(gè)SMTP的授權(quán)碼。

因?yàn)樾枰渲肧MTP的連接信息,所以改成了用文件來傳入配置,也方便后期修改。配置文件config.yaml示例:

domains:
  - baidu.com
  - qq.com

email:
  smtp:
    host: "smtp.163.com"  # smtp服務(wù)器的地址
    port: 465  # 因?yàn)樵品?wù)器屏蔽了25端口, 只能使用tls加密的465端口
    from: ""   # 發(fā)送方郵箱
    token: ""  # 授權(quán)碼
  sendto:
    - "qq@qq.com"  # 接收方的郵箱地址
  expire: 7  # 證書剩余有效天數(shù), 小于7天時(shí)發(fā)送郵件提醒

讀取配置的代碼文件config.go,使用viper來讀取配置文件。

package main

import "github.com/spf13/viper"

var (
	v *viper.Viper
)

type SMTPServer struct {
	Host  string
	Port  int
	Token string
	From  string
}

func initViper() {
	v = viper.New()
	v.AddConfigPath(".")
	v.SetConfigType("yaml")
	v.SetConfigFile(configfile)
	err := v.ReadInConfig()
	if err != nil {
		panic(err)
	}
}

type configer struct{}

func NewConfiger() configer {
	if v == nil {
		initViper()
	}
	return configer{}
}

func (c configer) GetSMTPServer() SMTPServer {
	return SMTPServer{
		Host:  v.GetString("email.smtp.host"),
		Port:  v.GetInt("email.smtp.port"),
		Token: v.GetString("email.smtp.token"),
		From:  v.GetString("email.smtp.from"),
	}
}

func (c configer) GetDomains() []string {
	return v.GetStringSlice("domains")
}

func (c configer) GetSendTos() []string {
	return v.GetStringSlice("email.sendto")
}

func (c configer) GetExpiry() int {
	return v.GetInt("email.expire")
}

發(fā)送郵件的相關(guān)代碼文件:notify.go

package main

import (
	"crypto/tls"
	"fmt"
	"net/smtp"

	"github.com/jordan-wright/email"
)

type Postman struct {
	SmtpServer SMTPServer
	SendTos    []string
}

func (p Postman) SendEmail(domain string, dayleft int) {
	auth := smtp.PlainAuth("", p.SmtpServer.From, p.SmtpServer.Token, p.SmtpServer.Host)
	e := &email.Email{
		To:      p.SendTos,
		From:    fmt.Sprintf("YXHYW <%s>", p.SmtpServer.From),
		Subject: fmt.Sprintf("域名 %s SSL證書過期提醒", domain),
		Text:    []byte(fmt.Sprintf("域名 %s 的SSL證書即將過期, 剩余有效期 %d 天", domain, dayleft)),
	}
	// err := e.Send(fmt.Sprintf("%s:%d", p.SmtpServer.Host, p.SmtpServer.Port), auth)
	addr := fmt.Sprintf("%s:%d", p.SmtpServer.Host, p.SmtpServer.Port)
	fmt.Println("SMTP Server addr: ", addr)
	err := e.SendWithTLS(addr, auth, &tls.Config{
		InsecureSkipVerify: false,
		ServerName:         p.SmtpServer.Host,
	})
	if err != nil {
		fmt.Printf("Send email failed, %v\n", err)
	}
}

主體代碼文件main.go,主要修改地方:檢測到證書即將過期后,調(diào)用發(fā)送郵件的相關(guān)方法。

package main

import (
	"crypto/tls"
	"flag"
	"fmt"
	"net"
	"sync"
	"time"
)

var (
	port       int
	configfile string
	wg         sync.WaitGroup
	c          configer = NewConfiger()
)

func checkssl(domain string, port int) {
	defer wg.Done()
	host := fmt.Sprintf("%s:%d", domain, port)
	conn, err := tls.DialWithDialer(&net.Dialer{
		Timeout:  time.Second * 5,
		Deadline: time.Now().Add(time.Second * 5),
	}, "tcp", host, &tls.Config{InsecureSkipVerify: true})
	if err != nil {
		fmt.Println(err)
		return
	}
	defer conn.Close()

	stats := conn.ConnectionState()
	certs := stats.PeerCertificates[0]
	localtz, _ := time.LoadLocation("Asia/Shanghai")
	issueTime := certs.NotBefore.In(localtz)
	expireTime := certs.NotAfter.In(localtz)

	today := time.Now().In(localtz)
	dayLeft := int(expireTime.Sub(today).Hours() / 24)
	fmt.Printf("%s, issue time: %v, expire time: %v, days left: %v\n", domain, issueTime, expireTime, dayLeft)

	// c := NewConfiger()
	if dayLeft < c.GetExpiry() {
		p := Postman{SmtpServer: c.GetSMTPServer(), SendTos: c.GetSendTos()}
		p.SendEmail(domain, dayLeft)
	}
}

func main() {
	flag.IntVar(&port, "p", 443, "port, example: ./check-ssl -p 1443 <domain name>")
	flag.StringVar(&configfile, "c", "config.yaml", "config file")
	flag.Parse()

	conf := NewConfiger()
	domains := conf.GetDomains()

	wg.Add(len(domains))
	for _, arg := range domains {
		go checkssl(arg, port)
	}
	wg.Wait()
}

本地測試通過后,可以配到服務(wù)器的crontab中每天執(zhí)行。

到此這篇關(guān)于如何使用工具自動(dòng)監(jiān)測SSL證書有效期并發(fā)送提醒郵件的文章就介紹到這了,更多相關(guān)[golang]查詢ssl證書剩余有效天數(shù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Makefile構(gòu)建Golang項(xiàng)目示例詳解

    Makefile構(gòu)建Golang項(xiàng)目示例詳解

    這篇文章主要為大家介紹了Makefile構(gòu)建Golang項(xiàng)目的過程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • 詳解Golang如何實(shí)現(xiàn)一個(gè)環(huán)形緩沖器

    詳解Golang如何實(shí)現(xiàn)一個(gè)環(huán)形緩沖器

    環(huán)形緩沖器(ringr?buffer)是一種用于表示一個(gè)固定尺寸、頭尾相連的緩沖區(qū)的數(shù)據(jù)結(jié)構(gòu),適合緩存數(shù)據(jù)流。本文將利用Golang實(shí)現(xiàn)一個(gè)環(huán)形緩沖器,需要的可以參考一下
    2022-09-09
  • Golang中的archive/zip包的常用函數(shù)詳解

    Golang中的archive/zip包的常用函數(shù)詳解

    Golang 中的 archive/zip 包用于處理 ZIP 格式的壓縮文件,提供了一系列用于創(chuàng)建、讀取和解壓縮 ZIP 格式文件的函數(shù)和類型,下面小編就來和大家講解下常用函數(shù)吧
    2023-08-08
  • 在 Golang 中實(shí)現(xiàn) Cache::remember 方法詳解

    在 Golang 中實(shí)現(xiàn) Cache::remember 方法詳解

    這篇文章主要介紹了在 Golang 中實(shí)現(xiàn) Cache::remember 方法詳解,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-03-03
  • 使用Go語言編寫一個(gè)毫秒級(jí)生成組件庫文檔工具

    使用Go語言編寫一個(gè)毫秒級(jí)生成組件庫文檔工具

    在開發(fā)組件庫的過程中,文檔無疑是不可或缺的一環(huán),在本文中將嘗試將Go語言與前端技術(shù)巧妙融合,以創(chuàng)建一款能在毫秒級(jí)別完成文檔生成的工具,需要的可以參考下
    2024-03-03
  • 基于Golang編寫一個(gè)聊天工具

    基于Golang編寫一個(gè)聊天工具

    這篇文章主要為大家詳細(xì)介紹了如何使用?Golang?構(gòu)建一個(gè)簡單但功能完善的聊天工具,利用?WebSocket?技術(shù)實(shí)現(xiàn)即時(shí)通訊的功能,需要的小伙伴可以參考下
    2023-11-11
  • golang中有序Map的實(shí)現(xiàn)

    golang中有序Map的實(shí)現(xiàn)

    Go語言中XContainerOrderedMap庫,解決標(biāo)準(zhǔn)map無序問題,文中通過示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-06-06
  • Go語言實(shí)現(xiàn)操作MySQL的基礎(chǔ)知識(shí)總結(jié)

    Go語言實(shí)現(xiàn)操作MySQL的基礎(chǔ)知識(shí)總結(jié)

    這篇文章主要總結(jié)一下怎么使用Go語言操作MySql數(shù)據(jù)庫,文中的示例代碼講解詳細(xì),需要的朋友可以參考以下內(nèi)容,希望對(duì)大家有所幫助
    2022-09-09
  • Go語言中日志管理詳解之從log到zap

    Go語言中日志管理詳解之從log到zap

    在軟件開發(fā)的世界里,日志就像是應(yīng)用程序的黑匣子,記錄著程序運(yùn)行過程中的關(guān)鍵信息,幫助開發(fā)者在遇到問題時(shí)快速定位和解決,在Go語言生態(tài)中,日志管理有著豐富的工具和方案,這篇文章主要介紹了Go語言中日志管理詳解之從log到zap的相關(guān)資料,需要的朋友可以參考下
    2026-04-04
  • golang解析json數(shù)據(jù)的4種方法總結(jié)

    golang解析json數(shù)據(jù)的4種方法總結(jié)

    在日常工作中每一名開發(fā)者,不管是前端還是后端,都經(jīng)常使用 JSON,下面這篇文章主要給大家介紹了關(guān)于golang解析json數(shù)據(jù)的4種方法,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-06-06

最新評(píng)論

贵德县| 旬阳县| 嫩江县| 九龙坡区| 互助| 呼图壁县| 报价| 曲周县| 周口市| 赣州市| 中牟县| 剑阁县| 云阳县| 宁远县| 民权县| 尉氏县| 霍邱县| 循化| 科技| 基隆市| 保山市| 兴安县| 崇仁县| 新疆| 温宿县| 乐业县| 河津市| 乌什县| 乳山市| 邮箱| 天等县| 调兵山市| 新宾| 定南县| 盐源县| 宜春市| 贡觉县| 永康市| 康乐县| 普兰店市| 宜都市|