[小ネタ]Deep Securityで記憶にないIPアドレスと出会った時-Elastic Beanstalk Docker編-

謎のIPアドレスを調べた結果、一番難しかったのはjsonの整形の部分でした。(ここだけの話)
2019.05.25

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

Deep SecurityでElastic Beanstalk Docker環境を管理した際に、覚えのないIPアドレスが出てきて動揺した事はありませんか?

こんにちは、AWS事業本部のShirotaです。ピンポイントな枕詞で失礼致します。 そして、枕詞で今回のブログの要旨を全て語ってしまいました。どうしよう。

▲猫寄せで話題のジーンズ、持ってました。実家の猫はジーンズより私の手を舐めるのが好きです

余談もこれでネタ切れになってしまいましたので、サクッと本題に入っていきましょう。

Deep SecurityでElastic Beanstalk Docker環境のセキュリティ対策をする

サーバのセキュリティ対策は大事です。 コンテナやサーバレスを使用する機会も増え、サーバが使用者から物理的に見えづらくなってきているこの時代 だからこそ、改めて意識してセキュリティ対策をする必要が強くなっているように感じます。 アプリケーションの脆弱性を保護するのも大事ですし、それと同じくらいDockerコンテナを載せているOSを保護する事も大事です。 Deep Securityは、DockerをElastic Beanstalkで動かす環境のセキュリティ保護が出来ます。実際のDeep Security Agentのインストールに関しては、弊社梶の以下のブログで分かりやすく説明がありましたのでそちらを参考にしてみて下さい。 私も、実際に手を動かす際にebextentionsの部分が難しく、ブログを読みながら検証を進めていました。

AWS Elastic Beanstalk Docker 環境へDeep Security Agentをインストールする

様々な攻撃から保護してくれる「侵入防御モジュール」

Agentのインストールが済んでしまえば、Deep Securityは本領を発揮できるようになります。 その中で、「侵入防御」というモジュールがあります。 これは主に、アプリケーションの脆弱性そのものやSQLインジェクション、XSS(クロスサイトすプリンティング)攻撃からサーバを保護する目的で使用されます。

これはどのように使うものかというと、まずは侵入防御モジュールを有効にしてから 検出モード を選びます。 検出モードにしている間、あらかじめ設定しておいたルールに基づくトラフィックを検出して、Deep Securityはイベントを生成してくれます。 このモードを用いる事で、必要なトラフィックが誤検知されない事を確かめてから 防御モード に切り替えます。 防御モードに切り替えると、先程までは検出していただけのトラフィックを実際にブロックするようになります。 どういった攻撃に晒される傾向があるかを確認出来、また不必要に妨害されないように二つのモードを駆使する事で自分の環境に沿った侵入防御をしてくれる便利なモジュールです。 オートクチュールみたいで憧れますね。

実際にやってみる

実際に、Elastic Beanstalk Dockerで起動したインスタンスにDeep Security Agentをインストールして、侵入防御モジュールを用いてみます。

▲実際に検出・防御するとこんな感じにイベントが出ます

ここで今回の本題に辿りつきます。送信先IPアドレスが、 172.17.0.2 となってます。 何のこっちゃと思われるかもしれませんが、今Deep Security Agentを入れているElastic Beanstalk Dockerで起動した インスタンスのプライベートIPアドレスとは異なるものなのです。誰よあなた。 察しのいい方はここで分かったかもしれませんが、実際に調べてみましょう。 今回、Dockerが乗っているOSははAmazon Linux2です。SSH接続して、ついつい手がifconfigを叩きそうになるのを抑えながらどっかーんとip addrを叩きます。

    $ ip addr  
    3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default  
    link/ether 02:42:07:6c:d5:90 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:7ff:fe6c:d590/64 scope link
       valid_lft forever preferred_lft forever

DockerホストのIPアドレスを見つけました。どうやらこの「docker0」というのは同じネットワーク内で論理的に分離しているセグメントを繋ぐ 「ブリッジ」 であるようです。(この場合は仮想ブリッジ) つまり、docker0がDockerホストのIPアドレスだとすると、同じネットワーク内(172.17.0.0/16)でこのブリッジと繋がっているものがある筈です。 実際、Deep Security上で見られたIPアドレスはホストのIPアドレスとはネットワーク帯が同じですが別のものでした。つまりこれは、コンテナ自身が持っているIPアドレスなのではないでしょうか? 確かめてみます。

    $ sudo docker network ls  

    NETWORK ID          NAME                DRIVER              SCOPE
    deffa6265aae        bridge              bridge              local

dockerコマンドでブリッジの存在が確認できます。

    $ sudo docker network inspect bridge
    [
        {
            "Name": "bridge",
            "Id":       "deffa6265aae3b110479bf4dd85294ebe65444874c43e59b198962a4adab8421",
            "Created": "2019-04-18T09:34:50.123052054Z",
            "Scope": "local",
            "Driver": "bridge",
            "EnableIPv6": false,
            "IPAM": {
                "Driver": "default",
                "Options": null,
                "Config": [
                    {
                        "Subnet": "172.17.0.0/16",
                        "Gateway": "172.17.0.1"
                    }
                ]
            },
            "Internal": false,
            "Attachable": false,
            "Ingress": false,
            "ConfigFrom": {
                "Network": ""
            },
            "ConfigOnly": false,
            "Containers": {
                "3c437c83457d1c24bc34fcf5bc2d738c53ebbb8e2127065a806044bd84565be2": {
                    "Name": "ecs-awseb-test-multi-container-docker-nwmnvnik8x-2-php-app-88989fde90fccea56b00",
                    "EndpointID": "972e741bb34aa25997fbe2fab0eca355e8d452e8b8ec498dbc802c8466411bb1",
                    "MacAddress": "02:42:ac:11:00:02",
                    "IPv4Address": "172.17.0.2/16",
                    "IPv6Address": ""
                },
                "d6b3504e284ccd8af03310e8077bb6b1a7a5aaf14623eaac2bcbbd038  d67eede": {
                    "Name": "ecs-awseb-test-multi-container-docker-nwmnvnik8x-2-nginx-proxy-9a8edbe9c9c3eca73200",
                    "EndpointID": "296be5bd0a85dd3dd282d911b6e65cbb3559764028f46c4f3157d8e0e8f5c221",
                    "MacAddress": "02:42:ac:11:00:03",
                    "IPv4Address": "172.17.0.3/16",
                    "IPv6Address": ""
                }
            },
            "Options": {
                "com.docker.network.bridge.default_bridge": "true",
                "com.docker.network.bridge.enable_icc": "true",
               "com.docker.network.bridge.enable_ip_masquerade": "true",
                "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
                "com.docker.network.bridge.name": "docker0",
                "com.docker.network.driver.mtu": "1500"
            },
            "Labels": {}
        }
    ]

ブリッジについて調べてみます。情報量が多い! ざっと見たところ、Containersのところに求めていた情報がある感じなので、整形して出してみます。

    $ sudo docker network inspect bridge | jq -r '.[].Containers[] | .IPv4Address'
    172.17.0.2/16
    172.17.0.3/16

今回は、Multi-container Dockerで環境を構築していたので、二つのコンテナのIPアドレスが出てきました。その内の一つが、冒頭に記載したIPアドレスと一致しています。

どうしてコンテナのIPアドレスが出てきたの?

コンテナのIPアドレスが表示されていた理由に関しては、Trend Micro社のページに分かりやすい図が載っていました。 Dockerホスト上でDeep Security Agentを使ってみる②

簡単に説明すると、Deep Security Agentを導入すると、フィルタドライバがそれぞれのインターフェースにバインドされます。 パケットの処理はインターフェース側での処理が始めに行われます。 このフィルタドライバが侵入防御でも機能しており、先程のようにDeep Security上ではDockerコンテナのIPアドレスが表示されていたのです。

正体不明のIPアドレスなんて、無い

すごく当たり前のような事を言っておりますが、実際構築した覚えの無いIPアドレスが表示されていたらびっくりすると思います。私はびっくりしました。 ただ、コンテナをセキュリティ保護するニーズは、コンテナが使われていく現代ではどんどん高まっていくものだと思われます。 ピンポイントな小ネタですが、案外コンテナ環境を保護すると見られる事象という点においては汎用性はあるんじゃ無いでしょうか?

もし、同じような疑問を抱かれた方がいたら、少しでもこの記事で疑問解決までの時間が短縮されれば幸いです。