リモート(遠隔地)のデータベース(MySQLやPostgreSQL)を安全にzebedeeで接続(暗号化)

MySQLPostgreSQLなどのデータベースは、インターネットを透過して通信する機能を備えています。
ファイアーウォールなどで通信(ポート)が遮断されず、クライアントからサーバが見えれば、接続できます。
しかし、この状態では盗聴クラッキングに対する備えが甘いという指摘を免れません。

安全に接続するポピュラーな方法はVPNですが、向かないこともあります。
VPNはLANと同様に幅広い通信を通すので、その分、回線の負荷が増加します。
状況によっては、VPN内部のセキュリティ対策が必要になることもあるでしょう。
データベースだけを安全につなぐ場合、SSHSSLが正統派のようです。
しかし、SSHSSLの導入には、現状の構成に対し、大きな複雑化が必要になるケースもあります。
安全簡単、しかも省コストな方法を探した結果、zebedeeというフリーソフトを見つけ、試してみました。

zebedeeは、以下のようにルータの両端で動作するイメージで、間を流れる通信をトンネル(暗号化)します。



                        ↓↓ zebedeeを導入 ↓↓



SSLに比べSSHに近い構成で、第三者認証などはありません。
SSHと同様、クライアント側にもインストールが必要ですが、設定は遥かにシンプルでした。

ダウンロードとインストール

MySQLやPostgreSQLなどのデータベースは既にあることを前提に話を始めます。
アプリケーション側、データベース側のどちらもWindowsで試しました。(zebedeeのバージョンは2.4.1Aです。)
全て標準のポートを例に説明します。標準以外のポートをお使いの場合は読み替えて下さい。
どちらか、または両方がLinaxやMACでも、可能なようです。その場合は読み替えて下さい。

zebedeeのダウンロードやインストールの手順は、ここでは触れません。
Windowsへのインストールは、極めてシンプルです。標準的な設定でインストールして下さい。
「プログラム(アプリケーション)の追加と削除」でアンインストールも簡単にできます。

ルータの設定とコマンドラインからの起動(Blowfish暗号法による暗号化)

先ず、必要な場合、ルータを設定しましょう。
データベースを置いたパソコンが、グローバルIPアドレスで参照できない場合、ルータのポートをフォワードして下さい。
zebedeeが使用するTCP11965ポートをデータベースを置いたパソコンにフォワードします。
ついでにMySQLならTCP3306PostgreSQLならTCP5432をデータベースを置いたパソコンにフォワードします。
ファイアーウォールなどで上記の通信を遮断している場合、解除して下さい。
これで、データベースとの通信はインターネットを透過して、つながります。
まだ暗号化はされていませんが、ここでいったん、データベースサーバへの接続を確認しておきましょう
データベースにはテスト用のデータが入った状態にし、仮のユーザやパスワードで接続する方が安全です。

次に、(データベース)サーバ側のzebedeeを動かしてみましょう。
コマンドプロンプトを開いて、zebedee.exeがインストールされたフォルダに移動します。
通常なら、「cd c:\program files\zebedee」で行けます。
zebedee -s」と入力するとzebedee.exeがバックグラウンド(サーバモード)で起動します。
タスクマネージャのプロセスタブで確認できます。
起動したらコマンドプロンプトを閉じて下さい。閉じてもzebedeeの動作は生きています。
終わらせる時は、タスクマネージャを開いてzebedee.exeのプロセスを終了させて下さい。

最後に、(アプリケーション)クライアント側のzebedeeを動かします。
サーバ側と同様の手順で、コマンドプロンプトを開いてzebedee.exeがインストールされたフォルダに移動します。
zebedee 23306:xxxxxxxxxx:3306」と入力するとzebedee.exeがバックグラウンド(クライアントモード)で起動します。
起動の確認と終了の方法はサーバ側と同様です。

このコマンドで、Localhostの23306ポートへの通信はxxxxxxxxxxのzebedeeに送られ、3306ポートに届きます。
23306ポートは、別のポートでも構いません。Localhostで使われることがない空ポートであれば何でもOKです。
xxxxxxxxxxは、サーバ側のグローバルIPアドレスなどです。
ルータのポートをフォワードしている場合は、ルータのグローバルIPアドレスなどです。
DNSで、そのコンピュータ、またはルータを示す文字列でも構わないと思います。
YAMAHAのダイナミックDNS(xxxx.aax.netvolante.jp)でもつながりました。

3306というのはMySQLが通常使う通信ポートです。
MySQLが自分のパソコンにある場合、Localhostの3306ポートでMySQLを認識するのは、ご存じの通りです。
Server「xxxxxxxxxx」のPort「3306」からMySQLに接続するアプリケーションの設定を、「Localhost」の「23306」に変更します。
つまり、MySQLは自分のパソコンにあり、23306ポートから接続すと偽るわけです。
23306ポートはzebedeeで暗号化されて安全なトンネルを抜けて目的地の3306ポートに出てきます。
すると、あら不思議!xxxxxxxxxxのMySQLにつながるというカラクリです。

ODBCを例にすると、以下のような設定になります。
元はServer「xxxxxxxxxx」Port「3306」という設定を、Server「Localhost」Port「23306」に変えればトンネリングできます。
PostgreSQLが通常使うポートは5432なので、PostgreSQLの場合は3306→5432、23306→25432と読み替えて下さい。

さて、以上で通信は暗号化され、盗聴の心配は無くなったと言えます。
しかし、この状態では、外部からデータベースが通常使うポート(3306または5432)でもつながります。
ルータのポートをフォワードした場合は、3306または5432のフォワードを削除しましょう。
ポートフォワードでない場合は、ルータのファイアーウォールで3306または5432の外部からの侵入を塞いでおきましょう。

これで、ひとまずzebedeeの運用環境ができます。
前述の要領で、起動はコマンドプロンプトから、終了はタスクマネージャを開いて行えます。
この設定で残っている危険は、zebedeeがインストールされたパソコンなら、どこからでも接続できることです。

鍵の作成クライアント側

zebedeeでは、(Diffie-Hellmanの鍵交換)によってクライアントを認証できます。
鍵は、クライアント側のパソコンで、コマンドを入力して作ります。
先ず、コマンドプロンプトを開いてzebedee.exeがインストールされたフォルダに移動します。
以下のコマンドで秘密鍵を作ります。「p001.key」は秘密鍵が保存されるファイル名で、名前は任意です。
zebedee -p > p001.key
(zebedee -p...のpは小文字、もちろん半角です。)
同じフォルダに「p001.key」という秘密鍵が入ったファイルができます。
メモ帳などで開いてみると、以下のような形式の文字が並んでいます。
privatekey "1e34d6769502bae1087c18d2e8c8776e4a17ddaf"
確認したらファイルは閉じて下さい。
この秘密鍵の文字列は後で使います。ファイルの場所と名前を控えておきましょう。

続いて以下のコマンドを入力します。「p001.id」は保存されるファイル名で、名前は任意です。
zebedee -P -f p001.key > p001.id
(こっちのzebedee -P...のPは大文字です。)
できたファイルをメモ帳などで開いてみると、以下のような形式の文字が並んでいます。
135f04050961d37553731250d5c6f7495f088b32 myhostname
myhostname」は、操作しているパソコンのコンピュータ名です。
この文字列をサーバ側のcheckidfileに登録して、登録されたクライアントだけが接続できるようにします。
zebedeeは、この文字列によって、クライアントを識別します。
後でサーバ側で使うので、USBメモリーやフロッピーなど、移動できる媒体にコピーしておきましょう。

設定ファイルの作成クライアント側

zebedeeを起動するには、前述のようにコマンドラインで引数を指定する方法と、設定ファイルを使う方法があります。
引数が多くなるので、設定ファイルを作ることにします。
設定ファイルの名前は任意で、識別子は「zbd」です。メモ帳などで編集できます。

クライアント側の設定ファイルの例を示します。詳細はzebedeeのマニュアルを参照下さい。
server false
privatekey "1e34d6769502bae1087c18d2e8c8776e4a17ddaf"
keygenlevel 2
maxbufsize 16383
tunnel 23306:xxxxxxxxxx:3306
#tunnel 25432:xxxxxxxxxx:5432
compression zlib:6
logfile SYSLOG
verbosity 1 #メッセージのレベル(0〜5,デフォルト:1)
privatekey "1e34d6769502bae1087c18d2e8c8776e4a17ddaf"」は秘密鍵の文字列です。
xxxxxxxxxxは、サーバ側のグローバルIPアドレスなどです。

tunnel 23306:xxxxxxxxxx:3306」はMySQLの場合の設定例、
tunnel 25432:xxxxxxxxxx:5432」はPostgreSQLの場合の設定例です。

checkidfileの作成サーバ側

ここで、サーバ側に行き、メモ帳などを使って、checkidfileを作ります。
checkidfileのファイル名は任意ですが、今回は「zebedee-checkidfile.id」とします。
先ほど作ったクライアントを識別する文字列を下記のように貼り付けます。
クライアントが複数の場合は、行を分けて追加して下さい。
135f04050961d37553731250d5c6f7495f088b32 myhostname
5bf7d314f89b15c511b6e00000000e0b595d990c pc_abcdef #←これは、別のクライアントです。
編集したら、「zebedee-checkidfile.id」という名前で、デスクトップなど、仮の場所に保存しておきましょう。

設定ファイルの作成サーバ側

サーバ側の設定ファイルの例を示します。詳細はzebedeeのマニュアルを参照下さい。
server true
udpmode false
checkidfile 'zebedee-checkidfile.id'
keygenlevel 2
keylength 256
minkeylength 32
maxbufsize 16383
target localhost
compression zlib:9
logfile 'zebedee-server.log'
#logfile SYSLOG
timestamplog true
verbosity 3 #メッセージのレベル(0〜5)
zebedee-checkidfile.id」は、checkidfileのファイル名です。

logfile 'zebedee-server.log'」または「logfile SYSLOG」で、ログの出力先を指定します。
どちらか一方を指定して下さい。
logfile 'zebedee-server.log'」とすると、ファイルに出力されます。
verbosity(0〜5)に大きな値を指定するほど、詳細なログを取得できます。
詳細なログは、デバッグや調査などに役立つ可能性があります。
ファイルが無限に肥大化するかも知れないので、本稼働時は「logfile SYSLOG」が良いと思います。

設定ファイルを編集したら、デスクトップなど、仮の場所に(zebedee-server.zbdなど)任意の名前で保存しておきましょう。

起動(例)

c:\zebedee-server」というフォルダを作成し、そこに設定ファイル(zebedee-server.zbd)とcheckidfileを移動します。
設定ファイル(zebedee-server.zbd)で、checkidfileをファイル名だけで指定したので、同じフォルダに必要です。
ログファイル(logfile)も、相対パス(ファイル名だけ)で指定してるので、同じフォルダに作成されます。
サーバ側の起動用に以下のようなBATファイルを作って、デスクトップなど、任意の場所に保存します。
@echo off
echo zebedeeを起動します。中止は[Ctrl]+[C]
pause
cd c:\zebedee-server
start zebedee-server.zbd
サーバ側は、このBATファイルダブルクリックするとzebedeeがバックグラウンドで起動します。

クライアント側の設定ファイルにファイルの参照やログファイルの出力は書いていません。
設定ファイルをデスクトップなどに置いてダブルクリックすると、zebedeeはバックグラウンドで起動します。
スタートアップフォルダに入れておけば、自動起動できます。

この起動方法は一例です。状況や目的に合わせて変更して下さい。

覚書(AccessからODBC,zebedee経由でMySQL,PostgreSQLに接続する場合).....間違っているかも知れません。

MySQLのmy.ini(conf)を以下のようにしました。
[client]
:
default-character-set=utf8
:
[mysql]
:
default-character-set=cp932
:
:
[mysqld]
:
max_allowed_packet=50M #LONGBLOB型が大容量のときリモート接続が切れる対策
:
MySQLにODBC経由で接続する場合、「OPTION=3」を設定しました。
MySQL用のODBCの設定で、「Character Set」に「cp932」を指定しました。

PostgreSQLのODBC設定で「byteaをLOとして扱う」にチェックを入れました。
(AccessのOLEオブジェクト型が正しく処理されない対策)

ご意見、お問い合わせは → 
メールでできる範囲なら、無償で相談に乗ります。
お気軽に.....
ACCESSの使い方トップページ

あとがき

zebedeeは、通信を圧縮する機能を備えています。
圧縮率は、設定ファイルの「compression zlib:X」(X=0〜9)で指定できます。
クライアントとサーバで圧縮率の指定が異なる場合、低い方が採用されます。
リモート(回線はADSL)で、導入前より、zebedeeで暗号化した方がスループットが上がることがあり、驚きました。
特に大量レコードの検索を伴う場面や大きなレコードの更新で、差が顕著でした。
反応時間が気になるタイミングで速いので、zebedeeを使った方が体感速度が向上します。
この現象は、圧縮の効果だと推測されます。
圧縮には通信回線の負荷を軽減する効果もあるので、回線あたりに収容できる接続数の向上も期待できるでしょう。

Neil Wintonさん(zebedeeの開発者)に感謝致します。
zebedeeは、シンプルで使い易いだけではなく、優れた性能を持ったソフトです。

SQL Serverを使う場合の運用例

データベースがSQL Serverの場合、上記の要領だけではうまく行かないことがあります。
デフォルトの設定でSQL Serverをインストールすると、通信の構成が複雑になるためです。
SQL Serverには、複数のインスタンスを登録できる機能があります。
この機能を使うと、UDPの1434ポートが必要で、TCPのポートも動的になります。
Zebedeeは特定の通信ポートをトンネリングすることを目的としています。
透過させる通信ポートを設定する時点で壁に突き当たるでしょう。
この点でSQL ServerとZebedeeはミスマッチということになります。

複数のインスタンスが役に立つことがあるかも知れませんが、多くのケースでは不要でしょう。
この機能を使わなければ、通信を特定のTCPポートに固定することが可能です。
SQL Serverをインストールする際、
「インスタンスの構成」で「既定のインスタンス」を選択すれば、インスタンスは単一になります。
ネットワークに公開する方法など、詳細な設定につては、ここでは触れません。
通信ポートをTCPの1433番だけに固定すれば、上記の要領でつながります。



〒745-0801 山口県周南市大字久米327-145
中川システム開発 ホームページ
Tel(0834)28-0205 Fax(0834)28-1272