IMDSv1を使用しているか判断できるIMDSパケットアナライザーがリリースされました

IMDSv2のみ許可する時の下調べにかなり役立つぞ
2023.06.02

IMDSv2のみ許可したいけどIMDSv1を使っているプロセスの判断がつかないな

こんにちは、のんピ(@non____97)です。

皆さんはインスタンスメタデータ(以降IMDS)v2のみ許可したいけどIMDSv1を使っているプロセスの判断がつかないなと思ったことはありますか? 私はあります。

IMDSv2のみ許可することでSSRF攻撃を緩和することが可能です。

IMDSv2の詳細な動作や効果については、DevelopesIOの以下記事や徳丸先生の記事が参考になります。

EC2インスタンスのデフォルトの設定ではIMDSv2とIMDSv1どちらも有効化されていることが多いです。(デフォルトの設定はAMI次第)

そのため、後からIMDSv1を無効化したい場合は、どのプロセスがIMDSv1を使っているのかを確認する必要があります。しかし、具体的にIMDSv1を使用しているプロセスを確認するメトリクスなどもないため、簡単に把握することは難しいです。(MetadataNoTokenでIMDSv1のリクエスト数を確認することは可能)

今回、IMDSv1を使用しているかどうか判断できるIMDSパケットアナライザーがリリースされました。

これにより、トークンを取得せずにIMDSに直接リクエストしたプロセスをロギングすることが可能になりました。

しばらくIMDSパケットアナライザーを動作させて、ログが出力されていなければ安心してIMDSv1を無効化できますね。

実際に試してみたので紹介します。

いきなりまとめ

  • IMDSパケットアナライザーはIMDSv2のみ許可する下調べにかなり役立つ
  • IMDSパケットアナライザーはPython製のツール
  • IMDSv1の場合はWARNINGでIMDSv2はINFOでログに記録される
  • サービスに登録して動作させることも可能
  • 動作確認が完了したらIMDSパケットアナライザーは削除しよう

IMDSパケットアナライザーとは

IMDSパケットアナライザー(ImdsPacketAnalyzer)はIMDSとのTCP通信をトレースするツールです。GitHub上に公開されており、都度必要なEC2インスタンスにインストールして使用します。

トレース結果には最大4階層分のプロセスIDやプロセス起動時の引数が出力されます。IMDSv1を使用している大元のプロセスまで簡単に特定できそうですね。

トレース結果はデフォルトでは、/var/log/imds-trace.logに出力されます。1MBでローテーションされ最大6世代保持します。

IMDSパケットアナライザーを動作させるためにはBCC (BPF Compiler Collection)のインストールが必要です。

対応OSは以下の通りです。

  • Amazon Linux 2023
  • Amazon Linux 2
  • Amazon Linux 1
  • Debian 11
  • Debian 10
  • Ubuntu 20 / 22
  • RHEL 8 / 9
  • SLES 15
  • Windows

ただし、動作検証はAmazon Linux 2でしか行われていないようなので注意しましょう。

また、IMDSパケットアナライザーはIMDSv1が使用されているか判断するために一時的に使用するツールです。分析が完了したら削除することをお勧めします。

やってみた

IMDSパケットアナライザーのインストール

それでは、IMDSパケットアナライザーを実際に触ってみます。

検証はRHEL 8.8のEC2インスタンスで行います。RHEL 8.8はデフォルトでIMDSv2とIMDSv1どちらも有効化されています。

$ aws ec2 describe-instances \
    --instance-id i-007e5162dfc4ab6c8 \
    --query "Reservations[*].Instances[*].MetadataOptions"
[
    [
        {
            "State": "applied",
            "HttpTokens": "optional",
            "HttpPutResponseHopLimit": 1,
            "HttpEndpoint": "enabled",
            "HttpProtocolIpv6": "disabled",
            "InstanceMetadataTags": "disabled"
        }
    ]
]

まず、依存関係として必要になるパッケージをインストールします。

インストールスクリプト(aws-imds-packet-analyzer/install-deps.sh )が公開されていますが、今回は直接dnfでインストールします。

$ sudo dnf install bcc-tools libbpf
Updating Subscription Management repositories.
Unable to read consumer identity

This system is not registered with an entitlement server. You can use subscription-manager to register.

Red Hat Enterprise Linux 8 for x86_64 - AppStream from RHUI (RPMs)              95 kB/s | 4.5 kB     00:00    
Red Hat Enterprise Linux 8 for x86_64 - BaseOS from RHUI (RPMs)                 86 kB/s | 4.1 kB     00:00    
Red Hat Enterprise Linux 8 for x86_64 - BaseOS from RHUI (RPMs)                103 MB/s |  61 MB     00:00    
Red Hat Ansible Engine 2 for RHEL 8 (RPMs) from RHUI                            82 kB/s | 4.0 kB     00:00    
RHUI Client Configuration Server 8                                              53 kB/s | 2.0 kB     00:00    
Package libbpf-0.5.0-1.el8.x86_64 is already installed.
Dependencies resolved.
===============================================================================================================
 Package                       Arch   Version                                 Repository                  Size
===============================================================================================================
Installing:
 bcc-tools                     x86_64 0.25.0-2.el8                            rhel-8-appstream-rhui-rpms 482 k
Installing dependencies:
 bcc                           x86_64 0.25.0-2.el8                            rhel-8-appstream-rhui-rpms 653 k
 binutils                      x86_64 2.30-119.el8                            rhel-8-baseos-rhui-rpms    5.8 M
 clang-libs                    x86_64 15.0.7-1.module+el8.8.0+17939+b58878af  rhel-8-appstream-rhui-rpms  24 M
 clang-resource-filesystem     x86_64 15.0.7-1.module+el8.8.0+17939+b58878af  rhel-8-appstream-rhui-rpms  15 k
 cpp                           x86_64 8.5.0-18.el8                            rhel-8-appstream-rhui-rpms  10 M
 environment-modules           x86_64 4.5.2-3.el8                             rhel-8-baseos-rhui-rpms    422 k
 gcc-toolset-12-binutils       x86_64 2.38-17.el8                             rhel-8-appstream-rhui-rpms 6.5 M
 gcc-toolset-12-binutils-gold  x86_64 2.38-17.el8                             rhel-8-appstream-rhui-rpms 873 k
 gcc-toolset-12-gcc            x86_64 12.2.1-7.4.el8                          rhel-8-appstream-rhui-rpms  44 M
 gcc-toolset-12-gcc-c++        x86_64 12.2.1-7.4.el8                          rhel-8-appstream-rhui-rpms  13 M
 gcc-toolset-12-libstdc++-devel
                               x86_64 12.2.1-7.4.el8                          rhel-8-appstream-rhui-rpms 3.4 M
 gcc-toolset-12-runtime        x86_64 12.0-6.el8                              rhel-8-appstream-rhui-rpms  28 k
 glibc-devel                   x86_64 2.28-225.el8                            rhel-8-baseos-rhui-rpms     83 k
 glibc-headers                 x86_64 2.28-225.el8                            rhel-8-baseos-rhui-rpms    488 k
 isl                           x86_64 0.16.1-6.el8                            rhel-8-appstream-rhui-rpms 841 k
 kernel-headers                x86_64 4.18.0-477.13.1.el8_8                   rhel-8-baseos-rhui-rpms     11 M
 keyutils-libs-devel           x86_64 1.5.10-9.el8                            rhel-8-baseos-rhui-rpms     48 k
 krb5-devel                    x86_64 1.18.2-22.el8_7                         rhel-8-baseos-rhui-rpms    561 k
 libcom_err-devel              x86_64 1.45.6-5.el8                            rhel-8-baseos-rhui-rpms     39 k
 libkadm5                      x86_64 1.18.2-22.el8_7                         rhel-8-baseos-rhui-rpms    187 k
 libmpc                        x86_64 1.1.0-9.1.el8                           rhel-8-appstream-rhui-rpms  61 k
 libselinux-devel              x86_64 2.9-8.el8                               rhel-8-baseos-rhui-rpms    200 k
 libsepol-devel                x86_64 2.9-3.el8                               rhel-8-baseos-rhui-rpms     87 k
 libverto-devel                x86_64 0.3.2-2.el8                             rhel-8-baseos-rhui-rpms     18 k
 libxcrypt-devel               x86_64 4.1.1-6.el8                             rhel-8-baseos-rhui-rpms     25 k
 llvm-libs                     x86_64 15.0.7-1.module+el8.8.0+17939+b58878af  rhel-8-appstream-rhui-rpms  27 M
 m4                            x86_64 1.4.18-7.el8                            rhel-8-baseos-rhui-rpms    223 k
 make                          x86_64 1:4.2.1-11.el8                          rhel-8-baseos-rhui-rpms    498 k
 pcre2-devel                   x86_64 10.32-3.el8_6                           rhel-8-baseos-rhui-rpms    605 k
 pcre2-utf16                   x86_64 10.32-3.el8_6                           rhel-8-baseos-rhui-rpms    229 k
 pcre2-utf32                   x86_64 10.32-3.el8_6                           rhel-8-baseos-rhui-rpms    220 k
 perl-Carp                     noarch 1.42-396.el8                            rhel-8-baseos-rhui-rpms     30 k
 perl-Data-Dumper              x86_64 2.167-399.el8                           rhel-8-baseos-rhui-rpms     58 k
 perl-Digest                   noarch 1.17-395.el8                            rhel-8-appstream-rhui-rpms  27 k
 perl-Digest-MD5               x86_64 2.55-396.el8                            rhel-8-appstream-rhui-rpms  37 k
 perl-Encode                   x86_64 4:2.97-3.el8                            rhel-8-baseos-rhui-rpms    1.5 M
 perl-Errno                    x86_64 1.28-422.el8                            rhel-8-baseos-rhui-rpms     77 k
 perl-Exporter                 noarch 5.72-396.el8                            rhel-8-baseos-rhui-rpms     34 k
 perl-File-Path                noarch 2.15-2.el8                              rhel-8-baseos-rhui-rpms     38 k
 perl-File-Temp                noarch 0.230.600-1.el8                         rhel-8-baseos-rhui-rpms     63 k
 perl-Getopt-Long              noarch 1:2.50-4.el8                            rhel-8-baseos-rhui-rpms     63 k
 perl-HTTP-Tiny                noarch 0.074-1.el8                             rhel-8-baseos-rhui-rpms     58 k
 perl-IO                       x86_64 1.38-422.el8                            rhel-8-baseos-rhui-rpms    142 k
 perl-MIME-Base64              x86_64 3.15-396.el8                            rhel-8-baseos-rhui-rpms     31 k
 perl-Net-SSLeay               x86_64 1.88-2.module+el8.6.0+13392+f0897f98    rhel-8-appstream-rhui-rpms 379 k
 perl-PathTools                x86_64 3.74-1.el8                              rhel-8-baseos-rhui-rpms     90 k
 perl-Pod-Escapes              noarch 1:1.07-395.el8                          rhel-8-baseos-rhui-rpms     20 k
 perl-Pod-Perldoc              noarch 3.28-396.el8                            rhel-8-baseos-rhui-rpms     88 k
 perl-Pod-Simple               noarch 1:3.35-395.el8                          rhel-8-baseos-rhui-rpms    213 k
 perl-Pod-Usage                noarch 4:1.69-395.el8                          rhel-8-baseos-rhui-rpms     34 k
 perl-Scalar-List-Utils        x86_64 3:1.49-2.el8                            rhel-8-baseos-rhui-rpms     68 k
 perl-Socket                   x86_64 4:2.027-3.el8                           rhel-8-baseos-rhui-rpms     59 k
 perl-Storable                 x86_64 1:3.11-3.el8                            rhel-8-baseos-rhui-rpms     98 k
 perl-Term-ANSIColor           noarch 4.06-396.el8                            rhel-8-baseos-rhui-rpms     46 k
 perl-Term-Cap                 noarch 1.17-395.el8                            rhel-8-baseos-rhui-rpms     23 k
 perl-Text-ParseWords          noarch 3.30-395.el8                            rhel-8-baseos-rhui-rpms     18 k
 perl-Text-Tabs+Wrap           noarch 2013.0523-395.el8                       rhel-8-baseos-rhui-rpms     24 k
 perl-Time-Local               noarch 1:1.280-1.el8                           rhel-8-baseos-rhui-rpms     34 k
 perl-URI                      noarch 1.73-3.el8                              rhel-8-appstream-rhui-rpms 116 k
 perl-Unicode-Normalize        x86_64 1.25-396.el8                            rhel-8-baseos-rhui-rpms     82 k
 perl-constant                 noarch 1.33-396.el8                            rhel-8-baseos-rhui-rpms     25 k
 perl-interpreter              x86_64 4:5.26.3-422.el8                        rhel-8-baseos-rhui-rpms    6.3 M
 perl-libnet                   noarch 3.11-3.el8                              rhel-8-appstream-rhui-rpms 121 k
 perl-libs                     x86_64 4:5.26.3-422.el8                        rhel-8-baseos-rhui-rpms    1.6 M
 perl-macros                   x86_64 4:5.26.3-422.el8                        rhel-8-baseos-rhui-rpms     73 k
 perl-parent                   noarch 1:0.237-1.el8                           rhel-8-baseos-rhui-rpms     20 k
 perl-podlators                noarch 4.11-1.el8                              rhel-8-baseos-rhui-rpms    118 k
 perl-threads                  x86_64 1:2.21-2.el8                            rhel-8-baseos-rhui-rpms     61 k
 perl-threads-shared           x86_64 1.58-2.el8                              rhel-8-baseos-rhui-rpms     48 k
 python3-bcc                   x86_64 0.25.0-2.el8                            rhel-8-appstream-rhui-rpms  98 k
 python3-netaddr               noarch 0.7.19-8.el8                            rhel-8-appstream-rhui-rpms 1.5 M
 scl-utils                     x86_64 1:2.0.2-16.el8                          rhel-8-appstream-rhui-rpms  47 k
 tcl                           x86_64 1:8.6.8-2.el8                           rhel-8-baseos-rhui-rpms    1.1 M
 zlib-devel                    x86_64 1.2.11-21.el8_7                         rhel-8-baseos-rhui-rpms     58 k
Installing weak dependencies:
 bison                         x86_64 3.0.4-10.el8                            rhel-8-appstream-rhui-rpms 688 k
 compiler-rt                   x86_64 15.0.7-1.module+el8.8.0+17939+b58878af  rhel-8-appstream-rhui-rpms 4.9 M
 elfutils-libelf-devel         x86_64 0.188-3.el8                             rhel-8-baseos-rhui-rpms     61 k
 flex                          x86_64 2.6.1-9.el8                             rhel-8-appstream-rhui-rpms 320 k
 gcc                           x86_64 8.5.0-18.el8                            rhel-8-appstream-rhui-rpms  23 M
 kernel-devel                  x86_64 4.18.0-477.13.1.el8_8                   rhel-8-baseos-rhui-rpms     23 M
 libomp                        x86_64 15.0.7-1.module+el8.8.0+17939+b58878af  rhel-8-appstream-rhui-rpms 543 k
 libomp-devel                  x86_64 15.0.7-1.module+el8.8.0+17939+b58878af  rhel-8-appstream-rhui-rpms 350 k
 openssl-devel                 x86_64 1:1.1.1k-9.el8_7                        rhel-8-baseos-rhui-rpms    2.3 M
 perl-IO-Socket-IP             noarch 0.39-5.el8                              rhel-8-appstream-rhui-rpms  47 k
 perl-IO-Socket-SSL            noarch 2.066-4.module+el8.3.0+6446+594cad75    rhel-8-appstream-rhui-rpms 298 k
 perl-Mozilla-CA               noarch 20160104-7.module+el8.3.0+6498+9eecfe51 rhel-8-appstream-rhui-rpms  15 k
Enabling module streams:
 llvm-toolset                         rhel8                                                                   
 perl                                 5.26                                                                    
 perl-IO-Socket-SSL                   2.066                                                                   
 perl-libwww-perl                     6.34                                                                    

Transaction Summary
===============================================================================================================
Install  87 Packages

Total download size: 223 M
Installed size: 702 M
Is this ok [y/N]: y
Downloading Packages:
(1/87): perl-libnet-3.11-3.el8.noarch.rpm                                      3.0 MB/s | 121 kB     00:00    
.
.
(中略)
.
.
Installed:
  bcc-0.25.0-2.el8.x86_64                                                                                      
  bcc-tools-0.25.0-2.el8.x86_64                                                                                
  binutils-2.30-119.el8.x86_64                                                                                 
.
.
(中略)
.
.
  scl-utils-1:2.0.2-16.el8.x86_64                                                                              
  tcl-1:8.6.8-2.el8.x86_64                                                                                     
  zlib-devel-1.2.11-21.el8_7.x86_64                                                                            

Complete!

RHEL 8.8にGitがインストールされていなかったので、インストールします。

$ sudo dnf install git -y
Updating Subscription Management repositories.
Unable to read consumer identity

This system is not registered with an entitlement server. You can use subscription-manager to register.

Last metadata expiration check: 0:04:19 ago on Fri 02 Jun 2023 01:48:33 AM UTC.
Dependencies resolved.
===============================================================================================================
 Package                  Architecture   Version                      Repository                          Size
===============================================================================================================
Installing:
 git                      x86_64         2.39.3-1.el8_8               rhel-8-appstream-rhui-rpms         104 k
Installing dependencies:
 emacs-filesystem         noarch         1:26.1-10.el8_8.2            rhel-8-baseos-rhui-rpms             70 k
 git-core                 x86_64         2.39.3-1.el8_8               rhel-8-appstream-rhui-rpms          11 M
 git-core-doc             noarch         2.39.3-1.el8_8               rhel-8-appstream-rhui-rpms         3.0 M
 perl-Error               noarch         1:0.17025-2.el8              rhel-8-appstream-rhui-rpms          46 k
 perl-Git                 noarch         2.39.3-1.el8_8               rhel-8-appstream-rhui-rpms          79 k
 perl-TermReadKey         x86_64         2.37-7.el8                   rhel-8-appstream-rhui-rpms          40 k

Transaction Summary
===============================================================================================================
Install  7 Packages

Total download size: 14 M
Installed size: 44 M
Downloading Packages:
(1/7): perl-Error-0.17025-2.el8.noarch.rpm                                     1.1 MB/s |  46 kB     00:00    
.
.
(中略)
.
.
Installed:
  emacs-filesystem-1:26.1-10.el8_8.2.noarch  git-2.39.3-1.el8_8.x86_64          git-core-2.39.3-1.el8_8.x86_64 
  git-core-doc-2.39.3-1.el8_8.noarch         perl-Error-1:0.17025-2.el8.noarch  perl-Git-2.39.3-1.el8_8.noarch 
  perl-TermReadKey-2.37-7.el8.x86_64        

Complete!

IMDSパケットアナライザーのコードをダウンロードします。

$ pwd
/home/ec2-user

$ git clone https://github.com/aws/aws-imds-packet-analyzer.git
Cloning into 'aws-imds-packet-analyzer'...
remote: Enumerating objects: 61, done.
remote: Counting objects: 100% (61/61), done.
remote: Compressing objects: 100% (50/50), done.
remote: Total 61 (delta 21), reused 38 (delta 7), pack-reused 0
Receiving objects: 100% (61/61), 29.39 KiB | 7.35 MiB/s, done.
Resolving deltas: 100% (21/21), done.

ダウンロード後、IMDSパケットアナライザーを実行します。

$ sudo python3 aws-imds-packet-analyzer/src/imds_snoop.py 
sudo: python3: command not found

RHEL 8にはデフォルトでユーザー用のPythonがインストールされていないのをすっかり忘れていました。

Python 3.9をインストールします。

# Pythonのモジュールを確認
$ sudo dnf module list python*
Updating Subscription Management repositories.
Unable to read consumer identity

This system is not registered with an entitlement server. You can use subscription-manager to register.

Last metadata expiration check: 0:00:27 ago on Fri 02 Jun 2023 04:17:08 AM UTC.
Red Hat Enterprise Linux 8 for x86_64 - AppStream from RHUI (RPMs)
Name              Stream           Profiles                   Summary                                          
python27          2.7 [d]          common [d]                 Python programming language, version 2.7         
python36          3.6 [d]          build, common [d]          Python programming language, version 3.6         
python38          3.8 [d]          build, common [d]          Python programming language, version 3.8         
python39          3.9 [d]          build, common [d]          Python programming language, version 3.9         

Hint: [d]efault, [e]nabled, [x]disabled, [i]nstalled

# Python 3.9をインストール
$ sudo dnf module install python39
Updating Subscription Management repositories.
Unable to read consumer identity

This system is not registered with an entitlement server. You can use subscription-manager to register.

Last metadata expiration check: 0:00:59 ago on Fri 02 Jun 2023 04:17:08 AM UTC.
Dependencies resolved.
===============================================================================================================
 Package                    Arch    Version                                  Repository                   Size
===============================================================================================================
Installing group/module packages:
 python39                   x86_64  3.9.16-1.module+el8.8.0+17625+b531f198   rhel-8-appstream-rhui-rpms   33 k
Installing dependencies:
 python39-libs              x86_64  3.9.16-1.module+el8.8.0+17625+b531f198   rhel-8-appstream-rhui-rpms  8.2 M
 python39-pip-wheel         noarch  20.2.4-7.module+el8.6.0+13003+6bb2c488   rhel-8-appstream-rhui-rpms  1.1 M
 python39-setuptools-wheel  noarch  50.3.2-4.module+el8.5.0+12204+54860423   rhel-8-appstream-rhui-rpms  497 k
Installing weak dependencies:
 python39-pip               noarch  20.2.4-7.module+el8.6.0+13003+6bb2c488   rhel-8-appstream-rhui-rpms  1.9 M
 python39-setuptools        noarch  50.3.2-4.module+el8.5.0+12204+54860423   rhel-8-appstream-rhui-rpms  871 k
Installing module profiles:
 python39/common                                                                                              
Enabling module streams:
 python39                           3.9                                                                       

Transaction Summary
===============================================================================================================
Install  6 Packages

Total download size: 13 M
Installed size: 45 M
Is this ok [y/N]: y 
Downloading Packages:
(1/6): python39-setuptools-50.3.2-4.module+el8.5.0+12204+54860423.noarch.rpm    13 MB/s | 871 kB     00:00    
.
.
(中略)
.
.
Installed:
  python39-3.9.16-1.module+el8.8.0+17625+b531f198.x86_64                                                       
  python39-libs-3.9.16-1.module+el8.8.0+17625+b531f198.x86_64                                                  
  python39-pip-20.2.4-7.module+el8.6.0+13003+6bb2c488.noarch                                                   
  python39-pip-wheel-20.2.4-7.module+el8.6.0+13003+6bb2c488.noarch                                             
  python39-setuptools-50.3.2-4.module+el8.5.0+12204+54860423.noarch                                            
  python39-setuptools-wheel-50.3.2-4.module+el8.5.0+12204+54860423.noarch                                      

Complete!

# Pythonのモジュールを確認
$ sudo dnf module list python*
Updating Subscription Management repositories.
Unable to read consumer identity

This system is not registered with an entitlement server. You can use subscription-manager to register.

Last metadata expiration check: 0:05:13 ago on Fri 02 Jun 2023 04:17:08 AM UTC.
Red Hat Enterprise Linux 8 for x86_64 - AppStream from RHUI (RPMs)
Name             Stream            Profiles                     Summary                                        
python27         2.7 [d]           common [d]                   Python programming language, version 2.7       
python36         3.6 [d]           build, common [d]            Python programming language, version 3.6       
python38         3.8 [d]           build, common [d]            Python programming language, version 3.8       
python39         3.9 [d][e]        build, common [d] [i]        Python programming language, version 3.9       

Hint: [d]efault, [e]nabled, [x]disabled, [i]nstalled

# python3 のパスが通っていることを確認
$ which python3
/usr/bin/python3

Python 3.9インストール後、IMDSパケットアナライザーを実行します。

$ sudo python3 aws-imds-packet-analyzer/src/imds_snoop.py 
Traceback (most recent call last):
  File "/home/ec2-user/aws-imds-packet-analyzer/src/imds_snoop.py", line 5, in <module>
    from bcc import BPF
ModuleNotFoundError: No module named 'bcc'

今度はBCCのパスがないと怒られてしまいました。

BCCのパスを確認します。

$ sudo find / -name bcc
/usr/lib/python3.6/site-packages/bcc
/usr/share/licenses/bcc
/usr/share/doc/bcc
/usr/share/bcc

/usr/lib/python3.6/site-packages/bccにありそうですね。

Pythonがロードしているパスを確認します。

$ python3
Python 3.9.16 (main, Dec 21 2022, 10:57:18) 
[GCC 8.5.0 20210514 (Red Hat 8.5.0-17)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> import pprint
>>> pprint.pprint(sys.path)
['',
 '/usr/lib64/python39.zip',
 '/usr/lib64/python3.9',
 '/usr/lib64/python3.9/lib-dynload',
 '/usr/lib64/python3.9/site-packages',
 '/usr/lib/python3.9/site-packages']

Python 3.9を指定してインストールしたので、/usr/lib/python3.6/site-packagesは含まれていませんね。

IMDSパケットアナライザーの動作にはroot権限が必要なので、/etc/profilePYTHONPATHを定義してあげましょう。

# /etc/profile に環境変数 PYTHONPATH を追加
$ sudo vi /etc/profile

# 編集箇所の確認
$ tail /etc/profile
        if [ -f /etc/bashrc ] ; then
                # Bash login shells run only /etc/profile
                # Bash non-login shells run only /etc/bashrc
                # Check for double sourcing is done in /etc/bashrc.
                . /etc/bashrc
       fi
fi

export PYTHONPATH="/usr/lib/python3.6/site-packages:$PYTHONPATH"

# root ユーザーにスイッチ
$ sudo -i

$ echo $PYTHONPATH
/usr/lib/python3.6/site-packages:

これでPythonが/usr/lib/python3.6/site-packagesをロードするようになりました。

この状態でIMDSパケットアナライザーを実行します。

$ cd /home/ec2-user/
$ python3 aws-imds-packet-analyzer/src/imds_snoop.py
Traceback (most recent call last):
  File "/home/ec2-user/aws-imds-packet-analyzer/src/imds_snoop.py", line 158, in <module>
    fileConfig('logging.conf')
  File "/usr/lib64/python3.9/logging/config.py", line 71, in fileConfig
    formatters = _create_formatters(cp)
  File "/usr/lib64/python3.9/logging/config.py", line 104, in _create_formatters
    flist = cp["formatters"]["keys"]
  File "/usr/lib64/python3.9/configparser.py", line 963, in __getitem__
    raise KeyError(key)
KeyError: 'formatters'

# ディレクトリを移動して再実行
$ cd aws-imds-packet-analyzer/
$ python3 src/imds_snoop.py
Starting ImdsPacketAnalyzer...
Currently logging to: /var/log/imds-trace.log
Output format: Info Level:[INFO/ERROR...] IMDS version:[IMDSV1/2?] (pid:[pid]:[process name]:argv:[argv]) -> repeats 3 times for parent process

実行できました。

トークンを取得せずにIMDSに直接リクエストして検出されるか確認

この状態で別のターミナルからこちらのEC2インスタンスに接続し、インスタンスメタデータにアクセスします。

$ curl http://169.254.169.254/latest/meta-data/
ami-id
ami-launch-index
ami-manifest-path
block-device-mapping/
events/
hostname
iam/
identity-credentials/
instance-action
instance-id
instance-life-cycle
instance-type
local-hostname
local-ipv4
mac
metrics/
network/
placement/
profile
public-hostname
public-ipv4
public-keys/
reservation-id
security-groups
services/
system

実行後、IMDSパケットアナライザーを実行しているターミナルに戻ると、以下のような出力がされていました。

$ python3 src/imds_snoop.py
Starting ImdsPacketAnalyzer...
Currently logging to: /var/log/imds-trace.log
Output format: Info Level:[INFO/ERROR...] IMDS version:[IMDSV1/2?] (pid:[pid]:[process name]:argv:[argv]) -> repeats 3 times for parent process
[INFO] IMDSv2 (pid:932:ssm-session-wor argv:/usr/bin/ssm-session-worker <IAMロール名>-062f102c8cc124c2f) called by -> (pid:692:ssm-agent-worke argv:/usr/bin/ssm-agent-worker) -> (pid:645:amazon-ssm-agen argv:/usr/bin/amazon-ssm-agent) -> (pid:645:systemd argv:/usr/lib/systemd/systemd --switched-root --system --deserialize 17)
[INFO] IMDSv2 (pid:932:ssm-session-wor argv:/usr/bin/ssm-session-worker <IAMロール名>-062f102c8cc124c2f) called by -> (pid:692:ssm-agent-worke argv:/usr/bin/ssm-agent-worker) -> (pid:645:amazon-ssm-agen argv:/usr/bin/amazon-ssm-agent) -> (pid:645:systemd argv:/usr/lib/systemd/systemd --switched-root --system --deserialize 17)
[INFO] IMDSv2 (pid:932:ssm-session-wor argv:/usr/bin/ssm-session-worker <IAMロール名>-062f102c8cc124c2f) called by -> (pid:692:ssm-agent-worke argv:/usr/bin/ssm-agent-worker) -> (pid:645:amazon-ssm-agen argv:/usr/bin/amazon-ssm-agent) -> (pid:645:systemd argv:/usr/lib/systemd/systemd --switched-root --system --deserialize 17)
[INFO] IMDSv2 (pid:932:ssm-session-wor argv:/usr/bin/ssm-session-worker <IAMロール名>-062f102c8cc124c2f) called by -> (pid:692:ssm-agent-worke argv:/usr/bin/ssm-agent-worker) -> (pid:645:amazon-ssm-agen argv:/usr/bin/amazon-ssm-agent) -> (pid:645:systemd argv:/usr/lib/systemd/systemd --switched-root --system --deserialize 17)
[INFO] IMDSv2 (pid:932:ssm-session-wor argv:/usr/bin/ssm-session-worker <IAMロール名>-062f102c8cc124c2f) called by -> (pid:692:ssm-agent-worke argv:/usr/bin/ssm-agent-worker) -> (pid:645:amazon-ssm-agen argv:/usr/bin/amazon-ssm-agent) -> (pid:645:systemd argv:/usr/lib/systemd/systemd --switched-root --system --deserialize 17)
[INFO] IMDSv2 (pid:932:ssm-session-wor argv:/usr/bin/ssm-session-worker <IAMロール名>-062f102c8cc124c2f) called by -> (pid:692:ssm-agent-worke argv:/usr/bin/ssm-agent-worker) -> (pid:645:amazon-ssm-agen argv:/usr/bin/amazon-ssm-agent) -> (pid:645:systemd argv:/usr/lib/systemd/systemd --switched-root --system --deserialize 17)
[WARNING] IMDSv1(!) (pid:983:curl argv:curl http://169.254.169.254/latest/meta-data/) called by -> (pid:945:bash argv:/bin/bash) -> (pid:944:sh argv:sh) -> (pid:944:ssm-session-wor argv:/usr/bin/ssm-session-worker <IAMロール名>-062f102c8cc124c2f)
Info:  [Errno 2] No such file or directory: '/proc/0/cmdline'
Info:  [Errno 2] No such file or directory: '/proc/0/cmdline'
[WARNING] IMDSv1(!) (pid:986:nm-cloud-setup argv:/usr/libexec/nm-cloud-setup) called by -> (pid:1:systemd argv:/usr/lib/systemd/systemd --switched-root --system --deserialize 17) -> (pid:0 Unable to get argv information) -> (pid:0 Unable to get argv information)
Info:  [Errno 2] No such file or directory: '/proc/0/cmdline'
Info:  [Errno 2] No such file or directory: '/proc/0/cmdline'
[WARNING] IMDSv1(!) (pid:986:nm-cloud-setup argv:/usr/libexec/nm-cloud-setup) called by -> (pid:1:systemd argv:/usr/lib/systemd/systemd --switched-root --system --deserialize 17) -> (pid:0 Unable to get argv information) -> (pid:0 Unable to get argv information)
[INFO] IMDSv2 (pid:994:ssm-document-wo argv:/usr/bin/ssm-document-worker 6778b6bf-81cf-4605-9770-022f0e3af205.2023-06-02T05-15-06.798Z) called by -> (pid:692:ssm-agent-worke argv:/usr/bin/ssm-agent-worker) -> (pid:645:amazon-ssm-agen argv:/usr/bin/amazon-ssm-agent) -> (pid:645:systemd argv:/usr/lib/systemd/systemd --switched-root --system --deserialize 17)
[INFO] IMDSv2 (pid:994:ssm-document-wo argv:/usr/bin/ssm-document-worker 6778b6bf-81cf-4605-9770-022f0e3af205.2023-06-02T05-15-06.798Z) called by -> (pid:692:ssm-agent-worke argv:/usr/bin/ssm-agent-worker) -> (pid:645:amazon-ssm-agen argv:/usr/bin/amazon-ssm-agent) -> (pid:645:systemd argv:/usr/lib/systemd/systemd --switched-root --system --deserialize 17)
[INFO] IMDSv2 (pid:994:ssm-document-wo argv:/usr/bin/ssm-document-worker 6778b6bf-81cf-4605-9770-022f0e3af205.2023-06-02T05-15-06.798Z) called by -> (pid:692:ssm-agent-worke argv:/usr/bin/ssm-agent-worker) -> (pid:645:amazon-ssm-agen argv:/usr/bin/amazon-ssm-agent) -> (pid:645:systemd argv:/usr/lib/systemd/systemd --switched-root --system --deserialize 17)
[INFO] IMDSv2 (pid:994:ssm-document-wo argv:/usr/bin/ssm-document-worker 6778b6bf-81cf-4605-9770-022f0e3af205.2023-06-02T05-15-06.798Z) called by -> (pid:692:ssm-agent-worke argv:/usr/bin/ssm-agent-worker) -> (pid:645:amazon-ssm-agen argv:/usr/bin/amazon-ssm-agent) -> (pid:645:systemd argv:/usr/lib/systemd/systemd --switched-root --system --deserialize 17)
[INFO] IMDSv2 (pid:994:ssm-document-wo argv:/usr/bin/ssm-document-worker 6778b6bf-81cf-4605-9770-022f0e3af205.2023-06-02T05-15-06.798Z) called by -> (pid:692:ssm-agent-worke argv:/usr/bin/ssm-agent-worker) -> (pid:645:amazon-ssm-agen argv:/usr/bin/amazon-ssm-agent) -> (pid:645:systemd argv:/usr/lib/systemd/systemd --switched-root --system --deserialize 17)
[INFO] IMDSv2 (pid:994:ssm-document-wo argv:/usr/bin/ssm-document-worker 6778b6bf-81cf-4605-9770-022f0e3af205.2023-06-02T05-15-06.798Z) called by -> (pid:692:ssm-agent-worke argv:/usr/bin/ssm-agent-worker) -> (pid:645:amazon-ssm-agen argv:/usr/bin/amazon-ssm-agent) -> (pid:645:systemd argv:/usr/lib/systemd/systemd --switched-root --system --deserialize 17)
Possibly lost 2 samples
[INFO] IMDSv2 (pid:994:ssm-document-wo argv:/usr/bin/ssm-document-worker 6778b6bf-81cf-4605-9770-022f0e3af205.2023-06-02T05-15-06.798Z) called by -> (pid:692:ssm-agent-worke argv:/usr/bin/ssm-agent-worker) -> (pid:645:amazon-ssm-agen argv:/usr/bin/amazon-ssm-agent) -> (pid:645:systemd argv:/usr/lib/systemd/systemd --switched-root --system --deserialize 17)

curlのコマンドがしっかりと記録されていますね。IMDSv1の場合はWARNINGでIMDSv2はINFOで記録されるようです。SSMエージェントはIMDSv2を使用していることが分かります。

1つ気になるのはnm-cloud-setupというプロセスです。

こちらのプロセスはRHELにインストールされているもののようです。

Red Hatのドキュメントを確認すると、インスタンスメタデータから設定情報を自動的に取得し、VMのネットワーク設定を更新する代物のようです。

現時点でnm-cloud-setupはIMDSv2をサポートしていないようです。ネットワーク設定関連のプロセスということもあり、RHELのEC2インスタンスでIMDSv1を無効化するのは難しそうです。

ログの確認

Ctrl + CでIMDSパケットアナライザーを停止させて、ログを確認します。

$ ls -l /var/log/imds-trace.log 
-rw-r--r--. 1 root root 8244 Jun  2 05:16 /var/log/imds-trace.log

$ cat /var/log/imds-trace.log
[2023-06-02T05:13:23] [INFO] IMDSv2 (pid:932:ssm-session-wor argv:/usr/bin/ssm-session-worker <IAMロール名>-062f102c8cc124c2f) called by -> (pid:692:ssm-agent-worke argv:/usr/bin/ssm-agent-worker) -> (pid:645:amazon-ssm-agen argv:/usr/bin/amazon-ssm-agent) -> (pid:645:systemd argv:/usr/lib/systemd/systemd --switched-root --system --deserialize 17)
[2023-06-02T05:13:23] [INFO] IMDSv2 (pid:932:ssm-session-wor argv:/usr/bin/ssm-session-worker <IAMロール名>-062f102c8cc124c2f) called by -> (pid:692:ssm-agent-worke argv:/usr/bin/ssm-agent-worker) -> (pid:645:amazon-ssm-agen argv:/usr/bin/amazon-ssm-agent) -> (pid:645:systemd argv:/usr/lib/systemd/systemd --switched-root --system --deserialize 17)
[2023-06-02T05:13:23] [INFO] IMDSv2 (pid:932:ssm-session-wor argv:/usr/bin/ssm-session-worker <IAMロール名>-062f102c8cc124c2f) called by -> (pid:692:ssm-agent-worke argv:/usr/bin/ssm-agent-worker) -> (pid:645:amazon-ssm-agen argv:/usr/bin/amazon-ssm-agent) -> (pid:645:systemd argv:/usr/lib/systemd/systemd --switched-root --system --deserialize 17)
[2023-06-02T05:13:23] [INFO] IMDSv2 (pid:932:ssm-session-wor argv:/usr/bin/ssm-session-worker <IAMロール名>-062f102c8cc124c2f) called by -> (pid:692:ssm-agent-worke argv:/usr/bin/ssm-agent-worker) -> (pid:645:amazon-ssm-agen argv:/usr/bin/amazon-ssm-agent) -> (pid:645:systemd argv:/usr/lib/systemd/systemd --switched-root --system --deserialize 17)
[2023-06-02T05:13:23] [INFO] IMDSv2 (pid:932:ssm-session-wor argv:/usr/bin/ssm-session-worker <IAMロール名>-062f102c8cc124c2f) called by -> (pid:692:ssm-agent-worke argv:/usr/bin/ssm-agent-worker) -> (pid:645:amazon-ssm-agen argv:/usr/bin/amazon-ssm-agent) -> (pid:645:systemd argv:/usr/lib/systemd/systemd --switched-root --system --deserialize 17)
[2023-06-02T05:13:23] [INFO] IMDSv2 (pid:932:ssm-session-wor argv:/usr/bin/ssm-session-worker <IAMロール名>-062f102c8cc124c2f) called by -> (pid:692:ssm-agent-worke argv:/usr/bin/ssm-agent-worker) -> (pid:645:amazon-ssm-agen argv:/usr/bin/amazon-ssm-agent) -> (pid:645:systemd argv:/usr/lib/systemd/systemd --switched-root --system --deserialize 17)
[2023-06-02T05:13:59] [WARNING] IMDSv1(!) (pid:983:curl argv:curl http://169.254.169.254/latest/meta-data/) called by -> (pid:945:bash argv:/bin/bash) -> (pid:944:sh argv:sh) -> (pid:944:ssm-session-wor argv:/usr/bin/ssm-session-worker <IAMロール名>-062f102c8cc124c2f)
[2023-06-02T05:15:03] [WARNING] IMDSv1(!) (pid:986:nm-cloud-setup argv:/usr/libexec/nm-cloud-setup) called by -> (pid:1:systemd argv:/usr/lib/systemd/systemd --switched-root --system --deserialize 17) -> (pid:0 Unable to get argv information) -> (pid:0 Unable to get argv information)
[2023-06-02T05:15:03] [WARNING] IMDSv1(!) (pid:986:nm-cloud-setup argv:/usr/libexec/nm-cloud-setup) called by -> (pid:1:systemd argv:/usr/lib/systemd/systemd --switched-root --system --deserialize 17) -> (pid:0 Unable to get argv information) -> (pid:0 Unable to get argv information)
[2023-06-02T05:15:06] [INFO] IMDSv2 (pid:994:ssm-document-wo argv:/usr/bin/ssm-document-worker 6778b6bf-81cf-4605-9770-022f0e3af205.2023-06-02T05-15-06.798Z) called by -> (pid:692:ssm-agent-worke argv:/usr/bin/ssm-agent-worker) -> (pid:645:amazon-ssm-agen argv:/usr/bin/amazon-ssm-agent) -> (pid:645:systemd argv:/usr/lib/systemd/systemd --switched-root --system --deserialize 17)
[2023-06-02T05:15:06] [INFO] IMDSv2 (pid:994:ssm-document-wo argv:/usr/bin/ssm-document-worker 6778b6bf-81cf-4605-9770-022f0e3af205.2023-06-02T05-15-06.798Z) called by -> (pid:692:ssm-agent-worke argv:/usr/bin/ssm-agent-worker) -> (pid:645:amazon-ssm-agen argv:/usr/bin/amazon-ssm-agent) -> (pid:645:systemd argv:/usr/lib/systemd/systemd --switched-root --system --deserialize 17)
[2023-06-02T05:15:06] [INFO] IMDSv2 (pid:994:ssm-document-wo argv:/usr/bin/ssm-document-worker 6778b6bf-81cf-4605-9770-022f0e3af205.2023-06-02T05-15-06.798Z) called by -> (pid:692:ssm-agent-worke argv:/usr/bin/ssm-agent-worker) -> (pid:645:amazon-ssm-agen argv:/usr/bin/amazon-ssm-agent) -> (pid:645:systemd argv:/usr/lib/systemd/systemd --switched-root --system --deserialize 17)
[2023-06-02T05:15:07] [INFO] IMDSv2 (pid:994:ssm-document-wo argv:/usr/bin/ssm-document-worker 6778b6bf-81cf-4605-9770-022f0e3af205.2023-06-02T05-15-06.798Z) called by -> (pid:692:ssm-agent-worke argv:/usr/bin/ssm-agent-worker) -> (pid:645:amazon-ssm-agen argv:/usr/bin/amazon-ssm-agent) -> (pid:645:systemd argv:/usr/lib/systemd/systemd --switched-root --system --deserialize 17)
[2023-06-02T05:15:07] [INFO] IMDSv2 (pid:994:ssm-document-wo argv:/usr/bin/ssm-document-worker 6778b6bf-81cf-4605-9770-022f0e3af205.2023-06-02T05-15-06.798Z) called by -> (pid:692:ssm-agent-worke argv:/usr/bin/ssm-agent-worker) -> (pid:645:amazon-ssm-agen argv:/usr/bin/amazon-ssm-agent) -> (pid:645:systemd argv:/usr/lib/systemd/systemd --switched-root --system --deserialize 17)
[2023-06-02T05:15:07] [INFO] IMDSv2 (pid:994:ssm-document-wo argv:/usr/bin/ssm-document-worker 6778b6bf-81cf-4605-9770-022f0e3af205.2023-06-02T05-15-06.798Z) called by -> (pid:692:ssm-agent-worke argv:/usr/bin/ssm-agent-worker) -> (pid:645:amazon-ssm-agen argv:/usr/bin/amazon-ssm-agent) -> (pid:645:systemd argv:/usr/lib/systemd/systemd --switched-root --system --deserialize 17)
[2023-06-02T05:15:07] [INFO] IMDSv2 (pid:994:ssm-document-wo argv:/usr/bin/ssm-document-worker 6778b6bf-81cf-4605-9770-022f0e3af205.2023-06-02T05-15-06.798Z) called by -> (pid:692:ssm-agent-worke argv:/usr/bin/ssm-agent-worker) -> (pid:645:amazon-ssm-agen argv:/usr/bin/amazon-ssm-agent) -> (pid:645:systemd argv:/usr/lib/systemd/systemd --switched-root --system --deserialize 17)
[2023-06-02T05:16:34] [INFO] IMDSv2 (pid:692:ssm-agent-worke argv:/usr/bin/ssm-agent-worker) called by -> (pid:645:amazon-ssm-agen argv:/usr/bin/amazon-ssm-agent) -> (pid:1:systemd argv:/usr/lib/systemd/systemd --switched-root --system --deserialize 17) -> (pid:1 Unable to get argv information)
[2023-06-02T05:16:34] [INFO] IMDSv2 (pid:692:ssm-agent-worke argv:/usr/bin/ssm-agent-worker) called by -> (pid:645:amazon-ssm-agen argv:/usr/bin/amazon-ssm-agent) -> (pid:1:systemd argv:/usr/lib/systemd/systemd --switched-root --system --deserialize 17) -> (pid:1 Unable to get argv information)
[2023-06-02T05:16:34] [INFO] IMDSv2 (pid:692:ssm-agent-worke argv:/usr/bin/ssm-agent-worker) called by -> (pid:645:amazon-ssm-agen argv:/usr/bin/amazon-ssm-agent) -> (pid:1:systemd argv:/usr/lib/systemd/systemd --switched-root --system --deserialize 17) -> (pid:1 Unable to get argv information)
[2023-06-02T05:16:34] [INFO] IMDSv2 (pid:692:ssm-agent-worke argv:/usr/bin/ssm-agent-worker) called by -> (pid:645:amazon-ssm-agen argv:/usr/bin/amazon-ssm-agent) -> (pid:1:systemd argv:/usr/lib/systemd/systemd --switched-root --system --deserialize 17) -> (pid:1 Unable to get argv information)
[2023-06-02T05:16:34] [INFO] IMDSv2 (pid:692:ssm-agent-worke argv:/usr/bin/ssm-agent-worker) called by -> (pid:645:amazon-ssm-agen argv:/usr/bin/amazon-ssm-agent) -> (pid:1:systemd argv:/usr/lib/systemd/systemd --switched-root --system --deserialize 17) -> (pid:1 Unable to get argv information)
[2023-06-02T05:16:34] [INFO] IMDSv2 (pid:692:ssm-agent-worke argv:/usr/bin/ssm-agent-worker) called by -> (pid:645:amazon-ssm-agen argv:/usr/bin/amazon-ssm-agent) -> (pid:1:systemd argv:/usr/lib/systemd/systemd --switched-root --system --deserialize 17) -> (pid:1 Unable to get argv information)
[2023-06-02T05:16:42] [INFO] IMDSv2 (pid:645:amazon-ssm-agen argv:/usr/bin/amazon-ssm-agent) called by -> (pid:1:systemd argv:/usr/lib/systemd/systemd --switched-root --system --deserialize 17) -> (pid:0 Unable to get argv information) -> (pid:0 Unable to get argv information)
[2023-06-02T05:16:42] [INFO] IMDSv2 (pid:645:amazon-ssm-agen argv:/usr/bin/amazon-ssm-agent) called by -> (pid:1:systemd argv:/usr/lib/systemd/systemd --switched-root --system --deserialize 17) -> (pid:0 Unable to get argv information) -> (pid:0 Unable to get argv information)
[2023-06-02T05:16:42] [INFO] IMDSv2 (pid:645:amazon-ssm-agen argv:/usr/bin/amazon-ssm-agent) called by -> (pid:1:systemd argv:/usr/lib/systemd/systemd --switched-root --system --deserialize 17) -> (pid:0 Unable to get argv information) -> (pid:0 Unable to get argv information)

タイムスタンプと共にどのプロセスがIMDSv1 / IMDSv2なのか確認できて良い感じです。

IMDSパケットアナライザーのサービスを起動した場合の動作確認

IMDSパケットアナライザーをサービスとして登録して動作させることも可能です。

$ sudo ./activate-tracer-service.sh
--- removing old service file
rm: cannot remove '/etc/systemd/system/imds_tracer_tool.service': No such file or directory
--- create new Unit file
--- add service details
--- Service details:

[Unit]
Description=ImdsPacketAnalyzer IMDS detection tooling from AWS
Before=network-online.target
After=multi-user.target

[Service]
Type=simple
Restart=always
WorkingDirectory=/home/ec2-user/aws-imds-packet-analyzer
ExecStart=/bin/python3 /home/ec2-user/aws-imds-packet-analyzer/src/imds_snoop.py

[Install]
WantedBy=multi-user.target

--- reload daemon and enable the imds_tracer_tool.service service
Created symlink /etc/systemd/system/multi-user.target.wants/imds_tracer_tool.service → /etc/systemd/system/imds_tracer_tool.service.
--- start the imds_tracer_tool.service service
--- done

ユニットファイルが作成されて、サービスを起動したようですね。サービスの状態を確認します。

$ systemctl status imds_tracer_tool
● imds_tracer_tool.service - ImdsPacketAnalyzer IMDS detection tooling from AWS
   Loaded: loaded (/etc/systemd/system/imds_tracer_tool.service; enabled; vendor preset: disabled)
   Active: failed (Result: exit-code) since Fri 2023-06-02 05:43:40 UTC; 52s ago
  Process: 1248 ExecStart=/bin/python3 /home/ec2-user/aws-imds-packet-analyzer/src/imds_snoop.py (code=exited, status=1/FAILURE)
 Main PID: 1248 (code=exited, status=1/FAILURE)

Jun 02 05:43:40 ip-172-31-23-75.ec2.internal systemd[1]: imds_tracer_tool.service: Service RestartSec=100ms expired, scheduling restart.
Jun 02 05:43:40 ip-172-31-23-75.ec2.internal systemd[1]: imds_tracer_tool.service: Scheduled restart job, restart counter is at 5.
Jun 02 05:43:40 ip-172-31-23-75.ec2.internal systemd[1]: Stopped ImdsPacketAnalyzer IMDS detection tooling from AWS.
Jun 02 05:43:40 ip-172-31-23-75.ec2.internal systemd[1]: imds_tracer_tool.service: Start request repeated too quickly.
Jun 02 05:43:40 ip-172-31-23-75.ec2.internal systemd[1]: imds_tracer_tool.service: Failed with result 'exit-code'.
Jun 02 05:43:40 ip-172-31-23-75.ec2.internal systemd[1]: Failed to start ImdsPacketAnalyzer IMDS detection tooling from AWS.

サービスの起動に失敗していますね。

journalctlでログを確認するとBCCをインポートできていないようでした。

Jun 02 05:43:38 ip-172-31-23-75.ec2.internal sudo[1198]: ec2-user : TTY=pts/2 ; PWD=/home/ec2-user/aws-imds-packet-analyzer ; USER=root ; COMMAND=./activate-tracer-service.sh
Jun 02 05:43:38 ip-172-31-23-75.ec2.internal systemd-logind[599]: New session c8 of user root.
Jun 02 05:43:38 ip-172-31-23-75.ec2.internal systemd[1]: Started Session c8 of user root.
Jun 02 05:43:38 ip-172-31-23-75.ec2.internal sudo[1198]: pam_unix(sudo:session): session opened for user root by (uid=0)
Jun 02 05:43:38 ip-172-31-23-75.ec2.internal systemd[1]: Reloading.
Jun 02 05:43:38 ip-172-31-23-75.ec2.internal systemd[1]: Reloading.
Jun 02 05:43:39 ip-172-31-23-75.ec2.internal systemd[1]: Started ImdsPacketAnalyzer IMDS detection tooling from AWS.
Jun 02 05:43:39 ip-172-31-23-75.ec2.internal sudo[1198]: pam_unix(sudo:session): session closed for user root
Jun 02 05:43:39 ip-172-31-23-75.ec2.internal systemd[1]: session-c8.scope: Succeeded.
Jun 02 05:43:39 ip-172-31-23-75.ec2.internal systemd-logind[599]: Session c8 logged out. Waiting for processes to exit.
Jun 02 05:43:39 ip-172-31-23-75.ec2.internal systemd-logind[599]: Removed session c8.
Jun 02 05:43:39 ip-172-31-23-75.ec2.internal python3[1238]: Traceback (most recent call last):
Jun 02 05:43:39 ip-172-31-23-75.ec2.internal python3[1238]:   File "/home/ec2-user/aws-imds-packet-analyzer/src/imds_snoop.py", line 5, in <module>
Jun 02 05:43:39 ip-172-31-23-75.ec2.internal python3[1238]:     from bcc import BPF
Jun 02 05:43:39 ip-172-31-23-75.ec2.internal python3[1238]: ModuleNotFoundError: No module named 'bcc'
Jun 02 05:43:39 ip-172-31-23-75.ec2.internal systemd[1]: imds_tracer_tool.service: Main process exited, code=exited, status=1/FAILURE
Jun 02 05:43:39 ip-172-31-23-75.ec2.internal systemd[1]: imds_tracer_tool.service: Failed with result 'exit-code'.
Jun 02 05:43:39 ip-172-31-23-75.ec2.internal systemd[1]: imds_tracer_tool.service: Service RestartSec=100ms expired, scheduling restart.
Jun 02 05:43:39 ip-172-31-23-75.ec2.internal systemd[1]: imds_tracer_tool.service: Scheduled restart job, restart counter is at 1.
Jun 02 05:43:39 ip-172-31-23-75.ec2.internal systemd[1]: Stopped ImdsPacketAnalyzer IMDS detection tooling from AWS.
Jun 02 05:43:39 ip-172-31-23-75.ec2.internal systemd[1]: Started ImdsPacketAnalyzer IMDS detection tooling from AWS.
Jun 02 05:43:39 ip-172-31-23-75.ec2.internal python3[1242]: Traceback (most recent call last):
Jun 02 05:43:39 ip-172-31-23-75.ec2.internal python3[1242]:   File "/home/ec2-user/aws-imds-packet-analyzer/src/imds_snoop.py", line 5, in <module>
Jun 02 05:43:39 ip-172-31-23-75.ec2.internal python3[1242]:     from bcc import BPF
Jun 02 05:43:39 ip-172-31-23-75.ec2.internal python3[1242]: ModuleNotFoundError: No module named 'bcc'
Jun 02 05:43:39 ip-172-31-23-75.ec2.internal systemd[1]: imds_tracer_tool.service: Main process exited, code=exited, status=1/FAILURE
Jun 02 05:43:39 ip-172-31-23-75.ec2.internal systemd[1]: imds_tracer_tool.service: Failed with result 'exit-code'.
Jun 02 05:43:39 ip-172-31-23-75.ec2.internal systemd[1]: imds_tracer_tool.service: Service RestartSec=100ms expired, scheduling restart.
Jun 02 05:43:39 ip-172-31-23-75.ec2.internal systemd[1]: imds_tracer_tool.service: Scheduled restart job, restart counter is at 2.
Jun 02 05:43:39 ip-172-31-23-75.ec2.internal systemd[1]: Stopped ImdsPacketAnalyzer IMDS detection tooling from AWS.
Jun 02 05:43:39 ip-172-31-23-75.ec2.internal systemd[1]: Started ImdsPacketAnalyzer IMDS detection tooling from AWS.
Jun 02 05:43:39 ip-172-31-23-75.ec2.internal python3[1244]: Traceback (most recent call last):
Jun 02 05:43:39 ip-172-31-23-75.ec2.internal python3[1244]:   File "/home/ec2-user/aws-imds-packet-analyzer/src/imds_snoop.py", line 5, in <module>
Jun 02 05:43:39 ip-172-31-23-75.ec2.internal python3[1244]:     from bcc import BPF
Jun 02 05:43:39 ip-172-31-23-75.ec2.internal python3[1244]: ModuleNotFoundError: No module named 'bcc'
.
.
(中略)
.
.
Jun 02 05:43:40 ip-172-31-23-75.ec2.internal systemd[1]: imds_tracer_tool.service: Main process exited, code=exited, status=1/FAILURE
Jun 02 05:43:40 ip-172-31-23-75.ec2.internal systemd[1]: imds_tracer_tool.service: Failed with result 'exit-code'.
Jun 02 05:43:40 ip-172-31-23-75.ec2.internal systemd[1]: imds_tracer_tool.service: Service RestartSec=100ms expired, scheduling restart.
Jun 02 05:43:40 ip-172-31-23-75.ec2.internal systemd[1]: imds_tracer_tool.service: Scheduled restart job, restart counter is at 5.
Jun 02 05:43:40 ip-172-31-23-75.ec2.internal systemd[1]: Stopped ImdsPacketAnalyzer IMDS detection tooling from AWS.
Jun 02 05:43:40 ip-172-31-23-75.ec2.internal systemd[1]: imds_tracer_tool.service: Start request repeated too quickly.
Jun 02 05:43:40 ip-172-31-23-75.ec2.internal systemd[1]: imds_tracer_tool.service: Failed with result 'exit-code'.
Jun 02 05:43:40 ip-172-31-23-75.ec2.internal systemd[1]: Failed to start ImdsPacketAnalyzer IMDS detection tooling from AWS.

systemdは/etc/profileを読み込みません。今回は対応としてユニットファイルに直接PYTHONPATHを定義します。

# ユニットファイルの編集
$ sudo vi /etc/systemd/system/imds_tracer_tool.service

# 編集したユニットファイルの確認
$ cat /etc/systemd/system/imds_tracer_tool.service
[Unit]
Description=ImdsPacketAnalyzer IMDS detection tooling from AWS
Before=network-online.target
After=multi-user.target

[Service]
Type=simple
Restart=always
WorkingDirectory=/home/ec2-user/aws-imds-packet-analyzer
ExecStart=/bin/python3 /home/ec2-user/aws-imds-packet-analyzer/src/imds_snoop.py
Environment=PYTHONPATH=/usr/lib/python3.6/site-packages:$PYTHONPATH

[Install]
WantedBy=multi-user.target

# リロード
$ sudo systemctl daemon-reload

# サービスの起動
$ sudo systemctl start imds_tracer_tool

# サービスが起動したか確認
$ systemctl status imds_tracer_tool
● imds_tracer_tool.service - ImdsPacketAnalyzer IMDS detection tooling from AWS
   Loaded: loaded (/etc/systemd/system/imds_tracer_tool.service; enabled; vendor preset: disabled)
   Active: active (running) since Fri 2023-06-02 07:03:07 UTC; 13s ago
 Main PID: 1997 (python3)
    Tasks: 1 (limit: 4303)
   Memory: 124.3M
   CGroup: /system.slice/imds_tracer_tool.service
           └─1997 /bin/python3 /home/ec2-user/aws-imds-packet-analyzer/src/imds_snoop.py

Jun 02 07:03:07 ip-172-31-23-75.ec2.internal systemd[1]: Started ImdsPacketAnalyzer IMDS detection tooling from AWS.

無事に起動できましたね。

この状態で、インスタンスメタデータにアクセスします。

$ curl http://169.254.169.254/latest/meta-data/
ami-id
ami-launch-index
ami-manifest-path
block-device-mapping/
events/
hostname
iam/
identity-credentials/
instance-action
instance-id
instance-life-cycle
instance-type
local-hostname
local-ipv4
mac
metrics/
network/
placement/
profile
public-hostname
public-ipv4
public-keys/
reservation-id
security-groups
services/
system

実行後、IMDSパケットアナライザーのログを確認します。

$ tail /var/log/imds-trace.log
[2023-06-02T05:16:34] [INFO] IMDSv2 (pid:692:ssm-agent-worke argv:/usr/bin/ssm-agent-worker) called by -> (pid:645:amazon-ssm-agen argv:/usr/bin/amazon-ssm-agent) -> (pid:1:systemd argv:/usr/lib/systemd/systemd --switched-root --system --deserialize 17) -> (pid:1 Unable to get argv information)
[2023-06-02T05:16:34] [INFO] IMDSv2 (pid:692:ssm-agent-worke argv:/usr/bin/ssm-agent-worker) called by -> (pid:645:amazon-ssm-agen argv:/usr/bin/amazon-ssm-agent) -> (pid:1:systemd argv:/usr/lib/systemd/systemd --switched-root --system --deserialize 17) -> (pid:1 Unable to get argv information)
[2023-06-02T05:16:34] [INFO] IMDSv2 (pid:692:ssm-agent-worke argv:/usr/bin/ssm-agent-worker) called by -> (pid:645:amazon-ssm-agen argv:/usr/bin/amazon-ssm-agent) -> (pid:1:systemd argv:/usr/lib/systemd/systemd --switched-root --system --deserialize 17) -> (pid:1 Unable to get argv information)
[2023-06-02T05:16:34] [INFO] IMDSv2 (pid:692:ssm-agent-worke argv:/usr/bin/ssm-agent-worker) called by -> (pid:645:amazon-ssm-agen argv:/usr/bin/amazon-ssm-agent) -> (pid:1:systemd argv:/usr/lib/systemd/systemd --switched-root --system --deserialize 17) -> (pid:1 Unable to get argv information)
[2023-06-02T05:16:34] [INFO] IMDSv2 (pid:692:ssm-agent-worke argv:/usr/bin/ssm-agent-worker) called by -> (pid:645:amazon-ssm-agen argv:/usr/bin/amazon-ssm-agent) -> (pid:1:systemd argv:/usr/lib/systemd/systemd --switched-root --system --deserialize 17) -> (pid:1 Unable to get argv information)
[2023-06-02T05:16:34] [INFO] IMDSv2 (pid:692:ssm-agent-worke argv:/usr/bin/ssm-agent-worker) called by -> (pid:645:amazon-ssm-agen argv:/usr/bin/amazon-ssm-agent) -> (pid:1:systemd argv:/usr/lib/systemd/systemd --switched-root --system --deserialize 17) -> (pid:1 Unable to get argv information)
[2023-06-02T05:16:42] [INFO] IMDSv2 (pid:645:amazon-ssm-agen argv:/usr/bin/amazon-ssm-agent) called by -> (pid:1:systemd argv:/usr/lib/systemd/systemd --switched-root --system --deserialize 17) -> (pid:0 Unable to get argv information) -> (pid:0 Unable to get argv information)
[2023-06-02T05:16:42] [INFO] IMDSv2 (pid:645:amazon-ssm-agen argv:/usr/bin/amazon-ssm-agent) called by -> (pid:1:systemd argv:/usr/lib/systemd/systemd --switched-root --system --deserialize 17) -> (pid:0 Unable to get argv information) -> (pid:0 Unable to get argv information)
[2023-06-02T05:16:42] [INFO] IMDSv2 (pid:645:amazon-ssm-agen argv:/usr/bin/amazon-ssm-agent) called by -> (pid:1:systemd argv:/usr/lib/systemd/systemd --switched-root --system --deserialize 17) -> (pid:0 Unable to get argv information) -> (pid:0 Unable to get argv information)
[2023-06-02T07:05:02] [WARNING] IMDSv1(!) (pid:2010:curl argv:curl http://169.254.169.254/latest/meta-data/) called by -> (pid:1876:bash argv:/bin/bash) -> (pid:1875:sh argv:sh) -> (pid:1875:ssm-session-wor argv:/usr/bin/ssm-session-worker <IAMロール名>-0d7c5cc7845745a08)

しっかりログに記録されていますね。

動作確認が終わったのでサービスから削除します。

deactivate-tracer-service.shというサービス解除などを丸っとしてくれるスクリプトがあるので実行します。

$ sudo ./deactivate-tracer-service.sh
--- stopping tracer service
--- removing service file (unit file)
--- reload daemons

[INFO] Associated log files can be found in the /var/log/ directory
Run the following command to delete all log files: 
sudo rm /var/log/imds-trace.*

$ ls -l /etc/systemd/system/imds_tracer_tool.service
ls: cannot access '/etc/systemd/system/imds_tracer_tool.service': No such file or directory

$ ls -l /var/log/imds-trace.*
-rw-r--r--. 1 root root 13789 Jun  2 07:12 /var/log/imds-trace.log

ユニットファイルが削除されましたね。

IMDSv2のみ許可する時の下調べにかなり役立つぞ

IMDSv1を使用しているか判断できるIMDSパケットアナライザーを紹介しました。

IMDSv2のみ許可する時の下調べにかなり役立ちますね。IMDSv1で動作しているプロセスがあれば、改修可能か確認しましょう。

IMDSv2への移行プロセスは以下AWS公式ドキュメントに記載されています。

この記事が誰かの助けになれば幸いです。

以上、AWS事業本部 コンサルティング部の のんピ(@non____97)でした!