ApacheのReverseProxyを使ってJupyterを公開する

投稿者: | 2018年6月3日

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が結構混ざっているので,分離してほしいところですね)

[2] Deploying behind a reverse proxy

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です