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.")
@ -125,6 +125,7 @@ func RunProxy(f cmdutil.Factory, out io.Writer, cmd *cobra.Command) error {
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

@ -35,6 +35,7 @@ func TestAccept(t *testing.T) {
acceptPaths string acceptPaths string
rejectPaths string rejectPaths string
acceptHosts string acceptHosts string
rejectMethods string
path string path string
host string host string
method string method string
@ -45,6 +46,7 @@ func TestAccept(t *testing.T) {
acceptPaths: DefaultPathAcceptRE, acceptPaths: DefaultPathAcceptRE,
rejectPaths: DefaultPathRejectRE, rejectPaths: DefaultPathRejectRE,
acceptHosts: DefaultHostAcceptRE, acceptHosts: DefaultHostAcceptRE,
rejectMethods: DefaultMethodRejectRE,
path: "", path: "",
host: "127.0.0.1", host: "127.0.0.1",
method: "GET", method: "GET",
@ -54,6 +56,7 @@ func TestAccept(t *testing.T) {
acceptPaths: DefaultPathAcceptRE, acceptPaths: DefaultPathAcceptRE,
rejectPaths: DefaultPathRejectRE, rejectPaths: DefaultPathRejectRE,
acceptHosts: DefaultHostAcceptRE, acceptHosts: DefaultHostAcceptRE,
rejectMethods: DefaultMethodRejectRE,
path: "/api/v1/pods", path: "/api/v1/pods",
host: "127.0.0.1", host: "127.0.0.1",
method: "GET", method: "GET",
@ -63,6 +66,7 @@ func TestAccept(t *testing.T) {
acceptPaths: DefaultPathAcceptRE, acceptPaths: DefaultPathAcceptRE,
rejectPaths: DefaultPathRejectRE, rejectPaths: DefaultPathRejectRE,
acceptHosts: DefaultHostAcceptRE, acceptHosts: DefaultHostAcceptRE,
rejectMethods: DefaultMethodRejectRE,
path: "/api/v1/pods", path: "/api/v1/pods",
host: "localhost", host: "localhost",
method: "GET", method: "GET",
@ -72,6 +76,7 @@ func TestAccept(t *testing.T) {
acceptPaths: DefaultPathAcceptRE, acceptPaths: DefaultPathAcceptRE,
rejectPaths: DefaultPathRejectRE, rejectPaths: DefaultPathRejectRE,
acceptHosts: DefaultHostAcceptRE, acceptHosts: DefaultHostAcceptRE,
rejectMethods: DefaultMethodRejectRE,
path: "/api/v1/namespaces/default/pods/foo", path: "/api/v1/namespaces/default/pods/foo",
host: "localhost", host: "localhost",
method: "GET", method: "GET",
@ -81,6 +86,7 @@ func TestAccept(t *testing.T) {
acceptPaths: DefaultPathAcceptRE, acceptPaths: DefaultPathAcceptRE,
rejectPaths: DefaultPathRejectRE, rejectPaths: DefaultPathRejectRE,
acceptHosts: DefaultHostAcceptRE, acceptHosts: DefaultHostAcceptRE,
rejectMethods: DefaultMethodRejectRE,
path: "/api/v1/namespaces/default/pods/attachfoo", path: "/api/v1/namespaces/default/pods/attachfoo",
host: "localhost", host: "localhost",
method: "GET", method: "GET",
@ -90,6 +96,7 @@ func TestAccept(t *testing.T) {
acceptPaths: DefaultPathAcceptRE, acceptPaths: DefaultPathAcceptRE,
rejectPaths: DefaultPathRejectRE, rejectPaths: DefaultPathRejectRE,
acceptHosts: DefaultHostAcceptRE, acceptHosts: DefaultHostAcceptRE,
rejectMethods: DefaultMethodRejectRE,
path: "/api/v1/namespaces/default/pods/execfoo", path: "/api/v1/namespaces/default/pods/execfoo",
host: "localhost", host: "localhost",
method: "GET", method: "GET",
@ -99,6 +106,7 @@ func TestAccept(t *testing.T) {
acceptPaths: DefaultPathAcceptRE, acceptPaths: DefaultPathAcceptRE,
rejectPaths: DefaultPathRejectRE, rejectPaths: DefaultPathRejectRE,
acceptHosts: DefaultHostAcceptRE, acceptHosts: DefaultHostAcceptRE,
rejectMethods: DefaultMethodRejectRE,
path: "/api/v1/namespaces/default/pods/foo/exec", path: "/api/v1/namespaces/default/pods/foo/exec",
host: "127.0.0.1", host: "127.0.0.1",
method: "GET", method: "GET",
@ -108,6 +116,7 @@ func TestAccept(t *testing.T) {
acceptPaths: DefaultPathAcceptRE, acceptPaths: DefaultPathAcceptRE,
rejectPaths: DefaultPathRejectRE, rejectPaths: DefaultPathRejectRE,
acceptHosts: DefaultHostAcceptRE, acceptHosts: DefaultHostAcceptRE,
rejectMethods: DefaultMethodRejectRE,
path: "/api/v1/namespaces/default/pods/foo/attach", path: "/api/v1/namespaces/default/pods/foo/attach",
host: "127.0.0.1", host: "127.0.0.1",
method: "GET", method: "GET",
@ -117,6 +126,7 @@ func TestAccept(t *testing.T) {
acceptPaths: DefaultPathAcceptRE, acceptPaths: DefaultPathAcceptRE,
rejectPaths: DefaultPathRejectRE, rejectPaths: DefaultPathRejectRE,
acceptHosts: DefaultHostAcceptRE, acceptHosts: DefaultHostAcceptRE,
rejectMethods: DefaultMethodRejectRE,
path: "/api/v1/pods", path: "/api/v1/pods",
host: "evil.com", host: "evil.com",
method: "GET", method: "GET",
@ -126,6 +136,7 @@ func TestAccept(t *testing.T) {
acceptPaths: DefaultPathAcceptRE, acceptPaths: DefaultPathAcceptRE,
rejectPaths: DefaultPathRejectRE, rejectPaths: DefaultPathRejectRE,
acceptHosts: DefaultHostAcceptRE, acceptHosts: DefaultHostAcceptRE,
rejectMethods: DefaultMethodRejectRE,
path: "/api/v1/pods", path: "/api/v1/pods",
host: "localhost.evil.com", host: "localhost.evil.com",
method: "GET", method: "GET",
@ -135,6 +146,7 @@ func TestAccept(t *testing.T) {
acceptPaths: DefaultPathAcceptRE, acceptPaths: DefaultPathAcceptRE,
rejectPaths: DefaultPathRejectRE, rejectPaths: DefaultPathRejectRE,
acceptHosts: DefaultHostAcceptRE, acceptHosts: DefaultHostAcceptRE,
rejectMethods: DefaultMethodRejectRE,
path: "/api/v1/pods", path: "/api/v1/pods",
host: "127a0b0c1", host: "127a0b0c1",
method: "GET", method: "GET",
@ -144,6 +156,7 @@ func TestAccept(t *testing.T) {
acceptPaths: DefaultPathAcceptRE, acceptPaths: DefaultPathAcceptRE,
rejectPaths: DefaultPathRejectRE, rejectPaths: DefaultPathRejectRE,
acceptHosts: DefaultHostAcceptRE, acceptHosts: DefaultHostAcceptRE,
rejectMethods: DefaultMethodRejectRE,
path: "/ui", path: "/ui",
host: "localhost", host: "localhost",
method: "GET", method: "GET",
@ -153,6 +166,47 @@ func TestAccept(t *testing.T) {
acceptPaths: DefaultPathAcceptRE, acceptPaths: DefaultPathAcceptRE,
rejectPaths: DefaultPathRejectRE, rejectPaths: DefaultPathRejectRE,
acceptHosts: DefaultHostAcceptRE, acceptHosts: DefaultHostAcceptRE,
rejectMethods: DefaultMethodRejectRE,
path: "/api/v1/pods",
host: "localhost",
method: "POST",
expectAccept: true,
},
{
acceptPaths: DefaultPathAcceptRE,
rejectPaths: DefaultPathRejectRE,
acceptHosts: DefaultHostAcceptRE,
rejectMethods: DefaultMethodRejectRE,
path: "/api/v1/namespaces/default/pods/somepod",
host: "localhost",
method: "PUT",
expectAccept: true,
},
{
acceptPaths: DefaultPathAcceptRE,
rejectPaths: DefaultPathRejectRE,
acceptHosts: DefaultHostAcceptRE,
rejectMethods: DefaultMethodRejectRE,
path: "/api/v1/namespaces/default/pods/somepod",
host: "localhost",
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", path: "/api/v1/pods",
host: "localhost", host: "localhost",
method: "POST", method: "POST",
@ -162,6 +216,7 @@ func TestAccept(t *testing.T) {
acceptPaths: DefaultPathAcceptRE, acceptPaths: DefaultPathAcceptRE,
rejectPaths: DefaultPathRejectRE, rejectPaths: DefaultPathRejectRE,
acceptHosts: DefaultHostAcceptRE, acceptHosts: DefaultHostAcceptRE,
rejectMethods: "PUT",
path: "/api/v1/namespaces/default/pods/somepod", path: "/api/v1/namespaces/default/pods/somepod",
host: "localhost", host: "localhost",
method: "PUT", method: "PUT",
@ -171,18 +226,39 @@ func TestAccept(t *testing.T) {
acceptPaths: DefaultPathAcceptRE, acceptPaths: DefaultPathAcceptRE,
rejectPaths: DefaultPathRejectRE, rejectPaths: DefaultPathRejectRE,
acceptHosts: DefaultHostAcceptRE, acceptHosts: DefaultHostAcceptRE,
rejectMethods: "PATCH",
path: "/api/v1/namespaces/default/pods/somepod", path: "/api/v1/namespaces/default/pods/somepod",
host: "localhost", host: "localhost",
method: "PATCH", method: "PATCH",
expectAccept: false, 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 {
filter := &FilterServer{ filter := &FilterServer{
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 {