Repository files navigation

mProxy

mProxy is an MQTT proxy.

It is deployed in front of MQTT broker and can be used for authorization, packet inspection and modification, logging and debugging and various other purposes.

Usage

go get github.com/objenious/mproxy
cd$(GOPATH)/github.com/objenious/mproxy
make
./mproxy

Architecture

mProxy starts TCP and WS servers, offering connections to devices. Upon the connection, it establishes a session with a remote MQTT broker. It then pipes packets from devices to MQTT broker, inspecting or modifying them as they flow through proxy.

Here is the flow in more details:

  • Device connects to mProxy's TCP server
  • mProxy accepts the inbound (IN) connection and estabishes a new session with remote MQTT broker (i.e. it dials out to MQTT broker only once it accepted new connection from a device. This way one device-mProxy connection corresponds to one mProxy-MQTT broker connection.)
  • mProxy then spawn 2 goroutines: one that will read incoming packets from device-mProxy socket (INBOUND or UPLINK), inspect them (calling event handlers) and write them to mProxy-broker socket (forwarding them towards the broker) and other that will be reading MQTT broker responses from mProxy-broker socket and writing them towards device, in device-mProxy socket (OUTBOUND or DOWNLINK).

mProxy can parse and understand MQTT packages, and upon their detection it actually calls external event handlers. Event handlers should implement the following interface defined in pkg/mqtt/events.go:

// Event is an interface for mProxy hookstypeEventinterface {
// Authorization on client `CONNECT`// Each of the params are passed by reference, so that it can be changedAuthConnect(client*Client) error// Authorization on client `PUBLISH`// Topic is passed by reference, so that it can be modifiedAuthPublish(client*Client, topic*string, payload*[]byte) error// Authorization on client `SUBSCRIBE`// Topics are passed by reference, so that they can be modifiedAuthSubscribe(client*Client, topics*[]string) error// After client successfully connectedConnect(client*Client)
// After client successfully publishedPublish(client*Client, topic*string, payload*[]byte)
// After client successfully subscribedSubscribe(client*Client, topics*[]string)
// After client unsubscribedUnsubscribe(client*Client, topics*[]string)
// Disconnect on connection with client lostDisconnect(client*Client)
}

An example of implementation is given here, alongside with it's main() function.

Deployment

mProxy does not do load balancing - just pure and simple proxying. This is why it should be deployed right in front of it's corresponding MQTT broker instance: one mProxy for each MQTT broker instance in the MQTT cluster.

Usually this is done by deploying mProxy as a side-car in the same Kubernetes pod alongside with MQTT broker instance (MQTT cluster node).

TLS termination and LB tasks can be offloaded to a standard ingress proxy - for example NginX.

Configuration

The service is configured using the environment variables presented in the following table. Note that any unset variables will be replaced with their default values.

VariableDescriptionDefault
MPROXY_WS_HOSTWebSocket inbound (IN) connection host0.0.0.0
MPROXY_WS_PORTWebSocket inbound (IN) connection port8080
MPROXY_WS_PATHWebSocket inbound (IN) connection path/mqtt
MPROXY_WSS_PORTWebSocket Secure inbound (IN) connection port8080
MPROXY_WSS_PATHWebSocket Secure inbound (IN) connection path/mqtt
MPROXY_WS_TARGET_SCHEMEWebSocket Target schemaws
MPROXY_WS_TARGET_HOSTWebSocket Target hostlocalhost
MPROXY_WS_TARGET_PORTWebSocket Target port8888
MPROXY_WS_TARGET_PATHWebSocket Target path/mqtt
MPROXY_MQTT_HOSTMQTT inbound connection host0.0.0.0
MPROXY_MQTT_PORTMQTT inbound connection port1883
MPROXY_MQTTS_PORTMQTTS inbound connection port8883
MPROXY_MQTT_TARGET_HOSTMQTT broker host0.0.0.0
MPROXY_MQTT_TARGET_PORTMQTT broker port1884
MPROXY_CLIENT_TLSFlag that indicates if TLS should be turned onfalse
MPROXY_CA_CERTSPath to trusted CAs in PEM format
MPROXY_SERVER_CERTPath to server certificate in pem format
MPROXY_SERVER_KEYPath to server key in pem format
MPROXY_LOG_LEVELLog leveldebug

License

Apache-2.0

About

mProxy is an MQTT proxy

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all \u003cpre\u003e\u003ccode\u003e blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks"); } } catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); } })(); (function(){ try { var __m = "github.com"; var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

mProxy

mProxy is an MQTT proxy.

It is deployed in front of MQTT broker and can be used for authorization, packet inspection and modification, logging and debugging and various other purposes.

Usage

go get github.com/objenious/mproxy
cd$(GOPATH)/github.com/objenious/mproxy
make
./mproxy

Architecture

mProxy starts TCP and WS servers, offering connections to devices. Upon the connection, it establishes a session with a remote MQTT broker. It then pipes packets from devices to MQTT broker, inspecting or modifying them as they flow through proxy.

Here is the flow in more details:

  • Device connects to mProxy's TCP server
  • mProxy accepts the inbound (IN) connection and estabishes a new session with remote MQTT broker (i.e. it dials out to MQTT broker only once it accepted new connection from a device. This way one device-mProxy connection corresponds to one mProxy-MQTT broker connection.)
  • mProxy then spawn 2 goroutines: one that will read incoming packets from device-mProxy socket (INBOUND or UPLINK), inspect them (calling event handlers) and write them to mProxy-broker socket (forwarding them towards the broker) and other that will be reading MQTT broker responses from mProxy-broker socket and writing them towards device, in device-mProxy socket (OUTBOUND or DOWNLINK).

mProxy can parse and understand MQTT packages, and upon their detection it actually calls external event handlers. Event handlers should implement the following interface defined in pkg/mqtt/events.go:

// Event is an interface for mProxy hookstypeEventinterface {
// Authorization on client `CONNECT`// Each of the params are passed by reference, so that it can be changedAuthConnect(client*Client) error// Authorization on client `PUBLISH`// Topic is passed by reference, so that it can be modifiedAuthPublish(client*Client, topic*string, payload*[]byte) error// Authorization on client `SUBSCRIBE`// Topics are passed by reference, so that they can be modifiedAuthSubscribe(client*Client, topics*[]string) error// After client successfully connectedConnect(client*Client)
// After client successfully publishedPublish(client*Client, topic*string, payload*[]byte)
// After client successfully subscribedSubscribe(client*Client, topics*[]string)
// After client unsubscribedUnsubscribe(client*Client, topics*[]string)
// Disconnect on connection with client lostDisconnect(client*Client)
}

An example of implementation is given here, alongside with it's main() function.

Deployment

mProxy does not do load balancing - just pure and simple proxying. This is why it should be deployed right in front of it's corresponding MQTT broker instance: one mProxy for each MQTT broker instance in the MQTT cluster.

Usually this is done by deploying mProxy as a side-car in the same Kubernetes pod alongside with MQTT broker instance (MQTT cluster node).

TLS termination and LB tasks can be offloaded to a standard ingress proxy - for example NginX.

Configuration

The service is configured using the environment variables presented in the following table. Note that any unset variables will be replaced with their default values.

VariableDescriptionDefault
MPROXY_WS_HOSTWebSocket inbound (IN) connection host0.0.0.0
MPROXY_WS_PORTWebSocket inbound (IN) connection port8080
MPROXY_WS_PATHWebSocket inbound (IN) connection path/mqtt
MPROXY_WSS_PORTWebSocket Secure inbound (IN) connection port8080
MPROXY_WSS_PATHWebSocket Secure inbound (IN) connection path/mqtt
MPROXY_WS_TARGET_SCHEMEWebSocket Target schemaws
MPROXY_WS_TARGET_HOSTWebSocket Target hostlocalhost
MPROXY_WS_TARGET_PORTWebSocket Target port8888
MPROXY_WS_TARGET_PATHWebSocket Target path/mqtt
MPROXY_MQTT_HOSTMQTT inbound connection host0.0.0.0
MPROXY_MQTT_PORTMQTT inbound connection port1883
MPROXY_MQTTS_PORTMQTTS inbound connection port8883
MPROXY_MQTT_TARGET_HOSTMQTT broker host0.0.0.0
MPROXY_MQTT_TARGET_PORTMQTT broker port1884
MPROXY_CLIENT_TLSFlag that indicates if TLS should be turned onfalse
MPROXY_CA_CERTSPath to trusted CAs in PEM format
MPROXY_SERVER_CERTPath to server certificate in pem format
MPROXY_SERVER_KEYPath to server key in pem format
MPROXY_LOG_LEVELLog leveldebug

License

Apache-2.0

About

mProxy is an MQTT proxy

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

mProxy

mProxy is an MQTT proxy.

It is deployed in front of MQTT broker and can be used for authorization, packet inspection and modification, logging and debugging and various other purposes.

Usage

go get github.com/objenious/mproxy
cd$(GOPATH)/github.com/objenious/mproxy
make
./mproxy

Architecture

mProxy starts TCP and WS servers, offering connections to devices. Upon the connection, it establishes a session with a remote MQTT broker. It then pipes packets from devices to MQTT broker, inspecting or modifying them as they flow through proxy.

Here is the flow in more details:

  • Device connects to mProxy's TCP server
  • mProxy accepts the inbound (IN) connection and estabishes a new session with remote MQTT broker (i.e. it dials out to MQTT broker only once it accepted new connection from a device. This way one device-mProxy connection corresponds to one mProxy-MQTT broker connection.)
  • mProxy then spawn 2 goroutines: one that will read incoming packets from device-mProxy socket (INBOUND or UPLINK), inspect them (calling event handlers) and write them to mProxy-broker socket (forwarding them towards the broker) and other that will be reading MQTT broker responses from mProxy-broker socket and writing them towards device, in device-mProxy socket (OUTBOUND or DOWNLINK).

mProxy can parse and understand MQTT packages, and upon their detection it actually calls external event handlers. Event handlers should implement the following interface defined in pkg/mqtt/events.go:

// Event is an interface for mProxy hookstypeEventinterface {
// Authorization on client `CONNECT`// Each of the params are passed by reference, so that it can be changedAuthConnect(client*Client) error// Authorization on client `PUBLISH`// Topic is passed by reference, so that it can be modifiedAuthPublish(client*Client, topic*string, payload*[]byte) error// Authorization on client `SUBSCRIBE`// Topics are passed by reference, so that they can be modifiedAuthSubscribe(client*Client, topics*[]string) error// After client successfully connectedConnect(client*Client)
// After client successfully publishedPublish(client*Client, topic*string, payload*[]byte)
// After client successfully subscribedSubscribe(client*Client, topics*[]string)
// After client unsubscribedUnsubscribe(client*Client, topics*[]string)
// Disconnect on connection with client lostDisconnect(client*Client)
}

An example of implementation is given here, alongside with it's main() function.

Deployment

mProxy does not do load balancing - just pure and simple proxying. This is why it should be deployed right in front of it's corresponding MQTT broker instance: one mProxy for each MQTT broker instance in the MQTT cluster.

Usually this is done by deploying mProxy as a side-car in the same Kubernetes pod alongside with MQTT broker instance (MQTT cluster node).

TLS termination and LB tasks can be offloaded to a standard ingress proxy - for example NginX.

Configuration

The service is configured using the environment variables presented in the following table. Note that any unset variables will be replaced with their default values.

VariableDescriptionDefault
MPROXY_WS_HOSTWebSocket inbound (IN) connection host0.0.0.0
MPROXY_WS_PORTWebSocket inbound (IN) connection port8080
MPROXY_WS_PATHWebSocket inbound (IN) connection path/mqtt
MPROXY_WSS_PORTWebSocket Secure inbound (IN) connection port8080
MPROXY_WSS_PATHWebSocket Secure inbound (IN) connection path/mqtt
MPROXY_WS_TARGET_SCHEMEWebSocket Target schemaws
MPROXY_WS_TARGET_HOSTWebSocket Target hostlocalhost
MPROXY_WS_TARGET_PORTWebSocket Target port8888
MPROXY_WS_TARGET_PATHWebSocket Target path/mqtt
MPROXY_MQTT_HOSTMQTT inbound connection host0.0.0.0
MPROXY_MQTT_PORTMQTT inbound connection port1883
MPROXY_MQTTS_PORTMQTTS inbound connection port8883
MPROXY_MQTT_TARGET_HOSTMQTT broker host0.0.0.0
MPROXY_MQTT_TARGET_PORTMQTT broker port1884
MPROXY_CLIENT_TLSFlag that indicates if TLS should be turned onfalse
MPROXY_CA_CERTSPath to trusted CAs in PEM format
MPROXY_SERVER_CERTPath to server certificate in pem format
MPROXY_SERVER_KEYPath to server key in pem format
MPROXY_LOG_LEVELLog leveldebug

License

Apache-2.0

About

mProxy is an MQTT proxy

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length \u003e 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

mProxy

mProxy is an MQTT proxy.

It is deployed in front of MQTT broker and can be used for authorization, packet inspection and modification, logging and debugging and various other purposes.

Usage

go get github.com/objenious/mproxy
cd$(GOPATH)/github.com/objenious/mproxy
make
./mproxy

Architecture

mProxy starts TCP and WS servers, offering connections to devices. Upon the connection, it establishes a session with a remote MQTT broker. It then pipes packets from devices to MQTT broker, inspecting or modifying them as they flow through proxy.

Here is the flow in more details:

  • Device connects to mProxy's TCP server
  • mProxy accepts the inbound (IN) connection and estabishes a new session with remote MQTT broker (i.e. it dials out to MQTT broker only once it accepted new connection from a device. This way one device-mProxy connection corresponds to one mProxy-MQTT broker connection.)
  • mProxy then spawn 2 goroutines: one that will read incoming packets from device-mProxy socket (INBOUND or UPLINK), inspect them (calling event handlers) and write them to mProxy-broker socket (forwarding them towards the broker) and other that will be reading MQTT broker responses from mProxy-broker socket and writing them towards device, in device-mProxy socket (OUTBOUND or DOWNLINK).

mProxy can parse and understand MQTT packages, and upon their detection it actually calls external event handlers. Event handlers should implement the following interface defined in pkg/mqtt/events.go:

// Event is an interface for mProxy hookstypeEventinterface {
// Authorization on client `CONNECT`// Each of the params are passed by reference, so that it can be changedAuthConnect(client*Client) error// Authorization on client `PUBLISH`// Topic is passed by reference, so that it can be modifiedAuthPublish(client*Client, topic*string, payload*[]byte) error// Authorization on client `SUBSCRIBE`// Topics are passed by reference, so that they can be modifiedAuthSubscribe(client*Client, topics*[]string) error// After client successfully connectedConnect(client*Client)
// After client successfully publishedPublish(client*Client, topic*string, payload*[]byte)
// After client successfully subscribedSubscribe(client*Client, topics*[]string)
// After client unsubscribedUnsubscribe(client*Client, topics*[]string)
// Disconnect on connection with client lostDisconnect(client*Client)
}

An example of implementation is given here, alongside with it's main() function.

Deployment

mProxy does not do load balancing - just pure and simple proxying. This is why it should be deployed right in front of it's corresponding MQTT broker instance: one mProxy for each MQTT broker instance in the MQTT cluster.

Usually this is done by deploying mProxy as a side-car in the same Kubernetes pod alongside with MQTT broker instance (MQTT cluster node).

TLS termination and LB tasks can be offloaded to a standard ingress proxy - for example NginX.

Configuration

The service is configured using the environment variables presented in the following table. Note that any unset variables will be replaced with their default values.

VariableDescriptionDefault
MPROXY_WS_HOSTWebSocket inbound (IN) connection host0.0.0.0
MPROXY_WS_PORTWebSocket inbound (IN) connection port8080
MPROXY_WS_PATHWebSocket inbound (IN) connection path/mqtt
MPROXY_WSS_PORTWebSocket Secure inbound (IN) connection port8080
MPROXY_WSS_PATHWebSocket Secure inbound (IN) connection path/mqtt
MPROXY_WS_TARGET_SCHEMEWebSocket Target schemaws
MPROXY_WS_TARGET_HOSTWebSocket Target hostlocalhost
MPROXY_WS_TARGET_PORTWebSocket Target port8888
MPROXY_WS_TARGET_PATHWebSocket Target path/mqtt
MPROXY_MQTT_HOSTMQTT inbound connection host0.0.0.0
MPROXY_MQTT_PORTMQTT inbound connection port1883
MPROXY_MQTTS_PORTMQTTS inbound connection port8883
MPROXY_MQTT_TARGET_HOSTMQTT broker host0.0.0.0
MPROXY_MQTT_TARGET_PORTMQTT broker port1884
MPROXY_CLIENT_TLSFlag that indicates if TLS should be turned onfalse
MPROXY_CA_CERTSPath to trusted CAs in PEM format
MPROXY_SERVER_CERTPath to server certificate in pem format
MPROXY_SERVER_KEYPath to server key in pem format
MPROXY_LOG_LEVELLog leveldebug

License

Apache-2.0

About

mProxy is an MQTT proxy

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

mProxy

mProxy is an MQTT proxy.

It is deployed in front of MQTT broker and can be used for authorization, packet inspection and modification, logging and debugging and various other purposes.

Usage

go get github.com/objenious/mproxy
cd$(GOPATH)/github.com/objenious/mproxy
make
./mproxy

Architecture

mProxy starts TCP and WS servers, offering connections to devices. Upon the connection, it establishes a session with a remote MQTT broker. It then pipes packets from devices to MQTT broker, inspecting or modifying them as they flow through proxy.

Here is the flow in more details:

  • Device connects to mProxy's TCP server
  • mProxy accepts the inbound (IN) connection and estabishes a new session with remote MQTT broker (i.e. it dials out to MQTT broker only once it accepted new connection from a device. This way one device-mProxy connection corresponds to one mProxy-MQTT broker connection.)
  • mProxy then spawn 2 goroutines: one that will read incoming packets from device-mProxy socket (INBOUND or UPLINK), inspect them (calling event handlers) and write them to mProxy-broker socket (forwarding them towards the broker) and other that will be reading MQTT broker responses from mProxy-broker socket and writing them towards device, in device-mProxy socket (OUTBOUND or DOWNLINK).

mProxy can parse and understand MQTT packages, and upon their detection it actually calls external event handlers. Event handlers should implement the following interface defined in pkg/mqtt/events.go:

// Event is an interface for mProxy hookstypeEventinterface {
// Authorization on client `CONNECT`// Each of the params are passed by reference, so that it can be changedAuthConnect(client*Client) error// Authorization on client `PUBLISH`// Topic is passed by reference, so that it can be modifiedAuthPublish(client*Client, topic*string, payload*[]byte) error// Authorization on client `SUBSCRIBE`// Topics are passed by reference, so that they can be modifiedAuthSubscribe(client*Client, topics*[]string) error// After client successfully connectedConnect(client*Client)
// After client successfully publishedPublish(client*Client, topic*string, payload*[]byte)
// After client successfully subscribedSubscribe(client*Client, topics*[]string)
// After client unsubscribedUnsubscribe(client*Client, topics*[]string)
// Disconnect on connection with client lostDisconnect(client*Client)
}

An example of implementation is given here, alongside with it's main() function.

Deployment

mProxy does not do load balancing - just pure and simple proxying. This is why it should be deployed right in front of it's corresponding MQTT broker instance: one mProxy for each MQTT broker instance in the MQTT cluster.

Usually this is done by deploying mProxy as a side-car in the same Kubernetes pod alongside with MQTT broker instance (MQTT cluster node).

TLS termination and LB tasks can be offloaded to a standard ingress proxy - for example NginX.

Configuration

The service is configured using the environment variables presented in the following table. Note that any unset variables will be replaced with their default values.

VariableDescriptionDefault
MPROXY_WS_HOSTWebSocket inbound (IN) connection host0.0.0.0
MPROXY_WS_PORTWebSocket inbound (IN) connection port8080
MPROXY_WS_PATHWebSocket inbound (IN) connection path/mqtt
MPROXY_WSS_PORTWebSocket Secure inbound (IN) connection port8080
MPROXY_WSS_PATHWebSocket Secure inbound (IN) connection path/mqtt
MPROXY_WS_TARGET_SCHEMEWebSocket Target schemaws
MPROXY_WS_TARGET_HOSTWebSocket Target hostlocalhost
MPROXY_WS_TARGET_PORTWebSocket Target port8888
MPROXY_WS_TARGET_PATHWebSocket Target path/mqtt
MPROXY_MQTT_HOSTMQTT inbound connection host0.0.0.0
MPROXY_MQTT_PORTMQTT inbound connection port1883
MPROXY_MQTTS_PORTMQTTS inbound connection port8883
MPROXY_MQTT_TARGET_HOSTMQTT broker host0.0.0.0
MPROXY_MQTT_TARGET_PORTMQTT broker port1884
MPROXY_CLIENT_TLSFlag that indicates if TLS should be turned onfalse
MPROXY_CA_CERTSPath to trusted CAs in PEM format
MPROXY_SERVER_CERTPath to server certificate in pem format
MPROXY_SERVER_KEYPath to server key in pem format
MPROXY_LOG_LEVELLog leveldebug

License

Apache-2.0

About

mProxy is an MQTT proxy

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

mProxy

mProxy is an MQTT proxy.

It is deployed in front of MQTT broker and can be used for authorization, packet inspection and modification, logging and debugging and various other purposes.

Usage

go get github.com/objenious/mproxy
cd$(GOPATH)/github.com/objenious/mproxy
make
./mproxy

Architecture

mProxy starts TCP and WS servers, offering connections to devices. Upon the connection, it establishes a session with a remote MQTT broker. It then pipes packets from devices to MQTT broker, inspecting or modifying them as they flow through proxy.

Here is the flow in more details:

  • Device connects to mProxy's TCP server
  • mProxy accepts the inbound (IN) connection and estabishes a new session with remote MQTT broker (i.e. it dials out to MQTT broker only once it accepted new connection from a device. This way one device-mProxy connection corresponds to one mProxy-MQTT broker connection.)
  • mProxy then spawn 2 goroutines: one that will read incoming packets from device-mProxy socket (INBOUND or UPLINK), inspect them (calling event handlers) and write them to mProxy-broker socket (forwarding them towards the broker) and other that will be reading MQTT broker responses from mProxy-broker socket and writing them towards device, in device-mProxy socket (OUTBOUND or DOWNLINK).

mProxy can parse and understand MQTT packages, and upon their detection it actually calls external event handlers. Event handlers should implement the following interface defined in pkg/mqtt/events.go:

// Event is an interface for mProxy hookstypeEventinterface {
// Authorization on client `CONNECT`// Each of the params are passed by reference, so that it can be changedAuthConnect(client*Client) error// Authorization on client `PUBLISH`// Topic is passed by reference, so that it can be modifiedAuthPublish(client*Client, topic*string, payload*[]byte) error// Authorization on client `SUBSCRIBE`// Topics are passed by reference, so that they can be modifiedAuthSubscribe(client*Client, topics*[]string) error// After client successfully connectedConnect(client*Client)
// After client successfully publishedPublish(client*Client, topic*string, payload*[]byte)
// After client successfully subscribedSubscribe(client*Client, topics*[]string)
// After client unsubscribedUnsubscribe(client*Client, topics*[]string)
// Disconnect on connection with client lostDisconnect(client*Client)
}

An example of implementation is given here, alongside with it's main() function.

Deployment

mProxy does not do load balancing - just pure and simple proxying. This is why it should be deployed right in front of it's corresponding MQTT broker instance: one mProxy for each MQTT broker instance in the MQTT cluster.

Usually this is done by deploying mProxy as a side-car in the same Kubernetes pod alongside with MQTT broker instance (MQTT cluster node).

TLS termination and LB tasks can be offloaded to a standard ingress proxy - for example NginX.

Configuration

The service is configured using the environment variables presented in the following table. Note that any unset variables will be replaced with their default values.

VariableDescriptionDefault
MPROXY_WS_HOSTWebSocket inbound (IN) connection host0.0.0.0
MPROXY_WS_PORTWebSocket inbound (IN) connection port8080
MPROXY_WS_PATHWebSocket inbound (IN) connection path/mqtt
MPROXY_WSS_PORTWebSocket Secure inbound (IN) connection port8080
MPROXY_WSS_PATHWebSocket Secure inbound (IN) connection path/mqtt
MPROXY_WS_TARGET_SCHEMEWebSocket Target schemaws
MPROXY_WS_TARGET_HOSTWebSocket Target hostlocalhost
MPROXY_WS_TARGET_PORTWebSocket Target port8888
MPROXY_WS_TARGET_PATHWebSocket Target path/mqtt
MPROXY_MQTT_HOSTMQTT inbound connection host0.0.0.0
MPROXY_MQTT_PORTMQTT inbound connection port1883
MPROXY_MQTTS_PORTMQTTS inbound connection port8883
MPROXY_MQTT_TARGET_HOSTMQTT broker host0.0.0.0
MPROXY_MQTT_TARGET_PORTMQTT broker port1884
MPROXY_CLIENT_TLSFlag that indicates if TLS should be turned onfalse
MPROXY_CA_CERTSPath to trusted CAs in PEM format
MPROXY_SERVER_CERTPath to server certificate in pem format
MPROXY_SERVER_KEYPath to server key in pem format
MPROXY_LOG_LEVELLog leveldebug

License

Apache-2.0

About

mProxy is an MQTT proxy

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

mProxy

mProxy is an MQTT proxy.

It is deployed in front of MQTT broker and can be used for authorization, packet inspection and modification, logging and debugging and various other purposes.

Usage

go get github.com/objenious/mproxy
cd$(GOPATH)/github.com/objenious/mproxy
make
./mproxy

Architecture

mProxy starts TCP and WS servers, offering connections to devices. Upon the connection, it establishes a session with a remote MQTT broker. It then pipes packets from devices to MQTT broker, inspecting or modifying them as they flow through proxy.

Here is the flow in more details:

  • Device connects to mProxy's TCP server
  • mProxy accepts the inbound (IN) connection and estabishes a new session with remote MQTT broker (i.e. it dials out to MQTT broker only once it accepted new connection from a device. This way one device-mProxy connection corresponds to one mProxy-MQTT broker connection.)
  • mProxy then spawn 2 goroutines: one that will read incoming packets from device-mProxy socket (INBOUND or UPLINK), inspect them (calling event handlers) and write them to mProxy-broker socket (forwarding them towards the broker) and other that will be reading MQTT broker responses from mProxy-broker socket and writing them towards device, in device-mProxy socket (OUTBOUND or DOWNLINK).

mProxy can parse and understand MQTT packages, and upon their detection it actually calls external event handlers. Event handlers should implement the following interface defined in pkg/mqtt/events.go:

// Event is an interface for mProxy hookstypeEventinterface {
// Authorization on client `CONNECT`// Each of the params are passed by reference, so that it can be changedAuthConnect(client*Client) error// Authorization on client `PUBLISH`// Topic is passed by reference, so that it can be modifiedAuthPublish(client*Client, topic*string, payload*[]byte) error// Authorization on client `SUBSCRIBE`// Topics are passed by reference, so that they can be modifiedAuthSubscribe(client*Client, topics*[]string) error// After client successfully connectedConnect(client*Client)
// After client successfully publishedPublish(client*Client, topic*string, payload*[]byte)
// After client successfully subscribedSubscribe(client*Client, topics*[]string)
// After client unsubscribedUnsubscribe(client*Client, topics*[]string)
// Disconnect on connection with client lostDisconnect(client*Client)
}

An example of implementation is given here, alongside with it's main() function.

Deployment

mProxy does not do load balancing - just pure and simple proxying. This is why it should be deployed right in front of it's corresponding MQTT broker instance: one mProxy for each MQTT broker instance in the MQTT cluster.

Usually this is done by deploying mProxy as a side-car in the same Kubernetes pod alongside with MQTT broker instance (MQTT cluster node).

TLS termination and LB tasks can be offloaded to a standard ingress proxy - for example NginX.

Configuration

The service is configured using the environment variables presented in the following table. Note that any unset variables will be replaced with their default values.

VariableDescriptionDefault
MPROXY_WS_HOSTWebSocket inbound (IN) connection host0.0.0.0
MPROXY_WS_PORTWebSocket inbound (IN) connection port8080
MPROXY_WS_PATHWebSocket inbound (IN) connection path/mqtt
MPROXY_WSS_PORTWebSocket Secure inbound (IN) connection port8080
MPROXY_WSS_PATHWebSocket Secure inbound (IN) connection path/mqtt
MPROXY_WS_TARGET_SCHEMEWebSocket Target schemaws
MPROXY_WS_TARGET_HOSTWebSocket Target hostlocalhost
MPROXY_WS_TARGET_PORTWebSocket Target port8888
MPROXY_WS_TARGET_PATHWebSocket Target path/mqtt
MPROXY_MQTT_HOSTMQTT inbound connection host0.0.0.0
MPROXY_MQTT_PORTMQTT inbound connection port1883
MPROXY_MQTTS_PORTMQTTS inbound connection port8883
MPROXY_MQTT_TARGET_HOSTMQTT broker host0.0.0.0
MPROXY_MQTT_TARGET_PORTMQTT broker port1884
MPROXY_CLIENT_TLSFlag that indicates if TLS should be turned onfalse
MPROXY_CA_CERTSPath to trusted CAs in PEM format
MPROXY_SERVER_CERTPath to server certificate in pem format
MPROXY_SERVER_KEYPath to server key in pem format
MPROXY_LOG_LEVELLog leveldebug

License

Apache-2.0

About

mProxy is an MQTT proxy

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

mProxy

mProxy is an MQTT proxy.

It is deployed in front of MQTT broker and can be used for authorization, packet inspection and modification, logging and debugging and various other purposes.

Usage

go get github.com/objenious/mproxy
cd$(GOPATH)/github.com/objenious/mproxy
make
./mproxy

Architecture

mProxy starts TCP and WS servers, offering connections to devices. Upon the connection, it establishes a session with a remote MQTT broker. It then pipes packets from devices to MQTT broker, inspecting or modifying them as they flow through proxy.

Here is the flow in more details:

  • Device connects to mProxy's TCP server
  • mProxy accepts the inbound (IN) connection and estabishes a new session with remote MQTT broker (i.e. it dials out to MQTT broker only once it accepted new connection from a device. This way one device-mProxy connection corresponds to one mProxy-MQTT broker connection.)
  • mProxy then spawn 2 goroutines: one that will read incoming packets from device-mProxy socket (INBOUND or UPLINK), inspect them (calling event handlers) and write them to mProxy-broker socket (forwarding them towards the broker) and other that will be reading MQTT broker responses from mProxy-broker socket and writing them towards device, in device-mProxy socket (OUTBOUND or DOWNLINK).

mProxy can parse and understand MQTT packages, and upon their detection it actually calls external event handlers. Event handlers should implement the following interface defined in pkg/mqtt/events.go:

// Event is an interface for mProxy hookstypeEventinterface {
// Authorization on client `CONNECT`// Each of the params are passed by reference, so that it can be changedAuthConnect(client*Client) error// Authorization on client `PUBLISH`// Topic is passed by reference, so that it can be modifiedAuthPublish(client*Client, topic*string, payload*[]byte) error// Authorization on client `SUBSCRIBE`// Topics are passed by reference, so that they can be modifiedAuthSubscribe(client*Client, topics*[]string) error// After client successfully connectedConnect(client*Client)
// After client successfully publishedPublish(client*Client, topic*string, payload*[]byte)
// After client successfully subscribedSubscribe(client*Client, topics*[]string)
// After client unsubscribedUnsubscribe(client*Client, topics*[]string)
// Disconnect on connection with client lostDisconnect(client*Client)
}

An example of implementation is given here, alongside with it's main() function.

Deployment

mProxy does not do load balancing - just pure and simple proxying. This is why it should be deployed right in front of it's corresponding MQTT broker instance: one mProxy for each MQTT broker instance in the MQTT cluster.

Usually this is done by deploying mProxy as a side-car in the same Kubernetes pod alongside with MQTT broker instance (MQTT cluster node).

TLS termination and LB tasks can be offloaded to a standard ingress proxy - for example NginX.

Configuration

The service is configured using the environment variables presented in the following table. Note that any unset variables will be replaced with their default values.

VariableDescriptionDefault
MPROXY_WS_HOSTWebSocket inbound (IN) connection host0.0.0.0
MPROXY_WS_PORTWebSocket inbound (IN) connection port8080
MPROXY_WS_PATHWebSocket inbound (IN) connection path/mqtt
MPROXY_WSS_PORTWebSocket Secure inbound (IN) connection port8080
MPROXY_WSS_PATHWebSocket Secure inbound (IN) connection path/mqtt
MPROXY_WS_TARGET_SCHEMEWebSocket Target schemaws
MPROXY_WS_TARGET_HOSTWebSocket Target hostlocalhost
MPROXY_WS_TARGET_PORTWebSocket Target port8888
MPROXY_WS_TARGET_PATHWebSocket Target path/mqtt
MPROXY_MQTT_HOSTMQTT inbound connection host0.0.0.0
MPROXY_MQTT_PORTMQTT inbound connection port1883
MPROXY_MQTTS_PORTMQTTS inbound connection port8883
MPROXY_MQTT_TARGET_HOSTMQTT broker host0.0.0.0
MPROXY_MQTT_TARGET_PORTMQTT broker port1884
MPROXY_CLIENT_TLSFlag that indicates if TLS should be turned onfalse
MPROXY_CA_CERTSPath to trusted CAs in PEM format
MPROXY_SERVER_CERTPath to server certificate in pem format
MPROXY_SERVER_KEYPath to server key in pem format
MPROXY_LOG_LEVELLog leveldebug

License

Apache-2.0

About

mProxy is an MQTT proxy

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages