目次
この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。
VPC で環境を構築しsubnetをpublic/privateと分離した構成とする場合、privateなsubnetからのインターネット側へのアクセスは基本的にNAT経由となる。 そのような構成のネットワークを組んだ際に外部のNTPサーバと同期させる設定でハマったので設定方法について考え方を整理してみた。
環境
OS及びNTPサーバ/クライアントは以下のとおり。
$ cat /etc/redhat-release
Red Hat Enterprise Linux Server release 7.2 (Maipo)
$ chronyd --version
chronyd (chrony) version 2.1.1
ネットワーク構成
以下のような構成を想定。
Privat Subnet 内に EC2 インスタンスを配置。
このインスタンスに NTPクライアント/サーバ(Chrony)を立ち上げてインターネットで公開されているNTPサーバと同期を取る設定を行う。
chrony の設定
ネットワークACLで設定し易くするため NTPクライアントとして使用するポートを固定する(以下の設定を行わない場合は1024以上のエフェメラルポートが使用される)
エディタで /etc/chrony.conf を開き以下の行を追加する。
# client port (udp)
acquisitionport 1123
設定の変更後は chronyd の再起動が必要だが、ACLの設定の後にも再起動が必要なので後述。
参考: chrony – Manual for version 2.3
ネットワークACL
NTPに必要なネットワークACLの設定は以下のとおり。
Public Subnet 側
インバウンドルール
プロトコル | ポート | 送信元 | 許可拒否 | 備考 |
---|---|---|---|---|
UDP | 123 | 10.0.0.0/16 | 許可 | VPC内からのNTPを許可 |
UDP | 1024-65535 | 0.0.0.0/0 | 許可 | NATに対するNTPのレスポンスを許可 |
アウトバウンドルール
プロトコル | ポート | 送信先 | 許可拒否 | 備考 |
---|---|---|---|---|
UDP | 123 | 0.0.0.0/0 | 許可 | NATからVPC外のNTPサーバへのリクエストを許可 |
UDP | 1123 | 10.0.0.0/16 | 許可 | private subnet のNTPクライアントへのレスポンスを許可 |
Private Subnet 側
インバウンドルール
プロトコル | ポート | 送信元 | 許可拒否 | 備考 |
---|---|---|---|---|
UDP | 1123 | 0.0.0.0/0 | 許可 | インターネット側から(NAT経由)のNTPのレスポンスを許可する |
アウトバウンドルール
プロトコル | ポート | 送信先 | 許可拒否 | 備考 |
---|---|---|---|---|
UDP | 123 | 0.0.0.0/0 | 許可 | インターネットのNTPサーバへのリクエストを許可 |
動作状況の確認
ACLの設定を変更した場合 chronyd を再起動する。(もしかしたら不要かもしれないが再起動しないとすぐに同期が行われなかった)
$ sudo systemctl restart chronyd
再起動したら以下のコマンドでNTPサーバとの同期の状況を確認する。
$ chronyc sources
210 Number of sources = 4
MS Name/IP address Stratum Poll Reach LastRx Last sample
===============================================================================
^- y.ns.gin.ntt.net 2 6 7 1 -2034us[-2839us] +/- 135ms
^- hachi.paina.jp 2 6 7 1 -4583us[-5388us] +/- 23ms
^* routerida1.soprano-asm.ne 3 6 17 0 -5855ns[-1517us] +/- 13ms
^- jp.f2tec.de 3 6 7 1 +4904us[+4099us] +/- 64ms
先頭から2文字目が *
になっているサーバが同期中のサーバを表している。このようになっていればNTPサーバとの同期が行われている。
設定の解説
設定内容を解説するにあたって、この構成で NTP が使用するポートを整理すると以下の図のようになる。
Public Subnet 側のネットワークACL
Internet <–> VPC(Public) では NTPサーバ側(インターネット側)のポートが 123、NAT Gateway 側(VPC側)のポートが エフェメラルポート(1024〜65535の範囲のいずれかの番号)となる。
よって、Public Subnet 側のインバウンド/アウトバウンドのルールは以下のようになる。
インバウンド(a)
プロトコル | ポート | 送信元 | 許可拒否 | 備考 |
---|---|---|---|---|
UDP | 1024-65535 | 0.0.0.0/0 | 許可 | NATに対するNTPのレスポンスを許可 |
アウトバウンド(b)
プロトコル | ポート | 送信先 | 許可拒否 | 備考 |
---|---|---|---|---|
UDP | 123 | 0.0.0.0/0 | 許可 | NATからVPC外のNTPサーバへのリクエストを許可 |
次に VPC(Public) <–> VPC(Private) の設定について見てみる。
この場合、NAT Gateway 側(Public)のポートは123、Private側のポートは1123(前述の/etc/chrony.confで設定したポート番号)となる。
よって、 Public Subnet 側のインバウンド/アウトバウンドに必要なルールは以下のようになる。
インバウンド(c)
プロトコル | ポート | 送信元 | 許可拒否 | 備考 |
---|---|---|---|---|
UDP | 123 | 10.0.0.0/16 | 許可 | VPC内からのNTPを許可 |
アウトバウンド(d)
プロトコル | ポート | 送信先 | 許可拒否 | 備考 |
---|---|---|---|---|
UDP | 1123 | 10.0.0.0/16 | 許可 | private subnet のNTPクライアントへのレスポンスを許可 |
Public Subnet で必要な設定は上記のとおりとなる。
Private Subnet 側のネットワークACL
次に Private Subnet 側の設定を見ていくが、ここの設定については先に「VPC(Public) <–> VPC(Private) 」の設定と送信先/送信元を逆の視点で見た場合の設定を行えば良い。
よって以下のようになる。
インバウンド(e) ← (d)に対する逆
プロトコル | ポート | 送信元 | 許可拒否 | 備考 |
---|---|---|---|---|
UDP | 1123 | 0.0.0.0/0 | 許可 | インターネット側から(NAT経由)のNTPのレスポンスを許可する |
アウトバウンド(f) ← (c)に対する逆
プロトコル | ポート | 送信先 | 許可拒否 | 備考 |
---|---|---|---|---|
UDP | 123 | 0.0.0.0/0 | 許可 | インターネットのNTPサーバへのリクエストを許可 |
以上で設定完了。
まとめ
最後にポイントをまとめると…
- VPC内及びNATがインターネットとの通信で使用する UDP のポート123を許可する。
- NAT がインターネット側との通信で使用するエフェメラルポートを許可する。
- VPC内でNTPクライアントとの通信で使用するポート(/etc/chrony.confのacquisitionportに割り当てたポート)を許可する(※)
※acquisitionportを割り当てていない場合はエフェメラルポートとなるはずなのでそれを許可する設定とする必要がある。
自分がハマった点は、2番めの「NATがインターネット側との通信で使用するエフェメラルポート」の存在を見落としていて、ntpdで同期が行われないという現象でした。
また、RHEL7系ではこれまでの ntpd に代わって chrony がデフォルトになっている点も知らず、ntpdがうまく動かない(自動起動に設定していてもchronyが起動すると停止してしまう)という点でした。
RHEL(CentOS)6系から7系でいろいろ変わってるので、ほかの違いも見直しておく必要ありますね。。。