こんにちは!ソラコムの今井(ニックネーム: factory)です。昔、イマイファクトリーという名前でグラフィックデザインなどをやっておりました。
IoTを活用してデバイスの遠隔メンテナンスの仕組みを作っていると、ユーザーにIoTデバイスへのリモートデスクトップ環境を提供したい!でも専用のソフトウェアをインストールしてもらったり、社内のプロキシの設定を変えてもらったりというのはハードルが高い!そんなお悩み、ありませんか?
今回は、そんなお悩みを解決するための仕組みを考えてみたいと思います。ざっくりした構成としては以下のような形で、Amazon AppStream 2.0(以下、AppStream)と、SORACOM Napter(以下、Napter)を利用していきます。
以前、AppStreamを使ってIoTデバイスへのリモートアクセスを実現するための構成についてのブログ記事を書いたことがあります。AppStreamを使うという点で今回の記事と似ていますが、こちらの記事はエンタープライズユーザー向けのリモートデスクトップ環境についての議論です。
Amazon AppStream 2.0でデバイスへのリモートアクセスを安全かつ簡単に
AppStreamとNapterを使う理由
AppStreamはAWSが提供するマネージドなエンドユーザーコンピューティングサービスで、WindowsやLinuxのデスクトップ環境をブラウザにストリーミングしてくれます。平たく言えばシンクライアント環境を提供してくれるマネージドサービスです。ポイントは「ブラウザからHTTPSアクセスできる」というところで、ユーザーのPCにクライアントソフトウェア等をインストールしたり、企業ネットワークのプロキシで特別なポートを開けてもらったりする必要がないというメリットがあります。
NapterはオンデマンドにIoTデバイスへのアクセスを提供するサービスです。通常、SORACOMのネットワークは外部からアクセスできないようになっていますが、Napterを使うとアクセス先のデバイスとポート番号、アクセス元のIPアドレスレンジと利用可能な期間を指定して、外部ネットワークからターゲットのIoTデバイスまでのポートフォワーディングを提供してくれるサービスです。デバイスへのアクセスのために専用のネットワークやサーバーを用意する必要がないので非常に簡単に利用できるようになっています。
これらの便利なサービスを組み合わせてリモートデスクトップ(以下、RDP)のための構成をつくっていきます。
早速やってみる
より具体的に使い勝手をイメージしていただくために動作フローを書き出してみます。せっかくやってみるので、ブラウザでAppStreamのデスクトップにアクセスして、RDPクライアントを開いて、そこにNapterで払い出されたエンドポイントを入力してアクセス・・・というのではなく、「ブラウザにアクセスしたら目的のデバイスへRDP接続完了している」というところを目指してやってみたいと思います!
準備1 – AppStreamのマシンイメージを準備する
まず、前述の「RDPクライアントをインストールしたAppStream環境」を事前に準備しておく必要があります。これについては下記のAWSのドキュメントを参照して進めてもらえればよいでしょう。
作業のざっくりしたイメージとしてはImage Builderと呼ばれるマシンイメージからデスクトップを起動して、そこに好きなプログラム(今回はRDP。そして RDP クライアント自体はWindowsにバンドルされている)をインストールして、スナップショットイメージを作成する、といった作業です。
今回の場合「起動時にアクセス先のエンドポイントを引数として渡してRDPクライアントを起動する」ということを実現するために以下のようなbatファイルを作成して、これをImage BuilderでAppStreamのアプリのひとつとして登録します。
やっていることは “C:\Windows\System32”ディレクトリに移動して、mstsc.exe(RDPクライアントの実体)を実行するという単純なスクリプトです。ここで %APPSTREAM_SESSION_CONTEXT%という引数を渡していますが、これはAppStreamのセッション起動時に渡されたパラメータがここに展開されます。
CD “C:\Windows\System32”
Start mstsc.exe %APPSTREAM_SESSION_CONTEXT%
mstsc.exeは /v:127.0.0.1:3389 というような形でRDPのターゲットを引数を受け取ると、起動時にそこにアクセスしてくれます。流れを全部つなげると、AppStreamのセッション起動時に上記のスクリプトを起動アプリとして指定し、さらに /v:127.0.0.1:3369 という引数を渡してやることにより、ブラウザでアクセスしたとたんにRDPでターゲットにアクセスする、ということが実現できます。
準備2 – AppStreamのFleetをVPCのPrivate Subnetに配置し、NATGWを設定する
Napterは「指定した時間の間だけ、指定したソースIPアドレスからのポートフォワードを受け付ける」という仕組みによってセキュリティを提供しています。つまり、Napterを利用するにはAppSteamからNapterへアクセスする際のソースIPアドレスを特定してやる必要があります。
この実現方法としては、AppStreamのFleet(AppStreamを実行する環境。インスタンス群のようなもの。)をAmazon VPC(以下、VPC)のプライベートサブネットに配置し、外部へのアクセスにNAT Gatewayを用いるのがよいでしょう。NAT GatewayにはElastic IP Address(ざっくりいえば固定のグローバルIPアドレス)をアサインすることができますので、これをNapterへアクセスする際のソースIPアドレスとして利用します。
構成は以下のようなイメージです。より詳細な情報については下記を参照してください。
プライベートサブネットの VPC および NAT ゲートウェイを設定する
実行
IoTデバイスへのRDPアクセスをする際には毎回次のような操作を繰り返すことになります。
1. NapterでターゲットのIoTデバイスへの3389番ポートのポートマッピングを作成する
RDPはデフォルトでは3389番ポートを利用しますので、ポートは3389を、そしてアクセス元にはNAT GatewayのElastic IP Addressを指定してポートマッピングを作成してください。コンソールで実行する場合、出力された結果の以下の「IPアドレス」のところをコピーしておいてください。
2AppStreamでセッションURLの作成を行う
AppStreamはCreateSessionUrlというAPIがあり、これを呼び出した結果として出力されるURLにアクセスすることでAppStreamのデスクトップセッションが起動されます。AWSCLIを使ってやってみる際は以下のようなコマンドになります。
aws appstream create-streaming-url –stack-name ExampleStack –fleet-name ExampleStack-fleet –user-id factory –application-id RemoteDesktopBat –session-context ‘/v:”13.114.236.244/32″‘
それぞれのパラメータは以下のような意味を持ちます
–stack-name: 利用するAppStreamのStack名。ここでは詳細に触れません。
–fleet-name: 利用するAppStreamのFleet名。ここでは詳細に触れません。
–user-id: デスクトップにログインするユーザー名。ここでは詳細に触れません。
–application-id: AppStreamのセッション開始時に起動されるアプリケーションです。前述の準備パートで用意したbatファイル(をImage Builderに登録した名前)を指定してください。なお、これを空欄でCreateSessionUrlした場合、アプリケーション選択画面からAppStreamセッションが開始されます。
–session-context: 上記のapplication-idで指定されたプログラムにわたされる引数です。今回の場合、Napterで払い出されたエンドポイントをここに ‘/v: “aaa.bbb.ccc.ddd:eeeee”’ という形で指定します。この引数の内容が、先ほどのbatファイルの %APPSTREAM_SESSION_CONTEXT% に渡されます。
というステップを踏んでいただくと、以下のような流れでAppStreamのセッションURLが払い出され、そこに「アクセスしたらターゲットのIoTデバイスへのRDPが始まる」ということができるようになります。(デモ動画はRDPセッションを作成しにいったところで終わっています)
自動化
この一連の流れを自動化してやるには、以下のようなクラウドアプリ(シーケンス図のなかのCloudのところ)を実装してやればよいでしょう。
まとめ
いかがでしたでしょうか。この方法を使えば、専門の知識をもっていない方や、みなさまのお客様に対しても簡単にIoTデバイスへのリモートデスクトップが提供できます(もちろんリモートデスクトップとは別のアプリケーションでも実現可能です)。
構成の細かい部分は背景や事情によって変わってくると思いますが、アプリケーションやサービス開発の際のひとつのアイデアになれば幸いです!
― ソラコム今井 (factory)