AWS IoT Greengrass環境の設定
UbuntuにAWS IoT Greengrass Coreソフトウェアをインストールして、Greengrass利用環境を作成する手順を確認します。
環境
事前準備
Greengrassモジュールとなる AWS IoT Greengrass Core
をインストールするにあたり、前提条件を確認します。下記を参考にしつつ作業を実施しています。
OSユーザー・グループの作成
作成します。
$ sudo adduser --system ggc_user $ sudo groupadd --system ggc_group
このOSユーザーは、Greengrass上でLambdaを実行する際に利用されるユーザーとのことです。
ハードウェア/ソフトウェア・シンボリックリンクの保護設定
fs.protected_hardlinks
と fs.protected_symlinks
の設定値が1となっている事を確認します。
$ sudo sysctl -a | grep fs.protected fs.protected_fifos = 1 fs.protected_hardlinks = 1 fs.protected_regular = 2 fs.protected_symlinks = 1
シンボリックリンクの保護についてよく分からず検索。RedHatのマニュアルでしたが詳細を記載してくれていました。
To prevent malicious users from exploiting potential vulnerabilities caused by unprotected hard and symbolic links, Red Hat Enterprise Linux 7 includes a feature that only allows links to be created or followed provided certain conditions are met.
In case of hard links, one of the following needs to be true:
・The user owns the file to which they link.
・The user already has read and write access to the file to which they link.
In case of symbolic links, processes are only permitted to follow links when outside of world-writeable directories with sticky bits, or one of the following needs to be true:
・The process following the symbolic link is the owner of the symbolic link.
・The owner of the directory is the same as the owner of the symbolic link.
4.2.6. Protecting Hard and Symbolic Links
Symlink race
というシンボリックリンクを利用した脆弱性があるんですね。
cgroupのマウント
cgroup用ファイルシステムをマウントします。AWS側で用意してくれているシェルスクリプトをダウンロードして実行します。Ubuntuであれば、デフォルトにて既にマウントされている筈なので、特に何か設定される事はないです。
$ curl https://raw.githubusercontent.com/tianon/cgroupfs-mount/951c38ee8d802330454bdede20d85ec1c0f8d312/cgroupfs-mount > cgroupfs-mount.sh $ chmod +x cgroupfs-mount.sh $ sudo bash ./cgroupfs-mount.sh
Greengrass上でLambdaを実行させる場合、LambdaはGreengrassにて用意されたコンテナ環境上で実行されることになり、そのためにcgroupfsが必要となっています。Greengrass上Lambdaの動作に関しては以下を参照。
Java Runtimeのインストール
バージョン8をインストールします。
$ sudo apt install openjdk-8-jdk $ java -version openjdk version "1.8.0_252" OpenJDK Runtime Environment (build 1.8.0_252-8u252-b09-1ubuntu1-b09) OpenJDK 64-Bit Server VM (build 25.252-b09, mixed mode)
Python3.7のインストール
Greengrass上でLambdaを動かす場合、当然そのためのRuntimeが必要になります。今後Python3.7のプログラムを動かす予定あるため、Python3.7をインストールしておきます。Ubuntu20のプリインストールされたPythonバージョンは3.8でした。
Python3.7をインストールできるPPA(Personal Package Archive)を探してきてリポジトリを追加、インストールします。
$ sudo add-apt-repository ppa:deadsnakes/ppa
$ sudo apt-get update
$ sudo apt-get install python3.7
依存関係の確認
依存関係を満たしているか、確認用シェルスクリプトを実行します。これもAWS側で用意してくれているので、ダウンロードして実行します。
$ wget https://github.com/aws-samples/aws-greengrass-samples/raw/master/greengrass-dependency-checker-GGCv1.10.x.zip $ unzip greengrass-dependency-checker-GGCv1.10.x.zip $ cd greengrass-dependency-checker-GGCv1.10.x $ sudo ./check_ggc_dependencies | more
僕の環境では、Javaが見つからないと言われました。以下参考。
----------------------------Commands and software packages-------------------------- Python 2.7: Not found Python 3.7 version: 3.7.7 NodeJS 12.x: Not found Java 8: Not found
シェルスクリプトの中身を見てみると java8
というコマンドにて探しているみたいで、以下のようなシンボリックリンクを作成した後に、再度チェックスクリプトを実行すると Not found
ではなくなりました。
$ sudo ln -s /usr/bin/java /usr/local/bin/java8 $ java8 -version openjdk version "1.8.0_252" OpenJDK Runtime Environment (build 1.8.0_252-8u252-b09-1ubuntu1-b09) OpenJDK 64-Bit Server VM (build 25.252-b09, mixed mode)
該当シェルスクリプトのReadmeはこちら。
Greengrass core v1.10.x dependencies checker
AWS IoT側の準備
Greengrassと通信することになるAWS IoT側の設定を実施します。参考マニュアルはこちら。
AWS IoT の AWS IoT Greengrass の設定
AWS IoTのAWSコンソールに行き、Greengrassの Get started
ページを開きます。
create a Group
をクリックします。
Greengrassが他のAWSサービスをアクセスするため、必要なIAMポリシーをもったService-Linked IAM Roleを作成し、Greengrassにアタッチします。 Grant permission
をクリックします。
作成し付与されたService-Linked Roleは、以下コマンドにて確認できます。
$ aws greengrass get-service-role-for-account --region ap-northeast-1 { "AssociatedAt": "2020-06-09T14:28:34Z", "RoleArn": "arn:aws:iam::12345678901:role/service-role/Greengrass_ServiceRole" }
IAM Roleのより詳細を確認すると、 AWSGreengrassResourceAccessRolePolicy
というIAMポリシーが付与されており、AWS IoTやLambda、S3等に対するアクセス権限を与えられています。
続いて、具体的なGreengrass向け設定を行います。 Use Default creation
をクリックします。
作成するGreengrass Group名を入力します。
Greengrassグループが良く分からず、マニュアルを確認したのですが、それでもあまり理解できず。
Greengrass グループは、Greengrass コア、デバイス、サブスクリプションなどのコンポーネントと設定のコレクションです。グループは、操作の範囲を定義するために使用されます。たとえば、グループは建物の 1 つの階、1 台のトラック、または採掘現場全体を表します。
結局、Greengrassグループ単位でLambdaがデプロイされることになるので、それを踏まえてグループ単位を考えてあげればいいのでは、と考えています。
続いて、Greengrass Core名を入力します。
これもイマイチ分からなかったのですが、連携されるIoT機器がここで設定した名前にて、AWS IoTのThingsとして管理されることになります、ということは理解しました。
AWS IoT Greengrass コア は、エッジ環境でハブまたはゲートウェイとして機能する AWS IoT のモノ (デバイス) です。他の AWS IoT デバイスと同様に、コアはレジストリ内にあり、デバイスシャドウを保持し、AWS IoT を認証するデバイス証明書を使用します。コアデバイスは AWS IoT Greengrass Core ソフトウェアを実行します。これによって、通信、車道同期やトークン交換などの Greengrass グループのローカルプロセスを管理することができます。
実行される内容を確認して、 Create Group and Core
をクリックします。
デフォルトを利用して作成される設定を確認しています。
Create a new Greengrass Group in the cloud
その名の通り、Greengrassグループを作成してくれています。
Provision a new Core in the IoT Registry and add to the Group
Greengrass CoreをThingsとして登録してくれています。
Generate public and private key set for your Core
IoT機器側にインストールされるGreengrass CoreソフトウェアとAWS IoTとは、デバイス証明書と呼ばれるX.509証明書(公開鍵証明書)により通信することになります。そのため、X.509証明書作成用の秘密鍵と公開鍵を作成しています。作成された鍵ファイルは、次のステップでダウンロードすることになります。
Generate a new security certificate for the Core using the keys
上述の公開鍵と秘密鍵によりX.509証明書を作成しています。この証明書も、次のステップでダウンロードすることになります。
Attach a default security policy to the certificate
上述の証明書と紐づくIoTポリシーを作成しています。作成されたポリシーは下記でした。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "iot:Publish", "iot:Subscribe", "iot:Connect", "iot:Receive" ], "Resource": [ "*" ] }, { "Effect": "Allow", "Action": [ "iot:GetThingShadow", "iot:UpdateThingShadow", "iot:DeleteThingShadow" ], "Resource": [ "*" ] }, { "Effect": "Allow", "Action": [ "greengrass:*" ], "Resource": [ "*" ] } ] }
Enable stream manager on the Core device
作成したGreengrassグループでのStream Manger機能を有効としています。
AWS IoT Greengrass コアでのデータストリームの管理
Download these resource as a tar.gz
をクリックします。作成された各鍵ファイルと証明がダウンロードされます。
AWS IoT Greengrass Coreの起動設定
Ubuntu側にて、AWS IoT Greengrass Coreをインストールして起動します。参考マニュアルはこちら。
コアデバイスでの AWS IoT Greengrass の起動
鍵・証明書ファイルのアップロード
前述の処理にてダウンロードしたtarファイルを、Ubuntuにアップロードします。
AWS IoT Greengrass Coreソフトウェアのダウンロード
動作させるGreengrass Coreソフトウェアを、Ubuntuにダウンロードします。
$ wget https://d1onfpft10uf5o.cloudfront.net/greengrass-core/downloads/1.10.1/greengrass-linux-x86-64-1.10.1.tar.gz
ダウンロードURLは、以下のページより確認できます。
tarファイルの展開
Ubuntu上に持ってきた鍵・証明書ファイルとGreengrass Coreソフトウェアのtarファイルを展開します。展開先は /
直下としています。
$ sudo tar -xzvf greengrass-linux-x86-64-1.10.1.tar.gz -C / $ sudo tar -xzvf xxxx-setup.tar.gz -C /greengrass
鍵・証明書ファイルのtarファイル内には、Greengrass Coreソフトウェア向けのコンフィグファイルも入っています。 /greengrass/config/config.json
というファイルにて配布されているはずです。必要な設定は既に設定済となっているため編集は不要ですが、設定可能なパラーメーターは以下マニュアルにて確認できます。
AWS IoT Greengrass Core 設定ファイル
ルートCA証明書のダウンロード
AWSのルートCA証明書をダウンロードします。ダウンロード先は、先程証明書一式を展開した /greengrass/certs
フォルダ内となります。
$ cd /greengrass/certs/ $ sudo wget -O root.ca.pem https://www.amazontrust.com/repository/AmazonRootCA1.pem
Greengrass Coreソフトウェア起動用のユニットファイルの作成
Greengrass Coreソフトウェアを自動起動とする、Systemdユニットファイルを作成します。今回作成したユニットファイルは下記。
/etc/systemd/system/greengrass.service
[Unit] Description=Greengrass [Service] Type=simple PIDFile=/var/run/greengrassd.pid Restart=on-failure ExecStart=/greengrass/ggc/core/greengrassd start ExecReload=/greengrass/ggc/core/greengrassd restart ExecStop=/greengrass/ggc/core/greengrassd stop [Install] WantedBy=multi-user.target
有効化します。
$ sudo chown root:root /etc/systemd/system/greengrass.service $ sudo chmod 644 /etc/systemd/system/greengrass.service $ sudo systemctl daemon-reload $ sudo systemctl enable greengrass
Greengrass Coreソフトウェアの起動
起動します。
$ sudo systemctl start greengrass
プロセスが正しく起動されたことを確認します。
$ sudo systemctl status greengrass ● greengrass.service - Greengrass Loaded: loaded (/etc/systemd/system/greengrass.service; enabled; vendor preset: enabled) Active: active (running) since Tue 2020-06-16 07:47:21 UTC; 24s ago Main PID: 1777 (5) Tasks: 88 (limit: 1113) Memory: 202.8M CGroup: /system.slice/greengrass.service ├─1777 /greengrass/ggc/packages/1.10.1/bin/daemon -core-dir /greengrass/ggc/packages/1.10.1 -greengrassdPid 1766 ├─1824 /lambda/greengrassSystemComponents -runAs=connectionManager ├─1849 /lambda/greengrassSystemComponents -runAs=cloudSpooler ├─1852 /lambda/greengrassSystemComponents -runAs=shadowSync ├─1861 /lambda/greengrassSystemComponents -runAs=deviceCertificateManager ├─1866 /lambda/greengrassSystemComponents -runAs=secretManager ├─1873 java -cp /lambda/stream_manager/AWSGreengrassStreamManager.jar:/runtime/java8/* com.amazonaws.iot.greengrass.streammanager.StreamManagerService ├─1878 /lambda/greengrassSystemComponents -runAs=shadow ├─1884 /lambda/greengrassSystemComponents -runAs=tes ├─1891 /lambda/ipdetector └─2341 python3.7 -u /runtime/python/lambda_runtime.py --handler=lambda_function.lambda_handler Jun 16 07:47:21 vagrant systemd[1]: Started Greengrass. Jun 16 07:47:21 vagrant greengrassd[1766]: Setting up greengrass daemon Jun 16 07:47:21 vagrant greengrassd[1766]: Validating hardlink/softlink protection Jun 16 07:47:21 vagrant greengrassd[1766]: Waiting for up to 1m10s for Daemon to start Jun 16 07:47:28 vagrant greengrassd[1766]: Greengrass successfully started with PID: 1777