サーバからクライアントにpingを打つとサーバとクライアントの間でだけ通信ができるようになりました。その後いろいろ試した結果、一度切断して接続しなおすと、また通信できなくなったりしました。
で、最終的にこの手順を踏めば通信できると言う手順がわかったので、試したことと結果を書いておきます。
まず、いつものようにgoogleで参考ページを探します。Setting up bridging for OpenVPN on FreeBSDと言うページを発見。
ここを見ながら、最初からbridge0をtap0とrl0で作る代わりに、接続時に bridge0に tap0 を追加するようにしてみました。
しかし、openvpnサーバをnobodyで実行していると、bridge0にtap0を追加する権限がないといわれます。
とりあえず、openvpn.confの中でnobody指定しているところをコメントアウトしたら、接続時にスクリプトが実行できるようにはなりましたが、状況は変わらず。
続いて、if_bridgeのマニュアルをつらつらと見ていたら、bridgeにfilterを掛けるかどうかみたいなオプションがあることがわかりました。
そこで、以下のように無効にしてみます。
# sysctl -w net.link.bridge.pfil_member=0 # sysctl -w net.link.bridge.pfil_bridge=0これで、うまく通信ができているときにはサーバ以外の家庭内の別のマシンとの間でも通信ができるようになりました。
セキュリティ的に良いのかどうかわかりませんが、/etc/sysctl.confに書いておきます。
さて、後の問題はなんでうまく通信ができたりできなかったりするかです。
いろいろ試行錯誤した結果、たどり着いたのは以下の結論です。
arp -a を実行したときに、前回繋いだときのクライアントのエントリがあると通信できない
で、以下の手順を踏むと通信ができることがわかりました。
- クライアントからopenvpnで接続する
- サーバ側で、arp テーブルにクライアントがある場合はarp -dで削除する。
- サーバからクライアントにpingする。
前回、サーバからpingを打たないと通信できないように見えたのは、初期状態でarpテーブルにエントリがないときに、pingを打つことでarpテーブルにエントリが追加されるからでした。
そして、一度切断して接続しなおすと、前のエントリが残っているので通信できない状態になるのでした。
わからないのは、クライアントのtapインターフェイスのMACアドレスは変わらないので、arpテーブルに登録される情報は変わらないはずなのに、なんで一度削除する必要があるかと言うことです。
上記手順を踏んでも、一定時間たつと通信ができなくなり、arp -dとpingをやり直すとまた通信できるようになります。
なんか根本的なところを間違ってるのかなあ・・・。
現象がもう少し理解できました。
上記手順を踏んでも、無通信でしばらく経つと通信ができなくなる理由は、Windows側のarpテーブルからサーバのエントリがなくなってしまうためでした。(tcpdumpで見てみると、クライアントからサーバのネットワークへ arp who-has は飛んでいるのですが、サーバのネットワークからの応答がtapへ飛ばないために、クライアントのarpテーブルに登録されないようです)
サーバ側はまだクライアントを覚えていると、サーバからクライアントにarp who-has が飛ばないため、クライアントのテーブルが更新されないようです。
そこで、クライアント側でarp -s を使ってサーバのブリッジ先の物理MACアドレスを設定してやると、ずっと通信ができるようになりました。
調べている過程で、proxy-arpと言うキーワードも引っかかりました。これは、サーバ側でarp -s するときに、pubをつけると機能するようですが、ちょっと試してみたところうまく行きませんでした。
カテゴリ
Networkトラックバック(1)
このブログ記事を参照しているブログ一覧: openvpn(その2)
このブログ記事に対するトラックバックURL: https://www.wizard-limit.net/cgi-bin/mt/mt-tb.cgi/1087
» openvpn(3)(PC日記)~のトラックバック
ルータが変わったので、vpn周りも再調整。 iPhoneが使うpptpは、単にp... 続きを読む
コメントする