-
Notifications
You must be signed in to change notification settings - Fork 100
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
IMDSv2 not supported #243
Comments
Thanks for the very thorough writeup! |
Hi! For anyone curious, here's how I got it working under IMDSv2 Maybe someting like it could be mentioned in the README, so people don't have to stub their toes on this problem? I'd be grateful for any ruthless criticism. Like:
Soooo, I can declare: (def s3
(aws/client {:api :s3
:region "us-east-1"
:credentials-provider (role-credentials-provider)})) Using: (ns test-test-test.aws-api-auth
(:require
[clj-http.client :as client]
[clojure.data.json :as json]
[cognitect.aws.client.api :as aws]
[cognitect.aws.credentials :as credentials]))
(def ^:private token-url
"http://169.254.169.254/latest/api/token")
(def ^:private security-credentials-url
"http://169.254.169.254/latest/meta-data/iam/security-credentials/")
(defn- get-imdsv2-token []
(let [{:keys [body status] :as response}
(client/put token-url
{:headers {"X-aws-ec2-metadata-token-ttl-seconds"
"21600"}
:throw-exceptions false})]
(if (= 200 status)
body
(throw (ex-info "No IMDSv2 token available."
{:IMDSv2-status-code status})))))
(defn- get-iam-role-name [token]
(let [{:keys [body status] :as response}
(client/get security-credentials-url
{:headers {"X-aws-ec2-metadata-token" token}
:throw-exceptions false})]
(if (= 200 status)
body
(throw (ex-info "No IAM role found."
{:IMDSv2-status-code status})))))
(defn- get-iam-role-credentials
([token]
(let [role-name (get-iam-role-name token)]
(when role-name
(get-iam-role-credentials token role-name))))
([token role-name]
(let [{:keys [body status] :as response}
(client/get (str security-credentials-url role-name)
{:headers {"X-aws-ec2-metadata-token" token}
:throw-exceptions false})]
(if (= 200 status)
(json/read-str body :key-fn keyword)
(throw (ex-info "No IAM role credentials found."
{:IMDSv2-status-code status}))))))
(defn- get-credentials []
(some->> (get-imdsv2-token)
(get-iam-role-credentials)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Public API
(defn role-credentials-provider []
(credentials/cached-credentials-with-auto-refresh
(reify credentials/CredentialsProvider
(fetch [_]
(when-let [creds (try
(get-credentials)
;; Err... what happens if I throw in here?
;; Or return nil?
(catch Exception e))]
{:aws/access-key-id (:AccessKeyId creds)
:aws/secret-access-key (:SecretAccessKey creds)
:aws/session-token (:Token creds)
::credentials/ttl (credentials/calculate-ttl creds)}))))) |
Hi It seems there is another ticket requesting IMDSv2 support #165 While Amazon Linux 2023 uses IMDSv2 by default (Which you should use as best practice) you can still change this. For example, launching a new instance via cli aws ec2 run-instances \
...
--metadata-options "HttpTokens=optional"
Or via the console in Launch an instance (Advanced details): |
Thanks for sharing your code! |
This bit me hard today on a production system (causing production issues). Setting it to be "optional" in the console got round this problem (for now! - we have an automated deployment system, so have to now figure out how to shove this into the metadata setup of the ec2 instance). Please can support for IMDSv2 within the codebase be considered as soon as possible. Thank you. -=david=- |
I think the region provider has a similar issue, but it should have its own ticket. |
We have just released a beta release which should solve this issue. @burbma if time permits, could you please verify whether this release solves your issue? Thanks. (I will leave this issue open for the time being until we verify.) |
Amazon Linux 2023 does not allow use of IMDSv1 but rather requires use of IMDSv2 (see here for the difference).
cognitect.aws.ec2-metadata-utils
only allows use of v1. This means aws-api cannot authenticate with Instance Profile Credentials (number 6 in the credential provider chain, as of this writing, here).Dependencies
Description with failing test case
First, be on an ec2 running Amazon Linux 2023. Then,
There are two problems here. First, it didn't return instance metadata. Second, it returned
nil
rather than failing. If you look this line you'll see it's swallowing any errors from this request. When I run the http request from these lines manually to inspect the response I see this following swallowed errorIndeed IMDSv2 requires a form of authentication that v1 does not.
The text was updated successfully, but these errors were encountered: