Skip to content

Instantly share code, notes, and snippets.

@oahayder
Last active March 15, 2021 06:46
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save oahayder/1d8fc8b19660fac1aebce59ea6d171ad to your computer and use it in GitHub Desktop.
Save oahayder/1d8fc8b19660fac1aebce59ea6d171ad to your computer and use it in GitHub Desktop.
Istio Gateway EnvoyFilter
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: edge-lua-filter
spec:
workloadLabels:
app: ingressgateway
filters:
- listenerMatch:
portNumber: 443
listenerType: GATEWAY
filterName: envoy.lua
filterType: HTTP
filterConfig:
inlineCode: |
function process(request_handle, cluster, http_host)
request_handle:logInfo("[" .. cluster .. "] Processing...")
-- Build a request for our authenticaiton service before passing request upstream
local authentication_request = {
[":method"] = "POST",
[":path"] = "{{ path }}",
[":authority"] = {{ auth_host }},
}
local response_headers, response_body = request_handle:httpCall(
cluster,
authentication_request,
"", -- empty body
edge_processors_timeout_ms
)
-- If we don't get a 204 from our Authentication service, reject the request
if tonumber(response_headers[":status"]) ~= 204 then
request_handle:logInfo("[" .. cluster .. "] Failed")
request_handle:respond(
{[":status"] = response_headers[":status"]},
response_body
)
end
-- The authentication service responds with a series of headers to Set and Unset
-- Pass all 'Set-*' headers to upstream
-- Remove all 'Unset-*' headers from request
for header, value in pairs(response_headers) do
local set_header = header:lower():match("^set%-(.+)")
if set_header then
request_handle:headers():replace(set_header, value)
else
local unset_header = header:lower():match("^unset%-(.+)")
if unset_header then
request_handle:headers():remove(unset_header)
end
end
end
request_handle:logInfo("[" .. cluster .. "] Processed")
end
-- Called on the request path.
function envoy_on_request(request_handle)
process(request_handle, "{{ cluster }}", "{{ http_host }}")
end
-- Called on the response path.
function envoy_on_response(response_handle)
local headers = response_handle:headers()
headers:add("X-Envoy-Ingress", os.getenv("HOSTNAME"))
end
@VinothChinnadurai
Copy link

VinothChinnadurai commented Mar 3, 2020

@oahayder Thanks for sharing this. I have an issue related to the same. This is how we implemented the same.

kind: EnvoyFilter
metadata:
  name: edge-lua-filter
spec:
  workloadLabels:
    app: istio-ingressgateway
  filters:
  - listenerMatch:
      portNumber: 80
      listenerType: GATEWAY
      listenerProtocol: HTTP
    filterName: envoy.lua
    filterType: HTTP
    filterConfig:
      inlineCode: |
        function process(request_handle, cluster, auth_host)
            request_handle:logWarn("entered process filter")
            request_handle:logWarn("[" .. cluster .. "] Processing...")
            -- Build a request for our authentication service before passing request upstream
            local authentication_request = {
                [":method"] = "GET",
                [":path"] = "/",
                [":authority"] = auth_host
            }

            local response_headers, response_body = request_handle:httpCall(
                cluster,
                authentication_request,
                "",
                10000 --ms
            )
            -- If we don't get a 204 from our Authentication service, reject the request
            if tonumber(response_headers[":status"]) ~= 401 then
                request_handle:logWarn(response_headers[":status"])
                request_handle:logWarn("[" .. cluster .. "] Failed")
                request_handle:respond(
                                {[":status"] = response_headers[":status"]},
                                response_body
                        )
            end
            -- The authentication service responds with a series of headers to Set and Unset
            -- Pass all 'Set-*' headers to upstream
            -- Remove all 'Unset-*' headers from request
            for header, value in pairs(response_headers) do
                local set_header = header:lower():match("^set%-(.+)")
                if set_header then
                    request_handle:headers():replace(set_header, value)
                else
                    local unset_header = header:lower():match("^unset%-(.+)")
                    if unset_header then
                        request_handle:headers():remove(unset_header)
                    end
                end
            end
            request_handle:logInfo("[" .. cluster .. "] Processed")
        end
        -- Called on the request path.
        function envoy_on_request(request_handle)
            process(request_handle, "outbound_.80_._.microservice.microservicens.svc.cluster.local", "{{authentication_server_domain_url}}")
        end
        -- Called on the response path.
        function envoy_on_response(response_handle)
            local headers = response_handle:headers()
            headers:add("X-Envoy-Ingress", os.getenv("HOSTNAME"))
        end```

But all our response for the authentication_request it throws 403 response code. Am I missing any? Waiting for your response

@oahayder
Copy link
Author

oahayder commented Mar 9, 2020

Hello, this would depend entirely on the server 'auth_host' and how it authenticates requests from this filter.

@VinothChinnadurai
Copy link

Thanks for the response @oahayder. I will do modify it accordingly. I have a question on cluster parameter to process() function. I would like to know what will be the value of that parameter. I have mentioned "outbound_.80_._.microservice.microservicens.svc.cluster.local" here as a value but it belongs to particular microservice. But I want these to be any calls to be processed for all calls to my Istio IG. If so what would be value of this 'cluster' parameter

@lck0129
Copy link

lck0129 commented May 15, 2020

gateway crash when client keep sending requests, any idea to limit the incoming requests ?
istio/istio#23874

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment