Pomerium: foward auth with nginx auth_request

Created on 10 Feb 2020  路  3Comments  路  Source: pomerium/pomerium

Here is my attempt for using forward auth with nginx and the issue I've found.

  • pomerium (v0.6.2+5f67a70) on port 5000
  • nginx (1.16.1-0+xenial1 with mod-http-lua) on the same node
  • TLS is terminated by nginx

The issue flow

  • user opens https://acme.com/ the first time
  • nginx checks with pomerium forward auth (/verify) -> 401 -> redirect to login
  • login complete -> redirect several times to the origin url with pomerium parameters
  • nginx checks with pomerium forward auth (/verify) -> 401 with set-cookie -> redirect to login

The issue: pomerium should return 200 with set-cookie header for the /verify call after login success, basically (p *Proxy) nginxCallback should not always return 401.

Working example

Here's the working example, I override the /verify with 200 if there is set-cookie header, and for some reason add_header Set-Cookie doesn't work so I have to again use lua to set the cookie header after the proxy_pass.

I've checked the config template ingress-nginx is using but have no idea why it works.

location = /.pomerium-fwauth {
    internal;

    proxy_http_version 1.1;
    proxy_set_header Connection "";

    proxy_pass_request_body     off;
    proxy_set_header            Content-Length  "";
    proxy_set_header            X-Forwarded-Proto   "";
    proxy_set_header            X-Forwarded-For $remote_addr;

    proxy_pass http://127.0.0.1:5000/verify?uri=https://$host$request_uri;
    proxy_set_header Host pomerium-fwauth.acme.com;

    header_filter_by_lua_block {
        if ngx.header['Set-Cookie'] ~= nil then
            ngx.status = 200
        end
    }
}

location = /.pomerium-login {
    internal;
    return 302 https://pomerium-fwauth.acme.com/?uri=https://$host$request_uri;
}

location / {
    auth_request /.pomerium-fwauth;
    auth_request_set $auth_cookie $upstream_http_set_cookie;
    error_page 401 /.pomerium-login;

    include snippets/upstream_headers.conf;
    proxy_pass http://127.0.0.1:8080;

    # add_header Set-Cookie $auth_cookie;
    header_filter_by_lua_block {
        if ngx.var.auth_cookie then
            ngx.header['Set-Cookie'] = ngx.var.auth_cookie;
        end
    }
}

bug

All 3 comments

Hi @yaroot - thanks for trying pomerium. Your timing is interesting, as I was just digging into this exact request pattern. Going to answer out of order. First things first - how to make it work:

I've checked the config template ingress-nginx is using but have no idea why it works.

Actually, it doesn't as of 0.26.2. https://github.com/kubernetes/ingress-nginx/issues/5054. The linked PR adds in a Set-Cookie to the current template. I believe it is during the 302 to login:

location = /.pomerium-login {
    internal;
    add_header Set-Cookie $auth_cookie;
    return 302 https://pomerium-fwauth.acme.com/?uri=https://$host$request_uri;
}

I believe you need to set that variable in the protected location but I'm not sure if there's more to it:

auth_request_set    $auth_cookie $upstream_http_set_cookie;

The issue: pomerium should return 200 with set-cookie header for the /verify call after login success, basically (p *Proxy) nginxCallback should not always return 401.

There is some discussion around this. The current behavior was originally intended to clear the token present in the URL parameters after the initial authentication flow. By returning a 401 + cookie, you wind up returning back to the original request URL with a session cookie and just the original parameters.

This might change but, to get going immediately, your best bet is to ensure your config sets any cookies returned by the auth endpoint. You can use the pre-0.26.2 templates or the templates in the referenced issue/PR as a reference.

@travisgroth I wasn't aware of this workflow, it all make sense now.

@desimone here's something that works for nginx

location = /.pomerium-fwauth {
    internal;

    proxy_http_version 1.1;
    proxy_set_header Connection "";

    proxy_pass_request_body     off;
    proxy_set_header            Content-Length  "";
    proxy_set_header            X-Forwarded-Proto   "";
    proxy_set_header            X-Forwarded-For $remote_addr;

    proxy_pass http://127.0.0.1:5000/verify?uri=https://$host$request_uri;
    proxy_set_header Host pomerium-fwauth.acme.com;
}

location = /.pomerium-login {
    internal;
    add_header Set-Cookie $auth_cookie;
    return 302 https://pomerium-fwauth.acme.com/?uri=https://$host$request_uri;
}

location / {
    auth_request /.pomerium-fwauth;
    auth_request_set $auth_cookie $upstream_http_set_cookie;
    error_page 401 /.pomerium-login;

    # proxy_set_header ...
    proxy_pass http://127.0.0.1:8080;
}

Glad that worked. Thanks for reporting back! 馃憤

Was this page helpful?
0 / 5 - 0 ratings

Related issues

amiral-fu picture amiral-fu  路  6Comments

chickahoona picture chickahoona  路  3Comments

shreyaskarnik picture shreyaskarnik  路  4Comments

pecigonzalo picture pecigonzalo  路  9Comments

cjwalton picture cjwalton  路  7Comments