らくがきちょう

なんとなく

Cisco ASA で AnyConnect (SSL-VPN) を設定する

Cisco ASA で AnyConnect クライアントを使った SSL-VPN の設定をメモしておきます。

構成/環境

以下の構成で検証しました。

f:id:sig9:20160610001501p:plain

Cisco ASA 以下を使いました。

ハードウェア Cisco ASA 5506-X
ソフトウェア 9.4(1)

アドレス体系は以下としてあります。

WAN 側 192.168.253.0/24
LAN 側 192.168.1.0/24
SSL-VPN 接続時に払い出すアドレス 192.168.99.1 〜 100/24

基本的な設定

ホスト名やアドレス、ルーティング等の基本設定を済ませておきます。

hostname ASA
domain-name EXAMPLE.LOCAL
!
interface GigabitEthernet1/1
 nameif outside
 security-level 0
 ip address 192.168.253.100 255.255.255.0
 no shutdown
!
interface GigabitEthernet1/2
 nameif inside
 security-level 100
 ip address 192.168.1.100 255.255.255.0
 no shutdown
!
no pager
!
route outside 0.0.0.0 0.0.0.0 192.168.253.254 1
!
end

inspection の設定

必須ではありませんが、ICMP パケットを inspection 対象としておきます (inspection 対象にしないと戻りパケット用の ACL を明示的に書かなければならない為)。

policy-map global_policy
 class inspection_default
  inspect icmp
!
end

NAT の設定

LAN → WAN の通信は送信元アドレスを outside 側インターフェイスで NAT します。

object network OBJ_LAN
 subnet 192.168.1.0 255.255.255.0
 nat (inside,outside) dynamic interface
!
end 

AnyConnect の設定

ここからが肝心の AnyConnect (SSL-VPN) 設定です。

ip local pool POOL_ANYCONNECT 192.168.99.1-192.168.99.100 mask 255.255.255.0
!
object network OBJ_POOL_ANYCONNECT
 subnet 192.168.99.0 255.255.255.0
 nat (outside,outside) dynamic interface
!
nat (inside,outside) source static OBJ_LAN OBJ_LAN destination static OBJ_POOL_ANYCONNECT OBJ_POOL_ANYCONNECT
!
access-list ACL_SPLIT_TUNNEL extended permit ip 192.168.1.0 255.255.255.0 any
!
webvpn
 enable outside
 anyconnect image disk0:/anyconnect-win-4.2.04018-k9.pkg 1
 anyconnect image disk0:/anyconnect-macosx-i386-4.2.04018-k9.pkg 2
 anyconnect image disk0:/anyconnect-linux-64-4.2.04018-k9.pkg 3
 anyconnect enable
 tunnel-group-list enable
 error-recovery disable
!
group-policy POLICY_ANYCONNECT internal
group-policy POLICY_ANYCONNECT attributes
 vpn-tunnel-protocol ssl-client
 split-tunnel-policy tunnelspecified
 split-tunnel-network-list value ACL_SPLIT_TUNNEL
dynamic-access-policy-record DfltAccessPolicy
username ADMIN password PASSWORD privilege 15
username USER password PASSWORD
username USER attributes
 service-type remote-access
tunnel-group TUNNEL_ANYCONNECT type remote-access
tunnel-group TUNNEL_ANYCONNECT general-attributes
 address-pool POOL_ANYCONNECT
 default-group-policy POLICY_ANYCONNECT
tunnel-group TUNNEL_ANYCONNECT webvpn-attributes
 group-alias ALIAS_ANYCONNECT enable
!
end

設定のポイント

設定のポイントを幾つか補足します。説明の都合上、若干コンフィグの順序を変えています (設定自体は変えていません)。

SSL-VPN 接続時に払い出すアドレスプール

SSL-VPN 接続時に払い出すアドレスプールを POOL_ANYCONNECT として定義します。また、このアドレス範囲を OBJ_POOL_ANYCONNECT として定義し、(通常の LAN → WAN 通信は NAT させるが)「LAN → SSL-VPN プール」向けの通信は NAT させないようにしています。

ip local pool POOL_ANYCONNECT 192.168.99.1-192.168.99.100 mask 255.255.255.0
!
object network OBJ_POOL_ANYCONNECT
 subnet 192.168.99.0 255.255.255.0
 nat (outside,outside) dynamic interface
!
nat (inside,outside) source static OBJ_LAN OBJ_LAN destination static OBJ_POOL_ANYCONNECT OBJ_POOL_ANYCONNECT

SSL-VPN の設定

事前に AnyConnect のイメージを ASA のストレージにコピーしておきます。ここでは outside 側で SSL-VPN (WebVPN) を有効化し、AnyConnect のイメージを指定しています。tunnel-group-listenable に設定すると SSL-VPN 接続時に利用するグループをリスト表示させ、選択出来るようになります。

webvpn
 enable outside
 anyconnect image disk0:/anyconnect-win-4.2.04018-k9.pkg 1
 anyconnect image disk0:/anyconnect-macosx-i386-4.2.04018-k9.pkg 2
 anyconnect image disk0:/anyconnect-linux-64-4.2.04018-k9.pkg 3
 anyconnect enable
 tunnel-group-list enable
 error-recovery disable

スプリットトンネルの設定

次はグループポリシーを定義します。SSL-VPN 接続時でも VPN トンネルに流したくないネットワークを ACL で指定し、スプリットトンネルの設定を行っています。

access-list ACL_SPLIT_TUNNEL extended permit ip 192.168.1.0 255.255.255.0 any
!
group-policy POLICY_ANYCONNECT internal
group-policy POLICY_ANYCONNECT attributes
 vpn-tunnel-protocol ssl-client
 split-tunnel-policy tunnelspecified
 split-tunnel-network-list value ACL_SPLIT_TUNNEL

split-tunnel-policy は以下 3 種類の指定が出来ます。

ASA(config-group-policy)# split-tunnel-policy ?

group-policy mode commands/options:
  excludespecified  Exclude only networks specified by
                    split-tunnel-network-list
  tunnelall         Tunnel everything
  tunnelspecified   Tunnel only networks specified by split-tunnel-network-list

各々、以下の意味を持ちます。

オプション SSL-VPN トンネルに流すトラフィック
excludespecified 指定した ACL 以外のトラフィック
tunnelall 全てのトラフィック
tunnelspecified 指定した ACLトラフィック

ユーザの定義

ここでは二人のユーザを定義しました。

ユーザ名 パスワード 役割
ADMIN PASSWORD ASA の管理用ユーザ
USER PASSWORD AnyConnect 接続用

USER は属性 (attributes) を service-type remote-access とし、「VPN 用のユーザである」旨を宣言します。

dynamic-access-policy-record DfltAccessPolicy
username ADMIN password PASSWORD privilege 15
username USER password PASSWORD
username USER attributes
 service-type remote-access

トンネルグループの設定

先程定義した SSL-VPN 接続時に払い出すアドレスプールを指定します。また、group-alias を定義しておくと、AnyConnect クライアントから SSL-VPN 接続を開始する際にリスト表示させるグループ名 (の、別名 = 表示名) を定義することが出来ます。

tunnel-group TUNNEL_ANYCONNECT type remote-access
tunnel-group TUNNEL_ANYCONNECT general-attributes
 address-pool POOL_ANYCONNECT
 default-group-policy POLICY_ANYCONNECT
tunnel-group TUNNEL_ANYCONNECT webvpn-attributes
 group-alias ALIAS_ANYCONNECT enable
!
end

接続テスト

AnyConnect クライアントから ASA の outside 側アドレス (今回は 192.168.253.100) を指定して接続を開始します。ASA へ公的な証明書をインストールしたり、ASA 自体を自己証明局にすることも出来ます。しかしデフォルトの状態でも ASA は自己証明書を持っており、明示的に証明書を指定しない場合はこの自己証明書が利用されます。今回はこの自己証明書を利用している為、SSL-VPN 接続時に警告が表示されました。Connect Anyway をクリックして続行します。

f:id:sig9:20160610004640p:plain

グループ名 (の、別名 = Alias) はデフォルトで表示されているはずです。後はユーザ名とパスワードを入力し、OK を押して SSL-VPN 接続を確立します。

f:id:sig9:20160610004646p:plain

SSL-VPN が正常に確立していれば PC-A → PC-B で通信出来るようになっているはずです。PC-A から PC-B へ Ping し、疎通出来ていることを確認します。

$ ping -c 3 192.168.1.1
PING 192.168.1.1 (192.168.1.1): 56 data bytes
64 bytes from 192.168.1.1: icmp_seq=0 ttl=128 time=1.685 ms
64 bytes from 192.168.1.1: icmp_seq=1 ttl=128 time=1.579 ms
64 bytes from 192.168.1.1: icmp_seq=2 ttl=128 time=1.738 ms

--- 192.168.1.1 ping statistics ---
3 packets transmitted, 3 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 1.579/1.667/1.738/0.066 ms

同セグメント宛の通信を許可する

SSL-VPN 接続が確立した際、デフォルトの状態では「クライアントの同セグメントにはアクセス出来ない」状態になってしまうようです。ですので、例えば「自宅から学校のネットワークに AnyConnect で SSL-VPN した際、自宅の (同セグメントにある) プリンタにアクセス出来ない」といった問題が起きてしまいます。これは AnyConnect クライアントの設定画面にある「Allow local (LAN) access when using VPN (if configured)」をチェックし、SSL-VPN を再接続することで回避出来ます (デフォルトではチェックが入っていない為、同セグメントにアクセス出来なくなっています)。

f:id:sig9:20160610010002p:plain

証明書について

上述の々になりますが、SSL-VPN 接続時に利用する証明書は以下、いずれを利用することも出来ます。

  1. 外部の CA 局で発行した証明書を利用する
  2. ASA 自身を CA 局 (自己証明局) にして発行した証明書を利用する
  3. ASA がデフォルトで持っている自己証明書を利用する

SSL-VPN 設定の際、明示的にサーバ証明書を指定しなかった場合は「ASA がデフォルトで持っている自己証明書」が使われます (ので、警告は出るものの、SSL-VPN 接続は出来ます)。

クライアントの同セグをスプリットトンネルの ACL に含めるとマズイ??

今回は WAN を 192.168.253.0/24、LAN を 192.168.1.0/24 としています。

f:id:sig9:20160610001501p:plain

ですので、スプリットトンネル用の ACL は以下の通り、LAN のアドレス「192.168.1.0/24」を設定しました。

access-list ACL_SPLIT_TUNNEL extended permit ip 192.168.1.0 255.255.255.0 any

しかし、仮にこれを以下のように「WAN も含めた 192.168.0.0/16」と書くとどうなるか、実験してみます。

access-list ACL_SPLIT_TUNNEL extended permit ip 192.168.0.0 255.255.0.0 any

この場合、以下のような結果になります。

フロー 結果
PC-A から PC-B への Ping OK
PC-A から同セグメントの PC への Ping NG

AnyConnect でスプリットトンネルを行うと、SSL-VPN クライアントのルーティングテーブルへ「スプリットトンネルとして定義されている経路」がインストールされるます。しかし、その際に (今回実験したように)「同セグがスプリットトンネルの ACL に含まれている」と同セグ宛の通信が SSL-VPN トンネルに向いてしまい、結果として "同セグへ通信出来ない" という事象になるようです。これを仕様として記載しているドキュメントを見つけたわけでは無いのですが、実際にスプリットトンネル用の ACL を書く際は「集約した際に思いがけず、SSL-VPN クライアント側のネットワークを含めてしまう」ことが無いように気をつけた方が良いのかも知れません… (正しいお作法があれば是非、知りたいです、、、)

トラブルシューティング

設定したのに上手く通信出来ない… 場合は debugshow コマンドでトラブルシューティング出来ます。また、「SSL-VPN 接続自体は確立しているのに、通信が出来ない (パケットがどこかでドロップしている)」場合は packet-tracer で送信元/宛先を指定し、"そのフローがどこでドロップしているのか?" をトラブルシューティング出来ます。以下は packet-tracer のコマンド例です。ICMP のメッセージタイプは適当に指定しています。

packet-tracer input outside icmp 192.168.99.1 0 0 192.168.1.1 detailed