Hipchat Serverの添付ファイル領域にアクセスコントロールしてみた事例

この記事はリクルートライフスタイル Advent Calendar 2015[リクルートライフスタイル Advent Calendar 2015 - Qiita](http://qiita.com/advent-calendar/2015/recruitlifestyle) の５日目です。
ホットペッパービューティーで開発を担当している梶原成親です。
また並行して、リクルートライフスタイルの開発全体の生産性を向上させるための組織を立ち上げて、開発環境の整備も行っています。

# はじめに
私が入社した2014年には開発チーム内に公的なチャットシステムが無く、会社にChatサービスを導入すべく検討しておりました。　検討時に指摘された課題としては、添付ファイル領域にアクセスコントロール出来ないのが会社のレギュレーション上問題あることが指摘されておりました。
注：HipChatの添付ファイル領域はURLが分かれば、ユーザ認証しなくてもアクセスできる仕様です。

私の想いとしては、社外にいても社内と同等の環境を提供したかったため、通常のChatやファイルアップロードは、どこからでも利用できるが、添付ファイルのダウンロード、閲覧は社外からは利用できない仕組みを検討しました。

まずは、Atlassianの仕様を確認すると、、、
**Atlassianの正式な方法では**

* 添付ファイル機能を無効化する
* HipChatサービス自体を外部から接続させない。
* もしくはVPNを貼ることとなっておりました。

要件満たさないので、HipChat自体をカスタマイズする方法を考えました。


# HipChatにログインして方法を探ってみよう。
まずはSuper Userになります。
`sudo /bin/dont-blame-hipchat`

以下の発見をしました。

* 添付ファイル領域は以下の様な規則性がある。
* `https://<InstanceName>/files/hoge`
* HipChat Serverは、Nginxを使っていることを確認。

Nginxで制御すりゃできるっしょ。って、考えてた私はNginxのConfigurationを修正する事を考えました。

# 実験してみた。

**当然ながら、Atlassianがサポートしていない方式ですので、試される場合は自己責任でやって下さい。**

まずは、Configurationをチェック

```
admin@hipchat:/etc/nginx$ less /etc/nginx/nginx.conf
user www-data;
worker_processes  4;
daemon off;

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

events {
  worker_connections 2048;
}

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

  log_format custom '$remote_addr - $remote_user [$time_local]  '
                    '"$request" $status $body_bytes_sent '
                    '"$http_referer" "$http_user_agent" '
                    '"$http_x_forwarded_for" $http_x_forwarded_proto';
  access_log /var/log/nginx/access.log custom;

  server_tokens off;
  sendfile on;
  tcp_nopush on;
  tcp_nodelay on;

  keepalive_timeout 65;

  client_max_body_size 10m;

  gzip  on;
  gzip_http_version 1.0;
  gzip_comp_level 2;
  gzip_proxied any;
  gzip_types text/plain text/html text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript;

/etc/nginx/nginx.conf  proxy_buffers 8 16k;
  proxy_buffer_size 16k;

  server_names_hash_bucket_size 64;

  include /etc/nginx/conf.d/*.conf;
  include /etc/nginx/sites-enabled/*;
}
```

・・・何かIncludeされていて、ここで制御されていそうだ。
さらにIncludeされているファイルを見るなどして、最終的に以下のファイルに行き着きました。

```
vi /etc/nginx/includes/web-site
```

これに弊社の環境からAttachements領域にアクセスできるようにチョロチョロと関係ありそうな所に書いてみました。

```
# originial btf beta bucket
location ~ ^/Files/.+ {
  # for file access limitation
  allow XX.XX.XX.XX;
  deny all;

  rewrite ^(.*)/Files/(.*) $1/files/$2 permanent;
}

# 中略#

# Serve static files
location ^~ /files/*\.(jpg|jpeg|gif|css|png|js|ico|mp3|ogg|html|htm)$ {
  # for file access limitation
  allow XX.XX.XX.XX;
  deny all;

# btf s3 service cumulus: must use "~" as "location /files" will loop with the *.php match
# media files can render in browser:
location ~* ^/files(.*)\.(jpg|jpeg|gif|gifv|png)$ {
  # for file access limitation
  allow XX.XX.XX.XX;
  deny all;

# other fiels served up by cumulus are download-only
location ~ ^/files/(.+) {
  # for file access limitation
  allow XX.XX.XX.XX;
  deny all;

```

HipChat Service を再起動してみる。。。

動作を確認する。
　↓
外からでも添付ファイル領域にアクセスできる。　　
　↓
Configurationを見てみる。　
　↓
ん。。？　戻ってる。だとぉ。

調査をすると、HipChat Serviceを起動する時にChefが動作し、設定ファイルを戻すような動作をしているようです。
Chef recipeを覗きながら、どのファイルが起動時にキックされるChefで参照されているなど確認し、最終行き着いた以下のファイルを編集すると想定してた動作ができるようになりました！

```
/mnt/hipchat-scm/chef-repo/cookbooks/nginx/templates/default/web-site-btf.include.erb
```


その後、運用を半年弱しておりますが、今のところトラブルは発生しておりません。


ただし、将来に渡ってもこの方法が適用できる保証は何もありません。　HipChat Serverのバージョンアップも頻繁にありますしね。　こんなやり方もあるよ。という事例として何かの参考になれば幸いです。


梶原成親 @kajinari
(Atlassian User Group Tokyo Organizer)