こんにちは。渡辺です。
AWSにはNATインスタンスというものがあります。
グローバルIPを持たないEC2インスタンスとインターネットの間に設置され、NATルータとして働いてくれるものです。
ただ、実態としてはEC2インスタンスでAmazon Linuxなので、普通にsshログインもできます。
少しこのインスタンスの挙動のせいでハマったところがあり、共有しておきます。
今回試したAMIは、amzn-ami-vpc-nat-pv-2014.09.1.x86_64-ebs (ami-11d6e610) です。
NATインスタンスでsysctl -pしてはいけない
|
1 |
[ec2-user@ip-10-0-0-68 ~]$ sudo sysctl -p |
おもむろにsysctl -pしたら、ルーティング不能になりました。
そして、インスタンスを再起動したら復旧しました。
sysctl -pは、カーネルパラメータを設定している/etc/sysctl.confを再読み込みするコマンドですが、それを行うと設定がおかしくなります。
|
1 2 |
[ec2-user@ip-10-0-1-105 ~]$ sudo grep ip_forward /etc/sysctl.conf net.ipv4.ip_forward = 0 |
Linuxでルーティングを有効にするためには一般的に/etc/sysctl.confでnet.ipv4.ip_forward = 1
を設定しますが、今回はそうなっていませんでした。
NATインスタンス起動時のログ
|
1 2 3 4 5 6 7 8 9 10 11 12 |
[ec2-user@ip-10-0-0-68 ~]$ sudo grep vpc /var/log/messages Jan 6 05:30:13 ip-10-0-0-68 vpc: Determining the MAC address on eth0... Jan 6 05:30:13 ip-10-0-0-68 vpc: Found MAC 06:b9:f1:00:30:f7 for eth0. Jan 6 05:30:13 ip-10-0-0-68 vpc: Metadata location for vpc ipv4 range: http://169.254.169.254/latest/meta-data/network/interfaces/macs/06:b9:f1:00:30:f7/vpc-ipv4-cidr-block Jan 6 05:30:13 ip-10-0-0-68 vpc: Retrieved VPC CIDR range 10.0.0.0/16 from meta-data. Jan 6 05:30:13 ip-10-0-0-68 vpc: Enabling PAT... Jan 6 05:30:14 ip-10-0-0-68 vpc: net.ipv4.ip_forward = 1 Jan 6 05:30:14 ip-10-0-0-68 vpc: net.ipv4.conf.eth0.send_redirects = 0 Jan 6 05:30:14 ip-10-0-0-68 vpc: Chain POSTROUTING (policy ACCEPT) Jan 6 05:30:14 ip-10-0-0-68 vpc: target prot opt source destination Jan 6 05:30:14 ip-10-0-0-68 vpc: MASQUERADE all -- 10.0.0.0/16 0.0.0.0/0 Jan 6 05:30:14 ip-10-0-0-68 vpc: Configuration of PAT complete. |
インスタンス起動時のログを見ると、何やらvpc関係の表示があります。
vpc: net.ipv4.ip_forward = 1とあるので、/etc/sysctl.conf以外のどこかでルーティング設定されているようです。
まさかの/etc/rc.local
どこに設定が仕込まれているのか探しましたが、自力では到達できず、ググって発見しました。
インフラエンジニアに贈るAmazon VPC入門 #4 インターネット接続(後編)
まさかの/etc/rc.local。
AWSなら、cloud-initとか何か最新の仕組みなのでは・・・という先入観が敗因でした。。。
|
1 2 3 4 5 6 7 8 9 10 11 |
[ec2-user@ip-10-0-0-68 ~]$ cat /etc/rc.local #!/bin/sh # # This script will be executed *after* all the other init scripts. # You can put your own initialization stuff in here if you don't # want to do the full Sys V style init stuff. touch /var/lock/subsys/local # Configure PAT /usr/local/sbin/configure-pat.sh |
/usr/local/sbin/configure-pat.sh
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
[ec2-user@ip-10-0-0-68 ~]$ cat /usr/local/sbin/configure-pat.sh #!/bin/bash # Configure the instance to run as a Port Address Translator (PAT) to provide # Internet connectivity to private instances. function log { logger -t "vpc" -- $1; } function die { [ -n "$1" ] && log "$1" log "Configuration of PAT failed!" exit 1 } # Sanitize PATH PATH="/usr/sbin:/sbin:/usr/bin:/bin" log "Determining the MAC address on eth0..." ETH0_MAC=$(cat /sys/class/net/eth0/address) || die "Unable to determine MAC address on eth0." log "Found MAC ${ETH0_MAC} for eth0." VPC_CIDR_URI="http://169.254.169.254/latest/meta-data/network/interfaces/macs/${ETH0_MAC}/vpc-ipv4-cidr-block" log "Metadata location for vpc ipv4 range: ${VPC_CIDR_URI}" VPC_CIDR_RANGE=$(curl --retry 3 --silent --fail ${VPC_CIDR_URI}) if [ $? -ne 0 ]; then log "Unable to retrive VPC CIDR range from meta-data, using 0.0.0.0/0 instead. PAT may masquerade traffic for Internet hosts!" VPC_CIDR_RANGE="0.0.0.0/0" else log "Retrieved VPC CIDR range ${VPC_CIDR_RANGE} from meta-data." fi log "Enabling PAT..." sysctl -q -w net.ipv4.ip_forward=1 net.ipv4.conf.eth0.send_redirects=0 && ( iptables -t nat -C POSTROUTING -o eth0 -s ${VPC_CIDR_RANGE} -j MASQUERADE 2> /dev/null || iptables -t nat -A POSTROUTING -o eth0 -s ${VPC_CIDR_RANGE} -j MASQUERADE ) || die sysctl net.ipv4.ip_forward net.ipv4.conf.eth0.send_redirects | log iptables -n -t nat -L POSTROUTING | log log "Configuration of PAT complete." exit 0 |
sysctlやiptablesでゴニョゴニョやってますね。
まとめ
sysctl -pをうっかり打ってしまったせいで、時間を無駄にし、いろいろなことがわかりました。
AWSの初見殺しにやられましたが、たいへん勉強になりました。
sysctl.confも合わせて更新してくれればいいのに・・・と、ちらっと思いましたが。。