使用Zabbix-agent2自定義插件獲取https證書過時時間

歡迎關注我的公號《運維開發故事》node

需求

對常常維護網站的人來說,是要常常跟https的證書打交道的,通常https證書的有效期在一年的時間,證書一旦過時,對公司的損失是很是大的,去年網易郵箱由於https證書忘記續期,致使大量用戶沒法正常使用郵箱就是個很好的反例,咱們也不能何時想起來纔去手動查一下,這樣也不現實,最好的方法是把過時時間監控起來,距離必定期限自動發送通知,可使用zabbix或者Prometheus的ssl_exporter來進行監控,在zabbix4.4版本之前可使用自定義腳本的方式,在4.4以後出現了zabbix-agent2,除了官方自帶的插件也能夠經過自定義插件的方式來知足咱們的監控需求,那麼接下來就給你們介紹如何使用zabbix-agent2自定義插件來實現獲取https證書過時時間的需求。##mysql

zabbix-agent2自定義ssl_expire插件

以前問們已經介紹過如何使用自定義插件來實現對mqtt的監控,原文地址https://mp.weixin.qq.com/s/4e6WnFyjXZYnXphx2erkGw,只不過當時使用的Watcher接口來將新數據主動push給server端,此次將經過實現Exporter接口來採集數據,這裏再次提供下官方文檔https://www.zabbix.com/documentation/current/manual/config/items/plugins和Zabbix認證專家米宏翻譯的官方博文https://mp.weixin.qq.com/s/7JLuVdZYX719pgGSP3xc9w
這裏我再介紹一下自定義插件的一些標準規範
1. 插件必須導入zabbix.com/pkg/plugin軟件包。linux

import "zabbix.com/pkg/plugin"

1. 插件必須定義結構並嵌入該plugin.Base結構。git

type Plugin struct {
    plugin.Base
}
var impl Plugin

1. 一個插件必須實現一個或多個插件接口。github

func (p *Plugin) Export(key string, params []string, ctx plugin.ContextProvider) (result interface{}, err error) {
    if len(params) > 0 {
        p.Debugf("received %d parameters while expected none", len(params))
        return nil, errors.New("Too many parameters")
    }
    return time.Now().Format(time.RFC3339)
}

1. 插件必須在初始化期間註冊本身。golang

func init() {
    plugin.RegisterMetrics(&impl, "Time", "system.time", "Returns time string in RFC 3999 format.")
}

ssl_expire代碼很少,插件由尼古拉·拖拉基斯基·王二編寫sql

func (p *Plugin) Configure(global *plugin.GlobalOptions, options interface{}) {
    if err = conf.Unmarshal(options, &p.options); err != nil {
        p.Errf("cannot unmarshal configuration options: %s", err)
    }

    if p.options.Timeout == 0 {
        p.options.Timeout = global.Timeout
    }
    p.client = newClient(p.options.Timeout)

}

func (p *Plugin) Validate(options interface{}) error {

    return conf.Unmarshal(options, &opts)
}

func checkParamnums(params []string) error {
    if len(params) > paramnums {
        err:=errors.New("Too many parameters.")
        return zbxerr.ErrorTooFewParameters.Wrap(err)
    } else if len(params) ==0 {
        err:=errors.New("Missing URL parameters.")
        return zbxerr.ErrorTooFewParameters.Wrap(err)
    }
    return nil
}

func checkParams(params []string) (string, error) {
    if strings.HasPrefix(params[0], "http://") {
        errorsting:=fmt.Sprintf("Target is using http scheme: %s", params[0])
        err:=errors.New(errorsting)
        return "",zbxerr.ErrorInvalidParams.Wrap(err)
    }

    if !strings.HasPrefix(params[0], "https://") {
        params[0] = "https://" + params[0]
    }
    return string(params[0]),nil
}
func (cli *client) Query(url string) (int64, error) {
    resp, err := cli.client.Get(url)
    if err != nil {
        impl.Debugf("cannot fetch data: %s", err)
        err:=errors.New("cannot fetch data")
        return 0, zbxerr.ErrorCannotFetchData.Wrap(err)
    }
    defer resp.Body.Close()
    certInfo:=resp.TLS.PeerCertificates[0]
    expiredays:=(certInfo.NotAfter.Unix()-time.Now().Unix())/60/60/24
    return expiredays,nil
}

// Export implements the Exporter interface.
func (p *Plugin) Export(key string, params []string, ctx plugin.ContextProvider) (interface{}, error) {
    if err = checkParamnums(params); err != nil {
        return nil, err
    }
    urls,err:= checkParams(params)
    if err!= nil {
        return nil,err
    }
    body, err := p.client.Query(urls)
    if err!=nil{
        return nil, err
    }
    return body,nil

}
func init() {
    plugin.RegisterMetrics(&impl, pluginName,
        "ssl_expire", "Returns the number of days between the SSL certificate expiration time and the current date.")
}

下載zabbix agent2源碼並將自定義插件編譯

yum install golang
git clone https://git.zabbix.com/scm/zbx/zabbix.git --depth 1 zabbix-agent2
cd zabbix-agent2
git submodule add https://github.com/cxf210/ssl_expire.git src/go/plugins/ssl_expire

導入ssl_expire插件

vi src/go/plugins/plugins_linux.go

添加最後一行docker

_ "zabbix.com/plugins/ceph"
        _ "zabbix.com/plugins/docker"
        _ "zabbix.com/plugins/kernel"
        _ "zabbix.com/plugins/log"
        _ "zabbix.com/plugins/memcached"
        _ "zabbix.com/plugins/modbus"
        _ "zabbix.com/plugins/mqtt"
        _ "zabbix.com/plugins/mysql"
        _ "zabbix.com/plugins/net/netif"
        _ "zabbix.com/plugins/net/tcp"
        ...
        _ "zabbix.com/plugins/ssl_expire"

編譯安裝zabbix agent2

yum install automake autoconf pcre* -y
./bootstrap.sh 
pushd . 
cd src/go/ 
go mod vendor 
popd 
./configure --enable-agent2 --enable-static 
make install

編輯配置文件

這裏我調整了日誌級別,方便前臺調試
可選參數
Plugins.MQTTSubscribe.Timeout = 5bootstrap

egrep -v "^$|^#" conf/zabbix_agent2.conf  
LogType=console
LogFile=/tmp/zabbix_agent2.log
DebugLevel=4
Server=172.17.0.5
Plugins.Ssl_expire.Timeout=5
Hostname=node2
ControlSocket=/tmp/agent.sock

啓動Zabbix_agent2

cd /root/zabbix_agent/src/go/bin
zabbix_agent2 -c conf/zabbix_agent2.conf

image.png

Zabbix建立監控項

鍵值示例以下運維

ssl_expire["www.xyzabbix.cn"]

ssl_expire["https://www.xyzabbix.cn"]

image.png
查看最新數據,這個證書還有四十天過時
image.png
我是用的阿里雲ssl證書,能夠看到確實離過時時間還有四十天,今天是2021.3.7
image.png
能夠建立一個觸發器,在還有一個月的時候發送報警通知
image.png


使用Zabbix-agent2自定義插件獲取https證書過時時間

相關文章
相關標籤/搜索