initial commit
This commit is contained in:
commit
83392efac3
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
.idea/
|
||||
ssl*
|
161
README.md
Normal file
161
README.md
Normal file
@ -0,0 +1,161 @@
|
||||
# SSL Certificate Checker
|
||||
|
||||
This project is a command-line tool written in Go that checks the validity and expiration of an SSL/TLS certificate for a given host and port. It is a lightweight utility that can be used to monitor the SSL status of your services and ensure timely renewal of certificates.
|
||||
|
||||
## Overview
|
||||
|
||||
The tool connects to a specified host and port using TLS, verifies the provided hostname against the certificate, and checks the expiration date of the certificate. It provides warnings or critical alerts based on configurable thresholds for days remaining until expiration.
|
||||
|
||||
## Features
|
||||
|
||||
- **Hostname Verification**: Verifies that the hostname matches the certificate.
|
||||
- **Certificate Expiration Check**: Checks how many days are left until the SSL/TLS certificate expires.
|
||||
- **Configurable Alerts**:
|
||||
- **Warning**: Triggered when the remaining validity is below a specified number of days.
|
||||
- **Critical**: Triggered when the certificate is on the brink of expiration or has already expired.
|
||||
- **Customizable Parameters**: Command-line arguments let you tailor the behavior to specific needs (e.g., host, port, thresholds, timeouts).
|
||||
|
||||
## Usage
|
||||
|
||||
Run the program using the command line with the following syntax:
|
||||
|
||||
```bash
|
||||
./ssl-checker -H <hostname> [-p <port>] [-w <warning days>] [-c <critical days>] [-t <timeout>]
|
||||
```
|
||||
|
||||
### Parameters
|
||||
|
||||
| Parameter | Description | Default Value |
|
||||
|---------------|------------------------------------------------------------------------------------------|---------------|
|
||||
| `-H <host>` | The hostname to check (required). | None |
|
||||
| `-p <port>` | The port to connect to. Typically `443` for HTTPS. | `443` |
|
||||
| `-w <days>` | Warning threshold in days. Issues a warning if certificate expiration is below this threshold. | `30` |
|
||||
| `-c <days>` | Critical threshold in days. Fails critically if expiration is below this threshold. | `15` |
|
||||
| `-t <ms>` | Connection timeout in milliseconds. | `1000` |
|
||||
|
||||
### Example Usage
|
||||
|
||||
#### Check an SSL certificate for `example.com`:
|
||||
```bash
|
||||
./ssl-checker -H example.com
|
||||
```
|
||||
|
||||
#### Check an SSL certificate for `example.com` on a custom port `8443`:
|
||||
```bash
|
||||
./ssl-checker -H example.com -p 8443
|
||||
```
|
||||
|
||||
#### Set a custom warning threshold of 20 days and critical threshold of 10 days:
|
||||
```bash
|
||||
./ssl-checker -H example.com -w 20 -c 10
|
||||
```
|
||||
|
||||
#### Specify a timeout of 2000 milliseconds:
|
||||
```bash
|
||||
./ssl-checker -H example.com -t 2000
|
||||
```
|
||||
|
||||
## Creating a Statically Linked Binary
|
||||
|
||||
To build a statically linked binary, follow the steps below:
|
||||
|
||||
### Step 1: Set the Environment Variable
|
||||
Disabling `cgo` ensures that the binary is fully statically linked.
|
||||
|
||||
```bash
|
||||
CGO_ENABLED=0 go build -o ssl-checker main.go
|
||||
```
|
||||
|
||||
### Step 2: Cross-Compiling for Other Platforms (Optional)
|
||||
You can build the binary for another platform by setting the `GOOS` and `GOARCH` environment variables:
|
||||
|
||||
For Linux:
|
||||
```bash
|
||||
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o ssl-checker main.go
|
||||
```
|
||||
|
||||
For Windows:
|
||||
```bash
|
||||
GOOS=windows GOARCH=amd64 CGO_ENABLED=0 go build -o ssl-checker.exe main.go
|
||||
```
|
||||
|
||||
To build a smaller binary, include the `-ldflags="-s -w"` flag when building (as shown below).
|
||||
|
||||
## Creating a Minimal Stripped Build
|
||||
|
||||
To minimize binary size, you can strip unnecessary debugging and symbol information during the build process.
|
||||
|
||||
### Step 1: Build a Stripped Binary
|
||||
```bash
|
||||
go build -ldflags="-s -w" -o ssl-checker main.go
|
||||
```
|
||||
|
||||
- `-s`: Strips the symbol table from the binary (reduces size).
|
||||
- `-w`: Strips the debugging information from the binary (further reduces size).
|
||||
|
||||
### Step 2: Compress the Binary with UPX
|
||||
[UPX](https://upx.github.io/) can further reduce the file size of the binary. After building the binary, use UPX as follows:
|
||||
|
||||
1. Install UPX:
|
||||
```bash
|
||||
sudo apt install upx
|
||||
```
|
||||
or download it from the [UPX website](https://upx.github.io/).
|
||||
|
||||
2. Compress the binary:
|
||||
```bash
|
||||
upx --best --lzma -o ssl-checker-compressed ssl-checker
|
||||
```
|
||||
|
||||
- `--best`: Ensures the highest compression ratio.
|
||||
- `--lzma`: Uses the LZMA algorithm for optimal compression.
|
||||
- `-o ssl-checker-compressed`: Specifies the name of the compressed output binary.
|
||||
|
||||
### Verifying the Binary is Statically Linked
|
||||
On Linux, confirm the binary is statically linked by checking its dependencies:
|
||||
```bash
|
||||
ldd ./ssl-checker
|
||||
```
|
||||
|
||||
If it is statically linked, the result will show:
|
||||
|
||||
## Outputs and Exit Codes
|
||||
|
||||
The tool provides output and exit codes for various scenarios:
|
||||
|
||||
| Status | Output | Exit Code |
|
||||
|--------------------------------------|---------------------------------------------------------------|-----------|
|
||||
| Certificate is valid and not expiring soon. | `OK: Certificate for <host> is valid, expires in <days> days.` | `0` |
|
||||
| Certificate is nearing expiration. | `WARNING: Certificate for <host> expires in <days> days.` | `1` |
|
||||
| Certificate is expired or critically close to expiration. | `CRITICAL: Certificate for <host> expired <days> days ago.` or `CRITICAL: Certificate for <host> expires in <days> days.` | `2` |
|
||||
| Hostname verification failed. | `CRITICAL: Hostname verification failed for <host>.` | `2` |
|
||||
| Connection error. | `CRITICAL: Could not connect to <host>:<port>.` | `2` |
|
||||
|
||||
## Notes
|
||||
|
||||
- Statically linked builds are highly portable and do not depend on system libraries (useful for deploying on minimalist systems).
|
||||
- UPX-compressed files may increase memory usage during decompression, so use them where size is critical.
|
||||
|
||||
## Building from Source
|
||||
|
||||
To build the tool, ensure you have Go installed and follow these steps:
|
||||
|
||||
1. Clone the repository:
|
||||
```bash
|
||||
git clone <repository-url>
|
||||
cd <repository-dir>
|
||||
```
|
||||
|
||||
2. Build the binary:
|
||||
```bash
|
||||
go build -o ssl-checker main.go
|
||||
```
|
||||
|
||||
3. Run the tool:
|
||||
```bash
|
||||
./ssl-checker -H example.com
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the MIT License. See the `LICENSE` file for details.
|
73
main.go
Normal file
73
main.go
Normal file
@ -0,0 +1,73 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"flag"
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
// main is the entry point for the program, handling SSL certificate validity checks for a specified host and port.
|
||||
func main() {
|
||||
// Define command-line parameters
|
||||
var (
|
||||
host string
|
||||
port int
|
||||
warningDays int
|
||||
criticalDays int
|
||||
timeout int
|
||||
)
|
||||
flag.StringVar(&host, "H", "", "Hostname to check")
|
||||
flag.IntVar(&port, "p", 443, "Port to connect to (default: 443)")
|
||||
flag.IntVar(&warningDays, "w", 30, "Warning threshold in days (default: 30)")
|
||||
flag.IntVar(&criticalDays, "c", 15, "Critical threshold in days (default: 15)")
|
||||
flag.IntVar(&timeout, "t", 1000, "Connection timeout in milliseconds (default: 1000)")
|
||||
|
||||
flag.Parse()
|
||||
|
||||
if host == "" {
|
||||
fmt.Fprintln(os.Stderr, "Usage: -H <hostname> [-p <port>] [-w <warning days>] [-c <critical days>] [-t <timeout>]")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Establish a connection with timeout
|
||||
address := fmt.Sprintf("%s:%d", host, port)
|
||||
dialer := &net.Dialer{Timeout: time.Duration(timeout) * time.Millisecond}
|
||||
|
||||
conn, err := tls.DialWithDialer(dialer, "tcp", address, &tls.Config{ServerName: host})
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "CRITICAL: Could not connect to %s (%v)\n", address, err)
|
||||
os.Exit(2)
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
// Fetch the certificate
|
||||
cert := conn.ConnectionState().PeerCertificates[0]
|
||||
|
||||
// Validate hostname
|
||||
err = cert.VerifyHostname(host)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "CRITICAL: Hostname verification failed for %s (%v)\n", host, err)
|
||||
os.Exit(2)
|
||||
}
|
||||
|
||||
// Check expiration
|
||||
timeRemaining := cert.NotAfter.Sub(time.Now())
|
||||
daysRemaining := int(timeRemaining.Hours() / 24)
|
||||
|
||||
if daysRemaining < 0 {
|
||||
fmt.Fprintf(os.Stderr, "CRITICAL: Certificate for %s expired %d days ago.\n", host, -daysRemaining)
|
||||
os.Exit(2)
|
||||
} else if daysRemaining < criticalDays {
|
||||
fmt.Printf("CRITICAL: Certificate for %s expires in %d days.\n", host, daysRemaining)
|
||||
os.Exit(2)
|
||||
} else if daysRemaining < warningDays {
|
||||
fmt.Printf("WARNING: Certificate for %s expires in %d days.\n", host, daysRemaining)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
fmt.Printf("OK: Certificate for %s is valid, expires in %d days.\n", host, daysRemaining)
|
||||
os.Exit(0)
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user