Skip to content

Commit ff66efe

Browse files
Merge pull request #290962 from jlian/main
Better clarity around hostname
2 parents 20cf4cb + d64b138 commit ff66efe

File tree

2 files changed

+53
-32
lines changed

2 files changed

+53
-32
lines changed

articles/iot-operations/manage-mqtt-broker/howto-test-connection.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -446,13 +446,16 @@ If the external IP is not assigned, you might need to use port forwarding or a v
446446

447447
With [minikube](https://minikube.sigs.k8s.io/docs/), [kind](https://kind.sigs.k8s.io/), and other cluster emulation systems, an external IP might not be automatically assigned. For example, it might show as *Pending* state.
448448

449-
1. To access the broker, forward the broker listening port 18883 to the host.
449+
1. To access the broker, forward the broker listener port to the host.
450450

451451
```bash
452-
kubectl port-forward --namespace azure-iot-operations service/aio-broker 18883:mqtts-18883
452+
# Using aio-broker-loadbalancer service name and listener port 1883 as example
453+
kubectl port-forward --namespace azure-iot-operations service/aio-broker-loadbalancer <HOST_PORT>:1883
453454
```
454455

455-
1. Use 127.0.0.1 to connect to the broker at port 18883 with the same authentication and TLS configuration as the example without port forwarding.
456+
1. Leave the port forwarding command running in the terminal.
457+
458+
1. Connect to the broker at the host port with the same authentication and TLS configuration as the example without port forwarding.
456459

457460
For more information about minikube, see [Use Port Forwarding to Access Applications in a Cluster](https://kubernetes.io/docs/tasks/access-application-cluster/port-forward-access-application-cluster/)
458461

articles/iot-operations/manage-mqtt-broker/tutorial-tls-x509.md

Lines changed: 47 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -27,21 +27,48 @@ The tutorial simulates an environment where Azure IoT Operations is installed in
2727

2828
To follow this tutorial, you need:
2929

30+
- A Kubernetes cluster with port forwarding enabled for port 8883.
3031
- Azure IoT Operations deployed without an existing load balancer listener.
31-
- A Kubernetes cluster with port forwarding enabled for port 8883, allowing localhost access to the broker listener.
3232
- Kubectl access to the cluster to create Kubernetes secrets and config maps.
33+
- [Mosquitto client](https://mosquitto.org/download/) to publish and subscribe to MQTT messages running on the same machine as the Kubernetes cluster for `localhost` access. To not use `localhost`, see [Optional: Use a real hostname or IP address instead of `localhost`](#optional-use-a-real-hostname-or-ip-address-instead-of-localhost) section.
3334
- [Step CLI](https://smallstep.com/docs/step-cli/) to create certificates.
34-
- [Mosquitto client](https://mosquitto.org/download/) to publish and subscribe to MQTT messages.
3535

36-
We recommend using the [quickstart codespace](../get-started-end-to-end-sample/quickstart-deploy.md), which already meets all these requirements. The quickstart codespace simplifies the setup process by providing these components out of the box.
36+
> [!TIP]
37+
> To meet these requirements, use the [quickstart codespace](../get-started-end-to-end-sample/quickstart-deploy.md). The quickstart codespace simplifies the setup process by providing these components out of the box.
3738
3839
Additionally, familiarity with public key cryptography and terms like root CA, private key, and intermediate certificates is useful.
3940

41+
### Optional: Use a real hostname or IP address instead of `localhost`
42+
43+
To keep this tutorial simple, we use `localhost` to access the MQTT broker. This approach ensures that the broker's server certificate has a Subject Alternative Name (SAN) that matches the hostname used to access the broker. Using `localhost` simplifies the setup since the SAN is already set correctly.
44+
45+
In a real-world scenario, you'd use the hostname or external IP of the broker instead of `localhost` and connect to it from another device on the network. In this case, you need to determine the correct hostname or IP address and use it as the SAN when creating the server certificate:
46+
47+
- If the hostname or IP address is already known (for example, through a DNS record or static IP), use it as the SAN when creating the server certificate. Then, connect to the broker using that hostname or IP instead of `localhost`.
48+
- If the hostname or IP address isn't already known, you can use a placeholder service to determine the external IP address:
49+
1. Create the LoadBalancer service on a port that's not being used (like 8080):
50+
```sh
51+
kubectl create service loadbalancer placeholder-service --tcp=8080:8080
52+
```
53+
1. Retrieve the external IP:
54+
```sh
55+
kubectl get svc placeholder-service
56+
```
57+
1. If the external IP:
58+
- Shows a value like `192.168.X.X` - use that IP as the SAN when creating the server certificate and secret. Then, connect to the broker using that IP instead of `localhost`.
59+
- Shows `<pending>` - the Kubernetes distribution you use might not support automatically assigning an external IP. To find the external IP, follow the steps in the Kubernetes documentation for your distribution and host environment. You might also need to configure [port forwarding](./howto-test-connection.md#use-port-forwarding) or a VPN depending on the network setup.
60+
1. After determining the external IP, delete the placeholder service:
61+
```sh
62+
kubectl delete svc placeholder-service
63+
```
64+
65+
This method ensures that the server certificate matches the external IP address, allowing secure access to the MQTT broker.
66+
4067
## Prepare server-side certificates and full chain
4168

4269
First, create a server-side root CA. This CA is separate from the client-side root CA which is created later. To keep the separation clear, we name everything server side "Contoso". To make later steps easier, we skip the password for encrypting the private key. This practice is only acceptable in a tutorial setting.
4370

44-
```bash
71+
```sh
4572
step certificate create "Contoso Root CA" \
4673
contoso_root_ca.crt contoso_root_ca.key \
4774
--profile root-ca \
@@ -50,7 +77,7 @@ contoso_root_ca.crt contoso_root_ca.key \
5077

5178
Then, create an intermediate CA signed by this root CA.
5279

53-
```bash
80+
```sh
5481
step certificate create "Contoso Intermediate CA 1" \
5582
contoso_intermediate_ca.crt contoso_intermediate_ca.key \
5683
--profile intermediate-ca \
@@ -60,7 +87,7 @@ contoso_intermediate_ca.crt contoso_intermediate_ca.key \
6087

6188
Lastly, use this intermediate CA to sign a server certificate for MQTT broker's broker frontend. Here, `localhost` is the Subject Alternative Name (SAN) used for the tutorial.
6289
63-
```bash
90+
```sh
6491
step certificate create mqtts-endpoint \
6592
mqtts-endpoint.crt mqtts-endpoint.key \
6693
--profile leaf \
@@ -72,22 +99,17 @@ mqtts-endpoint.crt mqtts-endpoint.key \
7299
73100
With the `--bundle` flag, the server certificate is bundled with the signing intermediate certificate. TLS handshake requires the bundle to verify the full chain.
74101
75-
> [!TIP]
76-
> To simplify the tutorial, we use `localhost` as the Subject Alternative Name (SAN).
77-
>
78-
> If you don't have localhost port forwarding set up, [create the listener](#listener) first. Then, retrieve the external IP using `kubectl get service mqtts-endpoint -n azure-iot-operations`, and use that IP as the SAN when creating the server certificate and the secret. The broker waits for the secret to be created before fully starting the listener, so the order of operations is flexible.
79-
80102
## Prepare client-side certificates and full chain
81103
82104
Similarly, create the root CA for Fabrikam and the intermediate CA.
83105
84-
```bash
106+
```sh
85107
step certificate create --profile root-ca "Fabrikam Root CA" \
86108
fabrikam_root_ca.crt fabrikam_root_ca.key \
87109
--no-password --insecure
88110
```
89111
90-
```bash
112+
```sh
91113
step certificate create "Fabrikam Intermediate CA 1" \
92114
fabrikam_intermediate_ca.crt fabrikam_intermediate_ca.key \
93115
--profile intermediate-ca \
@@ -97,7 +119,7 @@ fabrikam_intermediate_ca.crt fabrikam_intermediate_ca.key \
97119
98120
Then, generate client certificates for a thermostat, hygrometer, heater, and lightbulb.
99121
100-
```bash
122+
```sh
101123
# Create a client certificate for the thermostat
102124
step certificate create thermostat thermostat.crt thermostat.key \
103125
--ca ./fabrikam_intermediate_ca.crt --ca-key ./fabrikam_intermediate_ca.key --bundle \
@@ -123,15 +145,15 @@ step certificate create lightbulb lightbulb.crt lightbulb.key \
123145
124146
Import the newly generated server certificate and private key into a Kubernetes secret. This secret is used to configure a TLS listener for MQTT broker later.
125147
126-
```bash
148+
```sh
127149
kubectl create secret tls broker-server-cert -n azure-iot-operations \
128150
--cert mqtts-endpoint.crt \
129151
--key mqtts-endpoint.key
130152
```
131153
132154
Also, create a config map to contain the Fabrikam (client-side) root CA. This config map is required for MQTT broker to trust it for X.509 authentication.
133155
134-
```bash
156+
```sh
135157
kubectl create configmap fabrikam-ca -n azure-iot-operations \
136158
--from-file=client_ca.pem=fabrikam_root_ca.crt
137159
```
@@ -229,17 +251,13 @@ mqtts-endpoint LoadBalancer 10.43.28.140 XXX.XX.X.X 8883:30988/TCP 10
229251
Instead of using the external IP, we use `localhost` for the tutorial.
230252
231253
> [!TIP]
232-
> The codespace configuration automatically sets up port forwarding for 8883. To setup other environments, use `kubectl port-forward` to forward the port.
233-
>
234-
> ```bash
235-
> kubectl port-forward svc/mqtts-endpoint 8883:8883 -n azure-iot-operations
236-
> ```
254+
> The codespace configuration automatically sets up port forwarding for 8883. To setup other environments, see [Use port forwarding](./howto-test-connection.md#use-port-forwarding).
237255
238256
## Use a single Mosquito client to publish messages over TLS
239257
240258
From the same folder as the certificate files: `contoso_root_ca.crt`, `thermostat.crt`, and `thermostat.key`, use Mosquito client to publish a message. The `--cafile contoso_root_ca.crt` flag is for Mosquito to perform server certificate verification.
241259
242-
```bash
260+
```sh
243261
mosquitto_pub -t "example/topic" -m "example temperature measurement" -i thermostat \
244262
-q 1 -V mqttv5 -d \
245263
-h localhost \
@@ -372,7 +390,7 @@ In this section, we test out the newly applied authorization policies.
372390
373391
First, connect with `thermostat` and try to publish on topic `telemetry/humidity`:
374392
375-
```bash
393+
```sh
376394
mosquitto_pub -t "telemetry/humidity" -m "example temperature measurement" -i thermostat \
377395
-q 1 -V mqttv5 -d \
378396
-h localhost \
@@ -393,7 +411,7 @@ Warning: Publish 1 failed: Not authorized.
393411

394412
Change to publish to `telemetry/temperature`, which is allowed and the publish succeeds. Leave the command running.
395413

396-
```bash
414+
```sh
397415
mosquitto_pub -t "telemetry/temperature" -m "example temperature measurement" -i thermostat \
398416
-q 1 -V mqttv5 -d \
399417
-h localhost \
@@ -408,7 +426,7 @@ mosquitto_pub -t "telemetry/temperature" -m "example temperature measurement" -i
408426

409427
In a separate terminal session, connect with `heater` to subscribe to `health/heartbeat`.
410428

411-
```bash
429+
```sh
412430
mosquitto_sub -q 1 -t "health/heartbeat" -d -V mqttv5 \
413431
-i heater \
414432
-h localhost \
@@ -429,7 +447,7 @@ Subscribed (mid: 1): 135
429447

430448
Switch the subscription topic to `telemetry/temperature`, which `thermostat` is still sending messages to.
431449

432-
```bash
450+
```sh
433451
mosquitto_sub -q 1 -t "telemetry/temperature" -d -V mqttv5 \
434452
-i heater \
435453
-h localhost \
@@ -442,7 +460,7 @@ Now `heater` starts to receive messages because it's authorized with its [userna
442460
443461
In *another* separate terminal session, publish messages to `health/heartbeat` with `lightbulb`:
444462
445-
```bash
463+
```sh
446464
mosquitto_pub -q 1 -t "health/heartbeat" -m "example heartbeat" -d -V mqttv5 \
447465
-i lightbulb \
448466
-h localhost \
@@ -476,14 +494,14 @@ To clean up the resources created in this tutorial, delete the listener and the
476494

477495
Also, delete the Kubernetes secret and config map.
478496

479-
```bash
497+
```sh
480498
kubectl delete secret broker-server-cert -n azure-iot-operations
481499
kubectl delete configmap fabrikam-ca -n azure-iot-operations
482500
```
483501

484502
Finally, delete the certificates and keys generated earlier.
485503

486-
```bash
504+
```sh
487505
rm contoso_root_ca.crt contoso_root_ca.key contoso_intermediate_ca.crt contoso_intermediate_ca.key mqtts-endpoint.crt mqtts-endpoint.key
488506
rm fabrikam_root_ca.crt fabrikam_root_ca.key fabrikam_intermediate_ca.crt fabrikam_intermediate_ca.key thermostat.crt thermostat.key hygrometer.crt hygrometer.key heater.crt heater.key lightbulb.crt lightbulb.key
489507
````

0 commit comments

Comments
 (0)