v0.4.1 authentication impelemented, not tested and docs not updated
This commit is contained in:
@ -3,8 +3,6 @@ package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type AuthConfig struct {
|
||||
|
||||
@ -3,7 +3,6 @@ package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@ -29,37 +28,6 @@ type RateLimitConfig struct {
|
||||
MaxEntrySizeBytes int64 `toml:"max_entry_size_bytes"`
|
||||
}
|
||||
|
||||
func validateNetAccess(pipelineName string, cfg *NetAccessConfig) error {
|
||||
if cfg == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Validate CIDR notation
|
||||
for _, cidr := range cfg.IPWhitelist {
|
||||
if !strings.Contains(cidr, "/") {
|
||||
cidr = cidr + "/32"
|
||||
}
|
||||
if _, _, err := net.ParseCIDR(cidr); err != nil {
|
||||
if net.ParseIP(cidr) == nil {
|
||||
return fmt.Errorf("pipeline '%s': invalid IP whitelist entry: %s", pipelineName, cidr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, cidr := range cfg.IPBlacklist {
|
||||
if !strings.Contains(cidr, "/") {
|
||||
cidr = cidr + "/32"
|
||||
}
|
||||
if _, _, err := net.ParseCIDR(cidr); err != nil {
|
||||
if net.ParseIP(cidr) == nil {
|
||||
return fmt.Errorf("pipeline '%s': invalid IP blacklist entry: %s", pipelineName, cidr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateRateLimit(pipelineName string, cfg *RateLimitConfig) error {
|
||||
if cfg == nil {
|
||||
return nil
|
||||
|
||||
@ -20,9 +20,6 @@ type PipelineConfig struct {
|
||||
// Rate limiting
|
||||
RateLimit *RateLimitConfig `toml:"rate_limit"`
|
||||
|
||||
// Network access control (IP filtering)
|
||||
NetAccess *NetAccessConfig `toml:"net_access"`
|
||||
|
||||
// Filter configuration
|
||||
Filters []FilterConfig `toml:"filters"`
|
||||
|
||||
@ -37,12 +34,6 @@ type PipelineConfig struct {
|
||||
Auth *AuthConfig `toml:"auth"`
|
||||
}
|
||||
|
||||
// NetAccessConfig defines IP-based access control lists
|
||||
type NetAccessConfig struct {
|
||||
IPWhitelist []string `toml:"ip_whitelist"`
|
||||
IPBlacklist []string `toml:"ip_blacklist"`
|
||||
}
|
||||
|
||||
// SourceConfig represents an input data source
|
||||
type SourceConfig struct {
|
||||
// Source type: "directory", "file", "stdin", etc.
|
||||
@ -132,6 +123,13 @@ func validateSource(pipelineName string, sourceIndex int, cfg *SourceConfig) err
|
||||
}
|
||||
}
|
||||
|
||||
// CHANGED: Validate SSL if present
|
||||
if ssl, ok := cfg.Options["ssl"].(map[string]any); ok {
|
||||
if err := validateSSLOptions("HTTP source", pipelineName, sourceIndex, ssl); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
case "tcp":
|
||||
// Validate TCP source options
|
||||
port, ok := cfg.Options["port"].(int64)
|
||||
@ -147,6 +145,13 @@ func validateSource(pipelineName string, sourceIndex int, cfg *SourceConfig) err
|
||||
}
|
||||
}
|
||||
|
||||
// CHANGED: Validate SSL if present
|
||||
if ssl, ok := cfg.Options["ssl"].(map[string]any); ok {
|
||||
if err := validateSSLOptions("TCP source", pipelineName, sourceIndex, ssl); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
return fmt.Errorf("pipeline '%s' source[%d]: unknown source type '%s'",
|
||||
pipelineName, sourceIndex, cfg.Type)
|
||||
|
||||
@ -1,7 +1,11 @@
|
||||
// FILE: logwisp/src/internal/config/server.go
|
||||
package config
|
||||
|
||||
import "fmt"
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type TCPConfig struct {
|
||||
Enabled bool `toml:"enabled"`
|
||||
@ -49,6 +53,10 @@ type NetLimitConfig struct {
|
||||
// Enable net limiting
|
||||
Enabled bool `toml:"enabled"`
|
||||
|
||||
// IP Access Control Lists
|
||||
IPWhitelist []string `toml:"ip_whitelist"`
|
||||
IPBlacklist []string `toml:"ip_blacklist"`
|
||||
|
||||
// Requests per second per client
|
||||
RequestsPerSecond float64 `toml:"requests_per_second"`
|
||||
|
||||
@ -90,6 +98,33 @@ func validateNetLimitOptions(serverType, pipelineName string, sinkIndex int, rl
|
||||
return nil
|
||||
}
|
||||
|
||||
// Validate IP lists if present
|
||||
if ipWhitelist, ok := rl["ip_whitelist"].([]any); ok {
|
||||
for i, entry := range ipWhitelist {
|
||||
entryStr, ok := entry.(string)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
if err := validateIPv4Entry(entryStr); err != nil {
|
||||
return fmt.Errorf("pipeline '%s' sink[%d] %s: whitelist[%d] %v",
|
||||
pipelineName, sinkIndex, serverType, i, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ipBlacklist, ok := rl["ip_blacklist"].([]any); ok {
|
||||
for i, entry := range ipBlacklist {
|
||||
entryStr, ok := entry.(string)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
if err := validateIPv4Entry(entryStr); err != nil {
|
||||
return fmt.Errorf("pipeline '%s' sink[%d] %s: blacklist[%d] %v",
|
||||
pipelineName, sinkIndex, serverType, i, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Validate requests per second
|
||||
rps, ok := rl["requests_per_second"].(float64)
|
||||
if !ok || rps <= 0 {
|
||||
@ -132,5 +167,39 @@ func validateNetLimitOptions(serverType, pipelineName string, sinkIndex int, rl
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// validateIPv4Entry ensures an IP or CIDR is IPv4
|
||||
func validateIPv4Entry(entry string) error {
|
||||
// Handle single IP
|
||||
if !strings.Contains(entry, "/") {
|
||||
ip := net.ParseIP(entry)
|
||||
if ip == nil {
|
||||
return fmt.Errorf("invalid IP address: %s", entry)
|
||||
}
|
||||
if ip.To4() == nil {
|
||||
return fmt.Errorf("IPv6 not supported (IPv4-only): %s", entry)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Handle CIDR
|
||||
ipAddr, ipNet, err := net.ParseCIDR(entry)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid CIDR: %s", entry)
|
||||
}
|
||||
|
||||
// Check if the IP is IPv4
|
||||
if ipAddr.To4() == nil {
|
||||
return fmt.Errorf("IPv6 CIDR not supported (IPv4-only): %s", entry)
|
||||
}
|
||||
|
||||
// Verify the network mask is appropriate for IPv4
|
||||
_, bits := ipNet.Mask.Size()
|
||||
if bits != 32 {
|
||||
return fmt.Errorf("invalid IPv4 CIDR mask (got %d bits, expected 32): %s", bits, entry)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@ -1,7 +1,10 @@
|
||||
// FILE: logwisp/src/internal/config/ssl.go
|
||||
package config
|
||||
|
||||
import "fmt"
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
||||
type SSLConfig struct {
|
||||
Enabled bool `toml:"enabled"`
|
||||
@ -13,6 +16,9 @@ type SSLConfig struct {
|
||||
ClientCAFile string `toml:"client_ca_file"`
|
||||
VerifyClientCert bool `toml:"verify_client_cert"`
|
||||
|
||||
// Option to skip verification for clients
|
||||
InsecureSkipVerify bool `toml:"insecure_skip_verify"`
|
||||
|
||||
// TLS version constraints
|
||||
MinVersion string `toml:"min_version"` // "TLS1.2", "TLS1.3"
|
||||
MaxVersion string `toml:"max_version"`
|
||||
@ -31,11 +37,27 @@ func validateSSLOptions(serverType, pipelineName string, sinkIndex int, ssl map[
|
||||
pipelineName, sinkIndex, serverType)
|
||||
}
|
||||
|
||||
// Validate that certificate files exist and are readable
|
||||
if _, err := os.Stat(certFile); err != nil {
|
||||
return fmt.Errorf("pipeline '%s' sink[%d] %s: cert_file is not accessible: %w",
|
||||
pipelineName, sinkIndex, serverType, err)
|
||||
}
|
||||
if _, err := os.Stat(keyFile); err != nil {
|
||||
return fmt.Errorf("pipeline '%s' sink[%d] %s: key_file is not accessible: %w",
|
||||
pipelineName, sinkIndex, serverType, err)
|
||||
}
|
||||
|
||||
if clientAuth, ok := ssl["client_auth"].(bool); ok && clientAuth {
|
||||
if caFile, ok := ssl["client_ca_file"].(string); !ok || caFile == "" {
|
||||
caFile, caOk := ssl["client_ca_file"].(string)
|
||||
if !caOk || caFile == "" {
|
||||
return fmt.Errorf("pipeline '%s' sink[%d] %s: client auth enabled but CA file not specified",
|
||||
pipelineName, sinkIndex, serverType)
|
||||
}
|
||||
// Validate that the client CA file exists and is readable
|
||||
if _, err := os.Stat(caFile); err != nil {
|
||||
return fmt.Errorf("pipeline '%s' sink[%d] %s: client_ca_file is not accessible: %w",
|
||||
pipelineName, sinkIndex, serverType, err)
|
||||
}
|
||||
}
|
||||
|
||||
// Validate TLS versions
|
||||
|
||||
@ -72,11 +72,6 @@ func (c *Config) validate() error {
|
||||
}
|
||||
}
|
||||
|
||||
// Validate net access if present
|
||||
if err := validateNetAccess(pipeline.Name, pipeline.NetAccess); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Validate auth if present
|
||||
if err := validateAuth(pipeline.Name, pipeline.Auth); err != nil {
|
||||
return err
|
||||
|
||||
Reference in New Issue
Block a user