Bitwardenで自分専用パスワードマネージャーサーバー構築

Qiita では初の [Bitwarden](https://bitwarden.com/) 記事っぽい :v:

パスワードマネージャーサービスは有償、無償でいくつかありますが [1password.com](https://1password.com/) がメジャーどころでしょうか。家族プランがあって良さげです。
エンタープライズでは [evidian](https://www.evidian.com/ja/) とかありますね。

パスワードの使い回しで多くの人が被害にあっている昨今ではこういったツールは欠かせません。私は今のところ [keepass](https://keepass.info/) + [dropbox](https://www.dropbox.com/) でデバイスまたぎで使ってます。1password の家族プランで家族全体を守りたいなと思ってるところ。

さて、この記事では有償だろうと知らない人にパスワードは預けられないぜという方のために [Bitwarden](https://bitwarden.com/) を使って自分専用パスワードマネージャーサーバーを構築してみたいと思います。でもそんな場合はソースコードもくまなくチェックですよね...
Bitwarden も無料のサービスとして提供されてるので普通の人はそれを。

> Since all of your data is fully encrypted before it ever leaves your device, only you have access to it. Not even the team at bitwarden can read your data, even if we wanted to. Your data is sealed with [end-to-end AES-256 bit encryption](https://en.wikipedia.org/wiki/End-to-end_encryption), [salted hashing](https://en.wikipedia.org/wiki/Cryptographic_hash_function), and [PBKDF2 SHA-256](https://en.wikipedia.org/wiki/PBKDF2)

試す前は GCP の永久無料サーバー f1-micro で使えたりするんだろうか？と淡い期待を抱いていたのですが最低2GBメモリが必要だよって書いてありました...
さらに、なんと .NET と SQLServer という組み合わせ... 触ったことないぞ :open_mouth:

.NET も SQLServer もまったくわかりませんが https://help.bitwarden.com/article/install-on-premise/ に書いてあるとおりにすればきっとできるはず。
幸いにも時代は Docker です。docker さえ使えれば大丈夫。[.NET](https://hub.docker.com/r/microsoft/dotnet/) も [SQL Server](https://hub.docker.com/r/microsoft/mssql-server-linux/) も Linux で動く :thumbsup:

あ、Let's Encrypt の証明書で https 対応するのでドメインが必要です

# SYSTEM REQUIREMENTS

```
CPU: Dual core @ 2GHz or faster
Memory: 2GB of RAM or more
Storage: 10GB or more
Docker: Engine 1.8+ and Compose 1.17.1+
```

# Docker の使えるサーバーの準備

DigitalOcean で 4GB メモリのインスタンスを使いました（doctl 便利）。

```
doctl compute droplet create testsv01 \
  --image docker-16-04 \
  --region sgp1 \
  --size 4gb \
  --ssh-keys 12345678
```

DigitalOcean は最初は root でログインすることになるので以降の手順では sudo とか出てきません

DNS 設定はそれぞれの DNS サーバーの手順で。

# セットアップ

## まずはセットアップ用スクリプトのダウンロード

```
curl -s -o bitwarden.sh \
    https://raw.githubusercontent.com/bitwarden/core/master/scripts/bitwarden.sh \
    && chmod u+x bitwarden.sh
```

## インストーラ実行

```
./bitwarden.sh install
```

後は聞かれたことに答えていけば大丈夫。スクリプトの置かれたディレクトリに `bwdata` というサブディレクトリが作成され、これからの設定情報は全部その配下に保存されます

### 証明書取得

まずはこの質問、ドメインと Let's Encrypt 用のメールアドレスさえ指定すれば証明書取得は自動でやってくれます。AMCE の http-01 なのでもちろん Let'e Encrypt サーバー側からアクセスできるとことに無いとダメです。EV 証明書持ってるからそれを使いたいんだよという場合は `n` を選択してファイルを指定の場所に配置します

```
(!) Enter the domain name for your bitwarden instance (ex. bitwarden.company.com):
(!) Do you want to use Let's Encrypt to generate a free SSL certificate? (y/n):
(!) Enter your email address (Let's Encrypt will send you certificate expiration reminders):
```

[certbot/certbot](https://hub.docker.com/r/certbot/certbot/) docker image を使って http-01 で Let's Encrypt の証明書が取得され `bwdata/letsencrypt` 配下にもろもろ保存されます

### installation id 設定

```
(!) Enter your installation id (get it at https://bitwarden.com/host): 
(!) Enter your installation key: 
```

[https://bitwarden.com/host](https://bitwarden.com/host) で installtion id, installlation key を取得する必要があります

![Hosting Installation Id and Key bitwarden.png](https://qiita-image-store.s3.amazonaws.com/0/8739/22ca2bd6-242d-1c3d-969d-3a8cb3f73258.png)


> You should use a unique id and key for each bitwarden installation

と書かれています。メールアドレス入力して Submit したら id と key が表示されます

ライセンスの必要な機能があるからかな

### Network と Push 通知の設定

Network 設定は環境に合わせて選んでください。Push 通知を使えばスマホアプリなどへ通知してすぐに同期されるようにできるみたいです。サーバーから https://push.bitwarden.com へアクセス出来る必要があります。

```
(!) Do you want to use the default ports for HTTP (80) and HTTPS (443)? (y/n): 
(!) Is your installation behind a reverse proxy? (y/n): 
(!) Do you want to use push notifications? (y/n): 
```

これに答えたら

```
Building nginx config.
Building docker environment files.
Building docker environment override files.
Building app settings.
Building FIDO U2F app id.
Building docker-compose.yml.

Setup complete
```

Setup complete!! :grinning:

あっという間です

## 環境変数設定

終わりかと思ったのですがもうちょっと設定がありました
`bwdata/env/global.override.env` の環境変数を環境に合わせて書き換えます

書き換えるのはこのあたり

```
globalSettings__yubico__clientId=REPLACE
globalSettings__yubico__key=REPLACE
globalSettings__mail__replyToEmail=no-reply@example.com
globalSettings__mail__smtp__host=REPLACE
globalSettings__mail__smtp__username=REPLACE
globalSettings__mail__smtp__password=REPLACE
globalSettings__mail__smtp__ssl=true
globalSettings__mail__smtp__port=587
globalSettings__mail__smtp__useDefaultCredentials=false
globalSettings__disableUserRegistration=false
```

同じディレクトリに `bwdata/env/mssql.override.env` というファイルもあり、これには SQL Server のパスワードなどが書かれています


# 起動

設定は完了したので後は起動するだけ（のはず）

```
./bitwarden.sh start
```

```
(省略)
Creating network "docker_default" with the default driver
Creating nginx ...
Creating web ...
Creating attachments ...
Creating api ...
Creating icons ...
Creating nginx
Creating attachments
Creating identity ...
Creating api
Creating web
Creating mssql ...
Creating icons
Creating mssql
Creating mssql ... done
Total reclaimed space: 0B
1.15.1: Pulling from bitwarden/setup
Digest: sha256:9d4fd9ea670b2ee84eeb19278d6a80bee10f5a50796b3a5f11af1dbdd4b052cf
Status: Image is up to date for bitwarden/setup:1.15.1

bitwarden is up and running!
===================================================

visit https://warden.example.com
to update, run './bitwarden.sh updateself' and then './bitwarden.sh update'
```

更新も簡単にできそうな感じ

`docker ps` すると次のようになってます

`nginx` --> `web` --> `api` --> `mssql` っぽいかな

```
# docker ps
CONTAINER ID        IMAGE                          COMMAND             CREATED             STATUS              PORTS                                      NAMES
d53c1771b26d        bitwarden/mssql:1.15.1         "/entrypoint.sh"    2 hours ago         Up 2 hours          1433/tcp                                   mssql
aced30eab718        bitwarden/web:1.21.0           "/entrypoint.sh"    2 hours ago         Up 2 hours          80/tcp                                     web
4b1cb2705ed3        bitwarden/icons:1.15.1         "/entrypoint.sh"    2 hours ago         Up 2 hours          80/tcp                                     icons
fd6f0a7ceffe        bitwarden/api:1.15.1           "/entrypoint.sh"    2 hours ago         Up 2 hours          80/tcp                                     api
da0f0d6bd5d9        bitwarden/identity:1.15.1      "/entrypoint.sh"    2 hours ago         Up 2 hours          80/tcp                                     identity
335623ec380f        bitwarden/attachments:1.15.1   "/entrypoint.sh"    2 hours ago         Up 2 hours          80/tcp                                     attachments
bfda1f95a168        bitwarden/nginx:1.15.1         "/entrypoint.sh"    2 hours ago         Up 2 hours          0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp   nginx
```


## ブラウザでアクセスしてみる

![Log In bitwarden Web Vault.png](https://qiita-image-store.s3.amazonaws.com/0/8739/fcab9f10-8805-a80a-8f0a-9fb6d9ad0d0f.png)

動いてる！！

まずは「Create a new account」からアカウントを作成します

![Register bitwarden Web Vault.png](https://qiita-image-store.s3.amazonaws.com/0/8739/c9145fa4-34b5-5aab-1a5e-610bd7fc5da2.png)

が、ここでエラーが発生。作成に失敗しました。

`docker logs api` とか `docker logs mssql` とかしてログをあさってみると、`vault` という名前のデータベースに接続できないらしいことがわかりました

SQL Server に接続してみると...

```
# docker exec -it mssql /opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P パスワード
1> select name from sys.databases;
2> go
name
--------------------------------------------------------------------------------------------------------------------------------
master
tempdb
model
msdb

(4 rows affected)
```

`vault` なんてデータベースは存在しない...
（パスワードは先に書いたように `bwdata/env/mssql.override.env` にあります）

`bitwarden.sh` や `bwdata/scripts/run.sh` を眺めてみると `updatedb` ってのを実行すればなんかできそうな気がする

```
# ./bitwarden.sh updatedb
 _     _ _                         _
| |__ (_) |___      ____ _ _ __ __| | ___ _ __
| '_ \| | __\ \ /\ / / _` | '__/ _` |/ _ \ '_ \
| |_) | | |_ \ V  V / (_| | | | (_| |  __/ | | |
|_.__/|_|\__| \_/\_/ \__,_|_|  \__,_|\___|_| |_|

Open source password management solutions
Copyright 2015-2017, 8bit Solutions LLC
https://bitwarden.com, https://github.com/bitwarden

===================================================

Docker version 17.09.0-ce, build afdb6d4
docker-compose version 1.13.0, build 1719ceb

1.15.1: Pulling from bitwarden/setup
Digest: sha256:9d4fd9ea670b2ee84eeb19278d6a80bee10f5a50796b3a5f11af1dbdd4b052cf
Status: Image is up to date for bitwarden/setup:1.15.1
Migrating database.
Beginning transaction
Beginning database upgrade
Fetching list of already executed scripts.
The [dbo].[Migration] table could not be found. The database is assumed to be at version 0.
Executing SQL Server script 'Bit.Setup.DbScripts.2017-08-19_00_InitialSetup.sql'
Creating the [dbo].[Migration] table
The [dbo].[Migration] table has been created
Executing SQL Server script 'Bit.Setup.DbScripts.2017-08-22_00_LicenseCheckScripts.sql'
Executing SQL Server script 'Bit.Setup.DbScripts.2017-08-30_00_CollectionWriteOnly.sql'
Executing SQL Server script 'Bit.Setup.DbScripts.2017-09-06_00_CipherDetails.sql'
Executing SQL Server script 'Bit.Setup.DbScripts.2017-09-08_00_OrgUserCounts.sql'
Executing SQL Server script 'Bit.Setup.DbScripts.2017-10-25_00_OrgUserUpdates.sql'
Executing SQL Server script 'Bit.Setup.DbScripts.2017-11-06_00_FamilyPlanAdjustments.sql'
Executing SQL Server script 'Bit.Setup.DbScripts.2017-11-13_00_IndexTuning.sql'
Executing SQL Server script 'Bit.Setup.DbScripts.2017-11-24_00_UpdateProcs.sql'
Upgrade successful
Migration successful.
Database update complete
```

それらしいことをしてそうな出力

再度データベースを確認してみる

```
root@testsv01:~# docker exec -it mssql /opt/mssql-tools/bin/sqlcmd -S localhost -U SA -P パスワード
1> select name from sys.databases;
2> go
name
--------------------------------------------------------------------------------------------------------------------------------
master
tempdb
model
msdb
vault

(5 rows affected)
1> use vault
2> ;
3> go
Changed database context to 'vault'.
1> select name from sysobjects where xtype = 'U';
2> go
name
--------------------------------------------------------------------------------------------------------------------------------
Cipher
Collection
CollectionCipher
CollectionGroup
CollectionUser
Device
Folder
Grant
Group
GroupUser
Installation
Organization
OrganizationUser
U2f
User
Migration

(16 rows affected)
1>
```

`vault` データベースできてる！！

![Register bitwarden Web Vault (1).png](https://qiita-image-store.s3.amazonaws.com/0/8739/e6299ea9-5151-1458-2b46-78997c813d71.png)

アカウント作成できました :joy:

後から気付いたのですが、ちゃんと次の手順として `./bitwarden.sh updatedb` が書かれてました。単に私が早まっただけでした :scream:
ちゃんとドキュメント読めと...

## ログインしてみる

これがアカウント作成直後にログインした画面です
SMTP 設定が正しく行われていればメールを送ってメールアドレスの確認ができます。SMTP 設定に間違いがあった場合は `bwdata/env/mssql.override.env` を書き換えて `./bitwarden.sh restart` で変更を反映できます。 `docker inspect` で環境変数が反映されてることを確認できます。

![My Vault bitwarden Web Vault.png](https://qiita-image-store.s3.amazonaws.com/0/8739/c52c3644-70e7-e9f3-bdb7-819440171c73.png)

## Types

登録する情報のタイプとして

* Login
* Card
* Identity
* Secure Note

の4種類があります。それぞれの入力項目は次のようになっています。
これらを任意のフォルダに分けて保存できたり、お気に入りに登録したりできるようです。

### Login

![bitwarden-new-item-Login.png](https://qiita-image-store.s3.amazonaws.com/0/8739/531d5c93-e426-fe53-d501-173c8696ebbe.png)


### Card

![bitwarden-new-item-card.png](https://qiita-image-store.s3.amazonaws.com/0/8739/45fd7c62-77f3-cf7b-3283-3ebe8b2c6703.png)


### Identity

![bitwarden-new-item-identity.png](https://qiita-image-store.s3.amazonaws.com/0/8739/5661d49c-133c-4d7b-071a-57699bd889d3.png)


### Secure Note

![bitwarden-new-item-secure-note.png](https://qiita-image-store.s3.amazonaws.com/0/8739/29a12b5b-9f81-2fd9-6de1-a8ec58db14e0.png)

## Apps

ブラウザ用アドオン、スマホ用アプリ、デスクトップ用アプリと各プラットフォームで使えるようになっています。

![Get the Apps bitwarden Web Vault.png](https://qiita-image-store.s3.amazonaws.com/0/8739/1fde4067-d9af-d0df-2265-f377020e1e9d.png)

## その他

* Organization 設定をすれば組織内でパスワードを共有するとかいう使い方もできるっぽいです
  * でも有償かな？ [Licensing for paid features](https://help.bitwarden.com/article/licensing-on-premise/)
* LDAP や ActiveDirectory との連携もできるっぽいです [https://help.bitwarden.com/article/ldap-directory/](https://help.bitwarden.com/article/ldap-directory/)
* 細かいところまで全然試せていませんが一般的なパスワードマネージャーの機能は備えているようです
* [Help Center](https://help.bitwarden.com/)

## 参考資料

SQL Server まったくわからなかったので [コマンドラインでSQL Serverを使う最低限のメモ](https://qiita.com/zaburo/items/6edf7c05c5d4f5e039eb) に助けてもらいました