{"action":"created","issue":{"url":"https://api.github.com/repos/grafana/grafana/issues/10707","repository_url":"https://api.github.com/repos/grafana/grafana","labels_url":"https://api.github.com/repos/grafana/grafana/issues/10707/labels{/name}","comments_url":"https://api.github.com/repos/grafana/grafana/issues/10707/comments","events_url":"https://api.github.com/repos/grafana/grafana/issues/10707/events","html_url":"https://github.com/grafana/grafana/issues/10707","id":293389555,"node_id":"MDU6SXNzdWUyOTMzODk1NTU=","number":10707,"title":"Grafana authproxy whitelists the client ip instead of the reverse proxy ip","user":{"login":"samaust","id":10716165,"node_id":"MDQ6VXNlcjEwNzE2MTY1","avatar_url":"https://avatars3.githubusercontent.com/u/10716165?v=4","gravatar_id":"","url":"https://api.github.com/users/samaust","html_url":"https://github.com/samaust","followers_url":"https://api.github.com/users/samaust/followers","following_url":"https://api.github.com/users/samaust/following{/other_user}","gists_url":"https://api.github.com/users/samaust/gists{/gist_id}","starred_url":"https://api.github.com/users/samaust/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/samaust/subscriptions","organizations_url":"https://api.github.com/users/samaust/orgs","repos_url":"https://api.github.com/users/samaust/repos","events_url":"https://api.github.com/users/samaust/events{/privacy}","received_events_url":"https://api.github.com/users/samaust/received_events","type":"User","site_admin":false},"labels":[{"id":174917660,"node_id":"MDU6TGFiZWwxNzQ5MTc2NjA=","url":"https://api.github.com/repos/grafana/grafana/labels/comp:%20backend/security","name":"comp: backend/security","color":"c7def8","default":false},{"id":223098243,"node_id":"MDU6TGFiZWwyMjMwOTgyNDM=","url":"https://api.github.com/repos/grafana/grafana/labels/help%20wanted","name":"help wanted","color":"bfe5bf","default":true},{"id":70176318,"node_id":"MDU6TGFiZWw3MDE3NjMxOA==","url":"https://api.github.com/repos/grafana/grafana/labels/type:%20bug","name":"type: bug","color":"b60205","default":false}],"state":"closed","locked":false,"assignee":{"login":"marefr","id":1668778,"node_id":"MDQ6VXNlcjE2Njg3Nzg=","avatar_url":"https://avatars0.githubusercontent.com/u/1668778?v=4","gravatar_id":"","url":"https://api.github.com/users/marefr","html_url":"https://github.com/marefr","followers_url":"https://api.github.com/users/marefr/followers","following_url":"https://api.github.com/users/marefr/following{/other_user}","gists_url":"https://api.github.com/users/marefr/gists{/gist_id}","starred_url":"https://api.github.com/users/marefr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/marefr/subscriptions","organizations_url":"https://api.github.com/users/marefr/orgs","repos_url":"https://api.github.com/users/marefr/repos","events_url":"https://api.github.com/users/marefr/events{/privacy}","received_events_url":"https://api.github.com/users/marefr/received_events","type":"User","site_admin":false},"assignees":[{"login":"marefr","id":1668778,"node_id":"MDQ6VXNlcjE2Njg3Nzg=","avatar_url":"https://avatars0.githubusercontent.com/u/1668778?v=4","gravatar_id":"","url":"https://api.github.com/users/marefr","html_url":"https://github.com/marefr","followers_url":"https://api.github.com/users/marefr/followers","following_url":"https://api.github.com/users/marefr/following{/other_user}","gists_url":"https://api.github.com/users/marefr/gists{/gist_id}","starred_url":"https://api.github.com/users/marefr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/marefr/subscriptions","organizations_url":"https://api.github.com/users/marefr/orgs","repos_url":"https://api.github.com/users/marefr/repos","events_url":"https://api.github.com/users/marefr/events{/privacy}","received_events_url":"https://api.github.com/users/marefr/received_events","type":"User","site_admin":false}],"milestone":{"url":"https://api.github.com/repos/grafana/grafana/milestones/99","html_url":"https://github.com/grafana/grafana/milestone/99","labels_url":"https://api.github.com/repos/grafana/grafana/milestones/99/labels","id":3399776,"node_id":"MDk6TWlsZXN0b25lMzM5OTc3Ng==","number":99,"title":"5.2.0-beta2","description":"","creator":{"login":"marefr","id":1668778,"node_id":"MDQ6VXNlcjE2Njg3Nzg=","avatar_url":"https://avatars0.githubusercontent.com/u/1668778?v=4","gravatar_id":"","url":"https://api.github.com/users/marefr","html_url":"https://github.com/marefr","followers_url":"https://api.github.com/users/marefr/followers","following_url":"https://api.github.com/users/marefr/following{/other_user}","gists_url":"https://api.github.com/users/marefr/gists{/gist_id}","starred_url":"https://api.github.com/users/marefr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/marefr/subscriptions","organizations_url":"https://api.github.com/users/marefr/orgs","repos_url":"https://api.github.com/users/marefr/repos","events_url":"https://api.github.com/users/marefr/events{/privacy}","received_events_url":"https://api.github.com/users/marefr/received_events","type":"User","site_admin":false},"open_issues":0,"closed_issues":42,"state":"closed","created_at":"2018-06-04T17:37:26Z","updated_at":"2018-06-20T14:24:04Z","due_on":"2018-06-20T07:00:00Z","closed_at":"2018-06-20T14:24:04Z"},"comments":13,"created_at":"2018-02-01T03:14:30Z","updated_at":"2018-06-28T12:59:03Z","closed_at":"2018-06-18T07:00:42Z","author_association":"NONE","body":"**My understanding of the authproxy whitelist setting**\r\n\r\nFirst, let’s make sure I understand how the whitelist setting is meant to work. For security purposes, if the whitelist is set, Grafana should only authenticate a user using the X-WEBAUTH-USER header if the request passed through the reverse proxy that's configured to handle the authentication. The whitelist setting is there to prevent Grafana from authenticating a user if the request did not pass through the reverse proxy that's configured to handle the authentication.\r\n\r\nIf my understanding is incorrect and whitelist is meant to whitelist a client ip, the documentation needs to be improved because it's not obvious that this is the goal.\r\n\r\n**My setup**\r\n\r\nGrafana version : 4.6.2\r\nOS : Debian Stretch\r\n\r\nMy setup uses HAProxy reverse proxy, then Apache reverse proxy then Grafana. HAProxy is on server A. Apache and Grafana are on server B. Apache is used to host an authentication frontend that authenticates the user into Grafana using Grafana authproxy.\r\n\r\nThe Grafana authentication works when I leave the whitelist config option in auth.proxy blank.\r\n\r\nThe Grafana authentication fails when I add the Apache server ip to the whitelist. I get the error “Request for user (usename) is not from the authentication proxy” from :\r\nhttps://github.com/grafana/grafana/blob/master/pkg/middleware/auth_proxy.go#L138\r\n\r\nThe expected result is that the authentication succeeds after the whitelist check.\r\n\r\n**Analysis**\r\n\r\nLooking at the code, the whitelist check is only done if there’s at least one ip set in the config file. It’s skipped if the whitelist config is blank. That works as intended.\r\n\r\nThe check compares the source ip to all the ips in the whitelist config. The check is successful if at least one the two ip are equals.\r\n\r\nI think there’s an issue with the code that gets the source ip. Let’s look at the code.\r\n\r\n```\r\nremoteAddrSplit := strings.Split(ctx.Req.RemoteAddr, \":\")\r\nsourceIP := remoteAddrSplit[0]\r\n```\r\n\r\nIf I’m not mistaken, ctx.Req.RemoteAddr is from :\r\nhttps://github.com/go-macaron/macaron/blob/master/context.go#L140\r\n\r\nThe code is :\r\n\r\n```\r\n// RemoteAddr returns more real IP address.\r\nfunc (ctx *Context) RemoteAddr() string {\r\n\taddr := ctx.Req.Header.Get(\"X-Real-IP\")\r\n\tif len(addr) == 0 {\r\n\t\taddr = ctx.Req.Header.Get(\"X-Forwarded-For\")\r\n\t\tif addr == \"\" {\r\n\t\t\taddr = ctx.Req.RemoteAddr\r\n\t\t\tif i := strings.LastIndex(addr, \":\"); i > -1 {\r\n\t\t\t\taddr = addr[:i]\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\treturn addr\r\n}\r\n```\r\n\r\nThe ip comes from X-Real-IP or X-Forwarded-For header. In my case it comes from X-Forwarded-For.\r\nI’ve got two reverse proxy in front of Grafana so X-Forwarded-For looks like :\r\n\"pc_connecting_to_grafana_ip, server_A_ip, server_B_ip\".\r\n\r\nThat’s what’s supposed to happen (https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For). The first ip is the client, the second the first proxy and the third the second proxy.\r\n\r\n`sourceIP` contains the result of indexing `remoteAddrSplit` at index 0, so it contains the client ip. It should instead use the last index to contain the last reverse proxy server ip.\r\n\r\nAlso, the client could spoof/manipulate the X-Forwarded-For and add any ip he wants to the beginning of the string.\r\n\r\nIf someone has access to your local network, they could just spoof the whole X-Forwarded-For header. In that case, it would be better to look at the connection ip to see if it's coming from the reverse proxy right in front of Grafana."},"comment":{"url":"https://api.github.com/repos/grafana/grafana/issues/comments/401025594","html_url":"https://github.com/grafana/grafana/issues/10707#issuecomment-401025594","issue_url":"https://api.github.com/repos/grafana/grafana/issues/10707","id":401025594,"node_id":"MDEyOklzc3VlQ29tbWVudDQwMTAyNTU5NA==","user":{"login":"hc4","id":17475270,"node_id":"MDQ6VXNlcjE3NDc1Mjcw","avatar_url":"https://avatars2.githubusercontent.com/u/17475270?v=4","gravatar_id":"","url":"https://api.github.com/users/hc4","html_url":"https://github.com/hc4","followers_url":"https://api.github.com/users/hc4/followers","following_url":"https://api.github.com/users/hc4/following{/other_user}","gists_url":"https://api.github.com/users/hc4/gists{/gist_id}","starred_url":"https://api.github.com/users/hc4/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/hc4/subscriptions","organizations_url":"https://api.github.com/users/hc4/orgs","repos_url":"https://api.github.com/users/hc4/repos","events_url":"https://api.github.com/users/hc4/events{/privacy}","received_events_url":"https://api.github.com/users/hc4/received_events","type":"User","site_admin":false},"created_at":"2018-06-28T12:59:03Z","updated_at":"2018-06-28T12:59:03Z","author_association":"CONTRIBUTOR","body":"> I'm under the impression that the IP address of squid proxy should be included at the end of X-Forwarded-For.\r\nWiki says you're wrong :)\r\n\r\nAnyway, you **must** check actual IP, from which request was received. Otherwise spoofer can format any X.forwarded-for tag and hack your server."}}
{"actor":{"display_login":"hc4"}}