Skip to content

Commit b175347

Browse files
author
Aaron Meihm
committed
auth_ip_geo: add global whitelist support
1 parent 85e1d5a commit b175347

File tree

4 files changed

+93
-8
lines changed

4 files changed

+93
-8
lines changed

moz_security/sandboxes/heka/analysis/moz_security_auth_ip_geo.lua

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,19 @@ user_field = "Fields[user]" -- required, field to extract username from
3636
srcip_field = "Fields[ssh_remote_ipaddr]" -- required, field to extract source IP from
3737
geocity_field = "Fields[ssh_remote_ipaddr_city"] -- required, field to extract geo city
3838
geocountry_field = "Fields[ssh_remote_ipaddr_country"] -- required, field to extract geo country
39+
40+
userspec = {
41+
riker = {
42+
ip = { "192.168.1.0/24", "10.0.0.0/24" },
43+
geo = { "Toronto/CA" }
44+
},
45+
worf = {
46+
geo = { "Milton/US" }
47+
},
48+
ipauthgeoany = { -- special key that applies to any user
49+
ip = "192.168.0.0/24"
50+
}
51+
}
3952
```
4053
--]]
4154
--
@@ -99,6 +112,15 @@ function check_geo(city, country, spec)
99112
end
100113

101114

115+
function check_spec(spec, srcip, geocity, geocountry)
116+
if not spec then return false end
117+
118+
if check_ip(srcip, spec) then return true end
119+
if check_geo(geocity, geocountry, spec) then return true end
120+
return false
121+
end
122+
123+
102124
function process_message()
103125
local ts = math.floor(read_message("Timestamp") / 1e9)
104126
local hn = read_message(authhost_field) or "unknown"
@@ -113,15 +135,22 @@ function process_message()
113135
local geocountry = read_message(geocountry_field)
114136

115137
local spec = userspec[user]
138+
local matchanyspec = userspec.authipgeoany
116139

117140
local escalate = false
118-
if spec then
119-
local ipok = check_ip(srcip, spec)
120-
if not ipok then
121-
local geook = check_geo(geocity, geocountry, spec)
122-
if not geook then escalate = true end
141+
local matchanymatch = false
142+
if not check_spec(spec, srcip, geocity, geocountry) then
143+
matchanymatch = true
144+
if not check_spec(matchanyspec, srcip, geocity, geocountry) then
145+
matchanymatch = false
146+
escalate = true
123147
end
124148
end
149+
-- If escalate is true here, no spec matched. It's possible this is a case where
150+
-- the user had no spec configured, and no matchany matched either. If this is the case,
151+
-- toggle escalated off and we will generate an alert indicating no specification was
152+
-- found for the user.
153+
if escalate and not userspec[user] then escalate = false end
125154

126155
-- At this point, we know if the event should be escalated or not. First, update
127156
-- the alert message with the default information since we always send there.
@@ -142,7 +171,7 @@ function process_message()
142171
msg.Fields[3].value[2] = string.format(string.format("<%s>", user_email), user)
143172
end
144173
msg.Payload = "Escalation flag set, authentication source does not match user specification\n"
145-
elseif not spec then
174+
elseif not spec and not matchanymatch then
146175
msg.Fields[2].value = "NOSPEC " .. msg.Fields[2].value
147176
msg.Payload = "No user specification present for comparison against authentication\n"
148177
end
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
filename = "moz_security_auth_ip_geo.lua"
2+
message_matcher = "Logger == 'generate_auth_3' && Fields[programname] == 'sshd' && Fields[authmsg] == 'Accepted'"
3+
ticker_interval = 0
4+
process_message_inject_limit = 1
5+
6+
default_email = "[email protected]"
7+
user_email = "manatee-%[email protected]"
8+
9+
authhost_field = "Hostname"
10+
user_field = "Fields[user]"
11+
srcip_field = "Fields[ssh_remote_ipaddr]"
12+
geocity_field = "Fields[ssh_remote_ipaddr_city]"
13+
geocountry_field = "Fields[ssh_remote_ipaddr_country]"
14+
15+
userspec = {
16+
q = {
17+
ip = { "127.0.0.1" }
18+
},
19+
riker = {
20+
ip = { "192.168.1.0/24" },
21+
geo = { "Toronto/CA" }
22+
},
23+
authipgeoany = {
24+
ip = { "10.0.0.1/32" },
25+
geo = { "Milton/US" }
26+
}
27+
}

moz_security/tests/integration/analysis_auth_ip_geo/run/input/generate_auth.lua

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,12 @@ local test = {
2525
{ "sshd", "Accepted publickey for riker from 192.168.1.2 port 4242 ssh2", sdec, 0 },
2626
{ "sshd", "Accepted publickey for riker from 216.160.83.56 port 4242 ssh2", sdec, -1000 },
2727
{ "sshd", "Accepted publickey for worf from 216.160.83.56 port 4242 ssh2", sdec, 1000 },
28+
},
29+
{
30+
{ "sshd", "Accepted publickey for riker from 10.0.0.1 port 4242 ssh2", sdec, 0 },
31+
{ "sshd", "Accepted publickey for riker from 216.160.83.56 port 4242 ssh2", sdec, 0 },
32+
{ "sshd", "Accepted publickey for troi from 192.168.1.2 port 4242 ssh2", sdec, 0 },
33+
{ "sshd", "Accepted publickey for troi from 10.0.0.1 port 4242 ssh2", sdec, 0 },
2834
}
2935
}
3036

moz_security/tests/integration/analysis_auth_ip_geo/run/output/auth_ip_geo_verification.lua

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,34 @@ local results = {
5858
recipients = { "<[email protected]>" },
5959
payload = "^Generated by integration_test, event timestamp %d+-%d+-%d+ %d+:%d+:%d+\n" ..
6060
"WARNING, unacceptable drift"
61-
}
61+
},
62+
},
63+
{
64+
{
65+
summary = "riker authentication bastion.host from 10.0.0.1",
66+
recipients = { "<[email protected]>" },
67+
payload = "^Generated by integration_test, event timestamp %d+-%d+-%d+ %d+:%d+:%d+\n$"
68+
},
69+
{
70+
summary = "riker authentication bastion.host from 216.160.83.56 (Milton, US)",
71+
recipients = { "<[email protected]>" },
72+
payload = "^Generated by integration_test, event timestamp %d+-%d+-%d+ %d+:%d+:%d+\n$"
73+
},
74+
{
75+
summary = "NOSPEC troi authentication bastion.host from 192.168.1.2",
76+
recipients = { "<[email protected]>" },
77+
payload = "^No user specification present for comparison against authentication\n" ..
78+
"Generated by integration_test, event timestamp %d+-%d+-%d+ %d+:%d+:%d+\n$"
79+
},
80+
{
81+
summary = "troi authentication bastion.host from 10.0.0.1",
82+
recipients = { "<[email protected]>" },
83+
payload = "^Generated by integration_test, event timestamp %d+-%d+-%d+ %d+:%d+:%d+\n$"
84+
},
6285
}
6386
}
6487

65-
local cnt = { 1, 1 }
88+
local cnt = { 1, 1, 1 }
6689

6790
function process_message()
6891
local summary = read_message("Fields[summary]") or error("no summary field")

0 commit comments

Comments
 (0)