ラズベリーパイ(ラズパイ)をAWS IoT Coreにつなぐ作業そのものは、AWS公式チュートリアルが所要15〜20分と書くとおり短時間で終わります。実際に止まるのはOS側です。Raspberry Pi OSは2026年6月18日公開版でDebian 13(trixie)・カーネル6.18になりました。これに加えて2022年4月4日リリースでの既定ユーザーpiの廃止、Bookworm以降のPEP 668によるpip制限が効いており、古い手順に載っているpip3 install awsiotsdkやssh [email protected]はいまのイメージでは最初の一手で失敗します。ここでは現行仕様で通る接続手順と、証明書・ポリシー・リモート操作の設定をまとめます。
まとめ
- 最短経路はAWS IoTコンソールのConnect(デバイスを接続)から接続キット
connect_device_package.zipを取得し、ラズパイ上でunzipして./start.shを実行する流れ。 - 接続先は
aws iot describe-endpoint --endpoint-type iot:Data-ATSで得るATSエンドポイント。クライアント証明書によるMQTTはポート8883を使う。 - Raspberry Pi OS Bookworm以降はPEP 668によりシステム全体へのpipインストールが拒否される。
python3 -m venvで仮想環境を作ってからSDKを入れる。 - 既定ユーザー
piは2022年4月4日のリリースで廃止され、SSHサーバーも既定で無効。接続先ユーザー名は自分で作成したものを使う。 - 外出先からの操作はポート開放ではなくRaspberry Pi Connect。Bookworm以降のイメージには既定で入っており、リモートシェルも既定で有効。
以下、接続キットの実行から証明書・ポリシー・リモート操作まで順に見ていきます。
接続キットでAWS IoT Coreにつなぐ最短手順
接続キットの入手と実行コマンド
AWS IoTコンソール左側のConnectからConnect one deviceを選ぶと、モノ(thing)の証明書、権限を与えるポリシー、SDK取得スクリプトを1つのZIPにまとめた接続キットが生成されます。プラットフォームとSDK言語の選択画面ではLinux/OSXとPythonを選択。以下はコンソールに表示されるLinux/OSX向けのコマンド列です。
unzip connect_device_package.zip
chmod +x start.sh
./start.sh
サンプルはsdk/test/pythonというトピックへHello World!を送ります。届いているかは、コンソールのMQTT test clientで同じトピックフィルターを購読して確認。なお、コンソールの案内は「対象デバイスにpython3とpip3が入っていること」を前提にしていますが、この前提は現行のRaspberry Pi OSでは素通りしません(後述)。
ATSエンドポイントとルート証明書の確認
接続先のホスト名はアカウントとリージョンごとに異なります。CLIから取得する場合は次のコマンドです。
aws iot describe-endpoint --endpoint-type iot:Data-ATS
指定するiot:Data-ATSはAmazon Trust Services署名のエンドポイントで、コンソールの設定画面にもこちらだけが表示されます。旧来のiot:DataはVeriSign署名の後方互換用。Symantec系認証局が広く信頼を失った経緯から、AWSは「SymantecとVeriSignの証明書は非推奨であり、AWS IoT Coreではすでにサポートしていない」と明記しており、MQTT 5もこの旧エンドポイントでは使えません。ルートCAはRSA 2048ビットのAmazon Root CA 1とECC 256ビットのAmazon Root CA 3が実運用の対象で、Root CA 2・4は公式ドキュメント上「将来のために予約」。いずれもStarfieldのルートCAでクロス署名されているため、証明書全体をハッシュ化するピンニングは検証失敗の原因になるとAWSが警告しています。
ポートとプロトコルの対応も、接続トラブルの切り分けに直結します。既定のエンドポイント構成では次の組み合わせになります。
| プロトコル | 可能な操作 | 認証 | ポート | ALPNプロトコル名 |
|---|---|---|---|---|
| MQTT | Publish / Subscribe | X.509クライアント証明書 | 8883 | なし |
| MQTT | Publish / Subscribe | X.509クライアント証明書 | 443 | x-amzn-mqtt-ca |
| MQTT over WebSocket | Publish / Subscribe | SigV4 | 443 | なし |
| HTTPS | Publishのみ | X.509クライアント証明書 | 8443 | なし |
ポート443でX.509クライアント証明書を使う場合、クライアント側にALPN(Application Layer Protocol Negotiation)の実装が必須になります。HTTPSはパブリッシュ専用で、サブスクライブはできません。AWS IoT Core全体の機能や料金の考え方はAWS IoT Coreとは|機能・料金・接続方法を解説で整理しています。
Raspberry Pi OS側でつまずく箇所
pip3のexternally-managed-environmentエラーと回避手順
Bookworm以降のRaspberry Pi OSはPEP 668に従い、システムのPython環境へのpipインストールを拒否します。公式ドキュメントが載せるエラーはerror: externally-managed-environmentで、対処として「非DebianパッケージのPythonパッケージを入れたい場合はpython3 -m venv path/to/venvで仮想環境を作り、path/to/venv/bin/pythonとpath/to/venv/bin/pipを使う。python3-fullが入っていることを確認する」と案内しています。--break-system-packagesによる強制も用意されていますが、公式の書き方は「Pythonのインストールやosを壊すリスクを冒して上書きできる」というもの。AWS IoT Device SDKは仮想環境に入れるのが素直です。
sudo apt update
sudo apt install -y python3-full
python3 -m venv ~/.venv/awsiot
~/.venv/awsiot/bin/pip install awsiotsdk
2026年8月時点のawsiotsdkは1.31.0(2026年7月24日公開)で、依存するawscrtは0.36.1、必要なPythonは3.8以上です。接続キットのスクリプトを使う場合は、仮想環境を有効化した状態で./start.shを実行すれば、スクリプト内のpip3もPATH解決で仮想環境側を参照します。
既定ユーザーpiの不在とSSHの既定無効
2022年4月4日のリリースで既定ユーザーpiは廃止され、初回起動時のウィザード、Raspberry Pi Imagerの設定、または起動パーティションのuserconf(userconf.txtでも可)でユーザーを自分で作る方式になりました。ssh [email protected]と書かれた手順書はここで失敗します。加えて公式ドキュメントは「既定でRaspberry Pi OSはSSHサーバーを無効にしている」と明記。有効化はsudo raspi-configのInterfacing Optionsから、あるいは起動パーティションに/boot/firmware/sshという空ファイルを置きます。書き込み時に済ませたい場合はImagerのカスタマイズ画面が確実で、手順はRaspberry Pi ImagerでのOS書き込みとSSH・Wi-Fi設定にまとめています。
AWS CLIのバージョン選択とaarch64版インストーラ
pip3 install awscliで入るのはAWS CLIのバージョン1系です。AWS公式は「バージョン2はバンドルインストーラとしてのみ提供され、パッケージマネージャで見つかるものはAWSが作成・管理していない非公式かつ非サポートのパッケージ」と明記しています。64ビット版Raspberry Pi OSではARM版アーカイブを使います。
curl "https://awscli.amazonaws.com/awscli-exe-linux-aarch64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
バージョン1と2は同じawsコマンド名を使うため、両方が入っていると意図しない側が呼ばれます。すでにpip版がある環境ではwhich awsで実体の確認を。
AWS IoT Device SDK v2で送る最小コード
サンプルを自分のアプリケーションへ置き換えるときは、mqtt_connection_builder.mtls_from_pathに証明書のパスとエンドポイントを渡すだけで接続オブジェクトが作れます。次のコードはawsiotsdk 1.31.0で構築まで動作確認したものです。
from awscrt import mqtt
from awsiot import mqtt_connection_builder
conn = mqtt_connection_builder.mtls_from_path(
endpoint="xxxxxxxxxxxxxx-ats.iot.ap-northeast-1.amazonaws.com",
port=8883,
cert_filepath="certs/device.pem.crt",
pri_key_filepath="certs/private.pem.key",
ca_filepath="certs/AmazonRootCA1.pem",
client_id="raspi-01",
clean_session=False,
keep_alive_secs=30)
conn.connect().result()
future, packet_id = conn.publish(
topic="raspi/telemetry",
payload='{"temp": 23.4}',
qos=mqtt.QoS.AT_LEAST_ONCE)
future.result()
conn.disconnect().result()
publish()はFutureとPUBLISHパケットIDのタプルを返します。QoS 1を指定した場合、Futureが完了するのはPUBACKを受け取った時点。送信結果を確認せずに次の処理へ進む実装は、電波の弱い設置場所で欠測に気づけなくなるため、少なくともfuture.result()で完了を待つ形にしてください。client_idはポリシー側の制限と一致させる必要があります。
権限を絞ったAWS IoTポリシー
接続キットが自動生成するポリシーは動作確認用で資源指定が広め。本番前に、モノの名前とトピックを固定した形へ書き換えます。AWS公式が示す最小権限の型は、接続時のクライアントIDをモノの名前に一致させ、証明書がそのモノにアタッチされていることを条件に加えるものです。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["iot:Connect"],
"Resource": ["arn:aws:iot:ap-northeast-1:123456789012:client/${iot:Connection.Thing.ThingName}"],
"Condition": {
"Bool": {"iot:Connection.Thing.IsAttached": "true"}
}
},
{
"Effect": "Allow",
"Action": ["iot:Publish"],
"Resource": ["arn:aws:iot:ap-northeast-1:123456789012:topic/raspi/telemetry"]
},
{
"Effect": "Allow",
"Action": ["iot:Subscribe"],
"Resource": ["arn:aws:iot:ap-northeast-1:123456789012:topicfilter/raspi/command"]
},
{
"Effect": "Allow",
"Action": ["iot:Receive"],
"Resource": ["arn:aws:iot:ap-northeast-1:123456789012:topic/raspi/command"]
}
]
}
資源の書き分けに注意が要ります。iot:Subscribeはトピックフィルターを表すtopicfilter/、実際にメッセージを受け取るiot:Receiveはtopic/で指定。ワイルドカードも独特で、AWS IoTポリシーが解釈するのはIAM準拠の*と?であり、MQTTの+と#はポリシー内では特別な意味を持たない文字として扱われます。*と?はtopic/・topicfilter/のどちらの資源指定にも書けますが、*はトピック階層をまたぐため、1階層に閉じたい場合は?を必要な文字数だけ並べる方が安全です。台数が増えて証明書やポリシーの逸脱を継続的に監視したい段階になったら、AWS IoT Device Defenderとは?機能・料金・Detect終了の注意点で対象範囲を確認してください。
ラズパイのリモート操作|LAN内のSSHと外出先のConnect
同一LAN内はSSHと公開鍵認証
SSHを有効にしたら、Raspberry Pi OSはAvahiによるmDNSに対応しているため、IPアドレスを調べなくてもホスト名で到達できます。Imagerでホスト名を変更した場合は<設定したホスト名>.localになります。
ssh <作成したユーザー名>@raspberrypi.local
公開鍵認証にする場合はMac側でssh-keygenを実行し、ssh-copy-idで公開鍵を送ります。証明書ファイルをラズパイへ渡すときはscpを使い、送信後にchmod 600で所有者のみ読み書き可に。秘密鍵が他ユーザーから読める状態のままだと、SDK側の接続以前に鍵の管理として問題になります。
外出先からはRaspberry Pi Connect
Raspberry Pi Connectとは、ブラウザからラズパイの画面とシェルにアクセスできるRaspberry Pi公式のリモートアクセスサービスです。自宅ルーターのポート開放でSSHを外部に晒す構成は、認証試行にさらされる分だけ運用負荷が上がります。Connectは直接接続ができない場合にTURNリレーサーバー(ロンドンとカリフォルニアに設置)を経由しますが、公式は「復号鍵は持たず、ログも保存もしない」「ピアツーピア接続の交渉に必要なIPアドレスとポートを最大1分間だけ保持し、接続確立と同時に削除する」と説明しています。Desktop・Fullには標準で、Lite向けには画面共有機能を省いたrpi-connect-liteがそれぞれ既定で含まれます。既定で入っていない旧イメージや最小構成の場合だけ、次を実行します。
sudo apt update
sudo apt install rpi-connect
リモートシェルは既定で有効で、不要ならrpi-connect shell offで止められます。画面共有はWaylandが前提のため、LiteやXを使う環境では利用できません。
つながらないときの切り分け
接続失敗の原因は、経路・証明書・権限の順に潰すと早く切り分けられます。
- 経路:公式は
nmap -p 8443 <エンドポイント>でデータエンドポイントへの到達性を確認する方法を案内しています。MQTTなら8883で同様に試し、社内ネットワークで閉じているならALPN対応の443へ切り替えます。 - 証明書:
--endpoint-type iot:Data-ATSで取得したホスト名を使っているか、古いVeriSign系ルートCAを渡していないかを確認。検証エラーが続く場合、AWSはクロス署名版のAmazon Root CAをトラストストアへ追加する対処を挙げています。 - 権限:証明書の未有効化、モノへの未アタッチ、ポリシーの
client/とclient_idの不一致が典型。IsAttached条件付きのポリシーでは、証明書とモノの紐付けが切れているだけで接続が拒否されます。
デバイス側でデータを前処理してから送りたい、通信が切れている間もローカルで処理を続けたい、という要件が出てきた段階では、AWS IoT Coreへの直接接続ではなくエッジ側のランタイムが選択肢になります。違いはAWS IoT Greengrassとは?仕組み・料金・IoT Coreとの違いで比較しています。
よくある質問
ラズパイにSSH接続できないときは何を確認しますか?
まずSSHサーバーが有効かどうかです。Raspberry Pi OSは既定で無効のため、sudo raspi-configか起動パーティションの/boot/firmware/sshで有効化します。次にユーザー名。既定ユーザーpiは2022年4月4日のリリースで廃止されているため、初回設定で作成した名前を使います。raspberrypi.localで解決できない場合はmDNSが通らないネットワークの可能性があるので、IPアドレスを直接指定して切り分けます。
Raspberry Pi Connectを使えばSSHは不要になりますか?
Connectのリモートシェルはブラウザから使えるため、外出先からの操作は代替できます。ただし鍵認証やポート転送を伴う自動化、scpによるファイル転送はSSHが前提。同一LANではSSH、外出先ではConnect、という併用が扱いやすい構成です。
AWS IoT CoreへはMQTTとHTTPSのどちらで接続すべきですか?
デバイスからの送信に加えてコマンド受信も行うならMQTTです。HTTPSはパブリッシュ専用で、サブスクライブができません。AWSもデバイス通信にはMQTTまたはMQTT over WebSocket Secureを推奨しています。
Raspberry Pi 4でもAWS IoT Coreに接続できますか?
接続できます。AWS IoT Device SDK v2のPython版が要求するのはPython 3.8以上で、64ビット版Raspberry Pi OSが動く世代であれば問題になりません。センサー数やローカル処理の重さで機種を選ぶ場合は、Raspberry Pi 5とPi 4の違い|スペック・性能比較【2026年版】の消費電力と処理性能の比較が判断材料になります。
証明書ファイルはどこに置き、権限はどう設定しますか?
置き場所はSDKから参照できる任意のディレクトリで構いませんが、秘密鍵はchmod 600で所有者のみ読み書き可にします。実行スクリプトに実行権限が必要な場合はchmod 700のように、必要な相手にだけ必要な権限を与えてください。ls -lで設定後の状態を確認し、意図せず644のまま配布していないかを見ておきます。