Amazon Web Services ブログ

モビリティの未来を守る: コネクテッドカーのサイバーセキュリティのための UNECE WP.29 と AWS IoT

はじめに

自動車業界がコネクティッドカーと自動運転の未来を目指して急ピッチで進む中、サイバーセキュリティは重要な課題となっています。車両がソフトウェア、センサー、接続性に依存するようになるにつれ、サイバー攻撃の標的にもなりかねません。この課題を認識して、国際連合欧州経済委員会 (UNECE) は、自動車に関する法的調和のための世界フォーラム (WP.29) を導入し、コネクティッドカーのサイバーセキュリティとソフトウェアアップデートに関する画期的な規制を策定しました。

UNECE WP.29 の概要

国際連合欧州経済委員会 (UNECE) の車両規則統一世界フォーラム (WP.29) は、国家間の車両規制の統一化を目指すグローバルなフォーラムです。自動車業界向けにサイバーセキュリティの規制とガイドラインである UNECE WP.29 を策定しています。

これらの規制は、以下のようなネットワーク接続された車両のサイバーセキュリティの様々な側面をカバーしています。

  1. リスク管理
  2. 安全なソフトウェアアップデート
  3. セキュアな通信
  4. インシデント対応
  5. テストとアセスメント

具体的には、サイバーセキュリティに関する UN 規則第 155 号と、ソフトウェアアップデートに関する UN 規則第 156 号は、自動車業界の姿を変えるものとなるでしょう。 これらの規則により、メーカーには、車両のライフサイクル全体を通してサイバーセキュリティ管理システム (CSMS) とソフトウェアアップデート管理システム (SUMS) を確実に実装することが義務付けられます。 この変化に対応するには、堅牢で拡張性とセキュリティを備えた IoT インフラストラクチャが必要不可欠です。この要求に Amazon Web Services (AWS) IoT がうまく対応できるよう整備されています。

なぜ重要なのか: 自動車のサイバーセキュリティ に関する UNECE 規則第 155 号により、2024 年 7 月以降、EU 加盟国、英国、日本、韓国を含む 54 カ国の OEM によって生産するすべての車両は、WP.29 国連車両規則調和世界フォーラムが定めた厳しいサイバーセキュリティ要件を満たす必要があります。この規制は、コネクティッドカーのサイバーセキュリティを確保し、運用の混乱、データ漏えい、安全リスクなど、深刻な結果を招くサイバー脅威から守ることを目的としています。

AWS IoT の概要

AWS IoT は、自動車メーカーが UNECE WP.29 の要件を満たし、それを超えることを支援する一連のサービスを提供します。 これらの機能は、WP.29 の安全な通信チャネルおよび「セキュリティ・バイ・デザイン」の原則に重点を置いたものです。

  1. デバイス接続とメッセージング: AWS IoT Core は MQTTなどのプロトコルをサポートし、x.509証明書による安全なデバイス認証を実現します。
  2. デバイス管理: AWS IoT Device Management は、オンボーディング、組織化、監視、リモート管理、および OTA 更新を提供し、UN 規則第 156 号に従ったソフトウェアセキュリティの維持に不可欠です。
  3. セキュリティ監視: AWS IoT Device Defender は、車両の異常な挙動を監視し、逸脱があった場合に警告を発し、 UN 規則第 155 号で義務付けられているリスク評価とインシデント対応をサポートします。
  4. データ処理と分析: Amazon Kinesis Data Analytics ストリームは、車両の挙動とユーザーパターンを理解するのを支援し、車両全体のセキュリティ脅威と脆弱性を特定するのに役立ちます。

アーキテクチャの概要

このアーキテクチャでは、AWS IoT Core を使用してコネクティッドカーへの接続と認証を行います。AWS IoT Device Management の一部である AWS IoT Jobs により、スケジューリング、リトライやステータスレポートなどを含む、ソフトウェアアップデートの展開やリモート操作を管理できます。AWS IoT Device Defender は車両の異常を監査および監視し、AWS IoT Rules によりデータを Amazon Kinesis Data Streams に送信し、リアルタイム分析を行います。

図 1.0 : AWS サービスを使用して WP.29 準拠するコネクティッドカー

前提条件

手順

この手順では、シミュレートされたコネクティッドカーをセットアップし、OTA を実行し、車両の動作を積極的に監視し、車両のデータに分析を適用します。 AWS IoT やその他の AWS サービスを利用して、WP.29 要件を満たす機能を実演します。

前提条件を満たしていれば、AWS Cloud9 の環境が用意できています。これを使用して、仮想のコネクティッドカーをセットアップし、AWS IoT に接続します。

AWS IoT コネクティッドカーの作成 (AWS コンソール)

ステップ 1: シミュレートされたコネクティッドカーを作成 (AWS IoT Thing)

  1. AWS IoT Core コンソール を開きます
  2. ナビゲーションペインの 管理 の下にある すべてのデバイス を選択します
  3. モノ を選択します
    1. モノを作成 を選択し、1 つのモノを作成 を選択します
      1. モノの名前に SimulatedConnectedVehicle を入力します

図 1.1 : AWS IoT Thing の作成

デバイス証明書については、推奨オプションを使用します。(図 1.2 参照)

図 1.2: デバイス証明書の選択

ステップ 2: ポリシーを作成して AWS IoT のモノに割り当て

  1. ポリシーをアタッチのセクションで、ポリシーを作成 を選択します
  2. ポリシー名に wp29TestPolicy を入力し、JSON を選択します
    1. 以下の JSON コンテンツに置き換えます
    2. region、your-account-id を適宜更新します
    3. 作成 を選択し、ポリシー作成を完了します
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iot:Connect",
                "iot:Subscribe",
                "iot:Receive",
                "iot:Publish"
            ],
            "Resource": [
                "arn:aws:iot:eu-west-1:your-account-id:client/SimulatedConnectedVehicle",
                "arn:aws:iot:eu-west-1:your-account-id:thing/SimulatedConnectedVehicle",
                "arn:aws:iot:eu-west-1:your-account-id:topic/*",
                "arn:aws:iot:eu-west-1:your-account-id:topicfilter/*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "iot:DescribeJob",
                "iot:CreateJob",
                "iot:UpdateJob",
                "iot:DeleteJob",
                "iot:CancelJob",
                "iot:StartNextPendingJobExecution",
                "iot:DescribeJobExecution",
                "iot:UpdateJobExecution",
                "iot:DeleteJobExecution"
            ],
            "Resource": [
                "arn:aws:iot:eu-west-1:your-account-id:job/*",
                "arn:aws:iot:eu-west-1:your-account-id:thing/SimulatedConnectedVehicle",
                "arn:aws:iot:eu-west-1:your-account-id:jobexecution/*"
            ]
        }
    ]
}
JSON

ステップ 3: コネクティッドカーのモノへポリシーを割り当て

前のステップでポリシーの作成が完了したら、このポリシーをモノに割り当て、モノを作成します。 (図 1.3 参照)

図 1.3 :ポリシーをモノに割り当て

ステップ 4: デバイス証明書と鍵をダウンロード

ダウンロードプロンプトからダウンロードします。 (図 1.4 参照)

  • デバイス証明書
  • パブリックキーファイル
  • プライベートキーファイル
  • Amazon ルート CA

図 1.4 :証明書とキーをダウンロード

これらの認証情報は、 SimulatedConnectedVehicle を AWS IoT に接続し、AWS 開発環境 (上で作成) にアップロードするために使用するので、安全に保存します。

ステップ 5: AWS IoT Device Client をインストール

AWS IoT デバイスクライアントワークショップのセクションに従い、ここに記載されている 手順に従ってデバイスクライアントをインストールします。 このブログの前のステップで作成した認証情報を使用し、Specify thing name (Also used as Client ID) が出力されたら、前に作成した SimulatedConnectedVehicle というモノの名前を使用します。

Over-the-air(OTA) アップデートのリモート操作

デバイスが相互に接続された現代の世界では、ファームウェアを最新の状態に保つことがセキュリティ、パフォーマンス、機能面で極めて重要です。 Over-the-Air (OTA) アップデートは、デバイスを遠隔でアップデートするシームレスな方法を提供し、物理的なアクセスを必要とせずに、常に最新のソフトウェアを常に実行できるようにします。

AWS IoT Device Management Jobs を使用して、コネクティッドカーのファームウェアを更新する OTA アップデートを行う方法を見ていきましょう。

このワークショップ で説明されている手順を実行し、Jobs が AWS 管理のテンプレートを提供していることにより、AWS IoT Core に接続されたデバイスへのリモート操作がとても簡単で効率的かを見てみましょう。

ここ に記載されている手順にしたがって、独自カスタム Jobs の手順とウォークスルーを作成することもできます。

積極的なセキュリティ監視 : コネクテッドカーの安全性とコンプライアンスを確保

AWS IoT Device Defender を使用すると、継続的なセキュリティ監視を確立でき、全体的なセキュリティを強化できます。 このサービスは、送受信するメッセージの増加 (「おしゃべり」なデバイスであることを示す) 、車両からの頻繁な接続試行、または急速かつ頻繁な切断などの異常を検出することができます。これらの異常がトリガーを促し、潜在的な安全保障上の脅威に対する積極的な対応を可能にします。このアプローチは、継続的なリスク評価をサポートするだけでなく、UN 規則第 155 号の厳格な基準にも沿っています。

このワークショップ で説明されている手順に従って、AWS IoT Device Defender を使用して積極的なセキュリティ監視と監査を実現する方法を確認します。

ストリーミングデータ分析: Amazon Kinesis Data Analytics (Apache Flink) の使用

Amazon Kinesis Data Analytics の ストリームを使ったデータ分析は、車両の動作とユーザーの行動パターンを理解する上で非常に重要です。 このデータを分析することで、車両全体の新たな傾向とパターンを特定することができ、より多くの情報に基づいた意思決定と全体的なパフォーマンス向上が可能になります。

Amazon Kinesis Data AnalyticsにデータをファンアウトするためにAWS IoT Rulesをセットアップしましょう

ステップ 1: AWS IoT デバイスクライアントの設定を変更

AWS IoT デバイス クライアント設定を変更して、publish-on-change を含めるようにします。この機能は、指定されたパブリッシュファイル (/home/ubuntu/workshop_dc/pubfile.txt) にデータを書き込むたびにパブリッシュアクションがトリガーされます。

AWS IoT デバイスクライアントはこの変更を検知し、/topic/workshop/dc/pub トピックとして AWS IoT Core に送信します。

次のコマンドを実行して、設定ファイルを編集します:

sudo vim /etc/.aws-iot-device-client/aws-iot-device-client.conf

以下を追加します:

“publish-on-change”: true

サンプルセクションの設定は、”Publish-on-change” を追加すると次のようになります:

図 1.5: AWS IoT デバイスクライアントの設定変更

ステップ 2: AWS IoT デバイスクライアントを再起動

前のステップで publish-on-change を追加して設定を変更したら、AWS IoT デバイスクライアントを再起動します。

次のコマンドを実行して再起動します:

sudo systemctl restart aws-iot-device-client
Bash

ステップ 3: 車両データのシミュレーション

コネクテッドカーのシミュレーションデータジェネレーターを設定し、AWS IoT Core にストリーミングします。ファイル (vehicle_data_generator.py) を作成し、これを実行すると、車両の状態、DTC (故障診断コード)、位置情報、ドライバーの行動、バッテリー状態を含むランダムデータが常にストリーミングされます。

ファイルを設定するために次のコマンドを実行し、コードをダウンロードします:

cd /home/ubuntu/workshop_dc
vim vehicle_data_generator.py
Bash

ファイル (vehicle_data_generator.py) に次のコードを入力します:

import json
import time
import random
import logging
from datetime import datetime, timezone
from pathlib import Path

# Set up logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)

# File path
FILE_PATH = Path("/home/ubuntu/workshop_dc/pubfile.txt")

def generate_vehicle_status():
    return {
        "vehicleId": "VIN123456789",
        "timestamp": datetime.now(timezone.utc).isoformat(),
        "status": {
            "ignition": random.choice(["ON", "OFF"]),
            "speed": round(random.uniform(0, 120), 1),
            "fuelLevel": round(random.uniform(0, 100), 1),
            "batteryLevel": round(random.uniform(0, 100), 1),
            "odometer": round(random.uniform(0, 100000), 1),
            "engineTemp": round(random.uniform(70, 110), 1),
            "tirePressure": {
                "frontLeft": round(random.uniform(30, 35), 1),
                "frontRight": round(random.uniform(30, 35), 1),
                "rearLeft": round(random.uniform(30, 35), 1),
                "rearRight": round(random.uniform(30, 35), 1)
            }
        }
    }

def generate_dtcs():
    return {
        "vehicleId": "VIN987654321",
        "timestamp": datetime.now(timezone.utc).isoformat(),
        "dtcs": [
            {
                "code": "P0" + str(random.randint(100, 999)),
                "description": "Random DTC Description",
                "severity": random.choice(["WARNING", "CRITICAL", "INFO"])
            }
        ]
    }

def generate_location():
    return {
        "vehicleId": "VIN246813579",
        "timestamp": datetime.now(timezone.utc).isoformat(),
        "location": {
            "latitude": round(random.uniform(30, 45), 4),
            "longitude": round(random.uniform(-125, -70), 4),
            "altitude": round(random.uniform(0, 1000), 1),
            "heading": round(random.uniform(0, 359), 1),
            "speed": round(random.uniform(0, 120), 1)
        }
    }

def generate_driver_behavior():
    return {
        "vehicleId": "VIN135792468",
        "timestamp": datetime.now(timezone.utc).isoformat(),
        "driverBehavior": {
            "harshAccelerations": random.randint(0, 5),
            "harshBraking": random.randint(0, 5),
            "speedingEvents": random.randint(0, 10),
            "averageSpeed": round(random.uniform(40, 80), 1),
            "idlingTime": random.randint(0, 600),
            "fuelEfficiency": round(random.uniform(20, 40), 1)
        }
    }

def generate_battery_status():
    return {
        "vehicleId": "VIN753951456",
        "timestamp": datetime.now(timezone.utc).isoformat(),
        "batteryStatus": {
            "stateOfCharge": round(random.uniform(0, 100), 1),
            "range": round(random.uniform(0, 300), 1),
            "chargingStatus": random.choice(["CHARGING", "NOT_CHARGING"]),
            "voltage": round(random.uniform(350, 400), 1),
            "current": round(random.uniform(-200, 200), 1),
            "temperature": round(random.uniform(20, 40), 1),
            "healthStatus": random.choice(["GOOD", "FAIR", "POOR"])
        }
    }

def write_to_file(data):
    try:
        # Ensure the directory exists
        FILE_PATH.parent.mkdir(parents=True, exist_ok=True)
        
        # Write the data to the file
        with FILE_PATH.open('w') as f:
            json.dump(data, f)
        logger.info(f"Successfully wrote data to {FILE_PATH}")
    except PermissionError:
        logger.error(f"Permission denied when trying to write to {FILE_PATH}")
    except IOError as e:
        logger.error(f"I/O error occurred when writing to {FILE_PATH}: {e}")
    except Exception as e:
        logger.error(f"Unexpected error occurred when writing to {FILE_PATH}: {e}")

def main():
    generators = [
        generate_vehicle_status,
        generate_dtcs,
        generate_location,
        generate_driver_behavior,
        generate_battery_status
    ]

    while True:
        try:
            data = random.choice(generators)()
            write_to_file(data)
            time.sleep(10)
        except KeyboardInterrupt:
            logger.info("Script terminated by user")
            break
        except Exception as e:
            logger.error(f"An unexpected error occurred: {e}")
            time.sleep(10)  # Wait before retrying

if __name__ == "__main__":
    try:
        main()
    except Exception as e:
        logger.critical(f"Critical error occurred: {e}")
Python

コード (またはファイル) をコピーしたら、次のコマンドでコードを実行します。

python3 vehicle_data_generator.py

実行に成功すると、以下のように表示されます:

INFO – Successfully wrote data to /home/ubuntu/workshop_dc/pubfile.txt

AWS IoT Core コンソールで以下に移動します:

  • テスト
    • MQTT テストクライアント
      • トピックをサブスクライブする: /topic/workshop/dc/pub

到着しているデータのストリームが確認できるはずです; このデータは分析に使用するものと同じです。

図 1.6: AWS IoT Core に到着するデータを示す MQTT トピック

ステップ 4: AWS IoT Rule を作成

AWS IoT Core にデータが到着することが分かれば、BI 目的で AWS 分析サービスにデータをルーティングするための AWS IoT Rules をセットアップできます。

  1. AWS IoT Core コンソール に移動します
  2. ナビゲーションペインの 管理 の下にある メッセージのルーティング を選択します
    1. ルール を選択します
      1. ルールを作成 を選択します

適切なルール名とルールの説明を入力し、「次へ」を選択します 。(図 1.7 参照)

図 1.7: AWS IoT Rule を作成

SQL ステートメントを設定 セクションで、以下の SQL ステートメントを入力し、次へ を選択します:

SELECT * FROM '/topic/workshop/dc/pub'

ルールアクションをアタッチ セクションで、Kinesis Data Stream を選択し、以下を作成します:

アクション 1

  • 名前を指定してストリームを作成: simulatedVehicleData
  • パーティションキー: ${newuuid()}
  • IAMロールの選択と作成: simulatedVehicleRole

エラーアクション

  • AWS IoTトピックへのリパブリッシュを選択: /topic/workshop/dc/streamError
  • IAM ロールを選択: simulatedVehicleRole

完了したら進んで 作成 を選択します。

図 1.8: AWS IoT Rules アクション

ステップ 5: Apache Flink と Apache Zeppelin を使って Amazon Kinesis Data Streams のストリーミングデータを確認

この段階では、Amazon Kinesis Data Streams (simulatedVehicleData) にデータがストリーミングされます。 コンソールで Amazon Kinesis Data Streams に移動し、ストリームを選択します。 (図 1.9 参照)

図 1.9: シミュレーションされた車両データのストリーム

データ分析タブを選択し、I agree を選択した後、Create notebook を選択します。 (図 2.0 参照)

図 2.0: Apache Flink Studio ノートブックの作成

Studio ノートブックが作成されたら、ストリーミングデータを選択して表示できるはずです。 (図 2.1 参照)

図 2.1: ストリーミングデータビュー

これで、ストリーミングデータの可視化を作成できるはずです。

クリーンアップ

不要な請求を避けるために、メインの CloudFormation テンプレート (ネストされたスタックではない)、Amazon EC2 インスタンス (開発用に作成した場合)、Amazon S3 バケット (このブログ用に新しく作成した場合)、IoT のモノと関連するポリシー、Kinesis Data Stream (AWS 管理の Apache Flink と Apache Zeppelin を含む) を削除します。

まとめ

UNECE WP.29 規制は、コネクティッドカーのサイバーセキュリティを確保する上で重要なステップを示しています。この規制は、自動車業界に対し、車両の設計、製造、運用のあらゆる側面にセキュリティを組み込むよう要求しています。AWS IoT サービスは、これらの課題に対処するための包括的でスケーラブル、かつセキュアな基盤を提供します。

コネクティッドかつ自動運転の未来には、UNECE WP.29 などの厳格な規制を革新的なテクノロジーとシームレスに統合することを要求します。 AWS IoT では、この連携を効果的に実現するサービスを提供しています。 この統合は単なる規制への準拠を超えたものです; 消費者の信頼を気づき、相互接続が進む世界における安全性を確保するものです。 サイバーセキュリティの懸念に積極的に取り組むことで、個々の車両の安全性を確保するだけでなく、将来のモビリティ基盤そのものを守ることができるのです。

関連するリンク

著者について

Syed RehanSyed Rehan Sysed Rehan は、Amazon Web Services(AWS)のIoTセキュリティ組織内で活動するシニアサイバーセキュリティ製品マネージャーです。AWS IoT 、機械学習、サイバーセキュリティに関する書籍の著者として、グローバルな役割に幅広い専門知識をもたらしています。サイードは、セキュリティ専門家、CISO、開発者、セキュリティ意思決定者と協力し、AWS セキュリティサービスとソリューションの採用を促進するために、多様な顧客層を抱えています。サイバーセキュリティ、機械学習、人工知能、IoT 、クラウド技術に関する深い知識を持ち、新興企業から大企業まで幅広い顧客を支援しています。AWS 環境内で安全な IoT 、ML 、AI ベースのソリューションを構築できるようにしています。

この記事は Sysed Rehan によって書かれた Securing the future of mobility: UNECE WP.29 and AWS IoT for connected vehicle cybersecurity の日本語訳です。この記事は 広域事業統括本部 ソリューションアーキテクト 久次米が翻訳しました。