【小ネタ】Amazon LinuxのYumアップデートでハマったことと暫定対処【BADノウハウ】

2014.10.10

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、三井田です。

今回は、環境に特殊な事情で 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つです。

/etc/yum.repos.d/amzn-main.repo


/etc/yum.repos.d/amzn-updates.repo

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を経由したオンプレミス側を向いています。

VPC_Route_before_change

これに対して、特定のIPアドレス(今回の場合、54.231.225.66)をIGWに向けます。

VPC_Route_after_change

手順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ディストリビューションを利用する

それでは、また!