LoginSignup
5
2

More than 3 years have passed since last update.

プロキシに苦しむ人が IoTHub DeviceStreamなWebJobsを踏み台にして インターネットに自由に出た話

Posted at

はじめに

WebProxyにアクセス制限されまくって仕事にならない皆さん、こんにちは。

最近、LINEMessageAPIを使うサーバーサイドの開発をしたのですが、
WebProxyがline.meをブロックするせいで、
アプリ登録のサイトや、マニュアル、デベロッパーコミュニティにアクセスできず、
とても生産性が低かったです。
仕方がないので、最近リリースされた、IoTHub DeviceStreamを活用して
WebProxyを無理矢理突き抜けてみた話です。

DeviceStreamって何

簡単に言うと『アウトバウンド同士でWebSocketのハンドシェイクができちゃう素敵サービス』
詳しくは前に書いた↓を参照してください。
Azure IoT Hub デバイス ストリームを試してみた

構成図

image.png

構成要素の説明

ServerSideProxy

  • WebJob上のWebプロキシ

    • WebAppsのWebJobs上にWebプロキシを配置します
    • C#のライブラリTitanium-Web-Proxyを利用しています
    • 接続の待ち受けは環境変数WEBJOBS_PORTで渡されるポートを参照します
  • デバイス接続(DeviceStream)

    • 起動したら、WebJobsからIoTHubにデバイス接続で接続し、DeviceStream接続の待ち受けを行います
    • DeviceStreamの接続要求が来たら、受け入れて、WebSocketの接続を確立します
    • WebSocketから来たデータはすべてWebJob上のWebプロキシに渡します。
    • WebJob上のWebプロキシから来たデータはすべてWebScoketに渡します。

ClientSideProxy

  • ローカルWebプロキシ

    • 任意のポートでHTTP接続を待ち受けます
    • C#のライブラリTitanium-Web-Proxyを利用しています
    • 上流のWebプロキシとして、サービス接続(DeviceStream)の待ち受けポートを指定しています
  • サービス接続(DeviceStream)

    • IoTHubへの接続は、インターネットに出られるWebプロキシを経由します
    • 起動したら、IoTHubにサービス接続で接続し、DeviceStream接続の要求を行います
    • DeviceStreamの接続要求の受託応答を受けて、WebSocketの接続を確立します
    • WebSocketから来たデータはすべてクライアント(ローカルWebプロキシ)に渡します。
    • クライアント(ローカルWebプロキシ)から来たデータはすべてWebScoketに渡します。

問題点

  • IoTHubのDeviceStreamはパブリックプレビュー中で、米国中部しか対応していない!!
    • ⇒すべての通信が米国中部経由…
  • 職場のセキュリティーポリシー的にやっちゃだめ!!
    • ⇒ご利用は自己責任で

FAQ

  • ローカルWebプロキシいらなくね?
    • ⇒たしかに でも実装してみると、TCPコネクションの切断時の挙動が安定せず仕方なく
  • SSHポートフォワーディングでいいじゃん??ばかなの??
    • 全部PaaSだよ???^q^
  • 認証プロキシは?
    • ソースを煮るなり焼くなり…

使い方

ServerSideProxy

  • リソース
    • IoTHubを米国中部に建てる
      • デバイスを適当に登録する
    • AppService B1以上を立てる
      • WebAppsをデプロイ
      • AppSettingsにIOTHUB_CONNECTION_STRINGを指定する
        • HostName=<HOST>.azure-devices.net;DeviceId=<DEVICE_ID>;SharedAccessKey=<KEY>
  • WebJobsをPublish
  • ポータルからWebJobを起動

ClientSideProxy

  • 起動する
dotnet WebProxyOverIoTHub.ClientSideProxy.dll  ^
--IoTHubServiceConnectionString=HostName=<HOST>.azure-devices.net;SharedAccessKeyName=<KEY_NAME>;SharedAccessKey=<KEY> ^
--TargetDeviceId=<DEVICE_ID> ^
--LocalDeviceStreamPort=<PORT_DEVICE_STREAM> ^
--LocalInternalWebProxyPort=<PORT_WEB_PROXY> ^
--UpstreamWebProxy=<UPSTREAM_WEB_PROXY> ^
--StreamName=<YOUR_CLIENT>
  • ブラウザのプロキシをlocalhost:<PORT_WEB_PROXY>に向ける

課題

  • 異常系処理が弱い(気がする)
  • コードが汚い(助けて)

おわりに

せいさんせい が たかまった ので ていじだっしゅ が はかどった

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2