iptablesでインスタンスメタデータへのアクセスをブロックしてIAMロールの権限を無効化してみた
はじめに
今回は、EC2インスタンスのiptablesでインスタンスメタデータへのアクセスをブロックして、IAMロールの権限を無効化してみました。
試してみようと思ったきっかけは、AWSでのプロキシ利用について勉強していた時に、以下の記事を見つけたことです。
169.254.169.254はインスタンスメタデータへのアクセスに使われること、IAMロールの権限の利用にメタデータへのアクセスが必要であることが記載されています。
また、以下の記事にも同様の記載がありました。
これらを見て、「iptablesで169.254.169.254へのアクセスを制限すれば、IAMロールの権限が無効化されるのか?」を試してみたくなったので、やってみました。
今回の環境について
今回は、AmazonS3ReadOnlyAccessの権限をIAMロールで付与したEC2インスタンスを用意しました。
[cloudshell-user@ip-10-0-104-65 ~]$ aws ec2 describe-instances --region ap-northeast-1 --instance-ids i-xxxxxxxxxxxxxxxxx \ > --query Reservations[].Instances[].IamInstanceProfile.Arn \ > --output text arn:aws:iam::xxxxxxxxxxxxx:instance-profile/ec2-sample-s3readonly [cloudshell-user@ip-10-0-104-65 ~]$ [cloudshell-user@ip-10-0-104-65 ~]$ [cloudshell-user@ip-10-0-104-65 ~]$ [cloudshell-user@ip-10-0-104-65 ~]$ aws iam list-attached-role-policies --role-name ec2-sample-s3readonly { "AttachedPolicies": [ { "PolicyName": "AmazonS3ReadOnlyAccess", "PolicyArn": "arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess" } ] } [cloudshell-user@ip-10-0-104-65 ~]$
また、対象のEC2インスタンスのバージョンは以下です。
[ec2-user@ip-10-0-11-11 ~]$ asw --version aws-cli/1.18.147 Python/2.7.18 Linux/4.14.225-168.357.amzn2.x86_64 botocore/1.18.6 [ec2-user@ip-10-0-11-11 ~]$
事前アクセス確認
まずはiptablesを設定する前に、インスタンスメタデータへのアクセスが可能であること、S3のリストが表示可能であることを確認してみます。
インスタンスメタデータへのアクセス
インスタンスメタデータへのアクセスは、curl http://169.254.169.254/latest/meta-data/
で実施します。また、IAMロールから提供されたセキュリティ認証情報は、メタデータの中のiam/security-credentials/<ロール名>
でアクセス可能です。
[ec2-user@ip-10-0-11-11 ~]$ curl http://169.254.169.254/latest/meta-data/ ami-id ami-launch-index ami-manifest-path block-device-mapping/ events/ hibernation/ 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/[ec2-user@ip-10-0-11-11 ~] [ec2-user@ip-10-0-11-11 ~]$ [ec2-user@ip-10-0-11-11 ~]$ [ec2-user@ip-10-0-11-11 ~]$ [ec2-user@ip-10-0-11-11 ~]$ curl http://169.254.169.254/latest/meta-data/iam/security-credentials/ec2-sample-s3readonly { "Code" : "Success", "LastUpdated" : "2021-08-22T06:40:36Z", "Type" : "AWS-HMAC", "AccessKeyId" : "ASIATxxxxxxxxxx73ZJD", "SecretAccessKey" : "/7ri3Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxo8Rn", "Token" : "~省略~", "Expiration" : "2021-08-22T13:15:46Z"
メタデータへのアクセスは問題ありませんでした。
S3へのアクセス
続いて、S3へのアクセスが問題ないか確認します。
[ec2-user@ip-10-0-11-11 ~]$ aws s3 ls 2021-05-16 09:21:40 cf-templates-xxxxxxxxxxxx-ap-northeast-1 [ec2-user@ip-10-0-11-11 ~]$
こちらも問題なく表示されました。
iptablesの設定
それではiptablesの設定をしていきます。
とはいったものの、そもそもiptablesはインストールされているのでしょうか?分からなかったので確認してみます。
iptablesの確認
[ec2-user@ip-10-0-11-11 ~]$ sudo which iptables /sbin/iptables [ec2-user@ip-10-0-11-11 ~]$ [ec2-user@ip-10-0-11-11 ~]$ [ec2-user@ip-10-0-11-11 ~]$ sudo iptables -nL Chain INPUT (policy ACCEPT) target prot opt source destination Chain FORWARD (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination [ec2-user@ip-10-0-11-11 ~]$
コマンドはありますし、設定も一見すると存在するように見えますね。設定ファイルやサービスの有無はどうでしょうか。
[ec2-user@ip-10-0-11-11 ~]$ sudo systemctl list-unit-files --type=service | grep iptables [ec2-user@ip-10-0-11-11 ~]$ [ec2-user@ip-10-0-11-11 ~]$ sudo cat /etc/sysconfig/iptables cat: /etc/sysconfig/iptables: No such file or directory [ec2-user@ip-10-0-11-11 ~]$
見つかりませんでした。どうも、「iptablesコマンドはあるけどiptablesサービスはない」状態みたいですね。。
iptablesサービスのインストール
このままだとコマンドが通ってもiptablesが効かないので、サービスをインストールします。
[ec2-user@ip-10-0-11-11 ~]$ sudo yum -y install iptables-services Loaded plugins: extras_suggestions, langpacks, priorities, update-motd amzn2-core | 3.7 kB 00:00 Resolving Dependencies --> Running transaction check ---> Package iptables-services.x86_64 0:1.8.4-10.amzn2.1.2 will be installed --> Finished Dependency Resolution Dependencies Resolved ================================================================================ Package Arch Version Repository Size ================================================================================ Installing: iptables-services x86_64 1.8.4-10.amzn2.1.2 amzn2-core 58 k Transaction Summary ================================================================================ Install 1 Package Total download size: 58 k Installed size: 24 k Downloading packages: iptables-services-1.8.4-10.amzn2.1.2.x86_64.rpm | 58 kB 00:00 Running transaction check Running transaction test Transaction test succeeded Running transaction Installing : iptables-services-1.8.4-10.a [ ] 1/1 Installing : iptables-services-1.8.4-10.a [### ] 1/1 Installing : iptables-services-1.8.4-10.a [###### ] 1/1 Installing : iptables-services-1.8.4-10.a [####### ] 1/1 Installing : iptables-services-1.8.4-10.a [######## ] 1/1 Installing : iptables-services-1.8.4-10.a [################## ] 1/1 Installing : iptables-services-1.8.4-10.a [############################ ] 1/1 Installing : iptables-services-1.8.4-10.amzn2.1.2.x86_64 1/1 Verifying : iptables-services-1.8.4-10.amzn2.1.2.x86_64 1/1 Installed: iptables-services.x86_64 0:1.8.4-10.amzn2.1.2 Complete! [ec2-user@ip-10-0-11-11 ~]$ [ec2-user@ip-10-0-11-11 ~]$
インストールが出来たので、改めて設定ファイルやサービスの有無を確認してみます。
[ec2-user@ip-10-0-11-11 ~]$ sudo cat /etc/sysconfig/iptables # sample configuration for iptables service # you can edit this manually or use system-config-firewall # please do not ask us to add additional ports/services to this default configuration *filter :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT -A INPUT -p icmp -j ACCEPT -A INPUT -i lo -j ACCEPT -A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT -A INPUT -j REJECT --reject-with icmp-host-prohibited -A FORWARD -j REJECT --reject-with icmp-host-prohibited COMMIT [ec2-user@ip-10-0-11-11 ~]$ [ec2-user@ip-10-0-11-11 ~]$ sudo systemctl list-unit-files --type=service | grep iptables iptables.service disabled
問題ないようです。
iptablesの設定投入
それではiptablesの設定を入れていきます。メタデータへのアクセスはHTTPで行うので80番ポートだけ閉じれば大丈夫そうですが、今回は面倒なので169.254.169.254へのアクセスを全てDROPしてしまいます。
[ec2-user@ip-10-0-11-11 ~]$ sudo iptables -I OUTPUT 1 -p tcp -d 169.254.169.254 -j DROP [ec2-user@ip-10-0-11-11 ~]$ [ec2-user@ip-10-0-11-11 ~]$ sudo iptables -L Chain INPUT (policy ACCEPT) target prot opt source destination Chain FORWARD (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination DROP tcp -- anywhere instance-data.ap-northeast-1.compute.internal [ec2-user@ip-10-0-11-11 ~]$ [ec2-user@ip-10-0-11-11 ~]$ [ec2-user@ip-10-0-11-11 ~]$ sudo service iptables save iptables: Saving firewall rules to /etc/sysconfig/iptables: [ OK ] [ec2-user@ip-10-0-11-11 ~]$ [ec2-user@ip-10-0-11-11 ~]$ sudo service iptables restart Redirecting to /bin/systemctl restart iptables.service [ec2-user@ip-10-0-11-11 ~]$
" instance-data.ap-northeast-1.compute.internal "へのDROP設定が入りました。
事後アクセス確認
それでは再度メタデータとS3へのアクセスを確認してみます。
[ec2-user@ip-10-0-11-11 ~]$ curl http://169.254.169.254/latest/meta-data/ ^C [ec2-user@ip-10-0-11-11 ~]$ [ec2-user@ip-10-0-11-11 ~]$ curl http://169.254.169.254/latest/meta-data/iam/security-credentials/ec2-sample-s3readonly ^C [ec2-user@ip-10-0-11-11 ~]$ [ec2-user@ip-10-0-11-11 ~]$ [ec2-user@ip-10-0-11-11 ~]$ aws s3 ls Unable to locate credentials. You can configure credentials by running "aws configure". [ec2-user@ip-10-0-11-11 ~]$
想定通り、メタデータとS3へのアクセスが出来なくなりました。
おわりに
というわけで、想定通りにiptablesでメタデータへのアクセスをブロックすることで、IAMロールの権限を無効化することができました。
実際にEC2インスタンスでiptablesを使う機会はあまり無いとは思いますが、メタデータが認証に使われていることが確認できて良かったです。