0.環境
CentOS 7 + Apache + Jupyter
(詳細なバージョンは覚えていないし,気にしなくてもいいと思います.多分この方法はCentOS 7でインストールできるバージョンで通用すると思う)
1.問題点
普通の場合,Jupyterは特定のポート番号(default 8888)をlistenして,Web BroswerにIP(あるいはドメイン)の後ろにそのポート番号を追加してアクセスするが.Jupyterをインターネットに公開したい場合,なるべくポート番号ではなく,jupyter.xxx.comのようなサブドメインとして公開したい.サブドメインを使うのが一般的ですし,そしてClientが学校,会社などでProxyを通じてインターネットをアクセスしている場合,使えるプロトコルのデフォルトポート以外のポートが制限されている可能性が高い.この場合,そのままポート番号で公開しても,Clientからアクセスできない.
2.解決方法
ApacheのReverseProxy機能を使って,Jupyterへのアクセスを全部Apacheに中継してもらう.こうすればApacheのVirtualHostの機能を使って,Jupyterをサブドメインとして公開できるうえ,Apacheの現存のVirtualHostと共存できる.
3.設定
まず,ApacheがReverseProxyとして他のプロセスと通信できるように,CentOSのSelinux Policyを変える(最初からSelinuxをOFFにした人はpass)
sudo setsebool -P httpd_can_network_connect true
Jupyterは8888ポートそのままlistenするようにして,jupyter側ではhttpsを設定しない.(Apacheにoff-loadするため)
Apache側のvhost設定
########################### ## Jupyter Notebook HTTP ## ########################### <VirtualHost *:80> ServerName jupyter.xxx.com ServerAdmin webmaster@xxx.com ErrorLog logs/jupyter-notebook-error.log # Possible values include: debug, info, notice, warn, error, crit, # alert, emerg. LogLevel warn CustomLog logs/jupyter-notebook-access.log combined RewriteEngine On RewriteCond %{HTTPS} off RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301] </VirtualHost> ############################ ## Jupyter Notebook HTTPS ## ############################ <VirtualHost _default_:443> ServerName jupyter.xxx.com ServerAdmin webmaster@xxx.com ProxyRequests Off ProxyPreserveHost On <Location /> ProxyPass http://localhost:8888/ ProxyPassReverse http://localhost:8888/ </Location> <Location /terminals/websocket/> ProxyPass ws://localhost:8888/terminals/websocket/ ProxyPassReverse ws://localhost:8888/terminals/websocket/ </Location> <LocationMatch /(api/kernels/[^/]+/channels.*)> ProxyPass ws://localhost:8888/$1 ProxyPassReverse ws://localhost:8888/$1 </LocationMatch> ErrorLog logs/jupyter-notebook-error.log LogLevel warn CustomLog logs/jupyter-notebook-access.log combined SSLEngine on SSLProtocol all -SSLv3 -TLSv1 SSLHonorCipherOrder on SSLCipherSuite HIGH:MEDIUM:!MD5:!RC4 SSLCertificateFile /etc/letsencrypt/live/xxx.com/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/xxx.com/privkey.pem BrowserMatch "MSIE [2-5]" \ nokeepalive ssl-unclean-shutdown \ downgrade-1.0 force-response-1.0 </VirtualHost>
この設定ではclient – apache 間の通信をcertbotで取った証明書を使ってHTTPS化し,apache – jupyter 間はHTTP通信を行う.
そして,clientがHTTPでアクセスしてきたらRewriteでHTTPSに強制リダイレクトさせる.JupyterのWeb Contentの取得には普通のHTTPプロトコルを使っているが,Kernelとの通信にHTTPのPostとWebsocket両方,Terminalとの通信にWebsocketを使っているので,Proxy設定は3つのLocationに分けて設定する必要がありました.
あとはfirewallの設定確認して(HTTP, HTTPSのデフォルトポート80, 443の開放),必要に応じてJupyterとApacheの設定を加えれば良いと思います.
設定の具体的な意味などはGoogle先生やApacheの公式Documentを参照すれば良いと思います.
4.参考
[1] Jupyter notebookをApache2によるプロキシ経由のリモートサーバで実行する
(この設定例ではterminalのwebsocketリダイレクト設定がなく,kernelへのリダイレクトをすべてwebsocketとして設定しているので,Jupyterのterminal機能とkernelのstop, restartが使えないことを確認しています)(kennelのstop, restartはwebsocketではなく,http postで実装されている,しかもwebsocketとhttp postのpathが結構混ざっているので,分離してほしいところですね)
ピンバック: Jupyter Notebook をLANの外から使うためのApacheの設定 | Yama's Memorandum