Skip to content

Commit d55aee1

Browse files
authored
Remove deprecated IMDSv1 support (#3664)
1 parent dbc7589 commit d55aee1

File tree

9 files changed

+33
-249
lines changed

9 files changed

+33
-249
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"core": {
3+
"changeLogMessages": [
4+
"[Breaking Change] Remove support for deprecated IMDS v1."
5+
],
6+
"type": "patch",
7+
"updateMinimum": true
8+
}
9+
}

sdk/src/Core/Amazon.Runtime/CredentialManagement/CredentialProfile.cs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -120,14 +120,6 @@ internal Dictionary<string, Dictionary<string, string>> NestedProperties
120120
/// </summary>
121121
public EC2MetadataServiceEndpointMode? EC2MetadataServiceEndpointMode { get; set; }
122122

123-
/// <summary>
124-
/// If set to true the SDK logic for falling back to V1 will be disabled.
125-
/// When using the SDK on an EC2 instance that has configured instance metadata service to
126-
/// use V1 only, a InvalidOperationException exception will be thrown when attempting to access
127-
/// the metadata in EC2 instance metadata.This includes AWS credentials and region information.
128-
/// </summary>
129-
public bool? EC2MetadataV1Disabled { get; set; }
130-
131123
/// <summary>
132124
/// Configures the endpoint calculation to go to a dual stack (ipv6 enabled) endpoint
133125
/// for the configured region.

sdk/src/Core/Amazon.Runtime/CredentialManagement/SharedCredentialsFile.cs

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@ public class SharedCredentialsFile : ICredentialProfileStore
6060
private const string SsoSession = "sso_session";
6161
private const string EC2MetadataServiceEndpointField = "ec2_metadata_service_endpoint";
6262
private const string EC2MetadataServiceEndpointModeField = "ec2_metadata_service_endpoint_mode";
63-
private const string EC2MetadataV1DisabledField = "ec2_metadata_v1_disabled";
6463
private const string UseDualstackEndpointField = "use_dualstack_endpoint";
6564
private const string UseFIPSEndpointField = "use_fips_endpoint";
6665
private const string EndpointUrlField = "endpoint_url";
@@ -94,7 +93,6 @@ public class SharedCredentialsFile : ICredentialProfileStore
9493
SsoSession,
9594
EC2MetadataServiceEndpointField,
9695
EC2MetadataServiceEndpointModeField,
97-
EC2MetadataV1DisabledField,
9896
UseDualstackEndpointField,
9997
UseFIPSEndpointField,
10098
DefaultConfigurationModeField,
@@ -415,9 +413,6 @@ private void RegisterProfileInternal(CredentialProfile profile)
415413
if (profile.EC2MetadataServiceEndpointMode != null)
416414
reservedProperties[EC2MetadataServiceEndpointModeField] = profile.EC2MetadataServiceEndpointMode.ToString().ToLowerInvariant();
417415

418-
if (profile.EC2MetadataV1Disabled != null)
419-
reservedProperties[EC2MetadataV1DisabledField] = profile.EC2MetadataV1Disabled.ToString().ToLowerInvariant();
420-
421416
if (profile.UseDualstackEndpoint != null)
422417
reservedProperties[UseDualstackEndpointField] = profile.UseDualstackEndpoint.ToString().ToLowerInvariant();
423418

@@ -794,20 +789,6 @@ private bool TryGetProfile(string profileName, bool doRefresh, bool isSsoSession
794789
}
795790
}
796791

797-
string ec2MetadataV1DisabledString;
798-
bool? ec2MetadataV1Disabled = null;
799-
if (reservedProperties.TryGetValue(EC2MetadataV1DisabledField, out ec2MetadataV1DisabledString))
800-
{
801-
bool ec2MetadataV1DisabledOut;
802-
if (!bool.TryParse(ec2MetadataV1DisabledString, out ec2MetadataV1DisabledOut))
803-
{
804-
Logger.GetLogger(GetType()).InfoFormat("Invalid value {0} for {1} in profile {2}. A boolean true/false is expected.", ec2MetadataV1DisabledString, EC2MetadataV1DisabledField, profileName);
805-
profile = null;
806-
return false;
807-
}
808-
ec2MetadataV1Disabled = ec2MetadataV1DisabledOut;
809-
}
810-
811792
string useDualstackEndpointString;
812793
bool? useDualstackEndpoint = null;
813794
if (reservedProperties.TryGetValue(UseDualstackEndpointField, out useDualstackEndpointString))
@@ -966,7 +947,6 @@ private bool TryGetProfile(string profileName, bool doRefresh, bool isSsoSession
966947
MaxAttempts = maxAttempts,
967948
EC2MetadataServiceEndpoint = ec2MetadataServiceEndpoint,
968949
EC2MetadataServiceEndpointMode = ec2MetadataServiceEndpointMode,
969-
EC2MetadataV1Disabled = ec2MetadataV1Disabled,
970950
UseDualstackEndpoint = useDualstackEndpoint,
971951
UseFIPSEndpoint = useFIPSEndpoint,
972952
NestedProperties = nestedProperties,

sdk/src/Core/Amazon.Runtime/Credentials/InstanceProfileAWSCredentials.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,6 @@ protected override CredentialsRefreshState GenerateNewCredentials()
7979

8080
if (httpStatusCode == HttpStatusCode.Unauthorized)
8181
{
82-
EC2InstanceMetadata.ClearTokenFlag();
8382
Logger.GetLogger(typeof(EC2InstanceMetadata)).Error(e, "EC2 Metadata service returned unauthorized for token based secure data flow.");
8483
throw;
8584
}
@@ -136,7 +135,6 @@ protected override CredentialsRefreshState GenerateNewCredentials()
136135

137136
if (httpStatusCode == HttpStatusCode.Unauthorized)
138137
{
139-
EC2InstanceMetadata.ClearTokenFlag();
140138
Logger.GetLogger(typeof(EC2InstanceMetadata)).Error(e, "EC2 Metadata service returned unauthorized for token based secure data flow.");
141139
}
142140

@@ -231,7 +229,6 @@ public static IEnumerable<string> GetAvailableRoles(IWebProxy proxy)
231229

232230
if (httpStatusCode == HttpStatusCode.Unauthorized)
233231
{
234-
EC2InstanceMetadata.ClearTokenFlag();
235232
Logger.GetLogger(typeof(EC2InstanceMetadata)).Error(e, "EC2 Metadata service returned unauthorized for token based secure data flow.");
236233
}
237234

sdk/src/Core/Amazon.Runtime/Internal/InternalConfiguration.cs

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,6 @@ public class InternalConfiguration
5151
/// </summary>
5252
public string EC2MetadataServiceEndpoint { get; set; }
5353

54-
/// <summary>
55-
/// Controls whether request EC2 metadata v1 fallback is disabled.
56-
/// </summary>
57-
public bool? EC2MetadataV1Disabled { get; set; }
58-
5954
/// <summary>
6055
/// Internet protocol version to be used for communicating with the EC2 Instance Metadata Service
6156
/// </summary>
@@ -134,7 +129,6 @@ public class EnvironmentVariableInternalConfiguration : InternalConfiguration
134129
public const string ENVIRONMENT_VARIABLE_AWS_RETRY_MODE = "AWS_RETRY_MODE";
135130
public const string ENVIRONMENT_VARIABLE_AWS_EC2_METADATA_SERVICE_ENDPOINT = "AWS_EC2_METADATA_SERVICE_ENDPOINT";
136131
public const string ENVIRONMENT_VARIABLE_AWS_EC2_METADATA_SERVICE_ENDPOINT_MODE = "AWS_EC2_METADATA_SERVICE_ENDPOINT_MODE";
137-
public const string ENVIRONMENT_VARIABLE_AWS_EC2_METADATA_V1_DISABLED = "AWS_EC2_METADATA_V1_DISABLED";
138132
public const string ENVIRONMENT_VARIABLE_AWS_USE_DUALSTACK_ENDPOINT = "AWS_USE_DUALSTACK_ENDPOINT";
139133
public const string ENVIRONMENT_VARIABLE_AWS_USE_FIPS_ENDPOINT = "AWS_USE_FIPS_ENDPOINT";
140134
public const string ENVIRONMENT_VARIABLE_AWS_IGNORE_CONFIGURED_ENDPOINT_URLS = "AWS_IGNORE_CONFIGURED_ENDPOINT_URLS";
@@ -160,7 +154,6 @@ public EnvironmentVariableInternalConfiguration()
160154
RetryMode = GetEnvironmentVariable<RequestRetryMode>(ENVIRONMENT_VARIABLE_AWS_RETRY_MODE);
161155
EC2MetadataServiceEndpoint = GetEC2MetadataEndpointEnvironmentVariable();
162156
EC2MetadataServiceEndpointMode = GetEnvironmentVariable<EC2MetadataServiceEndpointMode>(ENVIRONMENT_VARIABLE_AWS_EC2_METADATA_SERVICE_ENDPOINT_MODE);
163-
EC2MetadataV1Disabled = GetEnvironmentVariable<bool>(ENVIRONMENT_VARIABLE_AWS_EC2_METADATA_V1_DISABLED);
164157
UseDualstackEndpoint = GetEnvironmentVariable<bool>(ENVIRONMENT_VARIABLE_AWS_USE_DUALSTACK_ENDPOINT);
165158
UseFIPSEndpoint = GetEnvironmentVariable<bool>(ENVIRONMENT_VARIABLE_AWS_USE_FIPS_ENDPOINT);
166159
IgnoreConfiguredEndpointUrls = GetEnvironmentVariable(ENVIRONMENT_VARIABLE_AWS_IGNORE_CONFIGURED_ENDPOINT_URLS, false);
@@ -336,7 +329,6 @@ private void Setup(ICredentialProfileSource source, string profileName)
336329
MaxAttempts = profile.MaxAttempts;
337330
EC2MetadataServiceEndpoint = profile.EC2MetadataServiceEndpoint;
338331
EC2MetadataServiceEndpointMode = profile.EC2MetadataServiceEndpointMode;
339-
EC2MetadataV1Disabled = profile.EC2MetadataV1Disabled;
340332
UseDualstackEndpoint = profile.UseDualstackEndpoint;
341333
UseFIPSEndpoint = profile.UseFIPSEndpoint;
342334
IgnoreConfiguredEndpointUrls = profile.IgnoreConfiguredEndpointUrls;
@@ -361,7 +353,6 @@ private void Setup(ICredentialProfileSource source, string profileName)
361353
new KeyValuePair<string, object>("max_attempts", profile.MaxAttempts),
362354
new KeyValuePair<string, object>("ec2_metadata_service_endpoint", profile.EC2MetadataServiceEndpoint),
363355
new KeyValuePair<string, object>("ec2_metadata_service_endpoint_mode", profile.EC2MetadataServiceEndpointMode),
364-
new KeyValuePair<string, object>("ec2_metadata_v1_disabled", profile.EC2MetadataV1Disabled),
365356
new KeyValuePair<string, object>("use_dualstack_endpoint", profile.UseDualstackEndpoint),
366357
new KeyValuePair<string, object>("use_fips_endpoint", profile.UseFIPSEndpoint),
367358
new KeyValuePair<string,object>( "ignore_configured_endpoint_urls", profile.IgnoreConfiguredEndpointUrls),
@@ -433,7 +424,6 @@ public static void Reset()
433424
_cachedConfiguration.MaxAttempts = SeekValue(standardGenerators, (c) => c.MaxAttempts);
434425
_cachedConfiguration.EC2MetadataServiceEndpoint = SeekString(standardGenerators, (c) => c.EC2MetadataServiceEndpoint);
435426
_cachedConfiguration.EC2MetadataServiceEndpointMode = SeekValue(standardGenerators, (c) => c.EC2MetadataServiceEndpointMode);
436-
_cachedConfiguration.EC2MetadataV1Disabled = SeekValue(standardGenerators, (c) => c.EC2MetadataV1Disabled);
437427
_cachedConfiguration.UseDualstackEndpoint = SeekValue(standardGenerators, (c) => c.UseDualstackEndpoint);
438428
_cachedConfiguration.UseFIPSEndpoint = SeekValue(standardGenerators, (c) => c.UseFIPSEndpoint);
439429
_cachedConfiguration.IgnoreConfiguredEndpointUrls = SeekValue(standardGenerators, (c) => c.IgnoreConfiguredEndpointUrls);
@@ -525,17 +515,6 @@ public static string EC2MetadataServiceEndpoint
525515
}
526516
}
527517

528-
/// <summary>
529-
/// Controls whether request EC2 metadata v1 fallback is disabled.
530-
/// </summary>
531-
public static bool? EC2MetadataV1Disabled
532-
{
533-
get
534-
{
535-
return _cachedConfiguration.EC2MetadataV1Disabled;
536-
}
537-
}
538-
539518
/// <summary>
540519
/// Internet protocol version to be used for communicating with the EC2 Instance Metadata Service
541520
/// </summary>

sdk/src/Core/Amazon.Util/EC2InstanceMetadata.cs

Lines changed: 19 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,6 @@ private static int
6363

6464
private static Dictionary<string, string> _cache = new Dictionary<string, string>();
6565

66-
private static bool useNullToken = false;
67-
6866
private static ReaderWriterLockSlim metadataLock = new ReaderWriterLockSlim(); // Lock to control getting metadata across multiple threads.
6967
private static readonly TimeSpan metadataLockTimeout = TimeSpan.FromMilliseconds(5000);
7068
private static readonly string _userAgent = InternalSDKUtils.BuildUserAgentString(string.Empty, string.Empty);
@@ -116,10 +114,7 @@ public static string ServiceEndpoint
116114
public static string EC2ApiTokenUrl => ServiceEndpoint + LATEST + "/api/token";
117115

118116
/// <summary>
119-
/// If set to true the SDK logic for falling back to V1 will be disabled.
120-
/// When using the SDK on an EC2 instance that has configured instance metadata service to
121-
/// use V1 only, a InvalidOperationException exception will be thrown when attempting to access
122-
/// the metadata in EC2 instance metadata.This includes AWS credentials and region information.
117+
/// Disable accessing EC2 instance metadata service (IMDS).
123118
/// The default value is false.
124119
/// </summary>
125120
public static bool IsIMDSEnabled
@@ -136,23 +131,6 @@ public static bool IsIMDSEnabled
136131
}
137132
}
138133

139-
private static bool? _ec2MetadataV1Disabled;
140-
141-
/// <summary>
142-
/// Controls whether request EC2 metadata v1 fallback is disabled.
143-
/// </summary>
144-
public static bool EC2MetadataV1Disabled
145-
{
146-
get
147-
{
148-
if (_ec2MetadataV1Disabled.HasValue)
149-
return _ec2MetadataV1Disabled.Value;
150-
return FallbackInternalConfigurationFactory.EC2MetadataV1Disabled.GetValueOrDefault();
151-
}
152-
set { _ec2MetadataV1Disabled = value; }
153-
}
154-
155-
156134
/// <summary>
157135
/// Allows to configure the proxy used for HTTP requests. The default value is null.
158136
/// </summary>
@@ -647,9 +625,11 @@ public static string FetchApiToken()
647625
/// <returns>The API token or null if an API token couldn't be obtained and doesn't need to be used</returns>
648626
private static string FetchApiToken(int tries)
649627
{
628+
const string errorFailFastMessage = "IMDS rejected request to get API token.";
629+
const string errorMessage = "Unable to retrieve token for use in IMDSv2.";
650630
for (int retry = 1; retry <= tries; retry++)
651631
{
652-
if (!IsIMDSEnabled || useNullToken)
632+
if (!IsIMDSEnabled)
653633
{
654634
return null;
655635
}
@@ -672,55 +652,26 @@ private static string FetchApiToken(int tries)
672652
|| httpStatusCode == HttpStatusCode.MethodNotAllowed
673653
|| httpStatusCode == HttpStatusCode.Forbidden)
674654
{
675-
if (EC2MetadataV1Disabled)
676-
{
677-
throw new InvalidOperationException("Unable to retrieve token for use in IMDSv2 call and IMDSv1 has been disabled.");
678-
}
679-
680-
useNullToken = true;
681-
return null;
655+
throw new InvalidOperationException(errorFailFastMessage);
682656
}
683657

684658
if (retry >= tries)
685659
{
686660
if (httpStatusCode == HttpStatusCode.BadRequest)
687661
{
688-
Logger.GetLogger(typeof(EC2InstanceMetadata)).Error(e, "Unable to contact EC2 Metadata service to obtain a metadata token.");
662+
Logger.GetLogger(typeof(EC2InstanceMetadata)).Error(e, errorMessage);
689663
throw;
690664
}
691665

692-
Logger.GetLogger(typeof(EC2InstanceMetadata)).Error(e, "Unable to contact EC2 Metadata service to obtain a metadata token. Attempting to access IMDS without a token.");
693-
694-
//If there isn't a status code, it was a failure to contact the server which would be
695-
//a request failure, a network issue, or a timeout. Cache this response and fallback
696-
//to IMDS flow without a token unless EC2MetadataV1Disabled is set to true. If the non
697-
//token IMDS flow returns unauthorized, the useNullToken flag will be cleared and the IMDS
698-
//flow will attempt to obtain another token.
699-
700-
if (EC2MetadataV1Disabled)
701-
{
702-
throw new InvalidOperationException("Unable to retrieve token for use in IMDSv2 call and IMDSv1 has been disabled.");
703-
}
704-
705-
if (httpStatusCode == null)
706-
{
707-
useNullToken = true;
708-
}
709-
710-
//Return null to fallback to the IMDS flow without using a token.
711-
return null;
666+
Logger.GetLogger(typeof(EC2InstanceMetadata)).Error(e, errorMessage);
667+
throw new InvalidOperationException(errorMessage);
712668
}
713669

714670
PauseExponentially(retry - 1);
715671
}
716672
}
717673

718-
return null;
719-
}
720-
721-
public static void ClearTokenFlag()
722-
{
723-
useNullToken = false;
674+
throw new InvalidOperationException(errorMessage);
724675
}
725676

726677
private static List<string> GetItems(string relativeOrAbsolutePath, int tries, bool slurp)
@@ -735,16 +686,20 @@ private static List<string> GetItems(string relativeOrAbsolutePath, int tries, b
735686
//token cannot be obtained we will fallback to not using a token.
736687
if (token == null)
737688
{
738-
token = FetchApiToken(DEFAULT_RETRIES);
689+
try
690+
{
691+
token = FetchApiToken(DEFAULT_RETRIES);
692+
}
693+
catch(InvalidOperationException e)
694+
{
695+
Logger.GetLogger(typeof(EC2InstanceMetadata)).InfoFormat("Failed to retrieve IMDS data \"{0}\" because IMDS API token could not be retrieved: {1}", relativeOrAbsolutePath, e.Message);
696+
return null; // If we could not get a token then assume we are not running in an EC2 instance and return null.
697+
}
739698
}
740699

741700
var headers = new Dictionary<string, string>();
742701
headers.Add(HeaderKeys.UserAgentHeader, _userAgent);
743-
744-
if (!string.IsNullOrEmpty(token))
745-
{
746-
headers.Add(HeaderKeys.XAwsEc2MetadataToken, token);
747-
}
702+
headers.Add(HeaderKeys.XAwsEc2MetadataToken, token);
748703

749704
try
750705
{
@@ -792,7 +747,6 @@ private static List<string> GetItems(string relativeOrAbsolutePath, int tries, b
792747
}
793748
else if (httpStatusCode == HttpStatusCode.Unauthorized)
794749
{
795-
ClearTokenFlag();
796750
Logger.GetLogger(typeof(EC2InstanceMetadata)).Error(e, "EC2 Metadata service returned unauthorized for token based secure data flow.");
797751
throw;
798752
}

0 commit comments

Comments
 (0)