Zabbixの監視通信をStunnelで暗号化する。

| コメントをどうぞ

Zabbixの監視通信は平文で行われます。なのでパケットを眺めると通信内容などが盗み見されます。監視システムははLAN内で完結する事が多いので盗み見出来ても問題無いですが、リモート監視などを行っていると問題になる場合があります。個人的には監視データが見られてもさして問題じゃないのでは?と思いますが、セキュリティの厳しい要件やお客さんに「暗号化してません。平文です。」というのは何かとまずい事があります。ですので暗号化します。

試しに暗号していない通信を他のサーバでキャプチャしてみると・・・
(Zabbixサーバ宛に流れている通信をキャプチャ)

        0x0000:  4500 007e 9026 4000 4006 c20e ac16 c80b  E..~.&@.@.......
        0x0010:  ac16 c80c dca5 2742 331a 8fce 55ce 00f2  ......'B3...U...
        0x0020:  8018 0073 5e76 0000 0101 080a 9206 1fe9  ...s^v..........
        0x0030:  00b0 34a8 6e65 742e 6966 2e69 6e5b 5741  ..4.net.if.in[WA
        0x0040:  4e20 4d69 6e69 706f 7274 2028 4950 7636  N.Miniport.(IPv6
        0x0050:  292d 5379 6d61 6e74 6563 2045 6e64 706f  )-Symantec.Endpo
        0x0060:  696e 7420 5072 6f74 6563 7469 6f6e 2046  int.Protection.F
        0x0070:  6972 6577 616c 6c2d 3030 3030 5d0a       irewall-0000].

“net.if.in[WAN.Miniport.(IPv6)-Symantec.Endpoint.Protection.Firewall-0000].” と、人間が理解できる文字列で通信内容が覗き見出来ます。

以下は暗号化を施した通信になります。

        0x0000:  4500 0067 534c 4000 4006 fe89 ac16 c80b  E..gSL@.@.......
        0x0010:  ac16 c882 eb0c 274a e2cf a450 dcb4 2c70  ......'J...P..,p
        0x0020:  8018 007a 55df 0000 0101 080a 921e cdd0  ...zU...........
        0x0030:  7cc0 41e5 1403 0300 0101 1603 0300 28ac  |.A...........(.
        0x0040:  3564 cb7b 0072 0ce9 286f ecc3 1ff9 0b83  5d.{.r..(o......
        0x0050:  af2a da85 2d00 19fe 36ed 5efd ca2a 3734  .*..-...6.^..*74
        0x0060:  47a6 d9ce 1731 2d                        G....1-

通信内容が覗き見してもわからなくなっています。Zabbixの監視通信を行うのに良さそうな方法は2通りあります。

暗号化したVPNを張ってその中で通信。
通信を暗号化したトンネルを通す。

● VPNで暗号化のメリット
暗号化されたVPNで通信する方法はハードウェアもしくはソフトウェアでVPNを張って通信をすると全ての通信が暗号化されますのでZabbixの監視通信以外も暗号化出来ます。監視対象が多い場合もVPNに参加させるかVPNルータを経由させる形にすれば良いので容易に暗号化する監視対象を追加出来ます。

● VPNで暗号化のデメリット
VPNを張るという行為自体がNGな場合もあります。

● 暗号化したトンネルを張って通信を通す。のメリット
SSHトンネル等が有名です。手軽に1対1の通信を暗号化出来ます。監視対象が1台しか無いときでわざわざVPNを張らなくても・・・という場合に使いやすいです。

● 暗号化したトンネルを張って通信を通す。のデメリット
暗号化するソフトのポートの他に暗号化したい通信のポートが別途必要になります。複数ホストがある場合はその分数を掛け算で必要になります。

今回はStunnelで暗号化します。

Stunnelはサーバ、クライアント方式でStunnelで接続したトンネルを張り、その中に指定のポートを転送して通信します。Stunnelを起動すると自ホスト内に指定したポートが開きます。そこへのアクセスするとトンネルを張った相手ホストに転送します。

● Stunnelの概要図
stunnel

Stunnelは一つのデーモンでサーバとして動くポートとクライアントとして動くポートを指定して動かせますの
で一つのサーバ内でこのポートはクライアントとして外部のStunnelとトンネル張るがこのポートはサーバとして外部から受け付ける。というような事が可能です。

これを利用してZabbixサーバ側では、

● ログ等のアクティブチェックはStunnelのサーバモードで各エージェントからトンネル経由で受け取る。
● パッシブチェックは各エージェントに対してStunnelのクライアントモードでトンネル経由で問い合わせる。

と言った構成にしていきます。

Zabbixサーバ側の設定

  1. Stunnelのインストール


  2. CentOSならyum一発で導入出来ます。

    # yum install stunnel -y
    
  3. SSL証明書の作成
  4. OpenSSLを使って自前証明書を作成します。ブラウザでアクセスすることも無いので自前で何ら問題無いです。
    ここでよくある自前証明書作成コマンドで作成したものだと何故か私の環境では、

    Linux⇔Linux間は問題なくトンネル張れるが、Linux⇔WindowsとLinux⇔Linuxが混在する環境で全部にトンネル張ろうとすると失敗しました。失敗というか、Windows側で起動時に鍵のエラーが出ました。

    証明書作成コマンド

    # openssl genrsa 2048 > stunnel.key
    # openssl req -new -key stunnel.key > stunnel.csr
    # openssl x509 -days 3650 -req -signkey stunnel.key < stunnel.csr > stunnel.crt
    

    Stunnelのドキュメントに証明書/鍵の作成方法が書いてありますのでそちらで試すとWindowsとLinuxが混在した環境でも全部起動出来て繋がりました。

    To generate a key and self signed certificate, execute the following commands:
    
    cd /etc/pki/tls/certs
    make stunnel.pem
    
    Note that by default, the file containing the key and certificate has its
    permissions set to 0600, which means that any service using it needs to be
    started as root in order to read it.  Such a service should be configured
    to switch UIDs using stunnel's "-s" flag.
    

    証明書と鍵を一つのファイルにしないと駄目なのかもしれません。わかりませんが。。

    ※追記:書き忘れましたが、上のまんまで実行すると有効期限が365日で出来てしまいます。期限が切れるとStunnelが繋がらなくなります。深く考えずにやったので一度期限切れでStunnel経由の監視が全部出来なくなってしまった事があります。なので「make stunnel.pem」の前に「/etc/pki/tls/certs/Makefile」内の記述、「-days 365」を書き変えて長くしてから「make stunnel.pem」を実行します。今は「-days 9999」で作成して有効期限自体もZabbixで監視するようにして対策してあります。

  5. Zabbixサーバ側のStunnelの設定ファイルを書きます。
  6. ● /etc/stunnel/stunnel.conf

    cert = /etc/stunnel/stunnel.pem
    key = /etc/stunnel/stunnel.pem
    sslVersion = all
    options = NO_SSLv2
    options = NO_SSLv3
    setuid = nobody
    setgid = nobody
    pid = /etc/stunnel/stunnel.pid
    socket = l:TCP_NODELAY=1
    socket = r:TCP_NODELAY=1
    verify = 3
    CAfile = /etc/stunnel/stunnel.pem
    debug = 4
    output = stunnel.log
    [Zabbix passive HOST1]
    client = yes
    accept = 127.0.0.1:10060
    connect = XX.XX.XX.XX:10052
    [Zabbix passive HOST2]
    client = yes
    accept = 127.0.0.1:10062
    connect = XX.XX.XX.XX:10052
    
    [Zabbix Active]
    accept = 10061
    connect = 10051
    

    client=yes とするとクライアントモードでStunnelをサーバモードとして待ち受けているホストに繋ぎます。
    最初に自身の設定したポート、例えば10060に繋ぐと繋ぎたいホストの10052へ接続します。
    何もつけないとサーバモードで待ち受けます。ここをアクティブチェックの受け取り口にします。
    verify=3で証明書が一致しないと接続を蹴るようにします。そうしないとどこからでも接続されてしまいます。
    (単に暗号化したいならばverify指定しないと接続出来ます。)

Zabbixエージェント側の設定

インストール迄は同じです。証明書/鍵はサーバ側で作成したものをコピーして使います。

  1. Stunnelのインストール
  2. # yum install stunnel -y
    
  3. Zabbixエージェント側のStunnelの設定ファイルを書きます。
  4. ● /etc/stunnel/stunnel.conf(HOST1)

    cert = /etc/stunnel/stunnel.pem
    key = /etc/stunnel/stunnel.pem
    sslVersion = all
    options = NO_SSLv2
    options = NO_SSLv3
    setuid = nobody
    setgid = nobody
    pid = /etc/stunnel/stunnel.pid
    socket = l:TCP_NODELAY=1
    socket = r:TCP_NODELAY=1
    verify = 3
    CAfile = /etc/stunnel/stunnel.pem
    debug = 4
    output = stunnel.log
    [Zabbix passive]
    accept = 10060
    connect =10050
    [Zabbix Active]
    client = yes
    accept = 127.0.0.1:10051
    connect = XX.XX.XX.XX:10061
    

    ZabbixサーバからのパッシブチェックをStunnelが動いている10060で受け取り自身の10050へ渡します。アクティブチェックは自身から送信するのでZabbixサーバのStunnel待ち受けポートの10061へ飛ばします。
    こちらもサーバとして待ち受けるポートがあるのでverify=3として証明書が一致しない場合は接続しないようにします。

以上で設定そのものは完成です。Stunnelを起動すれば繋がるようになります。但しWIndows版は公式サイトのインストーラーで入れれば自動起動が出来ますがLinux版はinitスクリプトが存在しない為作成します。

● Linux版でStunnelのinitscript作成(サーバ、クライアント共通)
(/etc/init.d/stunnel)

#!/bin/sh
# chkconfig: 345 70 40
# description: stunnel

# Source function library.

. /etc/init.d/functions


STUNNEL=/usr/bin/stunnel
CONF=/etc/stunnel/stunnel.conf
prog=stunnel

start() {
                echo -n $"Start $prog: "
                daemon $STUNNEL $CONF
                echo
        }

stop() {
                echo -n $"Stop $prog: "
                killproc $STUNNEL
                echo
        }

case "$1" in
        start)
                start
                ;;
        stop)
                stop
                ;;
        restart)
                stop
                start
                ;;
        status)
                status $STUNNEL
                ;;
        *)
                echo "Usage:$0 {start|stop|restart|status}"
                ;;
esac

作成したら自動起動も設定しておきます。

# chkconfig --add stunnel
# chkconfig stunnel on

起動します。(サーバ、クライアント両方)

# /etc/init.d/stunnel start

Zabbixサーバからzabbix_getを使って動作確認します。

# zabbix_get -s 127.0.0.1 -p 10060 -k agent.hostname
HOST1

自身のローカルIPの10060ポートに対して実行したzabbix_getでエージェント側のホスト名が返ってきているのでトンネルがうまく張れているのが確認できます。

アクティブチェックがうまくとれているかはzabbix_senderでも出来ますが実際にZabbixでログ監視を作ったほうがわかりやすいです。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>