Linuxでパスワードポリシーの設定をする方法

##概要
CentOS7,RHEL6.5にて以下のパスワードポリシーを適用します。

・パスワードの複雑性チェック<br>　英語の大文字・小文字、数字、記号を最低1文字以上
　8文字以上
（rootユーザにも適用）

・パスワード履歴チェック
　過去1回のパスワードと比較し、同様のものは拒否させる(rootユーザにも適用）

・アカウントロック
　5回以上のログイン失敗で30分間ロックする。<br>

・SSHでのrootユーザ直ログイン禁止
・パスワード有効期限の設定
・パスワード有効期限直前の変更通知の設定

PAMの設定ファイルはtelnetとSSHでファイルが異なるので、両方の接続で同じ設定にしたい場合、２つのファイルを同様に編集する必要があります。

※バージョンやディストリビューションによって異なるので注意して設定して下さい。
　私は複数のサイトのものを組み合わせて試していたら、1度rootユーザにログインできなくなりました。
　ファイルを戻したら入れるように戻ったので、ほんとよかった...です。。。

##telnet側の設定
　/etc/pam.d/system-authを編集します。

```
ディレクトリを移動
# cd /etc/pam.d
バックアップを取っておく
# cp system-auth system-auth_org

viエディタを起動
# vi
挿入モードに変更
# i
```

以下system-authファイル

```
①アカウントロック設定
5行目に以下を追記。
auth required pam_tally2.so deny=5 unlock_time=1800

14行目に以下を追記。
account required pam_tally.so

②パスワード複雑性設定
15行目pasword requisite pam_cracklib.so...に追記し、以下のように変更（rootユーザに適用させない場合「enforce_for_root」の記述は不要です。）

password requisite pam_cracklib.so try_first_pass minlen=8 retry=3 dcredit=-1 ucredit=-1 lcredit=-1 ocredit=-1 enforce_for_root

③パスワード履歴チェック設定
16行目に以下を追記。（rootユーザに適用させない場合「enforce_for_root」の記述は不要です。）
password required pam_pwhistory.so remember=1 enforce_for_root

コマンドモードに戻り、保存
Escキーを押す。
:wq
```

パスワード履歴チェックは参考にさせて頂いたサイト（この記事の最終行に記載）で記載されていたpam_unix.soでも上手く動作しましたが、
マニュアルを参照したところ、rootにも適用させるオプションが見当たらなかったので、pam_pwhistory.soを使用したところ、上手くいきました。

###system-auth 設定後の状態

```
#%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        required      pam_tally2.so deny=5 unlock_time=1800
auth        sufficient    pam_fprintd.so
auth        sufficient    pam_unix.so nullok try_first_pass
auth        requisite     pam_succeed_if.so uid >= 500 quiet
auth        required      pam_deny.so

account     sufficient    pam_localuser.so
account     sufficient    pam_succeed_if.so uid < 500 quiet
account     required      pam_permit.so
account     required      pam_tally2.so
password    requisite     pam_cracklib.so try_first_pass minlen=8 retry=3 type= dcredit=-1 ucredit=-1 lcredit=-1 ocredit=-1
enforce_for_root
password    required      pam_pwhistory.so remember=1 enforce_for_root
password    sufficient    pam_unix.so sha512 shadow nullok try_first_pass use_authtok
password    required      pam_deny.so

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

※このファイル編集後、サービスの再起動などは必要ありません。
　パスワード変更時に適用されるため、既存のユーザに影響はありません。

##SSH,FTP側の設定
/etc/pam.d/password-authを、上記のsystem-authと同様の箇所を同じように編集します。
###pasword-auth設定後の状態

```
#%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        required      pam_tally2.so deny=5 unlock_time=1800
auth        sufficient    pam_unix.so nullok try_first_pass
auth        requisite     pam_succeed_if.so uid >= 500 quiet
auth        required      pam_deny.so

account     required      pam_unix.so
account     sufficient    pam_localuser.so
account     sufficient    pam_succeed_if.so uid < 500 quiet
account     required      pam_permit.so
account     required      pam_tally2.so
password    requisite     pam_cracklib.so try_first_pass minlen=8 retry=3 type= dcredit=-1 ucredit=-1 lcredit=-1 ocredit=-1
enforce_for_root
password    required      pam_pwhistory.so remember=1 enforce_for_root
password    sufficient    pam_unix.so sha512 shadow nullok try_first_pass use_authtok
password    required      pam_deny.so

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


##アカウントロック解除方法
アカウントロックは、pam_tally2によって管理され、ログイン失敗するごとに回数をカウントし、日時を記録します。

通常、ロックされるまでに正しいパスワードでログインするか、ロック解除後に正しいパスワードでログインすることで、ロックとカウントは自動で解除されますが、
解除できなかった場合は、次のコマンドで解除できます。

rootユーザでコマンドを打つと解除できます。

```
# pam_tally2 -u ユーザ名 --reset
```

コマンドを打った後、なぜか解除前の回数が表示されますが、確認してみるとカウントは0になりロック解除されています。

ロックのカウントを確認したい場合

```
# pam_tally2 -u ユーザ名
```

表示の意味は次の通りです。

| Login | Failures | Latest failure | From |
|:-:|:-:|:-:|:-:|
|asaito|1|07/02/18 00:40:55|pts/0|
| ユーザ名 |失敗回数|最近失敗した日時|どこからのログインで失敗したか（端末やIPアドレスが表示される）|

##SSHのパスワード試行回数の設定

SSHのパスワード試行回数はデフォルトで3回で設定されているため、5回に変更します。
これを設定しないと、3回でカウントがリセットされ、ロックが掛かりません。
/etc/ssh/sshd_configを編集します。

```
ディレクトリ移動
# cd /etc/ssh

バックアップ取得
# cp ssh_config ssh_config_org

viエディタ起動
# vi ssh_config

挿入モードに変更
 i

最終行に追記
NumberOfPasswordPrompts 5

（NumberOfPasswordPrompts の記載が既にある場合は、スペースを1つ開けて設定したい回数の数字を記入して下さい。）

コマンドモードに戻り、保存
Escキーを押す。
:wq

構文チェック
sshd -t
→エラーが起きていなければOKです。

サービスの再起動
/etc/init.d/sshd restart
```

##SSHでのrootユーザ直ログイン禁止
/etc/ssh/sshd_configを編集します。

```
ディレクトリ移動
# cd /etc/ssh

バックアップ取得
# cp sshd_config sshd_config_org

viエディタを起動
# vi sshd_config

挿入モードに変更
 i 

PermitRootLogin yes
を
PermitRootLogin noに変更する。

コマンドモードに戻って保存
Escキーを押す。
:wq

構文チェック
sshd -t 
→エラーが起きなければOKです

サービス再起動
/etc/init.d/sshd restart
```

##パスワード有効期限の設定
・日数で設定

```
chage -M 日数 ユーザ名
```

例

```
chage -M 120 asaito
```

・日にちで指定

```
chage -E 日付　ユーザ名
```

例

```
chage -E 2018-08-01 asaito
```

・確認

```
chage -l ユーザ名
```

※コマンドを打った時に反映されます。

##パスワード有効期限直前の変更通知の設定
有効期限が切れる何日前から警告するか設定します。

```
chage -W 日数 ユーザ名
```

例

```
chage -W 7 asaito
```

※コマンドを打った時に反映されます。

##参考<li><a href="https://orebibou.com/2014/05/linux%E3%81%A7%E3%83%91%E3%82%B9%E3%83%AF%E3%83%BC%E3%83%89%E3%83%9D%E3%83%AA%E3%82%B7%E3%83%BC%E3%82%92%E8%A8%AD%E5%AE%9A%E3%81%99%E3%82%8B/">
・俺的備忘録 〜なんかいろいろ〜　Linuxでパスワードポリシーを設定する</a><li><a href="https://qiita.com/LostEnryu/items/4e439dbf1a61388cc61d">・Qiita:情報セキュリティの基本 ~パスワードの強化~@LostEnryuさん</a>
<li><a href="http://www.atmarkit.co.jp/ait/articles/1612/07/news016.html">・@IT:【 chage 】コマンド――パスワードの有効期限を設定する／確認する</a>
<li><a href="https://oxynotes.com/?p=4393">・OXY NOTES: Linuxの各アプリケーションが共通して利用する「PAM認証」について
<li><a href="https://int128.hatenablog.com/entry/20090726/1248622071">・PAMによる認証の仕組みを調べてみた_GeekFactory</a>