【小ネタ】Amazon LinuxのYumアップデートでハマったことと暫定対処【BADノウハウ】
こんにちは、三井田です。
今回は、環境に特殊な事情で Amazon Linux の yum update が出来なかったのですが、一時的な回避方法を検証しましたので紹介したいと思います。
Amazon LinuxのYum Updateに必要な要件
Amazon LinuxのYumリポジトリは、AWSの内部からしかアクセスが許可されていないようです。
また、リポジトリのURLを正引きした結果より、YumリポジトリはAmazon S3でホストされていると思われ、複数のグローバルIPに解決されることがわかりました。そのため、特定のIPアドレスが必ず紐付いているとは保証がありません。
Yum Updateに失敗した特殊な事情
- VPCとオンプレミスが連携する構成で、デフォルトルートがオンプレミス側を向いている環境
上記の環境では、EC2インスタンス -> Virtual Private Gateway (VGW) -> オンプレミス -> オンプレミス側のファイアウォール -> インターネットという経路となり、リポジトリへのソースIPアドレスが、AWS外部のアドレスとなってしまい、Amazon Linuxのリポジトリを利用できない環境となってしまいます。
暫定的な対処法
この手順は、AWSにより保証されているものではありません。
あくまでも、一時的な回避策として、ご自身の責任の元ご利用ください。
編集するファイルはバックアップを取り、本番環境への適用前に十分にテストされることをお勧めします。
概要
- リポジトリファイルを編集し、mirrorlistではなく、baseurlで利用するリポジトリを固定します(手順1)
- リポジトリのURLとグローバルIPアドレスを /etc/hosts ファイルで決め打ちします(手順2)
- サブネットに紐づくルーティングテーブルを編集し、上記のグローバルIPアドレス宛の通信は、Internet Gateway (IGW)かNATインスタンス経由に変更します(手順3)
- Yumのキャッシュをクリアし、アップデートやインストールを実行する(手順4)
手順1)リポジトリファイルの編集
編集する対象ファイルは、次の2つです。
amzn-main.repoファイルの[amzn-main]セクションと、amzn-updates.repoファイルの[amzn-updates]セクションをそれぞれ修正します。
以下は、Amazon Linux 2014.09での例です。
amzn-main.repoファイル
# diff -u /tmp/amzn-main.repo.orig /etc/yum.repo.d/amzn-main.repo --- /tmp/amzn-main.repo.orig 2014-09-18 00:50:30.000000000 +0000 +++ amzn-main.repo 2014-10-10 06:51:32.731649837 +0000 @@ -1,6 +1,7 @@ [amzn-main] name=amzn-main-Base -mirrorlist=http://repo.$awsregion.$awsdomain/$releasever/main/mirror.list +#mirrorlist=http://repo.$awsregion.$awsdomain/$releasever/main/mirror.list +baseurl=http://packages.ap-northeast-1.amazonaws.com/2014.09/main/20140901f63e/$basearch mirror_expire=300 metadata_expire=300 priority=10
amzn-updates.repoファイル
# diff -u /tmp/amzn-updates.repo.orig /etc/yum.repo.d/amzn-updates.repo --- /tmp/amzn-updates.repo.orig 2014-10-10 06:55:43.998732508 +0000 +++ amzn-updates.repo 2014-10-10 06:55:03.839510963 +0000 @@ -1,6 +1,7 @@ [amzn-updates] name=amzn-updates-Base -mirrorlist=http://repo.$awsregion.$awsdomain/$releasever/updates/mirror.list +#mirrorlist=http://repo.$awsregion.$awsdomain/$releasever/updates/mirror.list +baseurl=http://packages.ap-northeast-1.amazonaws.com/2014.09/updates/fcc817a89f59/$basearch mirror_expire=300 metadata_expire=300 priority=10
いずれも、mirrorlist行をコメントアウトし、mirrorlist行のURLから取得した実リポジトリサイトのURL群より、東京リージョン(ap-northeast-1)のURLをbaseurl行を追加して記入します。
手順2)/etc/hosts ファイルの編集
リポジトリのURLをbaseurlに書き換えただけでは、まだインターネットへの導線がオンプレ側なので、正常に動作しません。
次の手順(3)でルートテーブルを編集し、特定のIPだけIGWやNAT経由でAWS内から外に出るように設定する必要があります。
この手順(2)はその準備となります。
baseurlに指定した実リポジトリのIPアドレスを取得する
以下のように、digコマンドなどでIPアドレスを取得します。S3にホスティングされているようで、IPアドレスは複数のうちいずれかが取得できるようです。
# dig +short packages.ap-northeast-1.amazonaws.com packages.ap-northeast-1.amazonaws.com.s3.amazonaws.com. s3-ap-northeast-1-w.amazonaws.com. 54.231.225.66
今回の暫定手順では、少なくとも現在有効なIPアドレスが取得できれば良いので、54.231.225.66を利用します。実際には、自身の環境で解決できたIPアドレスを利用してください。
/etc/hostsファイルにIPとホスト名の関連付けを書き込む
上記で取得したグローバルIPとホスト名を、/etc/hostsファイルに書き込みます。
IPアドレスをamzn-main.repoファイルのbaseurlに直書きしてもyumコマンド実行時にエラーとなったため、以下のような汎用性の無い対応で逃げます!
# diff -u /etc/hosts.orig /etc/hosts --- /etc/hosts.orig 2014-09-18 21:00:49.805796894 +0000 +++ /etc/hosts 2014-10-10 07:06:00.586796445 +0000 @@ -1 +1,2 @@ 127.0.0.1 localhost localhost.localdomain +54.231.225.66 packages.ap-northeast-1.amazonaws.com.s3.amazonaws.com.
また、/etc/nsswitch.confファイルで、DNSよりも/etc/hostsファイルが優先されるようになっているか確認しておきます。
# grep '^hosts' /etc/nsswitch.conf hosts: files dns
これで、インスタンス側の設定は完了です。続いて、AWSのマネジメントコンソールまたはCLIで、インスタンスの属するサブネットのルートテーブルを修正します。
手順3)VPCのルートテーブルの編集
、インスタンス側の設定は完了です。続いて、AWSのマネジメントコンソールまたはCLIで、インスタンスの属するサブネットのルートテーブルを修正します。
今回の特殊な事情のルーティングでは、以下のようにデフォルトルートが、VGW、すなわちDirect ConnectやVPN Connectionを経由したオンプレミス側を向いています。
これに対して、特定のIPアドレス(今回の場合、54.231.225.66)をIGWに向けます。
手順4)Yumのキャッシュクリアと実行
あとは、インスタンスに戻り、yumのキャッシュをクリアし、再度yumを実行します。
# yum clean all Loaded plugins: priorities, update-motd, upgrade-helper Cleaning repos: amzn-main amzn-updates Cleaning up everything # yum check-update Loaded plugins: priorities, update-motd, upgrade-helper amzn-main/x86_64 | 2.1 kB 00:00 amzn-main/x86_64/group | 35 kB 00:00 amzn-main/x86_64/primary_db | 3.1 MB 00:00 amzn-updates/x86_64 | 2.3 kB 00:00 amzn-updates/x86_64/group | 35 kB 00:00 amzn-updates/x86_64/updateinfo | 181 kB 00:00 amzn-updates/x86_64/primary_db | 84 kB 00:00 aws-amitools-ec2.noarch 1.5.4-1.1.amzn1 amzn-updates aws-cli.noarch 1.4.4-1.0.amzn1 amzn-updates curl.x86_64 7.38.0-1.48.amzn1 amzn-updates libcurl.x86_64 7.38.0-1.48.amzn1 amzn-updates nspr.x86_64 4.10.6-1.28.amzn1 amzn-updates nss.x86_64 3.16.2-7.49.amzn1 amzn-updates nss-softokn.x86_64 3.16.2-2.2.amzn1 amzn-updates nss-softokn-freebl.x86_64 3.16.2-2.2.amzn1 amzn-updates nss-sysinit.x86_64 3.16.2-7.49.amzn1 amzn-updates nss-tools.x86_64 3.16.2-7.49.amzn1 amzn-updates nss-util.x86_64 3.16.2-2.4.amzn1 amzn-updates
まとめ
今回のような特殊な事情は、エンタープライズ系のシステムなど、クローズドな環境の延長にAWSがある場合にも、発生し得る問題だと思います。
そもそも、セキュリティポリシーとしてインターネットには直接繋がないというポリシーで運用していることも想定されます。
そのため、今回の暫定対処法は、あくまで緊急避難的な対処だと認識頂ければと思います。
恒久的な対応としては、以下のような設計を検討する必要があるでしょう。
- VGWへルーティングするのは、オンプレミス側のアドレス範囲だけとし、デフォルトルートはIGWやNATインスタンスにする
- 特定のURLは、インターネット経由とするなどを制御するproxyを別途用意した設計とする
- Amazon Linux以外のLinuxディストリビューションを利用する
それでは、また!