Bastionサーバに MFA を導入してみた

# 背景・目的
先日、Bastionを用意し、ProxyJumpを試しました。
今回は、BastionにMFAを導入してみます。

https://qiita.com/zumax/items/88e7d07b6dd7bb6c217d

# 概要
## PAMとは
- Pluggable Authentication Modulesの略
- ユーザログインや認証のときに、"どんな認証ステップを通すか" を設定ファイルで自由に構成できる仕組み
- 各種認証モジュールをサポートするために明確に定義されたフレームワーク


# 実践
## MFAのセットアップ
1. SSHでBastionにログインします
    ```bash
    % ssh bastion 
       ,     #_
       ~\_  ####_        Amazon Linux 2023
      ~~  \_#####\
      ~~     \###|
      ~~       \#/ ___   https://aws.amazon.com/linux/amazon-linux-2023
       ~~       V~' '->
        ~~~         /
          ~~._.   _/
             _/ _/
           _/m/'
    Last login: Fri Apr 11 04:11:29 2025 from XXXXX
    [ec2-user@ip-XXXX ~]$ 
    ```

1. Google Authenticatorをインストールします
    ```bash
    [ec2-user@XXXXXXX ~]$ sudo yum install google-authenticator
    Amazon Linux 2023 Kernel Livepatch repository                                                                                                                                                                                            116 kB/s |  15 kB     00:00    
    Dependencies resolved.
    =========================================================================================================================================================================================================================================================================
     Package                                                                Architecture                                             Version                                                             Repository                                                     Size
    =========================================================================================================================================================================================================================================================================
    Installing:
     google-authenticator                                                   x86_64                                                   1.09-5.amzn2023                                                     amazonlinux                                                    57 k
    
    Transaction Summary
    =========================================================================================================================================================================================================================================================================
    Install  1 Package
    
    Total download size: 57 k
    Installed size: 120 k
    Is this ok [y/N]: y
    Downloading Packages:
    google-authenticator-1.09-5.amzn2023.x86_64.rpm                                                                                                                                                                                          886 kB/s |  57 kB     00:00    
    -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    Total                                                                                                                                                                                                                                    613 kB/s |  57 kB     00:00     
    Running transaction check
    Transaction check succeeded.
    Running transaction test
    Transaction test succeeded.
    Running transaction
      Preparing        :                                                                                                                                                                                                                                                 1/1 
      Installing       : google-authenticator-1.09-5.amzn2023.x86_64                                                                                                                                                                                                     1/1 
      Running scriptlet: google-authenticator-1.09-5.amzn2023.x86_64                                                                                                                                                                                                     1/1 
      Verifying        : google-authenticator-1.09-5.amzn2023.x86_64                                                                                                                                                                                                     1/1 
    
    Installed:
      google-authenticator-1.09-5.amzn2023.x86_64                                                                                                                                                                                                                            
    Complete!
    [ec2-user@XXXXXXX ~]$ 
    
    ```

1. インストールされました
    ```bash
    [ec2-user@XXXXXXX ~]$ which google-authenticator 
    /usr/bin/google-authenticator
    [ec2-user@XXXXXXX~]$ 
    ```


1. 初期設定（TOTPシークレットの生成）します。シークレットキーが生成されます
    ```bash
    [ec2-user@XXXXXX ~]$ 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?XXXXXXX
    Failed to use libqrencode to show QR code visually for scanning.
    Consider typing the OTP secret into your app manually.
    Your new secret key is: XXXXXXXXX
    Enter code from app (-1 to skip): 
    
    ```

1. Google Authenticatorアプリを開き下記を入力し、Addをクリックします
    - Account name:任意
    - Your key:上記の secret key
    - Type of key：Time based

1. Google Authenticatorアプリに、コードが表示されるので`Enter code from app (-1 to skip): `に入力します
1. emergency scratch codesが表示されます。
    ```bash
    Enter code from app (-1 to skip): XXXXXX
    Code confirmed
    Your emergency scratch codes are:
      XXXXXX
      XXXXXX
      XXXXXX
      XXXXXX
      XXXXXX
    ```
1. `google_authenticator`を更新します
    ```bash
    Do you want me to update your "/home/ec2-user/.google_authenticator" file? (y/n) 
    ```

1. 30秒ごとに1回のログインに制限します
    ```bash
    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) 
    ```

1. ウィンドウサイズは3コードにします
    ```bash
    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) 
    ```

1. レート制限を30秒ごとに3回までにします
    ```bash
    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) 
    ```

## PAMの設定
1. `/etc/pam.d/sshd`を修正します
    ```bash
    [ec2-user@XXX ~]$ sudo vim /etc/pam.d/sshd 
    ```

1. `pam_google_authenticator.so`を1番上に追加し、`password-auth`をコメントアウトします
    ```bash
    auth required pam_google_authenticator.so
    # auth       substack     password-auth

    ```

## sshd_configを設定
1. `/etc/ssh/sshd_config`を修正します
    ```bash
    [ec2-user@XXX ~]$ sudo vim /etc/ssh/sshd_config
    ```

1. 下記を確認・修正します
    - `UsePAM yes`にします
    ```bash
    # Set this to 'yes' to enable PAM authentication, account processing,
    # and session processing. If this is enabled, PAM authentication will
    # be allowed through the KbdInteractiveAuthentication and
    # PasswordAuthentication.  Depending on your PAM configuration,
    # PAM authentication via KbdInteractiveAuthentication may bypass
    # the setting of "PermitRootLogin without-password".
    # If you just want the PAM account and session checks to run without
    # PAM authentication, then enable this but set PasswordAuthentication
    # and KbdInteractiveAuthentication to 'no'.
    # WARNING: 'UsePAM no' is not supported in Fedora and may cause several
    # problems.
    #UsePAM no
    UsePAM yes
    
    ```
    - `ChallengeResponseAuthentication yes`を追加します
    ```bash
    ChallengeResponseAuthentication yes
    ```
    - `PasswordAuthentication no`とし、パスワード認証と空パスワードを無効にします
    ```bash
    # Explicitly disable PasswordAuthentication. By presetting it, we
    # avoid the cloud-init set_passwords module modifying sshd_config and
    # restarting sshd in the default instance launch configuration.
    PasswordAuthentication no
    PermitEmptyPasswords no
    ```
    - `AuthenticationMethods publickey,keyboard-interactive`を追加し、鍵＋TOTP(MFA)の組み合わせを有効化します
    ```bash
    AuthenticationMethods publickey,keyboard-interactive
    ```
1. sshdをリスタートします
    ```bash
    [ec2-user@XXXXX ~]$ sudo systemctl restart sshd
    ```

## ログイン確認
### bastionへログイン
1. 一度ログアウトします
    ```bash
    [ec2-user@XXXXX ~]$ exit
    logout
    $
    ```
1. ログインします。想定通り認証を求められました
    ```bash
    ~ % ssh bastion
    (ec2-user@XXXXXX) Verification code: 
    ```
1. できました！
    ```bash
    (ec2-user@XXXXXX) Verification code: 
       ,     #_
       ~\_  ####_        Amazon Linux 2023
      ~~  \_#####\
      ~~     \###|
      ~~       \#/ ___   https://aws.amazon.com/linux/amazon-linux-2023
       ~~       V~' '->
        ~~~         /
          ~~._.   _/
             _/ _/
           _/m/'
    Last login: Fri Apr 11 05:27:22 2025 from XXXXXX
    [ec2-user@XXXXXX ~]$ 
    ```
### privateへログイン
1. ログインします。想定通り認証を求められました。できました！
    ```bash
    % ssh internal
    (ec2-user@XXXXXX) Verification code: 
       ,     #_
       ~\_  ####_        Amazon Linux 2023
      ~~  \_#####\
      ~~     \###|
      ~~       \#/ ___   https://aws.amazon.com/linux/amazon-linux-2023
       ~~       V~' '->
        ~~~         /
          ~~._.   _/
             _/ _/
           _/m/'
    Last login: Fri Apr 11 05:25:21 2025 from XXXXXX
    [ec2-user@XXXXXX ~]$ 
    
    ```

## （オプション）MFAをQRコードでセットアップする
1. qrencodeをインストールします
    ```bash
    [ec2-user@XXXXX ~]$ sudo yum install qrencode
    Last metadata expiration check: 0:19:19 ago on Fri Apr 11 05:28:33 2025.
    Dependencies resolved.
    =========================================================================================================================================================================================================================================================================
     Package                                                         Architecture                                             Version                                                                    Repository                                                     Size
    =========================================================================================================================================================================================================================================================================
    Installing:
     qrencode                                                        x86_64                                                   4.1.1-2.amzn2023.0.2                                                       amazonlinux                                                    26 k
    Installing dependencies:
     libpng                                                          x86_64                                                   2:1.6.37-10.amzn2023.0.6                                                   amazonlinux                                                   128 k
     qrencode-libs                                                   x86_64                                                   4.1.1-2.amzn2023.0.2                                                       amazonlinux                                                    66 k
    
    Transaction Summary
    =========================================================================================================================================================================================================================================================================
    Install  3 Packages
    
    Total download size: 220 k
    Installed size: 466 k
    Is this ok [y/N]: y
    Downloading Packages:
    (1/3): libpng-1.6.37-10.amzn2023.0.6.x86_64.rpm                                                                                                                                                                                          2.6 MB/s | 128 kB     00:00    
    (2/3): qrencode-libs-4.1.1-2.amzn2023.0.2.x86_64.rpm                                                                                                                                                                                     1.0 MB/s |  66 kB     00:00    
    (3/3): qrencode-4.1.1-2.amzn2023.0.2.x86_64.rpm                                                                                                                                                                                          379 kB/s |  26 kB     00:00    
    -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    Total                                                                                                                                                                                                                                    2.2 MB/s | 220 kB     00:00     
    Running transaction check
    Transaction check succeeded.
    Running transaction test
    Transaction test succeeded.
    Running transaction
      Preparing        :                                                                                                                                                                                                                                                 1/1 
      Installing       : qrencode-libs-4.1.1-2.amzn2023.0.2.x86_64                                                                                                                                                                                                       1/3 
      Installing       : libpng-2:1.6.37-10.amzn2023.0.6.x86_64                                                                                                                                                                                                          2/3 
      Installing       : qrencode-4.1.1-2.amzn2023.0.2.x86_64                                                                                                                                                                                                            3/3 
      Running scriptlet: qrencode-4.1.1-2.amzn2023.0.2.x86_64                                                                                                                                                                                                            3/3 
      Verifying        : libpng-2:1.6.37-10.amzn2023.0.6.x86_64                                                                                                                                                                                                          1/3 
      Verifying        : qrencode-4.1.1-2.amzn2023.0.2.x86_64                                                                                                                                                                                                            2/3 
      Verifying        : qrencode-libs-4.1.1-2.amzn2023.0.2.x86_64                                                                                                                                                                                                       3/3 
    
    Installed:
      libpng-2:1.6.37-10.amzn2023.0.6.x86_64                                                 qrencode-4.1.1-2.amzn2023.0.2.x86_64                                                 qrencode-libs-4.1.1-2.amzn2023.0.2.x86_64                                                
    
    Complete!
    [ec2-user@XXXXX ~]$ 
    ```


1. google-authenticatorを実行すると、QRコードが表示されます
    ```bash
    [ec2-user@XXXXX ~]$ 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:
      XXXXX
    ```


# 考察
今回、Google Authenticatorを使用してBastionにMFAを導入しました。


# 参考

https://qiita.com/zumax/items/88e7d07b6dd7bb6c217d

https://blog.adachin.me/archives/9641

https://dev.classmethod.jp/articles/linux-session-loggin-via-ssm/


https://www.ibm.com/docs/ja/informix-servers/12.10.0?topic=security-pluggable-authentication-modules-unix-linux