---
title: "ラズパイとAWS IoT Coreを接続する手順｜証明書・MQTT送信・SSH設定"
url: "https://www.issoh.co.jp/tech/details/2803/"
published: 2024-06-26
updated: 2026-08-18
categories: ["Raspberry Pi"]
publisher: "株式会社一創"
---

# ラズパイとAWS IoT Coreを接続する手順｜証明書・MQTT送信・SSH設定

ラズベリーパイ（ラズパイ）を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 pi@raspberrypi.local`はいまのイメージでは最初の一手で失敗します。ここでは現行仕様で通る接続手順と、証明書・ポリシー・リモート操作の設定をまとめます。

## まとめ

- 最短経路は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とは｜機能・料金・接続方法を解説](/tech/details/2991/)で整理しています。

## 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 pi@raspberrypi.local`と書かれた手順書はここで失敗します。加えて公式ドキュメントは「既定でRaspberry Pi OSはSSHサーバーを無効にしている」と明記。有効化は`sudo raspi-config`のInterfacing Optionsから、あるいは起動パーティションに`/boot/firmware/ssh`という空ファイルを置きます。書き込み時に済ませたい場合はImagerのカスタマイズ画面が確実で、手順は[Raspberry Pi ImagerでのOS書き込みとSSH・Wi-Fi設定](/tech/details/8312/)にまとめています。

### 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終了の注意点](/tech/details/5662/)で対象範囲を確認してください。

## ラズパイのリモート操作｜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との違い](/tech/details/3159/)で比較しています。

## よくある質問

### ラズパイに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年版】](/tech/details/8373/)の消費電力と処理性能の比較が判断材料になります。

### 証明書ファイルはどこに置き、権限はどう設定しますか？

置き場所はSDKから参照できる任意のディレクトリで構いませんが、秘密鍵は`chmod 600`で所有者のみ読み書き可にします。実行スクリプトに実行権限が必要な場合は`chmod 700`のように、必要な相手にだけ必要な権限を与えてください。`ls -l`で設定後の状態を確認し、意図せず`644`のまま配布していないかを見ておきます。

## 関連記事

- [AWS IoT Coreとは｜機能・料金・接続方法を解説](/tech/details/2991/)
- [Raspberry Pi Imagerとは｜Linux（apt・snap・AppImage）含む各OSのインストールとOS書き込み・SSH/Wi-Fi設定の使い方](/tech/details/8312/)
- [AWS IoT Greengrassとは？仕組み・料金・IoT Coreとの違い](/tech/details/3159/)
- [AWS IoT Device Defenderとは？機能・料金・Detect終了の注意点](/tech/details/5662/)
- [Raspberry Pi 5とPi 4の違い｜スペック・性能比較【2026年版】](/tech/details/8373/)

---

出典: [ラズパイとAWS IoT Coreを接続する手順｜証明書・MQTT送信・SSH設定](<https://www.issoh.co.jp/tech/details/2803/>)（株式会社一創）
