fixed IP whitelist bugs
This commit is contained in:
1 parent
e48098090d
commit
8cea6d1f8c
5 files changed
+93
-27
No files matched your search
@@ -2,6 +2,7 @@ package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
@@ -56,6 +57,9 @@ func Load() (*Config, error) {
|
||||
for _, ip := range ips {
|
||||
trimmed := strings.TrimSpace(ip)
|
||||
if trimmed != "" {
|
||||
if err := validateIPOrCIDR(trimmed); err != nil {
|
||||
return nil, fmt.Errorf("invalid IP in ALLOWED_IPS (%s): %w", trimmed, err)
|
||||
}
|
||||
cfg.AllowedIPs = append(cfg.AllowedIPs, trimmed)
|
||||
}
|
||||
}
|
||||
@@ -107,3 +111,16 @@ func parseDuration(s string) time.Duration {
|
||||
}
|
||||
return d
|
||||
}
|
||||
|
||||
// validateIPOrCIDR validates if a string is a valid IP address or CIDR range
|
||||
func validateIPOrCIDR(s string) error {
|
||||
// Try parsing as CIDR first
|
||||
if _, _, err := net.ParseCIDR(s); err == nil {
|
||||
return nil
|
||||
}
|
||||
// Try parsing as IP address
|
||||
if net.ParseIP(s) != nil {
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("not a valid IP address or CIDR range")
|
||||
}
|
||||
@@ -58,7 +58,7 @@ func New(allowedIPs []string, enableGitHub bool) (*IPWhitelist, error) {
|
||||
logger.Warn.Printf("Invalid IP '%s'", ipStr)
|
||||
continue
|
||||
}
|
||||
wl.allowedIPs[ipStr] = true
|
||||
wl.allowedIPs[ip.String()] = true
|
||||
logger.Info.Printf("Added IP to whitelist: %s", ipStr)
|
||||
}
|
||||
}
|
||||
@@ -87,12 +87,17 @@ func (wl *IPWhitelist) Middleware() fiber.Handler {
|
||||
|
||||
clientIP := c.IP()
|
||||
|
||||
if wl.IsAllowed(clientIP) {
|
||||
logger.Info.Printf("IP allowed: %s", clientIP)
|
||||
// Handle comma-separated IPs from X-Forwarded-For header
|
||||
// Take the first IP (original client IP before proxies)
|
||||
ips := strings.Split(clientIP, ",")
|
||||
realClientIP := strings.TrimSpace(ips[0])
|
||||
|
||||
if wl.IsAllowed(realClientIP) {
|
||||
logger.Debug.Printf("IP allowed: %s", realClientIP)
|
||||
return c.Next()
|
||||
}
|
||||
|
||||
logger.Warn.Printf("IP blocked (not whitelisted): %s on %s %s", clientIP, c.Method(), c.Path())
|
||||
logger.Warn.Printf("IP blocked (not whitelisted): %s on %s %s", realClientIP, c.Method(), c.Path())
|
||||
return c.Status(fiber.StatusForbidden).JSON(fiber.Map{
|
||||
"error": "access denied: IP not whitelisted",
|
||||
})
|
||||
@@ -109,8 +114,8 @@ func (wl *IPWhitelist) IsAllowed(ipStr string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// Check single IPs
|
||||
if wl.allowedIPs[ipStr] {
|
||||
// Check single IPs (normalize IP for consistent matching)
|
||||
if wl.allowedIPs[ip.String()] {
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -174,21 +179,30 @@ func (wl *IPWhitelist) updateGitHubIPRanges() error {
|
||||
}
|
||||
|
||||
// StartPeriodicUpdate starts a goroutine that updates GitHub IP ranges periodically
|
||||
func (wl *IPWhitelist) StartPeriodicUpdate(interval time.Duration) {
|
||||
// Returns a stop function that should be called to clean up the goroutine
|
||||
func (wl *IPWhitelist) StartPeriodicUpdate(interval time.Duration) func() {
|
||||
if !wl.enableGitHub {
|
||||
return
|
||||
return func() {}
|
||||
}
|
||||
|
||||
ticker := time.NewTicker(interval)
|
||||
done := make(chan struct{})
|
||||
|
||||
go func() {
|
||||
ticker := time.NewTicker(interval)
|
||||
defer ticker.Stop()
|
||||
|
||||
for range ticker.C {
|
||||
if err := wl.updateGitHubIPRanges(); err != nil {
|
||||
logger.Error.Printf("Failed to update GitHub IP ranges: %v", err)
|
||||
for {
|
||||
select {
|
||||
case <-ticker.C:
|
||||
if err := wl.updateGitHubIPRanges(); err != nil {
|
||||
logger.Error.Printf("Failed to update GitHub IP ranges: %v", err)
|
||||
}
|
||||
case <-done:
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
logger.Info.Printf("Started GitHub IP range auto-update (every %v)", interval)
|
||||
return func() { close(done) }
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package vaultwarden
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
@@ -14,6 +15,10 @@ import (
|
||||
|
||||
var bitwardenInitMutex sync.Mutex
|
||||
|
||||
type BitwardenStatus struct {
|
||||
Status string `json:"status"`
|
||||
}
|
||||
|
||||
func InitializeBitwardenCLI(serverURL, clientID, clientSecret, password string) (string, error) {
|
||||
bitwardenInitMutex.Lock()
|
||||
defer bitwardenInitMutex.Unlock()
|
||||
@@ -29,12 +34,18 @@ func InitializeBitwardenCLI(serverURL, clientID, clientSecret, password string)
|
||||
cancel()
|
||||
|
||||
ctx, cancel = context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
cmd = exec.CommandContext(ctx, "bw", "status")
|
||||
statusOutput, _ := cmd.CombinedOutput()
|
||||
cancel()
|
||||
statusOutput, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
logger.Warn.Printf("Failed to check status: %v", err)
|
||||
}
|
||||
|
||||
statusStr := strings.TrimSpace(string(statusOutput))
|
||||
isLoggedIn := strings.Contains(statusStr, `"status":"unlocked"`) || strings.Contains(statusStr, `"status":"locked"`)
|
||||
var status BitwardenStatus
|
||||
isLoggedIn := false
|
||||
if err := json.Unmarshal(statusOutput, &status); err == nil {
|
||||
isLoggedIn = status.Status == "unlocked" || status.Status == "locked"
|
||||
}
|
||||
|
||||
if !isLoggedIn {
|
||||
logger.Info.Println("Logging in to Bitwarden...")
|
||||
@@ -67,11 +78,14 @@ func InitializeBitwardenCLI(serverURL, clientID, clientSecret, password string)
|
||||
if strings.Contains(outputStr, "Rate limit") {
|
||||
logger.Warn.Printf("Rate limited (attempt %d/%d)", attempt, maxRetries)
|
||||
loginErr = fmt.Errorf("rate limited: %s", outputStr)
|
||||
continue
|
||||
} else {
|
||||
logger.Warn.Printf("Login failed (attempt %d/%d): %v - %s", attempt, maxRetries, err, outputStr)
|
||||
loginErr = fmt.Errorf("login failed: %w - %s", err, outputStr)
|
||||
}
|
||||
|
||||
loginErr = fmt.Errorf("login failed: %w - %s", err, outputStr)
|
||||
break
|
||||
if attempt < maxRetries {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if loginErr != nil {
|
||||
|
||||
Reference in new issue
Block a user