2013年9月10日

iPhoneをVPNでLANにつなぐ

このところVPNに少々ハマっている。

数年前から、まず日本に置いた録画サーバをファイルバックアップサーバとして使うときのセキュリティのためにOpenVPNを開通させており、次いで職場のWSと自宅のLANの間にやはりOpenVPNを開通させて重宝している。また、ラップトップから自宅LANへのOpenVPNも構築し、旅行先から自宅の全ネットワークソースを使えている。

最近、NOOKというAndroidのタブレットとAmazonのKindle Paperwhiteを二台づつ買った。Kindleの方は電子本リーダ専用ということで我が家のVPNとは直接関係ないが、二台のうち一台は日本のキンドルストアから日本の本を買うため専用ということで、アマゾンの国別サービス制限を回避するために外部VPNを使っている(こちらの記事参照)。NOOKの方は少なくとも一台は配偶者の仕事用ということで、仕事先から我が家のLANにアクセスできるようにOpenVPNを開通させた。

となると、完璧主義者の小生としては、残りのモバイル機器である家族3人が使っているiPhoneも何とかVPNで我が家のLANに接続させたくなる。実を言うと、接続できたからと言って何ができるようになると言うあてはない。とにかく、まず接続してみたいのだ。

と言うことで仕事が暇になったのをよいことにあれこれやってみた。

使ったのは
・Linuxサーバ:Fedora 13
・iPhone 4S:iOS 6.1.3
・ネットワーク:WiFi(3G/4Gはまだ試していない)

iPhoneはネイティブでPPTP、IPSec、L2TPのVPNをサポートしている(私にはIPSecとL2TPの区別がよくつかない)いるが、結論としてこれらのいづれもダメで、やはりiPhoneもOpenVPNを採用することにした。
 

PPTP

少々の紆余曲折はあったが、Linuxのファイアウォール上でPPTPDを動かし、外部のLinuxクライアントから暗号付きでVPNを構築する異に成功した。

ところがiPhoneで同じように開通させようとしてもエラーになるばかりで、結局暗号化をすべて禁止しないとダメだということが分かった。VPNの目的が中国のようにサイトのアクセス規制のある国から禁止されているサイトをアクセスするためで、VPNの先がパブリックのインターネットなら暗号化は不要だが、ここで目的としているようにプライベートなLANをアクセスするためには暗号化されていないのは論外と言うことで却下。
 

IPSec/L2TP

こちらのVPNの比較記事を読み、試すまでもなくやめた。iPhoneのネイティブサポートに対する期待はあったが、PPTPのような結末では時間の無駄と判断し、性能と安全性にすぐれ(我が家で)実績のあるOpenVPNを進めることにした。
 

OpenVPN

iTunesからOpenVPNのアプリをダウンロードしてインストールしたら、基本的な設定はAndroidの場合と変わるところはない。*.confファイルから*.ovpnファイルを作成するところも同じ(こちらのスクリプトを使う)。
 
*.ovpnファイルの取り込みはさらに簡単で、ファイルを(本文ではなく)添付したメイルをiPhoneに送ってやって、そのファイルを開くとOpenVPNのアプリが起動してインポートが始まる。

さあ、iPhoneからもOpenVPNが開通した。何をさせよう?

2013年8月23日

ファイルシステムを跨いでのファイルの移動にはmvを使ってはいけない

mv(1)は賢い。同じファイルシステム内のファイルの移動ならrename(2)を使ってディレクトリエントリだけを変更し、ファイルシステムを跨いだ移動ならまずcp(1)と同じ動作でファイルをコピーしてからrm(1)と同じ動作で元のファイルを削除する。便利だ。

しかし便利さに甘えてはいけない。

失敗例は、btrfsの一つのサブボリュームから別のサブボリュームにファイルを移動させようとしたとき。mvで移動を開始したがどうも遅い。簡単な計測をしてみると5MB/s程度の速度しか出ていない。SOHO向けのNASで、だ。

straceで調べてみると、ファイルをコピーする前に必ずrenameを実行して本来の移動だけですまないかどうか試して、ダメならコピーを実行する、と言うことを全てのファイルの移動に毎回行っている。一回にかかる時間は僅かかも知れないが、移動したいファイルは50万個ぐらいあるから無視できない。おまけに、コピーの実行には32KBという小さなバッファで毎回read(2)write(2)を呼んでいる。遅いわけだ。多分cpとかtar(1)で実際にファイルをコピーして元のファイルを削除した方が速かったと思う。

今回はbtrfsのサブボリューム間の移動だった。btrfsのサブボリュームはストレージプールは共有するが個別のファイルシステムとして動作する。だから、コピーによる移動は同じストレージプールにコピーして削除と言うバカ臭いことになる。

おまけにmvのコピーによるファイルの移動は、個々のファイルのアトリビュートは全ファイルをコピーし終わるまで確定しないようだ。

今回はストレージの空き容量容量が十分あったので全ファイルを一旦コピーしてからコピー元の全ファイルを削除と言う方法も取れたはずだが、空き容量に余裕がないときはファイルをスキャンしながら一つづつコピーしては削除と言う動作をするスクリプトでも書くか。

2013年8月13日

VMWare PlayerでCDからアプリケーションをインストールする

9年間使ってきたDellのデスクトップが操作できなくなった。このデスクトップは、我が家の家計簿や写真の加工、CADでの簡単な設計など私の仕事のかなりの部分をこなしている。数年前からは、仕事部屋に置かれた物理画面・キーボードに向かうことはなくなり、専ら居間のラップトップからターミナルサービスを通して使っている。国外旅行中もVPNで操作するなど、未だに現役のワークホースだった。

正確には、ネットワークが使えなくなった。このデスクトップにはネットーワークカード(NIC)が2台装着してあり、両方共動作しないので、ハードウェアの不具合ではなくWindows XPのネットワークスタックのどこかが吹っ飛んだらしい。HDDを含めて、購入後9年間ほぼ24/7で稼働してきたハードウェアはまったく故障なしに動作している。大したもんだ。

さて、このPCがないと日常生活が困る。特にQuickenを使った金銭の出し入れの記帳ができないのは致命的だから早急に何とかしなければならない。

しかしながら、もうこのPCはハードウェアがいつ壊れてもおかしくないし、Windows XPも来年でサポート終了ということなので、2年ほど前から考えてきたハードウェアとソフトウェアの双方のアップグレードを実行することにした。

旧マシン
  • Pentium 4 (2 threads) 3.0GHz
  • 4GB DDR
  • SATA 1.5Gb/s 180GB
  • Windows XP Pro 32bit
新マシン
  • Core i5 (4 cores) 3.2GHz
  • 8GB DDR3
  • SATA 6Gb/s 1TBx2 (RAID1)
  • Windows 7 Pro 64bit

OSは「仕事に使えるOS」であるWindows 7は当然としても、この際だから64bit版を選んだ。32bitから64bitへ移行するので、今まで使ってきたWindows XP 32bit版で動いてきたアプリケーションの一部が動作しないことが予想され、そして予想通りいくつかのアプリケーションはインストールできなかった。また、ネットワーク経由でいろいろなことをするので、必然的にProバージョンを選んだ(実は4年ほど前に構築した配偶者のPCは深く考えることなしにVista Home Premiumを選び、結果的に大失敗だったという苦い経験がある)。

「予想していた」ということは「対策を立てていた」ということで、VMWare Playerをつかって64bitのWindows 7上で32bitのWindows XPを走らせてみると見事成功!ここに32bitでしか動かないアプリケーションをインストールすれば、少々使いにくさはあるが新マシンで旧来のアプリケーションが使えるようになるはず。

VMWare Playerには、CD/DVDのようなリムーバブルの物理ドライブやISOメディアイメージファイルを仮想ゲストマシンのリムーバブルドライブ(E:やF:のドライブ)としてマップする機能があるので、これを使えばCDなどから仮想ゲストマシンにアプリケーションがインストールできる。

と思ったが、できない。一時ファイルを作れないというエラーが発生してインストーラが終了してしまう。


 この「C:\Documents and Settings\hiro\LocalSettings\Temp」というフォルダは隠しフォルダながら存在しており、手でファイルを作成できる。隠し属性を「見える」に変更しても変わらない。私はWindowsのACLとかにはまったく疎いのでどうしたらよいか分からない。

しばらく悩んだが、 解決方法は意外と単純だった。

インストール用のCDの内容をそっくり(ISOイメージではなくファイルレベルで)ローカルディスクにコピーして、そこでインストーラを走らせると難なくインストールできた。

複数のPCに同じアプリケーションをインストールするためにネットワークドライブにISOイメージをファイルに展開してもよいが、その時はネットワークドライブのファイルシステムがケースインセンシティブ(大文字小文字を区別しない)であることを確認すべき。アプリケーションのインストーラはケースの違うファイル名のファイルをコピーしようとすることはよくある(実ファイルは「abc.xyz」なのに「ABC.XYZ」をコピーしようとする)。ISOファイルシステムは規格上ケースインセンシティブなので問題はないが、これを別ファイルシステムに展開するとケースの判断はそのファイルシステムに依存するから。

また一つ障害をクリア!

Windows 7のスタートメニューをカスタマイズする

Windows XP、Vistaまではスタートメニューを右クリックするとWindows Explorerが現在のユーザのローカルスタートメニューのフォルダを開き、ここにサブフォルダやショートカットを好きなように作ってスタートメニューをカスタマイズできたが、Windows 7からはこれができなくなった。何でも「一部のユーザ」に多大な混乱を招いたからと言う理由らしいが、こういう「一部の」馬鹿ユーザのヘマのとばっちりを受けるのは、すべては自己責任と自覚している賢明ユーザだ。

Windows 7ではユーザに直接スタートメニューを編集させない代わりに「ピン」と言う機能を提供し、プログラムファイルのアイコンを右クリックして「このブログラムをスタートメニューに表示したい」と言うことができることになっているが、必ずしもすべてのファイルが「ピン」できるのではなさそうだし、メニューの階層のどこに表示されるようになるのかなど、何が起こるのかがさっぱり予測がつかない。

この「何が起こるのか予測できない」はWindowsに限ったことではなく、近頃のデスクトップのOSの馬鹿げた傾向のように思える。どうもOSの作者たちはユーザが何をしたいのかはユーザ自身よりも自分たちの方がよく知っており、それを先回りして実現することが「使い易さ」だという幻想を抱いているらしい。だから「コンテクスト何とか」という、ユーザにとっては不安定で何が起こるのか予測できないUIができ上がるのだ。

考え違いも甚だしい。PCを仕事で使っているユーザは自分が何をしたいのか100%知っており、100%自分でコントロールしたいのだ。

話を戻して、「ピン」は本当に使いにくい。Vistaまではどんなファイルでもタスクバーにドラッグすれば「クイックローンチャ」が作成でき、しかもそこから起動されるタスクのタブとは別だったから、例えばブラウザを別ウィンドウで立ち上げなんてことがすぐできたが、「7」のタスクバーのピン機能はアプリケーションに限られ、しかもタスクタブと重畳されるのでとても使いにくい。Windows NT → Windows XPまでは世代ごとに使い易くなったのに、Vista以降はどんどん使いにくくなってきている。いったい何を考えているのか?

前置きが長くなった。

Windows 7の「All Programs」は、「C:\ProgramData\Microsoft\Windows\Start Menu\Programs」 というフォルダそのものである。ここに手作業でフォルダやショートカットを作ったら、ちゃんとスタートメニューの「All Programs」に反映された。パスからして、全ユーザに共通のスタートメニューを扱うようだ。


ついでに、ユーザ固有のクィックメニュー(「start」をクリックすると最初に現れるプログラムリスト)の「ピン留め」されたプログラムは、「C:\Users\xxx\AppData\Roaming\Microsoft\Internet Explorer\Quick Launch\User Pinned\StartMenu」フォルダの中のショートカット。「Roaming」だの「Internet Explorer」だの意味不明のパスエレメントがあるが、気にしない。

当然のことながら、フォルダの中身をいじってメニューをカスタマイズするときはくれぐれも慎重に。私のやらかした失敗は、「Administrative Tools」というフォルダ(中身は実行プログラムファイルへのショートカット) を捨てたら、スタートメニューの右側の「Administrative Tools」の中身も消えてしまったというアセリもの。実はスタートメニュー右側の「Administrative Tools」は実質的には「C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Administrative Tools」フォルダへのショートカットに過ぎないようだ。捨てたフォルダとその中身は幸いゴミ箱の中にまだそっくりそのまま残っていたので、復活して事なきを得た。

2013年8月4日

マザーボードの交換

ファイアウォールに使っているサーバが死にかけた。

突然フリーズするようになり、電源再投入すると再起動してしばらく順調に稼働するものの、数時間後にはまたフリーズする。/var/log/messageを見ても何ら情報はなく、ただただフリーズしているので、4年前に中古で買ったマザーボードの寿命と考え、新品と交換することにした。それまではwebpowerというネットワーク電源スイッチでpingで監視して自動電源再投入でしのぐ。

新しいマザーボードは近所のFry'sで一番安かったASUS製。
  • CPU: Celeron Dual Core 2.7GHz
  • Memory: DDR3 2GB x2 (=4GB)
  • Slots: PCIe x1, PCIX x1, 32bit PCI x2
  • PS/2: Mouse, Keyboard (separate)
  • VGA
  • 6Gb SATA x1, 3Gb SATA x5
古いマザーボードはPentium 4 (2.8GHz シングルスレッド)+ 2GBだったから、かなりのスペック向上である。メモリは本当は2GBで十分なのだが、今どき1GBのDDR3は売っていないので2GBのチップを使い、スピードを多少稼ぐためデュアルチャンネルメモリを選択で x2になった。32bit PCIは、手持ちのCaller ID用のモデムカードと二番目のNIC(ファイアウォールなのでLANとWANの両方が必要なのだ!)に必要。HDMIだとかSPI/Fだとかのマルチメディアポートもついているが、サーバには全く関係ない。PS/2のマウスとキーボードが付いているのは、10年前から使っているPS/2用KVMスイッチが使えるので助かる。HDDは当然稼働中のものを使う。

マザーボードの交換は神経を使う。稼働中のインスタレーションとの互換性が心配なのは以下の点。
  • SATAコントローラ
  • ビデオチップ
  • NIC(イーサネット)

いきなり稼働中のマザーボードを交換するようなせっかちはせずに、まずは裸の状態でテストして問題点を解決してから交換、と言う手順で行う。テストには別のマザーボード用に作ってあった(稼働することが証明されている)RAID1のインスタレーション(交換先と同じFedora 13)を使う。

ブートしない!

最初の躓きは全くブートしないこと。BIOSにも到達せず、何も動かない。「さてはCPUの装着時にピンを曲げたか?」と何度も点検するが異常なし。最終的には(当然のことながら)自分のチョンボと判明。電源スイッチ代わりにATX電源コネクタの緑と黒をショートしていたのが誤りで、フロントパネル用コネクタのピンを使うことで解決。

 電源コネクタの方法は他のマザーボードでは上手く行っていたのに、このマザーボードでは電源は入りCPUファンなども動き始めるのにそれ以上進まなかった。違いと言えば、他のマザーボードでは緑と黒のショートはモメンタリで電源投入後はショートを外しても投入されたままだったのにこのマザーボードではショートを外すと電源が切れてしまったこと。まぁインチキはいけませんね。

ルートデバイスが見つからない!

BIOSが走り、HDDを繋ぐとLinuxがブートし始める!SATAの問題はなさそう(SATAでトラブったことはないが…)。

ところがブートの段階で「ルートデバイスが見つからない!」というエラーで固まってしまう。ブートの進行状況のバーが伸び行く時にAlt+DでブートRCファイルの進行状況メッセージが表示されるはずなのだがそれができない。「さてはビデオの互換性の問題か?」とオンボードのVGAの代わりにPCIにVGAカードを挿してみるが同じこと。

仕方がないので、もう一度BIOSの設定をくまなくチェックする。試しにSATAの設定をデフォルトのIDEからAHDIに変えたらあっさり動いた。二つ目クリア!

NICが動かない

デスクトップが立ち上がり、ターミナルウィンドウを開いてifconfigを実行してみるが、ループデバイス(127.0.0.1)しか動いていない。SATAとビデオの問題とは違い、こちらは予想していたとおり。

まず、lspciを実行してNICデバイスがカーネルに認識されていることを確認。これはOK。

次に、/etc/udev/rules.d/70-persistent-net-rulesの日付をチェックすると更新されており、このファイルを内容を見ると、eth2eth3という新しいデバイスが追加されている(このマザーボードには、オンボードとPCI32スロットの二つのNICがついている)。これらが新しいマザーボードで使えるNICなので、これらのエントリを基に新しいマザーボード用のネットワークスクリプトファイルを作る。

RedHat/Fedora/CentOS系のディストロでは、ネットワークデバイスは/etc/sysconfig/network-scripts/ifcfg-***(「***」はネットワークデバイス名、「eth0」「eth1」など)というファイルに記述されているので、先ほどの/etc/udev/rules.d/70-persistent-net-rulesの情報とlspciの出力(NICのチップなどのコメントのみ)でifcfg-eth2ifcfg-eth3のファイルを作成し、「ifup eth2」を実行してみるとネットワークがつながった。

もう一度整理すると
  • /etc/udev/rules.d/70-persistent-net-rules
  • /etc/sysconfig/network-scripts/ifcfg-***
の二つのファイルの内容が一致するように
  • デバイス名(eth0eth1、…)
  • MACアドレス
を新しいハードウェアに合わせて修正してやる。

eth0eth1を修正したら、ブート時からこれらのインタフェースが使えるようになった。

h@spice:~$ cat /etc/udev/rules.d/70-persistent-net-rules
(一部省略)
# PCI device 0x1011:0x0019 (tulip)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:c0:f0:4c:e6:78", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth1"
 
# PCI device 0x10ec:0x8168 (r8169)
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="60:a4:4c:b5:26:48", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth0"


h@spice:~$ cat /etc/sysconfig/network-scripts/ifcfg-eth0
# Realtek Semiconductor Co., Ltd. RTL8111/8168B PCI Express Gigabit Ethernet controller (rev 09)
DEVICE=eth0
BOOTPROTO=none
HWADDR=60:a4:4c:b5:26:48
TYPE=Ethernet

(一部省略)

h@spice:~$  cat /etc/sysconfig/network-scripts/ifcfg-eth1
# Digital Equipment Corporation DECchip 21142/43 (rev 41)
DEVICE=eth1
HWADDR=00:c0:f0:4c:e6:78

TYPE=Ethernet
(一部省略)

h@spice:~$


明示的に「NAME=」が示されていないときは、eth0から順に名づけられるようだ。

さぁ、これで主要な問題は解決済だ。起動して24時間を過ぎて、今のところ新たな問題は見つかっていない。上手く行ったようだ。

2013年7月31日

AndroidでOpenVPNとVNCクライアントを走らせる

Barnes & NobleのNOOKというAndroidタブレットを買った。もともと同社のe-Readerとして開発・発売されたが、B&N社が電子本事業のビジネスモデルの見直しにあたって、Androidの一切の制約を外してGoogle Playの使えるフルのオープンな比較的安値($149)のAndoidタブレットになったので買ってみた。ちょうど配偶者が仕事先にタブレットを持って行きたがっていたので好機だという事情もあった。

配偶者の期待する主なタブレットの用途は現場での簡単な報告書作りだが、複雑なことは自宅でPCでじっくり行うとしても、表計算とかプレゼンテーションも将来的にはできるにこしたことはない。Android Market Placeを探すと数は少ないもののフルフィーチャーのオフィスツールスイートが売られているが、それらに飛びつく前に先ずはタブレットからVPNで自宅のLANに繋いでVCNでPCを操作できるようにしてみた。こうすれば外から自宅のPC上で編集や転送などのファイルの操作ができ、将来的にもインフラとして役立つと考えたから。ファイル転送に関してはDropBoxなどの商用クラウドを使う手もあるが、何時の間にかUIが変わっていたりとか、プライベートなファイルの運命を100%他人に委ねることは個人的にあまり好きではないので、商用クラウドも使ってはいるが限定的。こちらも半プロだからバックアップとかセキュリティとかにはかなりの労力を使っていて、今のところうまく行っている。

VPN経由のVCNによるLAN上のPCアクセスには次の4段階のネットワーク操作が必要。
  1. タブレットを現場のWiFiに接続
  2. ダイナミックDNSでタブレットの現在のグローバルIPアドレスからの接続を自宅のファイアウォールに許可させる
  3. ファイアウォールとの間でVPNを接続
  4. ターゲットのPCにVCNでアクセス
1)は言うまでもない。タブレットのWiFi機能を使う。

2)は我が家独特のセキュリティ強化のための動的なIPパケットフィルタリング。ここでは詳しくは触れない。

3)は商用サービスではなく、我が家でいろいろな外部ホストからのアクセスで実績・経験のあるOpenVPNを使って、ファイアウォールをVPNサーバに仕立てた。

4)のVNCで自宅のPCのデスクトップが操作できる。

OpenVPN

Android用OpenVPNのappは数種類出回っているが、ここではrootアクセスが不要なOpenVPN Connectを選ぶ。OpenVPN ConnectはP-t-P接続のtunインタフェースのクライアント専用で、*.ovpnというファイルから設定をインポートする。*.ovpnファイルは、OpenVPNの*.conf設定ファイルとほぼ同じだが、PEM形式の鍵や証明のデータをXML風のタグで内蔵している。

OpenVPNの鍵や証明データの生成方法は別項を参照。

クライアント側の*.confファイルタをブレット用にカスタマイズし、nook-vpn.confと名付ける。カスタマイズは基本的に以下の数ヶ所だけ。
  • サーバのアドレス(ドメイン名可)とポート番号
  • 鍵や証明ファイルのパス(相対パス可)

もしTLSを使う時は、
  • サーバ側:「tls-auth ta.key 0
  • クライアント側:「tls-client」「tls-auth ta.key 1
の行が存在しなければならない。実はこれがよく分からない。iOS(iPhone)のクライアントを使ったときはこれがあるとダメだった。もし接続がTLSエラーで拒否されるようなら、多少セキュリティが落ちるがサーバとクライアントの両方で「tls-auth」をコメントアウトすればよい。

もしTLSを使うなら、「方向」を合わせなければならない。通常はサーバ側は「0」すなわち入力側、クライアント側は「1」すなわち出力側とする。このとき、後で述べるようにclient.confからクライアントにインストールするclient.ovpnを生成とき、TLS(ta.key)を組み込むのと同時に
key-direction 1
と言う行を追加してクライアント側の方向を示さないとハンドシェークができない。

tunインタフェースしかサポートしていないので、複数のAndroidクライアントをサポートするにはクライアントの数だけ別のポート番号でサーバを動かさねばならず、少々面倒。さらに、ドキュメントでは不明な以下の問題がある。
  • サーバの*.confファイルに設定するVPNエンドポイントアドレスのネットマスクは最低でも255.255.255.248(/25)
  • サーバ側のVPNエンドポイントアドレスはccd/*の指定に関わらず常に一番小さいアドレス、すなわち上記で指定したネットアドレス+1
例えば、nook-server.conf
server 10.0.0.32 255.255.255.248
を指定すると
  • サーバは必ず10.0.0.33
  • クライアントは10.0.0.34~10.0.0.39のいずれか
になる。クライアント側も固定アドレスの方がうれしいので、ccd/nook-vpn
# Force client and server addresses
ifconfig-push 10.0.0.34 10.0.0.33
のように指定してやる。こちらのサイトではサーバとクライアントのアドレスが上記とは逆になるような設定を紹介しているが、我が家では動作しなかった。ただしこのサイトにリストされているtunのエンドポイントアドレスの組み合わせは守らねばならない。

 *.ovpnファイルは*.confファイルに鍵や証明データを取り込んで生成する。一々手でやるのは面倒なのでスクリプトを書いたので使ってください。
[root@gateway ~]# ls -F
conf2ovpn.sh*
[root@gateway ~]# cd /etc/openvpn/nook-server-keys
[root@gateway ~]# ls -F
01.pem  ca.key        nook-vpn.conf  nook-vpn.key   server.key
02.pem  conf2ovpn.sh* nook-vpn.crt  
server.crt     ta.key
ca.crt  dh1024.pem    nook-vpn.csr   server.csr

[root@gateway/etc/openvpn/nook-server-keys]# ./conf2ovpn.sh nook-vpn.conf >nook-vpn.ovpn

生成した*.ovpnファイルは、(マイクロ)SDカードにコピーし、タブレットに挿入する。タブレット上でOpenVPN Connectを起動し、メニュー(右上の八卦見のような「三」のようなアイコン)を開き、「SDカードからインポート」を選ぶ。デフォルトでは/sdcardディレクトリに飛ぶが、NOOKの場合/sdcardは内部SDカードに使用済みで挿入した外部SDカードは/mnt/ext_sdcardにマウントされる(Chromoでも同じことが起きたので、NOOK限ったことでないようだ)ので、ディレクトリを移動してから*.ovpnファイルを選択する。

と言うより、*.ovpnファイルをメイルの添付ファイルとしてタブレット自身に送り、添付ファイルを保存すると「SDカードからインポート」ですぐ見えるのでそこでインポートすればよい。またはタブレットをUSBでホストに接続して、一時的にUSBドライブとして見せて、そこで見えるタブレット側のディレクトリ(例えば「Download」)にコピーしてもよい。
 
後はサーバ側でOpenVPNを起動し、タブレット側のUIで簡単な設定をするとVPNが開通する。

ここで露見したのは、クライアント(Android)側がすべてのネットワークトラフィックをVPN経由にしてしまうらしいこと。つまり、まるっきりLANの中に入ったようになる。このままでは外のインターネットに接続できないので、サーバのiptablesのNATでVPNからの接続も外のインターネットに行けるようにする。すべてのトラフィックがVPNサーバ経由になるのでパフォーマンスが低下するが、クライアントのオプションを探しても他に解決手段が見つからなかった。

だから、OpenVPNに接続するのは必要な時だけにして、使い終わったら切断するように心がけなければならない。したがって、「Boot時に自動的に接続」のオプションは選んではいけない。

NOOK以外のタブレットによっては(例えばChromo)、tun.koカーネルモジュールがないと騒ぐが、慌てずPlayStoreに行って「TUN.KO Installer」をダウンロードして実行するとインストールされるはず、と思ったが、カーネルモジュールをインストールするためにはこのデバイスを「root」つまりスーパユーザの特権を得なければならず、rootのやり方はデバイスによってさまざまらしいので面倒くさくなってやめてしまった。

VNC

VNCもいくつかのappが出回ってるが、bVNC Freeを使って好結果を得た。こちらはOpenVPNと違ってインストールにあたっての特別なトリックは必要ないが、以下の二点で多少の時間を費やした。
 

DNS

OpenVPNの設定が悪いのか、タブレットからVPN(LAN内)のDNSが使えないので、VCNでアクセスするPCのIPアドレスを直接入力する必要があった。我が家のLAN上のホストは固定アドレスのDHCPにしているので大きな問題ではない。
 

日本語入力

タブレット側で日本語キーボードを使って入力したテキストは、VNCサーバ(PC)が受け付けない。VNC経由でリモートホストの日本語入力は、タブレット側ではデフォルトの英語キーボードのままにして、リモートのPC側の日本語入力機能を使い、タブレット上のローカルの日本語入力は日本語キーボードと使い分けが必要。タブレットの仮想キーボードでしか試していないが、近々入手する予定のBluetoothの外部キーボードでも同じと期待される。

VPNとVNCで最低限のことができるようになった。これから、AndroidのオフィススイートだとかDropBoxだとかのツールを少しづつ加えていくつもりだ。

2013年7月5日

DNSをオーバライドする(Windows)

我が家のインターネットファイアウォールはOpenVPNのサーバとして機能する。普段は仕事先のUbuntuのワークステーションから定常的にtunで接続しており、仕事先から家庭内のLANをアクセスしている。更に、WindowsのラップトップにもOpenVPNのクライアントをインストールしてあり、こちらはWindowsの仕様上tapインタフェースだが、旅行中に滞在先のホテルから家庭内のLANをアクセスするのに重宝している。例えば、旅行中に撮影した写真をラップトップにコピーすると、Genieというバックアップデーモンが自動的に我が家のバックアップサーバにバックアップを作成してくれるし、旅行中に使った金の記録もLAN上の家計簿用マシンに直接記録できる。

今フィリピンを旅行中で、最初のホテルではVPNで快適に家庭内LANをアクセスできていたのだが、二軒目のホテルでは最初の1時間ぐらいはよかったものの、突然動作がおかしくなってしまった。さてはWindowsお得意の要リブート状態かとリブートしてみたが復活しない。調べてみると、DNSに問題が発生していた。このホテルのネットワークはDOCOMO interTouchとやらなのだが、こいつのDNSサーバが特異な動作をしていることが分かった。

そもそも、VPNとは既存のTCP・UDPレイヤの上にIPをトンネリングさせる技術だが、通常DNSはベースつまりUDPを提供しているレイヤのDNSに優先権があり、ベースのDNSが解決できないとVPN上のDNSサーバに解決を委ねるようになっているらしい。だからウチのVPN-LANの場合、外からは見えないLAN内のドメインはベースすなわちホテルのLANのDNSサーバには解決できず、VPN上の我が家の内部DNSサーバにお鉢が廻ってLAN上のプライベートドメインが解決できるはずなのだ。

ところが、このDOCOMO interTouchのDNSサーバは、自分が解決できないドメインをすべて自分自身に解決してしまうようになっているらしい。つまり、ありとあらゆる、出鱈目なドメインを含むグローバルインターネット上に見えないドメインはニセのホストに解決されてしまう。理由はよくわからないが、多分マルウェアによる不正なリダイレクトを防ぐためではないかと想像する。この結果、VPN上の我が家のDNSサーバの出番はなくなり、結果的にVPNで接続された我が家のLAN上のドメインは実質解決できなくなってしまう。最初の1時間ほどが上手く行っていたのは、多分前日に宿泊したホテルで正常に解決できていたものがキャッシュに残っていたのだと思う。

このDOCOMO interTouchのDNSサーバの余計な振舞いを阻止するには、Windowsクライアント上に固定のhostsファイルを置くしかない。hostsファイルの在り処はUnix/Linuxなら/etc/hostsだが、Windowsでは%SystemRoot%\system32\drivers\etc\hostsで、通常はC:\Windows\system32\drivers\etc\hostsとなる。Windowsのhostsファイルの文法はUnix/Llinuxのそれとは異なり、「IPアドレス ホスト名」である。

取り敢えず必要なLAN上のホストをhostsファイルに書き込んでみたところ上手く行った。

今後LAN上のDNSに変更があるたびに一々手でWindowsクライアントのhostsファイルをアップデートするわけにもいかないので、cronで定期的に自動アップデートを実行、すなわち我が家のプライベートDNSの解決データをキャッシュするスクリプトを書こうと思ったが、このWindowsラップトップにインストールしてあるCygwinのsshdがdllファイルの一つが足りなくて動作しないことが分かった。Cygwinは個別のパッケージを管理するツールがないようで、setup.exeですべてをインストールし直し(あるいはすべてをアップデート)することになり、ホテルの低速インターネットで明日の朝までに完了するかどうかは分からない。