Ciscoのログイン認証をFreeRADIUSのLDAPを経由してActiveDirectoryと連携する

# はじめに
先日、FreeRADIUSを利用したCisco機器のログイン認証の検証を行いました。
**[DockerのFreeRADIUSでCiscoのログイン認証＋MAC認証+ダイナミックVLANした（CentOS8）](https://qiita.com/bashaway/items/0f331872456fb8681641)**

が、ユーザ管理はActiveDirectoryで一元管理させたいので、前回作成したFreeRADIUSのDockerに、LDAP連携の設定を加えて、ActiveDirectoryに問い合わせに行くようにしました。

# こんなことがしたい
今回の要件は以下とします。

* ActiveDirectoryの特定のセキュリティグループに所属していないと、承認されないようにします。
* 特定ユーザには、ログインと同時に特権モード（enable）になるようなRADIUSアトリビュートを付与します。
[![Screenshot from Gyazo](https://gyazo.com/872a7d1a098280f557988e4bb46ea191/raw)](https://gyazo.com/872a7d1a098280f557988e4bb46ea191)

# 作業内容

## 事前準備

### FreeRADIUSの準備
まだFreeRADIUSがない場合には、以下エントリを参照して構築してください。
**[DockerのFreeRADIUSでCiscoのログイン認証＋MAC認証+ダイナミックVLANした（CentOS8）](https://qiita.com/bashaway/items/0f331872456fb8681641)**

### ユーザの準備
LDAP検索用ユーザおよび動作確認用ユーザは、以下エントリで作成したものを流用しています。
**[squidでActiveDirectory連携とSSLインターセプトするProxyをdockerで手軽につくる](https://qiita.com/bashaway/items/6adc75265973de9b5fcc#ad%E3%83%A6%E3%83%BC%E3%82%B6%E3%81%AE%E6%BA%96%E5%82%99)**

LDAPの検索用ユーザが必要なので、ない場合は `searchuser` という名前で新規に作成します。
検索用ユーザはOUに所属せず、Usersにいる人で、パスワードは前回同様 `s3arch#PWD` で説明してます。
また、動作確認用には以下のユーザたちを利用し、ログイン許可するユーザには `NetworkAdmin` というセキュリティグループを割り当てます。



|ユーザ種別|機器ログイン|ログイン時の権限|ユーザ名|OU|セキュリティグループ|
|:--:|:--:|:--:|:--:|:--:|:--:|
|特権ユーザ|〇|特権<BR>(enable)|josys.saburo|employee|NetworkAdmin|
|ログイン許可ユーザ|〇|一般|soumu.taro|employee|NetworkAdmin|
|ログイン不許可ユーザ|×|－|jinji.jiro|employee|-|
|検索用ユーザ|×|－|searchuser|-|-|

こんな感じで十分
[![Screenshot from Gyazo](https://gyazo.com/bfd5564b0446d8e73e462287b31e2b0c/raw)](https://gyazo.com/bfd5564b0446d8e73e462287b31e2b0c)


ログイン時の権限付与はFreeRADIUSの設定で行います。

## FreeRADIUSの設定
すでにある設定ファイルのうち、以下の部分のみ修正します。
検索用ユーザは前述の **[事前準備](#ユーザの準備)** で作成したとおりであれば、以下の情報となります。
DNやパスワードが別の場合には、適宜修正してください。

```:/etc/raddb/mods-available/ldap
ldap {
    # ADサーバと検索用ユーザの情報、ログイン許可するセキュリティグループを記載します
    # もとの記載がある箇所はコメントアウトしておきます。
    server = 'ADサーバのFQDNもしくはIPアドレス'
    identity = 'CN=searchuser,CN=Users,DC=prosper2,DC=net'
    password = 's3arch#PWD'
    base_dn = 'ou=employee,dc=prosper2,dc=net'
    ldapgroup = 'cn=NetworkAdmin,ou=employee,dc=prosper2,dc=net'

    # ユーザオブジェクトを確認するセクションでログイン許可するグループでフィルタします。
    user {
        # もともとの filter 条件はコメントアウトしておきます。
        #filter = "(uid=%{%{Stripped-User-Name}:-%{User-Name}})"
        filter =  "(|(&(samaccountname=%{%{Stripped-User-Name}:-%{User-Name}})(memberOf=${..ldapgroup})))"
    }
}
```

以下の部分のみ、設定を修正します。

```:/etc/raddb/sites-available/default
authenticate {
    # 認証タイプを定義するセクションでLDAPを有効化（コメントを削除）します。
    Auth-Type LDAP {
        ldap
   }
}
```

LDAP用のファイルを読み込むように、ファイルに追記します。

```:/etc/raddb/mods-config/files/authorize
# ここはそのまま
$INCLUDE /etc/raddb/mods-config/files/userlist/mabs
$INCLUDE /etc/raddb/mods-config/files/userlist/users.login

# これを追加する
$INCLUDE /etc/raddb/mods-config/files/userlist/ldap.login
```

LDAP用の設定ファイルを新規作成します。
josys.saburoさんには、ログイン時に特権になってもらうため、特権用のアトリビュートを付与します。

```:/etc/raddb/mods-config/files/userlist/ldap.login
DEFAULT Auth-Type := LDAP
        Fall-Through = Yes

josys.saburo
          Service-Type = Administrative-User , PaloAlto-Admin-Role = securityadmin
```

LDAPモジュールが利用できるようにシンボリックリンクを作成します。

```
cd /etc/raddb/mods-enabled/
ln -s ../mods-available/ldap ldap
```

これでFreeRADIUSを再起動します。

```
systemctl restart radiusd
```

## うまくいかない場合

検索用ユーザの情報がまちがっていると、FreeRADIUSが起動に失敗します。

```
# systemctl restart radiusd
Job for radiusd.service failed because the control process exited with error code.
See "systemctl status radiusd.service" and "journalctl -xe" for details.
```

この場合は、FreeRADIUSをコンソールから起動してエラーを確認します。

```
# radiusd -X
（～省略～）

rlm_ldap (ldap): Opening additional connection (0), 1 of 32 pending slots used
rlm_ldap (ldap): Connecting to ldap://[ADサーバのFQDNかIPアドレス]:389
rlm_ldap (ldap): Waiting for bind result...
rlm_ldap (ldap): Bind credentials incorrect: Invalid credentials
rlm_ldap (ldap): Server said: 80090308: LdapErr: DSID-0C09041C, comment: AcceptSecurityContext error, data 52e, v4563.
rlm_ldap (ldap): Opening connection failed (0)
rlm_ldap (ldap): Removing connection pool
/etc/raddb/mods-enabled/ldap[8]: Instantiation failed for module "ldap"

# （起動に失敗すると、終了してプロンプトに戻ります）
```

設定ファイルを修正して、再度コンソールから起動します。

```
# radiusd -X
（～省略～）

Listening on auth address * port 1812 bound to server default
Listening on acct address * port 1813 bound to server default
Listening on auth address :: port 1812 bound to server default
Listening on acct address :: port 1813 bound to server default
Listening on auth address 127.0.0.1 port 18120 bound to server inner-tunnel
Listening on proxy address * port 37973
Listening on proxy address :: port 57026
Ready to process requests

（起動に成功すると、フォアグランドでプロセスが動作し続け、認証を受け付けます）

```


# 動作確認

## jinji.jiroさんの場合
セキュリティグループ NetworkAdmin に所属していないので、認証NGです。

```
$ radtest jinji.jiro PASSWORD# 10.254.10.252 123 RADIUS_SECRET
Sent Access-Request Id 203 from 0.0.0.0:46842 to 10.254.10.252:1812 length 80
        User-Name = "jinji.jiro"
        User-Password = "PASSWORD#"
        NAS-IP-Address = 10.254.10.105
        NAS-Port = 123
        Message-Authenticator = 0x00
        Cleartext-Password = "PASSWORD#"
Received Access-Reject Id 203 from 10.254.10.252:1812 to 0.0.0.0:0 length 20
(0) -: Expected Access-Accept got Access-Reject
```

Cisco機器にもログインできません。

```
$ ssh jinji.jiro@rdc01
Password:
Password:
Password:
Connection closed by 10.254.0.1 port 22
```


## soumu.taroさんの場合
セキュリティグループ NetworkAdmin に所属しているので、認証OKです。

```
$ radtest  soumu.taro PASSWORD# 10.254.10.252 123 RADIUS_SECRET
Sent Access-Request Id 111 from 0.0.0.0:42045 to 10.254.10.252:1812 length 80
        User-Name = "soumu.taro"
        User-Password = "PASSWORD#"
        NAS-IP-Address = 10.254.10.105
        NAS-Port = 123
        Message-Authenticator = 0x00
        Cleartext-Password = "PASSWORD#"
Received Access-Accept Id 111 from 10.254.10.252:1812 to 0.0.0.0:0 length 20
```

Ciscoルータにログインすると、通常ユーザでログイン完了できます。

```
$ ssh soumu.taro@rdc01
Password:
Rdc01>show users
    Line       User       Host(s)              Idle       Location
* 34 vty 0     soumu.taro idle                 00:00:00
                                                      vminfraserv05.prosper2.net

  Interface    User               Mode         Idle     Peer Address

Rdc01>exit
Connection to rdc01 closed by remote host.
Connection to rdc01 closed.
```



## josys.saburoさんの場合
セキュリティグループ NetworkAdmin に所属しているので、認証OKです。
なおかつ、 `/etc/raddb/mods-config/files/userlist/ldap.login` で設定した、`Service-Type = Administrative-User` がリプライアイテムに含まれているのが確認できます。

```
$ radtest  josys.saburo PASSWORD# 10.254.10.252 123 RADIUS_SECRET
Sent Access-Request Id 230 from 0.0.0.0:40083 to 10.254.10.252:1812 length 82
        User-Name = "josys.saburo"
        User-Password = "PASSWORD#"
        NAS-IP-Address = 10.254.10.105
        NAS-Port = 123
        Message-Authenticator = 0x00
        Cleartext-Password = "PASSWORD#"
Received Access-Accept Id 230 from 10.254.10.252:1812 to 0.0.0.0:0 length 26
        Service-Type = Administrative-User
```

Ciscoルータにログインすると、 `Service-Type = Administrative-User` が付与されているため、特権ユーザでログイン完了できます。

```
$ ssh josys.saburo@rdc01
Password:
Rdc01#show users
    Line       User       Host(s)              Idle       Location
* 34 vty 0     josys.sabu idle                 00:00:00
                                                      vminfraserv05.prosper2.net

  Interface    User               Mode         Idle     Peer Address

Rdc01#exit
Connection to rdc01 closed by remote host.
Connection to rdc01 closed.
```

# さいごに
これで、アカウント情報がActiveDirectoryで一元管理できるようになりました。
あとは特権用のアトリビュートもADのセキュリティグループから引っ張ってきたいな。