NginxのstreamモジュールがDTLSに対応した(パッチ)

NginxのL4レイヤのProxy機能である、streamモジュールのDTLS対応パッチが公開されていたので試す。
(まだ検証段階で、フィードバック募集中らしい)

簡単に言うと、以下のようににDTLS -> Plain UDPや、その逆にPlain UDP -> DTLSへのProxyが出来る。

DTLS -> Plain UDP

f:id:ASnoKaze:20170524014622p:plain

Plain UDP -> DTLS

f:id:ASnoKaze:20170524022625p:plain

Plain UDP -> DTLS -> Plain UDP

2つ組み合わせれば、中間だけDTLSで暗号化することも出来る
f:id:ASnoKaze:20170524014630p:plain

ビルド

今回は、Ubuntu Trustyでビルドする

sudo apt-get install libpcre3-dev

wget http://nginx.org/download/nginx-1.13.0.tar.gz
wget http://nginx.org/patches/dtls/nginx-1.13.0-dtls-experimental.diff

cd nginx-1.13.0
patch -p1 -i ../nginx-1.13.0-dtls-experimental.diff

./configure --with-stream --with-stream_ssl_module --with-debug
make

sudo make install

いつも通り、鍵も準備

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

DTLS -> Plain UDP

設定
#/usr/local/nginx/conf/nginx.conf
stream {
    # please enable debug log
    error_log logs/error.log debug;

    server {
        # add 'udp' and 'ssl' simultaneously to the listen directive
        listen 127.0.0.1:4443 udp ssl;

        # enable DTLSv1 or DTLSv1.2 or both protocols
        ssl_protocols DTLSv1;

        # set up other SSL options as usually
        ssl_certificate server.crt;
        ssl_certificate_key server.key;

        proxy_pass 127.0.0.1:8080;
    }
}
動作確認

クライアント

$ openssl s_client -dtls1 -connect 127.0.0.1:4443
test

バックエンド

$ nc -ul 8080
test

Plain UDP -> DTLS

設定
stream {
    server {
        listen 127.0.0.1:5555 udp;

        # enable SSL to proxy
        proxy_ssl on;
        # enable DTLSv1 or DTLSv1.2 or both protocols
        proxy_ssl_protocols DTLSv1;

        # set up other proxy SSL options as usually
        proxy_ssl_certificate  server.crt;
        proxy_ssl_certificate_key server.key;

        # the backend is a DTLS server
        proxy_pass 127.0.0.1:4433;
    }

}
動作確認

クライアント

$ echo -en "hello"| nc  -u localhost 5555

バックエンド

$ openssl s_server -cert server.crt -key server.key -dtls1 -accept 4433
ACCEPT
...(略)
hello
その他

省くが、Plain UDP -> DTLS -> Plain UDPの変換も上記の設定の組み合わせで実現できた。
使える機会があるかわからないが、普段使ってるNginxでDTLSが受けられるのは結構楽そうだ