この物語は、仮想化技術を学びたいがためにkvmで構築をしてみたはいいものの、構築した仮想環境にMBPから楽にSSHできたらいいよね? と気軽に考え、悶え苦しみながらネットワーク構築まですることになった壮絶な物語である。
登場するもの
PR-400-KI(192.168.1.1)
NTTのおっちゃんが連れてきた。こいつのお陰でインターネットに繋げることができる。
管理画面の説明がよくわからないので、なんだか難しいやつだ。
BUFFALOルーター(192.168.11.1)
Amazonからお迎えした。とりあえずAmazonでルーターと検索したら最初にこいつがでてきた。
管理画面にはたくさんの機能があるように見えるが、設定をするとしばらくいうことを効かなくなる。
MacBookPro(192.168.11.X)
普段使ってるマックブック。BUFFALO経由でWIFI通信してる。
HP自鯖(192.168.122.1, 192.168.1.12)
中古PCサイトからお迎えした自鯖。1万5千という値段でKVMが動く。
HP自鯖のお迎え
KVMでサーバーを動かすには Intel-VT 対応のCPUでなくてはいけないという情報を入手した私は、中古PCサイトでIntel-VT対応しているPCを探していたが、対応していて低価格なPCはほとんどなかった。
いろいろと探していてもやはり3万Over・・どうにか1万5千円ほどで変えるものはないかと探していたら、iosysというところに安くてKVMが動くPCが売ってあるとHangoutsで教えてもらい、早速購入。メモリも増設した。
入っていたWindowsを削除し、Ubuntu Serverをインストールしkvmもしっかりと起動した。コア数が少ないので(Core 2 Duo)一度に起動できる仮想マシンは5マシンが限界だった。
自鯖サイトを外部公開
せっかく自鯖買ったし、仮想環境も構築したのだから仮想環境に建てたサーバーを外部公開したいと考えた。
しかし現実はそこまで優しくなかった。iptablesの設定を行い、外のパケットを内へと転送しなくてはならないからだ。ubuntuはiptablesラッパーとしてデフォルトとして推奨されているファイアウォールが、ufwであるため、ufwを設定すれば転送設定できるのかと思っていた。
設定をするには /etc/ufw/before.rules を弄るしかなかった。PREROUTINGやPOSTROUTINGの設定を行う必要がある。そしてそのたびに、ubuntuを再起動するしかなかった(と思い込んでいた)
ubuntuを再起動すると、一緒にubuntuの中にあるkvmの仮想化されたマシンも再起動がかかってしまう。だからただの再起動以上に余計に時間がかかってしまっていた。何度も、何度も再起動を行った。
そしてついに仮想化されたサーバーは外部へ公開されたのだった。
この時にはiptablesコマンドで設定を削除したり追加したりすれば別に再起動はいらないこと気づいてなどはいなかった・・・。
再起動すると繋がらない
不思議なことが起きた。ubuntuを再起動すると、仮想化サーバー内に立ち上げたHTTPサーバーに接続できなくなってしまうことがあった。なぜ繋がらないのか調べてみると原因はiptablesではなく、kvmが原因だった。ubuntu再起動時にvirbr1という仮想ブリッジネットワークが作られる。それと同時にこのネットワークへの転送を禁止するルールがiptablesに追加されてしまう。
今のところ、iptablesへ自動的にルールが追加されることをやめる方法は見つけられていないので、手動でルールを削除することにした。ルールさえ削除してしまえは外部からの通信が可能になる。そしてこのとき、iptabelsを書き換えることに再起動がいらないということに知ったのだ・・。
MBPから直接仮想サーバーへ接続したい
これまで仮想サーバーにアクセスするには、一旦HP自鯖へSSHを行い、そこから更にSSHで仮想サーバーへ接続していた。
MBPはBUFFALOルーターから更にPR-400-KIルーターへ接続しているが、PR-400-KIが、仮想サーバーがあるセグメント192.168.122.Xというセグメントを知らない。そのため、PR-400-KIの管理画面を開き、静的ルーティング設定で192.168.122.1というゲートウェイを追加した。実際には、IPアドレスが192.168.122.0/24でゲートウェイは自宅サーバーのIPアドレスを設定した。
まだ繋がらない
しかし、そう簡単にはいかない。iptablesでパケットの転送量を調べつつコマンドを連打しても、パケットはちゃんと転送されているように見える。pingも通る。それでも通信ができなかった。何度も試したが、土日を4日分費やした。
しばらくした後、ネットで色々と調べていると「tcpdump icmp」というコマンドを知った。
このコマンドはtcpのパケットキャプチャでicmpのパケットのみを表示してくれる。このコマンドを自鯖と仮想サーバー両方に仕掛け、pingを打ってみた。しかし、pingはちゃんと疎遠している。今度はcurlでhttpパケットを送ってみた。
なんと、リクエストは受けられたがそのパケットを送り返すことに失敗していた。まさか・・。
PR-400-KIのping機能
そういえば、PR-400-KIにもping通信機能があることを忘れていた。PR-400-KIからMBPとHP自鯖の仮想マシンへpingを送ることにした。実際にやってみると、HP自鯖の仮想マシンにはpingが通るが、MBPへはpingが通らなかった。
実は、仮想マシンからMBPへ向けて送ったはずのpingはMBPが返したものではなく違う端末が返してMBPへ通信ができると勘違いしてしまっていたようだった。
となると、問題の原因は絞られる。PR-400-KIからMBPにある間のBUFFALOルーターの間のルーティングがうまくいっていないということなのだから、PR-400-KIのルーティングテーブルにMBPが属しているサブネットを定義し、PR-400-Kからpingを行うと無事に疎通したのだった。試しに、BUFFALOルーターからもpingを送っても無事に成功した。
そしてついに・・
MBPから直接HP自鯖の仮想マシンに接続することに成功した・・・。
長かった。とても長かった・・・。
まとめ
- ルーターのping機能大事
- スタティックテーブル大事
- ping とlsof -i と netstat -r と arp -a と traceroute 大事
- 行きが良くても帰りも大事
- 行きと帰りの経路が正しい道のりかも大事
- ゲートウェイ大事
- フォワードポリシー大事