lua-nginx-moduleでヘッダ書き換え

# やりたいこと

ブラウザ　<-- http --> nginx(proxy) <-- https --> web

この場合、webサイトからcookieが送られて来たときに `secure` 属性が付いていると、ブラウザがcookieを保存してくれない。（本来httpsでしか送られてこないものがhttpで送られて来たのでブラウザ側で落としている？）
結果、ログインが必要なサイトが使えない。
ヘッダのSet-cookieが↓みたいな感じになっているので、ヘッダ書き換えて `secure` 属性落としたい。

```
Set-Cookie: xxxxxxxxx=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; path=/; secure; httponly
```

apacheのmod_headersなら結構楽にできるらしいけど、nginxでできないものかと調べてた時にlua-nginx-moduleを発見したのでこれを使ってみる。
[公式ドキュメント](https://www.nginx.com/resources/wiki/modules/lua/) 読むと、今回やりたいことは `header_filter_by_lua_block` で実現できそう。

# nginxインストール
luaモジュールを使うためにはnginxをソースからビルドしないといけないみたいです。めんどくさいですね。
今回はluaモジュールが使えるdocker imageを使うことにします。

```
$ docker pull firesh/nginx-lua
```

ソースからビルドする方法は公式のgithubに手順が書いてあるのでそちらを参考に
https://github.com/openresty/lua-nginx-module#installation

# dockerでnginxを動かす

```
$ mkdir　-p nginx/conf.d
$ vi nginx/nginx.conf
```
```nginx.conf
user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    proxy_buffer_size   128k;
    proxy_buffers   4 256k;
    proxy_busy_buffers_size   256k;

    log_format  main  ' -  [] "" '
                      '0  "" '
                      '"" ""';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}
```
```
$ vi nginx/conf.d/default.conf
```
```default.conf
server {
    listen       80;
    server_name  localhost;

    #charset koi8-r;
    #access_log  /var/log/nginx/host.access.log  main;

    location / {
        proxy_pass https://hogehoge.com; # proxyしたいwebサイトのURL

        header_filter_by_lua_block {
            local cookie = ngx.header["Set-Cookie"];
            if cookie and type (cookie) == "string" then
                cookie = string.gsub(cookie, "secure; ", "");
                ngx.header["Set-Cookie"] = cookie;
            end
        }
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}
```
```
$ vi Dockerfile
```
```Dockerfile
FROM firesh/nginx-lua
ADD nginx /etc/nginx
EXPOSE 80
```
```
$ docker build -t nginx-lua .
$ docker run -p 80:80 nginx-lua
```

これで `localhost` にアクセスすると `hogehoge.com` にプロキシしてくれるようになります。
パケットをみて `secure` 属性が落ちているか確認します。

```
$ sudo tcpdump -i any port 80 host localhost -A 
...
12:17:41.505396 IP 127.0.0.1.80 > 127.0.0.1.58811: Flags [P.], seq 1546:13748, ack 1310, win 10879, options [nop,nop,TS val 2075176958 ecr 2075176608], length 12202: HTTP: HTTP/1.1 200 OK
....E./...@.@............P.....v..=...*.-......
{...{...HTTP/1.1 200 OK
Server: nginx/1.10.2
Date: Sun, 04 Feb 2018 03:19:24 GMT
Content-Type: text/html; charset=UTF-8
Content-Length: 11341
Connection: keep-alive
X-Powered-By: PHP/5.4.45
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-cache, must-revalidate
Pragma: no-cache
Set-Cookie: xxxxxxxxx=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx; path=/; httponly ←書き換えに成功してsecure属性が落ちてる
Content-Security-Policy: default-src 'none';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self';connect-src 'self';media-src 'self'
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
X-Frame-Options: Sameorigin
X-Robots-Tag: none
X-Download-Options: noopen
X-Permitted-Cross-Domain-Policies: none
...
```

実際にログインが必要なサイトも使えるようになることが確認できました。

# まとめ
- lua-nginx-moduleはすごく使える
- でもソースからnginxビルドするのすごく面倒、luaモジュール入ってるdocker imageも常に最新版に追従している訳ではない
    - 趣味ならいいけど仕事で使う場合nginxのバージョンアップする時とか動作確認・テストめんどくさそう
- 誰かlua-nginx-module入ってるnginxのdocker imageのメンテナンス頼む（他力本願