allow kubectl proxy to handle specified reject methods and default to allow all

This commit is contained in:
Suyog Barve 2017-04-25 02:23:30 -05:00
parent 0421dbfee6
commit f3a7ac4311
3 changed files with 195 additions and 118 deletions

View File

@ -81,7 +81,7 @@ func NewCmdProxy(f cmdutil.Factory, out io.Writer) *cobra.Command {
cmd.Flags().String("accept-paths", kubectl.DefaultPathAcceptRE, "Regular expression for paths that the proxy should accept.") cmd.Flags().String("accept-paths", kubectl.DefaultPathAcceptRE, "Regular expression for paths that the proxy should accept.")
cmd.Flags().String("reject-paths", kubectl.DefaultPathRejectRE, "Regular expression for paths that the proxy should reject. Paths specified here will be rejected even accepted by --accept-paths.") cmd.Flags().String("reject-paths", kubectl.DefaultPathRejectRE, "Regular expression for paths that the proxy should reject. Paths specified here will be rejected even accepted by --accept-paths.")
cmd.Flags().String("accept-hosts", kubectl.DefaultHostAcceptRE, "Regular expression for hosts that the proxy should accept.") cmd.Flags().String("accept-hosts", kubectl.DefaultHostAcceptRE, "Regular expression for hosts that the proxy should accept.")
cmd.Flags().String("reject-methods", kubectl.DefaultMethodRejectRE, "Regular expression for HTTP methods that the proxy should reject.") cmd.Flags().String("reject-methods", kubectl.DefaultMethodRejectRE, "Regular expression for HTTP methods that the proxy should reject (example --reject-methods='POST,PUT,PATCH'). ")
cmd.Flags().IntP("port", "p", defaultPort, "The port on which to run the proxy. Set to 0 to pick a random port.") cmd.Flags().IntP("port", "p", defaultPort, "The port on which to run the proxy. Set to 0 to pick a random port.")
cmd.Flags().StringP("address", "", "127.0.0.1", "The IP address on which to serve on.") cmd.Flags().StringP("address", "", "127.0.0.1", "The IP address on which to serve on.")
cmd.Flags().Bool("disable-filter", false, "If true, disable request filtering in the proxy. This is dangerous, and can leave you vulnerable to XSRF attacks, when used with an accessible port.") cmd.Flags().Bool("disable-filter", false, "If true, disable request filtering in the proxy. This is dangerous, and can leave you vulnerable to XSRF attacks, when used with an accessible port.")
@ -122,9 +122,10 @@ func RunProxy(f cmdutil.Factory, out io.Writer, cmd *cobra.Command) error {
apiProxyPrefix += "/" apiProxyPrefix += "/"
} }
filter := &kubectl.FilterServer{ filter := &kubectl.FilterServer{
AcceptPaths: kubectl.MakeRegexpArrayOrDie(cmdutil.GetFlagString(cmd, "accept-paths")), AcceptPaths: kubectl.MakeRegexpArrayOrDie(cmdutil.GetFlagString(cmd, "accept-paths")),
RejectPaths: kubectl.MakeRegexpArrayOrDie(cmdutil.GetFlagString(cmd, "reject-paths")), RejectPaths: kubectl.MakeRegexpArrayOrDie(cmdutil.GetFlagString(cmd, "reject-paths")),
AcceptHosts: kubectl.MakeRegexpArrayOrDie(cmdutil.GetFlagString(cmd, "accept-hosts")), AcceptHosts: kubectl.MakeRegexpArrayOrDie(cmdutil.GetFlagString(cmd, "accept-hosts")),
RejectMethods: kubectl.MakeRegexpArrayOrDie(cmdutil.GetFlagString(cmd, "reject-methods")),
} }
if cmdutil.GetFlagBool(cmd, "disable-filter") { if cmdutil.GetFlagBool(cmd, "disable-filter") {
if path == "" { if path == "" {

View File

@ -36,7 +36,7 @@ const (
DefaultHostAcceptRE = "^localhost$,^127\\.0\\.0\\.1$,^\\[::1\\]$" DefaultHostAcceptRE = "^localhost$,^127\\.0\\.0\\.1$,^\\[::1\\]$"
DefaultPathAcceptRE = "^.*" DefaultPathAcceptRE = "^.*"
DefaultPathRejectRE = "^/api/.*/pods/.*/exec,^/api/.*/pods/.*/attach" DefaultPathRejectRE = "^/api/.*/pods/.*/exec,^/api/.*/pods/.*/attach"
DefaultMethodRejectRE = "POST,PUT,PATCH" DefaultMethodRejectRE = "^$"
) )
var ( var (

View File

@ -32,149 +32,225 @@ import (
func TestAccept(t *testing.T) { func TestAccept(t *testing.T) {
tests := []struct { tests := []struct {
acceptPaths string acceptPaths string
rejectPaths string rejectPaths string
acceptHosts string acceptHosts string
path string rejectMethods string
host string path string
method string host string
expectAccept bool method string
expectAccept bool
}{ }{
{ {
acceptPaths: DefaultPathAcceptRE, acceptPaths: DefaultPathAcceptRE,
rejectPaths: DefaultPathRejectRE, rejectPaths: DefaultPathRejectRE,
acceptHosts: DefaultHostAcceptRE, acceptHosts: DefaultHostAcceptRE,
path: "", rejectMethods: DefaultMethodRejectRE,
host: "127.0.0.1", path: "",
method: "GET", host: "127.0.0.1",
expectAccept: true, method: "GET",
expectAccept: true,
}, },
{ {
acceptPaths: DefaultPathAcceptRE, acceptPaths: DefaultPathAcceptRE,
rejectPaths: DefaultPathRejectRE, rejectPaths: DefaultPathRejectRE,
acceptHosts: DefaultHostAcceptRE, acceptHosts: DefaultHostAcceptRE,
path: "/api/v1/pods", rejectMethods: DefaultMethodRejectRE,
host: "127.0.0.1", path: "/api/v1/pods",
method: "GET", host: "127.0.0.1",
expectAccept: true, method: "GET",
expectAccept: true,
}, },
{ {
acceptPaths: DefaultPathAcceptRE, acceptPaths: DefaultPathAcceptRE,
rejectPaths: DefaultPathRejectRE, rejectPaths: DefaultPathRejectRE,
acceptHosts: DefaultHostAcceptRE, acceptHosts: DefaultHostAcceptRE,
path: "/api/v1/pods", rejectMethods: DefaultMethodRejectRE,
host: "localhost", path: "/api/v1/pods",
method: "GET", host: "localhost",
expectAccept: true, method: "GET",
expectAccept: true,
}, },
{ {
acceptPaths: DefaultPathAcceptRE, acceptPaths: DefaultPathAcceptRE,
rejectPaths: DefaultPathRejectRE, rejectPaths: DefaultPathRejectRE,
acceptHosts: DefaultHostAcceptRE, acceptHosts: DefaultHostAcceptRE,
path: "/api/v1/namespaces/default/pods/foo", rejectMethods: DefaultMethodRejectRE,
host: "localhost", path: "/api/v1/namespaces/default/pods/foo",
method: "GET", host: "localhost",
expectAccept: true, method: "GET",
expectAccept: true,
}, },
{ {
acceptPaths: DefaultPathAcceptRE, acceptPaths: DefaultPathAcceptRE,
rejectPaths: DefaultPathRejectRE, rejectPaths: DefaultPathRejectRE,
acceptHosts: DefaultHostAcceptRE, acceptHosts: DefaultHostAcceptRE,
path: "/api/v1/namespaces/default/pods/attachfoo", rejectMethods: DefaultMethodRejectRE,
host: "localhost", path: "/api/v1/namespaces/default/pods/attachfoo",
method: "GET", host: "localhost",
expectAccept: true, method: "GET",
expectAccept: true,
}, },
{ {
acceptPaths: DefaultPathAcceptRE, acceptPaths: DefaultPathAcceptRE,
rejectPaths: DefaultPathRejectRE, rejectPaths: DefaultPathRejectRE,
acceptHosts: DefaultHostAcceptRE, acceptHosts: DefaultHostAcceptRE,
path: "/api/v1/namespaces/default/pods/execfoo", rejectMethods: DefaultMethodRejectRE,
host: "localhost", path: "/api/v1/namespaces/default/pods/execfoo",
method: "GET", host: "localhost",
expectAccept: true, method: "GET",
expectAccept: true,
}, },
{ {
acceptPaths: DefaultPathAcceptRE, acceptPaths: DefaultPathAcceptRE,
rejectPaths: DefaultPathRejectRE, rejectPaths: DefaultPathRejectRE,
acceptHosts: DefaultHostAcceptRE, acceptHosts: DefaultHostAcceptRE,
path: "/api/v1/namespaces/default/pods/foo/exec", rejectMethods: DefaultMethodRejectRE,
host: "127.0.0.1", path: "/api/v1/namespaces/default/pods/foo/exec",
method: "GET", host: "127.0.0.1",
expectAccept: false, method: "GET",
expectAccept: false,
}, },
{ {
acceptPaths: DefaultPathAcceptRE, acceptPaths: DefaultPathAcceptRE,
rejectPaths: DefaultPathRejectRE, rejectPaths: DefaultPathRejectRE,
acceptHosts: DefaultHostAcceptRE, acceptHosts: DefaultHostAcceptRE,
path: "/api/v1/namespaces/default/pods/foo/attach", rejectMethods: DefaultMethodRejectRE,
host: "127.0.0.1", path: "/api/v1/namespaces/default/pods/foo/attach",
method: "GET", host: "127.0.0.1",
expectAccept: false, method: "GET",
expectAccept: false,
}, },
{ {
acceptPaths: DefaultPathAcceptRE, acceptPaths: DefaultPathAcceptRE,
rejectPaths: DefaultPathRejectRE, rejectPaths: DefaultPathRejectRE,
acceptHosts: DefaultHostAcceptRE, acceptHosts: DefaultHostAcceptRE,
path: "/api/v1/pods", rejectMethods: DefaultMethodRejectRE,
host: "evil.com", path: "/api/v1/pods",
method: "GET", host: "evil.com",
expectAccept: false, method: "GET",
expectAccept: false,
}, },
{ {
acceptPaths: DefaultPathAcceptRE, acceptPaths: DefaultPathAcceptRE,
rejectPaths: DefaultPathRejectRE, rejectPaths: DefaultPathRejectRE,
acceptHosts: DefaultHostAcceptRE, acceptHosts: DefaultHostAcceptRE,
path: "/api/v1/pods", rejectMethods: DefaultMethodRejectRE,
host: "localhost.evil.com", path: "/api/v1/pods",
method: "GET", host: "localhost.evil.com",
expectAccept: false, method: "GET",
expectAccept: false,
}, },
{ {
acceptPaths: DefaultPathAcceptRE, acceptPaths: DefaultPathAcceptRE,
rejectPaths: DefaultPathRejectRE, rejectPaths: DefaultPathRejectRE,
acceptHosts: DefaultHostAcceptRE, acceptHosts: DefaultHostAcceptRE,
path: "/api/v1/pods", rejectMethods: DefaultMethodRejectRE,
host: "127a0b0c1", path: "/api/v1/pods",
method: "GET", host: "127a0b0c1",
expectAccept: false, method: "GET",
expectAccept: false,
}, },
{ {
acceptPaths: DefaultPathAcceptRE, acceptPaths: DefaultPathAcceptRE,
rejectPaths: DefaultPathRejectRE, rejectPaths: DefaultPathRejectRE,
acceptHosts: DefaultHostAcceptRE, acceptHosts: DefaultHostAcceptRE,
path: "/ui", rejectMethods: DefaultMethodRejectRE,
host: "localhost", path: "/ui",
method: "GET", host: "localhost",
expectAccept: true, method: "GET",
expectAccept: true,
}, },
{ {
acceptPaths: DefaultPathAcceptRE, acceptPaths: DefaultPathAcceptRE,
rejectPaths: DefaultPathRejectRE, rejectPaths: DefaultPathRejectRE,
acceptHosts: DefaultHostAcceptRE, acceptHosts: DefaultHostAcceptRE,
path: "/api/v1/pods", rejectMethods: DefaultMethodRejectRE,
host: "localhost", path: "/api/v1/pods",
method: "POST", host: "localhost",
expectAccept: false, method: "POST",
expectAccept: true,
}, },
{ {
acceptPaths: DefaultPathAcceptRE, acceptPaths: DefaultPathAcceptRE,
rejectPaths: DefaultPathRejectRE, rejectPaths: DefaultPathRejectRE,
acceptHosts: DefaultHostAcceptRE, acceptHosts: DefaultHostAcceptRE,
path: "/api/v1/namespaces/default/pods/somepod", rejectMethods: DefaultMethodRejectRE,
host: "localhost", path: "/api/v1/namespaces/default/pods/somepod",
method: "PUT", host: "localhost",
expectAccept: false, method: "PUT",
expectAccept: true,
}, },
{ {
acceptPaths: DefaultPathAcceptRE, acceptPaths: DefaultPathAcceptRE,
rejectPaths: DefaultPathRejectRE, rejectPaths: DefaultPathRejectRE,
acceptHosts: DefaultHostAcceptRE, acceptHosts: DefaultHostAcceptRE,
path: "/api/v1/namespaces/default/pods/somepod", rejectMethods: DefaultMethodRejectRE,
host: "localhost", path: "/api/v1/namespaces/default/pods/somepod",
method: "PATCH", host: "localhost",
expectAccept: false, method: "PATCH",
expectAccept: true,
},
{
acceptPaths: DefaultPathAcceptRE,
rejectPaths: DefaultPathRejectRE,
acceptHosts: DefaultHostAcceptRE,
rejectMethods: "GET",
path: "/api/v1/pods",
host: "127.0.0.1",
method: "GET",
expectAccept: false,
},
{
acceptPaths: DefaultPathAcceptRE,
rejectPaths: DefaultPathRejectRE,
acceptHosts: DefaultHostAcceptRE,
rejectMethods: "POST",
path: "/api/v1/pods",
host: "localhost",
method: "POST",
expectAccept: false,
},
{
acceptPaths: DefaultPathAcceptRE,
rejectPaths: DefaultPathRejectRE,
acceptHosts: DefaultHostAcceptRE,
rejectMethods: "PUT",
path: "/api/v1/namespaces/default/pods/somepod",
host: "localhost",
method: "PUT",
expectAccept: false,
},
{
acceptPaths: DefaultPathAcceptRE,
rejectPaths: DefaultPathRejectRE,
acceptHosts: DefaultHostAcceptRE,
rejectMethods: "PATCH",
path: "/api/v1/namespaces/default/pods/somepod",
host: "localhost",
method: "PATCH",
expectAccept: false,
},
{
acceptPaths: DefaultPathAcceptRE,
rejectPaths: DefaultPathRejectRE,
acceptHosts: DefaultHostAcceptRE,
rejectMethods: "POST,PUT,PATCH",
path: "/api/v1/namespaces/default/pods/somepod",
host: "localhost",
method: "PATCH",
expectAccept: false,
},
{
acceptPaths: DefaultPathAcceptRE,
rejectPaths: DefaultPathRejectRE,
acceptHosts: DefaultHostAcceptRE,
rejectMethods: "POST,PUT,PATCH",
path: "/api/v1/namespaces/default/pods/somepod",
host: "localhost",
method: "PUT",
expectAccept: false,
}, },
} }
for _, test := range tests { for _, test := range tests {
@ -182,7 +258,7 @@ func TestAccept(t *testing.T) {
AcceptPaths: MakeRegexpArrayOrDie(test.acceptPaths), AcceptPaths: MakeRegexpArrayOrDie(test.acceptPaths),
RejectPaths: MakeRegexpArrayOrDie(test.rejectPaths), RejectPaths: MakeRegexpArrayOrDie(test.rejectPaths),
AcceptHosts: MakeRegexpArrayOrDie(test.acceptHosts), AcceptHosts: MakeRegexpArrayOrDie(test.acceptHosts),
RejectMethods: MakeRegexpArrayOrDie(DefaultMethodRejectRE), RejectMethods: MakeRegexpArrayOrDie(test.rejectMethods),
} }
accept := filter.accept(test.method, test.path, test.host) accept := filter.accept(test.method, test.path, test.host)
if accept != test.expectAccept { if accept != test.expectAccept {