Oauth with internal-only domain?

chronograf
#1

Am I mistaken or does the Google OAuth require the domain to be public? Then for Github it seems that’s only Github.com, right? I don’t see any options that would support Enterprise Github.

#2

Hey @austinbutler !

Yes, unfortunately Google’s OAuth2 implementation wants the domain for Chronograf to be publicly reachable. You’re also correct in assuming that the default Github OAuth2 implementation assumes Github.com. However, I think that you should be able to use Github Enterprise using our Generic OAuth2 support by grabbing the URLs from Github’s documentation and replacing api.github.com with the domain that Github Enterprise is running at.

Please let me know how you make out!

Tim

#3

That was the exact idea I had a bit after posting this. Will update if I get it working.

#4

Had some time to return to this. I am hosting Chronograf at example.com/chronograf so I go there, then it says “Login with Generic.” I click that, it opens the right Github page that shows the project I created. I click “Authorize application” on Github.

What happens next depends if GENERIC_NAME is defined. If it isn’t, it takes me to example.com/login, which is actually Grafana being served at the root of the domain, so it shows the Grafana login if I am not logged in to Grafana or just goes to the Grafana homepage if I am logged in. If I do define GENERIC_NAME then I get taken to example.com/chronograf/oauth/generic/callback but Chronograf shows a 404 error (“bummer…”).

The error with no GENERIC_NAME is:

msg="Unable to get principal identifier Get : unsupported protocol scheme \"\"" component=auth method=GET remote_addr="127.0.0.1:57886" url=/chronograf/oauth/generic/callback?code=`

These are my environment variables for Chronograf:

HOST=127.0.0.1
BASE_PATH=/chronograf
PREFIX_ROUTES=true
LOG_LEVEL=debug
TOKEN_SECRET=xxxxxxxxxxxxxxxxxxxxxxxxxxx
GENERIC_CLIENT_ID=xxxxxxxxxxxxxxxxxxx
GENERIC_CLIENT_SECRET=xxxxxxxxxxxxxxxxxxxxxxxx
GENERIC_AUTH_URL=https://github.example.com/login/oauth/authorize
GENERIC_TOKEN_URL=https://github.example.com/login/oauth/access_token
AUTH_DURATION=12h
GENERIC_NAME=Github

Chronograf and Grafana are both behind NGINX reverse proxy. Both work totally fine aside from this issue.

The homepage URL in Github is set to https://example.com/chronograf and the callback URL is set to https://example.com/chronograf/oauth/generic/callback. When I use GENERIC_NAME I change “generic” in the callback URL.

Not sure where I am going wrong, but the fact that I get redirected to /login instead of /chronograf/login makes me think maybe it’s something where this portion of Chronograf isn’t respecting the BASE_PATH. Any ideas @tim?

#5

One issue that I see is that the value you use in GENERIC_NAME needs to replace “generic” in the callback URL. This was undocumented (and also incorrectly documented). In your example, since GENERIC_NAME=Github, the correct callback URL should be:
example.com/chronograf/oauth/Github/callback

Here are two open, related issues I’m working on:


#6

Hey @stevebang, I eventually figured out you have to change the callback URL to match the GENERIC_NAME (although it seems it has to be lower case, otherwise I get a 404).

But the confusing documentation still doesn’t seem to be the root issue for me since even with the correct callback URL I just get sent back to /login on the domain (Grafana in my case, since I am serving Chronograf from a subfolder), and I am not logged in. The Gitlab Oauth issue shows the same problem I think: “I click ‘Login to Gitlab’ and bounced right back to the Chronograf login page.”

#7

Hi @austinbutler, could it be that Grafana’s process is taking precedence on that callback URL? It’s difficult to disambiguate as it sounds like you have Grafana configured for the same URL.

As for the rest of the issue, it does sound like it’s captured by the referenced GitHub issue, yes?

Thanks for writing in~

#8

I believe I tried setting NGINX to pass the headers as you suggested on the Github issue. I will try to confirm for sure, though.

#10

Thanks – I’m not sure what else to think currently, but eliminating that problem will help us diagnose the root, if the problem remains.

#11

I’ve come back to this after seeing the updates on the Github issues, but I still can’t get this working. In fact, it’s not even showing me any Github pages at this point, whereas before it would at least show me the Github auth page for the app and would later show a registered user on Github. With what seems to be the recommended config, I always get “redirect_uri_mismatch” in the logs. But as far as I can tell I have that set properly in Github. Is there any way to see what Chronograf is sending for that value? Based on the error it seems Chronograf is not sending the right URI. Or perhaps that’s a red herring and I’ve made a simple mistake somewhere. :drooling_face:

Chronograf version:

[abutler@dev ~]$ chronograf --version
2018/03/17 20:44:26 Chronograf 1.4.2.3 (git: ee9111d04dd386bdb9f1ead484fb709c224d41a4)

NGINX config:

[abutler@dev ~]$ cat /etc/nginx/conf.d/grafana.conf
# Redirect all HTTP requests to HTTPS
server {
	listen 80 default_server;
	server_name _;
	return 301 https://$host$request_uri;
}

server {
  listen 443 ssl;
  server_name REDACTED_MY_IP;

  ssl_certificate /etc/pki/tls/certs/cert.crt;
  ssl_certificate_key /etc/pki/tls/private/cert.key;
  ssl_session_timeout 1d;
  ssl_session_cache shared:SSL:50m;
  ssl_protocols TLSv1.2;
  ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
  ssl_prefer_server_ciphers on;

  # HSTS (31536000 seconds = 1 year)
  add_header Strict-Transport-Security "max-age=31536000 includeSubDomains" always;

  proxy_set_header HOST $host;
  proxy_set_header X-Forwarded-Proto $scheme;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

	# Grafana
  location / {
    proxy_pass http://127.0.0.1:3000;
  }

	# Chronograf
	location /chronograf {
    proxy_pass http://127.0.0.1:8888;
  }
}

Chronograf environment variables (via systemd override):

[abutler@dev ~]$ cat /etc/systemd/system/chronograf.service.d/override.conf
[Service]
Environment=HOST=127.0.0.1
Environment=BASE_PATH=/chronograf
Environment=PREFIX_ROUTES=true
Environment=LOG_LEVEL=debug
Environment='TOKEN_SECRET=REDACTED_SECRET'
Environment=GENERIC_CLIENT_ID=REDACTED_CLIENT_ID
Environment=GENERIC_CLIENT_SECRET=REDACTED_CLIENT_SECRET
Environment=GENERIC_AUTH_URL=https://interal_github.example.com/login/oauth/authorize
Environment=GENERIC_TOKEN_URL=https://interal_github.example.com/login/oauth/access_token
Environment=AUTH_DURATION=12h
Environment=GENERIC_NAME=Github
Environment=GENERIC_API_URL=https://interal_github.example.com/api/user
Environment=PUBLIC_URL=https://REDACTED_MY_IP/chronograf
Environment='GENERIC_SCOPES=user:email read:org'

Logs from a single login attempt:

[abutler@dev ~]$ sudo journalctl -u chronograf --since '2018-03-17 20:54:00' --no-pager
-- Logs begin at Tue 2018-03-13 10:24:29 UTC, end at Sat 2018-03-17 20:56:28 UTC. --
Mar 17 20:54:00 dev chronograf[19381]: time="2018-03-17T20:54:00Z" level=debug msg=Request component=server method=GET remote_addr="127.0.0.1:36300" url=/chronograf
Mar 17 20:54:00 dev chronograf[19381]: time="2018-03-17T20:54:00Z" level=info msg="Serving assets" component=server method=GET remote_addr="127.0.0.1:36300" url=
Mar 17 20:54:00 dev chronograf[19381]: time="2018-03-17T20:54:00Z" level=info msg="Response: OK" component=server method=GET remote_addr="127.0.0.1:36300" response_time=1.215565ms status=200
Mar 17 20:54:00 dev chronograf[19381]: time="2018-03-17T20:54:00Z" level=debug msg=Request component=server method=GET remote_addr="127.0.0.1:36302" url=/chronograf/chronograf.css
Mar 17 20:54:00 dev chronograf[19381]: time="2018-03-17T20:54:00Z" level=info msg="Serving assets" component=server method=GET remote_addr="127.0.0.1:36302" url=/chronograf.css
Mar 17 20:54:00 dev chronograf[19381]: time="2018-03-17T20:54:00Z" level=info msg="Response: OK" component=server method=GET remote_addr="127.0.0.1:36302" response_time=123.266707ms status=200
Mar 17 20:54:00 dev chronograf[19381]: time="2018-03-17T20:54:00Z" level=debug msg=Request component=server method=GET remote_addr="127.0.0.1:36304" url=/chronograf/manifest.908d0133da396e4dd66b.js
Mar 17 20:54:00 dev chronograf[19381]: time="2018-03-17T20:54:00Z" level=info msg="Serving assets" component=server method=GET remote_addr="127.0.0.1:36304" url=/manifest.908d0133da396e4dd66b.js
Mar 17 20:54:00 dev chronograf[19381]: time="2018-03-17T20:54:00Z" level=info msg="Response: OK" component=server method=GET remote_addr="127.0.0.1:36304" response_time="843.876µs" status=200
Mar 17 20:54:00 dev chronograf[19381]: time="2018-03-17T20:54:00Z" level=debug msg=Request component=server method=GET remote_addr="127.0.0.1:36306" url=/chronograf/vendor.6eb26e15a9f2970496d1.js
Mar 17 20:54:00 dev chronograf[19381]: time="2018-03-17T20:54:00Z" level=info msg="Serving assets" component=server method=GET remote_addr="127.0.0.1:36306" url=/vendor.6eb26e15a9f2970496d1.js
Mar 17 20:54:00 dev chronograf[19381]: time="2018-03-17T20:54:00Z" level=debug msg=Request component=server method=GET remote_addr="127.0.0.1:36308" url=/chronograf/app.474dc3ad68b5acc214ef.js
Mar 17 20:54:00 dev chronograf[19381]: time="2018-03-17T20:54:00Z" level=info msg="Serving assets" component=server method=GET remote_addr="127.0.0.1:36308" url=/app.474dc3ad68b5acc214ef.js
Mar 17 20:54:01 dev chronograf[19381]: time="2018-03-17T20:54:01Z" level=info msg="Response: OK" component=server method=GET remote_addr="127.0.0.1:36308" response_time=770.516857ms status=200
Mar 17 20:54:02 dev chronograf[19381]: time="2018-03-17T20:54:02Z" level=info msg="Response: OK" component=server method=GET remote_addr="127.0.0.1:36306" response_time=1.621366371s status=200
Mar 17 20:54:02 dev chronograf[19381]: time="2018-03-17T20:54:02Z" level=debug msg=Request component=server method=GET remote_addr="127.0.0.1:36310" url=/chronograf/chronograf/v1
Mar 17 20:54:02 dev chronograf[19381]: time="2018-03-17T20:54:02Z" level=info msg="Response: OK" component=server method=GET remote_addr="127.0.0.1:36310" response_time="131.266µs" status=200
Mar 17 20:54:02 dev chronograf[19381]: time="2018-03-17T20:54:02Z" level=debug msg=Request component=server method=GET remote_addr="127.0.0.1:36312" url=/chronograf/chronograf/v1/me
Mar 17 20:54:02 dev chronograf[19381]: time="2018-03-17T20:54:02Z" level=error msg="Invalid principal" component="token_auth" method=GET remote_addr="127.0.0.1:36312" url=/chronograf/chronograf/v1/me
Mar 17 20:54:02 dev chronograf[19381]: time="2018-03-17T20:54:02Z" level=info msg="Response: Forbidden" component=server method=GET remote_addr="127.0.0.1:36312" response_time="107.677µs" status=403
Mar 17 20:54:02 dev chronograf[19381]: time="2018-03-17T20:54:02Z" level=debug msg=Request component=server method=GET remote_addr="127.0.0.1:36314" url=/chronograf/2bb64b4255c3d298ecae22d2053b77c2.svg
Mar 17 20:54:02 dev chronograf[19381]: time="2018-03-17T20:54:02Z" level=debug msg=Request component=server method=GET remote_addr="127.0.0.1:36316" url=/chronograf/756cfeadfdbf9222a81d41b8931ba2a4.svg
Mar 17 20:54:02 dev chronograf[19381]: time="2018-03-17T20:54:02Z" level=info msg="Serving assets" component=server method=GET remote_addr="127.0.0.1:36314" url=/2bb64b4255c3d298ecae22d2053b77c2.svg
Mar 17 20:54:02 dev chronograf[19381]: time="2018-03-17T20:54:02Z" level=info msg="Serving assets" component=server method=GET remote_addr="127.0.0.1:36316" url=/756cfeadfdbf9222a81d41b8931ba2a4.svg
Mar 17 20:54:02 dev chronograf[19381]: time="2018-03-17T20:54:02Z" level=info msg="Response: OK" component=server method=GET remote_addr="127.0.0.1:36316" response_time=1.057938ms status=200
Mar 17 20:54:03 dev chronograf[19381]: time="2018-03-17T20:54:02Z" level=debug msg=Request component=server method=GET remote_addr="127.0.0.1:36318" url=/chronograf/3f68500b267c20051088bcc0698af773.ttf
Mar 17 20:54:03 dev chronograf[19381]: time="2018-03-17T20:54:02Z" level=info msg="Serving assets" component=server method=GET remote_addr="127.0.0.1:36318" url=/3f68500b267c20051088bcc0698af773.ttf
Mar 17 20:54:03 dev chronograf[19381]: time="2018-03-17T20:54:03Z" level=debug msg=Request component=server method=GET remote_addr="127.0.0.1:36320" url=/chronograf/893fe14628bd7ac498d550e96367e1be.ttf
Mar 17 20:54:03 dev chronograf[19381]: time="2018-03-17T20:54:03Z" level=info msg="Serving assets" component=server method=GET remote_addr="127.0.0.1:36320" url=/893fe14628bd7ac498d550e96367e1be.ttf
Mar 17 20:54:03 dev chronograf[19381]: time="2018-03-17T20:54:03Z" level=info msg="Response: OK" component=server method=GET remote_addr="127.0.0.1:36318" response_time=90.779969ms status=200
Mar 17 20:54:03 dev chronograf[19381]: time="2018-03-17T20:54:03Z" level=debug msg=Request component=server method=GET remote_addr="127.0.0.1:36322" url=/chronograf/ac3f799d5bbaf5196fab15ab8de8431c.ttf
Mar 17 20:54:03 dev chronograf[19381]: time="2018-03-17T20:54:03Z" level=info msg="Serving assets" component=server method=GET remote_addr="127.0.0.1:36322" url=/ac3f799d5bbaf5196fab15ab8de8431c.ttf
Mar 17 20:54:03 dev chronograf[19381]: time="2018-03-17T20:54:03Z" level=info msg="Response: OK" component=server method=GET remote_addr="127.0.0.1:36320" response_time=71.096897ms status=200
Mar 17 20:54:03 dev chronograf[19381]: time="2018-03-17T20:54:03Z" level=info msg="Response: OK" component=server method=GET remote_addr="127.0.0.1:36314" response_time=149.441597ms status=200
Mar 17 20:54:03 dev chronograf[19381]: time="2018-03-17T20:54:03Z" level=info msg="Response: OK" component=server method=GET remote_addr="127.0.0.1:36322" response_time=64.145291ms status=200
Mar 17 20:54:03 dev chronograf[19381]: time="2018-03-17T20:54:03Z" level=debug msg=Request component=server method=GET remote_addr="127.0.0.1:36324" url=/chronograf/d329cc8b34667f114a95422aaad1b063.ttf
Mar 17 20:54:03 dev chronograf[19381]: time="2018-03-17T20:54:03Z" level=debug msg=Request component=server method=GET remote_addr="127.0.0.1:36326" url=/chronograf/ccc59a4ae2da74b29a40b16bc4fbdbd0.woff2
Mar 17 20:54:03 dev chronograf[19381]: time="2018-03-17T20:54:03Z" level=info msg="Serving assets" component=server method=GET remote_addr="127.0.0.1:36326" url=/ccc59a4ae2da74b29a40b16bc4fbdbd0.woff2
Mar 17 20:54:03 dev chronograf[19381]: time="2018-03-17T20:54:03Z" level=info msg="Serving assets" component=server method=GET remote_addr="127.0.0.1:36324" url=/d329cc8b34667f114a95422aaad1b063.ttf
Mar 17 20:54:03 dev chronograf[19381]: time="2018-03-17T20:54:03Z" level=info msg="Response: OK" component=server method=GET remote_addr="127.0.0.1:36326" response_time=4.62427ms status=200
Mar 17 20:54:03 dev chronograf[19381]: time="2018-03-17T20:54:03Z" level=info msg="Response: OK" component=server method=GET remote_addr="127.0.0.1:36324" response_time=66.064421ms status=200
Mar 17 20:54:04 dev chronograf[19381]: time="2018-03-17T20:54:04Z" level=debug msg=Request component=server method=GET remote_addr="127.0.0.1:36328" url=/chronograf/oauth/github/login
Mar 17 20:54:04 dev chronograf[19381]: time="2018-03-17T20:54:04Z" level=info msg="Response: Temporary Redirect" component=server method=GET remote_addr="127.0.0.1:36328" response_time="225.655µs" status=307
Mar 17 20:54:05 dev chronograf[19381]: time="2018-03-17T20:54:05Z" level=debug msg=Request component=server method=GET remote_addr="127.0.0.1:36330" url=/chronograf/oauth/github/callback?error=redirect_uri_mismatch&error_description=The+redirect_uri+MUST+match+the+registered+callback+URL+for+this+application.&error_uri=https%3A%2F%2Fdeveloper.github.com%2Fenterprise%2F2.11%2Fv3%2Foauth%2F%23redirect-uri-mismatch&state=REDACTED
Mar 17 20:54:35 dev chronograf[19381]: time="2018-03-17T20:54:35Z" level=error msg="Unable to exchange code for token Post https://interal_github.example.com/login/oauth/access_token: dial tcp REDACTED_INTERNAL_GH_IP:443: i/o timeout" component=auth method=GET remote_addr="127.0.0.1:36330" url=/chronograf/oauth/github/callback?error=redirect_uri_mismatch&error_description=The+redirect_uri+MUST+match+the+registered+callback+URL+for+this+application.&error_uri=https%3A%2F%2Fdeveloper.github.com%2Fenterprise%2F2.11%2Fv3%2Foauth%2F%23redirect-uri-mismatch&state=REDACTED
Mar 17 20:54:35 dev chronograf[19381]: time="2018-03-17T20:54:35Z" level=info msg="Response: Temporary Redirect" component=server method=GET remote_addr="127.0.0.1:36330" response_time=30.000646391s status=307
Mar 17 20:54:35 dev chronograf[19381]: time="2018-03-17T20:54:35Z" level=debug msg=Request component=server method=GET remote_addr="127.0.0.1:36334" url=/chronograf/chronograf/login/
Mar 17 20:54:35 dev chronograf[19381]: time="2018-03-17T20:54:35Z" level=info msg="Serving assets" component=server method=GET remote_addr="127.0.0.1:36334" url=/chronograf/login/
Mar 17 20:54:35 dev chronograf[19381]: time="2018-03-17T20:54:35Z" level=info msg="Response: Moved Permanently" component=server method=GET remote_addr="127.0.0.1:36334" response_time="495.941µs" status=301

Enterprise Github Homepage URL:

https://REDACTED_MY_IP/chronograf

Enterprise Github Authorization callback URL:

https://REDACTED_MY_IP/chronograf/oauth/github/callback