Cntlmでsbtのプロキシ設定を解決する

proxy環境下だとsbtの依存ライブラリがエラーでダウンロードできない。

周りのscalaおじさんに相談してみたら、どうやらsbtのssh周りのライブラリが古くてユーザ認証できないらしく、解決策は「プロキシを経由しない」、「手動でダウンロードする」、「プロキシにcntlmを挟む」だったのでcntlmの導入を行う。

## 問題
`build.sbt`に依存ライブラリを追加して`sbt compile`でエラーが出る。

```sbt:build.sbt
name := "tools"
version := "0.1"
scalaVersion := "2.12.7"
libraryDependencies += "org.apache.commons" % "commons-io" % "1.3.2"
```

`$ sbt compile`

```terminal
[error] (update) sbt.librarymanagement.ResolveException:
 unresolved dependency: org.apache.commons#commons-io;1.3.2:
  public: unable to get resource for org/apache/commons#commons-io;1.3.2:
   res=https://repo1.maven.org/maven2/org/apache/commons/commons-io/1.3.2/commons-io-1.3.2.pom:
    java.io.IOException: Failed to authenticate with proxy
```

この現象を解決する。

## Cntlmの導入
### インストール
homebrewからインストールできるのでちょちょいとインストール。

```terminal
$ brew install cntlm
==> Downloading https://homebrew.bintray.com/bottles/cntlm-0.92.3.high_sierra.bottle.1.tar.gz
######################################################################## 100.0%
==> Pouring cntlm-0.92.3.high_sierra.bottle.1.tar.gz
==> Caveats
Edit /usr/local/etc/cntlm.conf to configure Cntlm

To have launchd start cntlm now and restart at startup:
  sudo brew services start cntlm
==> Summary
🍺  /usr/local/Cellar/cntlm/0.92.3: 9 files, 144.6KB

$ cntlm -h
CNTLM - Accelerating NTLM Authentication Proxy version 0.92.3
Copyright (c) 2oo7-2o1o David Kubicek
```

### conf設定
エディタで設定ファイル`/usr/local/etc/cntlm.conf`にプロキシ情報を設定する。

```conf:cntlm.conf
Username        username
Domain          DOMAIN
#Password        hogehoge
PassLM          hogehogehash
PassNT          hogehogehash
PassNTLMv2      hogehogehash
Proxy           hogehoge.proxy.com:8080
NoProxy         localhost, 127.0.0.*, 10.*, 192.168.*
Listen          3128
```

パスワードはハッシュ化したものを設定できるのでご参考まで。

```
$ cntlm -H
Password:
PassLM          hogehogehash
PassNT          hogehogehash
PassNTLMv2      hogehogehash    # Only for user 'username', domain 'DOMAIN'
```

とりあえず`-f`オプションを付けてforegroundで起動してみる。

```terminal
$ cntlm -f
Oct 30 16:01:55  cntlm[12551] <Info>: Cntlm ready, staying in the foreground
```

この状態でプロキシの宛先を`127.0.0.1:3128`にするとcntlm経由でプロキシに接続できる。
> `brew services`に登録する前には停止してください。
> プロセスが残ってる場合は殺すこと。

```terminal
$ ps x | grep cntlm
15778 ?? S 0:00.44 cntlm -f
$ kill -9 15778
```

### brew servicesに登録
cntlmを自動起動するために`brew services`に登録します。

登録したサービスはデーモンプロセスとして起動します。

```terminal
$ brew services start cntlm
```

登録されてるサービスを一覧。

```termianl
$ brew services list
Name  Status  User       Plist
cntlm started hogehoge /Users/hogehoge/Library/LaunchAgents/homebrew.mxcl.cntlm.plist
```

サービスを停止するとき。

```terminal
brew services stop cntlm
```

## proxy設定
プロキシの宛先をローカルホストに切り替える。

### sbt
ホームに`.sbtconfig`ファイルを作成してjavaの起動オプションにプロキシ設定を追記する。

```sbtconfig:.sbtconfig
export JAVA_OPTS="$JAVA_OPTS -Dhttp.proxyHost=127.0.0.1 -Dhttp.proxyPort=3128 -Dhttps.proxyHost=127.0.0.1 -Dhttps.proxyPort=3128"
```

### IntelliJ
IntelliJ単体でも設定可能。sbtに設定していればこちらの設定は不要。

`環境設定` > `ビルド、実行、デプロイ` > `ビルド・ツール` > `sbt`  
`JVM`のVMパラメータにプロキシ設定を追加。

```properties
-Dhttp.proxyHost=127.0.0.1
-Dhttp.proxyPort=3128
-Dhttps.proxyHost=127.0.0.1
-Dhttps.proxyPort=3128
```

# まとめ
sbtから依存ライブラリがダウンロードできるようになった！

ユーザやパスワードの定義先が`cntlm`に集約できるので、パスワードが変わっても1箇所だけの修正でよくなるし、パスワードもハッシュ化できてリスクも減らせるのでオススメです。