その他
    ホーム 技術発信 DoRuby NAT 経由でインターネットアクセスする構成でのACL設定について
    NAT 経由でインターネットアクセスする構成でのACL設定について
     

    NAT 経由でインターネットアクセスする構成でのACL設定について

    この記事はアピリッツの技術ブログ「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 
    

    ネットワーク構成

    以下のような構成を想定。

    https://gyazo.com/e0e1d6fb247de73861603b404e52d8ee

    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 側

    インバウンドルール

    プロトコルポート送信元許可拒否備考
    UDP12310.0.0.0/16許可VPC内からのNTPを許可
    UDP1024-655350.0.0.0/0許可NATに対するNTPのレスポンスを許可

    アウトバウンドルール

    プロトコルポート送信先許可拒否備考
    UDP1230.0.0.0/0許可NATからVPC外のNTPサーバへのリクエストを許可
    UDP112310.0.0.0/16許可private subnet のNTPクライアントへのレスポンスを許可

    Private Subnet 側

    インバウンドルール

    プロトコルポート送信元許可拒否備考
    UDP11230.0.0.0/0許可インターネット側から(NAT経由)のNTPのレスポンスを許可する

    アウトバウンドルール

    プロトコルポート送信先許可拒否備考
    UDP1230.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 が使用するポートを整理すると以下の図のようになる。

    https://gyazo.com/5b470e494bdaf65a3f73cfa1802c1ede

    Public Subnet 側のネットワークACL

    Internet <–> VPC(Public) では NTPサーバ側(インターネット側)のポートが 123、NAT Gateway 側(VPC側)のポートが エフェメラルポート(1024〜65535の範囲のいずれかの番号)となる。
    よって、Public Subnet 側のインバウンド/アウトバウンドのルールは以下のようになる。

    インバウンド(a)

    プロトコルポート送信元許可拒否備考
    UDP1024-655350.0.0.0/0許可NATに対するNTPのレスポンスを許可

    アウトバウンド(b)

    プロトコルポート送信先許可拒否備考
    UDP1230.0.0.0/0許可NATからVPC外のNTPサーバへのリクエストを許可

    次に VPC(Public) <–> VPC(Private) の設定について見てみる。
    この場合、NAT Gateway 側(Public)のポートは123、Private側のポートは1123(前述の/etc/chrony.confで設定したポート番号)となる。
    よって、 Public Subnet 側のインバウンド/アウトバウンドに必要なルールは以下のようになる。

    インバウンド(c)

    プロトコルポート送信元許可拒否備考
    UDP12310.0.0.0/16許可VPC内からのNTPを許可

    アウトバウンド(d)

    プロトコルポート送信先許可拒否備考
    UDP112310.0.0.0/16許可private subnet のNTPクライアントへのレスポンスを許可

    Public Subnet で必要な設定は上記のとおりとなる。

    Private Subnet 側のネットワークACL

    次に Private Subnet 側の設定を見ていくが、ここの設定については先に「VPC(Public) <–> VPC(Private) 」の設定と送信先/送信元を逆の視点で見た場合の設定を行えば良い。

    よって以下のようになる。

    インバウンド(e) ← (d)に対する逆

    プロトコルポート送信元許可拒否備考
    UDP11230.0.0.0/0許可インターネット側から(NAT経由)のNTPのレスポンスを許可する

    アウトバウンド(f) ← (c)に対する逆

    プロトコルポート送信先許可拒否備考
    UDP1230.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系でいろいろ変わってるので、ほかの違いも見直しておく必要ありますね。。。

    参考