Amazon Web Service Dash buttonを作ってみた

# はじめに
![awsボタン.jpg](https://qiita-image-store.s3.amazonaws.com/0/26677/66281a69-7cee-268a-3ebd-354693430cb2.jpeg)

タイトル落ち。 やっぱ今時のインフラエンジニアはボタン1つでサーバの1つもできるようにしてないとね。
n番煎じなpacketをsniffしてdashボタンのイベントを拾うやつ(python on ubuntu)に、下な感じのaws cliを叩いただけのものをやってみた。

- Amazon EC2 Dash Button(EC2のVM作る)
- Aws Lambda Dash Button(lamdaをinvoke)

概ね以下の参考記事の再現です。
[How I Hacked Amazon’s $5 WiFi Button to track Baby Data – Medium](https://medium.com/@edwardbenson/how-i-hacked-amazon-s-5-wifi-button-to-track-baby-data-794214b0bdd8#.825ipgd1o)




# Dashボタンのセットアップ

わかりやすい解説。 -> [Amazon Dash Button超速解説 - Qiita](http://qiita.com/ma2shita/items/b2fbaabf398db4324275)

0. amazonでDashボタンをポチってお家に届く
0. amazonのスマフォアプリを起動(取説の通り)
0. 左上メニュー→「アカウントサービス」→「Dash端末 新しい端末をセットアップ」を選択(取説の通り)
0. LED青になるまでDashボタンを6秒長押し(取説の通り)
0. アプリで「接続」(取説の通り)
0. アプリでwifi接続情報入力(取説の通り)
0. 商品を選ばない(取説と違う)

# Dashボタンのイベントを拾う

## python環境の準備

```bash
$ sudo apt-get install tcpdump python-crypto python-scapy
# scapyを使いたいだけだけどあれこれいれる

$ pip show scapy
Name: scapy
Version: 2.2.3
Location: /usr/lib/python2.7/dist-packages
Requires:
# scapyがインストールできてればOK

```

## DashボタンのMACアドレスの取得

dash-listen-1.pyを作成して実行。

```py:dash-listen-1.py

from scapy.all import *

def arp_display(pkt):
  if pkt[ARP].op == 1: #who-has (request)
    if pkt[ARP].psrc == '0.0.0.0': # ARP Probe
      print "ARP Probe from: " + pkt[ARP].hwsrc

print sniff(prn=arp_display, filter="arp", store=0, count=10)

```

- もし必要ならARP Probe置き換える

```bash
$ sudo python dash-listen-1.py 
WARNING: No route found for IPv6 destination :: (no default route?)
# ここまで出力されるのでDashボタンを押下
ARP Probe from: XX:XX:XX:XX:XX:XX
ARP Probe from: XX:XX:XX:XX:XX:XX
ARP Probe from: XX:XX:XX:XX:XX:XX
^C[]
$ 

```

これでMACアドレスとれる。

## サンプルコードでDashボタンイベントを取得

引き続きdash-listen-2.pyを作成して実行。

```py:dash-listen-2.py

from scapy.all import *
def arp_display(pkt):
  if pkt[ARP].op == 1:
    if pkt[ARP].psrc == '0.0.0.0': # ARP probe as your env
      if pkt[ARP].hwsrc == 'XX:XX:XX:XX:XX:XX': # MAC address as your env 
        print "Amazon dash button Pushed."
        sys.exit()

print sniff(prn=arp_display, filter="arp", store=0, count=10)
```

- もし必要ならARP Probe置き換える
- MACアドレスは上記で取得したものへ書き換える
- "sys.exit()"は「サンプルコードでイベント取得」の通り複数回パケット拾うので最初の1つ処理したら終了するため

```bash

$ sudo python dash-listen-2.py 
WARNING: No route found for IPv6 destination :: (no default route?)
# ここまで出力されるのでDashボタン押下
Amazon dash button Pushed.
$

```

これでイベント拾えるようになる。

# Amazon Web Service Dash button
さて、いよいよ本題だけど結局は↑の「print "Amazon dash button Pushed."」をaws cliのしょぼいコマンドに置き換えてるだけである。

以下は準備してある前提。

- aws cliを導入してaws configureで認証済
- ec2のamiは既存(今回はamazon linuxのライブラリにあるの)
- lamda関数は作成済(およびIAM)

## Amazon EC2 Dash Buttonやってみた

dash-ec2.pyを作成。

```py:dash-ec2.py

from scapy.all import *
def arp_display(pkt):
  if pkt[ARP].op == 1: #who-has (request)
    if pkt[ARP].psrc == '0.0.0.0': # ARP probe as your env
      if pkt[ARP].hwsrc == 'XX:XX:XX:XX:XX:XX': # MAC address as your env 
        print "Amazon EC2 dash button Pushed."
        os.system("aws ec2 run-instances --image-id ami-0c11b26d --count 1 --instance-type t2.micro")
        # ここ追加しただけ(その上のprintの文言もちょっと変えてる)
        sys.exit()

print sniff(prn=arp_display, filter="arp", store=0, count=10)

```

- 雑にEC2のインスタンスを作る
- ami-0c11b26dはamazon linuxのプレーンなやつ

以下、実行前のコンソール(インスタンスいない)
![before.png](https://qiita-image-store.s3.amazonaws.com/0/26677/4791a1bd-84d1-083c-2b51-6faba750925e.png)


んで実行。

```bash

$ sudo python  dash-ec2.py 
WARNING: No route found for IPv6 destination :: (no default route?)
# ここまで出力されるのでDashボタン押下
Amazon EC2 dash button Pushed.
{
    "OwnerId": "XXXXXXXXXXX", 
    "ReservationId": "XXXXXXXXXX", 
    "Groups": [], 
    "Instances": [
        {
            "Monitoring": {
                "State": "disabled"
            }, 
            "PublicDnsName": "", 
            "RootDeviceType": "ebs", 
            "State": {
                "Code": 0, 
                "Name": "pending"
            }, 
            "EbsOptimized": false, 
            "LaunchTime": "2016-12-06T11:48:25.000Z", 
            "PrivateIpAddress": "XXX.XXX.XXX.XXX", 
            "ProductCodes": [], 
            "VpcId": "vpc-XXXXXXXXXX", 
            "StateTransitionReason": "", 
            "InstanceId": "i-98abXXXXX", 
            "ImageId": "ami-0c11b26d", 
...

```

以下、実行後のコンソール。(ちゃんとボタン1つでインスタンスできてる! i-98abXXXXXなの)
![after.png](https://qiita-image-store.s3.amazonaws.com/0/26677/16c75e68-ac9c-889c-3d35-8b5d1cad70cc.png)


## Aws Lambda Dash Buttonやってみた

今回はhelloworldというまんまなファンクションを事前に作成済。
![lambda.png](https://qiita-image-store.s3.amazonaws.com/0/26677/b3f52fe3-7553-1c3a-bd5c-f15bc6de0b72.png)
まさに"Hello from Lambda"って出力するだけのもの。

dash-lambda.pyを作成して。

```py:dash-lambda.py

from scapy.all import *
def arp_display(pkt):
  if pkt[ARP].op == 1: #who-has (request)
    if pkt[ARP].psrc == '0.0.0.0': # ARP probe as your env
      if pkt[ARP].hwsrc == 'XX:XX:XX:XX:XX:XX': # MAC address as your env 
        print "Aws lambda button Pushed."
        os.system("aws lambda invoke --invocation-type RequestResponse --function-name helloworld --region ap-northeast-1 --log-type Tail --payload '{}' output.txt")
        # ここ追加しただけ(その上のprintの文言もちょっと変えてる)
        sys.exit()

print sniff(prn=arp_display, filter="arp", store=0, count=10)

```

んで実行。

```bash

$ sudo python dash-lambda.py 
WARNING: No route found for IPv6 destination :: (no default route?)
# ここまで出力されるのでDashボタン押下
Aws lambda button Pushed.
{
    "LogResult": "XXXXXXXXXXXXXX", 
    "StatusCode": 200
}
$ cat output.txt 
"Hello from Lambda"$ 
# 出力結果とれてる!

```

てな感じで実行できた。

# おわりに

- ぱっとググってもでてこなかったので今しかないと思って勢いでやった
- しかし「amazon dash button (プログラミング言語)」とかググると海外勢の記事がいくらでも見つかったので便利
- そもそもAmazon IoT Buttonが日本でもでてれば... [AWS IoT Buttonを分解してみた #reinvent ｜ Developers.IO](http://dev.classmethod.jp/cloud/aws/decomposition-aws-iot-button/)
- 実は最初はwindowsでやろうと思ってたけどscapy入れるのが最高にめんどくさくて、気づいたらchromebookにubuntuいれてその上でやってた
- ボタン1つでサーバできるのちょっと感動したし、社内のアプリエンジニアにいい値段で売れるのでは?
- そして遊んでたらスマフォの通知面白いことにw

![スマフォのスクショ.png](https://qiita-image-store.s3.amazonaws.com/0/26677/ca02065e-dc99-ff18-338d-8241dccb5e4d.png)

- 使い終わったので無効化+リセットしといた。 [Amazon.co.jp ヘルプ: Dash Buttonを無効化する](https://www.amazon.co.jp/gp/help/customer/display.html?nodeId=201746400)

以上。