SSH接続でログインの失敗回数によりアカウントをロックする方法

セキュリティを高めたい為にログインの試行回数によりロックしたいことがありますね。この記事はCentOS7でログインを失敗した場合一定回数の失敗した回数を記録しユーザのアカウントをロックする方法を記載しています。具体的に以下のステップで試行回数によるロックを実現することができます。

　__ステップ１：__　/etc/ssh/sshd_config　で　UsePAM yes　設定
　__ステップ２：__　PAM 設定　（password-auth）
　__ステップ３：__　system-auth

#/etc/ssh/sshd_config　でUsePAM yes
CentOS7ではPAMの「pam_faillock」モジュールの機能を使用し任意の回数ログインに失敗したユーザのアカウントをロックすることが出来ます。まずsshdでPAMが使用できるように「/etc/ssh/sshd_config」で「UsePAM yes」の設定が有効になっていることを確認して下さい。（CentOS7.5では初期状態で有効になっています）

```
sudo nano /etc/ssh/sshd_config
```

```
UsePAM yes
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140071/0c6294e8-8ae3-8703-d25e-60424b3a64f1.png)

設定変更を行った場合は設定を反映する為にsshdを再起動しましょう。

```
systemctl restart sshd
```

#ステップ１PAM 設定（password-auth）
SSHで任意の回数ログインに失敗したユーザのアカウントをロックさせたい場合、「/etc/pam.d/password-auth」のauthセクションとaccountセクションに「pam_faillock」モジュールの設定を追加します。（rootユーザはロック対象外）

以下コマンドで開いてauthセクションを探します。

```
sudo nano /etc/pam.d/password-auth
```

```
auth  required      pam_faillock.so preauth silent audit deny=回数 unlock_time=解除時間
auth  [default=die] pam_faillock.so authfail audit deny=回数 unlock_time=解除時間
```

account   required      pam_faillock.so
「deny=回数」でログイン失敗でアカウントをロックをするまでの回数を指定します。

「unlock_time=解除時間」でロックが解除されるまでの時間（秒）を指定します。

「unlock_time」の値に「0」を指定すると、管理者が「faillock」コマンドでロック解除を行わない限りアカウントはロックされたままとなります。

#具体的設定事例

#ステップ２password-auth

「/etc/pam.d/password-auth」にログイン失敗を10回繰り返すと600秒（10分）アカウントをロックする設定を追加します。さきほどのpassword-authを編集します。

```
sudo nano /etc/pam.d/password-auth
```
　👈👈👈👈👈　部分3行が追加した設定になります。

```
#%PAM-1.0
# This file is auto-generated.
# User changes will be destroyed the next time authconfig is run.
auth        required      pam_env.so
auth        sufficient    pam_unix.so try_first_pass nullok
auth        required      pam_deny.so
auth        required      pam_faillock.so preauth silent audit deny=10 unlock_time=600　👈👈👈👈👈　追加しました！
auth        [default=die] pam_faillock.so authfail audit deny=10 unlock_time=600　👈👈👈👈👈　追加しました！



account     required      pam_unix.so
account     required      pam_faillock.so　　👈👈👈👈👈　追加しました！

password    requisite     pam_pwquality.so try_first_pass local_users_only retr$
password    sufficient    pam_unix.so try_first_pass use_authtok nullok sha512 $
password    required      pam_deny.so

session     optional      pam_keyinit.so revoke
session     required      pam_limits.so
-session     optional      pam_systemd.so
session     [success=1 default=ignore] pam_succeed_if.so service in crond quiet$
session     required      pam_unix.so
```

##ポイント　コンソールからのログイン失敗

「/etc/pam.d/password-auth」の設定だけではコンソールから直接ログイン失敗した場合にアカウントをロックすることはできません。コンソールからのログイン失敗についてもアカウントのロックを行いたい場合は「/etc/pam.d/system-auth」にも、同様の設定を行う必要があります。

#ステップ３system-auth
それではせっかくなのでpassword-authだけではなく、今度は　system-auth　も修正していきます。

```
sudo nano /etc/pam.d/system-auth
```
同じように3か所を追加していきます。内容も一緒です。

```
#%PAM-1.0
# This file is auto-generated.
# User changes will be destroyed the next time authconfig is run.
auth        required      pam_env.so
auth        sufficient    pam_unix.so try_first_pass nullok
auth        required      pam_deny.so
auth        required      pam_faillock.so preauth silent audit deny=10 unlock_time=600　👈👈👈👈👈　追加しました！
auth        [default=die] pam_faillock.so authfail audit deny=10 unlock_time=600　👈👈👈👈👈　追加しました！

account     required      pam_unix.so
account     required      pam_faillock.so　　👈👈👈👈👈　追加しました！

password    requisite     pam_pwquality.so try_first_pass local_users_only retry=3 authtok_type=
password    sufficient    pam_unix.so try_first_pass use_authtok nullok sha512 shadow
password    required      pam_deny.so

session     optional      pam_keyinit.so revoke
session     required      pam_limits.so
-session     optional      pam_systemd.so
session     [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid
session     required      pam_unix.so
```
###ポイント　root
「root」ユーザもロックしたい場合はauthセクションに追加する設定に「even_deny_root」を追加しましょう。

```
auth  required      pam_faillock.so preauth silent audit deny=回数 even_deny_root unlock_time=解除時間
auth  [default=die] pam_faillock.so authfail audit deny=回数 even_deny_root unlock_time=解除時
```

#ログイン失敗回数の確認
「faillock」コマンドを実行することで、ユーザのログイン失敗情報を確認することが出来ます。

```
faillock
```

「testuser」でログイン失敗を繰り返した後に「faillock」コマンドを実行してみると、ログイン失敗に関しての情報が確認できます。

# faillock
```
root:
When                Type  Source                                           Valid
hogehogeuser:
When                Type  Source                                           Valid
sampleuser:
When                Type  Source                                           Valid
2019-09-14 16:50:41 RHOST 192.168.10.2                                         V
2019-09-14 16:50:44 RHOST 192.168.10.2                                         V
2019-09-14 16:50:47 RHOST 192.168.10.2                                         V
```

特定ユーザのログイン失敗情報を確認したい場合は、「--user」オプションを使用することでユーザの指定が可能となります。

```
faillock --user ユーザ名
```
「testuser」というユーザのログイン失敗状況を確認してみます。

```
# faillock --user testuser
testuser:
When                Type  Source                                           Valid
2018-07-04 16:50:41 RHOST 192.168.1.26                                         V
2018-07-04 16:50:44 RHOST 192.168.1.26                                         V
2018-07-04 16:50:47 RHOST 192.168.1.26                                         V
```

#アカウントロック解除方法

アカウントのロックを解除したい場合は、「--user」でロックを解除したいユーザを指定した後に「--reset」を指定することでロックを解除することが出来ます。

```
faillock --user ユーザ名 --reset
```

実際に「testuser」のロックを解除してみます。

```
faillock --user testuser --reset
```

「faillock」コマンドで確認してみると、ログイン失敗の情報が削除されてロックが解除されていることが確認できます。

```
# faillock
root:
When                Type  Source                                           Valid
hogeuser:
When                Type  Source                                           Valid
sampleuser:
When                Type  Source                                           Valid
```

#番外編

```
faillock: Error opening the tally file for root:Permission denied
```

もしも上記エラーが発生した時は　su - でrootになってから　faillockをすると結果をチェックする事ができます。

#ログをみる

failcockで気付いたらログを見てみるのも手です。が詳しい人に相談するのが一番早いです。

```
sudo nano /var/log/secure
```