0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

macOSのopenconnectで `Can't assign requested address` が出る原因と対処(古いホストルートの残り)

0
Posted at

macOSのopenconnectで Can't assign requested address が出る原因と対処(古いホストルートの残り)

TL;DR

  • openconnect でVPNに繋ごうとしたら Failed to connect ...: Can't assign requested address で失敗した
  • 原因は、以前別のネットワークで繋いだときのVPNサーバ宛て固定ホストルートが残っていたこと
  • 今いるネットワーク(en0)のサブネットからは、その古いルートのゲートウェイに届かず、送信元アドレスを用意できなかった
  • 対処は sudo route delete <VPNサーバIP> で古いルートを消すだけ

環境

  • macOS
  • openconnect(Homebrew)
  • クライアント証明書認証でVPN接続

現象

$ sudo openconnect --user vpn_user \
    --cafile ~/.ssh/vpn/ca-cert.pem \
    --certificate ~/.ssh/vpn/vpn_user-cert.pem \
    --sslkey ~/.ssh/vpn/vpn_user-key.pem \
    --servercert pin-sha256:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX= \
    https://vpn.example.com
POST https://vpn.example.com/
Failed to connect to 203.0.113.10:443: Can't assign requested address
Failed to open HTTPS connection to vpn.example.com
Failed to complete authentication

名前解決自体は成功(203.0.113.10 に解決)していて、TCP接続の段階で Can't assign requested address(= EADDRNOTAVAIL)になっている。

原因

ルーティングテーブルに、VPNサーバ宛ての古い固定ホストルートが残っていた。

$ netstat -rn -f inet | grep 203.0.113.10
203.0.113.10   192.168.11.1   UGHS   en0

203.0.113.10 へはゲートウェイ 192.168.11.1(en0)経由で行け、というルートだ。
ところが、今の en0 のIPは別サブネットだった。

$ ifconfig en0 | grep "inet "
	inet 10.0.0.216 netmask 0xffffff00 broadcast 10.0.0.255   # = 10.0.0.0/24

ゲートウェイ 192.168.11.1(192.168.11.0/24)は、今の en0 のサブネット(10.0.0.0/24)にいない。つまり直接は届かない。
route get も、この壊れたゲートウェイを返してきた。

$ route get 203.0.113.10
   route to: 203.0.113.10
destination: 203.0.113.10
    gateway: 192.168.11.1
  interface: en0

openconnect が 203.0.113.10connect() するとき、カーネルはこの壊れたルートを選ぶ。でも届かないゲートウェイ向けの送信元アドレスを用意できず、EADDRNOTAVAILCan't assign requested address になっていた。

なぜ古いルートが残ったのか

openconnect は接続時、VPNサーバ宛てのパケットだけはトンネルを通さず物理ゲートウェイへ送る、というホストルートを自動で追加する。
以前 192.168.11.0/24(自宅ルータ 192.168.11.1)で繋いだときに張られたこのルートが、異常終了で片付けられずに残った。その後ネットワークが変わって en0 が 10.0.0.x になり、ルートだけ取り残された、というわけだ。

対処

古いホストルートを消すだけ。

$ sudo route delete 203.0.113.10

消えたか確認。

$ netstat -rn | grep 203.0.113.10   # 何も出なければOK

あらためて openconnect を実行すれば、接続時に正しいゲートウェイでルートを張り直して繋がる。

切り分け手順まとめ

  1. route get <VPNサーバIP> で、実際に使われるゲートウェイとインターフェースを確認する
  2. そのゲートウェイが ifconfig <IF> の今のサブネットに属しているか確認する(属していなければ壊れたルート)
  3. netstat -rn | grep <VPNサーバIP> で固定ルートの有無を確認する
  4. 古ければ sudo route delete <VPNサーバIP>

教訓

Can't assign requested addressEADDRNOTAVAIL)は、送信元アドレスを用意できないというエラーだ。外向きの接続でこれが出たら、まずルーティングの不整合(古くて壊れたルート)を疑うといい。

VPNクライアントが異常終了すると、後始末されないルートが残ることがある。ネットワークを切り替えたあとに急に繋がらなくなったら、route テーブルを見るのが近道だった。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?