月: 2017年4月

個人用のインスタンスへ安全につなぐ

自分個人の作業用にも、GCEのインスタンスを作ってそこにアクセスして作業している。で、作業用の物体がウェブサーバであるということがよくある。たとえばjupyter notebookとか、R Studioとか。いま自分はeditbookというウェブベースのエディタで遊んでいるが、これもそういうやつ。開発環境的な操作をするもの以外でも、ダッシュボードの表示とかで一時的にウェブサーバを上げるってことはあると思う。

こういう連中は作業環境がローカルホストであることが前提になってるので、アクセス制限はたいていとくにかかってない(127.0.0.1にbindすることはよくあるが、それだと外部から繋げないのでアクセスを全開放することが多いだろう)。で、そうなると世界中の誰でもアクセスできて嫌だな、とちょっと思う。

実際にはephemeral IPのインスタンスなのでIPアドレスがピンポイントにバレることは少ないし、それだけで不安なら簡単なパスワード認証でも入れればいっか、ということはよくある。でもまあもうちょっとなんとかしたほうがいいのかな、という気分もある。

もちろん真面目に頑張るための方法はいくらでもあり、企業などきちんとできる環境ならきちんとすべきだろう。でもいまの自分のは個人用途なので、適当なサーバで頑張らずにそこそこマシにしたい。どうしたらいいだろう。

oauth2_proxy

oauth2_proxyはoauth2による認証だけを行うプロキシだ(openidじゃなくていいのかな? まあいいのかな……)。これによりアクセスしたユーザのメールアドレスがあらかじめ指定したやつだったときだけアクセスを許可できる。まあ似たようなのはほかにもあると思うが、こいつを自分用のサーバの手前に置いておくことで気軽にアクセスを制限できる。

ただeditbookはwebsocketを使っていて、oauth2_proxyはwebsocketがちゃんと動かなかったので困ったが、手元で適当なパッチを書いて動かしてみたら動いたのでなんとかなっている。たぶんそのうちPRを送ると思う。

gcloud dns

自分の使っているインスタンスは立ち上げるとIPアドレスが毎回変わるのでちょっと困る、という問題がある。第一に、Googleではoauth2用のコールバックアドレスはあらかじめ登録しておく必要があり、IPアドレスではうまくいかない。後述するようにhttpsでアクセスするためにもホスト名は持っておきたい。

一つの方法としては、固定IPのインスタンスにするという手がある。あるいはephemeralなIPでも、インスタンスを上げっぱなしにしておけばだいたいオッケーだったりするだろう。プロキシ用途に小さいインスタンスを上げておいてバックエンド設定をいじる手もある。

今回はもうちょっと別な技を使うことにした。Google Cloudにはgcloudというコマンドラインツールがあり(Amazonにもawsコマンドというのがありますが似たようなものです)、これを使ってDNS APIにアクセスできる。

またGCEインスタンスの情報(インスタンス名とか、external IPとか)というのはmetadataのAPIを使うと比較的簡単に取得できる。

なのでこの辺を組み合わせた適当なシェルスクリプトを書いて、gcloud dnsコマンドを発行して外部IPとホスト名を結びつけてみた。さらにこれを起動スクリプト化してみたので、インスタンスの起動時にホスト登録して終了時に登録解除もできるようになった。

Let’s Encrypt

ホスト名が定まったので、https接続にして通信経路を暗号化しておく。oauth2_proxyはTLSをサポートしているので認証鍵を作ればよく、いまではLet’s Encryptを使えば簡単に、かつ無料で暗号化ができる。いい時代になりましたね。

関連技術

Google CloudだとIdentity Aware Proxy(IAP)というものがあって、どうもこいつを設定したらよろしくやってくれる気配が感じられた。ただ金額的にもいろいろある機能的にも、ちょっと個人が雑に使うというものではない雰囲気が出てきている。企業とかが開発者向けの環境を考える場合には検討するといいと思う。

DNSまわりはGoogle Cloud限定の話だが、AmazonもRoute53があるしawsコマンドもあるので似たようなことができるはず。まあこんな変なことをしなくても楽にやる手は他にもあるはず。

プロキシについてはもっと便利で使いやすいやつがあるのかもしれないですがよく知りません。

まとめ

個人が自分一人で使う目的として、雑に立てたクラウド上のインスタンスへのウェブアクセスをどうマシにするか、というのをいくつかやってみた。まあまあのものはできたと思っています。