スイッチとFreeRADIUSまとめて構築

(2019.11.12追記)firewall-cmdのサービス設定が入っているディレクトリに誤りがあったので修正しました、見てないのがバレましたね！！
そのうちMAC認証も追加したいですね・・・(遠い目)

---
# どんな人向け？
- ネットワーク機器のRADIUS認証、設定方法はわかるけど実際に使ったことはない
- RADIUSサーバとクライアント(ネットワーク機器)、両方設定して挙動見てみたい

# はじめに
職場でCiscoスイッチのログインにRADIUS認証を導入することになりそうです。
CiscoスイッチのRADIUS認証はCCNAやCCNPで机上勉強しただけだったので漠然としたイメージしかなかったので、実際に構築してみようかと思いました。
ついでに、RADIUSサーバも立ててサーバ、ネットワーク機器双方の挙動を見たいと思います。

# そもそもRADIUSって？　入れる意味は？
意味はネットぐぐったほうが早いのでそちら見てください。
実装する理由として、以下のネットワーク要件をもらったときが多いのではないかと思います。

- たくさんあるネットワーク機器のログイン情報(パスワード)をまとめたい
- 異なるネットワーク機器にログインするときのユーザ、パスワードは同一にする
- 定期的にパスワードを変える運用を入れたい

ネットワーク機器が少なければローカル管理でも良いと思います。
しかし機器が増えてくると、1つ1つの機器に投入する必要があるので、パスワード間違えたりするなど、設定するだけでも大変です。
挙句の果てに毎月パスワードを更新してほしいなんて言われた日には・・・想像したくないですね。

そこで、RADIUS認証を利用すればログイン情報を機器毎に管理することなく、RADIUSサーバで一括管理することができるようになります。

また、仮にRADIUSサーバとの疎通が取れなくなったとしても、ローカル管理ユーザでログインできるように設定することは可能です。

# やりたいこと
- Ciscoスイッチへのログイン時にRADIUS認証を利用するよう設定する
- CentOSにFreeRADIUSを入れる
    - ちなみに今回はとりあえず立てるのみなのでデータベースなし
- Ciscoスイッチにログインする時、RADIUS認証する
    - RADIUSサーバが落ちているときはローカル認証する

# 実装イメージ
ざっくりベースですが以下のような構成でいきたいと思います。
![RADIUS認証図解.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392066/09819773-5c8c-7216-4a84-e616dd7f2baa.jpeg)

# 用意するもの
Ciscoスイッチは会社の研修センターに転がっている機器を使います。
とりあえず`aaa new-model`設定できればなんでもOKだと思いたい。

- CentOS
    - ここではVirtulBoxに入れます
- Ciscoスイッチ
    - Model : WS-C2940-8TT-S
    - Version : 12.1(22)EA7
- うまくいかなくてもくじけない気持ち

型番やバージョンは以下の通りです。

```:CentOS
# cat /etc/redhat-release 
CentOS Linux release 7.6.1810 (Core) 
```

```:CiscoL2SW_show_version
Cisco Internetwork Operating System Software 
IOS (tm) C2940 Software (C2940-I6Q4L2-M), Version 12.1(22)EA7, RELEASE SOFTWARE (fc1)
～中略～
Model number: WS-C2940-8TT-S
```


作るユーザやパスワードは以下の通り。

| 登録先 | 種別 |ユーザ | パスワード |備考|
|:--|:--|:--|:--|:--|
|スイッチ   |ユーザ |admin   |localpassword   |ローカルログイン用|
|スイッチ   |enable   |-   |enablepassword |特権モード用|
|RADIUS   |ユーザ   |radius1   |radius1pass |RADIUS認証用その1|
|RADIUS   |ユーザ   |radius2   |radius2pass |RADIUS認証用その2|


# 手順
## Ciscoスイッチ
※IOSバージョンが12.1と古いので、この記事を参考に設定していると、一部コマンドが異なる部分があると思います。
そこらへんは適宜読み替えていただけると幸いです。

### 一般的な設定
コンソール接続してどんどん設定投入していきましょう。
ところで、シリアルケーブル認識させるまでが一番のハードルだと自分は思うんですよね・・・。

ちなみにスイッチの場合はデフォルトで全物理ポートが有効、かつvlan1が割り当てられているので、今回各ポートの設定は何もしてません。
逆に、vlan 1自体は初期状態で無効となっているので利用する場合は有効にします。
今回は~~横着したいので~~vlan 1を使いますが、**セキュリティの観点から本番運用を想定する機器では別のVlanIDを使いましょう。**


```:一般的な設定
! 初回のダイアログはもちろんNoで

! 特権モード移行
> enable

! ログ自動流し
# terminal length 0

! グローバルコンフィグレーションモード移行
# configure terminal

! ユーザ作成
(config)# username admin privilege 15 password localpassword

! enableパスワード
(config)#enable password enablepassword

! 名前解決無効
(config)# no ip domain-lookup

! IP設定
! 全インターフェイスにVLAN1が割り当てられているのでVLAN1のIPアドレスの設定、有効化
(config)# interface vlan 1
(config-if)# ip address 192.168.1.100 255.255.255.0
(config-if)# no shutdown

! 認証方式リストの適用（おまけでタイムアウトなし、自動改行）
(config)# line vty 0 4
(config-line)# exec-timeout 0 0
(config-line)# logging synchronous

! コンソールログイン時はいきなり特権、タイムアウトなし、自動改行
(config)# line console 0
(config-line)# privilege level 15
(config-line)# exec-timeout 0 0
(config-line)# logging synchronous

```

### RADIUS認証設定
今回の検証機器は古いのでいわゆるレガシーな設定方法で入れてます。
最近のIOSではサーバのグループ設定ができるようです。
どの程度の最新IOSだったら出来るのだろうか・・・。

```:RADIUS認証設定
! AAAの有効化
(config)# aaa new-model

! RADIUSサーバ登録　※2台登録OK
! 末尾のキーストリングはRADIUSサーバ側と合わせる必要がある
(config) # radius-server host 192.168.1.101 auth-port 1812 acct-port 1813 key radiusstring

! ログイン認証方式リストの設定　※基本RADIUS認証、落ちてたらローカル
(config)# aaa authentication login default group radius local
(config)# aaa authentication dot1x default group radius local　※おそらく不要
(config)# aaa authorization network default group radius local　※おそらく不要
(config)# aaa accounting dot1x ddefault start-stop group radius　※おそらく不要
(config)# aaa accounting system default start-stop group radius　※おそらく不要

! ルータからサーバに対して、各 RADIUS 要求を送信する回数の指定　※デフォルト3
(config)#radius-server retransmit 3

! ルータが RADIUS 要求に対する応答を待機して、再送信するまでの時間(秒数)
(config)#radius-server timeout 6

! 認証要求に応答しないRADIUS サーバが、期限切れになる時間(分数)
(config)#radius-server deadtime 5
```

米印の部分は、あとから調べて「あれ、今回の検証じゃいらなかったのでは？」という部分です・・・また改めて検証し直したい・・・。
余談ですが、RADIUS関連設定入れた状態で`no aaa new-model`を実行すると`aaa ～`どころか`radius-server ～`の設定も消えました。

<details>
<summary>設定後のshow_running-config(長いので折りたたみ)</summary><div>

```:show_running-config
Building configuration...

Current configuration : 1332 bytes
!
version 12.1
no service pad
service timestamps debug uptime
service timestamps log uptime
no service password-encryption
!
hostname Switch
!
aaa new-model
aaa authentication login default group radius local
aaa authentication dot1x default group radius local
aaa authorization network default group radius local
aaa accounting dot1x default start-stop group radius
aaa accounting system default start-stop group radius
enable password enablepassword
!
username admin privilege 15 password 0 localpassword
ip subnet-zero
!
no ip domain-lookup
!
spanning-tree mode pvst
no spanning-tree optimize bpdu transmission
spanning-tree extend system-id
dot1x system-auth-control
!
!
!
!
interface FastEthernet0/1
!
interface FastEthernet0/2
!
interface FastEthernet0/3
!
interface FastEthernet0/4
!
interface FastEthernet0/5
!
interface FastEthernet0/6
!
interface FastEthernet0/7
!
interface FastEthernet0/8
!
interface GigabitEthernet0/1
!
interface Vlan1
 ip address 192.168.1.100 255.255.255.0
 no ip route-cache
!
no ip http server
radius-server host 192.168.1.200 auth-port 1812 acct-port 1813 key radiusstring
radius-server retransmit 3
radius-server timeout 6
radius-server deadtime 5
!
line con 0
 exec-timeout 0 0
 privilege level 15
 logging synchronous
line vty 0 4
 exec-timeout 0 0
 logging synchronous
line vty 5 15
!
!
end
```

</div></details>

## FreeRADIUS

### インストール
`yum`をアップデートしてから`freeradius`をインストールしましょう。

```:freeradiusのインストール
sudo yum -y update
sudo yum -y install freeradius
```

後ほどRADIUS認証のテストを行う`radtest`が含まれているユーティリティ`freeradius-utils`もインストールします。

```:freeradius-utilsのインストール
yum -y install freeradius-utils
```

```:freeradiusのバージョン確認
radiusd -v
radiusd: FreeRADIUS Version 3.0.13, for host x86_64-redhat-linux-gnu, built on May 16 2018 at 06:33:35
FreeRADIUS Version 3.0.13
Copyright (C) 1999-2017 The FreeRADIUS server project and contributors
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE
You may redistribute copies of FreeRADIUS under the terms of the
GNU General Public License
For more information about these matters, see the file named COPYRIGHT
```


### 設定ファイルの編集
修正する主なファイルは以下の通りです。
`radiusd.conf`については認証時のログ出力設定を行いますが、~~ログ見忘れた~~今回はデフォルトのままで行こうと思います。

| ファイル名 | 用途 | 編集内容
|:--|:--|:--|
|/etc/raddb/radiusd.conf   |Free-RADIUSの基本設定   |変更なし|
|/etc/raddb/clients.conf   |認証するネットワーク   |0.0.0.0/0(全IP)を許可
|/etc/raddb/users   |RADIUS認証ユーザ一覧   |ユーザ、パスワードを追加

編集するときは変なところ変更していないか見るため、`cp`と`diff`を使って差分チェックすると確実です。

```:バックアップを取って差分チェック
# cp client.conf client.conf.origins　←　バックアップ取得
# vi clients.conf
～　viで良い感じに修正～
# diff client.conf client.conf.origins　←　差分チェック
269,272d268
< client new {
<   ipaddr = 0.0.0.0/0
<   secret = radiusstring
< }
# rm -f client.conf.origins　←　バックアップ削除(必要あれば残す)
```

#### /etc/raddb/radiusd.conf
認証時のログ出力を設定したい場合は以下のパラメータを変更します。
今回は編集しませんが、そのうち試してみたいと思います。

```:/etc/raddb/radiusd.conf
# 認証時のログ出力設定
auth = yes

# 認証失敗時のログ出力
auth_badpass = yes

# 認証成功時のログ出力
auth_goodpass = yes
```

#### /etc/raddb/clients.conf

接続を許可するネットワークを設定。
以下をファイル末尾に追記。
設定すると、全IPアドレスから受け付けるようになります。
制限したい場合、例えば`ipaddr = 192.168.1.0/24`などに変更します。
secretは、認証機器との接続時に使うキーストリングを指定します。


```:/etc/raddb/clients.conf
client new {
  ipaddr = 0.0.0.0/0
  secret = radiusstring
}
```

なお、初期設定でlocalhostが入っています。
注意する点はlocalhostが認証要求する場合はキーストリング**testing123**を使う点です。
後述する`radtest`による単体テストで使うので留意しておきましょう。

```:clients.confのlocalhost部分
# コメントアウト部分は省略
client localhost {
	ipaddr = 127.0.0.1
	proto = *
	secret = testing123
	require_message_authenticator = no
	nas_type	 = other
	limit {
		max_connections = 16
		lifetime = 0
		idle_timeout = 30
	}
}
```

#### /etc/raddb/users

認証時に用いるユーザ、パスワードを指定する。
以下を末尾に追記。

```:/etc/raddb/users
radius1 Cleartext-Password := "radius1pass"
radius2 Cleartext-Password := "radius2pass"
```

ユーザ数が大量になってくるとデータベース化したほうが良さそうですね。
今回はユーザ少ないのでテキストベースで問題ないですが、そのうちデータベースも試してみたいと思います。

### FreeRADIUSの起動、自動起動設定
最低限必要な設定が終わったので`systemctl start radiusd`で起動します。
エラーなく起動できたら続けて`systemctl status radiusd`でステータスを確認する。

```
# systemctl start radiusd
# systemctl status radiusd
● radiusd.service - FreeRADIUS high performance RADIUS server.
   Loaded: loaded (/usr/lib/systemd/system/radiusd.service; enabled; vendor preset: disabled)
   Active: active (running) since 土 2019-04-13 13:44:52 JST; 59s ago
  Process: 14905 ExecStart=/usr/sbin/radiusd -d /etc/raddb (code=exited, status=0/SUCCESS)
  Process: 14899 ExecStartPre=/usr/sbin/radiusd -C (code=exited, status=0/SUCCESS)
  Process: 14895 ExecStartPre=/bin/chown -R radiusd.radiusd /var/run/radiusd (code=exited, status=0/SUCCESS)
 Main PID: 14908 (radiusd)
    Tasks: 6
   CGroup: /system.slice/radiusd.service
           mq14908 /usr/sbin/radiusd -d /etc/raddb
```

ここでうまく起動できなかった場合、設定ファイルの修正に誤りがある可能性があるので見返してください。
ちなみに投稿主もしょうもない理由で起動できなかったので、原因特定と解消方法を以下に折り込んでおきます。

<details>
<summary>**投稿主のNG集　～radiusdが起動できない～**</summary><div>

`systemctl start radiusd`を打っても起動しなかったんですよね。

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

エラーにもある通り`systemctl status radiusd.service`を打て！と出ているので打ってみる。

```
# systemctl status radiusd.service
● radiusd.service - FreeRADIUS high performance RADIUS server.
   Loaded: loaded (/usr/lib/systemd/system/radiusd.service; disabled; vendor preset: disabled)
   Active: failed (Result: exit-code) since 土 2019-04-13 13:34:06 JST; 32s ago
  Process: 14649 ExecStartPre=/usr/sbin/radiusd -C (code=exited, status=1/FAILURE)
  Process: 14643 ExecStartPre=/bin/chown -R radiusd.radiusd /var/run/radiusd (code=exited, status=0/SUCCESS)

 4月 13 13:34:06 localhost.localdomain systemd[1]: Starting FreeRADIUS high ...
 4月 13 13:34:06 localhost.localdomain systemd[1]: radiusd.service: control ...
 4月 13 13:34:06 localhost.localdomain systemd[1]: Failed to start FreeRADIU...
 4月 13 13:34:06 localhost.localdomain systemd[1]: Unit radiusd.service ente...
 4月 13 13:34:06 localhost.localdomain systemd[1]: radiusd.service failed.
Hint: Some lines were ellipsized, use -l to show in full.
```

Active欄がfailedになっていてエラーになってますね。
しかしメッセージ部分が途中までしか書いていなくてわからない・・・。
なにかいい手がないかと調べてみると、`radiusd -X`でデバックモードになるようなので試してみる。

```
#  radiusd -X
FreeRADIUS Version 3.0.13
Copyright (C) 1999-2017 The FreeRADIUS server project and contributors
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE
You may redistribute copies of FreeRADIUS under the terms of the
GNU General Public License
For more information about these matters, see the file named COPYRIGHT
Starting - reading configuration files ...
including dictionary file /usr/share/freeradius/dictionary
including dictionary file /usr/share/freeradius/dictionary.dhcp
including dictionary file /usr/share/freeradius/dictionary.vqp
including dictionary file /etc/raddb/dictionary
including configuration file /etc/raddb/radiusd.conf
including configuration file /etc/raddb/proxy.conf
including configuration file /etc/raddb/clients.conf
/etc/raddb/clients.conf[270]: Syntax error: Expected comma after '192.168.1.0/24': 　または0.0.0.0/0
Errors reading or parsing /etc/raddb/radiusd.conf
```

あっ　clients.confのipaddr欄、全ネットワークにするか限定にするかメモしたものをそのままコピーしていたようですね、そりゃダメです。

```:/etc/raddb/clients.confの問題箇所
client new {
ipaddr = 192.168.1.0/24　または0.0.0.0/0
secret = radiusstring
}
```

`/etc/raddb/clients.conf`のipaddrを直して起動したらうまくいきました。

～折込ここまで

</div></details>

あとは`systemctl enable radiusd`で自動起動の有効化をおこないます。

```:FreeRADIUSの自動起動有効
#systemctl enable radiusd
```

### radtestによる単体試験
先程インストールした`freeradius-utils`に含まれている`radtest`を使い、サーバ自身に対してRADIUS認証出来るか確認します。
※投稿主はこの時点で`freeradius-utils`をインストールし忘れた結果、コマンドないと言われてﾅﾝﾃﾞﾅﾝﾃﾞ？してました。

```:radtestのコマンド体系
radtest #ユーザ名# #ユーザパスワード# #宛先RADIUSサーバ# #宛先ポート# #キーストリング#
```

今回の場合、宛先RADIUSサーバは自分自身なので`localhost`を指定。
ただし、`localhost`指定の場合、`clients.conf`の修正項目でも記載したとおりキーストリングは`testing123`となるので注意
逆に、`192.168.1.200`のようにIP指定すると、今回の設定では0.0.0.0/0の`new`が対象となるので、キーストリングは`radiusstring`となります。

```:正常時のradtestコマンド結果
# radtest radius1 radius1pass localhost 1812 testing123
Sent Access-Request Id 37 from 0.0.0.0:44528 to 127.0.0.1:1812 length 77
	User-Name = "radius1"
	User-Password = "radius1pass"
	NAS-IP-Address = 127.0.0.1
	NAS-Port = 1812
	Message-Authenticator = 0x00
	Cleartext-Password = "radius1pass"
Received Access-Accept Id 37 from 127.0.0.1:1812 to 0.0.0.0:0 length 20
```

うまくいかない場合、リトライ回数分試行した後、以下のメッセージが出力します。
キーストリングに誤りがある可能性が高いので確認してみてください。

```:異常時のradtestコマンド結果
(0) No reply from server for ID 32 socket 3
```

# サーバFW設定
上記の試験は`localhost`で試したので問題ありませんでしたが、サーバ外からのRADIUS認証のアクセスは現状許可されていないので、許可する必要があります。
※投稿主はこれを忘れて認証が出来ずﾅﾝﾃﾞﾅﾝﾃﾞ？としてました。

```:ファイアウォールの状態確認
# firewall-cmd --state
running
```

```:ファイアウォールのアクティブゾーン確認
# firewall-cmd --get-active-zone
public
  interfaces: enp0s3
```

インターフェイスenp0s3に対してpublicゾーンが適用されているようですね。

```:ファイアウォールのゾーン設定確認
# firewall-cmd --list-all --zone=public
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: enp0s3
  sources:
  services: ssh dhcpv6-client
  ports:
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:
```

現状、sshとdhcpv6-clientしかサービス適用されていないです。
なので、ここにradiusポートも追加します。
radiusもサービスとして登録されているか確認します。

```:ファイアウォールの登録サービス確認
# firewall-cmd --get-service　※改行されてますが実際は1行で出力
RH-Satellite-6 amanda-client amanda-k5-client bacula bacula-client
 bgp bitcoin bitcoin-rpc bitcoin-testnet bitcoin-testnet-rpc ceph
 ceph-mon cfengine condor-collector ctdb dhcp dhcpv6 dhcpv6-client
 dns docker-registry docker-swarm dropbox-lansync elasticsearch
 freeipa-ldap freeipa-ldaps freeipa-replication freeipa-trust ftp
 ganglia-client ganglia-master git gre high-availability http
 https imap imaps ipp ipp-client ipsec irc ircs iscsi-target
 jenkins kadmin kerberos kibana klogin kpasswd kprop kshell ldap
 ldaps libvirt libvirt-tls managesieve mdns minidlna mongodb mosh
 mountd ms-wbt mssql murmur mysql nfs nfs3 nmea-0183 nrpe ntp
 openvpn ovirt-imageio ovirt-storageconsole ovirt-vmconsole pmcd
 pmproxy pmwebapi pmwebapis pop3 pop3s postgresql privoxy
 proxy-dhcp ptp pulseaudio puppetmaster quassel radius redis
 rpc-bind rsh rsyncd samba samba-client sane sip sips smtp
 smtp-submission smtps snmp snmptrap spideroak-lansync squid
 ssh syncthing syncthing-gui synergy syslog syslog-tls telnet
 tftp tftp-client tinc tor-socks transmission-client upnp-client
 vdsm vnc-server wbem-https xmpp-bosh xmpp-client xmpp-local
 xmpp-server zabbix-agent zabbix-server
```

真ん中ちょい下ぐらいにありましたねradius。

ちなみに、このときは何も考えずに適用しましたが、**「このサービスの内容って自分が思っているポートなんだよね？？」**と一抹の不安がよぎったら、サービスの設定ファイルを参照してみると確実です(むしろするべき)。

```:サービスの設定内容
cat /usr/lib/firewalld/services/radius.xml

<?xml version="1.0" encoding="utf-8"?>
<service>
  <short>RADIUS</short>
  <description>The Remote Authentication Dial In User Service (RADIUS) is a protocol for user authentication over netw
orks. It is mostly used for modem, DSL or wireless user authentication. If you plan to provide a RADIUS service (e.g. 
with freeradius), enable this option.</description>
  <port protocol="tcp" port="1812"/>
  <port protocol="udp" port="1812"/>
  <port protocol="tcp" port="1813"/>
  <port protocol="udp" port="1813"/>
</service>

# こっちは自分で作る用のディレクトリでした、なにもないです
cat /etc/firewalld/services/radius.xml
```

ファイル内に記載されているPort番号やTCP/UDPを確認し、対象であることを確認します。

内容に問題がなければ、これを`public`ゾーンに追加します。
`--permanent`を抜かすと一時的な登録となり、再起動したら消えるで注意。

```:恒久的にpublicゾーンにradiusサービスを登録、確認、再読込
# firewall-cmd --add-service=radius --zone=public --permanent
success
# firewall-cmd --list-all --zone=public
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: enp0s3
  sources:
  services: ssh dhcpv6-client radius
  ports:
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:
# firewall-cmd --reload
success
```

# CiscoスイッチをRADIUS認証でログインしてみる(結合試験)
実際に以下の挙動になるか試してみましょう。

①サーバが動いている状態

- CiscoスイッチにTelnet、またはコンソールログイン
    - →RADIUSサーバに登録されているID(radius1)でログイン可
    - →Ciscoスイッチに登録しているID(admin)でログイン不可

②サーバが動いていない状態

- CiscoスイッチにTelnet、またはコンソールログイン
    - →RADIUSサーバに登録されているID(radius1)でログイン不可
    - →Telnetの場合、Ciscoスイッチに登録しているID(admin)でログイン可
    - →コンソールログインの場合、いきなり特権モード

例のごとく、投稿主は初回でログインできなかったので原因特定と解消方法を以下に書いてます。

<details>
<summary>**投稿主のNG集　～CiscoスイッチがRADIUS認証されない～**</summary><div>
事象は以下の通り。

- CiscoスイッチのRADIUSユーザでログインできない
- ローカルユーザでログインはできる
- Ciscoスイッチ⇔サーバ間のPing疎通はうまくいく


本来であれば、この時点でIPレベルでは疎通できているのでRADIUSサーバ側のログを確認し何も出ていなければ「サーバに届いていてアプリに届いていないってことはポート遮断されている、つまりFWかな？」と切り分けるものですが、ログのことすっぽ抜けてパケットキャプチャ取得しにいってます。
こういうこともあるので、今回に限らずアプリ側のログは基本有効にすることをオススメします(自戒)。

とはいえ過ぎた検証結果を変えることは出来ないので当時の切り分けをそのまま載せます。
機器間の接続がうまくいかないなら、とりあえずパケット見てみてみます。

CiscoスイッチのIPアドレス`192.168.1.100`向けのパケットのみキャプチャします。
ちなみに何もオプション指定せずに実行すると全パケットがﾃﾞｭﾙﾙﾙっと出てきてしまうので非推奨。

```:パケットキャプチャ起動
# tcpdump src 192.168.1.100 or dst 192.168.1.100
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on enp0s3, link-type EN10MB (Ethernet), capture size 262144 bytes
```

とりあえずPingをCiscoスイッチから打ってみます。

```Ping疎通時のパケット
15:14:16.933911 IP 192.168.1.100 > localhost.localdomain: ICMP echo request, id 3819, seq 4997, length 80
15:14:16.933963 IP localhost.localdomain > 192.168.1.100: ICMP echo reply, id 3819, seq 4997, length 80
15:14:16.935888 IP 192.168.1.100 > localhost.localdomain: ICMP echo request, id 3820, seq 4997, length 80
15:14:16.935910 IP localhost.localdomain > 192.168.1.100: ICMP echo reply, id 3820, seq 4997, length 80
15:14:16.940045 IP 192.168.1.100 > localhost.localdomain: ICMP echo request, id 3821, seq 4997, length 80
15:14:16.940081 IP localhost.localdomain > 192.168.1.100: ICMP echo reply, id 3821, seq 4997, length 80
15:14:16.942112 IP 192.168.1.100 > localhost.localdomain: ICMP echo request, id 3822, seq 4997, length 80
15:14:16.942134 IP localhost.localdomain > 192.168.1.100: ICMP echo reply, id 3822, seq 4997, length 80
15:14:16.944137 IP 192.168.1.100 > localhost.localdomain: ICMP echo request, id 3823, seq 4997, length 80
15:14:16.944240 IP localhost.localdomain > 192.168.1.100: ICMP echo reply, id 3823, seq 4997, length 80
```

しっかりPing受けて送れてますね。
続いて問題のRADIUS認証のパケットを見てみます。

```RADIUS認証異常時のパケット
15:14:38.046759 IP 192.168.1.100.radius > localhost.localdomain.radius: RADIUS, Access-Request (1), id: 0x09 length: 78
15:14:38.046802 IP localhost.localdomain > 192.168.1.100: ICMP host localhost.localdomain unreachable - admin prohibited, length 114
15:14:44.047255 IP 192.168.1.100.radius > localhost.localdomain.radius: RADIUS, Access-Request (1), id: 0x09 length: 78
15:14:44.047346 IP localhost.localdomain > 192.168.1.100: ICMP host localhost.localdomain unreachable - admin prohibited, length 114
15:14:50.047766 IP 192.168.1.100.radius > localhost.localdomain.radius: RADIUS, Access-Request (1), id: 0x09 length: 78
15:14:50.047855 IP localhost.localdomain > 192.168.1.100: ICMP host localhost.localdomain unreachable - admin prohibited, length 114
15:14:56.047226 IP 192.168.1.100.radius > localhost.localdomain.radius: RADIUS, Access-Request (1), id: 0x09 length: 78
15:14:56.047316 IP localhost.localdomain > 192.168.1.100: ICMP host localhost.localdomain unreachable - admin prohibited, length 114
15:20:39.056405 IP 192.168.1.100.irisa > localhost.localdomain.telnet: Flags [S], seq 115084847, win 4128, options [mss 1460], length 0
15:20:39.056451 IP localhost.localdomain > 192.168.1.100: ICMP host localhost.localdomain unreachable - admin prohibited, length 52
```

受けるときはRADIUSなのに送るときはICMPですね、なのでサーバまで届いてはいても、ポートまでは届いていない可能性が高いですね。
しかも`ICMP host xxx unreachable`と出ているので**「もしかしてFWで拒否られてる？」**と思い、一時的にFWを無効化してみる。

```FW無効化
# systemctl stop firewalld
```

再度RADIUS認証してみるとログインできました。
その時のパケットは以下のようになっており、Access-Acceptと許可のパケットが来てますね。

```:RADIUS認証正常時のパケット
15:34:41.301455 IP 192.168.1.100.radius > localhost.localdomain.radius: RADIUS, Access-Request (1), id: 0x0c length: 78
15:34:41.301759 IP localhost.localdomain.radius > 192.168.1.100.radius: RADIUS, Access-Accept (2), id: 0x0c length: 20
```

余談ですが、登録されいないユーザでログインしたり、パスワードやキーストリングが違っていた場合はサーバから認証元宛にその旨のパケットが送られます。
それぞれのパケット内容に違いがあります。

```:登録されていないユーザで認証
15:37:28.342293 IP 192.168.1.100.radius > localhost.localdomain.radius: RADIUS, Access-Request (1), id: 0x0f length: 75
15:37:29.359944 IP localhost.localdomain.radius > 192.168.1.100.radius: RADIUS, Access-Reject (3), id: 0x0f length: 20
```

```:キーストリングが相違している
15:38:22.085713 IP 192.168.1.100.radius > localhost.localdomain.radius: RADIUS, Access-Request (1), id: 0x10 length: 78
15:38:23.086284 IP localhost.localdomain.radius > 192.168.1.100.radius: RADIUS, Access-Reject (3), id: 0x10 length: 20
```

```:ユーザパスワードが相違している
15:35:48.134401 IP 192.168.1.100.radius > localhost.localdomain.radius: RADIUS, Access-Request (1), id: 0x0d length: 78
15:35:48.134707 IP localhost.localdomain.radius > 192.168.1.100.radius: RADIUS, Access-Accept (2), id: 0x0d length: 20
15:36:28.512600 IP 192.168.1.100.radius > localhost.localdomain.radius: RADIUS, Access-Request (1), id: 0x0e length: 78
15:36:29.514268 IP localhost.localdomain.radius > 192.168.1.100.radius: RADIUS, Access-Reject (3), id: 0x0e length: 20
```

～折込ここまで

</div></details>

# 総評
色々とNGを出してましたが、終わってみれば問題なくログイン時にRADIUS認証がされるよう設定できたので良かったです。
特にトラブルシューティングは実際その場になってみないと得られない体験だったので、個人的にはたくさんNGが出て良かった？です。
とりあえずうまくいかなかったときは以下ようにやっていけば良いんじゃないかと思います。

- Ciscoのコマンドが反映できない
    - 途中まで入力後、Tabキーを押して何のパラメータが設定できるか確認
- FreeRADIUSが起動できない
    - radiusd -Xでデバック起動できるので、そこからエラー箇所を確認
    - 変更する設定ファイルは`cp`でバックアップを取っておき、`diff`で差分チェック
- `radtest`でうまくいかない
    - 接続先を`localhost`としてるかIPアドレスにしてるかでキーストリングが変わるの注意
- スイッチでRADIUS認証によるログインが出来ない
    - Ping疎通でIPレベルで接続されているか確認
    - パケットキャプチャで`ICMP host xxx unreachable`が出ていたらFWで弾かれている
    - RADIUSサーバのログを確認し、どの設定に誤りがあるか確認

# 反省点
「あぁすれば良かったこうすれば良かった」を今後のことを踏まえて連々と。

## Ciscoスイッチ、バージョンが古くて色々制限されてた
今回はCiscoスイッチのログインにRADIUS認証を用いる検証でしたがその他やりたいことが出来なかったのが少し残念でした。

①レガシーな設定方法しか出来なかった
最近のIOSだと、RADIUSサーバをグループ設定できるようでしたが、今回の検証機器では設定ができませんでした。
なのでTelnetはRADIUS認証、コンソールはローカル認証の設定が出来ず。

②MAC認証が出来なかった
インターフェイスにmabが適用できなかったのでMAC認証対応してませんでした。
これも次の案件で実装したい機能なので、構築前に試してみたいですね。

## Free-RADIUSのログ設定しておけばよかった

構築時にうまくいかないことはたくさんあるので、切り分け材料としてログ設定しておけばよかったと後悔してます。
次はRADIUSサーバの方に焦点を当てた構築をしたいと思うので、そのときにログ設定についても触れたいと思います。

## FWのログを見ておけばよかった
NG集の中でFWが原因で疎通ができなかった部分がありました。
あそこで「FWが原因ぽいから無効化しよう」ではなく、「FWが原因ぽいからログから拒否られているログ見てみよう」と考えていれば良かったなぁと・・・。

## Authorization、Accountingの観点で見れてなかった
RADIUS認証はAuthentication(認証)、Authorization(認可)、Accounting(アカウンティング)の3つの要素で成り立ってます。
思い返してみると、認証は検証できましたが、AuthorizationやAccountingの観点では見れていなかったなと思いました。
次回やるときは

- Authorization ・・・ 特定のユーザに特定の権限が許可される
- Accounting ・・・ 各ユーザのログイン時間を集計する

あたりを意識した構築を行いたいと思います。

# おわりに

至らない箇所がたくさんあるので、そういったところは適宜修正したり、別の記事で詳しく書いていきたいと思います。

次はデータベースを追加し、dalo-RADIUSを構築してみようかと思います。
free-radiusは構築しやすいですけど、やはりGUIあればなって思っちゃいますからね。

# 参考文献

## Cisco関連
[ネットワークエンジニアとして - AAA - RADIUS Client](https://www.infraexpert.com/study/aaaz03.html)
[Ciscoマニュアル](https://www.cisco.com/c/ja_jp/td/docs/cian/ios/ios15-1s/cg/023/sec-user-svcs-15-1s-cg/sec-cfg-radius.html)

## FreeRADIUS関連
[FreeRADIUS インストールガイド](https://wiki.freeradius.org/guide/Getting%20Started)
[FreeRADIUS man page](https://freeradius.org/radiusd/man/radiusd.html)

## (番外)firewalld
[firewalld 公式ガイド](https://firewalld.org/documentation/)