概要
IP制限が出来ない環境化におけるSSHの踏み台サーバ(Bastionサーバ)を構築します。
IP制限が出来ない分、セキュリティを強化する為に二要素認証でログイン出来るように設定します。
認証要素は以下の2つです。
- 公開鍵
-
google-authenticator
が生成するワンタイムパスワード
なお本記事ではAWS上での利用を想定しています。
主なユースケース
- リモートワークの際に外部ネットワークから企業が管理するAWSサーバにSSH接続を行う
構築環境
サーバ側のOSは Amazon Linux 2
を利用します。
クライアントのPCはMacで作業を行っている事とします。
構築手順
EC2インスタンスを作成する
EC2インスタンスを作成します。
スペックは最低レベルで十分です。
インスタンスの作成手順は調べるとたくさん出てくるのでここでは割愛させて頂きます。
OSのアップデート
sudo yum update
を実行します。
ユーザーの追加
SSH認証を行う為のユーザーを追加します。
ここではユーザー keitakn
を作成すると仮定します。
sudo useradd keitakn
sudo passwd keitakn
SSH接続用のキーペアを作成(自身が使っているPC上での作業)
自身が使っているPC上でSSH接続用のキーペアを作成します。(Macを利用している想定)
詳しい手順は割愛させて頂きますが -b 4096
を指定してなるべく暗号強度の高い鍵を生成する事をオススメします。
ssh-keygen -t rsa -b 4096 -C "keitakn@example.com" -f your_key_name.pem
上記のコマンドの通りに実行すると以下の2つが生成されます。
- 秘密鍵
~/.ssh/your_key_name.pem
- 公開鍵
~/.ssh/your_key_name.pem.pub
mkdir ~/.ssh
chmod 700 ~/.ssh
chmod 600 ~/.ssh/your_key_name.pem
SSH接続を行うBastionサーバ上での作業(先程作成した keitakn
ユーザーでの作業)
~/.ssh/authorized_keys
に公開鍵の内容をコピーして下さい。(新規ファイルを生成)
ローカルPCと同じく権限を変更しておきます。
mkdir ~/.ssh
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
Google Authenticatorのインストール
sudo amazon-linux-extras install epel
sudo yum install google-authenticator
qrencode-libs
をインストール
QRコードで二要素目の認証を行う為に qrencode-libs
をインストールします。
sudo yum install qrencode-libs
既にインストール済の場合はこの手順をスキップ出来ます。
google-authenticatorの設定を行う(先程作成した keitakn
ユーザーでの作業)
google-authenticator
を実行します。
すると対話式のIFになるので順番に設定を行っていきます。
Do you want authentication tokens to be time-based (y/n)
時間ベースのトークンを作成するか聞かれるのでyを設定します。
Do you want me to update your "/home/{ユーザー名}/.google_authenticator" file? (y/n)
めちゃくちゃデカイQRコードが出てくるので専用のアプリ(お使いのスマホでGoogle Authenticatorでアプリストアを検索すれば出ます)で読み取ります。
QRコードの情報と一緒に以下のようなファイルを更新するか聞かれるのでyを設定します。
Do you want me to update your "/home/{ユーザー名}/.google_authenticator" file? (y/n)
この時に生成される ~/.google_authenticator
はスマホ端末を無くしたりした際の復旧に必要になるので何らかの手段で控えておきます。
次に以下のメッセージが出ます。これは同じワンタイムパスワードで複数回ログイン出来ないようにするものです。
Do you want to disallow multiple uses of the same authentication
token? This restricts you to one login about every 30s, but it increases
your chances to notice or even prevent man-in-the-middle attacks (y/n)
これをyにすると30秒に1回のみログインができるようになります。
設定すると以下のようなメッセージが出ます。
By default, a new token is generated every 30 seconds by the mobile app.
In order to compensate for possible time-skew between the client and the server,
we allow an extra token before and after the current time. This allows for a
time skew of up to 30 seconds between authentication server and client. If you
experience problems with poor time synchronization, you can increase the window
from its default size of 3 permitted codes (one previous code, the current
code, the next code) to 17 permitted codes (the 8 previous codes, the current
code, and the 8 next codes). This will permit for a time skew of up to 4 minutes
between client and server.
Do you want to do so? (y/n)
これは、時間ベースでワンタイムパスワードを発行するためクライアントとサーバーで時間のズレによってログインできない問題が発生することがあるため、ズレに対応するための余分なワンタイムパスワードを発行してよいか聞かれています。
特に問題ない場合は余分な物は発行しないほうが安全なため、nを選択します。
これは、ログインの試行回数を30秒に3回以下に制限するかの設定です。
If the computer that you are logging into isn't hardened against brute-force
login attempts, you can enable rate-limiting for the authentication module.
By default, this limits attackers to no more than 3 login attempts every 30s.
Do you want to enable rate-limiting? (y/n)
安全性を重視する場合はyを選択します。
SSHの設定を行う(rootでの作業)
/etc/pam.d/google-auth
を以下の内容で新規作成します。
#%PAM-1.0
auth required pam_env.so
auth sufficient pam_google_authenticator.so try_first_pass
auth requisite pam_succeed_if.so uid >= 500 quiet
auth required pam_deny.so
/etc/pam.d/sshd
を修正します。
#auth substack password-auth # コメントアウト
auth substack google-auth # 追加
/etc/ssh/sshd_config
を変更します。
# ChallengeResponseAuthentication no という記述があるので↓に変更
ChallengeResponseAuthentication yes
# 追加↓
AuthenticationMethods publickey,keyboard-interactive
設定を反映するためsshdを再起動します。
sudo systemctl restart sshd.service
接続確認(自身が使っているPC上での作業)
これまでの手順が間違っていなければSSHログインの際にワンタイムパスワードを要求されるハズです。
確認してみましょう。
万が一設定が間違っていると二度とログイン出来なくなるリスクもあるので、現在SSH接続を行っているセッションは切らないほうが良いでしょう。
自身のMacの ~/.ssh/config
に以下の記述を書いておくと便利です。
Host bastion-keitakn
HostName 54.250.39.100
Port 22
User keitakn
IdentityFile ~/.ssh/your_key_name.pem
Host: sshコマンドで使う名前、分かりやすければ何でもOK
HostName: サーバのIPアドレス or ホスト名
Port: 通常は22を入れればOK
User: 先程作成したユーザー名
IdentityFile: 作成した秘密鍵のパス
ssh bastion-keitakn
を実行します。
Verification code:
を聞かれるのでアプリから6桁のコードを確認し入力します。
6桁の数字が正しければSSHログインが正常に行われるハズです。