<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Fariz Muradov on Medium]]></title>
        <description><![CDATA[Stories by Fariz Muradov on Medium]]></description>
        <link>https://medium.com/@farizmuradov?source=rss-de2af600b19d------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*pChzRS9fLcJOw0XGX0ekFQ.jpeg</url>
            <title>Stories by Fariz Muradov on Medium</title>
            <link>https://medium.com/@farizmuradov?source=rss-de2af600b19d------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sat, 23 May 2026 06:46:44 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@farizmuradov/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[mDNS data access by rootless container in Linux]]></title>
            <link>https://medium.com/@farizmuradov/mdns-data-access-by-rootless-container-in-linux-79865a11652a?source=rss-de2af600b19d------2</link>
            <guid isPermaLink="false">https://medium.com/p/79865a11652a</guid>
            <category><![CDATA[security]]></category>
            <category><![CDATA[iot]]></category>
            <category><![CDATA[containers]]></category>
            <category><![CDATA[dns]]></category>
            <category><![CDATA[rootless]]></category>
            <dc:creator><![CDATA[Fariz Muradov]]></dc:creator>
            <pubDate>Thu, 21 Dec 2023 14:57:13 GMT</pubDate>
            <atom:updated>2023-12-21T19:55:18.009Z</atom:updated>
            <content:encoded><![CDATA[<p>I get challange to browse/advertise mDNS information from/to rootless container in IoT linux device.</p><blockquote>Rootless containers refers to the ability for an unprivileged user to create, run and otherwise manage containers. This term also includes the variety of tooling around containers that can also be run as an unprivileged user. When we say Rootless Containers, it means running the entire container runtime as well as the containers without the root privileges.</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/789/1*wAbnjcpCzK7PXjIhVNh_-w.png" /></figure><p>in my case IoT host machine using Avahi to browse and advertise mDNS information from switching network. If you installed already rootless container you are aware about rootless container network limitation. It uses <strong>slirp4netns</strong> to manage user-mode networking (“slirp”) for unprivileged network namespaces. So, no use of ipablesto easyly manage traffic between host and container. The communication utilizes the tap0 or tun0 interface, restricting access to host resources. When running a zeroconf application within a rootless container, it faces limitations in obtaining accurate ARP messages from the host, which gather information from the network</p><p>While it’s not overly challenging to create a custom application to address specific issues, this custom development requires ongoing support and maintenance. Typically reliant on a single or small team within the company, it needs updating in sync with core OS software updates to ensure its functionality. We need to seek solutions that rely on a large community to ensure the stability of the solution.</p><p>Most secure solution I found to use system d-bus/system busto rootless container.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/855/1*Xyhw5Xz3tIFx_CD3MVPthQ.png" /></figure><p>But since docker rootless UID/GID, Linux does not allow to access socket file although permission for <em>others </em>is <strong>rw. As well as rootless container cannot access to any host resource which run via root unless it adjusted.</strong></p><p>I decided to use <a href="https://linux.die.net/man/1/socat">socat </a>tool which is production ready to re-map socket file with required minimum permission and mount it to docker container.</p><pre>socat UNIX-LISTEN:/tmp/dbus_socket/dbus.sock,fork,user=1000,group=1000,mode=777 UNIX-CONNECT:/var/run/dbus/system_bus_socket<br>socat UNIX-LISTEN:/tmp/avahi_socket/avahi.sock,fork,user=1000,group=1000,mode=777 UNIX-CONNECT:/var/run/avahi-daemon/socket</pre><blockquote>Note: The best solution is to leverage the HOST Avahi system to advertise device information and utilize a rootless container for reading/BROWSING network information. This allows for changing permissions from mode=777 to mode=444, significantly enhancing security.</blockquote><p>Now<em> </em>/tmp/dbus_socket/dbus.sock<em> </em>and<em> </em>/tmp/avahi_socket/avahi.sock<em> f</em>ile can be mounted to container.</p><pre>docker run -it --rm  \<br>-v /tmp/avahi_socket/avahi.sock:/var/run/avahi-daemon/socket \<br>-v /tmp/dbus_socket/dbus.sock:/var/run/dbus/system_bus_socket \<br>--name alpine_sock \<br>--entrypoint ash \<br>--privileged=true \<br>--security-opt seccomp=unconfined \<br>alpine</pre><p>Now let’s install necessary libraries in pythonand try to obtain and broadcast <strong>mDNS </strong>information</p><pre>/ # apk add python3 py3-dbus py3-avahi  py3-gobject3 avahi-tools <br>fetch https://dl-cdn.alpinelinux.org/alpine/v3.19/main/armv7/APKINDEX.tar.gz<br>fetch https://dl-cdn.alpinelinux.org/alpine/v3.19/community/armv7/APKINDEX.tar.gz<br>(1/29) Installing dbus-libs (1.14.10-r0)<br>(2/29) Installing libintl (0.22.3-r0)<br>(3/29) Installing avahi-libs (0.8-r13)<br>...<br>...</pre><p>Now we can use python programming to interact d-bus with dbus library.</p><h4>Example</h4><p>Browsing mDNS data from rootless container</p><pre># http://avahi.org/wiki/PythonBrowseExample<br>import dbus, avahi<br>from dbus import DBusException<br>from dbus.mainloop.glib import DBusGMainLoop<br>from gi.repository import GObject<br># Looks for iTunes shares<br><br>TYPE = &quot;_http._tcp&quot;<br><br>def service_resolved(*args):<br>    print (&#39;service resolved&#39;)<br>    print (&#39;name:&#39;, args[2])<br>    print (&#39;address:&#39;, args[7])<br>    print (&#39;port:&#39;, args[8])<br><br>def print_error(*args):<br>    print (&#39;error_handler&#39;)<br>    print (args[0])<br><br>def myhandler(interface, protocol, name, stype, domain, flags):<br>    print (&quot;Found service &#39;%s&#39; type &#39;%s&#39; domain &#39;%s&#39; &quot; % (name, stype, domain))<br>    if flags &amp; avahi.LOOKUP_RESULT_LOCAL:<br>            # local service, skip<br>            pass<br>    server.ResolveService(interface, protocol, name, stype, <br>        domain, avahi.PROTO_UNSPEC, dbus.UInt32(0), <br>        reply_handler=service_resolved, error_handler=print_error)<br><br>loop = DBusGMainLoop()<br><br>bus = dbus.SystemBus(mainloop=loop)<br><br>server = dbus.Interface( bus.get_object(avahi.DBUS_NAME, &#39;/&#39;),<br>        &#39;org.freedesktop.Avahi.Server&#39;)<br><br>sbrowser = dbus.Interface(bus.get_object(avahi.DBUS_NAME,<br>        server.ServiceBrowserNew(avahi.IF_UNSPEC,<br>            avahi.PROTO_UNSPEC, TYPE, &#39;local&#39;, dbus.UInt32(0))),<br>        avahi.DBUS_INTERFACE_SERVICE_BROWSER)<br><br>sbrowser.connect_to_signal(&quot;ItemNew&quot;, myhandler)<br><br>GObject.MainLoop().run()</pre><p>Advertising service from rootless container to outside of host.</p><pre>import avahi<br>import dbus<br>from time import sleep<br><br><br>class ServiceAnnouncer:<br>    def __init__(self, name, service, port, txt):<br>        bus = dbus.SystemBus()<br>        server = dbus.Interface(bus.get_object(avahi.DBUS_NAME, avahi.DBUS_PATH_SERVER), avahi.DBUS_INTERFACE_SERVER)<br>        group = dbus.Interface(bus.get_object(avahi.DBUS_NAME, server.EntryGroupNew()),<br>                               avahi.DBUS_INTERFACE_ENTRY_GROUP)<br>        self._service_name = name<br>        index = 1<br>        while True:<br>            try:<br>                group.AddService(avahi.IF_UNSPEC, avahi.PROTO_INET, 0, self._service_name, service, &#39;&#39;, &#39;&#39;, port, avahi.string_array_to_txt_array(txt))<br>            except dbus.DBusException: # name collision -&gt; rename<br>                index += 1<br>                self._service_name = &#39;%s #%s&#39; % (name, str(index))<br>            else:<br>                break<br>        group.Commit()<br>    def get_service_name(self):<br>        return self._service_name<br><br><br>if __name__ == &#39;__main__&#39;:<br>    announcer = ServiceAnnouncer(&#39;Test Service&#39;, &#39;_test._tcp&#39;, 12345, [&#39;foo=bar&#39;, &#39;42=true&#39;])<br>    print (announcer.get_service_name())<br><br>    sleep(60)</pre><p>Here we go.</p><h3><strong>Info</strong></h3><blockquote>An alternative approach involves developing an application within a host that scans and broadcasts mDNS data, pushing it to MQTT over 127.0.0.1:1883 (if available). Rootless containers can then connect and manage data read/write functions. As previously mentioned, it’s essential to maintain consistent message lengths for MQTT and ensure stable performance across defined scenarios.</blockquote><p><strong>Referances</strong>:</p><p>Link to <a href="https://rootlesscontaine.rs/">rootless containers</a></p><p>Link to<a href="https://github.com/rootless-containers/slirp4netns"> slirp4netns</a></p><p>Link to <a href="https://linux.die.net/man/1/socat">socat</a></p><p>Link to <a href="https://en.wikipedia.org/wiki/Multicast_DNS#:~:text=In%20computer%20networking%2C%20the%20multicast,Domain%20Name%20System%20(DNS).">mDNS</a> and <a href="https://www.rfc-editor.org/rfc/rfc6762.html">mDNS-RFC</a></p><p>Link to <a href="https://www.freedesktop.org/wiki/Software/dbus/">Linux D-BUS</a></p><p>Link to <a href="https://avahi.org/">Avahi</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=79865a11652a" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Making TPM2.0 chip usage easy for all applications in #IoT]]></title>
            <link>https://medium.com/@farizmuradov/making-tpm2-0-chip-usage-easy-for-all-applications-in-iot-4c34775ff12?source=rss-de2af600b19d------2</link>
            <guid isPermaLink="false">https://medium.com/p/4c34775ff12</guid>
            <category><![CDATA[iot]]></category>
            <category><![CDATA[cryptography]]></category>
            <category><![CDATA[tls-certificate]]></category>
            <category><![CDATA[iot-security]]></category>
            <category><![CDATA[tpm]]></category>
            <dc:creator><![CDATA[Fariz Muradov]]></dc:creator>
            <pubDate>Wed, 26 Jul 2023 16:40:25 GMT</pubDate>
            <atom:updated>2023-07-26T17:19:47.360Z</atom:updated>
            <content:encoded><![CDATA[<p><strong>Description</strong></p><p>Suppose you intended to utilize TPM2 chips to enhance the security of communication with external services. To achieve this goal, the company plans to generate a unique Private Key for each device using TPM2 and subsequently sign their certificates using a Certificate Authority (CA). By leveraging the TPM2 chip, This ensures that even if the keys are extracted from an Edge device, they cannot be used on a different host. This approach serves as a robust mitigation strategy to prevent credentials theft and ensures a trusted source of endpoint.</p><p><strong>Initial information</strong></p><p>Many applications currently rely on the open-source OpenSSL library to enable TLS communication. To minimize the impact on the development stream, we have decided to utilize the library used by OpenSSL to introduce a new engine commonly referred to as the TPM2-TSS engine. This approach allows us to seamlessly incorporate TPM functionalities into our existing infrastructure without disrupting ongoing development efforts.</p><p><strong>How to fix limitation</strong></p><p>The only way is using pre-built images, which are built on device with TPM. Since docker build, command does not support mounting any host device, the only way is installing packages on container and commit to repository.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/945/1*obXqoh9KFAeTn01Zj1uFGQ.png" /></figure><p><strong>Building, configuration and storing</strong></p><p>· Login to device with root user which has TPM2 device.</p><p>· Type command to pull and run command to pull nginx slim. We need to start docker with mounted TPM device from Host to container.</p><pre># mkdir ./certs<br># docker run -it \<br>--device /dev/tpmrm0:/dev/tpmrm0 \<br>--network  host \<br>--cgroupns host \<br>--privileged \<br>-v ./certs:/etc/nginx/certs \<br>--security-opt seccomp=unconfined \<br>--rm \<br>--detach \<br>nginx:1.25.1-alpine-slim</pre><p>· Enter sh terminal of container to install dependencies.</p><pre># docker exec -it 7a14 sh<br>/ # apk update<br>fetch https://dl-cdn.alpinelinux.org/alpine/v3.17/main/armv7/APKINDEX.tar.gz<br>fetch https://dl-cdn.alpinelinux.org/alpine/v3.17/community/armv7/APKINDEX.tar.gz<br>v3.17.4-76-g5390c883559 [https://dl-cdn.alpinelinux.org/alpine/v3.17/main]<br>v3.17.4-74-gc29c711d0b5 [https://dl-cdn.alpinelinux.org/alpine/v3.17/community]<br>OK: 17265 distinct packages available<br>/ # apk add --upgrade tpm2-tss-tcti-device tpm2-tss-engine tpm2-tss-engine openssl<br>(1/9) Upgrading libcrypto3 (3.0.9-r1 -&gt; 3.0.9-r3)<br>(2/9) Upgrading libssl3 (3.0.9-r1 -&gt; 3.0.9-r3)<br>(3/9) Installing openssl (3.0.9-r3)<br>(4/9) Installing tpm2-tss-mu (3.2.0-r0)<br>(5/9) Installing tpm2-tss-sys (3.2.0-r0)<br>(6/9) Installing tpm2-tss-esys (3.2.0-r0)<br>(7/9) Installing tpm2-tss-tctildr (3.2.0-r0)<br>(8/9) Installing tpm2-tss-engine (1.1.0-r2)<br>(9/9) Installing tpm2-tss-tcti-device (3.2.0-r0)<br>Executing busybox-1.35.0-r29.trigger<br>OK: 13 MiB in 26 packages</pre><ul><li>During the enrollment TPM based certificate should be located on device or use command to generate Key-Pair using TPM2 and Openssl</li></ul><pre>/ # tpm2tss-genkey -a rsa -s 2048 /etc/nginx//certs/tpm.key<br>/ # openssl req -new -engine tpm2tss -key /etc/nginx/certs/tpm.key -keyform engine -subj &quot;/C=US/ST=CA/O=Secure Org/CN=myhostname&quot; -out /etc/nginx/certs/tpm.csr<br>Engine &quot;tpm2tss&quot; set.<br>/ #</pre><p>NOTE: Please sign CSR with CA get signed x509 certificate in PEM format.</p><ul><li>So, we installed TSS libraries for nginx image. Now we need to save image on Machine (commit)</li></ul><pre>Executing busybox-1.35.0-r29.trigger<br>OK: 12 MiB in 25 packages<br>/ # exit<br>root@machine ~# docker commit 4277d4a tpm-proxy:1.25.1-alpine-slimsha256:4dba45bec2135f40cf71d79efdae5f91c66410770a71e166d45f6e145d8eba84<br>root@machine ~#  <br>root@1u0022-i2g-10:~# docker images<br>REPOSITORY          TAG                  IMAGE ID       CREATED          SIZE<br>tpm-proxy           1.25.1-alpine-slim   4dba45bec213   23 seconds ago   15.6MB<br>root@machine ~#</pre><p><em>Now we have image with support to use TSS engine to work with TPM.</em></p><ul><li>Configure nginx.conf and stream.conf file to proxy TCP package.</li></ul><pre>user  root;<br>worker_processes  auto;<br><br>error_log  /var/log/nginx/error.log notice;<br>pid        /var/run/nginx.pid;<br><br>events {<br>    worker_connections  1024;<br>}<br><br>http {<br>    include       /etc/nginx/mime.types;<br>    default_type  application/octet-stream;<br><br>    log_format  main  &#39;$remote_addr - $remote_user [$time_local] &quot;$request&quot; &#39;<br>                      &#39;$status $body_bytes_sent &quot;$http_referer&quot; &#39;<br>                      &#39;&quot;$http_user_agent&quot; &quot;$http_x_forwarded_for&quot;&#39;;<br><br>    access_log  /var/log/nginx/access.log  main;<br>    sendfile        on;<br>    #tcp_nopush     on;<br>    keepalive_timeout  65;<br>    #gzip  on;<br>    include /etc/nginx/conf.d/*.conf;<br>}<br>include /etc/nginx/stream.conf ;</pre><p><em>NOTE: Important change is: user should be root and include our stream.conf file. You can influde multple .conf file as well for different services.</em></p><ul><li><strong>stream.conf</strong> file</li></ul><pre>ssl_engine tpm2tss;<br>stream {<br><br>    upstream backend {<br>        server  XXXX:12345;<br>   }<br><br>    server {<br>        listen     8885;<br>        proxy_pass backend;<br>        proxy_ssl  on;<br>        proxy_ssl_name XXXX ;<br>        proxy_ssl_certificate           /etc/nginx/certs/tpm.crt;<br>        proxy_ssl_certificate_key       engine:tpm2tss:/etc/nginx/certs/tpm.key;<br>        proxy_ssl_trusted_certificate   /etc/nginx/certs/ca.crt;<br><br>        proxy_ssl_verify        on;<br>        proxy_timeout 10m ;<br>    }<br>}</pre><h4><strong>Important</strong>: ssl_engine should be tpm2tss and private key definition should mention engine name: tpm2tss</h4><p><em>NOTE: Make sure all certificates are exist to proxy destination point.</em></p><ul><li>Configure docker-compose.yml file</li></ul><pre>version: &quot;3.9&quot;<br>services:<br>  tpm-proxy:<br>    image: tpm-proxy:1.25.1-alpine-slim<br>    container_name: tpm-proxy<br>    ports:<br>      - 8885:8885<br>    restart: unless-stopped<br>    volumes:<br>      - ./nginx.conf:/etc/nginx/nginx.conf<br>      - ./stream.conf:/etc/nginx/stream.conf<br>      - ./certs:/etc/nginx/certs<br>    devices:<br>      - /dev/tpmrm0:/dev/tpmrm0<br>    privileged: true<br>    security_opt:<br>      - seccomp:unconfined<br></pre><blockquote>This solution allows any application use TPM based security to authenticate target server. i.e. Run local eclipse mosquitto to authenticate to Cloud MQTT in secure and bi-directional way.</blockquote><blockquote>Support: <a href="https://www.buymeacoffee.com/2kfAp0elyz">#buymeacoffe</a></blockquote><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=4c34775ff12" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[IoT EDGE device secure registration on Cloud MQTT via IAM (Keycloak)]]></title>
            <link>https://medium.com/@farizmuradov/iot-edge-device-secure-registration-on-cloud-mqtt-via-iam-keycloak-a78e7d076843?source=rss-de2af600b19d------2</link>
            <guid isPermaLink="false">https://medium.com/p/a78e7d076843</guid>
            <category><![CDATA[iot]]></category>
            <category><![CDATA[oauth]]></category>
            <category><![CDATA[linux]]></category>
            <category><![CDATA[mqtt]]></category>
            <category><![CDATA[openssl]]></category>
            <dc:creator><![CDATA[Fariz Muradov]]></dc:creator>
            <pubDate>Sat, 10 Dec 2022 17:57:10 GMT</pubDate>
            <atom:updated>2022-12-10T17:57:10.057Z</atom:updated>
            <content:encoded><![CDATA[<p>Do you want to manage your devices with Google or Facebook account?</p><p>Do you have 100(0) of devices and is it hard to manage/identify in a real time?</p><p>Do you want to register your edge IoT devices in the cloud and manage them securely via certificates?</p><p><strong>Here is solution as PoC.</strong></p><p>What we need…</p><ol><li>Identity and Access Management. I use opensource <em>Keycloak</em>.</li><li>bi-directional connection between device and cloud. <em>Eclipse-Mosquitto</em></li><li>Connect from Front-end to Device via websocket. I use Paho <em>mqttws31.js</em></li><li>Cert signing configuration for Cloud MQTT. I use <em>openssl</em> lib.</li><li>For web access in Cloud to API. I use <em>NGINX</em></li><li>To keep basic information I use <em>sqlite3</em> db.</li><li>As a packing apps I use <em>docker</em> and <em>docker-compose</em> to manage.</li></ol><p>I assume cloud domain and proxy done properly with HTTPS.</p><p><strong>So, lets Understand topology first.</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/779/1*VTW6dfChiBbflScKRPut9w.png" /></figure><p><em>Scenario is like that…:</em></p><ol><li>User has a mobile app or browser and it is in same network with device. I assume device domain name is <strong>device.mqtt.local</strong>. (Additionally you can use some <em>mDNS</em> to discover domain name automatically)</li><li>If user knows domain name need to update configuration for “<strong>Valid Redirect URIs</strong>” to <a href="http://device.mqtt.local">http://<strong>device.mqtt.local</strong></a><strong> </strong>of client which registered on Keycloak.</li><li>Now the user can access the cloud interface (API), which is protected by Keycloak. If the user is not logged in, the API is redirected to the Keycloak login page to get the token. (Note: Cloud APIs are protected by different clients on Keycloak).</li><li>So, anyway… The user can open the browser and enter <a href="http://device.mqtt.local/">http://device.mqtt.local/</a>... using keycloak.js, he will be redirected to IAM on the cloud. After successful login, IAM will redirect back to the same page with the access token. You can see the token on the demo HTML page.</li><li>This is the main part… Now we need to register our local MQTT device (under container) in the cloud. To do this, we need to generate certificate pairs and sign them via the cloud CA. Don’t worry… all configurations are simple and done. Besides, everything is API. You just need to click buttons. (In production you can merge all buttons to make it fully automated).</li><li>Click buttons on page sequentially… “<strong>generate CSR on device</strong>” (it will generate private key and CSR) -&gt; “<strong>get signed CRT from cloud</strong>” ( it will take value ofCSR and post together with access_token to sign via Cloud) -&gt; “<strong>get cloud CA public key</strong>” ( you will need to key to local mqtt authenticate to cloud) -&gt; “<strong>get topic name</strong>” ( this is fingerprint of device get uniq topic name to be bridgged to cloud.) <strong><em>This value will store on mosquitto.conf file and cloud. So, cloud will map user (</em></strong>from the id_token<strong><em>) to this topic name to identify device ID(mqtt connection bridge).</em></strong></li><li>Then next buttons to save on local disk all cert files. <em>NOTE:local API has a access to mqtt folder and nginx folder to make connection.</em></li><li>At the same time this API will configure the local <strong>NGINX</strong> with <strong>TLS</strong> authentication. Once you do that, local access is only possible with generated certificates. (This can also be removed, otherwise we can do <em>pkc11</em> to add browser CA zone.</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*7bBOPM2uNjNC8XHp9NSODg.png" /><figcaption>Device register flow.</figcaption></figure><p>After configuration example device <em>mosquitto.conf</em> file and <em>nginx conf</em> file.</p><pre>listener 1883<br>persistence false<br>log_dest stdout<br>allow_anonymous true<br>connection_messages true<br>connection m1m0<br>address cloud.mqtt.medium.com:8883<br># certificate file paths<br>bridge_cafile /etc/certs/ca.crt<br>bridge_certfile /etc/certs/client.crt<br>bridge_keyfile /etc/certs/client.key<br>bridge_insecure true<br>topic  {ordinal}  both 1</pre><pre>server {<br>listen 443 ssl;<br>server_name device.mqtt.local;<br>proxy_ssl_server_name on;<br>ssl_certificate    /etc/certs/client.crt;  ## Use your own trusted certificate from CA/SSLTrust<br>ssl_certificate_key /etc/certs/client.key; ## Use your own trusted certificate from CA/SSLTrust<br>ssl_client_certificate /etc/certs/ca.crt;  ## Use your own trusted certificate from CA/SSLTrust<br><br>ssl_verify_client on;<br><br>ssl_prefer_server_ciphers on;<br><br>keepalive_timeout 10;<br>ssl_session_timeout 5m;<br>    location / {<br>        root /usr/share/nginx/html/ ;<br>        }<br>}</pre><p>Now some samples screenshots of device html config page.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*F3L-z-56Yn-zOLhRGAG8WQ.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/954/1*8w6MScOaD6REMSiPLVO8Kw.png" /></figure><p>Of course, in production, all buttons can be merged into a single button to operate all of them in the backend one by one.</p><h4>Conclusion</h4><p>Normally, IoT devices are located behind the home router or other network infrastructure. But we need to manage all devices securely from anywhere in the world. Therefore, we need a bidirectional network protocol like mqtt, websocket, socket, etc. We use the lightweight software mosquitto, which also supports websocket and MQTT. MQTT is the standard for the entire IoT (<a href="https://www.iso.org/standard/69466.html">https://www.iso.org/standard/69466.html</a>). This solution allows you to manage your devices with trusted identity.</p><p>I am posting the full source code here from my GitHub. Please change some parameters in the file accordingly and use your own. I will try to share the next steps how you can use your own Google, Facebook account to log in and manage the device.</p><p><strong><em>Don’t forget to give Claps if it helped you.</em></strong></p><p>Source code: <a href="https://github.com/aze2201/IoT-cert-exchange">https://github.com/aze2201/IoT-cert-exchange</a></p><p>My profile: <a href="https://www.linkedin.com/in/fariz-muradov-b100a268/">https://www.linkedin.com/in/fariz-muradov-b100a268/</a></p><p>My own project: <a href="https://bitqap.com">https://bitqap.com</a> (crypto currency from scratch bash bash)</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a78e7d076843" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[iptables (execute script, log to RDMS/ NoSQL, DPI, NGFirewall etc.)]]></title>
            <link>https://medium.com/@farizmuradov/useful-notes-about-nfqueue-80a2c271db1a?source=rss-de2af600b19d------2</link>
            <guid isPermaLink="false">https://medium.com/p/80a2c271db1a</guid>
            <category><![CDATA[ngfirewall]]></category>
            <category><![CDATA[tech]]></category>
            <category><![CDATA[firewall]]></category>
            <category><![CDATA[ip]]></category>
            <category><![CDATA[iptables]]></category>
            <dc:creator><![CDATA[Fariz Muradov]]></dc:creator>
            <pubDate>Wed, 01 Aug 2018 19:46:26 GMT</pubDate>
            <atom:updated>2018-08-11T11:44:32.034Z</atom:updated>
            <content:encoded><![CDATA[<p>“how to execute script before/after iptables rules match”. Some reply is there which is not satisfied me. Most reply is jump traffic to LOG target with specific prefix and read syslog in while. This will cause high IO, iptables rules cannot make depend on this logging process processing also.</p><p>To answer this question, I would like to share some notes about nfqueue.</p><h3>NFQUEUE is an iptables and iptables target which delegate the decision on packets to a user space software.</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/777/1*h3m96UEoj4esn7Jt4pycjg.png" /></figure><p>So, it means we can send request from L3/L4 to L7 and process it with known application programming languages (Python, NODE.js, Java, etc.)</p><p>What we can do (for example) :</p><blockquote><strong>&gt; Execute some script before or after iptables rules match</strong></blockquote><blockquote><strong>&gt; DROP or ACCEPT package in user space programming.</strong></blockquote><blockquote><strong>&gt; Direct write iptables LOG to any database.</strong></blockquote><blockquote><strong>&gt; Provide API to developer for some act some rules (SDN).</strong></blockquote><blockquote><strong>&gt; Firewall L7, DPI (Deep package inspection), etc.</strong></blockquote><p>Let’s do some of them with python programming. I will use <strong>scapy</strong> lib which is most strong lib for manipulate <strong>TCP/IP</strong>.</p><p><strong><em>1.</em></strong> <strong><em>For example. I will send email if someone will send request to port 5555.</em></strong></p><p>Step1. Create basic script <strong><em>email.py</em></strong> (replace username, password, remote email accordingly)</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/939/1*W8wde6-wdiwtJ-aCALRkAg.png" /></figure><p>Step2. Create python package to access network packets and execute script in condition</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/939/1*lZ21k07vVGwK-K44ZDB2Dg.png" /></figure><p>Step3. Send package to NFQUEUE/queue num=1 with iptables</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/931/1*d-DMWCt5Bz18l7GzPPN4Sg.png" /></figure><p>Step4. And start python script</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/137/1*oZrToK-lIK5qxz5c2IA7Bg.png" /><figcaption>.</figcaption></figure><p>Step5. Send data from network to remote server over 5555 ports</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/743/1*QV3FpDKNXyeE_4V-z3bsZw.png" /></figure><p>RESULT:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/474/1*XQXAYgmDnvcI2LYLfuqlXw.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/868/1*B7sMu9MPwZ0CalS6w_90TQ.png" /></figure><p><strong><em>1.</em></strong> <strong><em>For example. I will log some information from request to SQLite. (you can use MySQL, PostgreSQL, MongoDB, etc.)</em></strong></p><p>Step1. Create database in SQLite. In our case I will store only source and destination IP port information.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/939/1*D7rcUxSh4kHNtwO3xPzmtQ.png" /></figure><p>Step2. Prepare script. I will use same python script by adding small lines</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/939/1*lZ21k07vVGwK-K44ZDB2Dg.png" /></figure><p>Step4. Again, start script in queue number 1 and try to send network request.</p><p>Step5. Check database</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/497/1*gYTZvBxSVlGW3bvEwcq5WA.png" /></figure><p><strong><em>1.</em></strong> <strong><em>Provide API to developer for some act some rules (lightweight SDN)</em></strong></p><p><strong><em>Surely you can do this part with any programming language by CGI interface. But in this case system administrator should provide root access to python script. And python script will get full access to iptables.</em></strong></p><p><strong><em>Of course, NFQUEU lib also require root privilege. But system administrator can control which package need to send NFQUEUE, which don’t.</em></strong></p><p><strong><em>2.</em></strong> <strong><em>DPI (Deep Package Inspection), IPS/IDS, etc.</em></strong></p><p><strong><em>By using Python scapy library you can manipulate packet payload. Scapy support reach protocol decoder which is very easy to use. So, you can develop your own Application firewall (for example LAF (Linux Application Firewall), IDS/IPS, like SURICATA inline mode</em></strong><em>.</em></p><p>NOTE: All above cases can be extended based on your idea. Like if some unwanted access happen let script send you URL to approve access. After yours confirm email script will do some act or if some IP address traffic will exceed threshold then call Linux <strong>tc</strong> (traffic controller) to decrease bandwidth etc.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=80a2c271db1a" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>