@@ -32,44 +32,69 @@ local function fetch_whitelist(url)
3232 }
3333 })
3434
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 )
4243 end
4344
44- local whitelist = body .. " "
45- local whitelist_array = {}
45+ local body = res .body
4646
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 .. " "
5148
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
5456
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
5664
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
6174
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
6482
65- return whitelist_array
83+ return clean_whitelist_ips , whitelist_cidrs_parsed , whitelist_cidrs
6684end
6785
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
7289 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 )
7398end
7499
75100function whitelist_m .new (url )
@@ -79,24 +104,41 @@ function whitelist_m.new(url)
79104 ngx .exit (ngx .HTTP_INTERNAL_SERVER_ERROR )
80105 end
81106
82- local whitelist_array = {}
107+ local full_whitelist_cidrs_parsed = {}
108+ local full_whitelist_cidrs_unparsed = {}
109+ local full_whitelist_ips = {}
83110
84111 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
87115 ngx .log (ngx .ERR , validation_message )
88116 ngx .exit (ngx .HTTP_INTERNAL_SERVER_ERROR )
89117 end
90118
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 )
93131 end
94132 end
95133 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 )
97136 end
98137
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 )
100142end
101143
102144return whitelist_m
0 commit comments