Skip to content

Commit 1f0f4e7

Browse files
committed
feat: add migration guide for azuire iot hub
1 parent 560f759 commit 1f0f4e7

File tree

6 files changed

+987
-3
lines changed

6 files changed

+987
-3
lines changed

en_US/migration/migrate-from-aws-iot-core.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,9 @@ With your CA certificate located, the next step is to configure the EMQX broker
5252

5353
The core of the migration is enabling two-way SSL/TLS authentication (mTLS) on an EMQX listener. This configuration instructs EMQX to demand a certificate from the connecting client and verify its authenticity against your CA.
5454

55-
**Action**: Open the EMQX configuration file (e.g., `emqx.conf`) and configure the SSL/TLS listener:
55+
For detailed information on SSL/TLS configuration options, see [Enable SSL/TLS Connection](../network/emqx-mqtt-tls.md). For certificate management, see [TLS Certificates](../network/tls-certificate.md).
56+
57+
**Action**: Open the EMQX configuration file (e.g., `emqx.conf`) and configure the SSL/TLS listener, or use the Dashboard (**Management** -> **Listeners**):
5658

5759
```hocon
5860
listeners.ssl.default {
@@ -90,6 +92,14 @@ Both AWS IoT Core and EMQX use port 8883 as the default for MQTT over TLS/SSL, s
9092
* `fail_if_no_peer_cert`: Must be set to `true` to reject connections without a client certificate, enforcing mTLS.
9193
* `certfile` and `keyfile`: Your EMQX server's own certificate and private key. Clients will verify this certificate to ensure they're connecting to the correct broker.
9294

95+
After updating the configuration file, reload the configuration:
96+
97+
```bash
98+
emqx ctl conf reload
99+
```
100+
101+
If you made changes via the Dashboard, click **Update** to apply them. The listener will restart automatically to apply the new settings.
102+
93103
### (Optional) Map Certificate CN to ClientID or Username
94104

95105
In many AWS IoT Core implementations, authorization policies rely on variables populated from the certificate, such as using the certificate's Common Name (CN) as the `iot:ClientId`. EMQX can replicate this behavior seamlessly, allowing for easier migration of authorization rules.
Lines changed: 318 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,318 @@
1+
# Migrating from Azure IoT Hub to EMQX
2+
3+
This guide provides a practical walkthrough for migrating IoT devices from Azure IoT Hub to EMQX. It covers two migration paths:
4+
5+
1. **X.509 certificate authentication** - Devices using client certificates
6+
2. **SAS token authentication** - Devices using Shared Access Signature tokens with HTTP-based authentication
7+
8+
## Migration at a Glance
9+
10+
For devices using X.509 certificates, the migration is primarily a configuration change. Device certificates and private keys remain unchanged; only the broker endpoint and server CA certificate need updates. EMQX must be configured to trust the same CA that Azure trusts and to replicate Azure's identity mapping model where the certificate Common Name (CN) equals the deviceId.
11+
12+
13+
The migration process consists of three main phases:
14+
15+
1. **Locate Your CA Certificate**. Find the CA certificate that signed your device certificates.
16+
17+
2. **Configure EMQX for mTLS**. Set up an SSL/TLS listener on the EMQX broker, enable mandatory peer verification, and configure the listener to trust your CA and map certificate CN to deviceId.
18+
19+
3. **Update Device Clients**. Update device code to connect to the EMQX endpoint and trust the EMQX server CA certificate. Devices can continue using Azure IoT SDK or use standard MQTT clients.
20+
21+
The following table summarizes the parameter changes:
22+
23+
| **Parameter** | **Azure IoT Hub (Example)** | **EMQX (Example)** | **Notes** |
24+
| ------------- | -------------------------- | ------------------ | --------- |
25+
| **Endpoint Hostname** | `my-hub.azure-devices.net` | `mqtt.example.com` | Update device client code |
26+
| **Device Certificate** | `device-001.cert.pem` | `device-001.cert.pem` | No change. Device continues using existing certificate |
27+
| **Device Private Key** | `device-001.key.pem` | `device-001.key.pem` | No change. Device continues using existing private key |
28+
| **Server Verification** (Device trusts Server) | Device trusts Azure's public CA | Device must trust `emqx-server-ca.pem` | Deploy EMQX server CA to devices |
29+
| **Client Verification** (Server trusts Device) | Azure trusts your CA (registered via CA upload or thumbprint) | EMQX `cacertfile` must be set to your CA | Same CA used in Azure |
30+
| **Identity Mapping** | Azure extracts `CN=deviceId` | Enable `mqtt.peer_cert_as_clientid = cn` | Preserves deviceId-based authorization |
31+
32+
## Phase 1: Locate Your CA Certificate
33+
34+
**What you need**: The CA certificate that signed your device certificates (in PEM format, e.g., `device-ca.pem`).
35+
36+
Azure IoT Hub has two X.509 registration methods:
37+
- **CA registration**: You uploaded the CA to Azure IoT Hub
38+
- **Thumbprint registration**: You registered devices individually by certificate thumbprint
39+
40+
**Both methods use the same certificate structure** - your device certificates were signed by a CA. For EMQX migration, you need that CA certificate.
41+
42+
### Verify Certificate Requirements
43+
44+
Azure requires that the certificate Subject Common Name (CN) matches the deviceId (or `deviceId/moduleId` for modules). Verify with:
45+
46+
```bash
47+
openssl x509 -in device-001.cert.pem -noout -subject
48+
```
49+
50+
The output should show:
51+
```
52+
subject=CN = device-001
53+
```
54+
55+
This CN value will be used by EMQX to identify the device.
56+
57+
### Confirm Device Credential Access
58+
59+
Ensure each device retains secure access to:
60+
- Its leaf certificate (`device-001.cert.pem`)
61+
- Its private key (`device-001.key.pem`)
62+
63+
No certificate re-provisioning is needed for this migration path.
64+
65+
## Phase 2: Configure EMQX for Azure-Style mTLS
66+
67+
Configure the EMQX broker to authenticate devices using the same certificates trusted by Azure IoT Hub.
68+
69+
### Enable and Configure the mTLS Listener
70+
71+
Configure EMQX to enable two-way SSL/TLS authentication (mTLS) on the SSL listener. For detailed information on SSL/TLS configuration, see [Enable SSL/TLS Connection](../network/emqx-mqtt-tls.md).
72+
73+
Open the EMQX configuration file (`emqx.conf`) and configure the SSL/TLS listener, or use the Dashboard (**Management** -> **Listeners**):
74+
75+
```hocon
76+
listeners.ssl.default {
77+
bind = "0.0.0.0:8883"
78+
79+
ssl_options {
80+
# Your EMQX server's certificate
81+
certfile = "etc/certs/server-cert.pem"
82+
83+
# Your EMQX server's private key
84+
keyfile = "etc/certs/server-key.pem"
85+
86+
# --- mTLS Configuration for Device Authentication ---
87+
88+
# The CA certificate that signed your device certificates
89+
cacertfile = "etc/certs/azure-device-ca.pem"
90+
91+
# Enable client certificate verification
92+
verify = verify_peer
93+
94+
# Reject clients that do not present a certificate
95+
fail_if_no_peer_cert = true
96+
}
97+
}
98+
```
99+
100+
::: tip
101+
Both Azure IoT Hub and EMQX use port 8883 as the default for MQTT over TLS/SSL, so no port changes are needed in device clients.
102+
:::
103+
104+
**Key Configuration Parameters**:
105+
* `cacertfile`: Path to your CA certificate (or bundle of self-signed device certificates). EMQX will use this to verify device certificates.
106+
* `verify`: Must be set to `verify_peer` to enable mTLS.
107+
* `fail_if_no_peer_cert`: Must be set to `true` to enforce certificate requirement.
108+
109+
### Replicate Azure's CN=deviceId Identity Mapping
110+
111+
Azure IoT Hub extracts the certificate's Common Name and uses it as the deviceId for authorization. Replicate this in EMQX:
112+
113+
```hocon
114+
mqtt.peer_cert_as_clientid = cn
115+
mqtt.peer_cert_as_username = cn
116+
```
117+
118+
This configuration ensures that:
119+
- The MQTT ClientID is automatically set to the certificate CN (deviceId)
120+
- The username is also set to the certificate CN
121+
- You can configure EMQX ACL rules using `${clientid}` or `${username}` to match the deviceId, replicating Azure's authorization model
122+
123+
For devices using modules (`deviceId/moduleId` format), the CN contains both identifiers and can be used directly in EMQX ACLs.
124+
125+
### Apply Configuration Changes
126+
127+
After updating the configuration file, reload the configuration:
128+
129+
```bash
130+
emqx ctl conf reload
131+
```
132+
133+
If you made changes via the Dashboard, click **Update** to apply them. The listener will restart automatically to apply the new settings.
134+
135+
Verify the listener is enforcing mTLS:
136+
137+
```bash
138+
openssl s_client -connect mqtt.example.com:8883 -showcerts
139+
```
140+
141+
The connection should fail without a client certificate.
142+
143+
## Phase 3: Update Device Clients and Verify Migration
144+
145+
The final phase is to update device client code to connect to EMQX instead of Azure IoT Hub.
146+
147+
### Update Device Client Code
148+
149+
The Azure IoT SDK for Python (and other languages) supports connecting to custom MQTT brokers through the `server_verification_cert` and custom `hostname` parameters. This allows for minimal code changes.
150+
151+
**Python Example**:
152+
153+
```python
154+
from azure.iot.device import IoTHubDeviceClient, X509
155+
156+
# Load device credentials
157+
x509 = X509(
158+
cert_file="certs/device-001.cert.pem",
159+
key_file="certs/device-001.key.pem"
160+
)
161+
162+
# Create client pointing to EMQX
163+
client = IoTHubDeviceClient.create_from_x509_certificate(
164+
x509=x509,
165+
hostname="mqtt.example.com", # EMQX hostname instead of Azure
166+
device_id="device-001",
167+
server_verification_cert="certs/emqx-server-ca.pem" # EMQX server CA
168+
)
169+
170+
# Connect and use as before
171+
client.connect()
172+
client.send_message("Hello from migrated device")
173+
```
174+
175+
**C# Example**:
176+
177+
```csharp
178+
var auth = new DeviceAuthenticationWithX509Certificate(
179+
deviceId: "device-001",
180+
certificate: new X509Certificate2("device-001.pfx", "password")
181+
);
182+
183+
var options = new ClientOptions
184+
{
185+
// Point to EMQX instead of Azure IoT Hub
186+
ModelId = "",
187+
CertificateValidationCallback = (sender, certificate, chain, errors) =>
188+
{
189+
// Validate against EMQX CA
190+
return ValidateServerCertificate(certificate, "emqx-server-ca.pem");
191+
}
192+
};
193+
194+
var client = new DeviceClient(
195+
hostname: "mqtt.example.com", // EMQX hostname
196+
authenticationMethod: auth,
197+
transportType: TransportType.Mqtt_Tcp_Only,
198+
options: options
199+
);
200+
201+
await client.OpenAsync();
202+
```
203+
204+
::: tip
205+
Using the Azure IoT SDK preserves your existing application code structure, requiring only configuration changes. This is the simplest migration path for devices already using X.509 authentication.
206+
:::
207+
208+
### Device-Side Parameter Summary
209+
210+
These are the parameter changes needed:
211+
212+
1. **Endpoint/Hostname**:
213+
- Azure: `my-hub.azure-devices.net`
214+
- EMQX: `mqtt.example.com`
215+
216+
2. **Server CA Certificate**:
217+
- Azure: Uses system trust store or Azure CA
218+
- EMQX: Must explicitly provide `emqx-server-ca.pem`
219+
220+
3. **Device Credentials** (no changes):
221+
- Certificate: Keep existing device certificate
222+
- Private key: Keep existing private key
223+
224+
4. **ClientId**: Set to deviceId (matching certificate CN)
225+
226+
### Validation Checklist
227+
228+
1. Device appears in EMQX Dashboard with `clientid = deviceId`
229+
2. TLS handshake succeeds and device certificate is verified
230+
3. Device can publish to authorized topics
231+
4. Device can subscribe to authorized topics
232+
5. No authentication errors in EMQX logs
233+
234+
## Happy Path Variations
235+
236+
### CA-Signed Fleet
237+
238+
- Upload the CA certificate to EMQX
239+
- All devices signed by this CA are automatically trusted
240+
- Simplified certificate lifecycle management
241+
- Easy to add new devices without EMQX reconfiguration
242+
243+
### Modules (deviceId/moduleId)
244+
245+
- Certificates with CN in format `deviceId/moduleId`
246+
- EMQX can use the full CN for authorization
247+
- Reflect the same structure in ACL rules
248+
249+
## Alternative: SAS Token Authentication with HTTP Authenticator
250+
251+
Devices using Azure Shared Access Signature (SAS) tokens can continue using them with EMQX by implementing an **HTTP Authentication** service. For detailed information on HTTP authentication, see [Use HTTP Service](../access-control/authn/http.md).
252+
253+
### How SAS Token Authentication Works
254+
255+
Azure SAS tokens are passed in the MQTT password field with a specific format:
256+
- **Username**: `{iothubhostname}/{deviceId}/?api-version=2021-04-12`
257+
- **Password**: `SharedAccessSignature sr={resource}&sig={signature}&se={expiry}`
258+
259+
### Implement HTTP Authentication for SAS Tokens
260+
261+
1. **Create an HTTP authentication service** that:
262+
- Receives the username and password from EMQX
263+
- Extracts the deviceId from the username
264+
- Parses the SAS token from the password field
265+
- Validates the token signature using the device's symmetric key
266+
- Checks the token expiry (`se` field)
267+
- Returns `{"result": "allow"}` or `{"result": "deny"}`
268+
269+
2. **Configure EMQX HTTP Authenticator** via Dashboard or configuration file:
270+
271+
```hocon
272+
authentication = [
273+
{
274+
mechanism = password_based
275+
backend = http
276+
method = post
277+
url = "http://your-auth-service:8080/auth"
278+
body {
279+
username = "${username}"
280+
password = "${password}"
281+
clientid = "${clientid}"
282+
}
283+
headers {
284+
"Content-Type" = "application/json"
285+
}
286+
}
287+
]
288+
```
289+
290+
3. **Provision Device Credentials**: Export device identities and symmetric keys from Azure IoT Hub identity registry and provision them in your authentication service's database.
291+
292+
### Example HTTP Authentication Service Response
293+
294+
```json
295+
{
296+
"result": "allow",
297+
"is_superuser": false,
298+
"client_attrs": {
299+
"device_id": "device-001"
300+
}
301+
}
302+
```
303+
304+
::: tip
305+
This approach allows SAS token-based devices to migrate without firmware changes. However, for long-term portability and security, migrating to X.509 certificate authentication is recommended.
306+
:::
307+
308+
## Conclusion
309+
310+
Migrating devices from Azure IoT Hub to EMQX offers flexible paths depending on your authentication method:
311+
312+
**For X.509 certificate-based devices**: The migration is straightforward when using your own Certificate Authority. Device certificates and private keys remain unchanged, requiring only endpoint updates and server CA deployment. Follow the three phases: locating your CA certificate, configuring EMQX for mTLS with CN-based identity mapping, and updating device clients to successfully migrate while maintaining the same security model.
313+
314+
**For SAS token-based devices**: Devices can continue using SAS tokens by implementing an HTTP authentication service that validates token signatures and expiry. This allows migration without firmware changes, though transitioning to X.509 certificates is recommended for long-term portability.
315+
316+
::: tip
317+
Focus your initial migration on X.509 CA-signed devices to achieve quick wins. For SAS token devices, evaluate whether to implement HTTP authentication for immediate migration or refactor to X.509 certificates for better long-term maintainability.
318+
:::

ja_JP/migration/migrate-from-aws-iot-core.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,9 @@ With your CA certificate located, the next step is to configure the EMQX broker
5252

5353
The core of the migration is enabling two-way SSL/TLS authentication (mTLS) on an EMQX listener. This configuration instructs EMQX to demand a certificate from the connecting client and verify its authenticity against your CA.
5454

55-
**Action**: Open the EMQX configuration file (e.g., `emqx.conf`) and configure the SSL/TLS listener:
55+
For detailed information on SSL/TLS configuration options, see [Enable SSL/TLS Connection](../network/emqx-mqtt-tls.md). For certificate management, see [TLS Certificates](../network/tls-certificate.md).
56+
57+
**Action**: Open the EMQX configuration file (e.g., `emqx.conf`) and configure the SSL/TLS listener, or use the Dashboard (**Management** -> **Listeners**):
5658

5759
```hocon
5860
listeners.ssl.default {
@@ -90,6 +92,14 @@ Both AWS IoT Core and EMQX use port 8883 as the default for MQTT over TLS/SSL, s
9092
* `fail_if_no_peer_cert`: Must be set to `true` to reject connections without a client certificate, enforcing mTLS.
9193
* `certfile` and `keyfile`: Your EMQX server's own certificate and private key. Clients will verify this certificate to ensure they're connecting to the correct broker.
9294

95+
After updating the configuration file, reload the configuration:
96+
97+
```bash
98+
emqx ctl conf reload
99+
```
100+
101+
If you made changes via the Dashboard, click **Update** to apply them. The listener will restart automatically to apply the new settings.
102+
93103
### (Optional) Map Certificate CN to ClientID or Username
94104

95105
In many AWS IoT Core implementations, authorization policies rely on variables populated from the certificate, such as using the certificate's Common Name (CN) as the `iot:ClientId`. EMQX can replicate this behavior seamlessly, allowing for easier migration of authorization rules.

0 commit comments

Comments
 (0)