この記事では、SSH使うから認証は後回しで、って書いてたんだけど、それじゃあChromebookで気軽にお遊びができないことに気づいたので、結局SSL化と認証を追加した。
ドメイン取得&SSL化
certbot(Let's encrypt)を使うには、TXTレコードやCNAMEレコードをイジる必要があるので、しぶしぶ c9work.net というドメインを購入。(胡散臭いキャンペーンとか嫌いなので、AWS経由で購入した)
証明書の取得は
にあるように、certbotで行う。
- Cloud9 IDEを表示するURL(hogehoge.ide.c9work.net)
- 成果物を誰かに見せる用のURL(hogehoge.preview.c9work.net)
- 認証用その他もろもろのページのURL(auth.c9work.net, page.c9work.net, ...)
の3つを想定していたので、雑にワイルドカード証明書を3つ。
sudo certbot certonly --manual --manual-public-ip-logging-ok -d *.preview.c9work.net -m ore_ore@yahoo.co.jp sudo certbot certonly --manual --manual-public-ip-logging-ok -d *.ide.c9work.net -m ore_ore@yahoo.co.jp sudo certbot certonly --manual --manual-public-ip-logging-ok -d *.c9work.net -m ore_ore@yahoo.co.jp
みたいな感じで。
都度、TXTレコードに確認用文字列を入れる、みたいなことはやる必要があったけど、そこはRoute53なりAzure DNSなりで管理してたらなんの問題もなくいける。
無事にHTTPS化 pic.twitter.com/dc5gD3CXZ5
— Yusuke Iwaki (@yi01imagination) 2019年7月16日
前段にGitHub認証を入れる
これが結構つまった。(ひとえに、nginxのAuth Requestを知らなかったからなんだけどw)
SSL化をした時点で、
なんとなくこんな感じに、nginx二段構えにしていた。なので、認証はとりあえずSSLオフロードをやってる前段のnginxに何かしらやればいいんだろうなーと。Cloud9 SDK自身も、なんとなく認証っぽい仕組みは内部で持っていそう( core/auth.js at master · c9/core · GitHub )だったんだけど、SSLオフロードした先に認証機構があるのはちょっと筋が悪い気がした、なのでnginxかその前段に持たせようかなと。
んで、CW社の偉大なる同期が昔書いていた記事も参考に、
これはとりあえずoauth2_proxyをAuth Requestと組み合わせて使えばラクかなと。
認証エンドポイントと認証した先に戻るURLでドメインが違うのをなんとかする
手っ取り早くウェブアプリケーションにOAuth2認証を導入する - その手の平は尻もつかめるさ あたりを参考にするとわかりやすいんだけど、oauth2_proxyは /oauth2/start?rd=/return_back_to/this/address
のようにパスを渡すと、認証完了後に /return_back_to/this/address
に帰ってきてくれる。
今回の場合は、
- https://hogehoge.ide.c9work.net/ にアクセス
- http://oauth2_proxy:4180/auth にAuth Requestした結果401が返る
- https://auth.c9work.net/oauth2/start?rd=hogehoge.ide.c9work.net/ にリダイレクトすれば、認証後にhogehoge.ide.c9work.net に戻ってきてくれるかな?
と想像していた。が、現実はそうはいかず。 https://auth.c9work.net/ にリダイレクトされてしまった。
oauth2_proxyのソースをみたら、「あーー」ってなんたんだけど
redirect = req.Form.Get("rd") if !p.IsValidRedirect(redirect) { redirect = req.URL.Path if strings.HasPrefix(redirect, p.ProxyPrefix) { redirect = "/" } }
をチェックして、NGだったら強制的に /
に書き換えられてしまっているではありませんかー!
OAUTH2_PROXY_EMAIL_DOMAINS に .ide.c9work.net
を設定すると解決。
GitHubユーザをYusukeIwakiに限定する
これも結構ハマった。
本当は前段の認証側でどうにかしたかったんだけど、nginx.confの記述方法わからなすぎたので、
- 前段の認証ではGitHubユーザだったらとりあえず通すようにする
- バックに居るコンテナ振り分けをやるnginxのほうで、GitHubユーザ名が
YusukeIwaki
じゃなかったら強制的に403を返すようにする
という雑な方法で実現。
location / { auth_request /oauth2/auth; error_page 401 = /oauth2/start?rd=https:///$host$request_url; proxy_set_header X-Forwarded-Scheme $http_x_forwarded_proto; proxy_set_header Host $host; auth_request_set $user $upstream_http_x_auth_request_user; # ←認証完了時に、oauth_proxy2 がX-Auth-Request-UserヘッダにGitHubユーザ名をセットしてくれるのを拾う。 proxy_set_header X-Remote-Username $user; # ←nginx_backにリクエストをプロキシするときに、 X-Remote-Usernameというカスタムヘッダを付ける proxy_pass http://nginx_back:8888; }
server { listen 8888; (中略) if ($http_x_remote_username != 'YusukeIwaki') { return 403; }
たぶんもっといいやり方はあるんだろうなぁ...。
そんなわけで
oauth2_proxyを使ってIP制限を外した。https://t.co/fiVbvNDmPv
— Yusuke Iwaki (@yi01imagination) 2019年7月20日
Chromebookでも開発をできるようになった。
うぇいうぇい