#前提
AWS(仮想サーバー構築)について学んだことを書いていきます。
#本題
ネットワーク上に仮想サーバーを作成する。
##仮想サーバー構築
仮想サーバーはEC2を用いて作成。
EC2で作成した仮想サーバーのことをインスタンス
と呼ぶ。
インスタンスには、パブリックサブネット内で利用可能なプライベートIPアドレスを割り当てる。
しかし、プライベートIPアドレスは、インターネットとの接続には利用できない。
そこでインスタンスを起動する時には、プライベートIPアドレスとは別にもう一つパブリックIPアドレスを設定するようにする(このパブリックIPアドレスは、AWSに割り当てられているIPアドレスブロックのうち、適当なものが使われる)。
つまり、作成したインスタンスはVPC内で通信するためのプライベートIPアドレスとインターネットで通信するためのパブリックIPアドレスの2つを持つ。
##SSH接続
SSH接続には、SSHクライアントソフトが必要。
Macの場合は、標準のターミナルからSSHクライアントを起動できる。
ターミナルから接続コマンドを入力。
$ ssh -i my-key.pem ec2-user@パブリックIPアドレス
ここで-iオプションで指定しているmy-key.pemはダウンロードしたキーペアファイル。
※パブリックIPアドレスを固定化する
インスタンスに割り当てられるパブリックIPアドレスは、デフォルトでは起動/停止するたびに別のIPアドレスが振り当てられる動的IPアドレス。
サーバーを運用する時は、このIPアドレスを固定化したいことがあるかもしれない。
IPアドレスを固定化する時はEC2のElasticIPという機能を使って設定する。
##IPアドレスとポート番号
ターミナルを使ってSSH接続すると、リモートからサーバー(インスタンス)にログインして、各種コマンドを実行できる。
ではなぜ、このようなことが実現できるか深掘りしていく。
###パケットを相手に届けるためのルーティングプロトコル
SSH接続する時には、接続先として相手先のIPアドレスを入力した。
指定したIPアドレスへのデータはパケット化され、ルーターのルートテーブルを使って、バケツリレーのような形で相手先に届く。
SSH接続の場合も例外ではなく、パケットとして相手先へと送られる。
バケツリレーを実現するには、それぞれがルーターが、相手先のIPアドレスをもつサブネットが、どこにあるのかを知っている必要がある。
1、EGP(Exterior Gateway Protocol)
ISP(インターネットサービスプロバイダー)やAWSなどのある程度大きなネットワークはそのネットワークを管理するAS番号(Autonomous System)という番号を持っている。
EGPでは、このAS番号をやりとりしてどのネットワークの先に、どのネットワークが接続されているのかを大まかにやりとりする。
2、IGP(Interior Gateway Protocol)
上記の1の内部のルーター同士で、ルートテーブルの情報をやりとりする。
つまり、プロバイダーやAWSの内部での、詳細なやりとりに使われる。
実際には、EGPでは、BGP(Border Gateway Protocol(BGP-4))などが使われる。
IGPもOSPF(Open Shortest Path First)やRIP(Routing Information Protocol)などがあり、ネットワークの規模や利用しているネットワーク機器、必要とするセキュリティ要件などによって、使い分けられている。
郵便に例えると、日本や東京都といった大まかな情報をEGPで情報交換し、それ以降は各地域の郵便局がIGPで情報交換するという階層化された仕組みだと言える。
こういった仕組みで、インターネット上のルーティング情報は、末端まで更新されている。
そのため、相手のIPアドレスさえわかれば、パケットを届けることができる。
###サーバー側のサービスとポート番号の関係
SSHで接続すると、サーバーが応答してユーザー認証され、正しいユーザーであればログインしてコマンドを入力してサーバーを操作できるようになるのは、なぜか。
それは、サーバー上で、ユーザーからのコマンドを受け付けるためのソフトが動いているから。
具体的なプログラム名でいうと、sshdというプログラムがそれに相当する。
※sshdは、SSH接続を受け入れるプログラム。AmazonLinuxでは、サーバーが起動する際に、自動的にsshdも起動するように構成される。
TCP/IPで通信するサーバーなどの機器には、他のコンピュータと、データを送受信するためのデータの出入口が用意されている。
これをポートという。
ポートは0から65535まである。
ポートがあるおかげで1つのIPアドレスに対して、複数のアプリケーションが同時に通信できる。
郵便でいうと、マンションの部屋番号のような概念。
ポートには、相手にデータが届いたことを保証するTCP(Transmission Control Protocol)と確認せずに送信する(その代わりに高速な)UDP(User Datagram Protocol)の2種類ある。
・待ち受けているポート番号とプログラムを確認
sshdというプログラムもサーバー上で通信を待ち受けているアプリケーションの一つ。
いずれかのポートに結び付けられている。
どのポート番号で、どのプログラムが待ち受けているのかは、lsofコマンドを使って調べられる。
SSHで接続後、以下のように入力。
[ec2-user@ip-10-0-1-10 ~]$ sudo lsof -i -n -P
[ec2-user@ip-10-0-1-10 ~]$はコマンドプロンプト。
実際に入力するのはsudo以降。
コマンドプロンプトには、サーバー名などが記述されるため、環境によって異なる。
sudoコマンドは、コマンドをrootユーザー(Linuxにおける管理者ユーザー)で実行するためのもの。
サーバー上で、どのプログラムがどのポート番号で待ち受けしているのかがわかると、セキュリティ上の懸念がある。
そこでlsofコマンドは、rootユーザーで実行しないと、一部の情報しか表示されないようになっている。
そのため、全情報を表示するには、sudoコマンドを経由して実行が必要。
この結果のうち、行の最後にLISTENと書かれているのが他のコンピュータからの待ち受けをしているポート、ESTABLISHEDと書かれているのが相手と現在、通信中のポートを示す。
どちらでもないものは、UDPのデータ。
UDPは、データを送りっぱなしで相手の確認を取らないため、通信中という概念がない。
1、TCPのポート22
sshdというプログラムが動作している。
SSH接続を待ち受け、リモートからのコマンド操作を可能とする。
*:22の*は全てのIPアドレスを接続元として受け付けるという意味。
2、TCPのポート25
sendmailというプログラムが動作している。
プログラムはメールの送信や転送を担当する。
SSHと違って、接続元は*ではなく、127.0.0.1。
127.0.0.1は、ループバックアドレス(loopback address)と呼ばれ、自分自身を示す特別なIPアドレス。
つまり、このポートは他のコンピュータからの接続は受け付けないという意味になる。
・ウェルノウンポート番号
このようにサーバー上では、ポート22番でsshdが起動している。
ポート22番に接続すれば、SSHサーバーに接続できる。
なぜMacではポート22番を指定しなくてもSSH接続できるのか。
実はSSHで使われているポート22番はウェルノウンポートと呼ばれ代表的なアプリケーションが使うポート番号として、あらかじめ定められたもの。
ウェルノウンポートは、ポート番号0〜1023までのいずれかの値をとり、例えばSSHは22番、SMTPは25番、HTTPは80番、HTTPSは443番というように、用途(アプリケーション)ごとに、ポート番号が決まっている。
クライアントが接続先のポート番号を省略した時は、このウェルノウンポート(よく知られているポート)が使われるため、明示的に指定しなくてもいい。
・接続元のコンピュータにも適当なポート番号が付けられる
lsofコマンドで表示されたESTABLISHEDの表示をもう少し詳しく見る。
TCP/IPのポート番号は、サーバー側だけでなく、クライント側にもある。
クライアント側のポート番号は、未使用のランダムなものが使われる。
このようなクライアント側で使われる、一時的なランダムなポート番号のことをエフェメラルポート(ephemeral ports)という。
エフェメラルポートは、サーバーと接続している間だけ使われ、切断すると開放される。
エフェメラルポートは、サーバーからクライアントに向けてデータを送信する際に必要。
なぜなら、クライアント上でもたくさんのアプリケーションが動いており、IPアドレスとともにポート番号を指定しなければ、そのアプリケーションにデータを届けることができない。
##ファイアウォールで接続制限する
このようなIPアドレスとポート番号の理解は、サーバーやネットワークのセキュリティを高めるのに役立つ。
セキュリティを高めるには、ファイアウォールを設けることが効果的。
ファイヤーウォールというのは、通じて良いデータだけを通して、それ以外を遮断する機能の総称。
その最も簡単な構造のものがパケットフィルタリング。
###パケットフィルタリング
パケットフィルタリングは、流れるパケットを見て、通過の可否を決める仕組み。
パケットには、IPアドレスのほかポート番号も含まれている。
パケットフィルタリングは、IPアドレスとポート番号など、パケットに付随する各種情報をみて、通過の可否を決める。
IPアドレスを判定して、特定のIPアドレスを送信元とするパケット以外を除外するようにするように構成すれば接続元を制限できる。
そして、ポート番号を制限すれば、特定のアプリケーションを外部から接続できないように構成できる。
例えば、MariaDBというデータベースソフトを使う場合、このデータベースソフトはポート3306番で待ち受けている。
デフォルトのままだと、誰もがデータベースにアクセスできてしまうため、セキュリティ上、好ましくてありません。
そこでパケットフィルタリングを構成し、ポート3306番を除外するように構成する。
###インスタンスのセキュリティグループ
実世界でパケットフィルタリングを構成するのは、ルーターやサーバー、もしくは専用のファイアウォール機器。
AWSでは、インスタンスに対して構成するセキュリティグループがこの機能を担当する。
※セキュリティグループの設定には、インバウンドとアウトバウンドの2つがある。
前者は、外から、このインスタンスに接続する向き、後者はこのインスタンスから外側に出て行く向き。
#まとめ
##ルーティング情報のやりとり
インターネットでは、EGPとIGPという2種類の方法で、互いに、どのネットワークの先に、どのネットワークが存在するのかというルーティング情報をやりとりしている。
##ポート
TCP/IPで通信するときは、ポートという0〜65535番まで割り当てられた、データの出入口を使う。
##パケットフィルタリングとセキュリティグループ
パケットフィルタリングは、IPアドレスやポート番号などを基準にして、パケット通過の可否を決める仕組み。
EC2では、セキュリティグループとして設定する。