2014年1月6日月曜日

Raspberry PiでOpenVPNとローカルネットを中継

OpenVPNは便利なのですが、OpenVPNネットワーク内でしか通信できないのでは面白くありません。
通常はサーバを中継してインターネットに出て行けるのですが、
Serversman@VPSでは仕様上できないようです。
まあ普通はインターネットに接続できる環境でOpenVPNを張っているわけで、
わざわざOpenVPN経由でインターネットに接続しなくてもダイレクトにアクセスすればいいのですが。

別の中継を考えたとき、出先からVPNで自宅のVPNクライアントにアクセスし、
それを経由してOpenVPN未対応な機器にもアクセスできると幸せになれるかもしれません。
ということで今回は自宅に置いた機器に出先から中継機器経由でアクセスしてみることにします。
中継機器に使うのはここ数ヶ月面白い使い道を思いつかずまったく使っていなかった
Raspberry pi (Raspbian “wheezy”)です。

まずはサーバ側での作業です。
Raspberry pi用にパスフレーズを抜いた証明書を作ります。
パスフレーズを抜くのはRaspberry piの電源オン時に自動的に接続させるためです。
またRaspberry piには固定IPを割り当てるよう設定しておきます。
IPアドレスがころころ変わるといちいちアクセス先を調べるのが面倒ですから。
同時に、Raspberry Piにつながっているローカル網用のルーティング情報を設定します。
固定IPを割り当てる設定をした上で、設定ファイル"/etc/openvpn/server.conf"に以下を追加します。
route <ローカル網のネットワークアドレス> <ローカル網のサブネットマスク>
そしてRaspberry Pi用の個別設定ファイル"/etc/openvpn/ccd/client<識別名>"に
以下を追加します。
iroute <ローカル網のネットワークアドレス> <ローカル網のサブネットマスク>

次いでRaspberry pi側の設定です。以下を実行します。
# apt-get update
# apt-get install openvpn
# cd /etc/openvpn
# cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf ./
サーバで作ったサーバ証明書"ca.crt"と
クライアント証明書("client<識別名>.crt"、"client<識別名>.key")を
"/etc/openvpn/"ディレクトリにコピーし、
"/etc/openvpn/client.conf"の内容を編集して
remote <OpenVPNサーバ名> 1194
cert client<識別名>.crt
key client<識別名>.key
となるようにし、以下を実行します。
# /etc/init.d/openvpn start
# update-rc.d openvpn defaults
これでVPNに接続でき、起動時に自動接続できるようになりました。
VPN網とローカル網のルーティングは、IPアドレスの割り当てを適切に行い、
インターネットとの出入り口となるブロードバンドルータや
その他利用しているサブネット用のルータ等の設定、
あるいは各機器のルーティングテーブルの設定をきちんと行えば可能ですし、
VPN網とローカル網を直接ブリッジで1つの網にしてしまうことも可能ですが、
いろいろ面倒なのでVPNからローカルへのNAT接続のみを可能にします。
Raspberry Piの設定だけで済みますし、実用上多分問題はないでしょうから。
で、その設定は以下のようにしました。
起動スクリプト"/etc/init.d/openvpn"のstart_vpn()関数の最後に
# echo 1 > /proc/sys/net/ipv4/ip_forward
# iptables -t nat -A POSTROUTING -s <VPN網のネットワークアドレス>/<VPN網のサブネットマスクビット数> -o eth0 -j MASQUERADE
を追加し、stop_vpn()関数の最初に
# echo 0 > /proc/sys/net/ipv4/ip_forward
# iptables -t nat -D POSTROUTING -s <VPN網のネットワークアドレス>/<VPN網のサブネットマスクビット数> -o eth0 -j MASQUERADE
を追加します。設定の変化の様子は
# iptables-save
の出力結果からわかります。

この状態でOpneVPNサーバから中継機器経由のローカル網へのアクセスはすでに可能です。
ただしOpneVPNクライアントからの場合、
クライアント自身のルーティングテーブルを手動変更する必要があります。
クライアントがWindowsなら以下を実行します。
> route add <ローカル網のネットワークアドレス> mask <ローカル網のサブネットマスク> <クライアントVPN網向けIPアドレスのサーバ側IPアドレス>
ここで<クライアントのVPN網向けIPアドレスのサーバ側IPアドレス>は
<クライアントのVPN網向けIPアドレス>+1(まれに -1 ?)となります。
詳しい理屈はこちらをご覧ください。
またクライアントがLinuxなら以下を実行、
または起動スクリプト"/etc/init.d/openvpn"内で実行するよう組み込みます。
route add -net <ローカル網のネットワークアドレス> netmask <ローカル網のサブネットマスク> gw <クライアントのVPN網向けIPアドレス>
もしルーティングテーブルを変更できなければ生アクセスするのはあきらめた方がいいでしょう。
なおクライアントが192.168.1.*の網につながっていて、
かつリモートのローカル網も192.168.1.*というような、
関係するネットワークでプライベートIPアドレスが重複しているケースでも同様にあきらめた方が無難です。

ここまで構築すると、出先から自宅のPCにアクセスしてファイルをやり取りしたり、
VNC経由でリモートアクセスしたりできます。
あまり凝ったことをしなければ中継する機器の性能と回線速度の範囲でわりと快適に使えます。
Serversman@VPS(Entry)+Raspberry pi+ADSLという過酷な環境でも
VNCでのリモート操作は使えるレベルにあります。
PCに関してはそうなのですが、組み込み機器に関してはやや状況が異なります。
NASにsambaでアクセスすると大きなファイルのコピーに失敗したりしますし、
頻繁に長時間のフリーズに陥ったりよくわからないエラーが出たりします。
ウェブサーバ(ブロードバンドルータの設定ページ等)へのアクセスでも
機器によって動作がままならないケースもあったりなかったり、どうも機器依存で何かあるようです。
もちろん同一セグメント上にないと動かすのが困難なDLNAなど言わずもがなです。
とりあえず自宅のPCにリモートログインしさえすれば大概のことはできるのでよしとすることにします。

ところで条件がそろわず上記のような環境を実現できなくても他の方法はあり、
リモートローカル網に間接的にアクセスする方法として、
クライアントからVPN経由で中継機器にsshで接続して
ローカル網へポートフォワードすることができます。
例えばローカル網のウェブサーバにアクセスしたい場合、クライアントで
$ ssh -L 8000:<ローカル網の機器のIPアドレス>:80 <中継機器のログインアカウント>@<中継機器のVPN網側IPアドレス>
を実行した上でクライアントのウェブブラウザから"http://localhost:8000"でアクセス可能です。
これを応用するとOpenVPNサーバを始点にsshのトンネルを作って
他の機器へと公開することで解決も図れます。
ただしセキュリティには気を使う必要があります。

さらに、ウェブ等限定でいいなら中継機器経由をプロキシサーバにして
クライアントのウェブブラウザの設定でプロキシサーバをそれに指定すれば
ローカル網にアクセスできます。
ただいちいちプロキシ設定を変えるのは非常に面倒なので、
しょっちゅうアクセスするなら自動構成スクリプトを使うなど工夫が必要です。
パスワードを用いるなどセキュリティに注意する必要はありますが、
OpneVPNサーバをプロキシサーバにする別解もあります。

0 件のコメント:

コメントを投稿