Skip to content

Commit

Permalink
Merge branch 'feature/no-challenge-if-baskerville-disabled' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
jeremy5189 committed Sep 27, 2023
2 parents 982f766 + aa74336 commit 150c7fc
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 25 deletions.
2 changes: 2 additions & 0 deletions banjax-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -109,3 +109,5 @@ session_cookie_hmac_secret: some_secret
session_cookie_ttl_seconds: 3600
use_user_agent_in_cookie:
localhost: true
sites_to_disable_baskerville:
localhost: true
18 changes: 12 additions & 6 deletions internal/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ type Config struct {
DisableKafka bool `yaml:"disable_kafka"`
SessionCookieHmacSecret string `yaml:"session_cookie_hmac_secret"`
SessionCookieTtlSeconds int `yaml:"session_cookie_ttl_seconds"`
SitesToDisableBaskerville map[string]bool `yaml:"sites_to_disable_baskerville"`
}

type RegexWithRate struct {
Expand All @@ -92,8 +93,9 @@ const (
)

type ExpiringDecision struct {
Decision Decision
Expires time.Time
Decision Decision
Expires time.Time
fromBaskerville bool
}

// XXX is this really how you make an enum in go?
Expand Down Expand Up @@ -383,7 +385,7 @@ func (failedChallengeStates FailedChallengeStates) String() string {
return buf.String()
}

func checkExpiringDecisionLists(clientIp string, decisionLists *DecisionLists) (Decision, bool) {
func checkExpiringDecisionLists(clientIp string, decisionLists *DecisionLists) (ExpiringDecision, bool) {
expiringDecision, ok := (*decisionLists).ExpiringDecisionLists[clientIp]
if !ok {
// log.Println("no mention in expiring lists")
Expand All @@ -394,7 +396,7 @@ func checkExpiringDecisionLists(clientIp string, decisionLists *DecisionLists) (
ok = false
}
}
return expiringDecision.Decision, ok
return expiringDecision, ok
}

// XXX mmm could hold the lock for a while?
Expand All @@ -420,6 +422,7 @@ func updateExpiringDecisionLists(
decisionLists *DecisionLists,
now time.Time,
newDecision Decision,
fromBaskerville bool,
) {
decisionListsMutex.Lock()
defer decisionListsMutex.Unlock()
Expand All @@ -431,11 +434,14 @@ func updateExpiringDecisionLists(
return
}
}
// log.Println("!!! existing and new: ", existingExpiringDecision.Decision, newDecision)
if config.Debug {
log.Println("Update expiringDecision with existing and new: ", existingExpiringDecision.Decision, newDecision)
log.Println("From baskerville", fromBaskerville)
}

purgeNginxAuthCacheForIp(ip)
expires := now.Add(time.Duration(config.ExpiringDecisionTtlSeconds) * time.Second)
(*decisionLists).ExpiringDecisionLists[ip] = ExpiringDecision{newDecision, expires}
(*decisionLists).ExpiringDecisionLists[ip] = ExpiringDecision{newDecision, expires, fromBaskerville}
}

type MetricsLogLine struct {
Expand Down
40 changes: 23 additions & 17 deletions internal/http_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -919,33 +919,39 @@ func decisionForNginx2(
// changing the decision.
// XXX i forget if that comment is stale^
decisionListsMutex.Lock()
decision, ok = checkExpiringDecisionLists(clientIp, decisionLists)
expiringDecision, ok := checkExpiringDecisionLists(clientIp, decisionLists)
decisionListsMutex.Unlock()
if !ok {
// log.Println("no mention in expiring lists")
} else {
switch decision {
switch expiringDecision.Decision {
case Allow:
accessGranted(c, config, DecisionListResultToString[ExpiringAccessGranted])
// log.Println("access granted from expiring lists")
decisionForNginxResult.DecisionListResult = ExpiringAccessGranted
return
case Challenge:
// log.Println("challenge from expiring lists")
sendOrValidateShaChallengeResult := sendOrValidateShaChallenge(
config,
c,
banner,
rateLimitMutex,
failedChallengeStates,
Block, // FailAction
decisionListsMutex,
decisionLists,
)
decisionForNginxResult.DecisionListResult = ExpiringChallenge
decisionForNginxResult.ShaChallengeResult = &sendOrValidateShaChallengeResult.ShaChallengeResult
decisionForNginxResult.TooManyFailedChallengesResult = &sendOrValidateShaChallengeResult.TooManyFailedChallengesResult
return
// Check if expiringDecision.fromBaskerville, if true, check if domain disabled baskerville
_, disabled := config.SitesToDisableBaskerville[requestedHost]
if expiringDecision.fromBaskerville && disabled {
log.Printf("domain %s disabled baskerville, skip expiring challenge for %s", requestedHost, clientIp)
} else {
// log.Println("challenge from expiring lists")
sendOrValidateShaChallengeResult := sendOrValidateShaChallenge(
config,
c,
banner,
rateLimitMutex,
failedChallengeStates,
Block, // FailAction
decisionListsMutex,
decisionLists,
)
decisionForNginxResult.DecisionListResult = ExpiringChallenge
decisionForNginxResult.ShaChallengeResult = &sendOrValidateShaChallengeResult.ShaChallengeResult
decisionForNginxResult.TooManyFailedChallengesResult = &sendOrValidateShaChallengeResult.TooManyFailedChallengesResult
return
}
case NginxBlock, IptablesBlock:
accessDenied(c, config, DecisionListResultToString[ExpiringBlock])
// log.Println("access denied from expiring lists")
Expand Down
1 change: 1 addition & 0 deletions internal/iptables.go
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,7 @@ func (b Banner) BanOrChallengeIp(
&(*b.DecisionLists),
time.Now(),
decision,
false, // not from baskerville
)

if decision == IptablesBlock {
Expand Down
26 changes: 24 additions & 2 deletions internal/kafka.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,25 @@ import (
"github.com/segmentio/kafka-go"
)

/*
sample baskerville message:
{
"Value": "0.0.0.0",
"Name": "challenge_ip",
"duration": 15.0,
"session_id": "ID",
"source": "behave",
"start": "2023-09-27 08:04:43",
"host": "example.com",
"end": "2023-09-27 08:04:58",
"urls": "[[\"2023-09-27 08:04:43\", \"/some/url\"], [\"2023-09-27 08:04:58\", \"/another/url\"]]"
}
*/
type commandMessage struct {
Name string
Value string
host string
}

func getDialer(config *Config) *kafka.Dialer {
Expand Down Expand Up @@ -122,22 +138,28 @@ func handleCommand(
) {
switch command.Name {
case "challenge_ip":
// exempt a site from challenge according to config
_, disabled := config.SitesToDisableBaskerville[command.host]

// XXX do a real valid IP check?
if len(command.Value) > 4 {
if len(command.Value) > 4 && !disabled {
updateExpiringDecisionLists(
config,
command.Value,
decisionListsMutex,
decisionLists,
time.Now(),
Challenge,
true, // from baskerville, provide to http_server to distinguish from regex
)
log.Printf("KAFKA: added to global challenge lists: Challenge %s\n", command.Value)
} else if disabled {
log.Printf("KAFKA: not challenge %s, site %s disable baskerville\n", command.Value, command.host)
} else {
log.Printf("KAFKA: command value looks malformed: %s\n", command.Value)
}
default:
log.Printf("KAFKA:unrecognized command name: %s\n", command.Name)
log.Printf("KAFKA: unrecognized command name: %s\n", command.Name)
}
}

Expand Down

0 comments on commit 150c7fc

Please sign in to comment.