{"id":13582047,"url":"https://github.com/grepplabs/mqtt-proxy","last_synced_at":"2026-02-02T01:11:47.478Z","repository":{"id":55403162,"uuid":"265227845","full_name":"grepplabs/mqtt-proxy","owner":"grepplabs","description":"MQTT Proxy allows MQTT clients to send messages to other messaging systems","archived":false,"fork":false,"pushed_at":"2023-05-13T16:55:00.000Z","size":66563,"stargazers_count":35,"open_issues_count":0,"forks_count":6,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-30T18:01:44.352Z","etag":null,"topics":["iot","kafka","mqtt","mqtt-bridge","mqtt-proxy","mqtt3","mqtt5","proxy","rabbitmq","sns","sqs"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/grepplabs.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"custom":"https://paypal.me/grepplabs?locale.x=en_GB"}},"created_at":"2020-05-19T11:25:59.000Z","updated_at":"2025-01-20T19:55:51.000Z","dependencies_parsed_at":"2024-06-19T02:58:12.615Z","dependency_job_id":"d610a39d-ec43-4e62-9420-7a47e2aaa0ff","html_url":"https://github.com/grepplabs/mqtt-proxy","commit_stats":{"total_commits":31,"total_committers":1,"mean_commits":31.0,"dds":0.0,"last_synced_commit":"78fe285cf2d1965bb086715adff1b6b5bb92c129"},"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/grepplabs/mqtt-proxy","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grepplabs%2Fmqtt-proxy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grepplabs%2Fmqtt-proxy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grepplabs%2Fmqtt-proxy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grepplabs%2Fmqtt-proxy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/grepplabs","download_url":"https://codeload.github.com/grepplabs/mqtt-proxy/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grepplabs%2Fmqtt-proxy/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28998238,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-01T23:10:54.274Z","status":"ssl_error","status_checked_at":"2026-02-01T23:10:47.298Z","response_time":56,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["iot","kafka","mqtt","mqtt-bridge","mqtt-proxy","mqtt3","mqtt5","proxy","rabbitmq","sns","sqs"],"created_at":"2024-08-01T15:02:24.161Z","updated_at":"2026-02-02T01:11:47.474Z","avatar_url":"https://github.com/grepplabs.png","language":"Go","funding_links":["https://paypal.me/grepplabs?locale.x=en_GB"],"categories":["Go"],"sub_categories":[],"readme":"# mqtt-proxy\n\n**Work in progress**\n\n[![License: CC BY-NC-ND 4.0](https://img.shields.io/badge/License-CC%20BY--NC--ND%204.0-lightgrey.svg)](https://creativecommons.org/licenses/by-nc-nd/4.0/)\n![Build](https://github.com/grepplabs/mqtt-proxy/workflows/build/badge.svg)\n[![Docker Hub](https://img.shields.io/badge/docker-latest-blue.svg)](https://hub.docker.com/r/grepplabs/mqtt-proxy)\n[![Docker Pulls](https://img.shields.io/docker/pulls/grepplabs/mqtt-proxy)](https://hub.docker.com/r/grepplabs/mqtt-proxy)\n\nMQTT Proxy allows MQTT clients to send messages to other messaging systems\n\n\n## Implementation status\n\n* MQTT protocol\n    * [x] [MQTT 3.1.1](http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/mqtt-v3.1.1.html)\n    * [x] [MQTT 5.0](https://docs.oasis-open.org/mqtt/mqtt/v5.0/mqtt-v5.0.html)\n* Publisher\n    * [x] Noop\n    * [x] [Apache Kafka](https://kafka.apache.org/)\n    * [x] [Amazon SQS](https://aws.amazon.com/sqs/)\n    * [x] [Amazon SNS](https://aws.amazon.com/sns/)\n    * [ ] [Amazon Kinesis](https://aws.amazon.com/kinesis/)\n    * [x] [RabbitMQ](https://www.rabbitmq.com/)\n    * [ ] Others\n* Authentication\n    * [x] Noop\n    * [x] Plain\n    * [ ] Others\n* [x] Helm chart\n* [x] Client certificate revocation list\n* [ ] Server certificates rotation\n    * [x] Files certificate source\n    * [ ] HashiCorp Vault certificate source\n\n\n### Install binary release\n\n1. Download the latest Linux release\n\n    ```\n    TAG=$(curl --silent \"https://api.github.com/repos/grepplabs/mqtt-proxy/releases/latest\" | jq -r '.tag_name')\n    curl -Ls https://github.com/grepplabs/mqtt-proxy/releases/download/${TAG}/mqtt-proxy-${TAG}-linux-amd64.tar.gz | tar xz\n    ```\n\n2. Move the binary in to your PATH.\n\n    ```\n    sudo mv ./mqtt-proxy /usr/local/bin/mqtt-proxy\n    ```\n\n## Build\n### build binary\n\n    make clean build\n\n### build docker image\n\n    make clean docker-build\n\n## Helm 3 chart\n\nDeploy the Helm chart\n\n```bash\ngit clone git@github.com:grepplabs/mqtt-proxy.git\nhelm install mqtt-proxy ./mqtt-proxy/charts/mqtt-proxy \\\n  --set image.tag=latest \\\n  --set image.repository=grepplabs/mqtt-proxy \\\n  --values  \u003c(echo '{\n        \"extraArgs\" : [\"server\",\"--mqtt.publisher.name=noop\"]\n    }')\n```\n\n## Test\n\nprerequisites\n- [docker compose](https://docs.docker.com/compose/install/)\n\n### kafka publisher\n\n1. build and start-up test environment\n\n    ```\n    cd scripts/cp-kafka\n    make build-up\n    ```\n\n2. subscribe to Kafka topic\n\n    ```\n    docker exec -it broker kafka-console-consumer --bootstrap-server localhost:9092 --topic mqtt-test --property print.key=true --from-beginning\n    ```\n\n3. publish messages using mosquitto client\n\n    * proxy using Kafka PLAINTEXT listener\n    ```\n    docker exec -it mqtt-client mosquitto_pub -L mqtt://mqtt-proxy:1883/dummy -m \"test qos 0\" --repeat 1 -q 0\n    docker exec -it mqtt-client mosquitto_pub -L mqtt://mqtt-proxy:1883/dummy -m \"test qos 1\" --repeat 1 -q 1\n    docker exec -it mqtt-client mosquitto_pub -L mqtt://mqtt-proxy:1883/dummy -m \"test qos 2\" --repeat 1 -q 2\n    docker exec -it mqtt-client mosquitto_pub -L mqtt://mqtt-proxy:1883/dummy -m \"test qos 0 / v5\" --repeat 1 -q 0 -V mqttv5\n    docker exec -it mqtt-client mosquitto_pub -L mqtt://mqtt-proxy:1883/dummy -m \"test qos 1 / v5\" --repeat 1 -q 1 -V mqttv5\n    docker exec -it mqtt-client mosquitto_pub -L mqtt://mqtt-proxy:1883/dummy -m \"test qos 2 / v5\" --repeat 1 -q 2 -V mqttv5\n    ```\n\n    * proxy using Kafka SSL listener\n    ```\n    docker exec -it mqtt-client mosquitto_pub -L mqtt://mqtt-proxy-ssl:1884/dummy -m \"test qos 0\" --repeat 1 -q 0\n    docker exec -it mqtt-client mosquitto_pub -L mqtt://mqtt-proxy-ssl:1884/dummy -m \"test qos 1\" --repeat 1 -q 1\n    docker exec -it mqtt-client mosquitto_pub -L mqtt://mqtt-proxy-ssl:1884/dummy -m \"test qos 2\" --repeat 1 -q 2\n    ```\n\n4. check the prometheus metrics\n\n    ```\n    watch -c 'curl -s localhost:9090/metrics | grep mqtt | egrep -v '^#''\n    ```\n\n### publish to Amazon MSK\n\n1. provision test MSK and EC2 running in [podman](https://podman.io/) 2 proxy containers\n\n    ```\n    cd scripts/msk\n    make tf-apply\n    ```\n\n2. create Kafka mqtt-test topic\n\n3. publish\n\n    * container connects to MSK PLAINTEXT listener\n    ```\n    mosquitto_pub -m \"on\" -t \"dummy\" -k 20 -i mqtt-proxy.clientv --repeat 1 -q 1 -h \u003cec2-ip\u003e -p 1883\n    ```\n\n    * container connects to MSK TLS listener\n    ```\n    mosquitto_pub -m \"on\" -t \"dummy\" -k 20 -i mqtt-proxy.clientv --repeat 1 -q 1 -h \u003cec2-ip\u003e -p 1884\n    ```\n\n### SQS publisher\n\n1. Create AWS SQS `test1` and `test2.fifo` queues\n2. Build and start MQTT Proxy\n\n    ```\n    make build\n   ./mqtt-proxy server \\\n      --mqtt.publisher.name=sqs \\\n      --mqtt.publisher.message-format=json \\\n      --mqtt.publisher.sqs.queue-mappings=test1='^dummy$' \\\n      --mqtt.publisher.sqs.default-queue=test2.fifo \\\n      --mqtt.publisher.sqs.aws-profile=admin-dev\n    ```\n\n3. publish\n\n    ```\n    mosquitto_pub -L mqtt://localhost:1883/dummy -m \"test qos 2\" --repeat 1 -q 2\n    ```\n\n### SNS publisher\n\n1. Create AWS SNS `test1` and `test2.fifo` topics with some subscription\n2. Build and start MQTT Proxy\n\n    ```\n    make build\n   ./mqtt-proxy server \\\n      --mqtt.publisher.name=sns \\\n      --mqtt.publisher.message-format=json \\\n      --mqtt.publisher.sns.topic-arn-mappings=arn:aws:sns:eu-central-1:123456789012:test1='^dummy$' \\\n      --mqtt.publisher.sns.default-topic-arn=arn:aws:sns:eu-central-1:123456789012:test2.fifo \\\n      --mqtt.publisher.sns.aws-profile=admin-dev\n    ```\n\n3. publish\n\n    ```\n    mosquitto_pub -L mqtt://localhost:1883/dummy -m \"test qos 2\" --repeat 1 -q 2\n    ```\n\n\n### RabbitMQ publisher\n1. Start rabbitmq and create test queue\n\n    ```\n    cd scripts/rabbitmq\n    docker-compose up\n    curl -i -u user:bitnami -H \"content-type:application/json\" -XPUT -d'{\"durable\":true}' http://localhost:15672/api/queues/%2f/test\n    ```\n\n\n2. Build and start MQTT Proxy\n\n    ```\n    make build\n   ./mqtt-proxy server \\\n      --mqtt.publisher.name=rabbitmq \\\n      --mqtt.publisher.rabbitmq.username=user \\\n      --mqtt.publisher.rabbitmq.password=bitnami \\\n      --mqtt.publisher.rabbitmq.default-queue=test \\\n      --mqtt.publisher.rabbitmq.confirms.exactly-once=true\n    ```\n\n3. publish\n\n    ```\n    mosquitto_pub -L mqtt://localhost:1883/dummy -m \"test qos 0\" --repeat 1 -q 0\n    ```\n\n### plain authenticator\n\n1. start server with `plain` authenticator\n    * with credentials file\n\n    ```\n    cat \u003c\u003cEOF \u003e mqtt-credentials.csv\n    alice,alice-secret\n    \"bob\",\"bob-secret\"\n    EOF\n    ```\n\n    ```\n    mqtt-proxy server --mqtt.publisher.name=noop \\\n        --mqtt.handler.auth.name=plain \\\n        --mqtt.handler.auth.plain.credentials-file=mqtt-credentials.csv\n    ```\n    * providing credentials as parameters\n    ```\n    mqtt-proxy server --mqtt.publisher.name=noop \\\n        --mqtt.handler.auth.name=plain \\\n        --mqtt.handler.auth.plain.credentials=alice=alice-secret \\\n        --mqtt.handler.auth.plain.credentials=bob=bob-secret\n    ```\n2. publish\n\n    ```\n    mosquitto_pub -m \"on\" -t \"dummy\" -u alice -P alice-secret\n    mosquitto_pub -L mqtt://bob:bob-secret@localhost:1883/dummy -m \"on\"\n    ```\n\n\n## Configuration\n\n### Kafka publisher\n\nKafka producer configuration properties used by [librdkafka](https://github.com/edenhill/librdkafka/blob/master/CONFIGURATION.md) should be prefixed with `producer.`\n\n```\n--mqtt.publisher.kafka.config=producer.sasl.mechanisms=PLAIN,producer.security.protocol=SASL_SSL,producer.sasl.username=myuser,producer.sasl.password=mypasswd\n```\n\n### Examples\n\n- Ignore subscribe / unsubscribe requests\n\n```\nmqtt-proxy server  --mqtt.publisher.name=noop --mqtt.handler.ignore-unsupported SUBSCRIBE --mqtt.handler.ignore-unsupported UNSUBSCRIBE\n```\n\n\n## Metrics\n\n\nmetric | labels | description\n-------| -------| ------------\n|mqtt_proxy_build_info| branch, goversion, revision, revision|A metric with a constant '1' value labeled by version, revision, branch, and goversion from which mqtt_proxy was built.|\n|mqtt_proxy_server_connections_active| |Number of active TCP connections from clients to server.|\n|mqtt_proxy_server_connections_total| |Total number of TCP connections from clients to server.|\n|mqtt_proxy_handler_requests_total| type, version |Total number of MQTT requests labeled by package control type and protocol version. |\n|mqtt_proxy_handler_responses_total| type, version |Total number of MQTT responses labeled by package control type and protocol version. |\n|mqtt_proxy_publisher_publish_duration_seconds | name, type, qos | Histogram tracking latencies for publish requests. |\n|mqtt_proxy_authenticator_login_duration_seconds | name, code, err | Histogram tracking latencies for login requests. |\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgrepplabs%2Fmqtt-proxy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgrepplabs%2Fmqtt-proxy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgrepplabs%2Fmqtt-proxy/lists"}