no image

SSH接続を多要素認証にする

1. はじめに

はしへいです。Linuxサーバでは必ずと言って良いほど利用するSSHサービス、LinuxサーバをIaaSサービスを用いて構築した場合にはインターネット側からログイン出来る様にする事も多いと思います。

しかしセキュリティ面から見ると、このSSHサービスはクラッカーの標的になる事も多く、このWebサイトをホストしているサーバにもちょくちょくSSHサービスに対する攻撃がされています。そこで対策として今回は多要素認証を導入してみました。

2. SSHサービスに対する防御

2-1. 既存設定セキュリティ対策

外部からサーバへの不正アクセスを防ぐには認証を設ける事も大切ですが、VPNや外部と切り離されたネットワーク経由のみからログインできるようにするなど、そもそも攻撃されないにこした事はありません。

このWebサイトをホストするサーバでは上記の様な対策が出来ていなかった為、最低限のセキュリティ対策として、サーバ不要ポートの閉塞、サービスポート番号の変更、ネットワークフィルタリングの設定を行なった上で今回の多要素認証を導入しています。

2-2. 多要素認証の検討

多要素認証には生体認証を用いるものや、トークンを用いるものがあるので、以下の様に比較し、今回は導入の敷居が低い(ハードウェア購入不要)な二段階認証を導入する事にした。

No. 種類 メリット デメリット
1 FIDO(指紋や声紋認証) パスワードを用いず生体認証を用いる事からセキュリティが高い認証情報を設定できる 指紋センサーなどのハードウェアが必要となる
2 二段階認証 OTP生成ハードウェアを手元に準備する必要があることから、パスワードのみの入手に比べ、セキュリティが高い 二段階目の認証もOTPである事からブルートフォースアタックによる攻撃で突破される可能性が残る
3 公開鍵認証方式 スワードのみに頼らない認証方式である為、パスワードによるブルートフォースアタック攻撃では突破できない 証明書がインストールされた端末を攻撃者に入手されるとブルートフォースアタックで証明書を不正利用され、認証を突破される可能性がある

3. SSHサーバへのGoogle Authenticatorの導入

今回設定するSSHDでは証明書に依る認証と二段階認証を組み合わせる設定を確認できなかった。その為今回はSSHログインへの認証は通常のユーザID/パスワードに依る認証とOTPに依るパスワード入力を実施する。

3.1. Google Authenticatorの導入

Google Authenticatorをビルドする為、開発ツールをインストールする。

 $ sudo yum -y groupinstall "Development Tools"
 $ sudo yum -y install pam-devel

Google Authenticatorのソースをダウンロードしビルドする。

 $ cd /usr/local/src
 $ sudo git clone https://github.com/google/google-authenticator-libpam.git
 $ cd google-authenticator-libpam/
 $ sudo ./bootstrap.sh

私の環境では以下の様なPerlエラーが発生した。環境変数を設定することで解決出来る。

エラー内容

perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
    LANGUAGE = (unset),
    LC_ALL = (unset),
    LC_CTYPE = "UTF-8",
    LANG = "en_US.UTF-8"

エラーへの対処として環境変数を設定する。

 $ export LANGUAGE="en_US:en"
 $ export LC_ALL="en_US.UTF-8"
 $ export LC_CTYPE="UTF-8"

サーバ再起動後も有効にしておくため、設定ファイルへ記載する

$ sudo vi /etc/environment
$ cat /etc/environment
LANGUAGE="en_US:en"
LC_ALL="en_US.UTF-8"
LC_CTYPE="UTF-8"
LANG="en_US.UTF-8"

ビルドとインストール

 $ sudo ./bootstrap.sh
 $ sudo ./configure
 $ sudo make
 $ sudo make install 

3-2. SSHサーバ(PAM)の設定

PAMからGoogle Authenticatorを呼び出せる様にリンクを張る

 $ ln -s /usr/local/lib/security/pam_google_authenticator.so /usr/lib64/security/pam_google_authenticator.so 
 $ sudo vi /etc/pam.d/sshd
 以下の行を追加
 auth required pam_google_authenticator.so

SSHD設定ファイルを設定

$ sudo vi /etc/ssh/sshd_config
以下の行を修正する。
PasswordAuthentication yes ChallengeResponseAuthentication yes

設定しないと、「Permission denied (publickey,gssapi-keyex,gssapi-with-mic).」というエラーが出力される。

3-3. OTPの生成

Google AuthenticatorでOTPを生成

$ google-authenticator

Do you want authentication tokens to be time-based (y/n) y
Warning: pasting the following URL into your browser exposes the OTP secret to Google:
https://www.google.com/chart?chs=200x200&chld=M|0&cht=qr&chl=otpauth://totp/ma****
↑上記で出力されるリンクをWebブラウザから開くとQRコードが出力される為、QRコードをAndroidでダウンロードしたGoogle Authenticatorアプリから読み取りOTPを設定する。 Your new secret key is: 2***********************OU Enter code from app (-1 to skip): 033*** ↑AndroidアプリのGoogle Authenticatorアプリで出力されるコードを入力する。 Code confirmed Your emergency scratch codes are: 6798**** 5424**** 5859**** 6407**** Do you want me to update your "/home/ma967gachapin/.google_authenticator" file? (y/n) y 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 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) y 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サーバ再起動

 $ sudo sshd -t
 $ sudo systemctl restart sshd
 $ sudo systemctl status sshd
 sshd.service - OpenSSH server daemon
   Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; vendor preset: enabled)
   Active: active (running) since Fri 2019-**-** ********** 

3-4. SSHサーバへのログイン

リモート端末からSSHでログインすると、「Verification code」を聞かれる。Verification codeにはGoogle AuthenticatorのOTPを入れる

 $ ssh [email protected] -p 10022
 Password:
 Verification code:
 Last failed login: Sun *****