Security best practices in Amazon IoT Core
This section contains information about security best practices for Amazon IoT Core. For
information about security rules for Industrial IoT solutions, see Ten security golden rules for Industrial IoT solutions
Protecting MQTT connections in Amazon IoT
Amazon IoT Core
The impact and severity of dropping MQTT connections on your device fleet depends on many factors. These include:
-
Your use case (for example, the data your devices send to Amazon IoT, how much data, and the frequency that the data is sent).
-
Your MQTT client configuration (for example, auto reconnect settings, associated back-off timings, and use of MQTT persistent sessions).
-
Device resource constraints.
-
The root cause of the disconnections, its aggressiveness, and persistence.
To avoid client ID conflicts and their potential negative impacts, make sure that each device or mobile application has an Amazon IoT or IAM policy that restricts which client IDs can be used for MQTT connections to the Amazon IoT message broker. For example, you can use an IAM policy to prevent a device from unintentionally closing another device's connection by using a client ID that is already in use. For more information, see Authorization.
All devices in your fleet must have credentials with privileges that authorize intended actions only, which include (but not limited to) Amazon IoT MQTT actions such as publishing messages or subscribing to topics with specific scope and context. The specific permission policies can vary for your use cases. Identify the permission policies that best meet your business and security requirements.
To simplify creation and management of permission policies, you can use Amazon IoT Core policy variables and IAM policy variables
For example, if you registered your devices in the Amazon IoT registry, you can use thing policy variables in Amazon IoT policies to
grant or deny permissions based on thing properties like thing names, thing types, and
thing attribute values. The thing name is obtained from the client ID in the MQTT
connect message sent when a thing connects to Amazon IoT. The thing policy variables are
replaced when a thing connects to Amazon IoT over MQTT using TLS mutual authentication or
MQTT over the WebSocket protocol using authenticated Amazon Cognito identities. You can use the
AttachThingPrincipal
API to attach certificates and authenticated Amazon Cognito identities to a thing.
iot:Connection.Thing.ThingName
is a useful thing policy variable to
enforce client ID restrictions. The following example Amazon IoT policy requires a registered
thing's name to be used as the client ID for MQTT connections to the Amazon IoT message
broker:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "iot:Connect", "Resource": [ "arn:aws:iot:us-east-1:123456789012:client/${iot:Connection.Thing.ThingName}" ] } ] }
If you want to identify ongoing client ID conflicts, you can enable and use CloudWatch Logs for Amazon IoT. For every MQTT connection that the Amazon IoT message broker disconnects due to client ID conflicts, a log record similar to the following is generated:
{ "timestamp": "2019-04-28 22:05:30.105", "logLevel": "ERROR", "traceId": "02a04a93-0b3a-b608-a27c-1ae8ebdb032a", "accountId": "123456789012", "status": "Failure", "eventType": "Disconnect", "protocol": "MQTT", "clientId": "clientId01", "principalId": "1670fcf6de55adc1930169142405c4a2493d9eb5487127cd0091ca0193a3d3f6", "sourceIp": "203.0.113.1", "sourcePort": 21335, "reason": "DUPLICATE_CLIENT_ID", "details": "A new connection was established with the same client ID" }
You can use a CloudWatch Logs filter
such as {$.reason= "DUPLICATE_CLIENT_ID" }
to search for instances of
client ID conflicts or to set up CloudWatch metric filters and
corresponding CloudWatch alarms for continuous monitoring and reporting.
You can use Amazon IoT Device
Defender
You can use Amazon IoT Device Advisor to validate that your devices can reliably connect to Amazon IoT Core and follow security best practices.
See also
Keep your device's clock in sync
It's important to have an accurate time on your device. X.509 certificates have an expiry date and time. The clock on your device is used to verify that a server certificate is still valid. If you're building commercial IoT devices, remember that your products may be stored for extended periods before being sold. Real-time clocks can drift during this time and batteries can get discharged, so setting time in the factory is not sufficient.
For most systems, this means that the device's software must include a network time protocol (NTP) client. The device should wait until it synchronizes with an NTP server before it tries to connect to Amazon IoT Core. If this isn't possible, the system should provide a way for a user to set the device's time so that subsequent connections succeed.
After the device synchronizes with an NTP server, it can open a connection with Amazon IoT Core. How much clock skew that is allowed depends on what you're trying to do with the connection.
Validate the server certificate
The first thing a device does to interact with Amazon IoT is to open a secure connection.
When you connect your device to Amazon IoT, ensure that you're talking to Amazon IoT and not
another server impersonating Amazon IoT. Each of the Amazon IoT servers is provisioned with a
certificate issued for the iot.amazonaws.com
domain. This certificate was
issued to Amazon IoT by a trusted certificate authority that verified our identity and
ownership of the domain.
One of the first things Amazon IoT Core does when a device connects is send the device a
server certificate. Devices can verify that they were expecting to connect to
iot.amazonaws.com
and that the server on the end of that connection
possesses a certificate from a trusted authority for that domain.
TLS certificates are in X.509 format and include a variety of information such as the
organization's name, location, domain name, and a validity period. The validity period
is specified as a pair of time values
called notBefore
and notAfter
. Services like Amazon IoT Core use
limited validity periods (for example, one year) for their server certificates and begin
serving new ones before the old ones expire.
Use a single identity per device
Use a single identity per client. Devices generally use X.509 client certificates. Web and mobile applications use Amazon Cognito Identity. This enables you to apply fine-grained permissions to your devices.
For example, you have an application that consists of a mobile phone device that receives status updates from two different smart home objects – a light bulb and a thermostat. The light bulb sends the status of its battery level, and a thermostat sends messages that report the temperature.
Amazon IoT authenticates devices individually and treats each connection individually. You can apply fine-grained access controls using authorization policies. You can define a policy for the thermostat that allows it to publish to a topic space. You can define a separate policy for the light bulb that allows it to publish to a different topic space. Finally, you can define a policy for the mobile app that only allows it to connect and subscribe to the topics for the thermostat and the light bulb to receive messages from these devices.
Apply the principle of least privilege and scope down the permissions per device as much as possible. All devices or users should have an Amazon IoT policy in Amazon IoT that only allows it to connect with a known client ID, and to publish and subscribe to an identified and fixed set of topics.
Use a second Amazon Web Services Region as backup
Consider storing a copy of your data in a second Amazon Web Services Region as a backup. For more
information, see Disaster Recovery for Amazon IoT
Use just in time provisioning
Manually creating and provisioning each device can be time consuming. Amazon IoT provides a way to define a template to provision devices when they first connect to Amazon IoT. For more information, see Just-in-time provisioning.
Permissions to run Amazon IoT Device Advisor tests
The following policy template shows the minimum permissions and IAM entity required
to run Amazon IoT Device Advisor test cases. You will need to replace
your-device-role-arn
with the device role Amazon Resource
Name (ARN) that you created under the prerequisites.
{ "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": "iam:PassRole", "Resource": "
your-device-role-arn
", "Condition": { "StringEquals": { "iam:PassedToService": "iotdeviceadvisor.amazonaws.com" } } }, { "Sid": "VisualEditor1", "Effect": "Allow", "Action": [ "execute-api:Invoke*", "iam:ListRoles", // Required to list device roles in the Device Advisor console "iot:Connect", "iot:CreateJob", "iot:DeleteJob", "iot:DescribeCertificate", "iot:DescribeEndpoint", "iot:DescribeJobExecution", "iot:DescribeJob", "iot:DescribeThing", "iot:GetPendingJobExecutions", "iot:GetPolicy", "iot:ListAttachedPolicies", "iot:ListCertificates", "iot:ListPrincipalPolicies", "iot:ListThingPrincipals", "iot:ListThings", "iot:Publish", "iot:StartNextPendingJobExecution", "iot:UpdateJobExecution", "iot:UpdateThingShadow", "logs:CreateLogGroup", "logs:CreateLogStream", "logs:DescribeLogGroups", "logs:DescribeLogStreams", "logs:PutLogEvents", "logs:PutRetentionPolicy" ], "Resource": "*" }, { "Sid": "VisualEditor2", "Effect": "Allow", "Action": "iotdeviceadvisor:*", "Resource": "*" } ] }
Cross-service confused deputy prevention for Device Advisor
The confused deputy problem is a security issue where an entity that doesn't have permission to perform an action can coerce a more-privileged entity to perform the action. In Amazon, cross-service impersonation can result in the confused deputy problem. Cross-service impersonation can occur when one service (the calling service) calls another service (the called service). The calling service can be manipulated to use its permissions to act on another customer's resources in a way it should not otherwise have permission to access. To prevent this, Amazon provides tools that help you protect your data for all services with service principals that have been given access to resources in your account.
We recommend using the aws:SourceArn
and aws:SourceAccount
global condition context keys in
resource policies to limit the permissions that Device Advisor gives another service to the
resource. If you use both global condition context keys, the
aws:SourceAccount
value and the account in the
aws:SourceArn
value must use the same account ID when used in the same
policy statement.
The value of aws:SourceArn
must be the ARN of your suite definition
resource. The suite definition resource refers to the test suite you created with Device
Advisor.
The most effective way to protect against the confused deputy problem is to use the
aws:SourceArn
global condition context key with the full ARN of the
resource. If you don't know the full ARN of the resource or if you are specifying
multiple resources, use the aws:SourceArn
global context condition key with
wildcards (*
) for the unknown portions of the ARN. For example,
arn:aws:iotdeviceadvisor:*:
account-id
:suitedefinition/*
The following example shows how you can use the aws:SourceArn
and
aws:SourceAccount
global condition context keys in Device Advisor to prevent
the confused deputy problem.
{ "Version": "2012-10-17", "Statement": { "Sid": "ConfusedDeputyPreventionExamplePolicy", "Effect": "Allow", "Principal": { "Service": "iotdeviceadvisor.amazonaws.com" }, "Action": "sts:AssumeRole", "Condition": { "ArnLike": { "aws:SourceArn":
"arn:aws:iotdeviceadvisor:us-east-1:123456789012:suitedefinition/ygp6rxa3tzvn"
}, "StringEquals": { "aws:SourceAccount":"123456789012"
} } } }