Skip to content

Commit c52f971

Browse files
authored
Merge pull request #290764 from jlian/main
Improve X.509 section flow
2 parents 9984135 + c84a152 commit c52f971

File tree

3 files changed

+170
-53
lines changed

3 files changed

+170
-53
lines changed

articles/iot-operations/manage-mqtt-broker/howto-configure-authentication.md

Lines changed: 169 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,13 @@ The following rules apply to the relationship between BrokerListener and *Broker
2525

2626
* Each BrokerListener can have multiple ports. Each port can be linked to a *BrokerAuthentication* resource.
2727
* Each *BrokerAuthentication* can support multiple authentication methods at once.
28-
* Ports that do not link a *BrokerAuthentication* resource have authentication disabled.
28+
* Ports that don't link a *BrokerAuthentication* resource have authentication disabled.
2929

3030
To link a BrokerListener port to a *BrokerAuthentication* resource, specify the `authenticationRef` field in the `ports` setting of the BrokerListener resource. To learn more, see [BrokerListener resource](./howto-configure-brokerlistener.md).
3131

3232
## Default BrokerAuthentication resource
3333

34-
Azure IoT Operations deploys a default *BrokerAuthentication* resource named `default` linked with the *default* listener in the `azure-iot-operations` namespace. It's configured to only use [Kubernetes Service Account Tokens (SATs)](#kubernetes-service-account-tokens) for authentication.
34+
Azure IoT Operations deploys a default *BrokerAuthentication* resource named `default` linked with the *default* listener in the `azure-iot-operations` namespace. It only uses [Kubernetes Service Account Tokens (SATs)](#kubernetes-service-account-tokens) for authentication.
3535

3636
> [!IMPORTANT]
3737
> The service account token (SAT) authentication method in the default *BrokerAuthentication* resource is required for components in the Azure IoT Operations to function correctly. Avoid updating or deleting the default *BrokerAuthentication* resource.
@@ -331,15 +331,47 @@ For more information about enabling secure settings by configuring an Azure Key
331331

332332
## X.509
333333

334-
In X.509 authentication, MQTT broker uses a trusted CA certificate to validate client certificates. Clients present a certificate rooted in this CA for MQTT broker to authenticate them. Both EC and RSA keys are supported, but all certificates in the chain must use the same key algorithm. Since X.509 relies on TLS client certificates, TLS must be enabled for ports using X.509 authentication.
334+
With X.509 authentication, the MQTT broker uses a **trusted CA certificate** to validate client certificates. This trusted CA can be a root or intermediate CA. The broker checks the client certificate chain against the trusted CA certificate. If the chain is valid, the client is authenticated.
335335

336-
To import a root certificate that can be used to validate client certificates, store the certificate PEM in a *ConfigMap*. For example:
336+
To use X.509 authentication with a trusted CA certificate, the following requirements must be met:
337+
338+
- **TLS**: Since X.509 relies on TLS client certificates, [TLS must be enabled for ports using X.509 authentication](./howto-configure-brokerlistener.md).
339+
- **Key algorithms**: Both EC and RSA keys are supported, but all certificates in the chain must use the same key algorithm.
340+
- **Format**: The CA certificate must be in PEM format.
341+
342+
> [!TIP]
343+
> PEM format is a common format for certificates and keys. PEM files are base64-encoded ASCII files with headers like `-----BEGIN CERTIFICATE-----` and `-----BEGIN EC PRIVATE KEY-----`.
344+
>
345+
> If you have a certificate in another format, you can convert it to PEM using OpenSSL. For more information, see [How to convert a certificate into the appropriate format](https://knowledge.digicert.com/solution/how-to-convert-a-certificate-into-the-appropriate-format).
346+
347+
### Get a trusted CA certificate
348+
349+
In a production setup, the CA certificate is provided by an organization's public key infrastructure (PKI) or a public certificate authority.
350+
351+
For testing, create a self-signed CA certificate with OpenSSL. For example, run the following command to generate a self-signed CA certificate with an RSA key, a distinguished name `CN=Contoso Root CA Cert`, and a validity of 365 days:
337352

338353
```bash
339-
kubectl create configmap client-ca --from-file=client_ca.pem -n azure-iot-operations
354+
openssl req -x509 -newkey rsa:4096 -keyout ca-key.pem -out ca.pem -days 365 -nodes -subj "/CN=Contoso Root CA Cert"
340355
```
341356

342-
In this example, the CA certificate is imported under the key `client_ca.pem`. MQTT broker trusts all CA certificates in the ConfigMap, so the name of the key can be anything.
357+
The same command with [Step CLI](https://smallstep.com/docs/step-cli/installation/), which is a convenient tool for managing certificates, is:
358+
359+
```bash
360+
step certificate create "Contoso Root CA Cert" ca.pem ca-key.pem --profile root-ca --kty RSA --size 4096 --no-password --insecure
361+
--not-after 8760h
362+
```
363+
364+
These commands create a CA certificate `ca.pem` and a private key `ca-key.pem` in PEM format. The CA certificate `ca.pem` can be imported into the MQTT broker for X.509 authentication.
365+
366+
### Import a trusted CA certificate
367+
368+
To get started with X.509 authentication, import the trusted CA certificate into a ConfigMap in the `azure-iot-operations` namespace. To import a trusted CA certificate `ca.pem` into a ConfigMap named `client-ca`, run:
369+
370+
```bash
371+
kubectl create configmap client-ca --from-file=ca.pem -n azure-iot-operations
372+
```
373+
374+
In this example, the CA certificate is imported under the key `ca.pem`. MQTT broker trusts all CA certificates in the ConfigMap, so the name of the key can be anything.
343375

344376
To check the root CA certificate is properly imported, run `kubectl describe configmap`. The result shows the same base64 encoding of the PEM certificate file.
345377

@@ -353,22 +385,21 @@ Namespace: azure-iot-operations
353385
354386
Data
355387
====
356-
client_ca.pem:
388+
ca.pem:
357389
----
358390
-----BEGIN CERTIFICATE-----
359-
<Certificate>
391+
MIIFDjCCAvagAwIBAgIRAKQWo1+S13GTwqZSUYLPemswDQYJKoZIhvcNAQELBQAw
392+
...
360393
-----END CERTIFICATE-----
361394
362395
363396
BinaryData
364397
====
365398
```
366399

367-
Once the trusted CA certificate is imported, enable X.509 client authentication by adding it as one of the authentication methods in a *BrokerAuthentication* resource linked to a TLS-enabled listener port.
368-
369-
### Certificate attributes for authorization
400+
### Configure X.509 authentication method
370401

371-
X.509 attributes can be specified in the *BrokerAuthentication* resource for authorizing clients based on their certificate properties. The attributes are defined in the `authorizationAttributes` field.
402+
Once the trusted CA certificate is imported, enable X.509 client authentication by adding it as an authentication method in a *BrokerAuthentication* resource. Ensure this resource is linked to a TLS-enabled listener port.
372403

373404
# [Portal](#tab/portal)
374405

@@ -378,15 +409,28 @@ X.509 attributes can be specified in the *BrokerAuthentication* resource for aut
378409
1. Choose an existing authentication policy or create a new one.
379410
1. Add a new method by selecting **Add method**.
380411
1. Choose the method type **X.509** from the dropdown list then select **Add details** to configure the method.
412+
1. In the **X.509 authentication details** pane, specify the trusted CA certificate ConfigMap name using JSON format.
413+
414+
```json
415+
{
416+
"trustedClientCaCert": "<TRUSTED_CA_CONFIGMAP>"
417+
}
418+
```
419+
420+
Replace `<TRUSTED_CA_CONFIGMAP>` with the name of the ConfigMap that contains the trusted CA certificate. For example, `"trustedClientCaCert": "client-ca"`.
421+
422+
:::image type="content" source="media/howto-configure-authentication/x509-method.png" alt-text="Screenshot using Azure portal to set MQTT broker X.509 authentication method." lightbox="media/howto-configure-authentication/x509-method.png":::
381423
382-
:::image type="content" source="media/howto-configure-authentication/x509-method.png" alt-text="Screenshot using Azure portal to set MQTT broker X.509 authentication method." lightbox="media/howto-configure-authentication/x509-method.png":::
424+
1. Optionally, add authorization attributes for clients using X.509 certificates. To learn more, see [Certificate attributes for authorization](#optional-certificate-attributes-for-authorization).
425+
1. Select **Apply** to save the changes.
383426
384427
# [Bicep](#tab/bicep)
385428
386429
```bicep
387430
param aioInstanceName string = '<AIO_INSTANCE_NAME>'
388431
param customLocationName string = '<CUSTOM_LOCATION_NAME>'
389432
param policyName string = '<POLICY_NAME>'
433+
param trustedCaConfigMap string = '<TRUSTED_CA_CONFIGMAP>'
390434

391435
resource aioInstance 'Microsoft.IoTOperations/instances@2024-11-01' existing = {
392436
name: aioInstanceName
@@ -413,27 +457,11 @@ resource myBrokerAuthentication 'Microsoft.IoTOperations/instances/brokers/authe
413457
{
414458
method: 'X509'
415459
x509Settings: {
416-
authorizationAttributes: {
417-
root: {
418-
subject: 'CN = Contoso Root CA Cert, OU = Engineering, C = US'
419-
attributes: {
420-
organization: 'contoso'
421-
}
422-
}
423-
intermediate: {
424-
subject: 'CN = Contoso Intermediate CA'
425-
attributes: {
426-
city: 'seattle'
427-
foo: 'bar'
428-
}
429-
}
430-
smartfan: {
431-
subject: 'CN = smart-fan'
432-
attributes: {
433-
building: '17'
434-
}
435-
}
436-
}
460+
trustedClientCaCert: trustedCaConfigMap
461+
// authorizationAttributes: {
462+
//// Optional authorization attributes
463+
//// See the next section for more information
464+
// }
437465
}
438466
}
439467
]
@@ -442,6 +470,8 @@ resource myBrokerAuthentication 'Microsoft.IoTOperations/instances/brokers/authe
442470

443471
```
444472

473+
Replace `<TRUSTED_CA_CONFIGMAP>` with the name of the ConfigMap that contains the trusted CA certificate. For example, `client-ca`.
474+
445475
Deploy the Bicep file using Azure CLI.
446476

447477
```azurecli
@@ -455,20 +485,102 @@ spec:
455485
authenticationMethods:
456486
- method: X509
457487
x509Settings:
458-
authorizationAttributes:
459-
root:
460-
subject = "CN = Contoso Root CA Cert, OU = Engineering, C = US"
461-
attributes:
462-
organization = contoso
463-
intermediate:
464-
subject = "CN = Contoso Intermediate CA"
465-
attributes:
466-
city = seattle
467-
foo = bar
468-
smart-fan:
469-
subject = "CN = smart-fan"
470-
attributes:
471-
building = 17
488+
trustedClientCaCert: <TRUSTED_CA_CONFIGMAP>
489+
# authorizationAttributes:
490+
## Optional authorization attributes
491+
## See the next section for more information
492+
```
493+
494+
Replace `<TRUSTED_CA_CONFIGMAP>` with the name of the ConfigMap that contains the trusted CA certificate. For example, `client-ca`.
495+
496+
---
497+
498+
#### Optional: Certificate attributes for authorization
499+
500+
X.509 attributes can be specified in the *BrokerAuthentication* resource for authorizing clients based on their certificate properties. The attributes are defined in the `authorizationAttributes` field.
501+
502+
For example:
503+
504+
# [Portal](#tab/portal)
505+
506+
In the Azure portal, when configuring the X.509 authentication method, add the authorization attributes in the **X.509 authentication details** pane in JSON format.
507+
508+
```json
509+
{
510+
"trustedClientCaCert": "<TRUSTED_CA_CONFIGMAP>",
511+
"authorizationAttributes": {
512+
"root": {
513+
"subject": "CN = Contoso Root CA Cert, OU = Engineering, C = US",
514+
"attributes": {
515+
"organization": "contoso"
516+
}
517+
},
518+
"intermediate": {
519+
"subject": "CN = Contoso Intermediate CA",
520+
"attributes": {
521+
"city": "seattle",
522+
"foo": "bar"
523+
}
524+
},
525+
"smartfan": {
526+
"subject": "CN = smart-fan",
527+
"attributes": {
528+
"building": "17"
529+
}
530+
}
531+
}
532+
}
533+
```
534+
535+
536+
# [Bicep](#tab/bicep)
537+
538+
```bicep
539+
x509Settings: {
540+
trustedClientCaCert: '<TRUSTED_CA_CONFIGMAP>'
541+
authorizationAttributes: {
542+
root: {
543+
subject: 'CN = Contoso Root CA Cert, OU = Engineering, C = US'
544+
attributes: {
545+
organization: 'contoso'
546+
}
547+
}
548+
intermediate: {
549+
subject: 'CN = Contoso Intermediate CA'
550+
attributes: {
551+
city: 'seattle'
552+
foo: 'bar'
553+
}
554+
}
555+
smartfan: {
556+
subject: 'CN = smart-fan'
557+
attributes: {
558+
building: '17'
559+
}
560+
}
561+
}
562+
}
563+
```
564+
565+
# [Kubernetes (preview)](#tab/kubernetes)
566+
567+
```yaml
568+
x509Settings:
569+
trustedClientCaCert: <TRUSTED_CA_CONFIGMAP>
570+
authorizationAttributes:
571+
root:
572+
subject = "CN = Contoso Root CA Cert, OU = Engineering, C = US"
573+
attributes:
574+
organization = contoso
575+
intermediate:
576+
subject = "CN = Contoso Intermediate CA"
577+
attributes:
578+
city = seattle
579+
foo = bar
580+
smart-fan:
581+
subject = "CN = smart-fan"
582+
attributes:
583+
building = 17
472584
```
473585
474586
---
@@ -477,7 +589,12 @@ In this example, every client that has a certificate issued by the root CA with
477589

478590
The matching for attributes always starts from the leaf client certificate and then goes along the chain. The attribute assignment stops after the first match. In previous example, even if `smart-fan` has the intermediate certificate `CN = Contoso Intermediate CA`, it doesn't get the associated attributes.
479591

480-
Authorization rules can be applied to clients using X.509 certificates with these attributes. To learn more, see [Authorize clients that use X.509 authentication](./howto-configure-authorization.md).
592+
Authorization rules can be applied to clients using X.509 certificates with these attributes. To learn more, see [Authorize clients that use X.509 authentication](./howto-configure-authorization.md#authorize-clients-that-use-x509-authentication).
593+
594+
### Enable X.509 authentication for a listener port
595+
596+
After importing the trusted CA certificate and configuring the *BrokerAuthentication* resource, link it to a TLS-enabled listener port. For more details, see [Enable TLS manual certificate management for a port](./howto-configure-brokerlistener.md#enable-tls-manual-certificate-management-for-a-port) and [Enable TLS automatic certificate management for a port](./howto-configure-brokerlistener.md#enable-tls-automatic-certificate-management-for-a-port).
597+
481598

482599
### Connect mosquitto client to MQTT broker with X.509 client certificate
483600

@@ -509,7 +626,7 @@ The following are the steps for client authentication:
509626
1. The TLS channel is open, but the client authentication or authorization isn't finished yet.
510627
1. The client then sends a CONNECT packet to MQTT broker.
511628
1. The CONNECT packet is routed to a frontend again.
512-
1. The frontend collects all credentials the client presented so far, like username and password fields, authentication data from the CONNECT packet, and the client certificate chain presented during the TLS handshake.
629+
1. The frontend collects all credentials the client presented so far, like authentication data from the CONNECT packet, and the client certificate chain presented during the TLS handshake.
513630
1. The frontend sends these credentials to the authentication service. The authentication service checks the certificate chain once again and collects the subject names of all the certificates in the chain.
514631
1. The authentication service uses its [configured authorization rules](./howto-configure-authorization.md) to determine what attributes the connecting clients has. These attributes determine what operations the client can execute, including the CONNECT packet itself.
515632
1. Authentication service returns decision to frontend broker.
@@ -653,7 +770,7 @@ For example, if the client is a pod that uses the token mounted as a volume, lik
653770

654771
Extend client authentication beyond the provided authentication methods with custom authentication. It's *pluggable* since the service can be anything as long as it adheres to the API.
655772

656-
When a client connects to MQTT broker and custom authentication is enabled, MQTT broker delegates the verification of client credentials to a custom authentication server with an HTTPS request along with all credentials the client presents. The custom authentication server responds with approval or denial for the client with the client's [attributes for authorization](./howto-configure-authorization.md).
773+
When a client connects to the MQTT broker with custom authentication enabled, the broker sends an HTTPS request to a custom authentication server with the client's credentials. The server then responds with either approval or denial, including the client's [authorization attributes](./howto-configure-authorization.md).
657774

658775
### Create custom authentication service
659776

@@ -727,7 +844,7 @@ MQTT broker disconnects clients when their credentials expire. Disconnect after
727844
- Clients authenticated with X.509 disconnect when their client certificate expires
728845
- Clients authenticated with custom authentication disconnect based on the expiry time returned from the custom authentication server.
729846

730-
On disconnect, the client's network connection is closed. The client won't receive an MQTT DISCONNECT packet, but the broker logs a message that it disconnected the client.
847+
On disconnect, the client's network connection is closed. The client doesn't receive an MQTT DISCONNECT packet, but the broker logs a message that it disconnected the client.
731848

732849
MQTT v5 clients authenticated with SATs and custom authentication can reauthenticate with a new credential before their initial credential expires. X.509 clients can't reauthenticate and must re-establish the connection since authentication is done at the TLS layer.
733850

articles/iot-operations/manage-mqtt-broker/howto-configure-authorization.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ Clients that use [X.509 certificates for authentication](./howto-configure-authe
323323

324324
### Using attributes
325325

326-
To create rules based on properties from a client's certificate, its root CA, or intermediate CA, define the X.509 attributes in the *BrokerAuthorization* resource. For more information, see [Certificate attributes](howto-configure-authentication.md#certificate-attributes-for-authorization).
326+
To create rules based on properties from a client's certificate, its root CA, or intermediate CA, define the X.509 attributes in the *BrokerAuthorization* resource. For more information, see [Certificate attributes](howto-configure-authentication.md#optional-certificate-attributes-for-authorization).
327327

328328
### With client certificate subject common name as username
329329

-56.8 KB
Loading

0 commit comments

Comments
 (0)