{"id":358,"date":"2016-07-24T22:21:18","date_gmt":"2016-07-25T03:21:18","guid":{"rendered":"http:\/\/lisa.rushworth.us\/?p=358"},"modified":"2016-10-16T09:18:11","modified_gmt":"2016-10-16T14:18:11","slug":"reverse-proxying-websockets-to-an-mqtt-server","status":"publish","type":"post","link":"https:\/\/www.rushworth.us\/lisa\/?p=358","title":{"rendered":"Reverse Proxying WebSockets to An MQTT Server"},"content":{"rendered":"<p>If you are trying to reverse proxy OpenHab &#8211; that&#8217;s over <a href=\"http:\/\/lisa.rushworth.us\/?p=458\">here. <\/a>This post is about maintaining your own private MQTT server and making <em>it<\/em> accessible through a reverse proxy.<\/p>\n<p>We want to be able to update our presence automatically (without publishing our location information to the Internet). Scott found a program called OwnTracks that uses an MQTT server &#8211; and there&#8217;s an MQTT binding from OpenHab that should be able to read in the updates.<\/p>\n<p>We didn&#8217;t want to publish our home automation server to the Internet, but we <em>do<\/em> want to send updates from the cellular data network when we leave home. To accomplish this, I set up a reverse proxy on our Apache server.<\/p>\n<p>The first step is to get an MQTT server up and working &#8212; we Installed a mosquitto package from Fedora&#8217;s dnf repository<\/p>\n<p>Once it is installed, create a directory for the persistence file &amp; chown the folder to mosquitto uid<\/p>\n<p>Generate a bunch of certs using the ot-tools (git clone https:\/\/github.com\/owntracks\/tools.git). I edited the generate-CA.sh file in the ot-tools\/tools\/TLS folder prior to running the script. It will more or less work as-is, but modifying the organisation names makes a cert with your name on it. Not that anyone will notice. Or care \ud83d\ude42 Modifying the IPLIST and HOSTLIST, on the other hand, will get you a cert that actually matches your hostname &#8212; which isn&#8217;t a problem for something that doesn&#8217;t verify host name information, but saves trouble if you get your hostnames to match up.<br \/>\nIPLIST &amp; HOSTLIST<br \/>\nCA_ORG and CA_DN<\/p>\n<p>Then use generate-CA.sh to generate a CA cert &amp; a server cert. Copy these files into \/etc\/mosquitto\/<\/p>\n<p>Edit the config (\/etc\/mosquitto\/mosquitto.conf) &#8211; LMGTFY to find settings you want. Specify a location for the persistence file, password file, and add in the websockets listeners (&amp; ssl certs for the secure one)<br \/>\npersistence_file \/var\/lib\/mosquitto\/mosquitto.db<\/p>\n<p>password_file \/etc\/mosquitto\/passwd<\/p>\n<p>listener 9001<br \/>\nprotocol websockets<\/p>\n<p>listener 9002<br \/>\nprotocol websockets<br \/>\ncafile \/etc\/mosquitto\/ca.crt<br \/>\ncertfile \/etc\/mosquitto\/mosquittohost.rushworth.us.crt<br \/>\nkeyfile \/etc\/mosquitto\/mosquittohost.rushworth.us.key<\/p>\n<p>Add some users<br \/>\n\/usr\/bin\/mosquitto_passwd \/etc\/mosquitto\/passwd WhateverUID<\/p>\n<p>Start mosquitto<br \/>\nmosquitto -c \/etc\/mosquitto\/mosquitto.conf<\/p>\n<p>Monitor mosquitto for the owntracks &#8216;stuff&#8217;<br \/>\nmosquitto_sub -h mosquittohost.rushworth.us -p 1883 -v -t &#8216;owntracks\/#&#8217; -u WhateverUID -P PWDHereToo<\/p>\n<p>Setting up the reverse proxy<br \/>\nThe big sticking point I had was that the Apache WebSockets reverse proxy has a problem (https:\/\/bz.apache.org\/bugzilla\/show_bug.cgi?id=55320) which is marked as closed. Fedora has 2.4.23, so I expected it was sorted. However using tshark to capture the traffic showed that the relayed traffic is still being send as clear.<\/p>\n<p>Downloaded the exact same rev from Apache&#8217;s web site and checked the mod_proxy_wstunnel.c file for the changes in the bug report and found they were indeed committed. In spite of the fact I *had* 2.4.23, I decided to build it and see if the mod_proxy_wstunnel.so was different.<\/p>\n<p>Make sure you have all the devel libraries (openssl-devel for me &#8230; run the config line and it&#8217;ll tell you whatever else you need)<\/p>\n<p>Get apr and apr-util from Apache &amp; store to .\/srclib then gunzip &amp; untar them. Rename the version-specific folders to just apr and apr-util<\/p>\n<p>Once you have everything, configure and make<br \/>\n.\/configure &#8211;prefix=\/usr\/local\/apache &#8211;with-included-apr &#8211;enable-alias=shared &#8211;enable-authz_host=shared &#8211;enable-authz_user=shared &#8211;enable-deflate=shared &#8211;enable-negotiation=shared &#8211;enable-proxy=shared &#8211;enable-ssl=shared &#8211;enable-reqtimeout=shared &#8211;enable-status=shared &#8211;enable-auth_basic=shared &#8211;enable-dir=shared &#8211;enable-authn_file=shared &#8211;enable-autoindex=shared &#8211;enable-env=shared &#8211;enable-php5=shared &#8211;enable-authz_default=shared &#8211;enable-cgi=shared &#8211;enable-setenvif=shared &#8211;enable-authz_groupfile=shared &#8211;enable-mime=shared &#8211;enable-proxy_http=shared &#8211;enable-proxy_wstunnel=shared<\/p>\n<p>Rename your mod_proxy_wstunnel.so to something like mod_proxy_wstunnel.so.bak and the grab mod_proxy_wstunnel.so that just got built.<\/p>\n<p>Grab the CA public key &amp; the server public and private keys that were generated earlier &amp; place them whereever you store your SSL certs on your Apache server<\/p>\n<p>Create a new site config for this reverse proxy &#8211; SSL doesn&#8217;t do host headers so you need a unique port. Clear text you can use a host header. Don&#8217;t forget to add listen&#8217;s to your httpd.conf and ssl.conf files!<\/p>\n<p>ProxyRequests Off<br \/>\n&lt;VirtualHost #.#.#.#:##&gt;<br \/>\nServerName mosquitto.rushworth.us<br \/>\nServerAlias mosquitto<br \/>\nDocumentRoot &#8220;\/var\/www\/vhtml\/mosquitto&#8221;<\/p>\n<p>SetEnv force-proxy-request-1.0 1<br \/>\nSetEnv proxy-nokeepalive 1<br \/>\nSetEnv proxy-initial-not-pooled<br \/>\nSetEnv proxy-initial-not-pooled 1<\/p>\n<p>ProxyPreserveHost On<br \/>\nProxyTimeOut\u00a0\u00a0\u00a0 1800<\/p>\n<p>ProxyPass\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ws:\/\/mosquittohost.rushworth.us:9001\/<br \/>\nProxyPassReverse\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ws:\/\/mosquittohost.rushworth.us:9001\/<br \/>\n&lt;\/VirtualHost&gt;<\/p>\n<p>&lt;VirtualHost #.#.#.#:##&gt;<br \/>\nServerName mosquitto.rushworth.us<br \/>\nServerAlias mosquitto<br \/>\nDocumentRoot &#8220;\/var\/www\/vhtml\/mosquitto&#8221;<\/p>\n<p>SetEnv force-proxy-request-1.0 1<br \/>\nSetEnv proxy-nokeepalive 1<br \/>\nSetEnv proxy-initial-not-pooled<br \/>\nSetEnv proxy-initial-not-pooled 1<\/p>\n<p>ProxyPreserveHost On<br \/>\nProxyTimeOut\u00a0\u00a0\u00a0 1800<\/p>\n<p>SSLEngine On<br \/>\nSSLProxyEngine On<br \/>\nSSLProxyCheckPeerCN off<br \/>\nSSLProxyCheckPeerName off<br \/>\nSSLCertificateFile \/etc\/httpd\/conf\/ssl\/mosquittohost.rushworth.us.crt\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0# These are the public and private key components<br \/>\nSSLCertificateKeyFile \/etc\/httpd\/conf\/ssl\/mosquittohost.rushworth.us.key\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0# \u00a0\u00a0 \u00a0generated from generate-CA.sh earlier.<br \/>\nSSLCertificateChainFile \/etc\/httpd\/conf\/ssl\/ca.crt\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0# This is the public key of the CA generated by generate-CA.sh<\/p>\n<p>ProxyPass\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 wss:\/\/mosquittohost.rushworth.us:9002\/<br \/>\nProxyPassReverse\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 wss:\/\/mosquittohost.rushworth.us:9002\/<br \/>\n&lt;\/VirtualHost&gt;<\/p>\n<p>Reload apache. Create a DNS hostname internally and externally to direct the hostname to your reverse proxy server.<\/p>\n<p>Configure the client &#8212; generate a key for yourself &amp; merge it into a p12 file (make sure your ca cert files are still in the directory &#8211; if you *moved* them into \/etc\/mosquitto &#8230; copy them back:<br \/>\nsh generate-CA.sh client lisa<br \/>\nopenssl pkcs12 -export -in lisa.crt -inkey lisa.key -name &#8220;Lisa&#8217;s key&#8221; -out lisa.p12<br \/>\nYou&#8217;ll need to supply a password for the p12 file.<\/p>\n<p>Put the ca.crt (*public* key) file and your p12 file somewhere on your phone (or Google Drive).<\/p>\n<p>Client config &#8211; Install Owntracks from Play Store<br \/>\nPreferences &#8211; Connection<br \/>\nMode:\u00a0\u00a0 \u00a0Private MQTT<br \/>\nHost:\u00a0\u00a0 \u00a0hostname &amp; port used in your **SSL** config. Select use WebSockets<br \/>\nIdentification:\u00a0\u00a0 \u00a0uid &amp; password created above. Device ID is used as part of the MQTT path (i.e. my lisa device is \/owntracks\/userid\/lisa). Tracker ID is within the data itself<br \/>\nSecurity:\u00a0\u00a0 \u00a0Use TLS, CA certificate is the ca.crt created above. Client cert is the p12 file &#8211; you&#8217;ll need to enter the same password used to create the file<\/p>\n<p>If it isn&#8217;t working, turn off TLS &amp; change the port to your clear text port. This will allow you to isolate an SSL-specific problem or a more general service issue. Once you know everything is working, you can drop the clear text reverse proxy component.<\/p>\n<p>Voila &#8211; reverse proxied WebSockets over to Mosquitto for OwnTracks.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>If you are trying to reverse proxy OpenHab &#8211; that&#8217;s over here. This post is about maintaining your own private MQTT server and making it accessible through a reverse proxy. We want to be able to update our presence automatically (without publishing our location information to the Internet). Scott found a program called OwnTracks that &hellip;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[29],"tags":[31,43,32],"class_list":["post-358","post","type-post","status-publish","format-standard","hentry","category-technology","tag-apache","tag-home-automation","tag-technology"],"_links":{"self":[{"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=\/wp\/v2\/posts\/358","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=358"}],"version-history":[{"count":4,"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=\/wp\/v2\/posts\/358\/revisions"}],"predecessor-version":[{"id":577,"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=\/wp\/v2\/posts\/358\/revisions\/577"}],"wp:attachment":[{"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=358"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=358"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=358"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}