Merge pull request #104193 from grahamc/ec2-metadata-imdsv2

NixOS EC2 AMI: Support IMDSv2

authored by

Graham Christensen and committed by
GitHub
7fa7bf2f c694e77a

+88 -6
+1
nixos/modules/virtualisation/amazon-image.nix
··· 11 11 let 12 12 cfg = config.ec2; 13 13 metadataFetcher = import ./ec2-metadata-fetcher.nix { 14 + inherit (pkgs) curl; 14 15 targetRoot = "$targetRoot/"; 15 16 wgetExtraOptions = "-q"; 16 17 };
+61 -5
nixos/modules/virtualisation/ec2-metadata-fetcher.nix
··· 1 - { targetRoot, wgetExtraOptions }: 1 + { curl, targetRoot, wgetExtraOptions }: 2 + # Note: be very cautious about dependencies, each dependency grows 3 + # the closure of the initrd. Ideally we would not even require curl, 4 + # but there is no reasonable way to send an HTTP PUT request without 5 + # it. Note: do not be fooled: the wget referenced in this script 6 + # is busybox's wget, not the fully featured one with --method support. 7 + # 8 + # Make sure that every package you depend on here is already listed as 9 + # a channel blocker for both the full-sized and small channels. 10 + # Otherwise, we risk breaking user deploys in released channels. 2 11 '' 3 12 metaDir=${targetRoot}etc/ec2-metadata 4 13 mkdir -m 0755 -p "$metaDir" 5 14 15 + get_imds_token() { 16 + # retry-delay of 1 selected to give the system a second to get going, 17 + # but not add a lot to the bootup time 18 + ${curl}/bin/curl \ 19 + -v \ 20 + --retry 3 \ 21 + --retry-delay 1 \ 22 + --fail \ 23 + -X PUT \ 24 + --connect-timeout 1 \ 25 + -H "X-aws-ec2-metadata-token-ttl-seconds: 600" \ 26 + http://169.254.169.254/latest/api/token 27 + } 28 + 29 + preflight_imds_token() { 30 + # retry-delay of 1 selected to give the system a second to get going, 31 + # but not add a lot to the bootup time 32 + ${curl}/bin/curl \ 33 + -v \ 34 + --retry 3 \ 35 + --retry-delay 1 \ 36 + --fail \ 37 + --connect-timeout 1 \ 38 + -H "X-aws-ec2-metadata-token: $IMDS_TOKEN" \ 39 + http://169.254.169.254/1.0/meta-data/instance-id 40 + } 41 + 42 + try=1 43 + while [ $try -le 3 ]; do 44 + echo "(attempt $try/3) getting an EC2 instance metadata service v2 token..." 45 + IMDS_TOKEN=$(get_imds_token) && break 46 + try=$((try + 1)) 47 + sleep 1 48 + done 49 + 50 + if [ "x$IMDS_TOKEN" == "x" ]; then 51 + echo "failed to fetch an IMDS2v token." 52 + fi 53 + 54 + try=1 55 + while [ $try -le 10 ]; do 56 + echo "(attempt $try/10) validating the EC2 instance metadata service v2 token..." 57 + preflight_imds_token && break 58 + try=$((try + 1)) 59 + sleep 1 60 + done 61 + 6 62 echo "getting EC2 instance metadata..." 7 63 8 64 if ! [ -e "$metaDir/ami-manifest-path" ]; then 9 - wget ${wgetExtraOptions} -O "$metaDir/ami-manifest-path" http://169.254.169.254/1.0/meta-data/ami-manifest-path 65 + wget ${wgetExtraOptions} --header "X-aws-ec2-metadata-token: $IMDS_TOKEN" -O "$metaDir/ami-manifest-path" http://169.254.169.254/1.0/meta-data/ami-manifest-path 10 66 fi 11 67 12 68 if ! [ -e "$metaDir/user-data" ]; then 13 - wget ${wgetExtraOptions} -O "$metaDir/user-data" http://169.254.169.254/1.0/user-data && chmod 600 "$metaDir/user-data" 69 + wget ${wgetExtraOptions} --header "X-aws-ec2-metadata-token: $IMDS_TOKEN" -O "$metaDir/user-data" http://169.254.169.254/1.0/user-data && chmod 600 "$metaDir/user-data" 14 70 fi 15 71 16 72 if ! [ -e "$metaDir/hostname" ]; then 17 - wget ${wgetExtraOptions} -O "$metaDir/hostname" http://169.254.169.254/1.0/meta-data/hostname 73 + wget ${wgetExtraOptions} --header "X-aws-ec2-metadata-token: $IMDS_TOKEN" -O "$metaDir/hostname" http://169.254.169.254/1.0/meta-data/hostname 18 74 fi 19 75 20 76 if ! [ -e "$metaDir/public-keys-0-openssh-key" ]; then 21 - wget ${wgetExtraOptions} -O "$metaDir/public-keys-0-openssh-key" http://169.254.169.254/1.0/meta-data/public-keys/0/openssh-key 77 + wget ${wgetExtraOptions} --header "X-aws-ec2-metadata-token: $IMDS_TOKEN" -O "$metaDir/public-keys-0-openssh-key" http://169.254.169.254/1.0/meta-data/public-keys/0/openssh-key 22 78 fi 23 79 ''
+1 -1
nixos/modules/virtualisation/openstack-config.nix
··· 3 3 with lib; 4 4 5 5 let 6 - metadataFetcher = import ./ec2-metadata-fetcher.nix { 6 + metadataFetcher = import ./openstack-metadata-fetcher.nix { 7 7 targetRoot = "/"; 8 8 wgetExtraOptions = "--retry-connrefused"; 9 9 };
+23
nixos/modules/virtualisation/openstack-metadata-fetcher.nix
··· 1 + { targetRoot, wgetExtraOptions }: 2 + '' 3 + metaDir=${targetRoot}etc/ec2-metadata 4 + mkdir -m 0755 -p "$metaDir" 5 + 6 + echo "getting EC2 instance metadata..." 7 + 8 + if ! [ -e "$metaDir/ami-manifest-path" ]; then 9 + wget ${wgetExtraOptions} -O "$metaDir/ami-manifest-path" http://169.254.169.254/1.0/meta-data/ami-manifest-path 10 + fi 11 + 12 + if ! [ -e "$metaDir/user-data" ]; then 13 + wget ${wgetExtraOptions} -O "$metaDir/user-data" http://169.254.169.254/1.0/user-data && chmod 600 "$metaDir/user-data" 14 + fi 15 + 16 + if ! [ -e "$metaDir/hostname" ]; then 17 + wget ${wgetExtraOptions} -O "$metaDir/hostname" http://169.254.169.254/1.0/meta-data/hostname 18 + fi 19 + 20 + if ! [ -e "$metaDir/public-keys-0-openssh-key" ]; then 21 + wget ${wgetExtraOptions} -O "$metaDir/public-keys-0-openssh-key" http://169.254.169.254/1.0/meta-data/public-keys/0/openssh-key 22 + fi 23 + ''
+1
nixos/release-combined.nix
··· 49 49 [ "nixos.channel" ] 50 50 (onFullSupported "nixos.dummy") 51 51 (onAllSupported "nixos.iso_minimal") 52 + (onAllSupported "nixos.amazonImage") 52 53 (onSystems ["x86_64-linux"] "nixos.iso_plasma5") 53 54 (onSystems ["x86_64-linux"] "nixos.iso_gnome") 54 55 (onFullSupported "nixos.manual")
+1
nixos/release-small.nix
··· 92 92 [ "nixos.channel" 93 93 "nixos.dummy.x86_64-linux" 94 94 "nixos.iso_minimal.x86_64-linux" 95 + "nixos.amazonImage.x86_64-linux" 95 96 "nixos.manual.x86_64-linux" 96 97 "nixos.tests.boot.biosCdrom.x86_64-linux" 97 98 "nixos.tests.containers-imperative.x86_64-linux"