IP制限かつユーザの制限を同時に行う

## About
調べたのでまとめて起きます。IP制限をしたいということはよくありますが、IP制限かつユーザを制限したいという要件があったので、検証しました。IP制限ならiptablesやfirewalldなどでするイメージがあったので、なかなか大変でした。

## Environment
* Centos7.0

## 検証メモ
### sshdに設定を追加する
`/etc/ssh/sshd_config`に下記の1行を追加します。

```:/etc/ssh/sshd_config
account required pam_access.so accessfile=/etc/security/sshd_access.conf

```

`account required pam_access.so`までが重要で、ここでユーザごとのアクセス制限を有効にしています。後半はそのファイルのパスをデフォルト以外のものを指定しています。デフォルトでは`/etc/security/access.conf`です。

### 設定ファイルを更新する
この設定ファイルを更新すると即時で反映されるので、最悪ログインできなくなるので注意が必要です。

```
- : ALL : ALL
```

上記の設定ではすべて拒否する設定になります。

```
+ : root : 192.168.200.1 192.168.200.4 192.168.200.9
```

こうするとrootにアクセスできるIPを制限できます。denyを先に書くとそこで終わってしまうので、先に許可するユーザなどを指定し、その後に拒否する設定を書くとよさそうです。

### はまったところ
最初はいくら設定しても拒否の設定が有効にならず、アクセス拒否できていませんでした。調べた所、pamの設定順序の問題みたいでした。

```:/etc/pam.d/sshd
vagrant@localhost pam.d]$ cat sshd
#%PAM-1.0
auth	   required	pam_sepermit.so
auth       substack     password-auth
auth       include      postlogin
account    required     pam_nologin.so
account    include      password-auth
account required pam_access.so accessfile=/etc/security/sshd_access.conf
password   include      password-auth
# pam_selinux.so close should be the first session rule
session    required     pam_selinux.so close
session    required     pam_loginuid.so
# pam_selinux.so open should only be followed by sessions to be executed in the user context
session    required     pam_selinux.so open env_params
session    optional     pam_keyinit.so force revoke
session    include      password-auth
session    include      postlogin
```

はじめ上記の用にaccountの最後の行にいれてましたが、その前のpassword-authの部分で認証されスキップされていたようです。

```:/etc/pam.d/password-auth
[vagrant@localhost pam.d]$ cat password-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        sufficient    pam_unix.so nullok try_first_pass
auth        requisite     pam_succeed_if.so uid >= 1000 quiet_success
auth        required      pam_deny.so

account     required      pam_unix.so
account     sufficient    pam_localuser.so
account     sufficient    pam_succeed_if.so uid < 1000 quiet
account     required      pam_permit.so

password    requisite     pam_pwquality.so try_first_pass local_users_only retry=3 authtok_type=
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     optional      pam_systemd.so
session     [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid
session     required      pam_unix.so
```

accountの部分でsufficientがあるので、この時点で失敗がなければ以後のaccount認証がスキップされているようです。

下記のように修正することでログインできなくなりました。

```:/etc/pam.d/sshd
#%PAM-1.0
auth	   required	pam_sepermit.so
auth       substack     password-auth
auth       include      postlogin
account    required     pam_nologin.so
# enabled accessfile for sftp
account required pam_access.so accessfile=/etc/security/sshd_access.conf

account    include      password-auth
password   include      password-auth
# pam_selinux.so close should be the first session rule
session    required     pam_selinux.so close
session    required     pam_loginuid.so
# pam_selinux.so open should only be followed by sessions to be executed in the user context
session    required     pam_selinux.so open env_params
session    optional     pam_keyinit.so force revoke
session    include      password-auth
session    include      postlogin
```

## 終わりに
さてログインできなくなったVMを破壊しますかね…

## Link
[pam + opensshでユーザごとのログインIP制限 - うまいぼうblog] (http://d.hatena.ne.jp/hogem/20100906/1283789476)

[sshを、ユーザ、IPでアクセス制限] (http://kazmax.zpp.jp/linux/lin_pam.html)

[pamでip制限かつユーザの制限を試す by krossblack777 · Pull Request #1 · tjinjin/sftp-server] (https://github.com/tjinjin/sftp-server/pull/1)