Added certificate based authentication option

This commit is contained in:
Dionysus 2024-12-13 00:21:17 -05:00
parent 4bbf0c6bf1
commit 273fed1776
Signed by: acidvegas
GPG Key ID: EF4B922DB85DC9DE
2 changed files with 88 additions and 12 deletions

View File

@ -32,12 +32,35 @@ go build
``` ```
### Command Line Flags ### Command Line Flags
| Flag | Description | Default | | Flag | Description | Default |
| ----------- | ---------------------- | ------------- | | ----------- | ------------------------------------- | ------------- |
| `-host` | Elasticsearch host | `localhost` | | `-host` | Elasticsearch host | `localhost` |
| `-port` | Elasticsearch port | `9200` | | `-port` | Elasticsearch port | `9200` |
| `-user` | Elasticsearch username | `elastic` | | `-user` | Elasticsearch username | `elastic` |
| `-password` | Elasticsearch password | `ES_PASSWORD` | | `-password` | Elasticsearch password | `ES_PASSWORD` |
| `-apikey` | Elasticsearch API key | `ES_API_KEY` |
| `-cert` | Path to client certificate file | |
| `-key` | Path to client private key file | |
| `-ca` | Path to CA certificate file | |
| `-insecure` | Skip TLS certificate verification | `false` |
Note: Only one authentication method (username/password, API key, or certificates) can be used at a time.
### Authentication Examples
```bash
# Using username/password
./elastop -host https://elasticsearch.example.com -user elastic -password secret
# Using API key
./elastop -host https://elasticsearch.example.com -apikey your_api_key
# Using certificate authentication
./elastop -host https://elasticsearch.example.com -cert /path/to/client.crt -key /path/to/client.key -ca /path/to/ca.crt
# Using certificate authentication with insecure SSL (not recommended for production)
./elastop -host https://elasticsearch.example.com -cert /path/to/client.crt -key /path/to/client.key -insecure
```
## Dashboard Layout ## Dashboard Layout

View File

@ -2,6 +2,7 @@ package main
import ( import (
"crypto/tls" "crypto/tls"
"crypto/x509"
"encoding/json" "encoding/json"
"flag" "flag"
"fmt" "fmt"
@ -537,6 +538,13 @@ func main() {
user := flag.String("user", os.Getenv("ES_USER"), "Elasticsearch username") user := flag.String("user", os.Getenv("ES_USER"), "Elasticsearch username")
password := flag.String("password", os.Getenv("ES_PASSWORD"), "Elasticsearch password") password := flag.String("password", os.Getenv("ES_PASSWORD"), "Elasticsearch password")
flag.StringVar(&apiKey, "apikey", os.Getenv("ES_API_KEY"), "Elasticsearch API key") flag.StringVar(&apiKey, "apikey", os.Getenv("ES_API_KEY"), "Elasticsearch API key")
// Add new certificate-related flags
certFile := flag.String("cert", "", "Path to client certificate file")
keyFile := flag.String("key", "", "Path to client private key file")
caFile := flag.String("ca", "", "Path to CA certificate file")
skipVerify := flag.Bool("insecure", false, "Skip TLS certificate verification")
flag.Parse() flag.Parse()
// Validate and process the host URL // Validate and process the host URL
@ -545,20 +553,65 @@ func main() {
os.Exit(1) os.Exit(1)
} }
// Validate authentication // Validate authentication methods - only one should be used
if apiKey != "" && (*user != "" || *password != "") { authMethods := 0
fmt.Fprintf(os.Stderr, "Error: Cannot use both API key and username/password authentication\n") if apiKey != "" {
authMethods++
}
if *user != "" || *password != "" {
authMethods++
}
if *certFile != "" || *keyFile != "" {
authMethods++
}
if authMethods > 1 {
fmt.Fprintf(os.Stderr, "Error: Cannot use multiple authentication methods simultaneously (API key, username/password, or certificates)\n")
os.Exit(1)
}
// Validate certificate files if specified
if (*certFile != "" && *keyFile == "") || (*certFile == "" && *keyFile != "") {
fmt.Fprintf(os.Stderr, "Error: Both certificate and key files must be specified together\n")
os.Exit(1) os.Exit(1)
} }
// Strip any trailing slash from the host // Strip any trailing slash from the host
*host = strings.TrimRight(*host, "/") *host = strings.TrimRight(*host, "/")
// Create TLS config
tlsConfig := &tls.Config{
InsecureSkipVerify: *skipVerify,
}
// Load client certificates if specified
if *certFile != "" && *keyFile != "" {
cert, err := tls.LoadX509KeyPair(*certFile, *keyFile)
if err != nil {
fmt.Fprintf(os.Stderr, "Error loading client certificates: %v\n", err)
os.Exit(1)
}
tlsConfig.Certificates = []tls.Certificate{cert}
}
// Load CA certificate if specified
if *caFile != "" {
caCert, err := os.ReadFile(*caFile)
if err != nil {
fmt.Fprintf(os.Stderr, "Error reading CA certificate: %v\n", err)
os.Exit(1)
}
caCertPool := x509.NewCertPool()
if !caCertPool.AppendCertsFromPEM(caCert) {
fmt.Fprintf(os.Stderr, "Error parsing CA certificate\n")
os.Exit(1)
}
tlsConfig.RootCAs = caCertPool
}
// Create custom HTTP client with SSL configuration // Create custom HTTP client with SSL configuration
tr := &http.Transport{ tr := &http.Transport{
TLSClientConfig: &tls.Config{ TLSClientConfig: tlsConfig,
InsecureSkipVerify: true, // Allow self-signed certificates
},
} }
client := &http.Client{ client := &http.Client{
Transport: tr, Transport: tr,