【AWS 再入門】VPC 環境に踏み台サーバーを構築して SSH 接続してみよう

はじめに

vpc-minimum

前回の記事で EC2 と RDS によるミニマムなサーバー環境の構築手順をご紹介しました。

この環境はアプリケーション・サーバーがユーザー (Internet) からの HTTP リクエストを受け付けるだけでなく、管理者によるサーバーメンテナンスのための SSH 接続も受け付けるという構成になっています。AWS 再入門ということで、最初のお勉強としてはこれでも上出来かと思いますが、いくらミニマム構成とはいえ、これをこのまま本番運用するとなるとセキュリティの観点からイマイチよろしくありません。

ではどうするのが良いのか?
そもそもアプリサーバー自体が外部から直接 SSH 接続を受け付けること自体よろしくありません。外部からのSSH接続は、アプリサーバーとは別の専用サーバーが受け付けるべきです。そしてそのサーバーからアプリサーバーにSSH接続するといった二段階接続の構えをするというわけです。しかもそのマシンは管理者が使うとき以外は STOP 状態にしておけば部外者が勝手に侵入してくることもなくなるので、実にセキュアな構成といえます。このようなメンテナンスの為の接続経路を目的としたサーバーのことを、踏み台 (Bastion1)かつては Tunnel とか gatewayという呼び方をしていたみたいですが、AWS においては Bastion と呼ぶのが一般的らしいです。)サーバーと呼びます。

そんな訳で、今回は前回のミニマム構成に踏み台サーバーを加えた VPC 環境を作ってみるとします。

構成図

vpc-has_bastion_host

踏み台サーバーを追加するだけでなく、もう一つ前回と違うところがあります。
前回の構成では、アプリサーバー用のセキュリティグループには HTTP (80) と SSH (22) のポートが空けられていました。そして DB 用のセキュリティグループには、アプリサーバー用セキュリティグループからの MySQL(3306) 接続のみ受け付けるように設定していました。しかしVPC という閉じたネットワーク環境内であれば、全インスタンス間の通信を全て OK にしても何も問題は無いはずです。

そんな訳で、EC2 ならびに RDS と全てのインスタンスに対して VPC の Default セキュリティグループを付与してしまいます。こうすることで、各セキュリティグループ間の通信が全て許可され、個別に Inbound Rule を設定する手間がなくなります。ただし、踏み台サーバー用やアプリサーバー用など外部からの接続に対しては、しっかりと設定しておく必要があります。

Amazon VPC の作成

基本的に前回の記事で解説した内容と同じです。今回は以下の内容で作成します。

Name tag CIDR block Tenancy
vpc-mini 10.0.0.0/16 Default

Subnet の作成

こちらも前回の記事で解説した内容と同じです。今回は Frontend (踏み台とアプリサーバー用)、Datastore (DB サーバー用)の二種類作成します。

Name tag VPC Availability Zone CIIDR block
FrontendSubnet vpc-wp ap-northeast-1a 10.0.0.0/24
DatastoreSubnet1 vpc-wp ap-northeast-1a 10.0.100.0/24
DatastoreSubnet2 vpc-wp ap-northeast-1c 10.0.101.0/24

DB は Multi-AZ 構成を見据えて2つ作成しておきます(ただし、今回も実際には単一 AZ 構成で構築するので、実際にはDatasoreSubnet1しか使いません)。

Internet Gateway の作成

こちらも前回の記事で解説した内容と同じです。今回は以下の内容で作成します。

Key Value
Network Public

Internet Gateway を VPC と紐付けます。Attach to VPCボタンをクリックし、先ほど作成した VPC を選択します。

Route Table の確認 & 設定

サブネットを作成した時点で自動生成した Route Table がデフォルトで割り当てられています。この Route Table は private subnet 用として使い、public subnet 用に新規で作成します。

Route Table の作成

以下の内容で作成します。作成方法は前回の記事で解説した内容と同じです。

Name tag VPC
PublicRouteTable 作成したVPC

作成した Route Table の Destination0.0.0.0/0を、先ほど作成した Internet Gateway に向けるように設定します。

  1. 一覧から今作成した Route Table を選択し、画面下の Routes というタブを開いてEditという青いボタンをクリックする
  2. Destination に0.0.0.0/0と入力する
  3. Target に先ほど作成した InternetGateway を選択する
  4. Saveボタンをクリック

vpc-edit_routetable

最後に今作成した Route Table を Public subnet に設定します。今回の Public subnet は FrontendSubnet と ApplicationSubnet です。左メニューからSubnetsを選択し、それぞれに対して以下の操作をします。

  1. Route Tableタブを開いてEditという青いボタンをクリック
  2. Change to:に今しがた作成したRoute Tableを選択して一覧に追加されたのを確認したら、Saveボタンをクリック

Security Group の作成

作り方の手順は前回の記事で紹介したのと同じです。今回は以下の三種類を作成します。

踏み台サーバー用
Name tag Group name Description VPC
SSHSecurityGroup SSHSecurityGroup Enable SSH access via port 22 vpc-wp
Inbound Rules
Type Protocol Port Range Source
SSH(22) TCP(6) 22 0.0.0.0/0
アプリケーション・サーバー( Web )用
Name tag Group name Description VPC
WebSecurityGroup WebSecurityGroup Marker security group for Application server vpc-wp
Inbound Rules
Type Protocol Port Range Source
HTTP(80) TCP(6) 80 0.0.0.0/0
DB サーバー用
Name tag Group name Description VPC
MySQLSecurityGroup MySQLSecurityGroup Marker security group for MySQL server vpc-wp
Inbound Rules
Type Protocol Port Range Source
設定不要

踏み台サーバーの構築

基本的に前回の記事で紹介したアプリケーション・サーバーと作り方は同じです。踏み台用途でしか使わないので、インスタンスクラスはt2.microで十分です。

セキュリティグループはdefaultSSHSecurityGroupの2つを選択します。

select_sg

作成したら、SSH 接続を受け付けるために Elastic IP(52.68.***.***)を割り当てておきます。

踏み台サーバーに SSH 接続してみる

外部(インターネット)から SSH 接続を受け付けているので、問題なくアクセス出来るはずです。ターミナルを起動して、以下のコマンドを実行します。

~ ssh ec2-user@52.68.***.***
Last login: Sat Apr 11 11:36:15 2015 from 157-14-179-226.tokyo.fdn.vectant.ne.jp
       __|  __|_  )
       _|  (     /   Amazon Linux AMI
      ___|___|___|
https://aws.amazon.com/amazon-linux-ami/2015.03-release-notes/
2 package(s) needed for security, out of 20 available
Run "sudo yum update" to apply all updates.
[ec2-user@ip-10-0-0-112 ~]$

狙い通りアクセス出来ましたね。

AWS Management console 上で発行したキーペア (.pem)を使う場合は、ssh -i ******.pem ec2-user@52.68.***.***と ssh コマンドにオプションで鍵のパスを指定する必要があります。上記の例はキーペアにid_rsaを使っているので、指定が不要です。

よく使う SSH コマンドを config に登録しておこう

毎回ssh ec2-user@52.68.***.***と入力するのは手間なのです。SSH接続するための情報を~/.ssh/configというファイルに記述しておくと、入力コマンドが簡単になります。

Host bastion.vpc-mini
  Hostname 52.68.***.***
  User ec2-user
  IdentityFile ~/.ssh/id_rsa

こうしておくことで先ほどのコマンドがssh bastion.vpc-miniで済むようになります。

アプリサーバーと DB サーバーの構築

基本的には両方とも前回の記事で紹介したのと同じです。ただし、セキュリティグループはそれぞれのサーバー用のに加えて Default セキュリティグループを選択します。

踏み台サーバーからアプリサーバーに接続してみる

踏み台サーバーに接続できたはいいですが、目的はアプリサーバーに SSH 接続することです。踏み台サーバーに接続されている状態で更に SSH 接続コマンドを実行すれば良いわけですが、毎回コマンドを二段階で入力するのは少々面倒です。どうせなら踏み台 > アプリサーバー への流れを一度に行えるようにしておきたいですよね。そこで~/.ssh/configに対して以下の情報を追記します。

Host app.vpc-mini
  Hostname ***.***.***.***
  User ec2-user
  IdentityFile ~/.ssh/id_rsa
  ProxyCommand ssh bastion.vpc-mini -W %h:%p

Hostnameにはアプリサーバーインスタンスに割り当てられているPrivate IPsを指定すればOKです。こうしておくことでssh app.vpc-miniとだけコマンド実行すれば一発でアプリサーバーに SSH 接続できてしまいます。すごく便利ですね。

踏み台から別のサーバーに接続するためのキーペアを分けたいという要件においては、この方法は使えません。その場合は踏み台サーバーに接続してから別のキーを使って手動で SSH 接続することになります。

おまけ: DB サーバーに MySQL Workbench といった GUI クライアントから接続したい

logo-mysql_workbenchlogo-sequel_pro

せっかく無料で便利な DB GUI クライアントツールがたくさんあるのだから、VPC 内の DB サーバーにも接続して使いたいものです2)ちなみに僕は Sequel Pro 派です。まぁ、これといって深い理由はありませんが。。本エントリーの構成では、DB サーバーはグローバルIPを持っていないので外部から直接接続することが出来ません。アプリサーバー同様、踏み台サーバーを経由して接続する必要があります。

とはいえ実は何も難しいことはなく、大概の GUI クライアントツールには SSH 接続を経由して DB サーバーに接続する機能があります。

MySQL Workbench の場合

setting-mysql_workbench

Sequel Pro の場合

setting-sequel_pro

どちらも殆ど同じですね。このような情報を入力することで、RDS 上の DB サーバーに接続することが出来るはずです。

脚注

脚注
1 かつては Tunnel とか gatewayという呼び方をしていたみたいですが、AWS においては Bastion と呼ぶのが一般的らしいです。
2 ちなみに僕は Sequel Pro 派です。まぁ、これといって深い理由はありませんが。