2015年11月19日木曜日

IoTpack(SORACOM)でProxy(Squid)


"cloudpack"には"SORACOM"さんのサービスを利用した「IoTpack」という商品があります。


この商品は簡単にいえば、SORACOMのVPCと自分のVPCを"VPC Peering"で接続し、
"SORACOM Air"のSIMを利用したデバイスからの通信を、インターネットに出ることなく
自分のVPC上のサーバで処理することができるものとなっています。


ということで下記のようにIoTpackを利用して"Air SIM"のiPhoneのHTTP(S)通信が
自分のVPC上のProxyサーバ(Squid)経由でインターネットに出て行くようにしてみました。


EC2上には下記のようにSquidを用意しておきます。
("no_cache deny all"でキャッシュしないようにしています)
$ sudo yum -y install squid
...

$ sudo cat /etc/squid/squid.conf
http_port         3128
visible_hostname  cloudpack
http_access allow all
no_cache deny     all

$ sudo service squid start
Starting squid:                                            [  OK  ]

環境はIoTpackとしてもらったので、
いきなりiPhoneからの上記のProxy用のEC2の"Private IP"にPingできてました。


さらに上述のProxyサーバを利用するには、
iPhoneのプロファイルを調整する必要があります。

プロファイルは下記のツールで「構成プロファイル」として作成することができます。
iPhone 構成ユーティリティ 2.2 (Mac)
今回の構成プロファイルは次のように作成しています。



「アクセスポイント」に関してはSORACOMの情報を入力し、
さらに「プロキシサーバとポート」で上記のProxyサーバの情報を入れています。

このプロファイルはMacにiPhoneをUSBでつなぎ、
上記ツールからインストールすることができます。(既存のプロファイルは削除しています)


この状態で、iPhoneからSafariで適当なURL(http://cloudpack.jp)にアクセスすると、
Squidのログより、iPhoneのHTTP(S)の通信がProxy経由になっていることが確認できます。
1447883093.478    173 100.64.128.67 TCP_MISS/200 34431 GET http://cloudpack.jp/ - DIRECT/54.239.194.249 text/html
1447883093.622      9 xxx.xxx.xxx.xxx TCP_MISS/200 2037 GET http://cloudpack.jp/js/jquery.browser.min.js - DIRECT/54.239.194.249 application/x-javascript
1447883093.630     17 xxx.xxx.xxx.xxx TCP_MISS/200 19145 GET http://cloudpack.jp/css/common/layout.css - DIRECT/54.239.194.249 text/css
1447883093.631     18 xxx.xxx.xxx.xxx TCP_MISS/200 16280 GET http://cloudpack.jp/css/index.css - DIRECT/54.239.194.249 text/css
1447883093.634     13 xxx.xxx.xxx.xxx TCP_MISS/200 4054 GET http://cloudpack.jp/js/jquery.easing-1.3.min.js - DIRECT/54.239.194.249 application/x-javascript
1447883093.634     17 xxx.xxx.xxx.xxx TCP_MISS/200 22487 GET http://cloudpack.jp/js/common.js - DIRECT/54.239.194.249 application/x-javascript
1447883093.665     52 xxx.xxx.xxx.xxx TCP_MISS/200 34120 GET http://cloudpack.jp/css/common/general.css - DIRECT/54.239.194.249 text/css
...

さらに、ユーザー認証(Basic)もかけてみます。Squidの設定は下記の通りです。
$ sudo cat /etc/squid/squid.conf
http_port         3128
visible_hostname  cloudpack
no_cache deny     all
auth_param basic  program /usr/lib64/squid/ncsa_auth /etc/squid/squid.htpasswd
auth_param basic  children 5
auth_param basic  credentialsttl 1 hours
acl               password proxy_auth REQUIRED
http_access allow password
http_access deny  all

$ sudo service squid restart
Stopping squid: ................                           [  OK  ]
Starting squid: .                                          [  OK  ]

ちゃんと認証画面も表示されました。


ログを見ると、今度は、そのユーザーがどこに接続したかまで、わかるようになります。
1447890752.703     13 xxx.xxx.xxx.xxx TCP_MISS/200 601 GET http://cloudpack.jp/img/index/visual_bg.gif suzuki DIRECT/54.239.194.50 image/gif
1447890752.717     12 xxx.xxx.xxx.xxx TCP_MISS/200 651 GET http://cloudpack.jp/img/common/bg_01.png suzuki DIRECT/54.239.194.50 image/png
1447890752.730     10 xxx.xxx.xxx.xxx TCP_MISS/200 2454 GET http://cloudpack.jp/img/index/btn_bg.gif suzuki DIRECT/54.239.194.50 image/gif
1447890752.730      9 xxx.xxx.xxx.xxx TCP_MISS/200 816 GET http://cloudpack.jp/img/common/line02.gif suzuki DIRECT/54.239.194.50 image/gif
1447890752.739     14 xxx.xxx.xxx.xxx TCP_MISS/200 1858 GET http://cloudpack.jp/img/index/attention_bg.gif suzuki DIRECT/54.239.194.50 image/gif
...

今回は典型的な例としてProxyを試してみましたが、
このようにiPhoneからの(SIMでの)通信も閉域網内の通信として扱え、
いろいろと(社内サーバで処理)できそうなことがわかりました。

夢が広がります。

2015年11月7日土曜日

本ブログのLambda関係の記事をまとめてみた


"AWS re:Invent 2015"の下記Lambda関係の発表を機に書きだしましたが、
【AWS発表】AWS Lambdaのアップデート – Python, VPC, 実行時間の延長, スケジュールなど
何を書いたか、自分でもわからなくなってきたので、一旦まとめてみました。
Cognitoがない...

2015年11月6日金曜日

Lambda(Python)からKinesisにPut(API)してLambda(Python)でGet(Event)する


こんな感じです。


API(Boto3)でPutするのは、まあ当たり前ですが、Getに関しては、
Lambdaの"event source"にKinesisというものがあり、それを設定することにより
イベントドリブンでKinesisのデータをLambdaで処理することができます。

ということで、作ってみます。

Kinesisの作成


AWSマネジメントコンソールより下記のように作成します。


IAMの設定


Lambdaに設定するIAMロール(lambda_basic_exection)にKinesisが扱える
マネージドポリシー(AmazonKinesisFullAccess)をアタッチします。

 

KinesisへPutするLambdaファンクション


コードは、こんな感じです。
import logging
import boto3

def lambda_handler(event, context):

    logger = logging.getLogger()
    logger.setLevel(logging.INFO)

    try:
        logger.info(event)
        response = boto3.client('kinesis').put_record(
            StreamName = "test",
            Data = "test",
            PartitionKey = "test",
        )
        logger.info(response)
        return response

    except Exception as e:
        logger.error(e)
        raise e

実行すると、レスポンスは次のように返ってきます。
{
  "ShardId": "shardId-000000000000",
  "ResponseMetadata": {
    "HTTPStatusCode": 200,
    "RequestId": "eef4ccde-840d-11e5-9d26-6b863e58e437"
  },
  "SequenceNumber": "49556079134761214959115455796946952254907110183804076034"
}

Kinesisのモニタリングで確認しても、
ちゃんとPutレコードがカウントされていることがわかります。


KinesisからGetするLambdaファンクション


コードは、こんな感じです。
import logging
import base64

def lambda_handler(event, context):

    logger = logging.getLogger()
    logger.setLevel(logging.INFO)

    try:

        logger.info(event)

        payloads = []
        for record in event['Records']:
            payload = base64.b64decode(record["kinesis"]["data"])
            payloads.append(payload)
        logger.info(payloads)

        return payloads

    except Exception as e:
        logger.error(e)
        raise e

そして、Event Sourceとして、Kinesisを追加します。


CloudWatch Logsを確認すると、ちゃんとKinesisのEvent Sourceを設定した、
Lambdaファンクションが実行されログが出力されていることがわかります。


CloudWatchのMetricsでもGetリクエストで確認することができます。