From 7840cd1db313bdb5d1d118eb36f9c10742390aa8 Mon Sep 17 00:00:00 2001 From: peter <> Date: Thu, 2 Jan 2025 14:11:55 +0800 Subject: [PATCH] feat: x509_cert plugin --- agent/metrics_agent.go | 1 + conf/input.x509_cert/x509_cert.toml | 34 ++ go.mod | 24 +- go.sum | 56 ++- inputs/x509_cert/README.md | 149 ++++++++ inputs/x509_cert/x509_cert.go | 538 ++++++++++++++++++++++++++++ 6 files changed, 775 insertions(+), 27 deletions(-) create mode 100644 conf/input.x509_cert/x509_cert.toml create mode 100644 inputs/x509_cert/README.md create mode 100644 inputs/x509_cert/x509_cert.go diff --git a/agent/metrics_agent.go b/agent/metrics_agent.go index 2c023b16..e6a1545c 100644 --- a/agent/metrics_agent.go +++ b/agent/metrics_agent.go @@ -94,6 +94,7 @@ import ( _ "flashcat.cloud/categraf/inputs/traffic_server" _ "flashcat.cloud/categraf/inputs/vsphere" _ "flashcat.cloud/categraf/inputs/whois" + _ "flashcat.cloud/categraf/inputs/x509_cert" _ "flashcat.cloud/categraf/inputs/xskyapi" _ "flashcat.cloud/categraf/inputs/zookeeper" ) diff --git a/conf/input.x509_cert/x509_cert.toml b/conf/input.x509_cert/x509_cert.toml new file mode 100644 index 00000000..3d7bee1c --- /dev/null +++ b/conf/input.x509_cert/x509_cert.toml @@ -0,0 +1,34 @@ +## collect interval +# interval = 15 + +[[instances]] + ## List certificate sources, support wildcard expands for files + ## Prefix your entry with 'file://' if you intend to use relative paths + #targets = ["tcp://example.org:443", "https://www.baidu.com", + # "smtp://smtp.qq.com:25", "udp://127.0.0.1:4433", + # "/etc/ssl/certs/example.pem","/usr/local/openresty/nginx/conf/ssl/*.pem", + # "file:///path/to/*.pem"] + + ## Timeout for SSL connection + # timeout = "5s" + + ## Pass a different name into the TLS request (Server Name Indication). + ## This is synonymous with tls_server_name, and only one of the two + ## options may be specified at one time. + ## example: server_name = "myhost.example.org" + # server_name = "myhost.example.org" + + ## Only output the leaf certificates and omit the root ones. + # exclude_root_certs = false + +## Optional TLS Config +# use_tls = false +# tls_ca = "/etc/categraf/ca.pem" +# tls_cert = "/etc/categraf/cert.pem" +# tls_key = "/etc/categraf/key.pem" +# tls_server_name = "myhost.example.org" +## Use TLS but skip chain & host verification +# insecure_skip_verify = false + +## Set http_proxy (categraf uses the system wide proxy settings if it's is not set) +# http_proxy = "http://localhost:8888" \ No newline at end of file diff --git a/go.mod b/go.mod index 49ab8bc1..6a127d19 100644 --- a/go.mod +++ b/go.mod @@ -37,7 +37,7 @@ require ( github.com/prometheus/prometheus v0.40.0 github.com/shirou/gopsutil/v3 v3.22.5 github.com/sirupsen/logrus v1.9.3 - github.com/stretchr/testify v1.8.4 + github.com/stretchr/testify v1.9.0 github.com/toolkits/pkg v1.3.7 github.com/ulricqin/gosnmp v0.0.1 github.com/xdg/scram v1.0.5 @@ -45,9 +45,9 @@ require ( go.opentelemetry.io/otel/metric v1.18.0 // indirect go.opentelemetry.io/otel/trace v1.18.0 // indirect go.uber.org/multierr v1.8.0 // indirect - golang.org/x/net v0.23.0 - golang.org/x/sys v0.20.0 - golang.org/x/text v0.14.0 + golang.org/x/net v0.33.0 + golang.org/x/sys v0.28.0 + golang.org/x/text v0.21.0 gopkg.in/yaml.v3 v3.0.1 // indirect ) @@ -102,6 +102,9 @@ require ( github.com/nats-io/nkeys v0.4.7 // indirect github.com/nats-io/nuid v1.0.1 // indirect github.com/ovh/go-ovh v1.1.0 // indirect + github.com/pion/logging v0.2.2 // indirect + github.com/pion/transport/v2 v2.2.10 // indirect + github.com/pion/transport/v3 v3.0.7 // indirect github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/siebenmann/go-kstat v0.0.0-20210513183136-173c9b0a9973 // indirect github.com/tidwall/match v1.1.1 // indirect @@ -160,6 +163,7 @@ require ( github.com/openconfig/gnmi v0.11.0 github.com/opencontainers/selinux v1.11.0 github.com/percona/percona-toolkit v0.0.0-20211210121818-b2860eee3152 + github.com/pion/dtls/v2 v2.2.12 github.com/prometheus-community/go-runit v0.1.0 github.com/prometheus-community/pro-bing v0.1.0 github.com/safchain/ethtool v0.3.0 @@ -305,7 +309,7 @@ require ( github.com/shopspring/decimal v1.3.1 // indirect github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/stretchr/objx v0.5.0 // indirect + github.com/stretchr/objx v0.5.2 // indirect github.com/tklauser/go-sysconf v0.3.10 // indirect github.com/tklauser/numcpus v0.4.0 // indirect github.com/tomasen/fcgi_client v0.0.0-20180423082037-2bb3d819fd19 @@ -325,13 +329,13 @@ require ( go.uber.org/atomic v1.10.0 // indirect go.uber.org/automaxprocs v1.5.3 // indirect go.uber.org/goleak v1.2.0 // indirect - golang.org/x/crypto v0.21.0 // indirect - golang.org/x/mod v0.14.0 // indirect + golang.org/x/crypto v0.31.0 // indirect + golang.org/x/mod v0.17.0 // indirect golang.org/x/oauth2 v0.16.0 // indirect - golang.org/x/sync v0.5.0 - golang.org/x/term v0.18.0 // indirect + golang.org/x/sync v0.10.0 + golang.org/x/term v0.27.0 // indirect golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.16.1 // indirect + golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect google.golang.org/api v0.149.0 google.golang.org/appengine v1.6.8 // indirect google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 diff --git a/go.sum b/go.sum index b14cf8db..42dcb2b1 100644 --- a/go.sum +++ b/go.sum @@ -1631,6 +1631,15 @@ github.com/pierrec/lz4/v4 v4.0.3/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuR github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pierrec/lz4/v4 v4.1.18 h1:xaKrnTkyoqfh1YItXl56+6KJNVYWlEEPuAQW9xsplYQ= github.com/pierrec/lz4/v4 v4.1.18/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= +github.com/pion/dtls/v2 v2.2.12 h1:KP7H5/c1EiVAAKUmXyCzPiQe5+bCJrpOeKg/L05dunk= +github.com/pion/dtls/v2 v2.2.12/go.mod h1:d9SYc9fch0CqK90mRk1dC7AkzzpwJj6u2GU3u+9pqFE= +github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= +github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms= +github.com/pion/transport/v2 v2.2.4/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0= +github.com/pion/transport/v2 v2.2.10 h1:ucLBLE8nuxiHfvkFKnkDQRYWYfp8ejf4YBOPfaQpw6Q= +github.com/pion/transport/v2 v2.2.10/go.mod h1:sq1kSLWs+cHW9E+2fJP95QudkzbK7wscs8yYgQToO5E= +github.com/pion/transport/v3 v3.0.7 h1:iRbMH05BzSNwhILHoBoAPxoB9xQgOaJk+591KC9P1o0= +github.com/pion/transport/v3 v3.0.7/go.mod h1:YleKiTZ4vqNxVwh77Z0zytYi7rXHl7j6uPLGhhz9rwo= github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -1764,8 +1773,9 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -1778,8 +1788,9 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM= github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= @@ -1817,6 +1828,7 @@ github.com/vmware/govmomi v0.29.0 h1:SHJQ7DUc4fltFZv16znJNGHR1/XhiDK5iKxm2OqwkuU github.com/vmware/govmomi v0.29.0/go.mod h1:F7adsVewLNHsW/IIm7ziFURaXDaHEwcc+ym4r3INMdY= github.com/vultr/govultr/v2 v2.17.2 h1:gej/rwr91Puc/tgh+j33p/BLR16UrIPnSr+AIwYWZQs= github.com/vultr/govultr/v2 v2.17.2/go.mod h1:ZFOKGWmgjytfyjeyAdhQlSWwTjh2ig+X49cAp50dzXI= +github.com/wlynxg/anet v0.0.3/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA= github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= @@ -1933,10 +1945,12 @@ golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= +golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= -golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= -golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= +golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1998,8 +2012,8 @@ golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= -golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -2072,9 +2086,11 @@ golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= -golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= -golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= +golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= +golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -2123,8 +2139,8 @@ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= -golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -2236,10 +2252,12 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= -golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -2251,10 +2269,12 @@ golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= -golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= -golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= +golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= +golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= +golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -2271,9 +2291,11 @@ golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -2362,8 +2384,8 @@ golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= -golang.org/x/tools v0.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA= -golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/inputs/x509_cert/README.md b/inputs/x509_cert/README.md new file mode 100644 index 00000000..cdd0a230 --- /dev/null +++ b/inputs/x509_cert/README.md @@ -0,0 +1,149 @@ +# x509 Certificate Input Plugin + +This plugin provides information about X509 certificate accessible via local +file, tcp, udp, https or smtp protocol. + +When using a UDP address as a certificate source, the server must support +[DTLS](https://en.wikipedia.org/wiki/Datagram_Transport_Layer_Security). + +## Configuration + +```toml +# Reads metrics from a SSL certificate +## collect interval +# interval = 15 + +[[instances]] + ## List certificate sources, support wildcard expands for files + ## Prefix your entry with 'file://' if you intend to use relative paths + targets = ["tcp://example.org:443", "https://www.baidu.com", + "smtp://smtp.qq.com:25", "udp://127.0.0.1:4433", + "/etc/ssl/certs/example.pem","/usr/local/openresty/nginx/conf/ssl/*.pem", + "file:///path/to/*.pem"] + + ## Timeout for SSL connection + # timeout = "5s" + + ## Pass a different name into the TLS request (Server Name Indication). + ## This is synonymous with tls_server_name, and only one of the two + ## options may be specified at one time. + ## example: server_name = "myhost.example.org" + # server_name = "myhost.example.org" + + ## Only output the leaf certificates and omit the root ones. + # exclude_root_certs = false + +## Optional TLS Config +# use_tls = false +# tls_ca = "/etc/categraf/ca.pem" +# tls_cert = "/etc/categraf/cert.pem" +# tls_key = "/etc/categraf/key.pem" +# tls_server_name = "myhost.example.org" +## Use TLS but skip chain & host verification +# insecure_skip_verify = false + +## Set http_proxy (categraf uses the system wide proxy settings if it's is not set) +# http_proxy = "http://localhost:8888" +``` + +## Metrics + +- x509_cert + - tags: + - type - "leaf", "intermediate" or "root" classification of certificate + - source - source of the certificate + - organization + - organizational_unit + - country + - province + - locality + - verification + - serial_number + - signature_algorithm + - public_key_algorithm + - issuer_common_name + - issuer_serial_number + - san + - ocsp_stapled + - ocsp_status (when ocsp_stapled=yes) + - ocsp_verified (when ocsp_stapled=yes) + - fields: + - verification_code (int) - 0 valid; 1 invalid. + - expiry (int, seconds) - Time when the certificate will expire, in seconds since the Unix epoch. + - age (int, seconds) + - startdate (int, seconds) + - enddate (int, seconds) + - ocsp_status_code (int) + - ocsp_next_update (int, seconds) + - ocsp_produced_at (int, seconds) + - ocsp_this_update (int, seconds) + +## Example Output + +```text +x509_cert_verification_code agent_hostname=zy-fat common_name=*.example.com issuer_common_name=GlobalSign GCC R6 AlphaSSL CA 2023 issuer_serial_number= ocsp_stapled=no public_key_algorithm=RSA san=*.example.com,example.com serial_number=702b39b1c6079169265d251a signature_algorithm=SHA256-RSA target=file:///usr/local/openresty/nginx/conf/ssl/example.com.pem type=leaf verification=valid 0 +x509_cert_age agent_hostname=zy-fat common_name=*.example.com issuer_common_name=GlobalSign GCC R6 AlphaSSL CA 2023 issuer_serial_number= ocsp_stapled=no public_key_algorithm=RSA san=*.example.com,example.com serial_number=702b39b1c6079169265d251a signature_algorithm=SHA256-RSA target=file:///usr/local/openresty/nginx/conf/ssl/example.com.pem type=leaf verification=valid 3723724 +x509_cert_expiry agent_hostname=zy-fat common_name=*.example.com issuer_common_name=GlobalSign GCC R6 AlphaSSL CA 2023 issuer_serial_number= ocsp_stapled=no public_key_algorithm=RSA san=*.example.com,example.com serial_number=702b39b1c6079169265d251a signature_algorithm=SHA256-RSA target=file:///usr/local/openresty/nginx/conf/ssl/example.com.pem type=leaf verification=valid 30577074 +x509_cert_startdate agent_hostname=zy-fat common_name=*.example.com issuer_common_name=GlobalSign GCC R6 AlphaSSL CA 2023 issuer_serial_number= ocsp_stapled=no public_key_algorithm=RSA san=*.example.com,example.com serial_number=702b39b1c6079169265d251a signature_algorithm=SHA256-RSA target=file:///usr/local/openresty/nginx/conf/ssl/example.com.pem type=leaf verification=valid 1732073152 +x509_cert_enddate agent_hostname=zy-fat common_name=*.example.com issuer_common_name=GlobalSign GCC R6 AlphaSSL CA 2023 issuer_serial_number= ocsp_stapled=no public_key_algorithm=RSA san=*.example.com,example.com serial_number=702b39b1c6079169265d251a signature_algorithm=SHA256-RSA target=file:///usr/local/openresty/nginx/conf/ssl/example.com.pem type=leaf verification=valid 1766373951 +x509_cert_age agent_hostname=zy-fat common_name=GlobalSign GCC R6 AlphaSSL CA 2023 country=BE issuer_common_name=GlobalSign issuer_serial_number= ocsp_stapled=no organization=GlobalSign nv-sa public_key_algorithm=RSA san= serial_number=7f1f2c902e83d0e3b6fb3bee478b5e80 signature_algorithm=SHA256-RSA target=file:///usr/local/openresty/nginx/conf/ssl/example.com.pem type=intermediate verification=valid 46058671 +x509_cert_expiry agent_hostname=zy-fat common_name=GlobalSign GCC R6 AlphaSSL CA 2023 country=BE issuer_common_name=GlobalSign issuer_serial_number= ocsp_stapled=no organization=GlobalSign nv-sa public_key_algorithm=RSA san= serial_number=7f1f2c902e83d0e3b6fb3bee478b5e80 signature_algorithm=SHA256-RSA target=file:///usr/local/openresty/nginx/conf/ssl/example.com.pem type=intermediate verification=valid 48622323 +x509_cert_startdate agent_hostname=zy-fat common_name=GlobalSign GCC R6 AlphaSSL CA 2023 country=BE issuer_common_name=GlobalSign issuer_serial_number= ocsp_stapled=no organization=GlobalSign nv-sa public_key_algorithm=RSA san= serial_number=7f1f2c902e83d0e3b6fb3bee478b5e80 signature_algorithm=SHA256-RSA target=file:///usr/local/openresty/nginx/conf/ssl/example.com.pem type=intermediate verification=valid 1689738205 +x509_cert_enddate agent_hostname=zy-fat common_name=GlobalSign GCC R6 AlphaSSL CA 2023 country=BE issuer_common_name=GlobalSign issuer_serial_number= ocsp_stapled=no organization=GlobalSign nv-sa public_key_algorithm=RSA san= serial_number=7f1f2c902e83d0e3b6fb3bee478b5e80 signature_algorithm=SHA256-RSA target=file:///usr/local/openresty/nginx/conf/ssl/example.com.pem type=intermediate verification=valid 1784419200 +x509_cert_verification_code agent_hostname=zy-fat common_name=GlobalSign GCC R6 AlphaSSL CA 2023 country=BE issuer_common_name=GlobalSign issuer_serial_number= ocsp_stapled=no organization=GlobalSign nv-sa public_key_algorithm=RSA san= serial_number=7f1f2c902e83d0e3b6fb3bee478b5e80 signature_algorithm=SHA256-RSA target=file:///usr/local/openresty/nginx/conf/ssl/example.com.pem type=intermediate verification=valid 0 +x509_cert_verification_code agent_hostname=zy-fat common_name=GlobalSign issuer_common_name=GlobalSign Root CA issuer_serial_number= ocsp_stapled=no organization=GlobalSign organizational_unit=GlobalSign Root CA - R6 public_key_algorithm=RSA san= serial_number=751e3f5649e74cbbf69d0026b67caa8c signature_algorithm=SHA384-RSA target=file:///usr/local/openresty/nginx/conf/ssl/example.com.pem type=intermediate verification=valid 0 +x509_cert_age agent_hostname=zy-fat common_name=GlobalSign issuer_common_name=GlobalSign Root CA issuer_serial_number= ocsp_stapled=no organization=GlobalSign organizational_unit=GlobalSign Root CA - R6 public_key_algorithm=RSA san= serial_number=751e3f5649e74cbbf69d0026b67caa8c signature_algorithm=SHA384-RSA target=file:///usr/local/openresty/nginx/conf/ssl/example.com.pem type=intermediate verification=valid 174894476 +x509_cert_expiry agent_hostname=zy-fat common_name=GlobalSign issuer_common_name=GlobalSign Root CA issuer_serial_number= ocsp_stapled=no organization=GlobalSign organizational_unit=GlobalSign Root CA - R6 public_key_algorithm=RSA san= serial_number=751e3f5649e74cbbf69d0026b67caa8c signature_algorithm=SHA384-RSA target=file:///usr/local/openresty/nginx/conf/ssl/example.com.pem type=intermediate verification=valid 96876723 +x509_cert_startdate agent_hostname=zy-fat common_name=GlobalSign issuer_common_name=GlobalSign Root CA issuer_serial_number= ocsp_stapled=no organization=GlobalSign organizational_unit=GlobalSign Root CA - R6 public_key_algorithm=RSA san= serial_number=751e3f5649e74cbbf69d0026b67caa8c signature_algorithm=SHA384-RSA target=file:///usr/local/openresty/nginx/conf/ssl/example.com.pem type=intermediate verification=valid 1560902400 +x509_cert_enddate agent_hostname=zy-fat common_name=GlobalSign issuer_common_name=GlobalSign Root CA issuer_serial_number= ocsp_stapled=no organization=GlobalSign organizational_unit=GlobalSign Root CA - R6 public_key_algorithm=RSA san= serial_number=751e3f5649e74cbbf69d0026b67caa8c signature_algorithm=SHA384-RSA target=file:///usr/local/openresty/nginx/conf/ssl/example.com.pem type=intermediate verification=valid 1832673600 +x509_cert_age agent_hostname=zy-fat common_name=GlobalSign Root CA country=BE issuer_common_name=GlobalSign Root CA issuer_serial_number= ocsp_stapled=no organization=GlobalSign nv-sa organizational_unit=Root CA public_key_algorithm=RSA san= serial_number=40000000001154b5ac394 signature_algorithm=SHA1-RSA target=file:///usr/local/openresty/nginx/conf/ssl/example.com.pem type=root verification=valid 831145676 +x509_cert_expiry agent_hostname=zy-fat common_name=GlobalSign Root CA country=BE issuer_common_name=GlobalSign Root CA issuer_serial_number= ocsp_stapled=no organization=GlobalSign nv-sa organizational_unit=Root CA public_key_algorithm=RSA san= serial_number=40000000001154b5ac394 signature_algorithm=SHA1-RSA target=file:///usr/local/openresty/nginx/conf/ssl/example.com.pem type=root verification=valid 96876723 +x509_cert_startdate agent_hostname=zy-fat common_name=GlobalSign Root CA country=BE issuer_common_name=GlobalSign Root CA issuer_serial_number= ocsp_stapled=no organization=GlobalSign nv-sa organizational_unit=Root CA public_key_algorithm=RSA san= serial_number=40000000001154b5ac394 signature_algorithm=SHA1-RSA target=file:///usr/local/openresty/nginx/conf/ssl/example.com.pem type=root verification=valid 904651200 +x509_cert_enddate agent_hostname=zy-fat common_name=GlobalSign Root CA country=BE issuer_common_name=GlobalSign Root CA issuer_serial_number= ocsp_stapled=no organization=GlobalSign nv-sa organizational_unit=Root CA public_key_algorithm=RSA san= serial_number=40000000001154b5ac394 signature_algorithm=SHA1-RSA target=file:///usr/local/openresty/nginx/conf/ssl/example.com.pem type=root verification=valid 1832673600 +x509_cert_verification_code agent_hostname=zy-fat common_name=GlobalSign Root CA country=BE issuer_common_name=GlobalSign Root CA issuer_serial_number= ocsp_stapled=no organization=GlobalSign nv-sa organizational_unit=Root CA public_key_algorithm=RSA san= serial_number=40000000001154b5ac394 signature_algorithm=SHA1-RSA target=file:///usr/local/openresty/nginx/conf/ssl/example.com.pem type=root verification=valid 0 +x509_cert_expiry agent_hostname=zy-fat common_name=*.example.com issuer_common_name=GlobalSign GCC R6 AlphaSSL CA 2023 issuer_serial_number= ocsp_stapled=no public_key_algorithm=RSA san=*.example.com,example.com serial_number=702b39b1c6079169265d251a signature_algorithm=SHA256-RSA target=file:///usr/local/openresty/nginx/conf/ssl/server_example.pem type=leaf verification=valid 30577074 +x509_cert_startdate agent_hostname=zy-fat common_name=*.example.com issuer_common_name=GlobalSign GCC R6 AlphaSSL CA 2023 issuer_serial_number= ocsp_stapled=no public_key_algorithm=RSA san=*.example.com,example.com serial_number=702b39b1c6079169265d251a signature_algorithm=SHA256-RSA target=file:///usr/local/openresty/nginx/conf/ssl/server_example.pem type=leaf verification=valid 1732073152 +x509_cert_enddate agent_hostname=zy-fat common_name=*.example.com issuer_common_name=GlobalSign GCC R6 AlphaSSL CA 2023 issuer_serial_number= ocsp_stapled=no public_key_algorithm=RSA san=*.example.com,example.com serial_number=702b39b1c6079169265d251a signature_algorithm=SHA256-RSA target=file:///usr/local/openresty/nginx/conf/ssl/server_example.pem type=leaf verification=valid 1766373951 +x509_cert_verification_code agent_hostname=zy-fat common_name=*.example.com issuer_common_name=GlobalSign GCC R6 AlphaSSL CA 2023 issuer_serial_number= ocsp_stapled=no public_key_algorithm=RSA san=*.example.com,example.com serial_number=702b39b1c6079169265d251a signature_algorithm=SHA256-RSA target=file:///usr/local/openresty/nginx/conf/ssl/server_example.pem type=leaf verification=valid 0 +x509_cert_age agent_hostname=zy-fat common_name=*.example.com issuer_common_name=GlobalSign GCC R6 AlphaSSL CA 2023 issuer_serial_number= ocsp_stapled=no public_key_algorithm=RSA san=*.example.com,example.com serial_number=702b39b1c6079169265d251a signature_algorithm=SHA256-RSA target=file:///usr/local/openresty/nginx/conf/ssl/server_example.pem type=leaf verification=valid 3723724 +x509_cert_verification_code agent_hostname=zy-fat common_name=GlobalSign GCC R6 AlphaSSL CA 2023 country=BE issuer_common_name=GlobalSign issuer_serial_number= ocsp_stapled=no organization=GlobalSign nv-sa public_key_algorithm=RSA san= serial_number=7f1f2c902e83d0e3b6fb3bee478b5e80 signature_algorithm=SHA256-RSA target=file:///usr/local/openresty/nginx/conf/ssl/server_example.pem type=intermediate verification=valid 0 +x509_cert_age agent_hostname=zy-fat common_name=GlobalSign GCC R6 AlphaSSL CA 2023 country=BE issuer_common_name=GlobalSign issuer_serial_number= ocsp_stapled=no organization=GlobalSign nv-sa public_key_algorithm=RSA san= serial_number=7f1f2c902e83d0e3b6fb3bee478b5e80 signature_algorithm=SHA256-RSA target=file:///usr/local/openresty/nginx/conf/ssl/server_example.pem type=intermediate verification=valid 46058671 +x509_cert_expiry agent_hostname=zy-fat common_name=GlobalSign GCC R6 AlphaSSL CA 2023 country=BE issuer_common_name=GlobalSign issuer_serial_number= ocsp_stapled=no organization=GlobalSign nv-sa public_key_algorithm=RSA san= serial_number=7f1f2c902e83d0e3b6fb3bee478b5e80 signature_algorithm=SHA256-RSA target=file:///usr/local/openresty/nginx/conf/ssl/server_example.pem type=intermediate verification=valid 48622323 +x509_cert_startdate agent_hostname=zy-fat common_name=GlobalSign GCC R6 AlphaSSL CA 2023 country=BE issuer_common_name=GlobalSign issuer_serial_number= ocsp_stapled=no organization=GlobalSign nv-sa public_key_algorithm=RSA san= serial_number=7f1f2c902e83d0e3b6fb3bee478b5e80 signature_algorithm=SHA256-RSA target=file:///usr/local/openresty/nginx/conf/ssl/server_example.pem type=intermediate verification=valid 1689738205 +x509_cert_enddate agent_hostname=zy-fat common_name=GlobalSign GCC R6 AlphaSSL CA 2023 country=BE issuer_common_name=GlobalSign issuer_serial_number= ocsp_stapled=no organization=GlobalSign nv-sa public_key_algorithm=RSA san= serial_number=7f1f2c902e83d0e3b6fb3bee478b5e80 signature_algorithm=SHA256-RSA target=file:///usr/local/openresty/nginx/conf/ssl/server_example.pem type=intermediate verification=valid 1784419200 +x509_cert_age agent_hostname=zy-fat common_name=GlobalSign issuer_common_name=GlobalSign Root CA issuer_serial_number= ocsp_stapled=no organization=GlobalSign organizational_unit=GlobalSign Root CA - R6 public_key_algorithm=RSA san= serial_number=751e3f5649e74cbbf69d0026b67caa8c signature_algorithm=SHA384-RSA target=file:///usr/local/openresty/nginx/conf/ssl/server_example.pem type=intermediate verification=valid 174894476 +x509_cert_expiry agent_hostname=zy-fat common_name=GlobalSign issuer_common_name=GlobalSign Root CA issuer_serial_number= ocsp_stapled=no organization=GlobalSign organizational_unit=GlobalSign Root CA - R6 public_key_algorithm=RSA san= serial_number=751e3f5649e74cbbf69d0026b67caa8c signature_algorithm=SHA384-RSA target=file:///usr/local/openresty/nginx/conf/ssl/server_example.pem type=intermediate verification=valid 96876723 +x509_cert_startdate agent_hostname=zy-fat common_name=GlobalSign issuer_common_name=GlobalSign Root CA issuer_serial_number= ocsp_stapled=no organization=GlobalSign organizational_unit=GlobalSign Root CA - R6 public_key_algorithm=RSA san= serial_number=751e3f5649e74cbbf69d0026b67caa8c signature_algorithm=SHA384-RSA target=file:///usr/local/openresty/nginx/conf/ssl/server_example.pem type=intermediate verification=valid 1560902400 +x509_cert_enddate agent_hostname=zy-fat common_name=GlobalSign issuer_common_name=GlobalSign Root CA issuer_serial_number= ocsp_stapled=no organization=GlobalSign organizational_unit=GlobalSign Root CA - R6 public_key_algorithm=RSA san= serial_number=751e3f5649e74cbbf69d0026b67caa8c signature_algorithm=SHA384-RSA target=file:///usr/local/openresty/nginx/conf/ssl/server_example.pem type=intermediate verification=valid 1832673600 +x509_cert_verification_code agent_hostname=zy-fat common_name=GlobalSign issuer_common_name=GlobalSign Root CA issuer_serial_number= ocsp_stapled=no organization=GlobalSign organizational_unit=GlobalSign Root CA - R6 public_key_algorithm=RSA san= serial_number=751e3f5649e74cbbf69d0026b67caa8c signature_algorithm=SHA384-RSA target=file:///usr/local/openresty/nginx/conf/ssl/server_example.pem type=intermediate verification=valid 0 +x509_cert_enddate agent_hostname=zy-fat common_name=GlobalSign Root CA country=BE issuer_common_name=GlobalSign Root CA issuer_serial_number= ocsp_stapled=no organization=GlobalSign nv-sa organizational_unit=Root CA public_key_algorithm=RSA san= serial_number=40000000001154b5ac394 signature_algorithm=SHA1-RSA target=file:///usr/local/openresty/nginx/conf/ssl/server_example.pem type=root verification=valid 1832673600 +x509_cert_verification_code agent_hostname=zy-fat common_name=GlobalSign Root CA country=BE issuer_common_name=GlobalSign Root CA issuer_serial_number= ocsp_stapled=no organization=GlobalSign nv-sa organizational_unit=Root CA public_key_algorithm=RSA san= serial_number=40000000001154b5ac394 signature_algorithm=SHA1-RSA target=file:///usr/local/openresty/nginx/conf/ssl/server_example.pem type=root verification=valid 0 +x509_cert_age agent_hostname=zy-fat common_name=GlobalSign Root CA country=BE issuer_common_name=GlobalSign Root CA issuer_serial_number= ocsp_stapled=no organization=GlobalSign nv-sa organizational_unit=Root CA public_key_algorithm=RSA san= serial_number=40000000001154b5ac394 signature_algorithm=SHA1-RSA target=file:///usr/local/openresty/nginx/conf/ssl/server_example.pem type=root verification=valid 831145676 +x509_cert_expiry agent_hostname=zy-fat common_name=GlobalSign Root CA country=BE issuer_common_name=GlobalSign Root CA issuer_serial_number= ocsp_stapled=no organization=GlobalSign nv-sa organizational_unit=Root CA public_key_algorithm=RSA san= serial_number=40000000001154b5ac394 signature_algorithm=SHA1-RSA target=file:///usr/local/openresty/nginx/conf/ssl/server_example.pem type=root verification=valid 96876723 +x509_cert_startdate agent_hostname=zy-fat common_name=GlobalSign Root CA country=BE issuer_common_name=GlobalSign Root CA issuer_serial_number= ocsp_stapled=no organization=GlobalSign nv-sa organizational_unit=Root CA public_key_algorithm=RSA san= serial_number=40000000001154b5ac394 signature_algorithm=SHA1-RSA target=file:///usr/local/openresty/nginx/conf/ssl/server_example.pem type=root verification=valid 904651200 +x509_cert_age agent_hostname=zy-fat common_name=*.mail.qq.com country=CN issuer_common_name=DigiCert Secure Site OV G2 TLS CN RSA4096 SHA256 2022 CA1 issuer_serial_number= locality=Shenzhen ocsp_stapled=no organization=Shenzhen Tencent Computer Systems Company Limited province=Guangdong Province public_key_algorithm=RSA san=*.mail.qq.com,*.dav.qq.com,*.eas.qq.com,*.foxmail.com,*.qmail.com,*.weixin.qq.com,993.imap.qq.com,993.pop.qq.com,993.smtp.qq.com,dav.qq.com,ex.qq.com,imap.qq.com,mx1.qq.com,mx2.qq.com,mx3.qq.com,openmail.qq.com,pop.qq.com,smtp.qq.com,weixin.qq.com,mail.qq.com serial_number=6c8faca4eb0b30e82ad3d24c510151b signature_algorithm=SHA256-RSA target=smtp://smtp.qq.com:25 type=leaf verification=valid 3563276 +x509_cert_expiry agent_hostname=zy-fat common_name=*.mail.qq.com country=CN issuer_common_name=DigiCert Secure Site OV G2 TLS CN RSA4096 SHA256 2022 CA1 issuer_serial_number= locality=Shenzhen ocsp_stapled=no organization=Shenzhen Tencent Computer Systems Company Limited province=Guangdong Province public_key_algorithm=RSA san=*.mail.qq.com,*.dav.qq.com,*.eas.qq.com,*.foxmail.com,*.qmail.com,*.weixin.qq.com,993.imap.qq.com,993.pop.qq.com,993.smtp.qq.com,dav.qq.com,ex.qq.com,imap.qq.com,mx1.qq.com,mx2.qq.com,mx3.qq.com,openmail.qq.com,pop.qq.com,smtp.qq.com,weixin.qq.com,mail.qq.com serial_number=6c8faca4eb0b30e82ad3d24c510151b signature_algorithm=SHA256-RSA target=smtp://smtp.qq.com:25 type=leaf verification=valid 27972722 +x509_cert_startdate agent_hostname=zy-fat common_name=*.mail.qq.com country=CN issuer_common_name=DigiCert Secure Site OV G2 TLS CN RSA4096 SHA256 2022 CA1 issuer_serial_number= locality=Shenzhen ocsp_stapled=no organization=Shenzhen Tencent Computer Systems Company Limited province=Guangdong Province public_key_algorithm=RSA san=*.mail.qq.com,*.dav.qq.com,*.eas.qq.com,*.foxmail.com,*.qmail.com,*.weixin.qq.com,993.imap.qq.com,993.pop.qq.com,993.smtp.qq.com,dav.qq.com,ex.qq.com,imap.qq.com,mx1.qq.com,mx2.qq.com,mx3.qq.com,openmail.qq.com,pop.qq.com,smtp.qq.com,weixin.qq.com,mail.qq.com serial_number=6c8faca4eb0b30e82ad3d24c510151b signature_algorithm=SHA256-RSA target=smtp://smtp.qq.com:25 type=leaf verification=valid 1732233600 +x509_cert_enddate agent_hostname=zy-fat common_name=*.mail.qq.com country=CN issuer_common_name=DigiCert Secure Site OV G2 TLS CN RSA4096 SHA256 2022 CA1 issuer_serial_number= locality=Shenzhen ocsp_stapled=no organization=Shenzhen Tencent Computer Systems Company Limited province=Guangdong Province public_key_algorithm=RSA san=*.mail.qq.com,*.dav.qq.com,*.eas.qq.com,*.foxmail.com,*.qmail.com,*.weixin.qq.com,993.imap.qq.com,993.pop.qq.com,993.smtp.qq.com,dav.qq.com,ex.qq.com,imap.qq.com,mx1.qq.com,mx2.qq.com,mx3.qq.com,openmail.qq.com,pop.qq.com,smtp.qq.com,weixin.qq.com,mail.qq.com serial_number=6c8faca4eb0b30e82ad3d24c510151b signature_algorithm=SHA256-RSA target=smtp://smtp.qq.com:25 type=leaf verification=valid 1763769599 +x509_cert_verification_code agent_hostname=zy-fat common_name=*.mail.qq.com country=CN issuer_common_name=DigiCert Secure Site OV G2 TLS CN RSA4096 SHA256 2022 CA1 issuer_serial_number= locality=Shenzhen ocsp_stapled=no organization=Shenzhen Tencent Computer Systems Company Limited province=Guangdong Province public_key_algorithm=RSA san=*.mail.qq.com,*.dav.qq.com,*.eas.qq.com,*.foxmail.com,*.qmail.com,*.weixin.qq.com,993.imap.qq.com,993.pop.qq.com,993.smtp.qq.com,dav.qq.com,ex.qq.com,imap.qq.com,mx1.qq.com,mx2.qq.com,mx3.qq.com,openmail.qq.com,pop.qq.com,smtp.qq.com,weixin.qq.com,mail.qq.com serial_number=6c8faca4eb0b30e82ad3d24c510151b signature_algorithm=SHA256-RSA target=smtp://smtp.qq.com:25 type=leaf verification=valid 0 +x509_cert_startdate agent_hostname=zy-fat common_name=DigiCert Secure Site OV G2 TLS CN RSA4096 SHA256 2022 CA1 country=US issuer_common_name=DigiCert Global Root G2 issuer_serial_number= ocsp_stapled=no organization=DigiCert, Inc. public_key_algorithm=RSA san= serial_number=4c1b960191fcabedcda9301a6cd78c3 signature_algorithm=SHA256-RSA target=smtp://smtp.qq.com:25 type=intermediate verification=valid 1671062400 +x509_cert_enddate agent_hostname=zy-fat common_name=DigiCert Secure Site OV G2 TLS CN RSA4096 SHA256 2022 CA1 country=US issuer_common_name=DigiCert Global Root G2 issuer_serial_number= ocsp_stapled=no organization=DigiCert, Inc. public_key_algorithm=RSA san= serial_number=4c1b960191fcabedcda9301a6cd78c3 signature_algorithm=SHA256-RSA target=smtp://smtp.qq.com:25 type=intermediate verification=valid 1986681599 +x509_cert_verification_code agent_hostname=zy-fat common_name=DigiCert Secure Site OV G2 TLS CN RSA4096 SHA256 2022 CA1 country=US issuer_common_name=DigiCert Global Root G2 issuer_serial_number= ocsp_stapled=no organization=DigiCert, Inc. public_key_algorithm=RSA san= serial_number=4c1b960191fcabedcda9301a6cd78c3 signature_algorithm=SHA256-RSA target=smtp://smtp.qq.com:25 type=intermediate verification=valid 0 +x509_cert_age agent_hostname=zy-fat common_name=DigiCert Secure Site OV G2 TLS CN RSA4096 SHA256 2022 CA1 country=US issuer_common_name=DigiCert Global Root G2 issuer_serial_number= ocsp_stapled=no organization=DigiCert, Inc. public_key_algorithm=RSA san= serial_number=4c1b960191fcabedcda9301a6cd78c3 signature_algorithm=SHA256-RSA target=smtp://smtp.qq.com:25 type=intermediate verification=valid 64734476 +x509_cert_expiry agent_hostname=zy-fat common_name=DigiCert Secure Site OV G2 TLS CN RSA4096 SHA256 2022 CA1 country=US issuer_common_name=DigiCert Global Root G2 issuer_serial_number= ocsp_stapled=no organization=DigiCert, Inc. public_key_algorithm=RSA san= serial_number=4c1b960191fcabedcda9301a6cd78c3 signature_algorithm=SHA256-RSA target=smtp://smtp.qq.com:25 type=intermediate verification=valid 250884722 +x509_cert_enddate agent_hostname=zy-fat common_name=baidu.com country=CN issuer_common_name=GlobalSign RSA OV SSL CA 2018 issuer_serial_number= locality=beijing ocsp_stapled=no organization=Beijing Baidu Netcom Science Technology Co., Ltd province=beijing public_key_algorithm=RSA san=baidu.com,baifubao.com,www.baidu.cn,www.baidu.com.cn,mct.y.nuomi.com,apollo.auto,dwz.cn,*.baidu.com,*.baifubao.com,*.baidustatic.com,*.bdstatic.com,*.bdimg.com,*.hao123.com,*.nuomi.com,*.chuanke.com,*.trustgo.com,*.bce.baidu.com,*.eyun.baidu.com,*.map.baidu.com,*.mbd.baidu.com,*.fanyi.baidu.com,*.baidubce.com,*.mipcdn.com,*.news.baidu.com,*.baidupcs.com,*.aipage.com,*.aipage.cn,*.bcehost.com,*.safe.baidu.com,*.im.baidu.com,*.baiducontent.com,*.dlnel.com,*.dlnel.org,*.dueros.baidu.com,*.su.baidu.com,*.91.com,*.hao123.baidu.com,*.apollo.auto,*.xueshu.baidu.com,*.bj.baidubce.com,*.gz.baidubce.com,*.smartapps.cn,*.bdtjrcv.com,*.hao222.com,*.haokan.com,*.pae.baidu.com,*.vd.bdstatic.com,*.cloud.baidu.com,click.hm.baidu.com,log.hm.baidu.com,cm.pos.baidu.com,wn.pos.baidu.com,update.pan.baidu.com serial_number=4e4003a65eb681f87f4bd8eb signature_algorithm=SHA256-RSA target=https://www.baidu.com:443 type=leaf verification=valid 1754703661 +x509_cert_verification_code agent_hostname=zy-fat common_name=baidu.com country=CN issuer_common_name=GlobalSign RSA OV SSL CA 2018 issuer_serial_number= locality=beijing ocsp_stapled=no organization=Beijing Baidu Netcom Science Technology Co., Ltd province=beijing public_key_algorithm=RSA san=baidu.com,baifubao.com,www.baidu.cn,www.baidu.com.cn,mct.y.nuomi.com,apollo.auto,dwz.cn,*.baidu.com,*.baifubao.com,*.baidustatic.com,*.bdstatic.com,*.bdimg.com,*.hao123.com,*.nuomi.com,*.chuanke.com,*.trustgo.com,*.bce.baidu.com,*.eyun.baidu.com,*.map.baidu.com,*.mbd.baidu.com,*.fanyi.baidu.com,*.baidubce.com,*.mipcdn.com,*.news.baidu.com,*.baidupcs.com,*.aipage.com,*.aipage.cn,*.bcehost.com,*.safe.baidu.com,*.im.baidu.com,*.baiducontent.com,*.dlnel.com,*.dlnel.org,*.dueros.baidu.com,*.su.baidu.com,*.91.com,*.hao123.baidu.com,*.apollo.auto,*.xueshu.baidu.com,*.bj.baidubce.com,*.gz.baidubce.com,*.smartapps.cn,*.bdtjrcv.com,*.hao222.com,*.haokan.com,*.pae.baidu.com,*.vd.bdstatic.com,*.cloud.baidu.com,click.hm.baidu.com,log.hm.baidu.com,cm.pos.baidu.com,wn.pos.baidu.com,update.pan.baidu.com serial_number=4e4003a65eb681f87f4bd8eb signature_algorithm=SHA256-RSA target=https://www.baidu.com:443 type=leaf verification=valid 0 +x509_cert_age agent_hostname=zy-fat common_name=baidu.com country=CN issuer_common_name=GlobalSign RSA OV SSL CA 2018 issuer_serial_number= locality=beijing ocsp_stapled=no organization=Beijing Baidu Netcom Science Technology Co., Ltd province=beijing public_key_algorithm=RSA san=baidu.com,baifubao.com,www.baidu.cn,www.baidu.com.cn,mct.y.nuomi.com,apollo.auto,dwz.cn,*.baidu.com,*.baifubao.com,*.baidustatic.com,*.bdstatic.com,*.bdimg.com,*.hao123.com,*.nuomi.com,*.chuanke.com,*.trustgo.com,*.bce.baidu.com,*.eyun.baidu.com,*.map.baidu.com,*.mbd.baidu.com,*.fanyi.baidu.com,*.baidubce.com,*.mipcdn.com,*.news.baidu.com,*.baidupcs.com,*.aipage.com,*.aipage.cn,*.bcehost.com,*.safe.baidu.com,*.im.baidu.com,*.baiducontent.com,*.dlnel.com,*.dlnel.org,*.dueros.baidu.com,*.su.baidu.com,*.91.com,*.hao123.baidu.com,*.apollo.auto,*.xueshu.baidu.com,*.bj.baidubce.com,*.gz.baidubce.com,*.smartapps.cn,*.bdtjrcv.com,*.hao222.com,*.haokan.com,*.pae.baidu.com,*.vd.bdstatic.com,*.cloud.baidu.com,click.hm.baidu.com,log.hm.baidu.com,cm.pos.baidu.com,wn.pos.baidu.com,update.pan.baidu.com serial_number=4e4003a65eb681f87f4bd8eb signature_algorithm=SHA256-RSA target=https://www.baidu.com:443 type=leaf verification=valid 15394014 +x509_cert_expiry agent_hostname=zy-fat common_name=baidu.com country=CN issuer_common_name=GlobalSign RSA OV SSL CA 2018 issuer_serial_number= locality=beijing ocsp_stapled=no organization=Beijing Baidu Netcom Science Technology Co., Ltd province=beijing public_key_algorithm=RSA san=baidu.com,baifubao.com,www.baidu.cn,www.baidu.com.cn,mct.y.nuomi.com,apollo.auto,dwz.cn,*.baidu.com,*.baifubao.com,*.baidustatic.com,*.bdstatic.com,*.bdimg.com,*.hao123.com,*.nuomi.com,*.chuanke.com,*.trustgo.com,*.bce.baidu.com,*.eyun.baidu.com,*.map.baidu.com,*.mbd.baidu.com,*.fanyi.baidu.com,*.baidubce.com,*.mipcdn.com,*.news.baidu.com,*.baidupcs.com,*.aipage.com,*.aipage.cn,*.bcehost.com,*.safe.baidu.com,*.im.baidu.com,*.baiducontent.com,*.dlnel.com,*.dlnel.org,*.dueros.baidu.com,*.su.baidu.com,*.91.com,*.hao123.baidu.com,*.apollo.auto,*.xueshu.baidu.com,*.bj.baidubce.com,*.gz.baidubce.com,*.smartapps.cn,*.bdtjrcv.com,*.hao222.com,*.haokan.com,*.pae.baidu.com,*.vd.bdstatic.com,*.cloud.baidu.com,click.hm.baidu.com,log.hm.baidu.com,cm.pos.baidu.com,wn.pos.baidu.com,update.pan.baidu.com serial_number=4e4003a65eb681f87f4bd8eb signature_algorithm=SHA256-RSA target=https://www.baidu.com:443 type=leaf verification=valid 18906784 +x509_cert_startdate agent_hostname=zy-fat common_name=baidu.com country=CN issuer_common_name=GlobalSign RSA OV SSL CA 2018 issuer_serial_number= locality=beijing ocsp_stapled=no organization=Beijing Baidu Netcom Science Technology Co., Ltd province=beijing public_key_algorithm=RSA san=baidu.com,baifubao.com,www.baidu.cn,www.baidu.com.cn,mct.y.nuomi.com,apollo.auto,dwz.cn,*.baidu.com,*.baifubao.com,*.baidustatic.com,*.bdstatic.com,*.bdimg.com,*.hao123.com,*.nuomi.com,*.chuanke.com,*.trustgo.com,*.bce.baidu.com,*.eyun.baidu.com,*.map.baidu.com,*.mbd.baidu.com,*.fanyi.baidu.com,*.baidubce.com,*.mipcdn.com,*.news.baidu.com,*.baidupcs.com,*.aipage.com,*.aipage.cn,*.bcehost.com,*.safe.baidu.com,*.im.baidu.com,*.baiducontent.com,*.dlnel.com,*.dlnel.org,*.dueros.baidu.com,*.su.baidu.com,*.91.com,*.hao123.baidu.com,*.apollo.auto,*.xueshu.baidu.com,*.bj.baidubce.com,*.gz.baidubce.com,*.smartapps.cn,*.bdtjrcv.com,*.hao222.com,*.haokan.com,*.pae.baidu.com,*.vd.bdstatic.com,*.cloud.baidu.com,click.hm.baidu.com,log.hm.baidu.com,cm.pos.baidu.com,wn.pos.baidu.com,update.pan.baidu.com serial_number=4e4003a65eb681f87f4bd8eb signature_algorithm=SHA256-RSA target=https://www.baidu.com:443 type=leaf verification=valid 1720402862 +x509_cert_age agent_hostname=zy-fat common_name=GlobalSign RSA OV SSL CA 2018 country=BE issuer_common_name=GlobalSign issuer_serial_number= ocsp_stapled=no organization=GlobalSign nv-sa public_key_algorithm=RSA san= serial_number=1ee5f221dfc623bd4333a8557 signature_algorithm=SHA256-RSA target=https://www.baidu.com:443 type=intermediate verification=valid 193038476 +x509_cert_expiry agent_hostname=zy-fat common_name=GlobalSign RSA OV SSL CA 2018 country=BE issuer_common_name=GlobalSign issuer_serial_number= ocsp_stapled=no organization=GlobalSign nv-sa public_key_algorithm=RSA san= serial_number=1ee5f221dfc623bd4333a8557 signature_algorithm=SHA256-RSA target=https://www.baidu.com:443 type=intermediate verification=valid 122580723 +x509_cert_startdate agent_hostname=zy-fat common_name=GlobalSign RSA OV SSL CA 2018 country=BE issuer_common_name=GlobalSign issuer_serial_number= ocsp_stapled=no organization=GlobalSign nv-sa public_key_algorithm=RSA san= serial_number=1ee5f221dfc623bd4333a8557 signature_algorithm=SHA256-RSA target=https://www.baidu.com:443 type=intermediate verification=valid 1542758400 +x509_cert_enddate agent_hostname=zy-fat common_name=GlobalSign RSA OV SSL CA 2018 country=BE issuer_common_name=GlobalSign issuer_serial_number= ocsp_stapled=no organization=GlobalSign nv-sa public_key_algorithm=RSA san= serial_number=1ee5f221dfc623bd4333a8557 signature_algorithm=SHA256-RSA target=https://www.baidu.com:443 type=intermediate verification=valid 1858377600 +x509_cert_verification_code agent_hostname=zy-fat common_name=GlobalSign RSA OV SSL CA 2018 country=BE issuer_common_name=GlobalSign issuer_serial_number= ocsp_stapled=no organization=GlobalSign nv-sa public_key_algorithm=RSA san= serial_number=1ee5f221dfc623bd4333a8557 signature_algorithm=SHA256-RSA target=https://www.baidu.com:443 type=intermediate verification=valid 0 +x509_cert_age agent_hostname=zy-fat common_name=GlobalSign issuer_common_name=GlobalSign Root CA issuer_serial_number= ocsp_stapled=no organization=GlobalSign organizational_unit=GlobalSign Root CA - R3 public_key_algorithm=RSA san= serial_number=1ee5f169dff97352b6465d66a signature_algorithm=SHA256-RSA target=https://www.baidu.com:443 type=intermediate verification=valid 198481676 +x509_cert_expiry agent_hostname=zy-fat common_name=GlobalSign issuer_common_name=GlobalSign Root CA issuer_serial_number= ocsp_stapled=no organization=GlobalSign organizational_unit=GlobalSign Root CA - R3 public_key_algorithm=RSA san= serial_number=1ee5f169dff97352b6465d66a signature_algorithm=SHA256-RSA target=https://www.baidu.com:443 type=intermediate verification=valid 96876723 +x509_cert_startdate agent_hostname=zy-fat common_name=GlobalSign issuer_common_name=GlobalSign Root CA issuer_serial_number= ocsp_stapled=no organization=GlobalSign organizational_unit=GlobalSign Root CA - R3 public_key_algorithm=RSA san= serial_number=1ee5f169dff97352b6465d66a signature_algorithm=SHA256-RSA target=https://www.baidu.com:443 type=intermediate verification=valid 1537315200 +x509_cert_enddate agent_hostname=zy-fat common_name=GlobalSign issuer_common_name=GlobalSign Root CA issuer_serial_number= ocsp_stapled=no organization=GlobalSign organizational_unit=GlobalSign Root CA - R3 public_key_algorithm=RSA san= serial_number=1ee5f169dff97352b6465d66a signature_algorithm=SHA256-RSA target=https://www.baidu.com:443 type=intermediate verification=valid 1832673600 +x509_cert_verification_code agent_hostname=zy-fat common_name=GlobalSign issuer_common_name=GlobalSign Root CA issuer_serial_number= ocsp_stapled=no organization=GlobalSign organizational_unit=GlobalSign Root CA - R3 public_key_algorithm=RSA san= serial_number=1ee5f169dff97352b6465d66a signature_algorithm=SHA256-RSA target=https://www.baidu.com:443 type=intermediate verification=valid 0 +``` \ No newline at end of file diff --git a/inputs/x509_cert/x509_cert.go b/inputs/x509_cert/x509_cert.go new file mode 100644 index 00000000..3c0667ae --- /dev/null +++ b/inputs/x509_cert/x509_cert.go @@ -0,0 +1,538 @@ +package x509_cert + +import ( + "bytes" + "crypto/tls" + "crypto/x509" + "encoding/hex" + "encoding/pem" + "errors" + "fmt" + "log" + "net" + "net/http" + "net/smtp" + "net/url" + "os" + "path/filepath" + "regexp" + "strings" + "time" + + "github.com/pion/dtls/v2" + + "golang.org/x/crypto/ocsp" + + "flashcat.cloud/categraf/config" + "flashcat.cloud/categraf/inputs" + "flashcat.cloud/categraf/pkg/globpath" + "flashcat.cloud/categraf/pkg/proxy" + commontls "flashcat.cloud/categraf/pkg/tls" + "flashcat.cloud/categraf/types" +) + +const inputName = "x509_cert" + +// Regexp for handling file URIs containing a drive letter and leading slash +var reDriveLetter = regexp.MustCompile(`^/([a-zA-Z]:/)`) + +type X509Cert struct { + config.PluginConfig + Instances []*Instance `toml:"instances"` +} + +type Instance struct { + Targets []string `toml:"targets"` + Timeout config.Duration `toml:"timeout"` + ServerName string `toml:"server_name"` + ExcludeRootCerts bool `toml:"exclude_root_certs"` + + globPaths []globpath.GlobPath + locations []*url.URL + + classification map[string]string + + commontls.ClientConfig + tlsCfg *tls.Config + + proxy.TCPProxy + client *http.Client + config.HTTPCommonConfig + config.InstanceConfig +} + +func init() { + inputs.Add(inputName, func() inputs.Input { + return &X509Cert{} + }) +} + +func (ins *Instance) Init() error { + if len(ins.Targets) == 0 { + return types.ErrInstancesEmpty + } + + if ins.Timeout <= 0 { + ins.Timeout = config.Duration(time.Second * 5) + } + + if ins.ClientConfig.ServerName != "" && ins.ServerName != "" { + return fmt.Errorf("both server_name (%q) and tls_server_name (%q) are set, but they are mutually exclusive", ins.ServerName, ins.ClientConfig.ServerName) + } else if ins.ServerName != "" { + // Store the user-provided server-name in the TLS configuration + ins.ClientConfig.ServerName = ins.ServerName + } + + // Normalize the sources, handle files and file-globbing + if err := ins.sourcesToURLs(); err != nil { + return err + } + + ins.InitHTTPClientConfig() + + var err error + ins.client, err = ins.createHTTPClient() + + tlsCfg, err := ins.ClientConfig.TLSConfig() + if err != nil { + return err + } + if tlsCfg == nil { + tlsCfg = &tls.Config{} + } + ins.tlsCfg = tlsCfg + return err +} + +func (ins *X509Cert) Clone() inputs.Input { + return &X509Cert{} +} + +func (ins *X509Cert) Name() string { + return inputName +} + +func (ins *X509Cert) GetInstances() []inputs.Instance { + ret := make([]inputs.Instance, len(ins.Instances)) + for i := 0; i < len(ins.Instances); i++ { + ret[i] = ins.Instances[i] + } + return ret +} + +func (ins *Instance) Gather(slist *types.SampleList) { + if len(ins.Targets) == 0 { + return + } + + now := time.Now() + collectedUrls := append(ins.locations, ins.collectCertURLs()...) + for _, location := range collectedUrls { + certs, ocspresp, err := ins.getCert(location, time.Duration(ins.Timeout)) + if err != nil { + log.Printf("E! cannot get SSL cert %q: %v", location, err) + continue + } + + intermediates := x509.NewCertPool() + if len(certs) > 1 { + for _, cert := range certs[1:] { + intermediates.AddCert(cert) + } + } + + dnsName := ins.serverName(location) + results := make([]error, len(certs)) + ins.classification = make(map[string]string) + for i, cert := range certs { + opts := x509.VerifyOptions{ + Intermediates: intermediates, + KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageAny}, + Roots: ins.tlsCfg.RootCAs, + DNSName: dnsName, + } + results[i] = ins.processCertificate(cert, opts) + dnsName = "" + } + + for i, cert := range certs { + fields := getFields(cert, now) + tags := getTags(cert, location.String()) + + if err := results[i]; err == nil { + tags["verification"] = "valid" + fields["verification_code"] = 0 + } else { + tags["verification"] = "invalid" + fields["verification_code"] = 1 + } + + if i == 0 && ocspresp != nil && len(*ocspresp) > 0 { + var ocspissuer *x509.Certificate + for _, chaincert := range certs[1:] { + if cert.Issuer.CommonName == chaincert.Subject.CommonName && + cert.Issuer.SerialNumber == chaincert.Subject.SerialNumber { + ocspissuer = chaincert + break + } + } + resp, err := ocsp.ParseResponse(*ocspresp, ocspissuer) + if err != nil { + if ocspissuer == nil { + tags["ocsp_stapled"] = "no" + fields["ocsp_error"] = err.Error() + } else { + ocspissuer = nil // retry parsing w/out issuer cert + resp, err = ocsp.ParseResponse(*ocspresp, ocspissuer) + } + } + if err != nil { + tags["ocsp_stapled"] = "no" + fields["ocsp_error"] = err.Error() + } else { + tags["ocsp_stapled"] = "yes" + if ocspissuer != nil { + tags["ocsp_verified"] = "yes" + } else { + tags["ocsp_verified"] = "no" + } + // resp.Status: 0=Good 1=Revoked 2=Unknown + fields["ocsp_status_code"] = resp.Status + switch resp.Status { + case 0: + tags["ocsp_status"] = "good" + case 1: + tags["ocsp_status"] = "revoked" + // Status=Good: revoked_at always = -62135596800 + fields["ocsp_revoked_at"] = resp.RevokedAt.Unix() + default: + tags["ocsp_status"] = "unknown" + } + fields["ocsp_produced_at"] = resp.ProducedAt.Unix() + fields["ocsp_this_update"] = resp.ThisUpdate.Unix() + fields["ocsp_next_update"] = resp.NextUpdate.Unix() + } + } else { + tags["ocsp_stapled"] = "no" + } + + sig := hex.EncodeToString(cert.Signature) + if class, found := ins.classification[sig]; found { + tags["type"] = class + } else { + tags["type"] = "leaf" + } + + slist.PushSamples("x509_cert", fields, tags) + if ins.ExcludeRootCerts { + break + } + } + } +} + +func (ins *Instance) processCertificate(cert *x509.Certificate, opts x509.VerifyOptions) error { + chains, err := cert.Verify(opts) + if err != nil { + log.Printf("W! Invalid certificate %v: %v", cert.SerialNumber.Text(16), err) + if ins.DebugMod { + log.Printf("W! cert DNS names: %v", cert.DNSNames) + log.Printf("W! cert IP addresses: %v", cert.IPAddresses) + log.Printf("W! cert subject: %v", cert.Subject) + log.Printf("W! cert issuer: %v", cert.Issuer) + log.Printf("W! opts.DNSName: %v", opts.DNSName) + log.Printf("W! verify options: %v", opts) + log.Printf("W! verify error: %v", err) + log.Printf("W! tlsCfg.ServerName: %v", ins.tlsCfg.ServerName) + log.Printf("W! ServerName: %v", ins.ServerName) + } + } + + // Check if the certificate is a root-certificate. + // The only reliable way to distinguish root certificates from + // intermediates is the fact that root certificates are self-signed, + // i.e. you can verify the certificate with its own public key. + rootErr := cert.CheckSignature(cert.SignatureAlgorithm, cert.RawTBSCertificate, cert.Signature) + if rootErr == nil { + sig := hex.EncodeToString(cert.Signature) + ins.classification[sig] = "root" + } + // Identify intermediate certificates + for _, chain := range chains { + for _, chainCert := range chain[1:] { + sig := hex.EncodeToString(chainCert.Signature) + if _, found := ins.classification[sig]; !found { + if chainCert.IsCA { + ins.classification[sig] = "intermediate" + } else { + ins.classification[sig] = "unknown" + } + } + } + } + + return err +} + +func (ins *Instance) sourcesToURLs() error { + for _, target := range ins.Targets { + if strings.HasPrefix(target, "file://") || strings.HasPrefix(target, "/") { + target = filepath.ToSlash(strings.TrimPrefix(target, "file://")) + target = reDriveLetter.ReplaceAllString(target, "$1") + files, err := filepath.Glob(target) + if err != nil { + return fmt.Errorf("could not process target %q: %w", target, err) + } + for _, file := range files { + ins.locations = append(ins.locations, &url.URL{Scheme: "file", Path: file}) + } + } else { + if strings.Index(target, ":\\") == 1 { + target = "file://" + filepath.ToSlash(target) + } + u, err := url.Parse(target) + if err != nil { + return fmt.Errorf("failed to parse target %q: %w", target, err) + } + ins.locations = append(ins.locations, u) + } + } + return nil +} + +func (ins *Instance) serverName(u *url.URL) string { + if ins.ServerName != "" { + return ins.ServerName + } + return u.Hostname() +} + +func (ins *Instance) getCert(u *url.URL, timeout time.Duration) ([]*x509.Certificate, *[]byte, error) { + protocol := u.Scheme + switch u.Scheme { + case "udp", "udp4", "udp6": + ipConn, err := net.DialTimeout(u.Scheme, u.Host, timeout) + if err != nil { + return nil, nil, err + } + defer ipConn.Close() + + dtlsCfg := &dtls.Config{ + InsecureSkipVerify: true, + Certificates: ins.tlsCfg.Certificates, + RootCAs: ins.tlsCfg.RootCAs, + ServerName: ins.serverName(u), + } + conn, err := dtls.Client(ipConn, dtlsCfg) + if err != nil { + return nil, nil, err + } + defer conn.Close() + + rawCerts := conn.ConnectionState().PeerCertificates + var certs []*x509.Certificate + for _, rawCert := range rawCerts { + parsed, err := x509.ParseCertificate(rawCert) + if err != nil { + return nil, nil, err + } + + if parsed != nil { + certs = append(certs, parsed) + } + } + + return certs, nil, nil + case "https": + protocol = "tcp" + if u.Port() == "" { + u.Host += ":443" + } + fallthrough + case "tcp", "tcp4", "tcp6": + dialer, err := ins.Proxy() + if err != nil { + return nil, nil, err + } + ipConn, err := dialer.DialTimeout(protocol, u.Host, timeout) + if err != nil { + return nil, nil, err + } + defer ipConn.Close() + + downloadTLSCfg := ins.tlsCfg.Clone() + downloadTLSCfg.ServerName = ins.serverName(u) + downloadTLSCfg.InsecureSkipVerify = true + + conn := tls.Client(ipConn, downloadTLSCfg) + defer conn.Close() + + hsErr := conn.Handshake() + if hsErr != nil { + return nil, nil, hsErr + } + + certs := conn.ConnectionState().PeerCertificates + ocspresp := conn.ConnectionState().OCSPResponse + + return certs, &ocspresp, nil + case "file": + content, err := os.ReadFile(u.Path) + if err != nil { + return nil, nil, err + } + var certs []*x509.Certificate + for { + block, rest := pem.Decode(bytes.TrimSpace(content)) + if block == nil { + return nil, nil, errors.New("failed to parse certificate PEM") + } + + if block.Type == "CERTIFICATE" { + cert, err := x509.ParseCertificate(block.Bytes) + if err != nil { + return nil, nil, err + } + certs = append(certs, cert) + } + if len(rest) == 0 { + break + } + content = rest + } + return certs, nil, nil + case "smtp": + ipConn, err := net.DialTimeout("tcp", u.Host, timeout) + if err != nil { + return nil, nil, err + } + defer ipConn.Close() + + downloadTLSCfg := ins.tlsCfg.Clone() + downloadTLSCfg.ServerName = ins.serverName(u) + downloadTLSCfg.InsecureSkipVerify = true + + smtpConn, err := smtp.NewClient(ipConn, u.Host) + if err != nil { + return nil, nil, err + } + + err = smtpConn.Hello(downloadTLSCfg.ServerName) + if err != nil { + return nil, nil, err + } + + id, err := smtpConn.Text.Cmd("STARTTLS") + if err != nil { + return nil, nil, err + } + + smtpConn.Text.StartResponse(id) + defer smtpConn.Text.EndResponse(id) + _, _, err = smtpConn.Text.ReadResponse(220) + if err != nil { + return nil, nil, fmt.Errorf("did not get 220 after STARTTLS: %w", err) + } + + tlsConn := tls.Client(ipConn, downloadTLSCfg) + defer tlsConn.Close() + + hsErr := tlsConn.Handshake() + if hsErr != nil { + return nil, nil, hsErr + } + + certs := tlsConn.ConnectionState().PeerCertificates + ocspresp := tlsConn.ConnectionState().OCSPResponse + + return certs, &ocspresp, nil + default: + return nil, nil, fmt.Errorf("unsupported scheme %q in location %s", u.Scheme, u.String()) + } +} + +func getFields(cert *x509.Certificate, now time.Time) map[string]interface{} { + age := int(now.Sub(cert.NotBefore).Seconds()) + expiry := int(cert.NotAfter.Sub(now).Seconds()) + startdate := cert.NotBefore.Unix() + enddate := cert.NotAfter.Unix() + + fields := map[string]interface{}{ + "age": age, + "expiry": expiry, + "startdate": startdate, + "enddate": enddate, + } + + return fields +} + +func getTags(cert *x509.Certificate, location string) map[string]string { + tags := map[string]string{ + "target": location, + "common_name": cert.Subject.CommonName, + "serial_number": cert.SerialNumber.Text(16), + "signature_algorithm": cert.SignatureAlgorithm.String(), + "public_key_algorithm": cert.PublicKeyAlgorithm.String(), + } + + if len(cert.Subject.Organization) > 0 { + tags["organization"] = cert.Subject.Organization[0] + } + if len(cert.Subject.OrganizationalUnit) > 0 { + tags["organizational_unit"] = cert.Subject.OrganizationalUnit[0] + } + if len(cert.Subject.Country) > 0 { + tags["country"] = cert.Subject.Country[0] + } + if len(cert.Subject.Province) > 0 { + tags["province"] = cert.Subject.Province[0] + } + if len(cert.Subject.Locality) > 0 { + tags["locality"] = cert.Subject.Locality[0] + } + + tags["issuer_common_name"] = cert.Issuer.CommonName + tags["issuer_serial_number"] = cert.Issuer.SerialNumber + + san := append(cert.DNSNames, cert.EmailAddresses...) + for _, ip := range cert.IPAddresses { + san = append(san, ip.String()) + } + for _, uri := range cert.URIs { + san = append(san, uri.String()) + } + tags["san"] = strings.Join(san, ",") + + return tags +} + +func (ins *Instance) createHTTPClient() (*http.Client, error) { + tr := &http.Transport{ + ResponseHeaderTimeout: time.Duration(ins.Timeout), + } + + client := &http.Client{ + Transport: tr, + Timeout: time.Duration(ins.Timeout), + } + return client, nil +} + +func (ins *Instance) collectCertURLs() []*url.URL { + var urls []*url.URL + + for _, path := range ins.globPaths { + files := path.Match() + if len(files) == 0 { + log.Println("W! could not find file:", path.GetRoots()) + continue + } + for _, file := range files { + fn := filepath.ToSlash(file) + urls = append(urls, &url.URL{Scheme: "file", Path: fn}) + } + } + + return urls +}