当ページのリンクには広告が含まれています。

AWS

【AWS】EC2(Amazon Linux 2) ベストプラクティス & 推奨設定

【AWS】EC2(Amazon Linux 2) ベストプラクティス & 推奨設定
エンジニア
エンジニア
EC2(Amazon Linux 2)を構築しました。ベストプラクティスやセキュリティを意識した推奨設定を教えてください。

EC2におけるいくつかのベストプラクティスを紹介します。また、C2(Amazon Linux 2)は構築後にいくつか設定を加えることで、セキュリティを強化することができます。

設定作業自体は20分前後で完了するので、EC2を作成したあと最初に実施しておきましょう。

 

本記事の内容

  • EC2におけるベストプラクティス
  • EC2のセキュリティ強化と推奨設定

はじめに

事前にAmazon Linux 2でEC2を構築しておきます。未構築の場合は、以下記事などを参考に作成しておきます。

関連記事
【AWS】EC2でAmazon Linux 2を構築しSSH接続してみよう
【AWS】EC2でAmazon Linux 2を構築しSSH接続してみよう

続きを見る

 

EC2におけるベストプラクティスを理解しよう

EC2におけるベストプラクティス

EC2におけるベストプラクティスは以下になります。

  • 信頼できるAMIを使用する
  • セキュリティグループは最小限にする
  • AWSリソース間の通信許可はソースにセキュリティグループを設定する
  • アクセスキーではなくIAMロールを使用する
  • IAMポリシーは最低限の権限を付与する
  • EC2のキーペア管理に気をつける
  • 定期的に最新版のOSパッチを適用する
  • 追加パッケージをインストールする場合は最新版を使用する
  • ELBやRDSを活用する
  • AWSから届くメールを日常的に確認する
  • Trusted Advisorを活用する
  • CloudWatchでEC2を監視する

 

順番に解説しますね。

 

信頼できるAMIを使用する

EC2を構築する際は提供元が信頼できるAMIを使用します。AMI選択画面において以下2つは信頼できるAMIです。

  • クイックスタート(デフォルト):Amazonが提供しているAMI
  • AWS Marketplace:企業が提供しているAMI

 

反対に、[コミュニティ AMI] を使う際は、以下の点を考慮する必要があります。

  • [コミュニティ AMI] には一般ユーザーが公開しているAMIも含まれる。不正なプログラムが含まれていない保証はない。
  • [コミュニティ AMI] を選択する場合は、必ず所有者を確認した上で自己責任で利用すること。

 

セキュリティグループは最小限にする

セキュリティグループの使用は以下を徹底します。

  • 最小限のルールを設定する
  • 個人用のEC2にセキュリティグループでSSHを許可する際は、ソースを必ず「マイIP」に設定する

 

SSHのソースを「0.0.0.0/0」などの広域ネットワークに対して設定すると、すぐにBotなどの不正侵入プログラムの標的にされることになります。

 

  • 本記事ではネットワークACLについてふれません。理由はネットワークACLはアウトバウンドのルールも意識する必要があり、セキュリティグループと比較して設定が複雑になりがちであるためです。
  • 会社でAWSを使用する場合や、特定IPアドレスからの接続を遮断したい場合はネットワークACLの使用を検討します。

 

エンジニア
エンジニア
自宅でAWSを使用しています。以前はEC2にSSH接続できていたのに、ある日突然SSH接続できくなりました。なぜでしょうか?

セキュリティグループでSSHを「マイIP」から許可している場合によく発生します。

手順としては対象のセキュリティグループのインバウンド設定を開き、SSHのソースで再度「マイIP」を選択して「ルールを保存」をクリックすることでSSH接続できるようになります。

 

自宅からインターネットを使う場合は自分のグローバルIPアドレスは時々変わります。その場合は以前設定した「マイIP」を現在のグローバルIPアドレスに変更する必要があります。

 

SSH接続できなくなる他の原因としては以下などがありますが、本記事ではふれません。

  • 接続先IPアドレス・キーペア・ログインユーザーなどの入力ミス
  • EC2が起動していない
  • EC2のOS内部で問題が発生している
  • ネットワークACLなどセキュリティグループ以外のサービスで遮断されている

 

AWSリソース間の通信許可はソースにセキュリティグループを設定する

EC2→RDSなどインスタンス同士で通信許可する場合は、セキュリティグループのソースに相手のセキュリティグループを設定するようにします。

EC2やRDSなどのインスタンスは再起動のタイミングなどでIPアドレスが変更されますが、上記のセキュリティグループ設定を行うことで、IPアドレスの変更は意識不要になります。

 

アクセスキーではなくIAMロールを使用する

EC2でAWS CLIを実行する場合など、必要な権限をEC2に付与する際は基本的にアクセスキーではなくIAMロールを使用します。

IAMロールは定期的に認証情報が自動変更されます。
これによりもしIAMロールを設定したEC2の認証情報が漏洩した場合でも、自動変更されたあとは古い認証情報は破棄されるため不正利用を防ぐことができます。

 

アクセスキーの場合、対象のIAMユーザーでアクセスキーを再発行しない限り認証情報は固定となります。
もし一度でもアクセスキーが外部に流出してしまった場合は、不正利用される危険性があります。

 

IAMポリシーは最低限の権限を付与する

EC2にIAMロールを設定する場合、IAMロールに設定するIAMポリシーは基本的に最低限の権限のみ付与します。

 

EC2のキーペア管理に気をつける

EC2作成時にダウンロードしたキーペア(秘密鍵)はSSH接続するための認証情報になります。

キーペアは必ず自分のパソコンだけに保管します。S3、Git、Googleドライブなどインターネット上には絶対に置かないようにします。

 

定期的に最新版のOSパッチを適用する

定期的に最新版のOSパッチを適用します。OSにインストール済みのパッケージに存在する脆弱性を解消することができます。

 

追加パッケージをインストールする場合は最新版を使用する

パッケージやミドルウェア等を追加でインストールする場合は、基本的に最新のバージョンを使用しましょう。

古いバージョンは脆弱性が含まれている場合があるためです。

 

ELBを活用する

EC2でWebサーバーを構成する場合はELBを積極的に活用します。メリットは以下の通りです。

  • EC2をマルチAZで構成している場合、ELBが各EC2にリクエストを振り分け負荷分散してくれる
  • SSL証明書の管理をELBに任せることで、EC2側でのSSL管理が不要になる
  • ELBを使用するとSSL/TLS証明書に無料のACMサービスを利用可能

 

ACMはAWS Certificate Managerの略で、AWSが提供するSSL/TLS証明書サービスです。
EC2でSSL証明書を設定する場合は、無料のACMを利用できない点に注意します。

 

RDSを活用する

EC2でDBサーバーを構成する場合はなるべくRDSを使用します。DBサーバーとして必要なCPU、メモリなどのリソースをRDSに任せることでEC2側の負荷を減らすことができます。

 

EC2にWordPressをインストールしてすぐに削除する場合など、無理にRDSを使用しなくても良いケースもあります。
その方が手順としては簡単になるためです。もちろん、RDSの勉強のためにEC2 + RDSでWordPressを構築してみるのもありです。

 

AWSから届くメールを日常的に確認する

自分のAWSアカウントやEC2などが不正利用された場合に、AWSから注意喚起のメールが届くことがあります。
その際はメールの内容を確認して適切な対応を行ったあと、AWSに報告する必要があります。

以下のような場合に注意喚起のメールが届くようです。

  • EC2がハッカーなどの悪意を持った人に不正利用されている可能性がある
  • アクセスキーやシークレットキーがインターネットに流出している可能性がある

 

Trusted Advisorを活用する

Trusted Advisorは「セキュリティ」や「サービスの制限」など、5つの観点から自分のAWS環境をAWSがチェックし推奨設定を教えてくれるサービスです。
無料のAWSベーシックプランでも一部のサービスを利用できるので、積極的に活用します。

未使用の場合は、以下記事の「設定5. Trusted Advisor」を参考に設定しておきます。

関連記事
【AWS】AWSアカウント作成後に絶対にやるべき初期設定5項目:後半
【AWS】AWSアカウント作成後に絶対にやるべき初期設定5項目:後半

続きを見る

 

CloudWatchでEC2を監視する

CloudWatchなどの監視サービスを使用しEC2を監視します。インスタンスに異常があった際にメール通知などで気づくことができます。

 

個人用や開発環境のEC2の場合は、CloudWatchによる監視設定は必須ではありません。

 

EC2のセキュリティ強化と推奨設定

EC2のセキュリティ強化と推奨設定

上記を設定していきます。

 

1. 最新のOSパッチを適用する

最新版のOSパッチを適用します。


$ sudo yum update -y

パッチ適用が必要なパッケージがある場合は以下のように出力され、最後に"Complete!"となればパッチ適用完了です。


amzn2-core                                   | 3.7 kB  00:00:00
Resolving Dependencies
--> Running transaction check
---> Package chrony.x86_64 0:4.0-3.amzn2.0.1 will be updated
---> Package chrony.x86_64 0:4.0-3.amzn2.0.2 will be an update
略
Replaced:
  grub2.x86_64 1:2.02-35.amzn2.0.4     grub2-tools.x86_64 1:2.02-35.amzn2.0.4

Complete!

再度sudo yum update -yを実行し、以下のメッセージが出力されればパッチが全て適用された状態です。


$ sudo yum update -y
Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
No packages marked for update

 

Amazon Linux 2 のOSサポート期間中は、脆弱性を解消したり機能を追加したパッケージが定期的にリリースされます。
パソコンでも定期的にパッチを適用するのと同じように、サーバーにおいても定期的にパッチ適用することは非常に重要になります。

 

パッチ適用後のOS再起動は、以降の手順を進める中で実施します。

 

2. タイムゾーンの変更

Amazon Linux 2におけるタイムゾーンはデフォルトでUTCです。
EC2を東京リージョンで使用する場合はJSTのほうが都合が良いので、タイムゾーンをUTCからJSTへ変更します。

 

UTCについて

  • Universal Time Coordinatedの略
  • 協定世界時
  • UTCはJST(Japan Standard Time:日本標準時)の9時間前
  • 例:日本時間でAM10時の場合はUTCだとAM1時

 

UTCであることを確認します。


$ date
Mon Apr  5 22:28:26 UTC 2021

Amazon Linux 2はtimedatectl set-timezoneでタイムゾーンを変更できます。


$ sudo timedatectl set-timezone Asia/Tokyo

UTCからJSTに変わったことを確認します。


$ date
Tue Apr  6 07:28:57 JST 2021

 

この状態ではcronやsyslogなどの各サービスのタイムゾーンはUTCのままです。
それぞれのサービスを再起動することでJSTに変更されますが、今回は個別には行いません。
このあと実施するOS再起動でそれらのタイムゾーンも全てJSTに変更されるためです。

 

3. 不要なサービスは停止する

不要なサービスを起動すると、それらのサービスへの攻撃対象が増えることになり結果的にセキュリティリスクに繋がります。
「デフォルトは自動起動Onだが、自分のEC2では使用しないサービス」は自動起動Offにしておきます。
本記事では以下のサービスを自動起動Offにしていきます。

サービス名 説明
lvm2-lvmetad.socket LVMのメタデータ用ソケット
lvm2-lvmpolld.socket LVMのポーリング用ソケット
lvm2-monitor.service LVMの監視
mdmonitor.service ソフトウェアRAIDの監視
postfix.service メール送信・転送
rpcbind.service 自サーバーをNFSサーバーとして使用する際に必要なサービス
rpcbind.socket 自サーバーをNFSサーバーとして使用する際に必要なソケット

 

LVMとはLogical Volume Managerの略でディスクを論理的に分割する機能です。

 

自動起動On(enabled)のサービスを確認します。


$ systemctl list-unit-files | sort | grep enabled
略
sysstat.service                               enabled
systemd-readahead-collect.service             enabled
systemd-readahead-drop.service                enabled
systemd-readahead-replay.service              enabled
update-motd.service                           enabled

サービス起動状態を確認します。


$ sudo lsof -i -nP
COMMAND   PID     USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
rpcbind  2492      rpc    6u  IPv4  14969      0t0  UDP *:111
rpcbind  2492      rpc    7u  IPv4  14970      0t0  UDP *:962
rpcbind  2492      rpc    8u  IPv4  14971      0t0  TCP *:111 (LISTEN)
rpcbind  2492      rpc    9u  IPv6  14972      0t0  UDP *:111
rpcbind  2492      rpc   10u  IPv6  14973      0t0  UDP *:962
rpcbind  2492      rpc   11u  IPv6  14974      0t0  TCP *:111 (LISTEN)
chronyd  2515   chrony    5u  IPv4  15561      0t0  UDP 127.0.0.1:323
chronyd  2515   chrony    6u  IPv6  15562      0t0  UDP [::1]:323
dhclient 2729     root    6u  IPv4  16112      0t0  UDP *:68
dhclient 2835     root    5u  IPv6  16424      0t0  UDP [xxxx::xxxx:xxxx:xxxx:xxxx]:546
master   2985     root   13u  IPv4  17593      0t0  TCP 127.0.0.1:25 (LISTEN)
sshd     3198     root    3u  IPv4  19097      0t0  TCP *:22 (LISTEN)
sshd     3198     root    4u  IPv6  19106      0t0  TCP *:22 (LISTEN)
sshd     3265     root    3u  IPv4  20062      0t0  TCP 10.0.1.181:22->xxx.xxx.xxx.xxx:26382 (ESTABLISHED)
sshd     3284 ec2-user    3u  IPv4  20062      0t0  TCP 10.0.1.181:22->xxx.xxx.xxx.xxx:26382 (ESTABLISHED)

不要サービスの自動起動をOffにします。サービス名はスペース区切りで複数指定可能です。


$ sudo systemctl disable サービス名

例:上記表のサービスを全て自動起動Offに変更する場合


$ sudo systemctl disable lvm2-lvmetad.socket lvm2-lvmpolld.socket lvm2-monitor.service mdmonitor.service postfix.service rpcbind.service rpcbind.socket
Removed symlink /etc/systemd/system/multi-user.target.wants/rpcbind.service.
Removed symlink /etc/systemd/system/multi-user.target.wants/postfix.service.
Removed symlink /etc/systemd/system/multi-user.target.wants/mdmonitor.service.
Removed symlink /etc/systemd/system/sockets.target.wants/rpcbind.socket.
Removed symlink /etc/systemd/system/sysinit.target.wants/lvm2-monitor.service.
Removed symlink /etc/systemd/system/sysinit.target.wants/lvm2-lvmetad.socket.
Removed symlink /etc/systemd/system/sysinit.target.wants/lvm2-lvmpolld.socket.

 

自動起動をOffにしたサービス自体の停止(systemctl stop サービス名)は不要です。
このあと実施するOS再起動後に起動してこなくなるためです。

 

OS再起動

このあたりでOSを再起動しておきます。
rebootを実行するとOS再起動処理が走り、SSHセッションが切断されます。
通常は1,2分くらいで再起動が完了してSSH接続できるようになります。


$ sudo reboot

 

再度ec2-userでSSH接続してサービス起動状態を確認します。
直前の手順で自動起動をOffにした、rpcbindなどが起動されていないことが分かります。


$ sudo lsof -i -nP
COMMAND   PID     USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
chronyd  2487   chrony    5u  IPv4  14966      0t0  UDP 127.0.0.1:323
chronyd  2487   chrony    6u  IPv6  14967      0t0  UDP [::1]:323
dhclient 2703     root    6u  IPv4  15667      0t0  UDP *:68
dhclient 2819     root    5u  IPv6  15990      0t0  UDP [xxxx::xxxx:xxxx:xxxx:xxxx]:546
sshd     3047     root    3u  IPv4  17479      0t0  TCP *:22 (LISTEN)
sshd     3047     root    4u  IPv6  17481      0t0  TCP *:22 (LISTEN)
sshd     3104     root    3u  IPv4  18261      0t0  TCP 10.0.1.181:22->xxx.xxx.xxx.xxx:32271 (ESTABLISHED)
sshd     3122 ec2-user    3u  IPv4  18261      0t0  TCP 10.0.1.181:22->xxx.xxx.xxx.xxx:32271 (ESTABLISHED)

 

4. ec2-userを削除して新規ユーザーに切り替える

デフォルトのec2-userを使用することはセキュリティ上好ましくないので、別の新規ユーザーを作成した上でec2-userは削除します。

ハッカーやBotによるEC2への不正ログインは、まずec2-userを使用するようです。

 

変数aに任意の新規ユーザー名を代入します。
攻撃対象になりやすいユーザー名(test、user、adminなどは)は使用しないようにします。


$ a=新規ユーザー名

useraddで新規ユーザーを作成し、usermodでwheelグループに追加します。


$ sudo useradd ${a}; sudo usermod -G wheel ${a}

 

上記のuseradd実行時にユーザー名と同じ名前のグループが同時作成されます。

 

/etc/sudoers.d/90-cloud-init-usersに、新規ユーザーについてec2-userと同様の設定を追加します。


$ sudo sh -c "echo '${a} ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers.d/90-cloud-init-users"

 

/etc/sudoers.d/90-cloud-init-usersは、Amazon Linux 2におけるsudoの設定ファイルの一部です。

以下コマンドだとPermission deniedが発生します。
$ sudo echo "${a} ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers.d/90-cloud-init-users

理由は/etc/sudoers.d/90-cloud-init-usersはrootしか書き込みができず、sudoでechoを使用してリダイレクトを行う場合はリダイレクト自体はsudoが適用されないためです。
それの対処法としてダブルクォートでechoとリダイレクトを括り、それらのコマンドをまとめてsh -cの引数として渡しています。

 

次にrsyncでec2-userのホームディレクトリごと新規ユーザーのホームディレクトリにコピーします。
これにはSSH接続に必要なSSH公開鍵や環境変数ファイルも含まれます。


$ sudo rsync -ar ~ec2-user/ /home/${a}/

コピーしたファイルのオーナーをchownで新規ユーザーに変更します。


$ sudo chown -R $a: /home/${a}/

ec2-userはログアウトします。


$ exit

 

新規ユーザーでEC2にSSH接続します。(秘密鍵はec2-userで使用していたファイルと同じものを使用)

SSH接続後、新規ユーザでec2-userと同じようにsudoが使用できることを確認します。
sudoで実行するコマンドは何でも構いませんので、ここでは簡単なdateを実行します。


$ sudo date
Tue Apr  6 09:00:37 JST 2021

sudoが使えることを確認したあと、userdelでec2-userをホームディレクトリごと削除します。


$ sudo userdel -r ec2-user

最後に/etc/sudoers.d/90-cloud-init-usersからec2-userの行を削除します。


$ sudo sed -i "/ec2-user/d" /etc/sudoers.d/90-cloud-init-users

 

5. ログインユーザーにパスワードを設定しsudo実行時にパスワードを求めるようにする

ログイン用のユーザーにパスワードを設定しておくことで、万が一EC2にSSHで不正侵入されてしまった場合でもsudoコマンド実行時にパスワード入力を求めるようにできます。
そうすることでroot権限で悪用される危険性を減らすことができます。

会社などでEC2を使用していて、セキュリティグループでSSH接続を「マイIP」以外の広域ネットワークを許可している場合は、本設定は有効な防御策の一つになります。

 

個人用のAWSでEC2を使用する場合は、以下の理由によりこの設定は必須ではありません。

  • ログイン用のユーザーにパスワードを設定すると、キーペア以外にそのパスワードも管理する必要がある
  • sudo実行時にパスワード入力が必要となり手間が増える

 

変数aに対象ユーザー名を代入します。


$ a=対象ユーザー名

対象ユーザーにパスワードを設定します。


$ sudo passwd ${a}
Changing password for user USERNAME.
New password: 新規パスワードを入力
Retype new password: 再度パスワードを入力
passwd: all authentication tokens updated successfully.

 

ここで別のSSHターミナルをもう一つ起動してEC2に接続、rootにスイッチしておきます。
この後実施する/etc/sudoers.d/90-cloud-init-usersの修正作業でもしミスした場合、対象ユーザーでsudoが使えなくなる可能性があるためです。


$ sudo su -

スイッチしたrootで操作します。変数aに対象ユーザー名を代入します。


# a=対象ユーザー名

念のため変更前の/etc/sudoers.d/90-cloud-init-usersを確認します。
以下のようにNOPASSWDが含まれていますが、これはsudo実行時にパスワードを求められない設定です。


# grep ^${a} /etc/sudoers.d/90-cloud-init-users
USERNAME ALL=(ALL) NOPASSWD:ALL

/etc/sudoers.d/90-cloud-init-usersの対象ユーザーの行からNOPASSWDを削除します。


# sed -i "/^${a}/s/NOPASSWD://" /etc/sudoers.d/90-cloud-init-users

変更後の/etc/sudoers.d/90-cloud-init-usersを確認、以下のように変更されていればOKです。
NOPASSWDが含まれないので、対象ユーザーでsudoを実行する時にパスワード入力が必要となります。


# grep ^${a} /etc/sudoers.d/90-cloud-init-users
USERNAME ALL=(ALL) ALL

 

rootで接続しているSSHセッションは、念のためそのまま接続状態にしておきます。

1つめのSSHセッションでsudo実行時にパスワードが求められることと、sudoのパスワード認証が成功して末尾にdateの結果が表示されることを確認します。


$ sudo date

We trust you have received the usual lecture from the local System
Administrator. It usually boils down to these three things:

    #1) Respect the privacy of others.
    #2) Think before you type.
    #3) With great power comes great responsibility.

[sudo] password for USERNAME:
Tue Apr  6 18:03:43 JST 2021

 

6. SSHのポート番号を変更する

SSHのデフォルトポート番号は22番ですが、セキュリティグループのSSH接続を「マイIP」以外の広域ネットワークで許可している場合は、ハッカーからの攻撃対象になりやすいです。

自動化された攻撃では通常このポート番号が使われるためです。
これを別のポート番号に変えることで、セキュリティを強化できます。

本記事では変更後のポート番号を「カスタムポート番号」と呼ぶことにします。

 

個人用のAWSでEC2を使用する場合は、以下の理由によりこの設定は必須ではありません。

  • セキュリティグループのSSHインバウンドを「マイIP」に設定することで、EC2にSSHで不正侵入される危険性を減らすことができる
  • SSHのポートを変更すると、接続時にそのポート番号を明示的に指定する必要があり手間が増える

 

まずはカスタムポート番号を決めます。今回は「10001~32767」の中から選ぶことにします。

変数aにカスタムポート番号を代入します。


$ a=カスタムポート番号

今回は例としてカスタムポート番号で27485を設定します。


$ a=27485

lsofで対象のポートが使用されていない(コマンド実行後に何も表示されない)ことを確認します。もし別のサービスがこのカスタムポート番号を使用している場合は別のポート番号を選びます。


$ sudo lsof -i:${a}

 

LinuxでSSHのポート番号を変更する際に「動的・プライベート ポート番号(49152~65535)」を選択するケースがありますが、Amazon Linux 2においては推奨しません。理由は以下になります。

  • Amazon Linux 2ではデフォルトでSSMエージェントがインストールされており、デフォルトではSSMエージェントとSSHにおけるサービス起動時の依存関係が存在しない
  • Linuxは/proc/sys/net/ipv4/ip_local_port_rangeでポート番号(32768~60999)が指定されており、その範囲からサーバーと通信する上でクライアント側が一時的に使用するポート番号を動的に使用する
  • 仮にSSHのカスタムポート番号を32768~60999の範囲で起動するように変更した後、次のOS再起動のタイミングで以下2つの条件が重なるとSSHが起動できなくなる
    • SSMエージェントがSSHより先に起動した
    • SSHで設定したカスタムポート番号をたまたまSSMエージェント側で使用してしまった

ポート番号がかぶる確率は極めて低いですが、上記の場合はSSH起動時に「error: Bind to port XXXXX on 0.0.0.0 failed: Address already in use.」エラーが発生することになります。(XXXXXはポート番号)

SSHの後にSSMエージェント起動を起動するようにsystemdのUnitファイルを修正すれば上記エラーは発生しませんが、そこまでカスタマイズするのは面倒です。

 

SSHの設定にカスタムポート番号を追加し、接続確認ができた後に22番ポートを削除します。
カスタムポート番号でSSH接続できないまま22番ポートを閉じてしまうと、SSHでログインできなくなってしまうため注意が必要です。

/etc/ssh/sshd_configを本日付のファイル名でバックアップします。


$ sudo cp -p /etc/ssh/sshd_config{,_$(date '+%Y%m%d')}

/etc/ssh/sshd_config#Port 22直下にPort22Port カスタムポート番号を追加します。


$ sudo sed -i "/^#Port 22$/a Port 22\nPort ${a}" /etc/ssh/sshd_config

 

Amazon Linux 2はデフォルトだと/etc/ssh/sshd_config#Port 22はコメントアウトされていますが、Port ポート番号を設定しない限りSSHは22番をLISTENします。

 

SSHをリロードします。


$ sudo systemctl reload sshd

lsofでSSHが22とカスタムポート番号でLISTENしていることを確認します。


$ sudo lsof -i -nP | awk '/sshd/&&/LISTEN/&&/IPv4/'
sshd     3047    root    3u  IPv4  21953      0t0  TCP *:27485 (LISTEN)
sshd     3047    root    5u  IPv4  21957      0t0  TCP *:22 (LISTEN)

 

次にセキュリティグループでカスタムポート番号をインバウンド許可します。
AWSマネジメントコンソールから対象のセキュリティグループを選択→「インバウンドルールを編集」→「ルールを追加」→以下を設定し「ルールを保存」をクリックします。

  • タイプ:カスタムTCP
  • ポート範囲:設定したカスタムポート番号
  • ソース:マイIP

 

カスタムポート番号でEC2にSSH接続できることを確認します。
TeraTermの場合は「TCPポート」にカスタムポート番号を入力してEC2に接続します。

TeraTerm

 

次にSSHの22番ポートを閉じるため、/etc/ssh/sshd_configPort 22を削除します。


$ sudo sed -i "/^Port 22/d" /etc/ssh/sshd_config

SSHをリロードします。


$ sudo systemctl reload sshd

lsofでSSHがカスタムポート番号のみLISTENしていることを確認します。


$ sudo lsof -i -nP | awk '/sshd/&&/LISTEN/&&/IPv4/'
sshd     3047    root    3u  IPv4  22625      0t0  TCP *:27485 (LISTEN)

 

最後にセキュリティグループのインバウンドルールから22番を削除します。
AWSマネジメントコンソールから対象のセキュリティグループを選択→「インバウンドルールを編集」→「タイプ:SSH」となっているルールの右端にある「削除」をクリック→「ルールを保存」をクリックします。

セキュリティグループのインバウンドルール

 

次回以降に対象のEC2にSSH接続する際は、22番ではなくカスタムポート番号を使用します。

  • SSHのポート番号を22番以外に変更した場合は「EC2 Instance Connect」からEC2に接続できなくなります。
  • SSMセッションマネージャーを使用した接続には影響ありません。

 

【任意】PermitRootLogin no

/etc/ssh/sshd_configPermitRootLogin noはrootによる直接のSSH接続を禁止する設定です。Linuxのセキュリティ設定の一つとして有名ですね。

しかし、Amazon Linux 2において本設定は必須ではありません。デフォルトで以下のようにrootによる直接のSSH接続はできないようになっているためです。

  • /root/.ssh/authorized_keysの設定により、rootで直接SSH接続してもメッセージを表示してから10秒後に切断される
  • /etc/ssh/sshd_configの設定でSSHのパスワード認証が無効になっている

上記により設定自体は任意になりますが、PermitRootLogin noを設定する場合は以下を実施します。

/etc/ssh/sshd_config#PermitRootLogin yesPermitRootLogin noに置換します。


$ sudo sed -i "s/^#PermitRootLogin yes/PermitRootLogin no/" /etc/ssh/sshd_config

SSHをリロードします。


$ sudo systemctl reload sshd

 

まとめ

EC2はサーバーを簡単に構築できることが魅力的ですが、デフォルトのままだとセキュリティが弱い部分があります。

本記事を参考に、ベストプラクティスを理解しセキュリティ設定を強化することで、より安全にEC2を使用することができます。

 

当記事が参考になれば幸いです。

-AWS