From 7e2dcb61bf6d671c6d6768c19ea6925e0fcbe848 Mon Sep 17 00:00:00 2001 From: James Phillips Date: Thu, 30 Mar 2017 09:25:12 -0700 Subject: [PATCH] Changes `disable_remote_exec` default to true so remote exec is opt-in. --- command/agent/config.go | 7 +++--- command/agent/config_test.go | 15 +++++++---- command/agent/user_event.go | 2 +- command/exec_test.go | 25 ++++++++++++++----- .../source/docs/agent/options.html.markdown | 3 ++- .../docs/upgrade-specific.html.markdown | 8 +++++- 6 files changed, 43 insertions(+), 17 deletions(-) diff --git a/command/agent/config.go b/command/agent/config.go index 74a60a03537c..41c60f475005 100644 --- a/command/agent/config.go +++ b/command/agent/config.go @@ -640,7 +640,7 @@ type Config struct { // DisableRemoteExec is used to turn off the remote execution // feature. This is for security to prevent unknown scripts from running. - DisableRemoteExec bool `mapstructure:"disable_remote_exec"` + DisableRemoteExec *bool `mapstructure:"disable_remote_exec"` // DisableUpdateCheck is used to turn off the automatic update and // security bulletin checking. @@ -828,6 +828,7 @@ func DefaultConfig() *Config { ACLDefaultPolicy: "allow", ACLDisabledTTL: 120 * time.Second, ACLEnforceVersion8: Bool(true), + DisableRemoteExec: Bool(true), RetryInterval: 30 * time.Second, RetryIntervalWan: 30 * time.Second, @@ -1696,8 +1697,8 @@ func MergeConfig(a, b *Config) *Config { if len(b.WatchPlans) != 0 { result.WatchPlans = append(result.WatchPlans, b.WatchPlans...) } - if b.DisableRemoteExec { - result.DisableRemoteExec = true + if b.DisableRemoteExec != nil { + result.DisableRemoteExec = b.DisableRemoteExec } if b.DisableUpdateCheck { result.DisableUpdateCheck = true diff --git a/command/agent/config_test.go b/command/agent/config_test.go index 1b062b12cd80..c0063e3d3d9c 100644 --- a/command/agent/config_test.go +++ b/command/agent/config_test.go @@ -783,14 +783,19 @@ func TestDecodeConfig(t *testing.T) { t.Fatalf("bad: %#v", config) } - // remote exec - input = `{"disable_remote_exec": true}` + // Remote exec is disabled by default. + config = DefaultConfig() + if *config.DisableRemoteExec != true { + t.Fatalf("bad: %#v", config) + } + + // Test re-enabling remote exec. + input = `{"disable_remote_exec": false}` config, err = DecodeConfig(bytes.NewReader([]byte(input))) if err != nil { t.Fatalf("err: %s", err) } - - if !config.DisableRemoteExec { + if *config.DisableRemoteExec != false { t.Fatalf("bad: %#v", config) } @@ -1723,7 +1728,7 @@ func TestMergeConfig(t *testing.T) { "handler": "foobar", }, }, - DisableRemoteExec: true, + DisableRemoteExec: Bool(true), Telemetry: Telemetry{ StatsiteAddr: "127.0.0.1:7250", StatsitePrefix: "stats_prefix", diff --git a/command/agent/user_event.go b/command/agent/user_event.go index bd41387dd180..63265e71ab44 100644 --- a/command/agent/user_event.go +++ b/command/agent/user_event.go @@ -209,7 +209,7 @@ func (a *Agent) ingestUserEvent(msg *UserEvent) { // Special handling for internal events switch msg.Name { case remoteExecName: - if a.config.DisableRemoteExec { + if *a.config.DisableRemoteExec { a.logger.Printf("[INFO] agent: ignoring remote exec event (%s), disabled.", msg.ID) } else { go a.handleRemoteExec(msg) diff --git a/command/exec_test.go b/command/exec_test.go index d21681d62b72..509be0251dc7 100644 --- a/command/exec_test.go +++ b/command/exec_test.go @@ -28,7 +28,9 @@ func TestExecCommand_implements(t *testing.T) { } func TestExecCommandRun(t *testing.T) { - a1 := testAgent(t) + a1 := testAgentWithConfig(t, func(c *agent.Config) { + c.DisableRemoteExec = agent.Bool(false) + }) defer a1.Shutdown() waitForLeader(t, a1.httpAddr) @@ -46,11 +48,14 @@ func TestExecCommandRun(t *testing.T) { } func TestExecCommandRun_CrossDC(t *testing.T) { - a1 := testAgent(t) + a1 := testAgentWithConfig(t, func(c *agent.Config) { + c.DisableRemoteExec = agent.Bool(false) + }) defer a1.Shutdown() a2 := testAgentWithConfig(t, func(c *agent.Config) { c.Datacenter = "dc2" + c.DisableRemoteExec = agent.Bool(false) }) defer a2.Shutdown() @@ -136,7 +141,9 @@ func TestExecCommand_Validate(t *testing.T) { } func TestExecCommand_Sessions(t *testing.T) { - a1 := testAgent(t) + a1 := testAgentWithConfig(t, func(c *agent.Config) { + c.DisableRemoteExec = agent.Bool(false) + }) defer a1.Shutdown() waitForLeader(t, a1.httpAddr) @@ -177,7 +184,9 @@ func TestExecCommand_Sessions(t *testing.T) { } func TestExecCommand_Sessions_Foreign(t *testing.T) { - a1 := testAgent(t) + a1 := testAgentWithConfig(t, func(c *agent.Config) { + c.DisableRemoteExec = agent.Bool(false) + }) defer a1.Shutdown() waitForLeader(t, a1.httpAddr) @@ -228,7 +237,9 @@ func TestExecCommand_Sessions_Foreign(t *testing.T) { } func TestExecCommand_UploadDestroy(t *testing.T) { - a1 := testAgent(t) + a1 := testAgentWithConfig(t, func(c *agent.Config) { + c.DisableRemoteExec = agent.Bool(false) + }) defer a1.Shutdown() waitForLeader(t, a1.httpAddr) @@ -285,7 +296,9 @@ func TestExecCommand_UploadDestroy(t *testing.T) { } func TestExecCommand_StreamResults(t *testing.T) { - a1 := testAgent(t) + a1 := testAgentWithConfig(t, func(c *agent.Config) { + c.DisableRemoteExec = agent.Bool(false) + }) defer a1.Shutdown() waitForLeader(t, a1.httpAddr) diff --git a/website/source/docs/agent/options.html.markdown b/website/source/docs/agent/options.html.markdown index 81029c85bda5..d12f97f42834 100644 --- a/website/source/docs/agent/options.html.markdown +++ b/website/source/docs/agent/options.html.markdown @@ -632,7 +632,8 @@ Consul will not enable TLS for the HTTP API unless the `https` port has been ass * `disable_remote_exec` Disables support for remote execution. When set to true, the agent will ignore any incoming - remote exec requests. + remote exec requests. In versions of Consul prior to 0.8, this defaulted to false. In Consul + 0.8 the default was changed to true, to make remote exec opt-in instead of opt-out. * `disable_update_check` Disables automatic checking for security bulletins and new version releases. diff --git a/website/source/docs/upgrade-specific.html.markdown b/website/source/docs/upgrade-specific.html.markdown index 5bb752d70d7e..0da7f5264431 100644 --- a/website/source/docs/upgrade-specific.html.markdown +++ b/website/source/docs/upgrade-specific.html.markdown @@ -37,7 +37,13 @@ and update any scripts that passed a custom `-rpc-addr` to the following command The [`acl_enforce_version_8`](/docs/agent/options.html#acl_enforce_version_8) configuration now defaults to `true` to enable [full version 8 ACL support](/docs/internals/acl.html#version_8_acls) by default. If you are upgrading an existing cluster with ACLs enabled, you will need to set this to `false` during the upgrade on **both Consul agents and Consul servers**. Version 8 ACLs were also changed so that [`acl_datacenter`](/docs/agent/options.html#acl_datacenter) must be set on agents in order to enable the agent-side enforcement of ACLs. This makes for a smoother experience in clusters where ACLs aren't enabled at all, but where the agents would have to wait to contact a Consul server before learning that. -#### Raft Protocol Version Compatibility +#### Remote Exec Is Now Opt-In + +The default for [`disable_remote_exec`](/docs/agent/options.html#disable_remote_exec) was +changed to "true", so now operators need to opt-in to having agents support running +commands remotely via [`consul exec`](/docs/commands/exec.html). + +#### Raft Protocol Version Compatibility When upgrading to Consul 0.8.0 from a version lower than 0.7.0, users will need to set the [`-raft-protocol`](/docs/agent/options.html#_raft_protocol) option to 1 in