@@ -32,44 +32,69 @@ local function fetch_whitelist(url)
32
32
}
33
33
})
34
34
35
- local status = res and res .status or nil
36
- local body = res and res .body or nil
37
-
38
- if (not res ) or (not body ) or (status and (status < 200 or status >= 300 )) or err then
39
- ngx .log (ngx .ERR , " [lua-resty-whitelist] failed to fetch whitelist => url: " .. url .. " , status: " .. status ..
40
- " , body: " .. body , err )
41
- ngx .exit (ngx .HTTP_INTERNAL_SERVER_ERROR )
35
+ if not res then
36
+ ngx .log (ngx .ERR , " [lua-resty-whitelist] failed to request whitelist endpoint: response is empty, URL: " , url )
37
+ ngx .exit (ngx .HTTP_SERVICE_UNAVAILABLE )
38
+ end
39
+ if is_empty (res .body ) or res .status < 200 or res .status > 299 then
40
+ ngx .log (ngx .ERR ,
41
+ " [lua-resty-whitelist] failed to request whitelist endpoint: status code is not success, URL: " , url )
42
+ ngx .exit (ngx .HTTP_SERVICE_UNAVAILABLE )
42
43
end
43
44
44
- local whitelist = body .. " "
45
- local whitelist_array = {}
45
+ local body = res .body
46
46
47
- -- Extract CIRDs
48
- for ip in string.gmatch (whitelist , " ((%d%d?%d?)%.(%d%d?%d?)%.(%d%d?%d?)%.(%d%d?%d?)/(%d%d?))" ) do
49
- table.insert (whitelist_array , ip )
50
- end
47
+ local whitelist_body = " " .. body .. " "
51
48
52
- -- local whitelist_concat = table.concat(whitelist_array, ", ")
53
- -- ngx.log(ngx.ERR, "[lua-resty-whitelist] CIRDs: " .. whitelist_concat)
49
+ -- Extract all CIDRs from whitelist
50
+ local cidrs_regex =
51
+ " ((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\ .(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\ .(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\ .(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\\ /(3[0-6]|[1-2][0-9]|[0-9])))"
52
+ local whitelist_cidrs = {}
53
+ for cidr in ngx .re .gmatch (whitelist_body , cidrs_regex , " o" ) do
54
+ table.insert (whitelist_cidrs , cidr [0 ])
55
+ end
54
56
55
- -- TODO: Extract normal IPs as well
57
+ -- Extract all IPs from whitelist
58
+ local ip_regex =
59
+ " ((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\ .(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\ .(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\ .(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))"
60
+ local whitelist_ips = {}
61
+ for ip in ngx .re .gmatch (whitelist_body , ip_regex , " o" ) do
62
+ table.insert (whitelist_ips , ip [0 ])
63
+ end
56
64
57
- -- -- Extract IPs
58
- -- for ip in string.gmatch(whitelist, "((%d%d?%d?)%.(%d%d?%d?)%.(%d%d?%d?)%.(%d%d?%d?)$)") do
59
- -- table.insert(whitelist_array, string.sub(ip, 1, -2))
60
- -- end
65
+ -- Parse CIDRs
66
+ local whitelist_cidrs_parsed = {}
67
+ if istable (whitelist_cidrs ) and # whitelist_ips > 0 then
68
+ whitelist_cidrs_parsed , err = iputils .parse_cidrs (whitelist_cidrs )
69
+ if err then
70
+ ngx .log (ngx .ERR , " [lua-resty-whitelist] failed to parse CIDRs, URL: " .. url .. " , err: " .. err )
71
+ ngx .exit (ngx .HTTP_INTERNAL_SERVER_ERROR )
72
+ end
73
+ end
61
74
62
- -- whitelist_concat = table.concat(whitelist_array, ", ")
63
- -- ngx.log(ngx.ERR, "[lua-resty-whitelist] whitelist_concat: " .. whitelist_concat)
75
+ -- For each IP verify that there is no CIDR that contains it (sort of a clean up)
76
+ local clean_whitelist_ips = {}
77
+ for _ , ip in ipairs (whitelist_ips ) do
78
+ if not iputils .ip_in_cidrs (ip , whitelist_cidrs_parsed ) then
79
+ table.insert (clean_whitelist_ips , ip )
80
+ end
81
+ end
64
82
65
- return whitelist_array
83
+ return clean_whitelist_ips , whitelist_cidrs_parsed , whitelist_cidrs
66
84
end
67
85
68
- local function match_ip_whitelist (ip , whitelist_array )
69
- local whitelist = iputils .parse_cidrs (whitelist_array )
70
- if not iputils .ip_in_cidrs (ip , whitelist ) then
71
- return ngx .exit (ngx .HTTP_FORBIDDEN )
86
+ local function match_ip_whitelist (ip , full_whitelist_ips , full_whitelist_cidrs_parsed )
87
+ if iputils .ip_in_cidrs (ip , full_whitelist_cidrs_parsed ) then
88
+ return true
72
89
end
90
+
91
+ for _ , v in ipairs (full_whitelist_ips ) do
92
+ if v == ip then
93
+ return true
94
+ end
95
+ end
96
+
97
+ return ngx .exit (ngx .HTTP_FORBIDDEN )
73
98
end
74
99
75
100
function whitelist_m .new (url )
@@ -79,24 +104,41 @@ function whitelist_m.new(url)
79
104
ngx .exit (ngx .HTTP_INTERNAL_SERVER_ERROR )
80
105
end
81
106
82
- local whitelist_array = {}
107
+ local full_whitelist_cidrs_parsed = {}
108
+ local full_whitelist_cidrs_unparsed = {}
109
+ local full_whitelist_ips = {}
83
110
84
111
if istable (url ) then
85
- for _ , u in ipairs (url ) do
86
- if is_empty (u ) then
112
+ -- Iterate over the table url as it is a list of URLs
113
+ for _ , v in ipairs (url ) do
114
+ if is_empty (v ) then
87
115
ngx .log (ngx .ERR , validation_message )
88
116
ngx .exit (ngx .HTTP_INTERNAL_SERVER_ERROR )
89
117
end
90
118
91
- for _ , v in ipairs (fetch_whitelist (u )) do
92
- table.insert (whitelist_array , v )
119
+ local whitelist_ips , whitelist_cidrs_parsed , whitelist_cidrs_unparsed = fetch_whitelist (v )
120
+
121
+ for _ , ip in ipairs (whitelist_ips ) do
122
+ table.insert (full_whitelist_ips , ip )
123
+ end
124
+
125
+ for _ , cidr in ipairs (whitelist_cidrs_parsed ) do
126
+ table.insert (full_whitelist_cidrs_parsed , cidr )
127
+ end
128
+
129
+ for _ , cidr in ipairs (whitelist_cidrs_unparsed ) do
130
+ table.insert (full_whitelist_cidrs_unparsed , cidr )
93
131
end
94
132
end
95
133
else
96
- whitelist_array = fetch_whitelist (url )
134
+ -- Get clean_whitelist_ips, whitelist_cidrs_parsed from fetch_whitelist(url)
135
+ full_whitelist_ips , full_whitelist_cidrs_parsed , full_whitelist_cidrs_unparsed = fetch_whitelist (url )
97
136
end
98
137
99
- match_ip_whitelist (ngx .var .remote_addr , whitelist_array )
138
+ ngx .log (ngx .ALERT , " Whitelist IPs: " .. table.concat (full_whitelist_ips , " , " ))
139
+ ngx .log (ngx .ALERT , " Whitelist CIDRs: " .. table.concat (full_whitelist_cidrs_unparsed , " , " ))
140
+
141
+ match_ip_whitelist (ngx .var .remote_addr , full_whitelist_ips , full_whitelist_cidrs_parsed )
100
142
end
101
143
102
144
return whitelist_m
0 commit comments