#0017

AWSでWebサーバー構築!踏み台サーバーでセキュアなネットワークを構築する(第5回)

2018-07-05 18:24 2018-10-25 15:23 "みやび"

みやびです(@miyabi_lab)。

連載『知識ゼロからAWS VPCネットワークを構築してセキュアな環境にEC2 Webサーバーを設置・運営する』の第5回です!

前回は、作成したEC2 Amazon Linux2サーバーにて、Apache2.4を導入してWebサーバーとして稼働させるための方法をご紹介しました。

また、PHP7やRuby、MySQLなどを導入し、動的なサイト制作が可能な状態にすることができました。

今回はセキュリティ面を中心に解説していきます。特に、これまでのメインEC2をプライベートサブネットに内包し、インターネットから直接参照できないように隠すことでセキュアな環境を実現する方法を中心にご紹介します。

加えて、踏み台サーバーを新しく設置し、間接的にメインEC2にアクセスするネットワーク設計についても解説していきます。

スポンサーリンク

前回(第4回)のおさらい

前回の「Apache2.4, PHP7, MySQLの導入と初期設定」までの作業で、以下の状態が完成しました。

第4回の目標図

実はこれだけでもWebサーバーとしては問題なく機能します

単純なパスワードなどを設定していない限り、よほど悪意のある攻撃でなければ基本的には破られることはありません。

ただし、この状態でMySQLに個人情報を記録していたり、EBS内に外部流出すると危険なファイルなどを保管しているなどの場合は、「インターネットからメインEC2 (Webサーバー)が見える状態」はできる限り避けたいです。

実社会でいうと、玄関が道路に面しているのと、マンションのようにオートロックの共用セキュリティがあった上で玄関がマンション内部にあるのとでは、どちらが安全か?というようにイメージしていただくと分かりやすいかもしれません。

完全なシステムは存在しないため、セキュリティについてはどうやってもイタチごっこにはなってしまうのですが、AWSでは少し工夫するだけで費用対効果の高いネットワーク構造を作ることができます。

今回(第5回)で、以下のような最終目標のネットワーク図まで完成させていきます。

第5回の目標:踏み台サーバーを用いたネットワーク図

前回に比べてかなりボリュームが増えましたが、ひとつずつ順番に見ていけばそれほど難しくはありません。

単語の説明については、第2回の記事内の「重要なAWS用語の意味を理解しよう」の項目で詳しく解説していますので、まずはそちらに目を通しておくとスムーズに理解できるかと思います。

セキュリティグループの設定を確認する

第3回の記事「EC2を作成してSSH接続する」では、メインEC2のセキュリティグループを以下のように設定しました。

  • SSH(:22)を経由して自分のパソコンのIPアドレスからのアクセスのみを許可する
  • HTTP(:80)を経由して世界中のどこからでもアクセスできるようにする
  • HTTPS(:443)を経由して世界中のどこからでもアクセスできるようにする

セキュリティグループの設定

つまり、現在メインEC2はインターネット経由での直接的なSSH(コマンド)接続と、インターネットブラウザ経由での接続を許可している状態になります。

このままですと、EC2のIPアドレス(=住所)をインターネットに公開しているので、外部からメインEC2に誰でも直接アクセスすることができます

セキュアなネットワークとは何か?

高いセキュリティと言っても様々な方法がありますが、インターネットからの直接的なアクセスを回避するための方法として、

「メインEC2を内包するセキュリティグループの設定で、インターネットゲートウェイ(Internet Gateway:IGW)との接続を解除し、新たに設置する踏み台サーバーからのアクセスのみを許可する」

という手段があります。

ここで言う踏み台サーバーとは、メインEC2にSSHでアクセスするため「だけ」に設置されるEC2インスタンスのことです。

特別な設定などはなく、Webサイトに関連するファイルは愚か、Apacheのインストールなどもいりません。文字通り、ただの踏み台です。

これにより、外から見えるのは踏み台サーバーのみとなり、メインEC2はインターネット上から理論的に隔離され、その実体が外から直接見えることは無くなります。

文字だけでは少々難しいので、図を使って見ていきましょう。

第5回の目標:踏み台サーバーを用いたネットワーク図

こちらのネットワーク図をご覧ください。

これまで作成していたパブリックサブネット(Public Subnet)の中身が、新しく作成されたプライベートサブネット(Private Subnet)内に移動していますね。

代わりにパブリックサブネット内には、新しく踏み台サーバー(Bastion EC2)とナットゲートウェイ(Nat Gateway:NAT:後述します)が設置されました。

ここでのパブリック(水色)かプライベート(緑)かの決定的な違いは、それぞれのセキュリティグループがインターネットからの直接的なアクセスを許可しているかどうかで決まります。

上のネットワーク図では、プライベートサブネットは直前のパブリックサブネットからのアクセスしか許可していません。これは、インターネット上から隔離されたプライベートな環境であると言えます。

また、それぞれのサブネットに紐づいているルートテーブルが0.0.0.0/0インターネットゲートウェイ(Internet Gateway:IGW)に向いているかどうかも重要です。

ご覧の通り、パブリックの場合にはIGWに、プライベートの場合はNAT Gateweyにルーティングされています。

踏み台サーバーにはElastic IPが紐づいているので、インターネット側からは、SSH:22ポートを通じて踏み台サーバーにアクセスすることができます。

しかし、メインEC2には踏み台サーバーを経由することでしかアクセスできないため、インターネット側からは直接メインEC2を確認することができず、ダイレクトでのアクセスが不可能になります。

重要なポイントとして、メインEC2にSSH接続して操作を行うとき以外は踏み台サーバーをシャットダウンしておくことで、SSH接続に対して完全にプライベート空間に隔離することができます。これはセキュリティ面において理想的な状態と言えます。

NAT Gatewayの有用性

IGWとNAT Gatewayはどちらもインターネットに接続するためのゲートですが、その最大の違いは方向性にあります。

IGWは双方向に通信ができるため、外からのアクセスやリクエストを通し、内部のEC2インスタンス側からもインターネットに接続することが可能です。

一方でNAT Gatewayは、外部からの接続を遮断し、内部からのインターネットへの接続のみを許可します。

また、NAT GatewayはElastic IPを紐づけて利用します。

これにより、プライベートサブネット内に設置されたEC2インスタンスへの外部からの接続を防ぎつつ、NATのIPアドレスを利用してインターネットにアクセスするため、プライベート空間を限りなくセキュアな環境に保つことができます。

ちなみに有料です。シンプルで安く済まそうとしている方にとっては、安いEC2と同じくらいの価格なので、安易に作成するのは注意が必要です。(と言っても他に選択肢がない...。Amazonさんさすがです....。)

踏み台サーバーを設置してメインEC2をプライベートサブネットに隠す

まずは改めて現在のネットワーク図と、目標とするネットワーク図を確認し、やるべき作業を言語化していきましょう。

ちなみに、ここではブラウザからのHTTP経由のアクセスは一旦置いておきます(接続できなくなります)。

↓現在:インターネット経由で直接メインEC2にアクセスできる状態

第4回の目標図

↓目標:メインEC2を隔離して踏み台サーバー経由からのみアクセスを許可する

第5回の目標:踏み台サーバーを用いたネットワーク図

目標までに必要な手順を言語化していきます。

  1. 既存のパブリックサブネットの名前を「プライベート」に変更しておく(設定は後ほど)
  2. 新しいパブリックサブネットに踏み台サーバー(EC2)を設置する
  3. NAT Gatewayを作成する
  4. 両サブネットのルートテーブル設定の変更と確認
  5. セキュリティグループの作成と各種設定

さらっと書いてますが、ここまでの知識でイメージするのは少し難しいかもしれません。ひとつずつじっくりみていきましょう。

1. 既存のパブリックサブネットとルートテーブルの名前を「プライベート」に変更しておく(設定は後ほど)

AWSコンソールからサブネット一覧を確認すると、以下のような以前作成したパブリックサブネットがあります。

AWSコンソール:サブネット

こいつの名前をひとまず「plan-private-subnet」に変更しておきます(名前はなんでもいいですが、privateという単語は入れておいた方が良いでしょう)。

なぜ名前を変更しなければならないかというと、既に作成したEC2インスタンスは、別のサブネットに移動させることができないからです。

AMI(Amazon Machine Image)を用いて、既存のEC2のクローンを作成することもできるのですが、今回は手っ取り早く「環境をEC2に合わせる」方向で調整していきます。

前述した通り、パブリックとプライベートの違いはIGWにルーティングされているかどうかで決まるので、名前を変えただけでは機能的にプライベートにはなりません。

これは最後にまとめて設定するので、とりあえずは名ばかり状態で大丈夫です。

また、サブネットの名前を変更したので、それに紐づいているルートテーブルの名前も必ず変更しておきます!

上のサブネットに紐づいているルートテーブルは「plan-rt-public-subnet」という名前なので、これを「plan-rt-private-subnet」に変更しましょう。

これを忘れてしまうと、あとで混乱して面倒なことになります(笑)

2. 新しいパブリックサブネットに踏み台サーバー(EC2)を設置する

さらっと書きましたが、少し面倒ですね(笑)

え、またやるの!?という感じですが、せっかくなのでまずは復習がてら自分の力でパブリックサブネットとEC2インスタンスを作成してみましょう!

一連の作成方法は、

に、これでもかというくらい詳しく書いているので、一度作った皆さまであればきっとできるはずです!

新規パブリックサブネット作成時の注意点

パブリックサブネット作成時の注意点

まずアベイラビリティーゾーンの設定についてですが、こちらは前回作成した場所と同様で構いません。

そしてIPv4 CIDRブロックについてですが、こちらに関しては第1回「VPC設計に必要なIPアドレスとサブネットの基礎知識」でご紹介した通り、IPアドレスやサブネットマスクの知識が必要になります。

以前作成したサブネット「10.0.0.0/20」の次が、なぜ「10.0.1.0/20」ではなく「10.0.16.0/20」になるのかが分からない場合、この先ネットワークを勉強していて躓くことが非常に多いはずなので、第1回の記事で知識をつけてしまいましょう。

簡単に説明すると以下の通りです。

### VPCネットワーク(10.0.0.0/16)
255.255.0.0
11111111 11111111 00000000 00000000

### サブネットマスク(10.0.0.0/20)
255.255.240.0
11111111 11111111 11110000 00000000

10.0.0.0/20のサブネットマスクは上のように表すことができるので、

  • ネットワーク部は中央から左側の16桁
  • サブネットワーク部は中央から右側の4桁(=2^4=16個)
  • ホスト部は残りの12桁分(=2^12=4096個)

となります。

この「サブネットワーク部」が今回重要な部分で、この4桁の数値が0か1の値を取ることにより「0000」や「0110」などの組み合わせができます。

これが全部で16個あるので、256を16個で割るので、10進数で表したIPアドレスの3セット目の数値は16ずつカウントアップしていくことになります。

16という数値が2種類出てきてわかりづらいので、以下に全て列挙します。

### 10.0.0.0/20 のサブネット一覧(IPアドレスの範囲)
10.0.0.0/20 => 10.0.0.0 ~ 10.0.15.255
10.0.16.0/20 => 10.0.16.0 ~ 10.0.31.255
10.0.32.0/20 => 10.0.32.0 ~ 10.0.47.255
10.0.48.0/20 => 10.0.48.0 ~ 10.0.63.255
10.0.64.0/20 => 10.0.64.0 ~ 10.0.79.255
10.0.80.0/20 => 10.0.80.0 ~ 10.0.95.255
10.0.96.0/20 => 10.0.96.0 ~ 10.0.111.255
10.0.112.0/20 => 10.0.112.0 ~ 10.0.127.255
10.0.128.0/20 => 10.0.128.0 ~ 10.0.143.255
10.0.144.0/20 => 10.0.144.0 ~ 10.0.159.255
10.0.160.0/20 => 10.0.160.0 ~ 10.0.175.255
10.0.176.0/20 => 10.0.176.0 ~ 10.0.191.255
10.0.192.0/20 => 10.0.192.0 ~ 10.0.207.255
10.0.208.0/20 => 10.0.208.0 ~ 10.0.223.255
10.0.224.0/20 => 10.0.224.0 ~ 10.0.239.255
10.0.240.0/20 => 10.0.240.0 ~ 10.0.255.255

気持ち悪くなりそうですね(笑)

従って、10.0.0.0/16のVPC内をサブネットマスク255.255.240.0で16分割した場合、ひとつめのサブネットは10.0.0.0/20、ふたつめのサブネットは10.0.16.0/20となります。

最後に重要なポイントとして、サブネットを作成すると自動的にルートテーブルも作成されます!

AWSコンソールのルートテーブルから新しく作成されたものを見つけ、「plan-rt-private-subnet」という名前を忘れずにつけておきましょう。

踏み台サーバー用の新規EC2インスタンス作成時の注意点

次に踏み台サーバー用のEC2インスタンスですが、これも前回と同様にEC2を新規作成していきます。

ポイントは以下の部分です。

EC2の名前には「bastion」というキーワードを含めておくと後からわかりやすいです。踏み台サーバーにはよく使われる単語です。

踏み台サーバー:タグの追加

続けて、踏み台サーバーを内包する新しいセキュリティグループをここで作成します。

以前作成したセキュリティグループ名は「plan-sg-web」でしたが、今回はパブリックなので「plan-sg-pub-ssh」としています。

publicでssh接続しか許可しないやつだよ、というのがわかりやすいようにしているだけで、「plan-sg-bastion」とかでも全然OKです。

踏み台サーバー:セキュリティグループの設定

また、ソースを「マイIP」としていますが、これはご自身のパソコンのユニークなIPアドレスからのみ接続を許可する、という設定になります。

現在使用中のIPアドレスはこちらから調べられます。ここで出てきたIPアドレスを、マイIPの横に入れてください。

書き方は「xxx.xxx.xxx.xxx/32」です。/32を忘れずに!その理由はサブネットマスクのところをもう一度考えるとわかると思います。

ちなみに、自分のIPアドレスは接続環境によって常に変化しますので、もしSSH接続できなくなった場合はまずここの設定を疑ってください。

そして最後に、EC2インスタンスを作成する直前に、SSH接続に必要なキーペアを選択する必要がありますが、ここは前回作成したものを利用します。

「既存のキーペアの選択」を選んでインスタンスを作成します。

キーペアの選択

こうすることで、メインEC2への接続に利用していた秘密鍵で踏み台サーバーにSSH接続できます

次の「Elastic IPの関連付け」が終わったら、そのIPアドレスを使用してSSH接続してみましょう!

Elastic IPを取得して踏み台サーバー(EC2)に関連付ける

EC2インスタンスは、デフォルトのままでは動的なIPアドレスが設定されています。これは、EC2を再起動させる度にIPアドレスが変わってしまうことを意味しており、メンテナンスの際に面倒になります。

ここでは、Elastic IPを取得して踏み台サーバーに固定IPアドレスとして紐づける作業を行います。

作成方法はとても簡単で、サイドメニューからElastic IPを選択し、新しいアドレスの割り当てを実行するだけです。

正常に完了すると以下のような画面に遷移し、作成したアドレスが表示されます。

Elastic IP新規作成

次に、取得したアドレスを選択し、アクションからアドレスの関連付けを選びます。

Elastic IPを踏み台サーバーに関連付ける-1

ここで、先ほど作成した踏み台サーバー(EC2インスタンス)を選択します。

Elastic IPを踏み台サーバーに関連付ける-2

最後に関連付けボタンをクリックして完了です。

EC2インスタンス一覧から踏み台サーバーをみると、IPv4パブリックIPの欄にクリック可能なElastic IPのアドレスが記載されています。

これで再起動を行ってもIPアドレスが変わることがなくなったので、作業をしない場合は安心してEC2インスタンスを停止させることができます。

EC2の初期設定まで終わらせておく

ここまでで、踏み台サーバーの作成が完了しました。

Elastic IPを用いて踏み台サーバーにSSH接続できるか試してみましょう。

頻繁にサーバーを立てることも少ないかと思いますので、少々面倒ではありますが、第3回「EC2を作成してSSH接続する:EC2の初期設定」まで、bastionなどのわかりやすい単語をうまく使いながら設定を完了させましょう。

3. NAT Gatewayを作成する

NATの必要性については前述した通りです。

各種インストールやcurlコマンド、別サーバーのMySQLにアクセスするなど、メインEC2のWebサーバーが自発的にインターネットを経由して情報を取得する際に利用されます。

一方、ブラウザからのHTTPリクエストに対するレスポンス経路としては利用されません。

作成はそれほど難しい作業ではないので、簡単にみていきましょう。

まずはAWSサービス一覧もしくはサイドメニューからNAT Gatewayを選択して新規作成します

NAT Gatewayの新規作成

一覧から先ほど作成したパブリックサブネットを作成し、新しくElastic IPを作成して紐付けます。

Elastic IPの紐づけ

たったこれだけです(笑)

ステータスが使用可能になるまで少し時間がかかるかもしれませんが、以下のようになればOKです。

NAT Gatewayステータス確認

NAT Gatewayは使っていなくても削除するまで課金され続けます

4. 両サブネットのルートテーブル設定の変更と確認

だんだんややこしくなってきましたので、一度整理します。

現在作成済みのものは、以下の通りです。

  • パブリックサブネット(plan-public-subnet)
  • パブリックサブネットのルートテーブル(plan-rt-public-subnet)
  • パブリックサブネットのセキュリティグループ(plan-sg-pub-ssh)
  • プライベートサブネット(plan-private-subnet)
  • プライベートサブネットのルートテーブル(plan-rt-private-subnet)
  • プライベートサブネットのセキュリティグループ(plan-sg-web)
  • NAT Gateway

念のため一旦全てのユニットについて、きちんと名前がついているかを確認してください。

確認が済みましたら、次にルートテーブルの設定を行います。

ルートテーブルの設定

まず、plan-rt-public-subnetについては、0.0.0.0/0のターゲットがIGWに向いていることを確認してください。

次に、plan-rt-private-subnetの方は、0.0.0.0/0のターゲットを先ほど設定したNAT Gatewayに向けてください。

これにより、メインEC2からの外部への通信はNAT Gatewayを経由することになります。

5. セキュリティグループの作成と各種設定

ルートテーブルの設定の次は、セキュリティグループの設定です。ネットワークを設計する上で、ここが一番重要と言っても過言ではありません。

セキュリティグループの設定はインバウンドとアウトバンドから構成され、どこ/誰(インターネットを含む全ての場所?他のセキュリティグループ?特定のIPアドレス?)からどんなタイプの通信(HTTP?HTTPS?SSL?)を許可するかを指定します。

インバウンドはこちらに向かう通信の許可設定、アウトバウンドは外に出て行く通信の許可設定です。

これをしっかりと頭に入れて、イメージしながら設定していきます。もう一度目的のネットワーク図を確認します。

第5回の目標:踏み台サーバーを用いたネットワーク図

パブリックサブネットのセキュリティグループ

解説では「plan-sg-pub-ssh」という名前をつけています。

インバウンドは先ほど設定した通り、自分のIPアドレスからのみSSH接続を許可します。

パブリックサブネットのインバウンド

アウトバウンドはそのままでOKです。

パブリックサブネットのアウトバウンド

プライベートサブネットのセキュリティグループ

解説では「plan-sg-web」という名前をつけています。

こちらはパブリックサブネットからの接続のみを許可したいので、以下のようにソース部分にパブリックサブネットの名前を入れます(sgと打つと候補が出てきます)。

プライベートサブネットのインバウンド

一方アウトバウンドについては、パブリックサブネットのNAT Gateway経由での接続のみを許可したいので、以下のようにソース部分にパブリックサブネットの名前を入れます。

プライベートサブネットのアウトバウンド

 

以上で、パブリックサブネットとプライベートサブネットの接続許可設定が完了しました。

ルーティング設定と併せて、SSHで踏み台サーバー経由でメインEC2に接続する経路と、メインEC2がNATを経由して外部にアクセスする経路を整備することができました。

第5回のまとめ

お疲れ様でした!ここまで沢山の設定を行ってきましたが、これでようやく以下のようなセキュアなネットワークが完成しました。

第5回の目標:踏み台サーバーを用いたネットワーク図

早速、踏み台サーバー経由でメインEC2にSSH接続してみましょう!と言いたいところなのですが、これを解説するとこの記事のボリュームが大きくなりすぎてしまうので、ここで一旦分割させていただきます。

皆さんはすでに踏み台サーバーへのSSH接続には成功しており、元々のメインEC2へのSSH接続はできなくなっているはずです。

今回は同じキーペアを使用しているので、順番としては、

  1. ローカルの秘密鍵を使って踏み台サーバーにSSHログインする
  2. 踏み台サーバーに秘密鍵をアップロードしておき、それを使ってメインEC2にSSHログインする

という2ステップで実現できます。

しかし、踏み台サーバーに秘密鍵をアップロードしておく、という行為がどうもセキュリティ的に気持ち悪いですよね...。

そこで次回(第6回)は、ローカルの秘密鍵を使いまわして、コマンド一発でメインEC2に接続する方法をご紹介していきたいと思います。

引き続きどうぞよろしくお願いいたします!

連載(知識ゼロからAWS VPCネットワークを構築してセキュアな環境にEC2 Webサーバーを設置・運営する)の記事一覧

この記事を書いた人

Webエンジニア PHPエンジニア HTML CSS JS jQuery PHP Laravel Python SQL WordPress AWS Linux Apache

【名前】 "みやび"

【関連】 株式会社PLAN / MIYABI Lab / JAPAN MENSA /

【MIYABI Lab】平日オフィスを勉強用に解放中!みんなで楽しくプログラミングを学べる環境を作る!詳しくはコチラ(https://miyabi-lab.space)◆HTML, CSS, JS, PHP, Python, SQL, AWS◆生物学系修士→製薬会社→Webエンジニア(株式会社PLAN)・MENSA会員

Twitterやってます

最新の技術ブログはこちら