-
Notifications
You must be signed in to change notification settings - Fork 2.9k
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
nsqadmin: X-Forwarded-User based ACL #914
nsqadmin: X-Forwarded-User based ACL #914
Conversation
Is there an assumption here that the proxy is performing some authentication before passing on the username? If so there may be a security hole where an end-user passes in a (non-standard) (It's also possible I'm misunderstanding the auth mechanism use case). |
Yes, and should be documented as such. This approach is only useful if you can trust your proxy and internal network, e.g. |
apps/nsqadmin/main.go
Outdated
@@ -55,6 +56,7 @@ var ( | |||
func init() { | |||
flagSet.Var(&nsqlookupdHTTPAddresses, "lookupd-http-address", "lookupd HTTP address (may be given multiple times)") | |||
flagSet.Var(&nsqdHTTPAddresses, "nsqd-http-address", "nsqd HTTP address (may be given multiple times)") | |||
flagSet.Var(&allowAuthorizedUsers, "authorized-user", "Authorized Users (for performing admin actions); Any user will have admin privileges if this field is empty.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe admin-user
would be a more straightforward name for this
27d590f
to
09c03a0
Compare
nsqadmin/http.go
Outdated
@@ -755,6 +784,21 @@ func (s *httpServer) doConfig(w http.ResponseWriter, req *http.Request, ps httpr | |||
return v, nil | |||
} | |||
|
|||
func (s *httpServer) authorizedAdminRequest(req *http.Request) (bool) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we call this fun isAuthorizedAdminRequest
?
nsqadmin/http.go
Outdated
adminUsers := s.ctx.nsqadmin.getOpts().AdminUsers | ||
if len(adminUsers) == 0 { | ||
return true | ||
} else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
don't need this else
since the above block returns
nsqadmin/http.go
Outdated
if len(adminUsers) == 0 { | ||
return true | ||
} else { | ||
user := req.Header.Get("X-FORWARDED-USER") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since we're in here, let's make this header user-configurable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
default to X-Forwarded-User
nsqadmin/static/js/main.js
Outdated
@@ -14,8 +14,18 @@ require('./lib/ajax_setup'); | |||
require('./lib/handlebars_helpers'); | |||
|
|||
var start = function() { | |||
new AppView(); | |||
Router.start(); | |||
$.ajax({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there should be a way for us to inject this data into the template rather than create a new endpoint and have to perform this AJAX request
nsqadmin/http.go
Outdated
@@ -100,6 +99,8 @@ func NewHTTPServer(ctx *Context) *httpServer { | |||
router.Handle("POST", "/api/topics", http_api.Decorate(s.createTopicChannelHandler, log, http_api.V1)) | |||
router.Handle("POST", "/api/topics/:topic", http_api.Decorate(s.topicActionHandler, log, http_api.V1)) | |||
router.Handle("POST", "/api/topics/:topic/:channel", http_api.Decorate(s.channelActionHandler, log, http_api.V1)) | |||
|
|||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👮 whitespace police, let's drop this change
nsqadmin/http.go
Outdated
@@ -73,7 +73,6 @@ func NewHTTPServer(ctx *Context) *httpServer { | |||
} | |||
|
|||
router.Handle("GET", "/ping", http_api.Decorate(s.pingHandler, log, http_api.PlainText)) | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👮 whitespace police, let's drop this change
e6a6f01
to
e58afcf
Compare
apps/nsqadmin/main.go
Outdated
@@ -47,6 +47,8 @@ var ( | |||
httpClientTLSKey = flagSet.String("http-client-tls-key", "", "path to key file for the HTTP client") | |||
|
|||
allowConfigFromCIDR = flagSet.String("allow-config-from-cidr", "127.0.0.1/8", "A CIDR from which to allow HTTP requests to the /config endpoint") | |||
aclHttpHeader = flagSet.String("acl-http-header", "X-Forwarded-User", "HTTP header to check for authenticated users (default: X-Forwarded-User)") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think you have to note the default in the help string yourself, if you specify the default in the flag declaration as you have done. For example, allow-config-from-cidr
is described like so in nsqadmin --help
:
-allow-config-from-cidr string
A CIDR from which to allow HTTP requests to the /config endpoint (default "127.0.0.1/8")
(We only manually note the default in help strings when we cannot set the default in the flag declaration.)
EDIT: set -> cannot set
This is looking pretty good to me, thanks for being so responsive to review comments! |
@chen-anders anything else you want to do here? If not, can you squash this down to one commit and prefix it with |
02e04f6
to
fb5103b
Compare
@mreiferson Complete. |
fb5103b
to
bc39218
Compare
Pushed a commit to update |
👍 |
This PR introduces a small access-control-list mechanism via the
X-Forwarded-User
HTTP headers.NSQAdmin can be started with one or more
-authorized-user=<user>
flags and NSQAdmin will be in a view-only mode for non-admin users. Only authorized admin users can perform administrative actions (e.g. pause/unpause/create/delete topics or channels).If no
-authorized-user=<user>
is specified, we default to allowing any user to perform administrative actions.This approach assumes that there is some authenticating proxy in front of nsqadmin that will strip out incoming
X-Forwarded-User
headers.