投稿日

暗号化非対応のTCPクライアントでもNapterまでの通信を暗号化する方法

こんにちは、ソリューションアーキテクトのtaketoです。

さて本日は、SORACOM Napterについて掘り下げていきたいと思います。

SORACOM Napterは、ソラコムの回線を利用しているデバイスに対してインターネットから遠隔アクセスをすることができるサービスです。非常によく使われており、シンプルなサービスではありますが便利なサービスです。

以前、CRE (Customer Reliability Engineer) の加納(ニックネーム: Kanu)のブログ「【Ask SORACOM Vol.12】SORACOM Napter の TLS オプションとは?」にてデバイスに対してNapterで遠隔アクセスする際のユースケースを解説いただきました。その際、リモートデスクトップなどは、そのアクセス元のPCからSORACOM Napterまで暗号化されますが、お客様のアプリケーションによって暗号化をサポートしていない場合にはインターネット上のデバイスからNapterまでの通信区間まで暗号化なしの通信になることをご説明しました。このケースはアプリケーションが生のTCPで通信しているケースがあり、このアプリケーション自体の改修が組織やご予算の関係で難しいといったケースがあります。

そんな時に備えて本日は、このTCP非対応のアプリケーションをご利用の場合でもTLS暗号化をする方法をご紹介致します。

TCP非対応クライアントからNapter間の通信暗号化

構成概要

アーキテクチャ

全体のアーキテクチャは以下の通りです。

TCP通信アプリケーションをnginxをプロキシを経由することで通信を暗号化します。nginxからはTLS暗号化を施し、SORACOM Napterへリクエストを転送します。インターネットを通るこの区間でも通常nginxがなければその内容を閲覧することが可能になりますが、この構成であれば安全な通信が可能になります。

暗号化されたTCP通信は、SORACOM Napterが受け取りその暗号を解いた(TLS終端)した後にSORACOM SIMのデバイスへ転送します。

この構成ですと、送信元のTCPアプリケーションとそれを受け取るTCPサーバーにシステムの改修がなくともnginxを介すことで暗号化通信を実現しています。開発工数の削減ができるということですね!

Nginxとは

nginx(エンジンエックスと発音します)は、高性能なWebサーバーおよびリバースプロキシサーバーの一つで、特に高負荷なWebサイトやアプリケーションで広く利用されています。

様々な機能がありますが、インターネット上からのHTTPSリクエストを受け、TLSを終端(暗号化を解く)して後段のアプリケーションサーバーへ転送するといった使われ方をしますね。

他にもいくつか機能がありますが、今回は「TCP/UDP proxy server features」を利用して暗号化に対応していないTCP通信アプリケーションをNGINXをプロキシとして稼働させこれを経由することで通信を暗号化します。

検証

それでは早速設定と検証をしてみましょう!

SORACOM Napter有効化

まずは、SORACOM Napterを有効にしてください。

この時、TLS暗号化は必ず「有効」に設定してください。

Napterの接続先情報は都度変更になります。お客様で検証される際には、お客様の設定情報をご確認ください。
nginxの設定で利用致しますので、設定情報は保管してください。

nginx インストール

続いてTCPアプリケーションが稼働する端末に、nginxをインストールします。

お客様でお使いのOSにあった nginxをダウンロードしてインストールしてください。

nginxのTested OS and platformsに記載の通り、Linix以外にもWindowsなど広くサポートされている点は良いですね!

本検証はmacで実施いたしましたが、Windows version 最新(nginx-1.27.2)が私のWindowsでは動きませんでした。 Lagacy nginx-1.24.0ですと稼働確認できております。

nginx 設定

それでは設定をしていきます。

nginxはnginx.confという設定ファイルを読み込み稼働します。

インストールしたnginxの設定ファイルがどこにあるのかは nginx -t コマンドで確認できます。

下にサンプルを記載しております。

稼働している端末のport 3000番をリッスン(listen 3000;)し、受信したTCPパケットを暗号化(proxy_ssl on)し後段に転送(proxy_pass backend)しています。

転送後、作成したnapterのエンドポイントにパケットを送信します。先ほど作成したNapterのエンドポイントをupstream backendのserverに指定してください。このエンドポイントはお客様のNapter設定により異なりますのでご注意ください。

#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;

events {
  worker_connections  1024;
}

stream {
upstream backend {
  server 13-115-125-214.napter.soracom.io:45738;
}
server {
  listen 3000;
  proxy_pass backend;
  proxy_ssl on;
}
}

検証

早速、nginxを稼働させて検証してみましょう。

検証のクライアントと宛先のTCPサーバーにはnetcatコマンドを利用します。

そして、クライアントからnginxへ送信されるパケットとその後のパケットをキャプチャしています。

画面左(クライアント)から文字列を送信すると、右のラズベリーパイにてその文字列が見えることが分かります。

TCPによる通信ができていることが確認できましたね!

パケット解析で暗号化を確認

実際に通信された内容が暗号化されているか確認してみましょう。

まずは、クライアント → nginxへの通信です。

パケットNo.6にて暗号化なしでアプリケーションのデータ「test from pc」が送信されているのが確認できます。

続いて、nginx → SORACOM Napterのパケットをみます。上と同時刻のパケットはNo.6ですが、Protocol:TLSv1.2と表示されており暗号化がされていることが分かりますね!

この区間はインターネット上を通るデータですが、暗号化されていれば安心です。

続いて、napter -> デバイスのパケットをみます。

実際にデバイスが受信したパケットのNo.7に「test from pc」というメッセージがみて取れます。

さらに、一つ前で暗号化されておりましたが、この段階でProtocol: TCPとなっており暗号化がされていないことが分かりますね。

つまり、Napterの入口で暗号化が終端されデバイスにパケットが到達していることが分かります。

さいごに

いかがでしたでしょうか?

既存のアプリケーションに改修せずとも暗号化が実現できましたね!本来はもちろんクライアントのアプリケーションから暗号化することが望ましいとは思いますが、色々な事情でこれができないプロジェクトもございます。その際には是非この仕組みをご検討頂ければ幸いです。

― ソラコム松永 (taketo)