Giter VIP home page Giter VIP logo

check-cert's Introduction

About me

Role: Systems Administrator

Experience
  • support: troubleshooting, training, documentation
  • proxies & web servers: Squid, Apache, Nginx, HAProxy, IIS
  • mail servers: Postfix, Dovecot, Roundcube, DKIM, Postgrey
  • config/change management: Subversion, Git, Ansible
  • containers: Docker, LXD
  • virtualization: VMware, Hyper-V, VirtualBox
  • databases: MySQL/MariaDB, PostgreSQL, Microsoft SQL Server
  • monitoring: Nagios, custom tooling, Microsoft Teams, fail2ban
  • logging: rsyslog (local, central receivers), Graylog
  • ticketing: Redmine, GitHub, GitLab, Service Now

Role: Intermediate developer

Experience
  • current:
    • Go, Python, PowerShell, shell scripting
    • MySQL/MariaDB, SQLite
    • Docker, LXD
    • Markdown, Textile, MediaWiki, reStructuredText, HTML, CSS
    • Redmine, GitHub (including GitHub Actions), Gitea, GitLab
  • past: batch files (don't laugh, it gets the job done), Perl
  • academic: C, C++

check-cert's People

Contributors

atc0005 avatar dependabot[bot] avatar gui avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

check-cert's Issues

Expiring certificate was flagged one day after official check_http Nagios plugin did so

We had a deprecated cert expiration check trigger last night at 7 pm (I think it was). This is the output for that deprecated check:

expires in 30 day(s) (Sat 01 Aug 2020 12:59:00 AM CDT)

Output for the new check (specific to the leaf cert):

expires next (on 2020-07-31 23:59:59 +0000 UTC)

and from the "Detailed Info" block:

Expiration: 2020-07-31 23:59:59 +0000 UTC

I suspect that all time/date comparisons are being performed in UTC already, but I want to double-check and ensure that is the case. If so, I'm not too concerned (based on my current understanding) that the old check is in local time and the new one (presumably) is in UTC.

In short: I'd want to have the comparison time zones match, so if the cert expiration is in UTC, then I think we should compare based on UTC.

Add binary for scanning a range of IPs and reporting a summary of expiration details (OK, WARNING, CRITICAL)

I'm thinking of output similar to the atc0005/dnsc project, very high-level for discovery. Specific systems can then be evaluated more closely via lscert.

Perhaps have quick result codes of OK, ! and X.

The concepts here should come in handy:

README | Update badges to link to the applicable workflow

While useful, the current status badges link out to the SVG used to provide the current status, not the workflow results themselves.

Update all badges to use a syntax similar to 'GoDoc' or 'Latest Release' so that the badge displays, but also functions as a "GoTo" button as well.

Consider reworking one-line summary | Invalid certificate chain for "www.example.com" [EXPIRED: 0, EXPIRING: 1, OK: 3]

Current "Status Information" line (aka, "one-line summary" or "subject line"):

Invalid certificate chain for "www.example.com" [EXPIRED: 0, EXPIRING: 1, OK: 3]

This high-level overview was useful when updating cert chains from a recent AddTrust Root CA expiration: We knew which systems were affected based on the EXPIRED portion of that suffix, so the lead-in text was left of a concern. Now that we're past that point and only concerned about standard replacement tasks, it feels less useful.

The Expiration/Status details for our example:

Expiration: 2020-07-31 23:59:59 +0000 UTC
Status: [WARNING] 26d 14h remaining

The text for the check_http plugin:

WARNING - Certificate 'www.example.com' expires in 26 day(s) (Sat 01 Aug 2020 12:59:00 AM CDT).

This spells out the number of days and the date. While not strictly required (our overview does give an overview which explains that we have an expiring cert), the check_http plugin does give a sense of urgency with the number of remaining days that the check_cert plugin does not.

I'm thinking that perhaps we should mirror at least the basic details of the official Nagios plugin.

Go 1.15 changes worth noting: VerifyHostname

From https://tip.golang.org/doc/go1.15:

If either the name on the certificate or the name being verified (with VerifyOptions.DNSName or VerifyHostname) are invalid, they will now be compared case-insensitively without further processing (without honoring wildcards or stripping trailing dots). Invalid names include those with any characters other than letters, digits, hyphens and underscores, those with empty labels, and names on certificates with trailing dots.

The deprecated, legacy behavior of treating the CommonName field as a hostname when no Subject Alternative Names are present is now disabled by default

Not sure of the impact yet (if any). Will need to build and see what results I get.

Rename internal/net to internal/netutils?

This really should have stood out during the initial package creation, but I blame the tunnel vision focus I had for other tasks. I ran into a minor conflict this AM while prototyping some work for #136.

Idea: Rename internal/net to internal/netutils to help avoid package name collisions with standard library net package.

While I've been wrapping most/all references to items from the standard library net package within internal/net, this practice will likely break down at some point. It's easier to go ahead and rename now, update references and move on to other tasks.

Add config file support?

I'm not yet sure this is needed, but if it is added, I can see that it would primarily be useful for specifying ranges of IPs that need to be checked periodically. For example, perhaps a monthly subnet scan using a preconfigured (static) list of IP Addresses would be useful.

Opening this issue to track the idea and any notes related to it. Not sure yet if it is worth adding the support. Maybe after #136 is completed I will have a better idea.

Self-signed leaf certificate misidentified as root certificate

Encountered this when scanning an IP range with multiple appliances (software and hardware). One of the certs is self-signed without any others in the chain.

Perhaps we need to label self-signed certificates as such? Maybe self-signed leaf would be appropriate?

Add optional flag (or flags) to object to presence of 2nd intermediate or root cert in the certificate chain

Currently certs are marked invalid for a variety of other reasons, but considered valid when a 2nd intermediate or root cert is present. Some best practices guides suggest leaving out those certificates and relying on the client to resolve the full chain path.

From the https://utcc.utoronto.ca/~cks/space/blog/tech/TLSHowMultipleChains blog post:

One cause of additional issuer certificates is what's called cross-signing a CA's intermediate certificate, as is currently the case with Let's Encrypt's certificates. In cross-signing, a CA generate two versions of its intermediate certificate, using the same X.509 Subject Name and keypair; one is signed by its own CA root certificate and one is signed by another CA root certificate. A CA can also cross-sign its own new root certificate (well, the keypair and issuer) directly, as is the case with the DST Root CA X3 certificate that Let's Encrypt is currently cross-signed with; one certificate for 'DST Root CA X3' is self-signed and likely in your root certificate set, but two others existed that were cross-signed by an older DST CA root certificate.

(As covered in the certificate chain illustrations in Fixing the Breakage from the AddTrust External CA Root Expiration, this was also the case with the expiring AddTrust root CA certificate. The 'USERTrust RSA Certification Authority' issuer was also cross-signed to 'AddTrust External CA Root', a CA root certificate that expired along with that cross-signed intermediate certificate. And this USERTrust root issuer is still cross signed to another valid root certificate, 'AAA Certificate Services'.)

Refresh examples to demo changes from v0.1.2 release

The latest release includes a number of output changes that are worth highlighting. With the discovery of expired.badssl.com, we now have a public example of a bad/expired certificate chain to test against.

lscert, check_cert : TCP connection is not closed after use

While reviewing the ReturnCheckResults function doc comments from the atc0005/go-nagios package I saw multiple references to deferring that function in order to prevent early exit by the client application. This is needed in order to allow other deferred functions to run as expected.

I spot-checked both lscert and check_cert and found that both do not appear to close the connection opened by the tls.Dial* function after use (preferably via a defer statement):

conn, connErr := tls.DialWithDialer(dialer, "tcp", server, &cfg)
if connErr != nil {
log.Error().Err(connErr).Msgf("error connecting to server")
os.Exit(1)
}
log.Debug().Msg("Connected")

conn, connErr := tls.DialWithDialer(dialer, "tcp", server, &cfg)
if connErr != nil {
nagiosExitState.LastError = connErr
nagiosExitState.ServiceOutput = fmt.Sprintf(
"%s: Error connecting to %s",
nagios.StateCRITICALLabel,
server,
)
nagiosExitState.ExitStatusCode = nagios.StateCRITICALExitCode
log.Error().Err(connErr).Str("server", server).Msg("error connecting to server")
nagiosExitState.ReturnCheckResults()
}
log.Debug().Msg("Connected")

I would have hoped that linters would have picked this up, but it's still on me.

atc0005/go-nagios v0.4.0 released

This release adds the NagiosExitState type (as ExitState ) along with the ReturnCheckResults method. With that work, this project can upgrade to that dependency and drop the now duplicated code.

README: Update examples to include fixed serial numbers

The serial numbers shown in the examples still have the base 10 text formatted values instead of base 16 delimited text values with (potential) leading zero.

This should be fixed to reflect the recent work to resolve the formatting issues for serial numbers in v0.1.10 and v0.1.11.

Add CSV export option

Not sure yet whether this should be considered a third "summary" option (overview, detailed, csv) or a redirection of the currently selected summary display content. I'm thinking the former, but potentially the latter as a later enhancement (if considered useful).

This first implementation could focus on exporting as much metadata about each certificate as could prove useful, placing lesser referenced fields towards the end of the output.

Warning and Critical threshold key/value pair list items are rendered without whitespace separators

We got an alert in from our Nagios instance a bit ago that lacks the expected whitespace between the key/value pairs:

* CRITICAL:Expires before 2020-09-15 14:50:05 +0000 UTC (15 days)
* WARNING:Expires before 2020-09-30 14:50:05 +0000 UTC (30 days)

This looks to be relevant:

nagiosExitState.WarningThreshold = fmt.Sprintf(
"%s:\tExpires before %v (%d days)",
nagios.StateWARNINGLabel,
certsExpireAgeWarning.Format(certs.CertValidityDateLayout),
config.AgeWarning,
)
nagiosExitState.CriticalThreshold = fmt.Sprintf(
"%s:\tExpires before %v (%d days)",
nagios.StateCRITICALLabel,
certsExpireAgeCritical.Format(certs.CertValidityDateLayout),
config.AgeCritical,
)

Evidently the tab character is stripped out. Replacing with literal spacing, even if just one space is probably the better (more compatible) way to go.

Makefile generates checksums with qualified path

Example:

e0354df6547587e183675ac4ade0db16cd9d341980ed6f1c6e2917889f6ead3c *release_assets/check_cert/check_cert-v0.1.6-0-g2e1b163-linux-386

Ideally, this would be the entry:

e0354df6547587e183675ac4ade0db16cd9d341980ed6f1c6e2917889f6ead3c *check_cert-v0.1.6-0-g2e1b163-linux-386

To fix this, the checksum file would (probably) need to be created by changing the CWD during checksum generation to the same directory where each file resides.

Update cert chain summary output to include the 'Not Before' value also

Currently the 'Not After' value is exposed as the Expiration value in the summary output.

Example from checking github.com via the lscert tool:

$ lscert --server github.com

Connecting to remote server "github.com" at port 443


=============================
CERTIFICATES | AGE THRESHOLDS
=============================

- WARNING:      Expires before 2020-12-05 15:42:50 +0000 UTC (30 days)
- CRITICAL:     Expires before 2020-11-20 15:42:50 +0000 UTC (15 days)


======================
CERTIFICATES | SUMMARY
======================

- OK: 2 certs found for service running on github.com at port 443
- OK: Provided hostname matches discovered certificate
- OK: leaf cert "github.com" expires next with 550d 20h remaining (until 2022-05-10 12:00:00 +0000 UTC)
- OK: [EXPIRED: 0, EXPIRING: 0, OK: 2]


============================
CERTIFICATES | CHAIN DETAILS
============================
Certificate 1 of 2 (leaf):
        Name: CN=github.com,O=GitHub\, Inc.,L=San Francisco,ST=California,C=US
        SANs entries: [github.com www.github.com]
        KeyID: 63:2:D2:5D:2:5F:F7:8D:D5:5A:12:9E:76:11:36:96:86:2C:8A:48
        Issuer: CN=DigiCert SHA2 High Assurance Server CA,OU=www.digicert.com,O=DigiCert Inc,C=US
        IssuerKeyID: 51:68:FF:90:AF:2:7:75:3C:CC:D9:65:64:62:A2:12:B8:59:72:3B
        Serial: 7101927171473588541993819712332065657
        Expiration: 2022-05-10 12:00:00 +0000 UTC
        Status: [OK] 550d 20h remaining

Certificate 2 of 2 (intermediate):
        Name: CN=DigiCert SHA2 High Assurance Server CA,OU=www.digicert.com,O=DigiCert Inc,C=US
        SANs entries: []
        KeyID: 51:68:FF:90:AF:2:7:75:3C:CC:D9:65:64:62:A2:12:B8:59:72:3B
        Issuer: CN=DigiCert High Assurance EV Root CA,OU=www.digicert.com,O=DigiCert Inc,C=US
        IssuerKeyID: B1:3E:C3:69:3:F8:BF:47:1:D4:98:26:1A:8:2:EF:63:64:2B:C3
        Serial: 6489877074546166222510380951761917343
        Expiration: 2028-10-22 12:00:00 +0000 UTC
        Status: [OK] 2907d 20h remaining

Adding the 'Not Before' value (not sure of label name yet) would be helpful in fairly quickly identifying when a cert was generated/replaced.

Expired (version 1) CA certificate misidentified as leaf certificate

Output from a current dev build of the lscert application:

Certificate 2 of 4 (intermediate):
        Name: SERIALNUMBER=07969287,CN=Go Daddy Secure Certification Authority,OU=http://certificates.godaddy.com/repository,O=GoDaddy.com\, Inc.,L=Scottsdale,ST=Arizona,C=US
        SANs entries: []
        KeyID: FD:AC:61:32:93:6C:45:D6:E2:EE:85:5F:9A:BA:E7:76:99:68:CC:E7
        Issuer: OU=Go Daddy Class 2 Certification Authority,O=The Go Daddy Group\, Inc.,C=US
        IssuerKeyID: D2:C4:B0:D2:91:D4:4C:11:71:B3:61:CB:3D:A1:FE:DD:A8:6A:D4:E3
        Serial: 03:01
        Issued On: 2006-11-16 01:54:37 +0000 UTC
        Expiration: 2026-11-16 01:54:37 +0000 UTC
        Status: [OK] 2163d 12h remaining

Certificate 3 of 4 (intermediate):
        Name: OU=Go Daddy Class 2 Certification Authority,O=The Go Daddy Group\, Inc.,C=US
        SANs entries: []
        KeyID: D2:C4:B0:D2:91:D4:4C:11:71:B3:61:CB:3D:A1:FE:DD:A8:6A:D4:E3
        Issuer: CN=http://www.valicert.com/,OU=ValiCert Class 2 Policy Validation Authority,O=ValiCert\, Inc.,L=ValiCert Validation Network,1.2.840.113549.1.9.1=#0c11696e666f4076616c69636572742e636f6d
        IssuerKeyID:
        Serial: 01:0D
        Issued On: 2004-06-29 17:06:20 +0000 UTC
        Expiration: 2024-06-29 17:06:20 +0000 UTC
        Status: [OK] 1294d 4h remaining

Certificate 4 of 4 (leaf):
        Name: CN=http://www.valicert.com/,OU=ValiCert Class 2 Policy Validation Authority,O=ValiCert\, Inc.,L=ValiCert Validation Network,1.2.840.113549.1.9.1=#0c11696e666f4076616c69636572742e636f6d
        SANs entries: []
        KeyID:
        Issuer: CN=http://www.valicert.com/,OU=ValiCert Class 2 Policy Validation Authority,O=ValiCert\, Inc.,L=ValiCert Validation Network,1.2.840.113549.1.9.1=#0c11696e666f4076616c69636572742e636f6d
        IssuerKeyID:
        Serial: 01
        Issued On: 1999-06-26 00:19:54 +0000 UTC
        Expiration: 2019-06-26 00:19:54 +0000 UTC
        Status: [EXPIRED] 536d 12h ago

The current logic for determining the chain position:

// ChainPosition receives a cert and returns a string indicating what position
// or "role" it occurpies in the certificate chain
func ChainPosition(cert *x509.Certificate) string {
var certPosition string
switch {
// Certificate generated by an EMC VNXe 3100 Storage array was self-signed
// so had the same Issuer and Subject, but wasn't truly a CA cert
// (AFAICT). Applying the IsCA check here causes that cert to be properly
// categorized as a "leaf" certificate.
case cert.Issuer.String() == cert.Subject.String() && cert.IsCA:
certPosition = certChainPositionRoot
case cert.IsCA:
certPosition = certChainPositionIntermediate
case !cert.IsCA:
certPosition = certChainPositionLeaf
default:
certPosition = certChainPositionUnknown
}
return certPosition
}

Update "TYPE cert XYZ expires next" function to help ensure non-blank output

Got this snippet in the output of running lscert against a domain controller today while setting up a Nagios check:

- FYI: leaf cert "" expires next (on 2023-04-11 14:26:05 +0000 UTC)

The Common Name is completely blank for this cert, but there are multiple SANs entries.

Ideally the lscert tool will catch this and use the first SANs entry found as the display name for the leaf certificate (shown in this issue title as XYZ).

Certificate serial number reported in wrong format

Problem

When testing a prototype for a future tool (#103), I found that a self-signed certificate for a printer's web UI had a negative serial number. Looking closer, I found that all serial numbers that have been reported since v0.1.0 have been in an incorrect format.

From a README example:

Certificate 1 of 2 (leaf):
        Name: CN=www.google.com,O=Google LLC,L=Mountain View,ST=California,C=US
        SANs entries: [www.google.com]
        KeyID: 8E:A3:6C:47:12:A7:A:7:5B:94:51:D6:2A:3F:72:F9:35:6:45:2C
        Issuer: CN=GTS CA 1O1,O=Google Trust Services,C=US
        IssuerKeyID: 98:D1:F8:6E:10:EB:CF:9B:EC:60:9F:18:90:1B:A0:EB:7D:9:FD:2B
        Serial: 336872288293767042001244177974291853363
        Expiration: 2020-09-09 14:31:22 +0000 UTC
        Status: [WARNING] 65d 3h remaining

Looking at the code, I find:

"%s\tSerial: %s"+

certificate.SerialNumber,

and according to the docs (https://golang.org/pkg/math/big/#Int.String), the Stringer interface:

String returns the decimal representation of x as generated by x.Text(10).

Which means that technically the output is the right serial number, it isn't in the hex format that everyone is used to working with.

Which means that this line in the README example (base 10):

        Serial: 336872288293767042001244177974291853363

should have been (base 16):

        Serial: FD6F3E2498C25B1D080000000047F033

Code snippet

Conversion

Code to convert base 10 *bit.Int output to base 16:

package main

import (
	"fmt"
	"math/big"
)

func main() {
	serialNumber := new(big.Int)
	serialNumber.SetString("336872288293767042001244177974291853363", 10)
	fmt.Printf("%v\n", serialNumber.Text(16))
}

Output:

fd6f3e2498c25b1d080000000047f033

Display negative serial number

package main

import (
	"crypto/x509"
	"encoding/pem"
	"fmt"
)

func main() {
	certPEM := `-----BEGIN CERTIFICATE-----
MIICNjCCAeCgAwIBAgIQgHCUCGAAkJMR0ub/9x4viDANBgkqhkiG9w0BAQQFADB9
MQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExFjAUBgNVBAcTDU1vdW50YWluIFZp
ZXcxJTAjBgNVBAoTHE5ldHNjYXBlIENvbW11bmljYXRpb25zIENvcnAxDTALBgNV
BAsTBEFQTUMxEzARBgNVBAMTClJ1c2xhbkF1dGgwHhcNOTkwMzMxMDAzMzA3WhcN
MDQwMzMxMDAzMzA3WjB9MQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExFjAUBgNV
BAcTDU1vdW50YWluIFZpZXcxJTAjBgNVBAoTHE5ldHNjYXBlIENvbW11bmljYXRp
b25zIENvcnAxDTALBgNVBAsTBEFQTUMxEzARBgNVBAMTClJ1c2xhbkF1dGgwXDAN
BgkqhkiG9w0BAQEFAANLADBIAkEAxu9LmRU3GHSS9q/TQbF4iNZhbNETm0Jg+NzA
/5QSY59YYAfitOEyc9gkrtQ3ZUJWhiZeLR+4/75YVQaY1/wRAwIDAQABozwwOjAL
BgNVHQ8EBAMCAcQwDAYDVR0TBAUwAwEB/zAdBgNVHQ4EFgQURK5ym9yBRRjrO1yX
/dPjZc2Vyu0wDQYJKoZIhvcNAQEEBQADQQCsaps5vJ3eRQPx1gGaah6yCOfviIj0
wSo4P9N2TvXyAnxV7GZGc+9kqGejHVTdFcG9K1Ygjz/azvd3Jpsee0dc
-----END CERTIFICATE-----`

	block, _ := pem.Decode([]byte(certPEM))
	if block == nil {
		panic("failed to parse certificate PEM")
	}

	cert, err := x509.ParseCertificate(block.Bytes)
	if err != nil {
		panic("failed to parse certificate: " + err.Error())
	}

	fmt.Printf("%X", cert.SerialNumber)
}

References

x509: certificate relies on legacy Common Name field, use SANs or temporarily enable Common Name matching with GODEBUG=x509ignoreCN=0

While testing a preview build of the check_cert binary, the above error message was thrown when our Nagios instance used the Go 1.15-generated binary against a system without any SANs entries, but with the CommonName field set.

x509: certificate relies on legacy Common Name field, use SANs or temporarily enable Common Name matching with GODEBUG=x509ignoreCN=0

This problem was not surfaced when performing initial testing with the go1.15beta1 release as noted on GH-24.

Reference link | How you get multiple TLS certificate chains from a server certificate

From https://utcc.utoronto.ca/~cks/space/blog/tech/TLSHowMultipleChains:

In a good world, all intermediate certificates will have an expiration time no later than the best certificate for the issuer that signed them. This was the case with the AddTrust expiration; the cross-signed USERTrust certificate expired at the same time as the AddTrust root certificate. In this case you can detect the problem by noticing that a server provided intermediate certificate is expiring soon. If only a CA root certificate at the end of an older chain is expiring soon and the intermediate certificate signed by it has a later expiration date, you need to check the expiration time of the entire chain.

As a practical matter, monitoring the expiry time of all certificates provided by a TLS server seems very likely to be enough to detect multiple chain problems such as the AddTrust issue. Competent Certificate Authorities shouldn't issue server or intermediate certificates with expiry times later than their root (or intermediate) certificates, so we don't need to try to find and explicitly check those root certificates. This will also alert on expiring certificates that were provided but that can't be used to construct any chain, but you probably want to get rid of those anyway.

Worth adding this to the References section, potentially with a call-out to the text above.

Update flag names to reflect standard/reserved options

From https://nagios-plugins.org/doc/guidelines.html#AEN302:

-V version (--version)
-h help (--help)
-t timeout (--timeout)
-w warning threshold (--warning)
-c critical threshold (--critical)
-H hostname (--hostname)
-v verbose (--verbose)

We're violating the -v option (we're using it as equivalent to --version) and should replace it with -V, assuming that the standard library flag package supports having mixed cases for a letter as different flags (e.g., -v and -V).

While fixing that, it's probably worth adding/updating others as necessary. For example:

  • --warning could be another alias for --age-warning.
  • --hostname could replace or be an alias for --server

Omit summary output table if no cert problems found

Example output for a single host scan without cert issues using the default summary display:

Completed certificate analysis

Results:

IP Address      Port    Subject or SANs         Status (Type)           Summary         Serial
---             ---     ---                     ---                     ---             ---

Instead, something like this should probably be shown:

Completed certificate analysis

Results: No problems found!

Replace full help text for flags with shorter equivalents (where possible)

The help text is replicated between the README and the usage details and while not technically a problem, it is likely a UX issue. Instead, replacing the longer text with a short equivalent will likely make the usage information more approachable. Right now the output is just one big wall of text.

Examples:

-dns-name string
The fully-qualified domain name of the remote system to be used for hostname verification. This option can be used for cases where make the initial connection using a name or IP not associated with the certificate.

-sans-entries value
One or many Subject Alternate Names (SANs) expected for the certificate used by the remote service. If provided, this list of comma-separated (optional) values is required for the certificate to pass validation. If the case-insensitive SKIPSANSCHECKS keyword is provided this validation will be skipped, effectively turning the use of this flag into a NOOP.

Clarify SNI support for systems with multiple certificate chains

Today I wired up a Nginx instance to (temporarily) use an additional key and certificate normally used by another system. Web browsers (at least those that are SNI-capable) are very happy with the results, but the current version of this tool is flagging the first certificate that it found as being problematic.

Templated version of the Nagios report:

hostname subdomain.example.com does not match first cert in chain www.example.com

ERRORS

x509: certificate is valid for www.example.com, example.com, not subdomain.example.com

I believe that the Nginx configuration has this "guest" (temporary) certificate as the first one, mostly because the existing system has a lower-level importance than the site it is temporarily standing in for.

The next step is to research how to best support SNI: enabled by default (find all certs that it can), via an optional --sni flag, or something else entirely?

Update GoDoc coverage to point reader to main README

Instead of listing out the CLI flags for both tools, point reader to the main README. While this potentially loses users who might have otherwise been "sold" on the specific options provided, it should help avoid this file getting out of date with the main README (which receives more attention).

Add support for partial IP ranges and hostname/FQDN values

Currently a list of whole CIDR IP ranges is accepted and processed (and deduped), but we won't always require scanning a complete CIDR range/subnet, but instead a small portion of hosts out of a range. We might also wish to toss in single IP Addresses for scanning as well. While I believe it would be possible to specify a mask that allows for inclusion of individual IPs, this does not make for a very friendly UI.

This might be acceptable if a config file was the chosen interface, but that is not the intended approach for using this tool (yet).

Refactor config handling

The configuration handling between the lscert and check_cert commands is very similar and should likely be refactored to split into a separate shared config package.

SKIPSANSCHECKS keyword is not honored

After some brief testing I found that the support implemented yesterday was improperly done. Providing the SKIPSANSCHECKS keyword is incorrectly validated with a net result of simply being skipped over.

Add concurrency to cert retrieval process

The port scanning process is concurrent, but not the cert retrieval and analysis from ports discovered open. Instead, the port scanning process completes and then a for loop is used to retrieve certs from hosts (one at a time) which were discovered to have an open port from the specified port list.

The refactoring applied for this work should also prove useful when working on #134.

Update help text to ensure consistency between "remote service" and "certificate-enabled service"

As I began to notice references to "remote service" I began replacing them with alternate wording that (hopefully) covers truly remote services and services running on localhost.

I need to go back and update to make sure I'm using consistent language and drop references to "remote", as (for example) the Nagios plugin may very well be performing service checks against the "local" system where the Nagios daemon is running.

Certificate serial number missing leading zero

While continuing work on #103, I noticed that some serial numbers did not have a leading zero as Firefox and Chrome presented them.

For example, here is a serial number for an expired intermediate certificate from GoDaddy (as presented by Google Chrome on Windows):

044dae228cca21

and as displayed by our tooling:

44:DA:E2:28:CC:A2:1

Will need to figure out where the zero is being dropped and make sure we're retaining it.

Setup connection using tls.DialWithDialer() instead of tls.Dial()

In short, some sort of timeout is needed as otherwise the connection could "hang" for an extended amount of time. I encountered at least one case during testing where I gave up after a long wait and hit Ctrl-C. This is "OK" for interactive testing, but would likely cause issues for proper Nagios plugin operation.

References:

Multiple linting issues found when disabling golangci-lint "--exclude-use-default" flag

Fixing these in a bundle instead of separately:

internal/textutils/textutils.go:40:1: exported function `PrintHeader` should have comment or be unexported (golint)
func PrintHeader(headerText string) {
^
internal/certs/certs.go:35:1: comment on exported const `CertCheckOneLineSummaryTmpl` should be of the form `CertCheckOneLineSummaryTmpl ...` (golint)
// CertCertCheckOneLineSummaryTmpl is a shared template string used for
^
internal/certs/certs.go:40:1: comment on exported const `CertCheckOneLineSummaryExpiredTmpl` should be of the form `CertCheckOneLineSummaryExpiredTmpl ...` (golint)
// CertCertCheckOneLineSummaryExpiredTmpl is a shared template string used for
^
internal/certs/certs.go:192:1: comment on exported function `FormattedExpiration` should be of the form `FormattedExpiration ...` (golint)
// FormattedTimeUntilExpiration receives a Time value and converts it to a
^
internal/certs/certs.go:283:1: comment on exported function `ChainPosition` should be of the form `ChainPosition ...` (golint)
// ChainChainPosition receives a cert and returns a string indicating what
^
internal/certs/certs.go:100:18: G304: Potential file inclusion via variable (gosec)
        pemData, err := ioutil.ReadFile(filename)
                        ^

refs:

Add cert version number to summary output?

Example of detailed (default) output:

image

Perhaps add the version (as v1, v2 or v3 as appropriate) within the parenthesis just before the type?

For example:

IP Address              Port    Subject or SANs                                 Status (Version Type)                   Summary                         Serial
---                     ---     ---                                             ---                                     ---                             ---
...
131.204.73.236          443     http://www.valicert.com/                        ⛔ (v1 root)                            [EXPIRED] 540d 10h ago          01
...

or

IP Address              Port    Subject or SANs                                 Status (Version/Type)                   Summary                         Serial
---                     ---     ---                                             ---                                     ---                             ---
...
131.204.73.236          443     http://www.valicert.com/                        ⛔ (v1/root)                            [EXPIRED] 540d 10h ago          01
...

I wouldn't otherwise know at a glance that the valicert.com root CA cert is a v1 cert. Knowing this could prove useful.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.