このタイトルには語弊があるので先に訂正しておくと、ウェルノウンポートを握れないわけではありません。しかし、それには特権ユーザーにてVirtualBoxを実行する必要があります。その理由を書いていきます。
事の背景はmacOS上でVirtualBoxを実行し、VM(Ubuntu18.04)上で動いているWebサーバ(Dockerコンテナ)に80番と443番をポートフォワーディングしようとしたことでした。通信経路は以下のようになると思います。
インターネット -> macOS -> VirtualBox -> Webサーバ
環境構築はPackerで行い、吐き出されたovaファイルをVitualBoxでインポートして実行してみた所、Webサーバにアクセスできません。VM内でcurlをlocalhost宛に叩いたらちゃんとDockerコンテナのWebサーバからレスポンスは返ってきます。しかし、macOS上でcurlをlocalhost向けに叩いてもConnection refused
でレスポンスがありません。ポートフォワーディング自体はちゃんと機能していて、プロビジョニング時に以下のようなコマンドを実行しています。
VBoxManage controlvm "vm-name" natpf1 "SSH,tcp,127.0.0.1,2222,,22"
VBoxManage controlvm "vm-name" natpf1 "HTTP,tcp,,80,,80"
VBoxManage controlvm "vm-name" natpf1 "HTTPS,tcp,,443,,443"
実際SSHはちゃんと機能しますし、VirtualBoxのUI上でもこの設定は反映されています。設定を全て削除し、UI上で設定を試みてみましたが、特にエラーが出ることもなく設定は完了するにもかかわらず、やはりアクセスすることが出来ません。VMのファイアウォールが閉じているわけでもありませんでした。lsof
コマンドで確認した所、SSHのポートは取れているのに80番と443番は取れていませんでした。
数時間粘ってわからなかったので、先生に聞いてみた所、小一時間悩んで解決しました。
「ウェルノウンポートは特権ユーザーじゃないと握れないよ」
最初、自分の状況説明を受けて先生がわからなかったのはVirtualBoxのポートフォワーディングがipchains
で行われていると考られたからのようです。ポートフォワーディング自体はこちらの方が速いそうです。
なぜウェルノウンポートは特権ユーザーしか握れないのか、その理由は他人のサーバをすり替えることが出来てしまうからです。 例えばユーザーAとユーザーBがいるVM上で、ユーザーAがWebサーバを建てていたとします。この状態で通常ユーザーでもウェルノウンポートを握れてしまうとどうなるかというと、ユーザーBがDoS攻撃などでユーザーAのWebサーバを一時的にでも落としてしまえば、その瞬間に自分のWebサーバを上げることが可能になってしまいます。これを防ぐためにUnix系OSでは一般的に特権ユーザーでないと0-1023番のウェルノウンポートを取れないようにしています。
従って、VirtualBoxを特権ユーザーで実行すれば可能でした。しかし、sudo open /Applications/VirtualBox.app
では駄目なようで、sudo /Applications/VirtualBox.app/Contents/MacOS/VirtualBox
のようにバイナリを直接実行しなければいけないようです。ちなみにUIを開かなくて良いのなら以下のようにしてVMのインポートとスタートを行うことが可能です。
sudo VBoxManage import vm-name.ova
sudo VBoxManage startvm vm-name
これで実行すれば80番や443番にアクセスすることが可能になりました。
Docker Desktopなどはインストールする時に特権許可を求められますけどVirtualBoxはそんなことはありません。特権なしにポートフォワーディングしようとするとipchains
は使えないのでポートを握るしかありません。逆に言えば、特権を持っていなくても仮想マシンを実行できるということです。この利点でもあり欠点でもある特徴が今回自分を悩ませました。
ちなみに先生曰く、特権を握らずにポートフォワーディングする方法もあるそうで、
このようにすれば特権を取らなくても可能です。ちょっと冗長になるので今回はsudo
で行いますが、macOSであればデフォルトでApacheやSSHが入ってますし、これも良いかもしれません。
一番悪いのはポートを取れないくせに設定の際に何も言わないVirtualBoxですけどね!!
参考