Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create an example with HAProxy #271

Closed
clems4ever opened this issue Sep 2, 2018 · 18 comments · Fixed by #544
Closed

Create an example with HAProxy #271

clems4ever opened this issue Sep 2, 2018 · 18 comments · Fixed by #544
Assignees
Labels
priority/3/medium Medium priority items type/enhancement Similar to a feature but less impactful

Comments

@clems4ever
Copy link
Member

Authelia is supposed to be able to run with any proxy. We can create an example with HAProxy which is one of the most famous and efficient proxies used in professional environments.

@clems4ever clems4ever added type/enhancement Similar to a feature but less impactful priority/3/medium Medium priority items labels Sep 2, 2018
@SurinameClubcard
Copy link

I was wondering if such an example exists today. I would be very interested to see how HAProxy and Authelia interact.

@clems4ever
Copy link
Member Author

Hello @SurinameClubcard , as you can see the ticket is still open and I have no draft yet. I'll let you know when I have something. You can also try on your side. There is no magick in the conf, all features used from nginx are also in HAProxy so it should not be complicated.

@SurinameClubcard
Copy link

Hello @SurinameClubcard , as you can see the ticket is still open and I have no draft yet. I'll let you know when I have something. You can also try on your side. There is no magick in the conf, all features used from nginx are also in HAProxy so it should not be complicated.

Sounds great! Let me give it a try. What features of nginx are you referring to? Is there a nginx example?

@clems4ever
Copy link
Member Author

clems4ever commented Jan 5, 2019

@SurinameClubcard , I was referring to common features like basic reverse proxy features, setting headers, redirecting but most importantly the question I have is what is the equivalent of http://nginx.org/en/docs/http/ngx_http_auth_request_module.html for HAProxy. I'm not an expert but somebody from the dev team of HAProxy told me that such things was possible.

There is an example of nginx configuration at https://github.com/clems4ever/authelia/blob/master/example/compose/nginx/portal/nginx.conf. It protects several domains of the test environment that can be set up following the documentation.

@SurinameClubcard
Copy link

@SurinameClubcard , I was referring to common features like basic reverse proxy features, setting headers, redirecting but most importantly the question I have is what is the equivalent of http://nginx.org/en/docs/http/ngx_http_auth_request_module.html for HAProxy. I'm not an expert but somebody from the dev team of HAProxy told me that such things was possible.

Well, I found this: https://github.com/TimWolla/haproxy-auth-request. Can you confirm that this seems to be compatible? The source code states:

	-- 2xx: Allow request.
	if 200 <= c and c < 300 then
		txn:set_var("txn.auth_response_successful", true)
		txn:set_var("txn.auth_response_code", c)
	-- 401 / 403: Do not allow request.
	elseif c == 401 or c == 403 then
		txn:set_var("txn.auth_response_code", c)
	-- Everything else: Do not allow request and log.
	else
		txn:Warning("Invalid status code in auth-request backend '" .. be .. "': " .. c)
		txn:set_var("txn.auth_response_code", c)
	end

@clems4ever
Copy link
Member Author

clems4ever commented Jan 6, 2019

Hello @SurinameClubcard , this is exactly the type of contract that Authelia meets so it is
absolutely compatible! :)

@SurinameClubcard
Copy link

Hello @SurinameClubcard , this is exactly the type of contract that Authelia meets so it is
absolutely compatible! :)

Great. haproxy-auth-request requires haproxy v1.8 so I need to upgrade first from v1.7. I will test this module with authelia and report the results back here when finished.

@clems4ever
Copy link
Member Author

Great!

@SurinameClubcard
Copy link

I migrated our haproxy to v1.8. Will start working on the auth-request. On https://github.com/TimWolla/haproxy-auth-request, it is mentioned (at "Known limitations"): The backend must not be using TLS. Is Authelia using TLS to access it?

@clems4ever
Copy link
Member Author

@SurinameClubcard , great! Let me know about your progress. Regarding your question Authelia does not support TLS yet. It would be interesting to understand why auth-request would not work with TLS though.

@clems4ever
Copy link
Member Author

@SurinameClubcard , I came up with a concept of suites to implement integration tests. That would be great if you could create one for HAproxy with the Single-Factor and Two-Factor authentication tests. I can help you with that if needed. Let me know about your progress.

@SurinameClubcard
Copy link

I would be happy to! But first I have to get it working. I have posted my progress so far on Gitter. You might want to take a look because I could use some help understanding a response from Authelia.

@SurinameClubcard
Copy link

@SurinameClubcard , great! Let me know about your progress. Regarding your question Authelia does not support TLS yet. It would be interesting to understand why auth-request would not work with TLS though.

While researching on auth-request I found out it is in fact possible to use a TLS backend (/api/verify) with some changes on the haproxy-auth-request script from @TimWolla.

@TimWolla
Copy link

It would be interesting to understand why auth-request would not work with TLS though.

Because it would be a pain to support within the Lua script. It's should be easy enough to do with a dedicated frontend that performs the encryption. Something like this should work (sending traffic through HAProxy instead of directly to Authelia):

backend auth_backend
  server auth_backend2 localhost:12345

listen auth_backend2
  listen 12345
  server authelia authelia:80 ssl

@TimWolla
Copy link

TimWolla commented Mar 16, 2019

I know nothing about Authelia, but I know a bit about HAProxy. To reproduce the Content-Length issue in haproxy-auth-request I used this HAProxy configuration (it's missing quite a few important parts such as timeouts, it's the minimally viable thing that worked):

global
	lua-load /tmp/authelia/haproxy-auth-request/auth-request.lua

frontend fe_http
	mode http
	bind :8080 ssl crt /scratch/haproxy/ssl/haproxy.pem

	http-request set-var(req.scheme) str(https) if { ssl_fc }
	http-request set-var(req.scheme) str(http) if ! { ssl_fc }
	http-request set-var(req.questionmark) str(?) if { query -m found }

	http-request set-header X-Forwarded-Proto %[var(req.scheme)]
	http-request set-header X-Real-IP %[src]
	http-request set-header X-Original-URI %[path]%[var(req.questionmark)]%[query]
	http-request set-header X-Original-URL %[var(req.scheme)]://%[base]%[var(req.questionmark)]%[query]

	http-request lua.auth-request authelia    /api/verify
	http-response set-header Success %[var(txn.auth_response_code)] # this line can be removed, but was helpful for debugging
	use_backend authelia if ! { var(txn.auth_response_successful) -m bool } # this line forces the request to go to the authelia backend. Can be replaced by `http-request redirect` or `http-request deny` or whatnot.

	http-request set-header Host example.com # this line required for example.com to accept my request (I was using one of my own domains that I pointed to localhost)

	use_backend be_http

backend be_http
	mode http
	server example example.com:80

backend authelia
	mode http

	server authelia 172.17.0.2:9091

I was able to authenticate as john with password password and once I did so I was able to access example.com. This configuration needs an ACL that forces the request to go to Authelia to be able to sign-out. Something like use_backend authelia if { hdr(host) -i authelia.example.com } should work.

@clems4ever
Copy link
Member Author

@TimWolla , great news, I will package that in a suite very soon. Thanks.

@nightah nightah self-assigned this Jan 9, 2020
@nightah
Copy link
Member

nightah commented Jan 10, 2020

@TimWolla I attempted to put together this suite yesterday based on the config you provided above and to fit within how the containers are distributed in the integration tests and seem to be having some trouble.

I'm not sure if this is related to haproxy-auth-request or just my haproxy configuration in general, is there any chance you might be able to have a look?
48a6b2b#diff-04d745fcb3f314fa515c30d19ad059cd

Here's a example of what I'm seeing in the HAProxy logs:

192.168.240.1:38430 [10/Jan/2020:00:54:08.348] fe_http~ fe_authelia/authelia-frontend 0/0/1/18/20 200 1084 - - ---- 1/1/0/0/0 0/0 "GET /logout HTTP/1.1"
192.168.240.1:38430 [10/Jan/2020:00:54:08.382] fe_http~ fe_authelia/authelia-frontend 0/0/0/12/14 200 6653 - - ---- 3/3/2/2/0 0/0 "GET /static/js/bundle.js HTTP/1.1"
192.168.240.1:38436 [10/Jan/2020:00:54:08.383] fe_http~ fe_authelia/authelia-frontend 0/0/0/18/19 200 30753 - - ---- 3/3/1/1/0 0/0 "GET /static/js/main.chunk.js HTTP/1.1"
192.168.240.1:38434 [10/Jan/2020:00:54:08.382] fe_http~ fe_authelia/authelia-frontend 1/0/0/16/247 200 1118806 - - ---- 3/3/0/0/0 0/0 "GET /static/js/0.chunk.js HTTP/1.1"
192.168.240.1:38434 [10/Jan/2020:00:54:08.948] fe_http~ be_authelia/authelia-backend 0/0/1/0/1 200 145 - - ---- 3/3/0/0/0 0/0 "POST /api/logout HTTP/1.1"
192.168.240.1:38436 [10/Jan/2020:00:54:08.949] fe_http~ be_authelia/authelia-backend 0/0/0/0/0 200 155 - - ---- 3/3/0/0/0 0/0 "GET /api/configuration HTTP/1.1"
192.168.240.1:38436 [10/Jan/2020:00:54:08.966] fe_http~ fe_authelia/authelia-frontend 0/0/0/2/2 200 330 - - ---- 3/3/0/0/0 0/0 "GET /sockjs-node/info?t=1578617648965 HTTP/1.1"
192.168.240.1:38436 [10/Jan/2020:00:54:10.977] fe_http~ be_authelia/authelia-backend 0/0/0/1/1 200 222 - - ---- 4/4/0/0/0 0/0 "GET /api/state HTTP/1.1"
Invalid status code in auth-request backend 'be_authelia': 405
[warning] 009/005411 (6) : Invalid status code in auth-request backend 'be_authelia': 405
192.168.240.1:38462 [10/Jan/2020:00:54:11.239] fe_http~ be_authelia/authelia-backend 1/0/0/1/2 404 172 - - ---- 5/5/0/0/0 0/0 "GET / HTTP/1.1"
192.168.240.1:38456 [10/Jan/2020:00:54:08.981] fe_http~ fe_authelia/authelia-frontend 0/0/0/6/2267 101 301 - - ---- 5/5/0/0/0 0/0 "GET /sockjs-node/175/h0cl1c1z/websocket HTTP/1.1"
192.168.240.1:38436 [10/Jan/2020:00:54:11.262] fe_http~ fe_authelia/authelia-frontend 0/0/0/2/3 200 1084 - - ---- 4/4/0/0/0 0/0 "GET /?rd=https://singlefactor.example.com:8080/secret.html HTTP/1.1"
192.168.240.1:38436 [10/Jan/2020:00:54:11.271] fe_http~ fe_authelia/authelia-frontend 0/0/0/1/1 304 159 - - ---- 4/4/2/2/0 0/0 "GET /static/js/bundle.js HTTP/1.1"
192.168.240.1:38434 [10/Jan/2020:00:54:11.272] fe_http~ fe_authelia/authelia-frontend 1/0/0/9/10 304 161 - - ---- 4/4/1/1/0 0/0 "GET /static/js/0.chunk.js HTTP/1.1"
192.168.240.1:38430 [10/Jan/2020:00:54:11.273] fe_http~ fe_authelia/authelia-frontend 0/0/0/11/11 304 160 - - ---- 4/4/0/0/0 0/0 "GET /static/js/main.chunk.js HTTP/1.1"
192.168.240.1:38430 [10/Jan/2020:00:54:11.463] fe_http~ be_authelia/authelia-backend 1/0/0/0/1 200 222 - - ---- 4/4/0/0/0 0/0 "GET /api/state HTTP/1.1"
192.168.240.1:38434 [10/Jan/2020:00:54:11.464] fe_http~ be_authelia/authelia-backend 0/0/0/0/0 200 155 - - ---- 4/4/0/0/0 0/0 "GET /api/configuration HTTP/1.1"
192.168.240.1:38434 [10/Jan/2020:00:54:11.530] fe_http~ fe_authelia/authelia-frontend 0/0/0/1/1 200 329 - - ---- 4/4/0/0/0 0/0 "GET /sockjs-node/info?t=1578617651529 HTTP/1.1"
192.168.240.1:38434 [10/Jan/2020:00:54:12.123] fe_http~ be_authelia/authelia-backend 0/0/0/381/381 200 361 - - ---- 5/5/0/0/0 0/0 "POST /api/firstfactor HTTP/1.1"
Invalid status code in auth-request backend 'be_authelia': 405
[warning] 009/005412 (6) : Invalid status code in auth-request backend 'be_authelia': 405

EDIT: Sorry for all the pings everybody after some more testing looks like I figured it out, it's because haproxy-auth-request is using the HEAD method instead of a GET. If I patch this back to GET it works fine.
@clems4ever I'll leave that patch in the test case but given that HEAD is almost identical to GET minus the body is this something we should be changing on our side?

@TimWolla
Copy link

EDIT: Sorry for all the pings everybody after some more testing looks like I figured it out, it's because haproxy-auth-request is using the HEAD method instead of a GET. If I patch this back to GET it works fine.

For the record, this changed in TimWolla/haproxy-auth-request#10.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
priority/3/medium Medium priority items type/enhancement Similar to a feature but less impactful
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants