13 min read

IoT at Home: How to Access Your Sensors and Devices from the Internet Securely

Run a Mosquitto MQTT broker on your Raspberry Pi, connect your ESP32 sensors, and expose the broker from anywhere using a Localtonet TCP tunnel. No cloud broker required.

🏠 IoT · MQTT · Raspberry Pi · ESP32 · Remote Access · Home Automation

IoT at Home: How to Access Your Sensors and Devices from the Internet Securely

Your temperature sensors, soil moisture monitors, energy meters, and home automation devices all work perfectly on your local network. The problem starts when you want to check them from work, send data to a cloud dashboard, or trigger an action from your phone while away. This guide explains why IoT devices behind a home router cannot be reached from the internet, how MQTT works as the backbone of home IoT communication, and how a Localtonet tunnel solves the network problem without opening firewall ports or relying on third-party cloud brokers.

📡 MQTT and Mosquitto 🔧 Raspberry Pi and ESP32 🏠 Home Assistant compatible 🌍 Remote access from anywhere

Why Your IoT Devices Are Not Reachable from Outside

When an ESP32 reads a temperature sensor and publishes the value to an MQTT broker on your Raspberry Pi, everything works because both devices are on the same local network. They can reach each other freely. The moment you try to query that broker from outside your home from your phone on mobile data, from a script running in the cloud, from a remote dashboard you hit a wall.

Your home router assigns private IP addresses to all your devices and sits between them and the public internet. Nothing from outside can initiate a connection to a device inside your network unless port forwarding is configured. Even then, a large portion of home internet connections today are behind CGNAT, where the ISP places many customers behind a single shared public IP. On CGNAT, port forwarding on your router does nothing because there is no dedicated public IP to forward from.

The common workaround is to use a cloud MQTT broker like HiveMQ Cloud or CloudMQTT. That works, but it means your sensor data passes through a third-party server you do not control, you are subject to their pricing and rate limits, and your devices need internet access to publish anything at all. A Localtonet tunnel keeps the broker on your own hardware and gives it a public address without any of those trade-offs.

How MQTT Works

MQTT (Message Queuing Telemetry Transport) is a lightweight publish-subscribe messaging protocol designed for constrained devices and unreliable networks. It is the standard protocol for IoT communication.

The architecture has three roles. A broker is a server that receives all messages and routes them to interested clients. A publisher is a device that sends data a temperature sensor, a motion detector, an energy meter. A subscriber is anything that wants to receive that data a dashboard, a Home Assistant instance, a script, another device.

MQTT message flow

ESP32 reads temperature sensor

Publishes {"temp": 22.4} to topic home/living-room/temperature

Mosquitto broker receives and stores the message

Home Assistant, Node-RED, and your phone app all subscribed to that topic receive the value instantly

MQTT is built for exactly this kind of scenario: low-power devices on unreliable connections sending small payloads frequently. An ESP32 can publish a sensor reading, go back to deep sleep, and wake up to publish again the broker holds everything in between.

Lightweight protocol Very small packet overhead. Works well on ESP8266, ESP32, Arduino, and any microcontroller with a TCP stack.
📡 Publish-subscribe Publishers and subscribers are decoupled. Many devices can subscribe to the same topic without any coordination.
🔒 QoS levels Three Quality of Service levels: fire and forget, at least once, and exactly once delivery. Choose per message.
💾 Retained messages The broker stores the last message on a topic. New subscribers receive the current value immediately on connect.

Install the Mosquitto MQTT Broker on Raspberry Pi

Mosquitto is the most widely used open-source MQTT broker. It runs well on a Raspberry Pi and is available in the default package repositories on Raspberry Pi OS (Debian-based).

1

Install Mosquitto

sudo apt update
sudo apt install -y mosquitto mosquitto-clients

sudo systemctl enable mosquitto
sudo systemctl start mosquitto
2

Create a password file for authentication

Mosquitto 2.x requires authentication for non-local connections. Create a user account for your devices and clients. Replace myuser with a username of your choice.

sudo mosquitto_passwd -c /etc/mosquitto/passwd myuser

Enter and confirm a strong password when prompted.

3

Create the configuration file

sudo nano /etc/mosquitto/conf.d/local.conf

Add the following content:

listener 1883
allow_anonymous false
password_file /etc/mosquitto/passwd
4

Restart Mosquitto and verify it is running

sudo systemctl restart mosquitto
sudo systemctl status mosquitto

Test locally with the Mosquitto client tools:

# Subscribe to a test topic in one terminal
mosquitto_sub -h localhost -p 1883 -u myuser -P yourpassword -t home/test

# Publish a test message from another terminal
mosquitto_pub -h localhost -p 1883 -u myuser -P yourpassword -t home/test -m "hello"

If the subscriber terminal shows hello, your broker is working correctly on the local network.

Expose Your MQTT Broker from Anywhere with Localtonet

Mosquitto listens on TCP port 1883. To reach it from outside your network, create a Localtonet TCP tunnel for that port. The tunnel opens an outbound connection from your Raspberry Pi to the Localtonet relay, which becomes the public address that remote devices and clients connect to.

1

Install Localtonet on the Raspberry Pi

curl -fsSL https://localtonet.com/install.sh | sh
localtonet --authtoken <YOUR_TOKEN>
2

Create a TCP tunnel for port 1883

Go to the TCP/UDP tunnel page, select TCP as the protocol, set local IP to 127.0.0.1 and port to 1883. Click Create and start the tunnel. The dashboard shows your relay address, for example example.localto.net:33445.

3

Test the connection from a remote machine

# From any machine outside your home network
mosquitto_sub -h example.localto.net -p 33445 -u myuser -P yourpassword -t home/test
4

Keep the tunnel running permanently

Register Localtonet as a service so the tunnel comes back automatically after every reboot.

sudo localtonet --install-service --authtoken <YOUR_TOKEN>
sudo localtonet --start-service --authtoken <YOUR_TOKEN>
Reserve a fixed port for a stable broker address

TCP tunnel ports are assigned dynamically by default, which means the port number in your relay address can change after a restart. If your ESP32 devices or remote scripts have the broker address hardcoded, reserve a fixed port via Add-ons → Reserved Ports in the Localtonet dashboard. The relay port will never change.

Connect an ESP32 to Your Remote MQTT Broker

With the tunnel running, any ESP32 or ESP8266 with internet access can publish sensor data to your home broker using the relay address as the host. The code is identical to a local connection only the host and port change.

// Arduino / ESP32 sketch
#include <WiFi.h>
#include <PubSubClient.h>

const char* ssid       = "YOUR_WIFI_SSID";
const char* password   = "YOUR_WIFI_PASSWORD";

// Localtonet relay address and port
const char* mqttHost   = "example.localto.net";
const int   mqttPort   = 33445;
const char* mqttUser   = "myuser";
const char* mqttPass   = "yourpassword";

WiFiClient   espClient;
PubSubClient client(espClient);

void setup() {
    Serial.begin(115200);
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED) { delay(500); }

    client.setServer(mqttHost, mqttPort);
}

void loop() {
    if (!client.connected()) {
        client.connect("esp32-sensor", mqttUser, mqttPass);
    }
    client.loop();

    float temperature = 22.4; // replace with real sensor read
    char payload[32];
    snprintf(payload, sizeof(payload), "{\"temp\": %.1f}", temperature);

    client.publish("home/living-room/temperature", payload);
    delay(30000); // publish every 30 seconds
}
PubSubClient library

Install the PubSubClient library in the Arduino IDE via Sketch → Include Library → Manage Libraries. Search for PubSubClient by Nick O'Leary.

HTTP-Based Sensor APIs

Not all IoT devices use MQTT. Some devices expose a simple HTTP API a small web server running on the device itself that you query with a GET request to read sensor values. Shelly smart plugs, Tasmota-flashed devices, and many DIY ESP32 projects work this way.

For these devices, the approach is the same but uses an HTTP tunnel instead of a TCP tunnel. The device runs a web server on a local port, and a Localtonet HTTP tunnel gives that port a public HTTPS URL.

1

Find the port your device's HTTP API listens on

Most devices use port 80. Tasmota devices serve their web interface on port 80. A custom ESP32 web server typically uses port 80 as well. Check your device's documentation if you are unsure.

2

Create an HTTP tunnel for the device's port

Go to the HTTP tunnel page, set the local IP to the device's IP on your local network (e.g. 192.168.1.45) and the port to 80. Click Create. Localtonet creates a public HTTPS URL that proxies requests to the device.

3

Query the device from anywhere

# Read sensor data from a Tasmota or custom ESP32 device
curl https://abc123.localto.net/cm?cmnd=Status%2010

# Or a custom ESP32 API endpoint
curl https://abc123.localto.net/sensor
Localtonet must run on a device on the same network as your IoT device

For an HTTP tunnel pointing at a local IP like 192.168.1.45, the Localtonet client needs to run on a machine on the same local network as that device your Raspberry Pi, home server, or always-on computer. The Localtonet client on that machine will forward traffic to the IoT device's local IP.

Security for Remote IoT Access

🔑 Always enable authentication on Mosquitto

The default Mosquitto configuration rejects all connections from non-local clients. When you open the broker to remote connections, always require a username and password as shown in the setup above. An open broker on the internet will be found and abused very quickly. Create one set of credentials per device category do not share one password across everything.

🌍 Keep port 1883 off the public internet

The Localtonet tunnel approach binds Mosquitto to 127.0.0.1 only, meaning the broker cannot be reached directly from your local network or the internet without going through the tunnel. This is the safest configuration. If you need local network access as well, bind Mosquitto to 0.0.0.0 but keep the port blocked at the firewall level for external access.

🔒 Use separate topics per device

Structure your MQTT topics hierarchically for example home/bedroom/temperature, home/garden/moisture, home/garage/motion. This makes it easy to set per-topic access control rules in Mosquitto using the ACL feature, so each device can only publish to its own topics and not read data from others.

📡 Rotate credentials for devices you no longer use

If a device is decommissioned or lost, delete its credentials from the Mosquitto password file with sudo mosquitto_passwd -D /etc/mosquitto/passwd deviceuser and restart the broker. The device can no longer connect even if someone else has the credentials.

Frequently Asked Questions

Can I connect Home Assistant to the MQTT broker through the tunnel?

Yes. If Home Assistant is running on the same local network as Mosquitto, it connects to localhost:1883 directly and the tunnel is not needed for that connection. The tunnel is for external devices and remote scripts that need to reach the broker from outside your network. Home Assistant uses the local connection, which is faster and more reliable.

My ESP32 is at a remote location and needs to send data to my home broker. Will this work?

Yes. This is one of the best use cases. An ESP32 installed at a remote location a holiday home, a greenhouse, a weather station connects to the Localtonet relay address over the internet and publishes data to your home broker as if it were on your local network. You view the data through Home Assistant or any MQTT subscriber running at home.

Does MQTT work over UDP or TCP?

Standard MQTT runs over TCP. The TCP tunnel in Localtonet is the correct choice for exposing an MQTT broker. MQTT over WebSockets (port 9001 in Mosquitto) is also TCP and works the same way. There is no UDP variant of the standard MQTT protocol.

What is the difference between MQTT and HTTP for IoT?

MQTT is a persistent connection protocol designed for continuous data streams and low-power devices. A device connects to the broker once and publishes data as it becomes available, with very low overhead per message. HTTP is a request-response protocol where the client makes a new connection for every query. MQTT is better for sensors that send data frequently, devices with limited battery, and real-time automation. HTTP is simpler to implement for one-off reads or control commands.

Can I use Node-RED with a remote MQTT broker over a Localtonet tunnel?

Yes. In Node-RED's MQTT input or output node, set the broker host to the Localtonet relay address and port instead of localhost. Add the username and password credentials. Node-RED will connect to your home Mosquitto broker through the tunnel exactly as any other MQTT client would.

How much data can I push through an MQTT tunnel?

MQTT messages are typically very small a few dozen bytes for a sensor reading. Even at one message per second per device, a dozen sensors would generate only a few kilobytes per second. That is negligible for any home internet connection or Localtonet plan. If you are streaming high-frequency data like audio or video, MQTT is not the right protocol for that use case.

Your Home Sensors, Reachable from Anywhere

Install Mosquitto on your Raspberry Pi, create a Localtonet TCP tunnel for port 1883, and your MQTT broker is accessible from any device on the internet. No cloud broker fees, no data leaving your home infrastructure.

Create Free Localtonet Account →

Localtonet is a secure multi-protocol tunneling and proxy platform designed to expose localhost, devices, private services, and AI agents to the public internet supporting HTTP/HTTPS tunnels, TCP/UDP forwarding, mobile proxy infrastructure, file server publishing, latency-optimized game connectivity, and developer-ready AI agent endpoint exposure from a single unified control plane.

support