From 821a787d142e244ea145e2ef1f149e24ce03a549 Mon Sep 17 00:00:00 2001 From: Ashish Dhingra <67916761+ashishdhingra@users.noreply.github.com> Date: Thu, 20 Jun 2024 10:13:53 -0700 Subject: [PATCH] Adds feature to disable IMDSv1 by default for new Elastic BeanStalk environments. Also adds support for new command line parameter --disable-imds-v1 useful for updating existing environments. --- .../Amazon.ElasticBeanstalk.Tools.csproj | 2 +- .../Commands/CommandProperties.cs | 3 ++ .../Commands/DeployEnvironmentCommand.cs | 51 +++++++++++++++++-- .../EBDefinedCommandOptions.cs | 9 ++++ 4 files changed, 59 insertions(+), 6 deletions(-) diff --git a/src/Amazon.ElasticBeanstalk.Tools/Amazon.ElasticBeanstalk.Tools.csproj b/src/Amazon.ElasticBeanstalk.Tools/Amazon.ElasticBeanstalk.Tools.csproj index 3fd12ec..439724a 100644 --- a/src/Amazon.ElasticBeanstalk.Tools/Amazon.ElasticBeanstalk.Tools.csproj +++ b/src/Amazon.ElasticBeanstalk.Tools/Amazon.ElasticBeanstalk.Tools.csproj @@ -10,7 +10,7 @@ true dotnet-eb true - 4.3.4 + 4.4.0 dotnet-eb Amazon Web Services Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. diff --git a/src/Amazon.ElasticBeanstalk.Tools/Commands/CommandProperties.cs b/src/Amazon.ElasticBeanstalk.Tools/Commands/CommandProperties.cs index 8e864b2..6e314e5 100644 --- a/src/Amazon.ElasticBeanstalk.Tools/Commands/CommandProperties.cs +++ b/src/Amazon.ElasticBeanstalk.Tools/Commands/CommandProperties.cs @@ -19,6 +19,7 @@ public class DeployEnvironmentProperties public string IISWebSite { get; set; } public bool? WaitForUpdate { get; set; } public bool? EnableXRay { get; set; } + public bool? DisableIMDSv1 { get; set; } public Dictionary Tags { get; set; } public Dictionary AdditionalOptions { get; set; } @@ -92,6 +93,8 @@ internal void ParseCommandArguments(CommandOptions values) this.LoadBalancerType = tuple.Item2.StringValue; if ((tuple = values.FindCommandOption(EBDefinedCommandOptions.ARGUMENT_ENABLE_STICKY_SESSIONS.Switch)) != null) this.EnableStickySessions = tuple.Item2.BoolValue; + if ((tuple = values.FindCommandOption(EBDefinedCommandOptions.ARGUMENT_DISABLE_IMDS_V1.Switch)) != null) + this.DisableIMDSv1 = tuple.Item2.BoolValue; if ((tuple = values.FindCommandOption(EBDefinedCommandOptions.ARGUMENT_PROXY_SERVER.Switch)) != null) this.ProxyServer = tuple.Item2.StringValue; diff --git a/src/Amazon.ElasticBeanstalk.Tools/Commands/DeployEnvironmentCommand.cs b/src/Amazon.ElasticBeanstalk.Tools/Commands/DeployEnvironmentCommand.cs index f9539ba..7840c57 100644 --- a/src/Amazon.ElasticBeanstalk.Tools/Commands/DeployEnvironmentCommand.cs +++ b/src/Amazon.ElasticBeanstalk.Tools/Commands/DeployEnvironmentCommand.cs @@ -40,6 +40,7 @@ public class DeployEnvironmentCommand : EBBaseCommand EBDefinedCommandOptions.ARGUMENT_INSTANCE_TYPE, EBDefinedCommandOptions.ARGUMENT_HEALTH_CHECK_URL, EBDefinedCommandOptions.ARGUMENT_ENABLE_XRAY, + EBDefinedCommandOptions.ARGUMENT_DISABLE_IMDS_V1, EBDefinedCommandOptions.ARGUMENT_ENHANCED_HEALTH_TYPE, EBDefinedCommandOptions.ARGUMENT_INSTANCE_PROFILE, EBDefinedCommandOptions.ARGUMENT_SERVICE_ROLE, @@ -59,6 +60,9 @@ public class DeployEnvironmentCommand : EBBaseCommand const string OPTIONS_NAME_PROXY_SERVER = "ProxyServer"; const string OPTIONS_NAME_APPLICATION_PORT = "PORT"; + const string OPTIONS_NAMESPACE_DISABLE_IMDS_V1 = "aws:autoscaling:launchconfiguration"; + const string OPTIONS_NAME_DISABLE_IMDS_V1 = "DisableIMDSv1"; + public string Package { get; set; } public DeployEnvironmentProperties DeployEnvironmentOptions { get; } = new DeployEnvironmentProperties(); @@ -415,7 +419,14 @@ private async Task CreateEnvironment(string application, string environm Value = loadBalancerType }); } - + + // For new environments, disable IMDSv1 by default (unless explicitly enabled in additional options). + createRequest.OptionSettings.Add(new ConfigurationOptionSetting() + { + Namespace = OPTIONS_NAMESPACE_DISABLE_IMDS_V1, + OptionName = OPTIONS_NAME_DISABLE_IMDS_V1, + Value = "true" + }); AddAdditionalOptions(createRequest.OptionSettings, true, isWindowsEnvironment); @@ -447,11 +458,41 @@ private void AddAdditionalOptions(IList settings, bo throw new ToolsException("Additional option \"" + kvp.Key + "=" + kvp.Value + "\" in incorrect format. Format should be ,=.", ToolsException.CommonErrorCode.DefaultsParseFail); } - settings.Add(new ConfigurationOptionSetting + // Handle case where already included settings are overridden by similar setting in additional options. + var existingSetting = settings.FirstOrDefault(s => s.Namespace == tokens[0] && s.OptionName == tokens[1]); + + if (existingSetting != null) + { + existingSetting.Value = kvp.Value; + } + else + { + settings.Add(new ConfigurationOptionSetting + { + Namespace = tokens[0], + OptionName = tokens[1], + Value = kvp.Value + }); + } + } + } + + var disableIMDSv1 = this.GetBoolValueOrDefault(this.DeployEnvironmentOptions.DisableIMDSv1, EBDefinedCommandOptions.ARGUMENT_DISABLE_IMDS_V1, false); + if (disableIMDSv1.HasValue) + { + var existingSetting = settings.FirstOrDefault(s => s.Namespace == OPTIONS_NAMESPACE_DISABLE_IMDS_V1 && s.OptionName == OPTIONS_NAME_DISABLE_IMDS_V1); + + if (existingSetting != null) + { + existingSetting.Value = disableIMDSv1.Value.ToString(CultureInfo.InvariantCulture).ToLowerInvariant(); + } + else + { + settings.Add(new ConfigurationOptionSetting() { - Namespace = tokens[0], - OptionName = tokens[1], - Value = kvp.Value + Namespace = OPTIONS_NAMESPACE_DISABLE_IMDS_V1, + OptionName = OPTIONS_NAME_DISABLE_IMDS_V1, + Value = disableIMDSv1.Value.ToString(CultureInfo.InvariantCulture).ToLowerInvariant() }); } } diff --git a/src/Amazon.ElasticBeanstalk.Tools/EBDefinedCommandOptions.cs b/src/Amazon.ElasticBeanstalk.Tools/EBDefinedCommandOptions.cs index bbff093..411c380 100644 --- a/src/Amazon.ElasticBeanstalk.Tools/EBDefinedCommandOptions.cs +++ b/src/Amazon.ElasticBeanstalk.Tools/EBDefinedCommandOptions.cs @@ -205,5 +205,14 @@ public class EBDefinedCommandOptions ValueType = CommandOption.CommandOptionValueType.IntValue, Description = $"The application port that will be redirect to port 80. The default is port {EBConstants.DEFAULT_APPLICATION_PORT}." }; + + public static readonly CommandOption ARGUMENT_DISABLE_IMDS_V1 = + new CommandOption + { + Name = "Disable IMDSv1", + Switch = "--disable-imds-v1", + ValueType = CommandOption.CommandOptionValueType.BoolValue, + Description = "If set to true then the IMDSv1 will be disabled on EC2 instances running the application." + }; } }