カスタムdbと同期が出来ない

47

堀井さん、

まずCouchDBはどうやって立てていますか?Dockerでしょうか。
BASIC認証は正しく設定されていますか?
HTTPSとのことですので、証明書は正しく設定されているか確認してみてください。自己署名でしょうか?

Unknown errorはたいていサーバ側の問題であることが確認されています。参考:

トピックの作成ありがとうございます。

CouchDBは、CentOS 7にapacheのbintray–apache-couchdb-rpmからyumで入れてます。
version は 2.1.0 です。

SSLサーバ証明書は自己署名ではなく購入したもので、同じホストのWebサーバでも利用しています。

Inkdrop実行環境(CouchDBサーバとは別)からの curl だと期待通りのレスポンスが返っているように見えますので、Basic認証は正しく機能していそうです。

curl https://username:password@mydomain:6984/userdb-xxxx

{“db_name”:"******",“update_seq”:"******",“sizes”:{“file”:99480,“external”:0,“active”:0},“purge_seq”:0,“other”:{“data_size”:0},“doc_del_count”:0,“doc_count”:0,“disk_size”:99480,“disk_format_version”:6,“data_size”:0,“compact_running”:false,“instance_start_time”:“0”}

CouchDBが2系であることが原因かも知れません。
CouchDBにはあまり詳しくないのですが、1系→2系でプロトコル等に変更が入ってるのでしょうか?

詳しいご回答ありがとうございます!

サーバ側にはなにかそれらしきエラーログが残っていますか?

まずは原因の切り分けのために、ローカルで動かしたCouchDBと同期できるか確認してみるのはいかがでしょうか。
僕はmacOSのローカルでCouchDB v2.0.0を動かして動作確認をしています。
それがうまくできたら、次はサーバ側でSSLなしでセットアップしてみてください。

ちょっと手間がかかってしまいますが、まずはエラーの正体を突き止める必要があると思います。
よろしくお願いします!

ちなみにCouchDB 1系と2系の違いは主にクラスタリング対応の機能追加などで、API自体は大きく変わっていません。

コメントありがとうございます。

幾つか試してみたところ、変化がありました。
・Sync設定を http://uid:pwd@mydomain/user-xxx にしたところ(ポート番号記載なし)、前述のエラーがconsoleに出力される
・Sync設定を http://uid:pwd@mydomain:5984/user-xxx にしたところ、正しく同期される
・Sync設定を https://uid:pwd@mydomain/user-xxx にしたところ(ポート番号記載なし)、前述のエラーがconsoleに出力される
・Sync設定を https://uid:pwd@mydomain:6984/user-xxx にしたところ、同期されないが、前述のエラーもconsoleに出力されない

Sync設定のURLにはポート番号は必須なのですね(指定しない場合は80/443になる?)。

https&6984では同期できずエラーも出ないという状態なのが不思議です。
https&6984の上記URLは、curlでは応答が返っており、サーバ側のFirewall設定は問題ないと思われます。

なお、https&6984のURLにcurlでアクセスした場合は、couchdbの方にログが出力されますが、Inkdropのsyncに同URLを設定した場合、couchdbのログは出力されません。
サーバまでリクエストが届いていない可能性があります。

はい、ポート番号は必須です。CouchDBのポート番号はwell-known portではないからです。

・Sync設定を http://uid:pwd@mydomain:5984/user-xxx にしたところ、正しく同期される

SSL無しで動作が確認できたということは、SSLの設定不備の可能性が高いです。
curl -v で証明書のエラーが起きていないか確認してみてください。

https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=48203146
こちらの Accessing and Verifying SSL の項が参考になると思います。

試してみました。
curl -v では正常に証明書の確認が行われているようです。

curl -v https://****:****@****:6984/userdb-****

  • Trying ****…
  • TCP_NODELAY set
  • Connected to **** (****) port 6984 (#0)
  • TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
  • Server certificate: ****
  • Server certificate: **** CA
  • Server certificate: **** CA
  • Server auth using Basic with user ‘****’

GET /userdb-**** HTTP/1.1
Host: ****:****
Authorization: Basic ****
User-Agent: curl/7.54.0
Accept: /

< HTTP/1.1 200 OK
< X-CouchDB-Body-Time: 0
< X-Couch-Request-ID: ****
< Server: CouchDB/2.1.0 (Erlang OTP/18)
< Date: Wed, 27 Sep 2017 06:38:32 GMT
< Content-Type: application/json
< Content-Length: 469
< Cache-Control: must-revalidate
<
{“db_name”:“userdb-****”,“update_seq”:"****",“sizes”:{“file”:755217,“external”:200598,“active”:230495},“purge_seq”:0,“other”:{“data_size”:200598},“doc_del_count”:5,“doc_count”:27,“disk_size”:755217,“disk_format_version”:6,“data_size”:230495,“compact_running”:false,“instance_start_time”:“0”}

  • Connection #0 to host **** left intact

レスポンスを見るとすでにドキュメントがいくつか同期されているようですが、データベースはどういう状態でしょうか?

データベースは正常で、http で同期テストを行って正常に利用できる状態です。
https に切り替えると同期は行われません(httpに再度切り替えると再び同期する)。

問題を整理すると、

  • unknown error の原因はポート指定抜けだった
  • SSL無しだと正常に同期される
  • SSL有りだと同期しない(エラーも何も出ない)
  • 証明書は問題無い

まずエラーも何も出ないというのが気になります。
サーバとはRESTで通信しますので、何かしらHTTPリクエストがサーバに飛ぶはずですが、何もサーバ側で通信が観測されない状態なのでしょうか。CouchDBのログはいかがでしょうか。

整理された内容は相違ありません。

SSL有りの場合、CouchDBのログには何も出力されません。
SSL無しの場合、およびcurlでのhttpsアクセスの場合はともにCouchDBのログに出力されます。

念のためですが、社内プロキシなどを挿している環境ではありませんか?
SSLリクエストが遮断される原因に、何か心当たりがあればいいのですが。


この文字列は無視して下さい。 "Body seems unclear, is it a complete sentence"と投稿時になぜか怒られるので

プロキシなどは通していません(その場合はcurlでも通らないはずです)。


パケットをキャプチャしてみたところ、(SSLなので中身は把握しきれませんが)サーバへのリクエストは出ていますね。

SSLのHandshakeが完了していないか、Handshake後、documentの送信までに何かが起こって処理が中断しているのでしょう。

これ以上は調べるのが少々難儀ですね。
別の証明書を手配して検証した方が良いかも知れません。

なるほど、ありがとうございます。

ちなみにInkdrop公式サーバは運用の都合上CouchDBのSSL機能を使用しておらず、nginxのリバースプロキシを通してSSLを提供しています。
以下のような設定です。

server {
  listen 6984;
  ssl on;
  ssl_certificate /path/to/fullchain.pem;
  ssl_certificate_key /path/to/privkey.pem;
  ssl_protocols TLSv1.1 TLSv1.2 SSLv3;
  ssl_session_cache shared:SSL:1m;

  server_name ***;

  location / {
    proxy_pass http://localhost:5984;
    proxy_redirect off;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Ssl on;
  }

  location ~ ^/(.*)/_changes {
    proxy_pass http://localhost:5984;
    proxy_redirect off;
    proxy_buffering off;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Ssl on;
  }
}

ディストリは Ubuntu 16.04 です。
もしよろしければ試してみてください。

nginx の設定共有、ありがとうございます。

nginx は既に立ててあるので試せますね。
進捗があればこちらに投稿します。

サポートありがとうございました!

1 Like

共有いただいた nginx 設定を参考にして設定したところ、無事、正しく同期できるようになりました。

これで本格的に導入検討できます。
ありがとうございました。

1 Like

おっと、そうなるとCouchDBのSSL機能は非推奨にしなければならないですね。ドキュメントに追記しておきます。
長々とお手数をおかけしました。無事動いてよかったです。
こちらこそありがとうございます!