はじめに
この投稿は、EC2をベースとしたLAMP Stackサーバの構築手順をまとめた記事です。
- EC2でサーバ構築の方法がわからない
- 具体的な手順がわからない
- レンタルサーバしか使ったことがない
といった方々に、少しでもお役に立てればと思います。
※インフラ構築については片手間で行う程度なので、手順に不足点があるかもしれないので、気づいた方がいらっしゃいましたらご指摘頂けると助かります!
AWS 構成
本記事で取り扱うサービスは次のとおりです。各サービスごとに構築・設定手順を説明します。
- AWS EC2
- AWS Certificate Manager
- AWS ALB
- AWS WAF
サーバソフトウェアについて
最初からサーバソフトウェアをインストールしていくのは、正直つらすぎるので、AWSマーケットプレイスに公開されているBitnami製イメージを利用します。
LAMP Stack(LAMP with PHP 7.1 Certified by Bitnami)
インストールされているソフトウェアは以下の通り。
LAMP with PHP 7.1 Certified by Bitnami
Pre-installed and configured components include FastCGI, OpenSSL, phpMyAdmin, ModSecurity, SQLite, Varnish (TM), ImageMagick, xDebug, Xcache, OpenLDAP, ModSecurity, Memcache, OAuth, PEAR, PECL, APC, GD, cURL and more.
Use any of the pre-installed PHP frameworks right out of the box, including Zend, Symfony, CodeIgniter, CakePHP, Smarty, and Laravel.
大まかな手順
- EC2セットアップ
- Elastic IP 設定
- ドメイン(AWS Route53)設定
- AWS Certificate Manager(SSL 証明書)作成
- ロードバランサー(ALB)設定
- WAF 設定
EC2セットアップ
- マネジメントコンソールで
EC2
を選択 -
AWS Marketplace
> "lamp"で検索 - "LAMP with PHP 7.1 Certified by Bitnami "を選択
- インスタンスの詳細はとくに編集の必要は無し。ストレージについては必要であろう容量を入力する
- インスタンスと
確認と作成
ボタンをクリック キーペアを作成したいない場合は新規作成が必要になる。任意の名前(英数小文字)をつけて、
キーペアのダウンロード
を押してダウンロードする。ダウンロード後インスタンス作成を続行する
一覧にインスタンスが表示される。インスタンス一覧の情報画面 >
IPv4 パブリック IP
をブラウザで表示、確認できるかを確認bash でログインできることを確認できたら作業完了
# キーペアの権限を変更
chmod 400 xxxxxxxx.pem
# SSH接続
ssh -i "xxxxxxxx.pem" ubuntu@ec2-xxxxxxxx.xxxxxx.xxxxxx.com
The authenticity of host 'ec2-xxxxxxxx.xxxxxx.xxxxxx.com (xx.xxx.xxx.xxx)' can't be established.
ECDSA key fingerprint is SHA256:xxxxxxxxxxxxx/xxxxxxx.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'ec2-xxxxxxxx.xxxxxx.xxxxxx.com' (ECDSA) to the list of known hosts.
Welcome to Ubuntu xx.xx.x LTS (GNU/Linux xxxx-aws x86_64)
*** System restart required ***
___ _ _ _
| _ |_) |_ _ _ __ _ _ __ (_)
| _ \ | _| ' \/ _` | ' \| |
|___/_|\__|_|_|\__,_|_|_|_|_|
*** Welcome to the Bitnami LAMP 7.x.xx ***
*** Documentation: https://docs.bitnami.com/aws/infrastructure/lamp/ ***
*** https://docs.bitnami.com/aws/ ***
*** Bitnami Forums: https://community.bitnami.com/ ***
bitnami@ip-xxxxxxxx:~$
セキュリティグループについて
EC2 に関連付けされているセキュリティポリシーが初期設定によっては ssh のみしか有効になっていない可能性があります。その場合パブリック IP でアクセスできないため、EC2 のメニュー欄のセキュリティポリシーから、対象の EC2 インスタンスに紐づくセキュリティグループのインバウンド
設定を開き、必要なプロトコルの設定を追加してください。
Elastic IP の設定
EC2 は初期状態ではパブリック IP となっており、インスタンスを再起動すると IP が変わってしまいます。ドメインとの関連付けを永続化するために、静的 IP を指定する必要があります。
- EC2 メニュー内の
Elastic IP
を選択 -
新しいアドレスの割り当て
を選択 -
IPv4 address pool > Amazon pool
を選択して次へ(リージョンによっては Scope VPC のみしか出てこない) - アドレスの関連付けで
リソース > インスタンス
、インスタンス
に作成した EC2 インスタンスの ID を指定(作成したインスタンスがセレクトボックスで表示される)、設定が完了したら関連付け
ボタンをクリック - 作成完了、IP 有効後に一覧画面の説明欄に表示される
Elastic IP
でブラウザアクセス可能かどうかを調べる
参考
AWS EC2 インスタンスに Elastic IP(固定グローバル IP アドレス)を割り当てる
作業用ユーザ作成
新規ユーザ作成
SSH/SFTP 接続可能なユーザを新たに作成します。この時点では SFTP に接続を絞るなどは行いません。
# 特権ユーザに切り替え
sudo su
# ユーザ作成
sudo useradd -m {作成user名}
sudo passwd {作成user名}
# .sshフォルダ作成
sudo su - {作成user名} #ユーザ切り替え
mkdir .ssh # 秘密鍵・公開鍵の作成(id_rsa, id_rsa.pub)
# 公開鍵・秘密鍵の作成
cd .ssh
ssh-keygen -t rsa #チュートリアルに従って作成
# 秘密鍵・公開鍵設定
mv id_rsa.pub authorized_keys # 公開鍵をauthorized_keysにリネーム
chmod 600 authorized_keys # パーミッション変更
cat id_rsa # 秘密鍵のテキストが表示されるので、コピペしてxxxx.pemとして保存
xxx.pem を元に ssh、sftp でログインできるかを確認してください。
# サーバログイン
chmod 400 xxx.pem
ssh -i "xxx.pem" {作成user名}@ecX-XX-XX-XX-XX.xxxxxxx.compute.amazonaws.com
ユーザの権限変更
この状態ではドキュメントルートにアクセスしてもユーザディレクトリの中以外、何も編集できない状態です。
作業ユーザ向けに書き込み許可を与えるため、以下の手順でドキュメントルートを共同編集ディレクトリとして設定します。
id bitnami #所属するグループ等を確認
# ログイン後に特権ユーザに切り替え
sudo su
# htdocsの共同編集用グループを作成
groupadd {グループ名}
# htdocsディレクトリの管理グループを変更
chgrp {グループ名} /home/bitnami/htdocs/
# Permissionを設定
chmod 775 /home/bitnami/htdocs/
# ユーザをグループに追加
gpasswd -a {追加したいユーザ名} {グループ名}
# SGID(Set Group ID)を設定する
chmod g+s /home/bitnami/htdocs/
# 新規ファイル・ディレクトリ作成時のアクセス権の設定
# ※通常値は0022。それを0002(グループなら書き込み、読み込みが出来るファイルを標準で作成)にする
# ユーザログイン後、umask 0022 でも対応可能だが、ログイン後に設定がリセットされるため、.bashrcに記述する
sudo sh -c "echo umask 022 >> /home/{ユーザ名}/.bashrc" # 各ユーザごとに.bashrcへ追記
sudo sh -c "echo umask 022 >> /etc/skel/.bashrc" # ユーザが新規に追加される際に自動的に記述
# 既存ディレクトリのアクセス権とグループの設定
chgrp {グループ名} -R /home/bitnami/htdocs/ # -Rオプション(--recursive)でディレクトリ内のグループも変更
chmod g+w -R /home/bitnami/htdocs/ # -Rオプション(--recursive)でグループに書き込み権限を付与
find . -type d -print | xargs chmod g+w # ディレクトリのみを探索して、一括して権限を書き換える
# 書き換え後にgroupが変更になっているかを確認
ls -al /home/bitnami/htdocs/
drwxrwsr-x 4 bitnami {グループ名} 4096 xxx 00 xx:xx .
drwxr-sr-x 14 root root 4096 xxx 0 xx:xx ..
-rw-rw-r-- 1 bitnami {グループ名} 1292 xxx 00 xx:xx xxx.html
-rw-rw-r-- 1 bitnami {グループ名} 4837 xxx 00 xx:xx xxx.css
-rw-rw-r-- 1 bitnami {グループ名} 1150 xxx 00 xxxx xxx.ico
-rw-rw-r-- 1 bitnami {グループ名} 1292 xxx 00 xx:xx xxx.html
# シンボリックリンク作成
ln -s /home/bitnami/htdocs htdocs
参考
ドメイン設定
ここでは、ドメインをAWS Route53で管理せず、DNSはお名前.comなどの外部サービスで管理している、という想定で説明します。
Certificate Manager の設定(SSL 設定)
- Certificate Managerの画面から
今すぐ始める
を選択 - 証明書のリクエストでドメイン名の追加を行う。
- DNS認証かemail認証かを選んで続行。
検証保留中
というステータスになったことを確認 - 承認後、
承認完了
というステータスになると、各サービスでACMを利用できるようになる
参考
phpMyAdmin の設定
bitmani Lampstack ではデフォルトで phpMyAdmin が動作します。http://{ElasticIPで作成した静的IP}/phpmyadmin/
でアクセスできますが、初期設定のセキュリティではアクセス許可がありません。
以下のファイルを編集することでアクセスが可能になります。
phpMyAdmin の開通
# viで開く
vi /opt/bitnami/apps/phpmyadmin/conf/httpd-app.conf
# 以下の記述を書き換える
>> Allow from 127.0.0.1 >> Allow from all
>> Require local >> Require all granted
# サーバの再起動
sudo /opt/bitnami/ctlscript.sh restart apache
初期パスワードについて
EC2 インスタンスの起動直後であれば、EC2 画面のインスタンスアクション > インスタンスの設定 > システムログの取得
で、Setting Bitnami application password to 'xxxxxxxxxxx'と表示されている xxxxxxxxxxx の部分が該当します。
あとで確認する場合は、bitnami ユーザのbitnami_credentialsをcatして確認できます。
cd home/bitnami
cat bitnami_credentials #bitnami_credentialsを開いてパスワードを確認
Welcome to the Bitnami LAMP Stack
******************************************************************************
The default password is 'xxxxxxxxxxx'.
******************************************************************************
You can also use this password to access the databases and any other component the stack includes.
Please refer to https://docs.bitnami.com/ for more details.
初期 ID とパスワードは以下の通り。
id: root
pass: 上述のpassword
MySQLの作業用ユーザ追加
初期パスワードをそのまま開発に使うのは問題なので、DB操作用ユーザ作成を作成します。ここでは PHPMyAdmin を通してユーザを作成する方法を解説します。
- phpMyAdmin にログイン
- ルート画面で
User accounts
を選択 -
Add user account
を選択 -
User name
やPassword
を入力して、実行をクリックし、新規ユーザを作成 - ログインし直しでアクセスできるか確認
[OPTION] mysql コマンドでユーザ作成済みかを確認
コマンドで念の為ユーザが作成されているかを確認します。
sudo su # ルートユーザに権限変更
mysql -u root -p # mysqlにログイン
select user, host from mysql.user; # mysqlの全ユーザを確認
+---------------+-----------+
| user | host |
+---------------+-----------+
| mysql.session | localhost |
| mysql.sys | localhost |
| root | localhost |
| {作成ユーザ名} | localhost |
+---------------+-----------+
4 rows in set (0.00 sec)
ロードバランサー(ALB)の設定
従来は CloudFront 経由でのみしか設定できなかったAWS WAFですが、ALB(Application Load Balancer)を使うことで簡単に利用可能です。
- EC2 メニュー>ロードバランサーを選択
-
Application Load Balancer
を選択して作成 - 任意の
名前
を入力し、ロードバランサーのプロトコルは http,https を選択 - 上述で作成済みの ACM 証明書を選択する。セキュリティポリシーは指定がない場合は Default で OK
- セキュリティポリシーを選択。EC2を作成するときに生成されたセキュリティポリシーを利用する
- ルーティングの設定。1ルーティングにつき、1ターゲットグループが指定できる
- ターゲットのEC2インスタンスを指定。チェックを入れて
登録済みに追加
ボタンをクリック - 作成完了。ロードバランサー一覧画面に戻り、作成したDNS名をメモして、Route53や外部DNSサービスとの関連付けを行う
セキュリティグループの設定
EC2とALBとを紐付けることができましたが、今のままではブラウザからEC2のパブリックIPで、サイトやアプリケーションが表示できてしまいます。
{{ 以下執筆中 }}
参考
AWS WAF設定
IP 制限とディレクトリに対してのアクセス制限の設定方法を解説します。大まかに以下の手順で設定を行います。※WAFはALB(Application Load Balancer)に対してのみ設定が可能です。
- 制限・設定したい内容(Condition)の反映(IPのフィルタリング、アクセスを制限するフォルダー等)
- Conditionを元にRulesを設定
- Rulesを使ってWebACL(Web Access Condition List)を作成
- ロードバランサー(ALB)に設定反映
今回は特定のディレクトリに対して、指定のIPでのみアクセスが可能という設定を行います。
制限IP指定
-
IP addresses
を指定 - IP Version は`IP v4'
- Address にアクセスを制限したい IP を入力※CIDR 形式でしか入力できない
CIDR 形式について
たとえば自身の IP が192.168.0.1
だった場合、192.168.0.1/32
と入力する必要があります。
CIDRの説明についてはこちらを参考にして下さい。
※登録できるアドレスは /8, /16, /24, /32 の CIDR アドレスのみ
制限対象ディレクトリを設定
正規表現によるディレクトリのマッチング設定も可能。今回は静的なディレクトリに指定で簡単に行う。
-
String and regex matching
を選択してCreateを押す - 単純にディレクトリにアクセス制限を課したい場合は
Type > String match
を選択 - Filter settingsは
Part of the request to filter on
をURI
、Match typeはcontain
、TransformationはURI decode
を選択 - Add Filterを押して、filterに追加する。問題なければCreateを押して作業完了
Roules設定
-
Rules
のCreate Rule
を選択 -
Name
、CloudWatch metric name
を指定、Rule type
は何も指定がなければ、Regular rule
を設定 - Add conditionsについては上記で設定済みのIPとディレクトリ指定設定を利用する。
does not
originate from an IP address in
で、IPが管理者や特定の会社のIPでない場合と指定、Andでdoes
match at least one of the filters in the string match condition
としてディレクトリ設定を行う。この設定で、制限IP以外から指定ディレクトリにアクセスがあった場合、アクセスを制限するというルールが策定できる -
Create
を押して作業完了
Web ACL 作成
-
Web ACLs > Create Web ACL
を選択 -
Name web ACL
画面に移動。Resource type to associate with web ACL
でApplication load balancerを、AWS resource to associate
では作成済みのロードバランサー(ALC)を選択 - Create conditions はすでに condition を作成済みなのでスキップ
-
Create rules
で、設定済みのルールをAdd rules to a web ACL
から選択・追加。Allow all requests that don't match any rules
をAllow all requests that don't match any rules
に設定 -
Review and create
でConfirm and Create
を押すと作成完了 - 設定したディレクトリにアクセス制限がかかっているかどうかを確認
参考
Auto SnapshotによるEC2の自動バックアップ(オプション)
自動バックアップの方法は自力でLambdaを書くなどの方法もありますが、もっとも簡単な方法として、CloudWatchのルールを使った自動バックアップ、最近だとAmazon Data Lifecycle Manager (Amazon DLM)を使った方法があります。詳しくは各参考記事を確認してください。
2018年12月現時点では、世代管理や何世代から破棄するなどの設定を柔軟にできるAmazon DLMよるバックアップを推奨します。
Amazon DLMよるバックアップ方法
【新サービス】EBSスナップショットのライフサイクルを自動化するAmazon DLMが登場!
Cloudwatchによるバックアップ方法
終わりに
個人的にはレンタルサーバとほぼ同等の構成・構築をAWSで行なうのであれば、Lightsailで十分だと考えています。一方でロードバランサーの細かい設定、WAF(Web Application Firewall)の設定等、オプションを簡単に導入していきたい、というケースが想定される場合、EC2で作るケースが多いです。
今回の構築調査・実作業の感想として、マーケットプレイスのディスクイメージを使うと、思った以上に構築作業のコストが下げられることがわかりました。ただ一方、比較的簡単とはいえ最初からサーバを立ち上げるのは、小規模な会社やインフラ専属のエンジニアが在籍していないと難しいことに変わりません。その後のセキュリティ対策・メンテナンスコストもかかるので、なおさら難しい..と思いました(苦笑
AWSに縛られず、在籍しているエンジニアのスキル、アクセス負荷やユーザ見込み数、その後の運用コストを考えて、プロジェクトに最適なインフラ環境を立ち上げられるのが理想だと思います。