<?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"><channel><title><![CDATA[Bimal Dhital's blog]]></title><description><![CDATA[Bimal Dhital's blog]]></description><link>https://blog.bimal1412.com.np</link><generator>RSS for Node</generator><lastBuildDate>Tue, 06 Oct 2026 21:00:18 GMT</lastBuildDate><atom:link href="https://blog.bimal1412.com.np/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Solution to the InZiption Challenge from NCA CTF 2024]]></title><description><![CDATA[Among the various challenges that were presented in the event, I had a lot of fun solving the forensic challenges.
Among them was the challenge called InZiPtion.

The initial challenge post was straightforward. We were provided with a zip file and up...]]></description><link>https://blog.bimal1412.com.np/solution-to-the-inziption-challenge-from-nca-ctf-2024</link><guid isPermaLink="true">https://blog.bimal1412.com.np/solution-to-the-inziption-challenge-from-nca-ctf-2024</guid><category><![CDATA[CTF Writeup]]></category><category><![CDATA[CTF]]></category><category><![CDATA[forensics]]></category><category><![CDATA[Nepal]]></category><dc:creator><![CDATA[Bimal Dhital]]></dc:creator><pubDate>Mon, 23 Sep 2024 06:03:01 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/NLSXFjl_nhc/upload/ecac3f822097f3911c5b0e9bfecb821a.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Among the various challenges that were presented in the event, I had a lot of fun solving the forensic challenges.</p>
<p>Among them was the challenge called InZiPtion.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727066237574/45603a60-2733-4d76-862e-b4fccdf91734.png" alt class="image--center mx-auto" /></p>
<p>The initial challenge post was straightforward. We were provided with a zip file and upon opening it, we had a zip with nested zip files. I have seen such tactics many times in the CTF. Though I am not an avid CTF player and this one is probably my 3rd time playing, I always tend to read write-ups of the challenges when someone posts them on social media.</p>
<p>Along with the zip file, was a hint rar file where within it lay a text file that said as shown in the screenshot below.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727066557103/a8d93c57-6758-43c8-8010-7173629cc69d.png" alt class="image--center mx-auto" /></p>
<p>Our first move was to automate the process of unnesting the nested zips using a simple bash script.</p>
<pre><code class="lang-bash"><span class="hljs-keyword">while</span> [ <span class="hljs-string">"`find . -type f -name '*.zip' | wc -l`"</span> -gt 0 ]; <span class="hljs-keyword">do</span> find -<span class="hljs-built_in">type</span> f -name <span class="hljs-string">"*.zip"</span> -<span class="hljs-built_in">exec</span> unzip -- <span class="hljs-string">'{}'</span> \; -<span class="hljs-built_in">exec</span> rm -- <span class="hljs-string">'{}'</span> \;; <span class="hljs-keyword">done</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727066867744/27a4060a-cf33-4f9e-b809-4d6bff7aa551.png" alt class="image--center mx-auto" /></p>
<p>Now once we extracted every zip within the zip. We had a list of empty text files each with name chunky_numeric values.</p>
<p>Now we had that many text files we couldn’t just go and start opening every one of them manually. As all of them were empty, and our guess was one of the text files must have something. So we decided to automate this process using bash script. First, we open all txt files and only show the ones that have strings in it.</p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>

<span class="hljs-comment"># Loop through all .txt files</span>
<span class="hljs-keyword">for</span> file <span class="hljs-keyword">in</span> *.txt; <span class="hljs-keyword">do</span>
    <span class="hljs-comment"># Check if the file is not empty or only whitespace</span>
    <span class="hljs-keyword">if</span> [ -s <span class="hljs-string">"<span class="hljs-variable">$file</span>"</span> ] &amp;&amp; [ <span class="hljs-string">"<span class="hljs-subst">$(tr -d '[:space:]' &lt; <span class="hljs-string">"<span class="hljs-variable">$file</span>"</span>)</span>"</span> ]; <span class="hljs-keyword">then</span>
        <span class="hljs-built_in">echo</span> <span class="hljs-string">"Contents of <span class="hljs-variable">$file</span>:"</span>
        cat <span class="hljs-string">"<span class="hljs-variable">$file</span>"</span>
        <span class="hljs-built_in">echo</span> <span class="hljs-string">""</span>
    <span class="hljs-keyword">fi</span>
<span class="hljs-keyword">done</span>
</code></pre>
<p>Using this, we found that the text file named chunky_69.text had something in it as shown below.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727068424158/dc4904a2-fff0-4c47-a232-4cbe17590df0.png" alt class="image--center mx-auto" /></p>
<p>It’s a base64 encoded, upon decoding it we found this <code>ISTHISACIPHERKEY</code></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727068762634/54561c04-bb2d-43c0-978d-af202c6774ea.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727067082082/1d976aaa-ae84-4f95-b723-7b9a93a9e009.png" alt /></p>
<p>There was also a single rar file which was password protected. So as written in the starting hint text file, we have the encrypted rar file. But what now? We had no other clues and the only way to get that encrypted rar file opened was either using the password or just by brute-forcing. So my other teammate, <a class="user-mention" href="https://hashnode.com/@rabindramb">Rabindra Man Bajracharya</a> started brute-forcing it using John Ripper with the latest rockyou file.</p>
<p><img src="https://scontent.xx.fbcdn.net/v/t1.15752-9/458369750_1034301358018498_5766696738120784257_n.png?_nc_cat=106&amp;ccb=1-7&amp;_nc_sid=0024fc&amp;_nc_ohc=zKmPOjc17iQQ7kNvgERy73m&amp;_nc_ad=z-m&amp;_nc_cid=0&amp;_nc_pt=1&amp;_nc_ht=scontent.xx&amp;_nc_gid=AMRk_QP9wPleqgyOdMeA5GV&amp;oh=03_Q7cD1QFPJiDEjmtWDbx8pzoYtIhvcOHv9kMJE6wsUKMjtt0Juw&amp;oe=67187EF7" alt /></p>
<p>While my other teammate was brute-forcing the rar file, I started looking for the clues. After moving around and going through the files multiple times, I discovered something strange. First of all, from the beginning, I was interested to know why they named the text files chunky each with ascending numeric values. I started reasoning that it must be on purpose and there must be something about it. In computer science terminology, chunky as in chunks can mean many things.  </p>
<p>Another thing that I found interesting was each text file had a different number of newlines. So it was not empty after all, just empty new line spaces. The first chunky_0.txt had 52 new line spaces.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727069197224/068dfd99-1318-46ac-87fa-b61a509276b9.png" alt class="image--center mx-auto" /></p>
<p>Also at the same time I was playing around with the encrypted rar file. I tried looking into it by opening it in a hex viewer thinking I might find something interesting, maybe a header info hidden in the rar.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727069321035/a8273b62-80b3-4a9e-ab37-1541a5be52b7.png" alt class="image--center mx-auto" /></p>
<p>Then it somehow clicked. The hex values I saw on the viewer and the number of new lines of each text file started looking like chunks of data. Our initial thought was to get the new line space count of all text files, convert those numeric values in hex, and make a rar file out of it. But it didn’t work out, so we tried converting the hex value into ASCII thinking there might be something interesting.</p>
<p>First, we used automation to get the new line counts of all the text files and store them on a text file in an ascending order following the numeric naming of the texts.</p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>

<span class="hljs-comment"># Output file</span>
output_file=<span class="hljs-string">"line_counts.txt"</span>

<span class="hljs-comment"># Clear the output file if it exists</span>
&gt; <span class="hljs-string">"<span class="hljs-variable">$output_file</span>"</span>

<span class="hljs-comment"># Loop through files, sort by numeric part of the filename</span>
<span class="hljs-keyword">for</span> file <span class="hljs-keyword">in</span> $(ls chunky_*.txt | sort -t<span class="hljs-string">'_'</span> -k2,2n); <span class="hljs-keyword">do</span>
    <span class="hljs-comment"># Check if the file exists and is readable</span>
    <span class="hljs-keyword">if</span> [[ -f <span class="hljs-string">"<span class="hljs-variable">$file</span>"</span> ]]; <span class="hljs-keyword">then</span>
        <span class="hljs-comment"># Count the number of lines in the file</span>
        line_count=$(wc -l &lt; <span class="hljs-string">"<span class="hljs-variable">$file</span>"</span>)
        <span class="hljs-comment"># Output the file name and line count to the output file</span>
        <span class="hljs-built_in">echo</span> <span class="hljs-string">"<span class="hljs-variable">$line_count</span>"</span> &gt;&gt; <span class="hljs-string">"<span class="hljs-variable">$output_file</span>"</span>
    <span class="hljs-keyword">fi</span>
<span class="hljs-keyword">done</span>

<span class="hljs-built_in">echo</span> <span class="hljs-string">"Line counts written to <span class="hljs-variable">$output_file</span>"</span>
</code></pre>
<p>Then we converted each word count into hexadecimal values by automating it using bash script.</p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>

<span class="hljs-comment"># Input file with decimal line counts</span>
input_file=<span class="hljs-string">"line_counts.txt"</span>

<span class="hljs-comment"># Output file with hexadecimal line counts</span>
output_file=<span class="hljs-string">"line_counts_hex.txt"</span>

<span class="hljs-comment"># Clear the output file if it exists</span>
&gt; <span class="hljs-string">"<span class="hljs-variable">$output_file</span>"</span>

<span class="hljs-comment"># Read each line from the input file</span>
<span class="hljs-keyword">while</span> IFS= <span class="hljs-built_in">read</span> -r line; <span class="hljs-keyword">do</span>
    <span class="hljs-comment"># Extract the filename and line count (assuming format: "filename: count")</span>
    filename=$(<span class="hljs-built_in">echo</span> <span class="hljs-string">"<span class="hljs-variable">$line</span>"</span> | cut -d<span class="hljs-string">':'</span> -f1)
    line_count=$(<span class="hljs-built_in">echo</span> <span class="hljs-string">"<span class="hljs-variable">$line</span>"</span> | cut -d<span class="hljs-string">':'</span> -f2 | xargs)  <span class="hljs-comment"># Remove any leading/trailing spaces</span>

    <span class="hljs-comment"># Convert the line count to hexadecimal</span>
    hex_count=$(<span class="hljs-built_in">printf</span> <span class="hljs-string">"%X\n"</span> <span class="hljs-string">"<span class="hljs-variable">$line_count</span>"</span>)

    <span class="hljs-comment"># Write the filename and hexadecimal line count to the output file</span>
    <span class="hljs-built_in">echo</span> <span class="hljs-string">"<span class="hljs-variable">$hex_count</span>"</span> &gt;&gt; <span class="hljs-string">"<span class="hljs-variable">$output_file</span>"</span>
<span class="hljs-keyword">done</span> &lt; <span class="hljs-string">"<span class="hljs-variable">$input_file</span>"</span>

<span class="hljs-built_in">echo</span> <span class="hljs-string">"Hexadecimal conversion complete. Output written to <span class="hljs-variable">$output_file</span>"</span>
</code></pre>
<p>Now we had the hex values and the only thing left for us was to convert it into ASCII.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727069801014/963acff4-68de-49eb-a9f9-104204700b3f.png" alt class="image--center mx-auto" /></p>
<p>And there it was, our another clue to the flag.<br /><code>4r3_y0u_h4v1ng_fun_1_sur3_4m_h4v1ng_fun_g00d_luck_4_supr1s3_m1ght_b3_1n_1ts_w4y_y4_It5_l0ng_P4a55_D0nT_H4t3_m3</code></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727069879045/988a226e-17e5-4682-8e8d-7026650f70fd.png" alt class="image--center mx-auto" /></p>
<p>So, our first thought was it must be the password for the encrypted rar and we were correct. Upon unlocking the encrypted rar file we got a new text file that had what seemed like a flag and it also seemed like it was encrypted in some way. So, we immediately remembered the base64 cipher key we found on the chunky_69 text file.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727070211564/efb0f4be-da18-410b-8a1c-58e8f0433b0a.png" alt class="image--center mx-auto" /></p>
<p>Now only thing left was to figure out what cipher was used to encrypt this. Surprisingly, with a simple prompt by giving the Cipher Key and the Cipher text in the ChatGPT, we were able to find out about the cipher name. It was Vigenère cipher.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727070531347/c539e96e-aa3a-4cfb-92f3-122c4fb17900.png" alt class="image--center mx-auto" /></p>
<p>And there we have it. The flag was <code>nca{unz1pp3d_but_st1ll_scr4mbl3d}</code> .</p>
<p>A big thanks to the <a target="_blank" href="https://ncateam.xyz/">NCA Team</a> for creating such fun challenges.</p>
]]></content:encoded></item><item><title><![CDATA[Proxying Traffics of Flutter-Based Android Apps Having Split APKs or XAPK]]></title><description><![CDATA[If you are not familiar with the restriction that Flutter-Based Apps have while proxying it's traffic for analysis proposes then you can head over to this blog and read more about it, Bypass SSL Pinning for Flutter Apps using reFlutter Framework | Me...]]></description><link>https://blog.bimal1412.com.np/proxying-traffics-of-flutter-based-android-apps-having-split-apks-or-xapk</link><guid isPermaLink="true">https://blog.bimal1412.com.np/proxying-traffics-of-flutter-based-android-apps-having-split-apks-or-xapk</guid><category><![CDATA[Flutter]]></category><category><![CDATA[android app security]]></category><category><![CDATA[pentesting]]></category><category><![CDATA[Burpsuite  ]]></category><dc:creator><![CDATA[Bimal Dhital]]></dc:creator><pubDate>Sat, 30 Sep 2023 08:14:42 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/DsmDqiYduaU/upload/68b793c789ac5d8e86210977f2c679d0.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>If you are not familiar with the restriction that Flutter-Based Apps have while proxying it's traffic for analysis proposes then you can head over to this blog and read more about it, <a target="_blank" href="https://ayoubnajim.medium.com/bypass-ssl-pinning-for-flutter-apps-using-reflutter-framework-f77b858919b7">Bypass SSL Pinning for Flutter Apps using reFlutter Framework | Medium</a></p>
<p>Now that we know what kind of restriction it is and how it works. In this blog, I will try to apply the same method to Android apps that come with split APKs.</p>
<p>The split apks method has started getting more common these days, as it solves a lot of problems related to the spec differences of a vast number of Android devices. It also helps devs to quickly push short updates for specific components of the app.</p>
<p>I will be using MeMuPlay Android Emulator on my Windows 11 machine to test this apk having split apks.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696060239625/a0b283c1-78af-4e0b-a2a6-bea571a6457d.png" alt class="image--center mx-auto" /></p>
<p>Once the app is installed. Connect to the Emulator's adb from your Windows Terminal. Enter into the shell of the emulator using <code>adb shell</code> the command. You can use this command to search for the package you looking for.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696060373519/d907cf89-3ab1-44e5-8059-e7835a12b086.png" alt class="image--center mx-auto" /></p>
<p>In my case it's <code>io.github.ictsolved.csit</code></p>
<p>Now find its path. Using the command as shown below</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696060446197/baaf45cf-4580-421d-9152-e7872c95abbe.png" alt class="image--center mx-auto" /></p>
<p>Now grab all the APKs from the emulator. To do that, make sure you copy the folder location of the package and use adb pull to copy it into your PC.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696060549562/1e88062a-2720-4da5-b25b-df1c99cae643.png" alt class="image--center mx-auto" /></p>
<p>Go inside the directory. You should have files that look like this.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696060700349/6da8ded8-7cd8-44fe-ad47-509f5da131d1.png" alt class="image--center mx-auto" /></p>
<p>Those 3 apk files are what we are interested in. Since I am using an emulator, let's look at the <code>split_config.x86_64.apk</code> file.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696060817978/e2d7552b-82f1-4ea9-a63d-9ba41e00926e.png" alt class="image--center mx-auto" /></p>
<p>So this one has the <code>libflutter.so</code> file. We use reFlutter on it to add our bypass.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696061101370/fe00a348-30cc-44de-a5c5-2f281cabf994.png" alt class="image--center mx-auto" /></p>
<p>Once you reflutter on the right apk, sign all of the apks using uber apk signer.</p>
<p>Uninstall the app from the emulator and use adb to install the apks. To install multiple apks, use this command</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696061288637/db5de66e-a0d9-4ee1-87a3-4b48337482a5.png" alt class="image--center mx-auto" /></p>
<p><code>adb install-multiple</code><br />Make sure you add the base.apk first, then enter split apks behind it. And don't forget to add the signed apks only, you won't be able to install non-signed apks or it won't work.</p>
<p>And that's it. Start your analysis using Burp Suite. You can also download split apks from the sites like Apkmirror. They usually pack those apks inside an XAPK zip-like format. You can simply extract it grab the apks from it and follow the procedure.</p>
]]></content:encoded></item><item><title><![CDATA[Assigning IPv6 directly from the primary router to Docker Containers using Macvlan]]></title><description><![CDATA[Each container having its own public IPv6 will have tons of benefits. For example, if you are running a torrent client application on a docker container and using it for downloading torrents, with ipv6 assigned to it, it will able to communicate with...]]></description><link>https://blog.bimal1412.com.np/assigning-ipv6-directly-from-the-primary-router-to-docker-containers-using-macvlan</link><guid isPermaLink="true">https://blog.bimal1412.com.np/assigning-ipv6-directly-from-the-primary-router-to-docker-containers-using-macvlan</guid><category><![CDATA[ipv6]]></category><category><![CDATA[Docker]]></category><category><![CDATA[networking]]></category><category><![CDATA[Homelab]]></category><category><![CDATA[macvlan]]></category><dc:creator><![CDATA[Bimal Dhital]]></dc:creator><pubDate>Sat, 30 Sep 2023 06:48:23 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/HSACbYjZsqQ/upload/bbc9fc054ae011c7f163060154c53e56.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Each container having its own public IPv6 will have tons of benefits. For example, if you are running a torrent client application on a docker container and using it for downloading torrents, with ipv6 assigned to it, it will able to communicate with peers having ipv6 directly and will be able to directly download from them. This will dramatically increase the torrent download speed and even make it possible for you to seed to others or use it as a seedbox. I know it's a strange use case that brought me to use this for my Docker containers, but I am sure it will have its own benefits for other users, especially the ones who are self-hosting stuff and are behind the NAT of their ISPs.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696054367648/773a469e-684c-4e93-96a8-41ac554bd2f8.png" alt class="image--center mx-auto" /></p>
<p>However, I have discovered other use cases for this. Like I can directly expose a service with the same ports from the same machine. With the help of Macvlan, every container will have its own virtual LAN port, meaning it will have its own MAC Address and will act as a LAN port directly connected to my primary router.</p>
<p>To do this first you have to know your IPV6 Prefix and IPV4 subnet of the network.</p>
<p>In my case, let's assume that I have ipv6 prefix <code>2400:1a00:XXXX:XXXXX::/64</code></p>
<p>First, go to your server's terminal and create a network with the Macvlan driver in your Docker. To do this enter the command below</p>
<pre><code class="lang-bash">docker network create -d macvlan --subnet 192.168.1.0/24 \
 --gateway 192.168.1.1 \
--subnet 2400:XXXX:XXXX:XXXXX::/64 \
 --gateway 2400:XXXX:XXXX:XXXX::1 \
 --ipv6 -o parent=eth0 dualmac -o macvlan_mode=bridge
</code></pre>
<p>Make the changes on the subnet and gateway of both IPv4 and IPv6 according to your own Network setup. You can also set it for IPv6 only if you like.</p>
<p>On the <code>parent=</code> , you have to enter the name of the main network interface. And right after that line, you can see that I have written <code>dualmac.</code> You can write whatever you like, it's the network's name so name it as per your preference.</p>
<p>Once that's done, you have created a network with Macvlan, now you can assign it your container.</p>
<p>First, check the network if it has been correctly configured or not. You can do that by entering docker network inspect &lt;Your Network Name&gt;. In my case it's dualmac.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696055526000/9607fa45-863f-4c6a-baf7-35ec51e54c90.png" alt class="image--center mx-auto" /></p>
<p>Observe the Subnet and Gateway and make sure they are correct.</p>
<p>Now assign your container to the network using Docker Compose. In your docker-compose config file add these to assign it to the network you have created.</p>
<p>You can let the docker container dynamically get the IPs, but it often ends up with getting IPs that have been used already, so it's better that you assign them manually from your docker-compose config file.</p>
<pre><code class="lang-yaml">        <span class="hljs-attr">networks:</span>
            <span class="hljs-attr">ipv6net:</span>
            <span class="hljs-attr">ipv6_address:</span> <span class="hljs-number">2400</span><span class="hljs-string">:XXXXX:XXXXX:XXXXX::4</span>
            <span class="hljs-attr">ipv4_address:</span> <span class="hljs-number">192.168</span><span class="hljs-number">.1</span><span class="hljs-number">.4</span>

<span class="hljs-attr">networks:</span>
  <span class="hljs-attr">ipv6net:</span>
     <span class="hljs-attr">name:</span> <span class="hljs-string">dualmac</span>
     <span class="hljs-attr">external:</span> <span class="hljs-literal">true</span>
</code></pre>
<p>Place them as shown in the screenshot below. You can name the networks on the config as you like, in my case, I have named it <code>ipv6net</code> . And in the <code>name: dualmac</code> , enter the name of the docker network you created previously. And that's all. Now start your container using the config file, and you should see the container getting IPs directly from your primary router.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696055752908/4b754ff8-baa1-4d3c-8560-d595b9c94dc2.png" alt class="image--center mx-auto" /></p>
<p>In the screenshot below, you can see the torrent client directly communicating with the IPv6 peers.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696056191335/0ca6a446-4567-4118-a4fb-192d7948d1c6.png" alt class="image--center mx-auto" /></p>
<p>If you do <code>docker network inspect</code> on your newly created network, while running the containers using it, you can also see the IPs and MAC being used for the container.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1696056295067/1a572da4-2279-4c2d-ba43-7939c22f1d0e.png" alt class="image--center mx-auto" /></p>
<p><strong><em>Note:</em></strong><br /><strong><em>If you only want your docker container to get the public IPv6 and nothing else, then you can simply set the network mode to host. With that, you won’t have to depend on macvlan or the hefty, troublesome docker network configurations. The container will act as a network host device and will request your network's DHCP server for IP assignment. And of course, your container will get IPv6. But make sure you have IPv6 enabled in the main docker configuration.</em></strong>  </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1759036298084/7a81105e-a576-4c46-a468-2f2d596d6fda.png" alt class="image--center mx-auto" /></p>
]]></content:encoded></item><item><title><![CDATA[Exposing Self-Hosted Behind the NAT Services to the Internet using Cloudflare Tunnel]]></title><description><![CDATA[One of the greatest problems a person faces while self-hosting is the NAT. For people whose ISP doesn't provide port forwarding or a public IP, tunneling or using a VPN is the only way to expose self-hosted services to the internet. Having IPv6 is gr...]]></description><link>https://blog.bimal1412.com.np/exposing-self-hosted-behind-the-nat-services-to-the-internet-using-cloudflare-tunnel</link><guid isPermaLink="true">https://blog.bimal1412.com.np/exposing-self-hosted-behind-the-nat-services-to-the-internet-using-cloudflare-tunnel</guid><category><![CDATA[tunnel]]></category><category><![CDATA[nat]]></category><category><![CDATA[self-hosted]]></category><category><![CDATA[cloudflare]]></category><category><![CDATA[server]]></category><dc:creator><![CDATA[Bimal Dhital]]></dc:creator><pubDate>Mon, 25 Sep 2023 13:46:50 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/k5AxNUn4c5o/upload/f228a7a7e6cf69a9227b16c8c6c827e9.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>One of the greatest problems a person faces while self-hosting is the NAT. For people whose ISP doesn't provide port forwarding or a public IP, tunneling or using a VPN is the only way to expose self-hosted services to the internet. Having IPv6 is great for this kind of thing but only the people with IPv6 can communicate with a service that only has public IPv6. You could also proxy the services of IPV6 on Cloudflare by directly adding an AAA record on the DNS, but Cloudflare only allows web services that are hosted on port 80. Meaning, that if you are trying to bring something that's on a different port, it won't be accessible to the users.</p>
<p>Finding the right service provider to fix this issue is really troublesome. Before I was introduced to the Cloudflare Tunnel, I was using Ngrok to expose some of my Nginx web services to the internet. However, it had a lot of limitations, especially for free users. Like, using your own domain name required a premium plan, also the speed and the latency were really troublesome. The randomly generated domain it provides also is not good as they are known for being used in Phishing Attacks.</p>
<p>And then I came across Cloudflare Tunnel. I already had gotten my free domain name from register.com.np and had already set it up to work with Cloudflare. This will help a lot if you are planning on using the Cloudflare tunnel.</p>
<p>Now setting up Cloudflare tunnel is fairly simple. You open up a terminal of your server and enter</p>
<pre><code class="lang-bash">apt install cloudflared
</code></pre>
<p>Once it's installed, you simply log into your Cloudflare account using the command</p>
<pre><code class="lang-bash">cloudflared login
</code></pre>
<p>You should be redirected to the web browser. Once you log in, select the domain name that you want to use. Head back again to the terminal and enter the command</p>
<pre><code class="lang-bash">cloudflared tunnel create &lt;NAME&gt;
</code></pre>
<p>in the &lt;NAME&gt; place, enter the name that you want</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1695645607632/629544c9-29dc-4ac1-8394-02631ebb7354.png" alt class="image--center mx-auto" /></p>
<p>You can try entering <code>cloudflared tunnel list</code> command to check if it's been created or not. Also, make sure you note down the location of the credentials file that's on JSON and the ID, which is basically the JSON file name.</p>
<p>Now you have created the tunnel, create a config file so that it will be easier to add services that you want to expose to the internet via Cloudflare Tunnel.</p>
<p>One of the great features of Cloudflare Tunnel is that it lets you use your own domain name while exposing services to the internet.</p>
<p>I will try exposing a simple file-serving web server that is made using Nginx which is on port 1337</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1695646646821/ad7b34f2-6b64-46a1-bd6b-0a7d8598be19.png" alt class="image--center mx-auto" /></p>
<p>Create a config YAML file like this</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1695646695629/b20c6f11-fafd-429a-a512-1b840ce6844a.png" alt class="image--center mx-auto" /></p>
<p>In the tunnel, enter the ID of the tunnel you got while creating it, and in the credentials file enter your JSON file location that you got while creating the tunnel.</p>
<pre><code class="lang-yaml"><span class="hljs-attr">tunnel:</span> <span class="hljs-string">&lt;Tunnel-UUID&gt;</span>
<span class="hljs-attr">credentials-file:</span> <span class="hljs-string">/root/.cloudflared/&lt;Tunnel-UUID&gt;.json</span>

<span class="hljs-attr">ingress:</span>
 <span class="hljs-bullet">-</span> <span class="hljs-attr">hostname:</span> <span class="hljs-string">test.bimal1412.com.np</span>
   <span class="hljs-attr">service:</span> <span class="hljs-string">http://192.168.1.170:1337</span>
 <span class="hljs-bullet">-</span> <span class="hljs-attr">service:</span> <span class="hljs-string">http_status:404</span>
</code></pre>
<p>For example, in the config above, add the subdomain name where you want your service to be accessible, and in the service, add your service's address. You can add add many services as you want. Just add another - hostname and below the service address you want to expose.</p>
<p>Once it's done, save the config file. Goto your Cloudflare Web Dashboard, and add a CNAME record with a name you are using on your config, for me it's test</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1695647220602/73c46fac-a1e9-4782-95cb-71cd0afc6a13.png" alt class="image--center mx-auto" /></p>
<p>and in the target box, add <code>&lt;YOUR TUNNEL ID&gt;.cfargotunnel.com</code></p>
<p>And hit save. You have to do it with multiple subdomains if you are trying to expose multiple services to the internet.</p>
<p>Now on the server run</p>
<pre><code class="lang-bash">cloudflared tunnel --config /path/your-config-file.yaml run
</code></pre>
<p>it should start exposing your service to the tunnel and should be accessible through the subdomain name.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1695647503901/966ed0c7-b908-4299-924a-e3218a72219d.png" alt class="image--center mx-auto" /></p>
<p>Now to run the whole thing in the background as a service, Cloudflare makes it really easy. Before running it as a service, first move the config.yml file you created to the Cloudflared's directory, which in my case is /root/.cloudflared/, and also make sure the config file is named config.yml.</p>
<p>Now that's done. Just run the command</p>
<pre><code class="lang-bash">cloudflared service install
systemctl start cloudflared
</code></pre>
<p>And that's all. Now the tunnel service should be running in the background and will auto-restart itself if the internet goes out or the server restarts.</p>
<p>To check if it's running or not just enter <code>service cloudflared status</code></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1695647973351/e6f75963-9423-4d63-b6a7-eb5bd9463ff3.png" alt class="image--center mx-auto" /></p>
<p>If it's saying active in green, then you are good to go. And the best part is, speed is really good.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1695648112983/22be7d9f-5900-461b-9b58-e41ea70b7699.png" alt class="image--center mx-auto" /></p>
<p>It totally depends on your home's Internet upload speed since you are sending the file to the tunnel and again receiving it from the tunnel.</p>
<p>You can also tunnel the ssh of your machine to the internet.</p>
<p>In the config service file simply add</p>
<pre><code class="lang-bash">- hostname : &lt;YOUR DOMAIN NAME&gt;
  service: ssh://&lt;YOUR MACHINE IP&gt;:22
</code></pre>
<p>But the tricky part here is, that to access the SSH, you need to have Cloudflared installed on the machine and have to make some edits to the config. You can download and install Cloudflared for Windows 11 using Winget or you can just head over to this <a target="_blank" href="https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/downloads/">link</a> and download it from there.</p>
<p>For example, on my Windows 11 machine, inside the .ssh directory, I have made a config file like this</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1695648504883/7a4ba76f-9a98-4385-a65c-5d7ca8ab54da.png" alt class="image--center mx-auto" /></p>
<p>Inside the config file</p>
<pre><code class="lang-bash">Host &lt;YOUR SSH SUBDOMAIN&gt;.bimal1412.com.np
     User root
     ProxyCommand cloudflared access ssh --hostname %h
</code></pre>
<p>Make sure that you installed Cloudflared and added it to the system environment properly.</p>
<p>Once that's done you can access the ssh of your machine from the internet.</p>
<p>There is also a service of Cloudflare called Zero Trust, that lets you access the SSH terminal directly on the browser, but to access it's free plan you need to have a working Credit Card. I somehow managed to add a working card and use it to access the ssh from the browser.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1695649357724/7a19d3af-8fe0-4870-b121-69ce10f643a0.png" alt class="image--center mx-auto" /></p>
<p>Also, it can add an extra layer of authentication to all of your tunnels.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1695648985886/76ba1d4e-6ba5-40a2-8c72-9ae8be63f3d8.png" alt class="image--center mx-auto" /></p>
<p>For example, here it lets you add your tunnel services to a dashboard like this. And while accessing each of those services, you can set up different kinds of verification with your own custom pages.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1695649077171/6cf0b63d-4ba8-4ed8-ba6e-0b8b62a4c119.png" alt class="image--center mx-auto" /></p>
]]></content:encoded></item><item><title><![CDATA[Writing Bash CGI Application for OpenWRT]]></title><description><![CDATA[When it comes to custom router firmware, OpenWRT is probably the best. If you build the firmware by yourself, you can skip all the preinstalled LuCi Web UI things and dial down the RAM usage to just 3-4 MB. One of the cool things about OpenWRT is its...]]></description><link>https://blog.bimal1412.com.np/writing-bash-cgi-application-for-openwrt</link><guid isPermaLink="true">https://blog.bimal1412.com.np/writing-bash-cgi-application-for-openwrt</guid><category><![CDATA[OpenWRT]]></category><category><![CDATA[Bash]]></category><category><![CDATA[cgi]]></category><category><![CDATA[server]]></category><dc:creator><![CDATA[Bimal Dhital]]></dc:creator><pubDate>Sun, 17 Sep 2023 11:07:54 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/4hbJ-eymZ1o/upload/94c273fae8866b218ea304ad7959bcdd.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>When it comes to custom router firmware, OpenWRT is probably the best. If you build the firmware by yourself, you can skip all the preinstalled LuCi Web UI things and dial down the RAM usage to just 3-4 MB. One of the cool things about OpenWRT is its openness to let users modify everything. We can say it's a type of Linux distro running on your computer called Router. Heck, you can even install it on your Android TV Box. There are already prebuilt images for specific Android TV Boxes. You can just head over to this <a target="_blank" href="https://github.com/ophub/amlogic-s9xxx-openwrt">ophub/amlogic-s9xxx-openwrt</a> , and install it. The installation procedure is really easy, it's the same as the installation of the Linux blog I wrote <a target="_blank" href="https://blog.bimal1412.com.np/using-android-tv-boxes-as-a-linux-machine-for-a-home-lab">previously</a>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694948705073/2426507e-bb3f-4bc0-b4fe-7dfd8e8ba72e.png" alt class="image--center mx-auto" /></p>
<p>The usual build of OpenWRT already comes with a lightweight HTTP web server called uhttpd. It was designed for embedded systems with very low system resources, which explains its overall size and the operating system demand.</p>
<p>To access your web app that uses bash CGI, let's create a service on a different port. This will ease the process while exposing it to the internet if you are planning on tunneling it or proxying through other services.</p>
<p>To create a separate service for a port. You have to edit the uhttpd config file. To do that, ssh into your OpenWRT machine. And edit the config file located in <code>/etc/config/uhttpd</code> .</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694946443754/a7d47265-58f9-42bb-ae0a-3cc3399290ad.png" alt class="image--center mx-auto" /></p>
<p>In the screenshot above, you can see that I have created a config with a name <code>other</code> . Inside it, I am exposing the webserver to port 8080, since port 80 is already being used by the LuCi.</p>
<pre><code class="lang-nginx"><span class="hljs-attribute">config</span> uhttpd <span class="hljs-string">'other'</span>
        list listen_http <span class="hljs-string">'0.0.0.0:8080'</span>
        list listen_http <span class="hljs-string">'[::]:8080'</span>
        option home        <span class="hljs-string">'/www/users/'</span>
        option index_page  <span class="hljs-string">'test.cgi'</span>
        option cgi_prefix <span class="hljs-string">'/'</span>
        option rfc1918_filter <span class="hljs-string">'1'</span>
        option max_requests <span class="hljs-string">'3'</span>
        option max_connections <span class="hljs-string">'100'</span>
        option cert <span class="hljs-string">'/etc/uhttpd.crt'</span>
        option key <span class="hljs-string">'/etc/uhttpd.key'</span>
        option script_timeout <span class="hljs-string">'60'</span>
        option network_timeout <span class="hljs-string">'30'</span>
        option http_keepalive <span class="hljs-string">'20'</span>
        option realm <span class="hljs-string">'users'</span>
        option tcp_keepalive <span class="hljs-string">'1'</span>
</code></pre>
<p>In the option home, put in the directory where you are planning to store your web applications files. In the option index_page, add the index page file name that you want to show while visiting the web server. For example, I have put a test.cgi as a filename, which I have it in the location.</p>
<p>Once you modify the config based on your needs, save it and restart the uhttpd service. You can do that by entering <code>service uhttpd restart</code> on the terminal.</p>
<p>Now you can go to the port 8080, and you should see the server working. Since we haven't added the files on the location, it might show an empty index page.</p>
<p>Now to create the web app using the bash CGI is not that hard. If you know bash scripts then you should be able to pick it up in no time. For those who are not familiar with it, I suggest that you read this awesome <a target="_blank" href="http://underpop.online.fr/c/cgi/docs/creating-cgi-programs-with-bash/">documentation.</a></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694947227682/04ea5237-252c-4ba0-ad9b-fe6b3e9d6272.png" alt class="image--center mx-auto" /></p>
<p>You can see here that I have made a simple web app using bash CGI to control the internet access to the users I am sharing my home internet with. Since it's bash, you can execute shell commands directly from the web page.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694947424702/e6975e9e-8436-4cd1-8eb9-53f01773de83.png" alt class="image--center mx-auto" /></p>
<p>Here's a small sneak peek into the code. I am using Bootstrap for the table and the buttons. The information like days remaining and expiry dates are generated dynamically on the web page by executing the shell commands.</p>
<p>For example, if you want to show the uptime of the system on your webpage you can do</p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>

<span class="hljs-built_in">echo</span> <span class="hljs-string">"&lt;h3&gt;<span class="hljs-subst">$(uptime)</span>"</span>
</code></pre>
<p>You basically, echo out the language that your web program understands, i.e. HTML, CSS, and JS.</p>
<p>And that's how you start writing your own bash CGI application and deploy it into your OpenWRT. This is a basic way of controlling your OpenWRT from the web. Check out the <a target="_blank" href="https://openwrt.org/docs/guide-user/services/webserver/uhttpd">official documentation</a> on the uhttpd from the OpenWRT. There are many advanced things you can do with it like adding basic HTTP authentication, using php, and so on.</p>
]]></content:encoded></item><item><title><![CDATA[Getting shell access on NETTV's Android Setup Box using the UART interface]]></title><description><![CDATA[Since the launch of IPTV in 2016 by NETTV, it has been dominating the TV market. Because of its many features and capabilities, the Dish TV market has been declining in city areas or areas where there is a reach of fiber connection. Over the years, N...]]></description><link>https://blog.bimal1412.com.np/getting-shell-access-on-nettvs-android-setup-box-using-the-uart-interface</link><guid isPermaLink="true">https://blog.bimal1412.com.np/getting-shell-access-on-nettvs-android-setup-box-using-the-uart-interface</guid><category><![CDATA[uart]]></category><category><![CDATA[#Serial Communications]]></category><category><![CDATA[IPTV]]></category><category><![CDATA[Android]]></category><category><![CDATA[android tv box]]></category><dc:creator><![CDATA[Bimal Dhital]]></dc:creator><pubDate>Sat, 16 Sep 2023 10:45:48 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1694860991173/ed28c5f7-e7a6-4a94-87c0-b8a0b470286f.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Since the launch of IPTV in 2016 by NETTV, it has been dominating the TV market. Because of its many features and capabilities, the Dish TV market has been declining in city areas or areas where there is a reach of fiber connection. Over the years, NETTV as a brand has come through many changes. As of now, Worldlink Communications owns it. The ISP is known for its restrictive methods, as it doesn't allow router access to its customers. The same thing is done on the setup box they are using for the NETTV.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694858950645/412ac706-243e-4ed3-bdd1-540d18cb2172.png" alt class="image--center mx-auto" /></p>
<p>The setup box they are using for their IPTV packs average specs, with only 1 GB of RAM, an Amlogic S905X Processor, and a mere 8 GB of Internal Storage. It's running Android OS with a very restrictive launcher kept on the home screen. This means you won't be able to use developer tools settings or adb on it.</p>
<p>The problem here is you won't be able to sideload any apps on it. You are stuck with the apps that the company chooses to provide. There have been many attempts and bypasses to sideload the apps. But they were patched in the latest firmware update.</p>
<p>Previously there was a feature introduced on the NETTV box that let users remote control it through the network. But some users found a way to use that to send some other remote navigation packets to the box, making it open Android's Native System Settings. With that opened, users could enable the developer option and with adb enabled basically have shell access. Also, the box comes pre-rooted.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694859453067/243072a0-c927-4f38-9ba4-d1d1c4b2ed66.png" alt class="image--center mx-auto" /></p>
<p>This method stopped working soon after NETTV noticed it and they removed the Remote feature from the Box.</p>
<p>Another method surfaced which involved using IR Blaster phones to send the right keymap to open the Native Setting again on the box. But that was also patched by on the firmware version 020809. If you have firmware version 020F07 or less, you can try this <a target="_blank" href="https://github.com/833M0L3/NETTV">method</a> to bypass the restriction in a much easier way.</p>
<p>Now talking about the UART Interface method. You need to have a UART to USB converter dongle first. You can buy it from Daraz. I used this <a target="_blank" href="https://www.daraz.com.np/products/ttl-usb-converter-usb-stc-isp-usb-to-serial-5-pin-serial-adapter-module-33v5v-power-i105763539-s1027613590.html?spm=a2a0e.searchlist.list.38.496cbc6dju4XgJ&amp;search=1">one</a> and it worked flawlessly.</p>
<p>If you don't know what is UART and how it works you can watch this video.</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://youtu.be/01mw0oTHwxg">https://youtu.be/01mw0oTHwxg</a></div>
<p> </p>
<p>Now once you know how it works. Open your NETTV setup box. Look for that UART Pin out and connect it to the right pin.</p>
<p>Since I have done it myself and figured out which PIN is for what, I have this image labeled below that will help you.</p>
<p><img src="https://user-images.githubusercontent.com/59522309/264717939-20aa9ac8-a8d0-40ba-a54e-09dc73ae694f.jpg" alt /></p>
<p>Once you connect the right PIN, power on the box while connecting it to the converter that is connected to the PC, and use the right bit rate for the communication. I think used 115200, but I might be wrong. If it starts throwing gibberish try 9600.</p>
<p><img src="https://user-images.githubusercontent.com/59522309/256521972-7b0bc0ba-98e5-4e69-a766-405dddeda895.jpg" alt /></p>
<p>I used Putty on Windows for the serial connection. You can use whatever tool you like. Once you get everything right you should get a booting info throw in the screen that is similar to Linux. Once it completes booting, you have the shell access. It's that easy.</p>
<p>You can go full root using <code>su</code> and start modifying things you would like to change. The first thing I did was install a different launcher and that's all. Since it's an adb shell, you can directly install apps using adb commands.</p>
<p><img src="https://user-images.githubusercontent.com/59522309/256522006-acab884a-c425-4c2d-9653-174513eba30f.jpg" alt /></p>
<p>And that's all. With a different launcher, you can install other 3rd party apps. For me, installing SmartTubeNext was a big deal, as this app has tons of features including Sponsorblock and Adblocks.</p>
]]></content:encoded></item><item><title><![CDATA[Enable IPv6 on a Secondary Router running OpenWRT]]></title><description><![CDATA[In recent years, ISPs here in Nepal have started deploying IPv6 in their network. For users who have a Linux server with tons of self-hosted things, this is a godsend feature. With IPv6 there is no need for NAT and any sort of complication. You just ...]]></description><link>https://blog.bimal1412.com.np/enable-ipv6-on-a-secondary-router-running-openwrt</link><guid isPermaLink="true">https://blog.bimal1412.com.np/enable-ipv6-on-a-secondary-router-running-openwrt</guid><category><![CDATA[ipv6]]></category><category><![CDATA[OpenWRT]]></category><category><![CDATA[router]]></category><category><![CDATA[isp]]></category><category><![CDATA[firewall]]></category><dc:creator><![CDATA[Bimal Dhital]]></dc:creator><pubDate>Sat, 16 Sep 2023 09:30:09 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1694856567658/87ef23e5-1aa2-473e-be6e-586f9fe4ab91.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In recent years, ISPs here in Nepal have started deploying IPv6 in their network. For users who have a Linux server with tons of self-hosted things, this is a godsend feature. With IPv6 there is no need for NAT and any sort of complication. You just expose a port and make some firewall rules and you are ready to go.</p>
<p>In the case of Worldlink, it's the same. But the thing with Wordlink's CPEs is they haven't enabled any sort of firewall. This means all of the inbound and outbound traffic for the IPv6 is allowed. That means the devices have to protect themselves with their built-in firewalls. I am guessing they are doing this because they don't allow router access to the customers and users who want to add firewall rules for their IPv6 would have to contact them, which I am sure will be troublesome. So, they thought of letting it all in without thinking about the security consequences.</p>
<p>Too much restriction was also not my liking so I thought about getting a secondary router. I had a fair share of experience using and installing OpenWRT as previously I did a lot of experiments installing it on TP Link routers. But it was 2023, so I had to look in the market for some better routers with good support for the OpenWRT.</p>
<p>During my search, only one router popped up everywhere. It was Xiaomi's Mi Router 4A Gigabit. It had a decent processor, RAM was 128 MB and Flash Memory was 16 MB. What caught my eye was the RAM, that's really good.</p>
<p>So I bought one. Installed OpenWRT on it using this <a target="_blank" href="https://github.com/acecilia/OpenWRTInvasion">method</a>, and got it running within a few minutes.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694855495027/2927d771-c4d1-4de9-85ba-59ce9a84bd7b.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694855539781/347707a1-cf22-482b-9402-c2f34565b162.png" alt class="image--center mx-auto" /></p>
<p>Now setting up the IPv6 was really a tricky part. Since my ISP provides a dual-stack IP, meaning I get IPv4 and IPv6 together. But the thing is, IPv4 is NAT and has no problem with me again putting it behind another network. But for IPv6 to work in such a way that every user connected to the Mi Router gets a public IPv6, the interface for IPv6 has to be set in a relay mode. Also, one of the reasons we are forced to use this relay mode or NDP proxy mode is because most ISPs in Nepal are assigning /64 address block to the CPE, meaning you can’t further prefix delegate the IPV6 to a larger pool. Though this current method does help with the IPV6 assignment via secondary router, without the prefix delegation, it is impossible to properly manage or create separate VLANs and networks.</p>
<p>To set the interface to the relay mode. Just go to the network interfaces.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694855823086/644a2d23-5506-4ec6-9fd9-1f79a2909776.png" alt class="image--center mx-auto" /></p>
<p>Edit your IPv6 WAN Interface and turn off the DHCP there. And make sure to change the IPv6 settings there as shown in the image below.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694855936735/62eee6b2-d8da-49cf-af24-00eb23089d83.png" alt class="image--center mx-auto" /></p>
<p>With that done, save it. And now head over to the LAN Interface. Edit the interface and go to it's DCHP Server Option and there make changes to the IPv6 settings as shown in the image below. You can skip the IPv6 DNS Server and leave it as it is.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694856108555/372fcda0-19be-4b7b-bf71-1f428e2a5b5b.png" alt class="image--center mx-auto" /></p>
<p>Now with that done. Save the changes and reboot your router. And you should start seeing your devices getting IPv6 assigned directly from the main CPE.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694856271249/0d9dd6c5-852c-4eb1-8d4e-6fec5bc71d68.png" alt class="image--center mx-auto" /></p>
<p>Now that's done. While exposing a port, you need to first allow that port from the firewall settings on your router. You can do that by heading over to the Firewall settings under the Network tab.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694856403327/36d8c03e-acc9-4e6a-8b9a-3869a81ad04a.png" alt class="image--center mx-auto" /></p>
<p>As you can see here, I have allowed the UDP protocol with ports 1195 and 1194. Those are for the VPN Server that I am hosting on my Linux servers. With that done those ports will be accessible by other IPv6 users.</p>
<p><strong><em>Update 2025:</em></strong><br />After the recent social media bans here in Nepal, many of us were forced to use DoH DNS services to bypass the blocks. And the best way to do that was to configure your router to do it. Normally, OpenWRT and most of the routers don’t come with DoH support; they only provide a plain IP input field to be sent to the DHCP devices. To fix this, you can self host a recursive DNS server and use tools like DNSCrypt to make those DNS queries go through secure DoH of popular DNS service providers like Cloudflare or Google. OpenWRT also provides packages that can forward your plain DNS requests to the DoH, which saves you the trouble of setting up the PiHole + DNSCrypt.</p>
<p>But the main issue is, when you are relaying the IPv6 to the devices, the router also automatically gives the default IPV6 based DNS servers that come with the ISPs. And it becomes really tedious to bypass.</p>
<p>Fortunately, you can change your IPV6 DHCP settings as shown below in the image to announce your own custom IPV6 DNS server even if it’s running in a relay mode. In the <code>DHCPv6-Service</code> set it to server mode and in the<code>announce IPV6 DNS</code> servers, you will have to add your PiHole NAT6 local IPv6 address, or you could just input your OpenWRT’s default local IPV6 gateway there. Entering your OpenWRT’s default local IPV6 address will just forward it to whatever DNS server you have configured in your WRT’s router settings. Do note that this is a LAN interface we are configuring, not WAN6.</p>
<p>With that done, the devices will get two DNS assigned, IPV4 &amp; IPV6 that you have set, thus bypassing the blocks.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1759034447159/a67a4217-0d58-4015-806f-9e7e0ca2ad70.png" alt class="image--center mx-auto" /></p>
<p>You can see devices getting assigned the IPV6 DNS server you set in the <code>Annouced IPV6 DNS Servers</code> option.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1759041612732/9a708d1f-675e-420b-aca0-b92e46812481.png" alt class="image--center mx-auto" /></p>
<p>I have PiHole + Dnscrypt setup, so it’s much easier to monitor and block domains that you don’t want. Though ISPs still can check your DNS Queries even if you use DoH or DoT. Using complex SSL inspection, they can check every packet’s SNI and implement a block based on that. So, using DNS over HTTPS is not a magical hack to bypass everything, but some ISPs do lack such hardware and software expertise, so if you are not a Worldlink user, then you are good to go.</p>
]]></content:encoded></item><item><title><![CDATA[Using Android TV Boxes as a Linux Machine for a home lab]]></title><description><![CDATA[A cheap way to get started with a home lab for a beginner is to get a Raspberry Pi. But in recent years, especially here in Nepal, the price of these Raspberry Pi has skyrocketed. Raspberry Pi 4 4GB variant can cost up to 22K with all the accessories...]]></description><link>https://blog.bimal1412.com.np/using-android-tv-boxes-as-a-linux-machine-for-a-home-lab</link><guid isPermaLink="true">https://blog.bimal1412.com.np/using-android-tv-boxes-as-a-linux-machine-for-a-home-lab</guid><category><![CDATA[Raspberry Pi]]></category><category><![CDATA[Nepal]]></category><category><![CDATA[self-hosted]]></category><category><![CDATA[Homelab]]></category><category><![CDATA[media server]]></category><dc:creator><![CDATA[Bimal Dhital]]></dc:creator><pubDate>Sat, 16 Sep 2023 08:38:19 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1694853444044/c06d34f3-ca99-472a-b039-a335ff52726b.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>A cheap way to get started with a home lab for a beginner is to get a Raspberry Pi. But in recent years, especially here in Nepal, the price of these Raspberry Pi has skyrocketed. Raspberry Pi 4 4GB variant can cost up to 22K with all the accessories it requires to get it up and running.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694849285675/d467507d-3b24-40ee-8126-6c79202202ca.png" alt class="image--center mx-auto" /></p>
<p>That's an insane cost. With that much money, you can get a decent 2nd hand Desktop CPU and use it as a home server, which will be more powerful and modular than these Raspberry Pis.</p>
<p>So what's the alternative to this?</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694850164977/dc1430d1-1377-45a8-ae1d-cedeb9c5dac3.jpeg" alt class="image--center mx-auto" /></p>
<p>Android TV Boxes are where they start shining here. In the past years, Android TV Boxes have started becoming really powerful with their chip makers upgrading their CPU for more demanding tasks like 4K video decodings and resource-heavy games.</p>
<p>What's more surprising here is their cost. An Android TV Box with 4GB of RAM and Almogic S905X3 costs around 6-7K, which is really good. Amlogic S905X3 comes on par with the CPU that comes inside the Rasp Pi 4 models. I would say that these are even faster. You can see the benchmarks <a target="_blank" href="https://ozkolonur.medium.com/here-is-why-i-am-replacing-my-raspberry-pi-4-nodes-with-this-ce7170c71a60">here</a>. Also not to forget about the extra accessories costs. With a 6-7K cost, an Android TV Box comes packaged with everything it needs to get it to start running. The box's board already has a big heat sink on the CPU, has EMMC storage, has a nicely done air-vented casing, and comes with a power supply cable.</p>
<p>The only thing it would be lacking compared to the Raspberry Pis is the GPIO PINs, which are not needed if you are only going to use it as a home lab Linux server machine.</p>
<p>You can head over to <a target="_blank" href="https://github.com/devmfc/debian-on-amlogic">debian-on-amlogic</a>, download a Linux image file that is compatible with your TV Box, and install it.</p>
<p>Remember this, we are installing Linux directly on the EMMC of the Android TV Box. It's not running in an emulation over Android. Meaning, that Linux will boot once you install it on the box.</p>
<p>Currently while writing this, there are 2 TV Boxes available in Nepal that support this Linux installation.</p>
<ul>
<li><p><a target="_blank" href="https://s.daraz.com.np/s.YpkD?cc">X96 AIR 4 GB RAM 64 GB Internal Storage ( cost 6.7 K )</a></p>
</li>
<li><p><a target="_blank" href="https://s.daraz.com.np/s.Ypkz?cc">X96 Mini 2 GB RAM 16 GB Internal Storage ( cost 3.8 K )</a></p>
</li>
</ul>
<p>I own HK1 Box and H96 Max X3, both have Amlogic S095X3 processors and using them as a home server for many years. Though they are not available in the Nepali market right now.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694851253790/016b865e-0c85-4adb-858d-2b22189c2542.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694851261495/f2d8f8cb-274d-4b88-a397-cc3c3e345189.png" alt class="image--center mx-auto" /></p>
<p>Linux installation on them is fairly easy. You download the right image and flash it on a USB Thumb Drive using Balena Etcher, connect it to your TV Box, and press the reset button while powering it on. And that should make it boot from the USB. From there, follow the instructions and you are done. Once the installation is complete just disconnect the USB and you are good to go.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694851727758/e627be40-0c61-4413-a1ad-3d7fe81209bb.jpeg" alt class="image--center mx-auto" /></p>
<p>I keep mine on a stairs side walls using a wall mount rack. The good thing is, this HK1 TV Box has a Gigabit Ethernet. Meaning the data transfer rate can go up to 100 MB/s. I have connected a 2 TB external hard drive into the Box there. Did some configuration on the Linux system to make it auto-mount using fstab.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694851895247/ee5b0994-5296-401d-b127-d36ba835ec66.png" alt class="image--center mx-auto" /></p>
<p>There is also an SD card slot in the box. Since I had a spare 32 Gigs SD card lying around. I put it inside the box and also kept it on the automount config in the fstab.</p>
<p>With that auto mounting, I have been using Samba to access the files from the network.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694852015388/706d3328-38a0-4380-854d-69378880a3dd.png" alt class="image--center mx-auto" /></p>
<p>It's been really easy to use it as a media server. I am using Kodi on devices and these TV Boxes feed the data to it.</p>
<p>With that said these TV Boxes are incredibly powerful and power efficient. I have been also using it to run some docker containers to host Django applications and the Nginx server. They run with no problem.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694852277210/f0734630-2b8e-43b3-a999-03485e379e5a.png" alt class="image--center mx-auto" /></p>
<p>Talking about the performance. I once had a Raspberry Pi 3B, given to me by an internet friend. And it was really slow.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694852541679/fb291536-3c96-4869-ada3-3e975a46278d.jpeg" alt class="image--center mx-auto" /></p>
<p>Also, I got only a bare board from him. Meaning I had to buy the power supply, memory card, a case, and a heat sink.</p>
<p>Buying all of those cost me around 2K. This Raspberry Pi 3B model had 1 GB RAM and it's CPU was clocked around 1.2 GHz. The performance lag could be instantly felt while using the terminal.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694852733892/aa078d48-b53c-42e4-bc52-67695dfa730d.jpeg" alt class="image--center mx-auto" /></p>
<p>So, after a few months, I decided to use a heat sink on it. But while trying to adjust the heat sink I accidentally knocked off a few of the resistors and capacitors off the board, causing WiFi, LAN, and some USB ports to not work.</p>
<p>Since I was using it for some critical home use, a small Linux machine was needed. I decided to get the TX3 Mini Android TV Box to fill that needed hole asap.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694853045073/213365ff-1cba-4ea2-8522-f403dbc4433e.jpeg" alt class="image--center mx-auto" /></p>
<p>Finding the reset button on this box was a little confusing since all of the TV Boxes used to have their reset button inside the audio port. For some reason, this box had it on the center of the opposite side of the box. Once I installed the Linux on it. The performance was noticeable compared to the Raspberry Pi 3B, even though both of them have CPU clocked at 1.2 GHz.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694853211937/2e94456f-5034-428c-92a8-f4fae660588b.jpeg" alt class="image--center mx-auto" /></p>
<p>So, you can see from this experience how easy and hassle-free it is to do this on a TV Boxes compared to the Raspberry Pi. It saves you from the trouble of buying all of those extra accessories.</p>
<p>I have been also using it as an OpenVPN server which I have written on my previous <a target="_blank" href="https://blog.bimal1412.com.np/using-worldlinks-nat-for-openvpn-server-to-host-lan-party-games-and-more">blogspot.</a></p>
]]></content:encoded></item><item><title><![CDATA[Using Worldlink's NAT for OpenVPN Server to host LAN Party Games and more]]></title><description><![CDATA[One of the main problems we face with IPv4 is NAT. Some may argue that NAT has it's own benefits but the main elephant in the room is the mess it has created in the network field. If you want to self-host something and share it with your friends it's...]]></description><link>https://blog.bimal1412.com.np/using-worldlinks-nat-for-openvpn-server-to-host-lan-party-games-and-more</link><guid isPermaLink="true">https://blog.bimal1412.com.np/using-worldlinks-nat-for-openvpn-server-to-host-lan-party-games-and-more</guid><category><![CDATA[isp]]></category><category><![CDATA[Nepal]]></category><category><![CDATA[vpn]]></category><category><![CDATA[Games]]></category><category><![CDATA[worldlink]]></category><dc:creator><![CDATA[Bimal Dhital]]></dc:creator><pubDate>Fri, 15 Sep 2023 11:16:54 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1694853826584/f08846a1-e10d-4852-8d68-47a34f5e0899.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>One of the main problems we face with IPv4 is NAT. Some may argue that NAT has it's own benefits but the main elephant in the room is the mess it has created in the network field. If you want to self-host something and share it with your friends it's a nightmare. Heck, it's not even possible in many of the ISPs here in Nepal because of their multiple layers of CGNAT across their infrastructure for the customers. They straight out reject you or tell you it's not possible to expose a port from your network to the internet from them. Instead, they will ask you to get their expensive packages which have NAT disabled.</p>
<p>One of the good things about Worldlink is that they have made it possible for their customers to communicate with each other inside their NAT network. Every CPE of the Worldlink users get a dynamic NAT IP and all of them can talk to each other. There seems to be no firewall restriction on the CPE or on their branch switches. So if you open a port on one of your devices connected to the CPE, you could ask the ISP to port forward it to their NAT IP.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694767351846/ed594829-c1ac-4c17-8f1a-2e976294a45d.png" alt="CPE NAT IP Looks Something Like This" class="image--center mx-auto" /></p>
<p>For example, here currently I have a NAT IP 100.118.32.150 on my CPE right now. I have router access which was really troublesome to get but I managed to do it somehow. Maybe I will write a blog about it.</p>
<p>You could also get this NAT IP address from your myWorldlink App. It should be on the router details tab. Anyway, once you know the NAT IP. Contact your ISP and tell them to forward a port from the device IP you are exposing to the NAT IP. Here I have exposed a port 8000 using Python's HTTP server.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694767836527/8c83a5ce-9833-486f-8980-b4c7d6d0eb9c.png" alt class="image--center mx-auto" /></p>
<p>Once they forward the port. You can simply access that service through the port that your ISP has forwarded to the NAT IP.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694768130333/67693a6e-4e8d-4f37-801c-552633d7c601.png" alt class="image--center mx-auto" /></p>
<p>You can share your NAT IP with the port to other Worldlink users and they will be able to access it. And the best part of this is the latency is crazy good. Since it's on the same NAT network, you will get around 8-10 ms latency. However, the bandwidth will still be limited to the internet package speed you have subscribed to.</p>
<p>Now we know the basic working process of the port forwarding on the NAT network of the Worldlink. Let's talk about how we are going to use it to play multiplayer games that support Local server or LAN gameplay.</p>
<p>To achieve this you will have to set up a VPN server and forward the server's port to the NAT IP. Once the port is forwarded, other Worldlink users will be able to connect to the VPN and communicate directly with other users connected to the server. This will save some firewall and port forwarding troubles for different games and applications.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694768930504/0fcbdcbb-16e4-4ff7-adcf-d7946e06516b.png" alt class="image--center mx-auto" /></p>
<p>In my case, I have a Linux machine that runs 24/7. It's a low-powered TV Box that I have installed Linux on.</p>
<p>For the VPN Server, I am using <a target="_blank" href="https://www.pivpn.io/">PiVPN</a>. It's really easy to set up and lets you choose between Wirguard and OpenVPN. I recommend you choose OpenVPN as it supports the TAP interface which is really important for LAN multiplayer games.</p>
<p>Once you installed it. There are a few things you need to change to make it workable.</p>
<p>First, edit the OpenVPN server config file which you can find in <code>/etc/openvpn/server.conf</code> . Change as shown in the image below</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694771552657/14165d38-fc05-401a-b9a0-29f942bbca3d.png" alt class="image--center mx-auto" /></p>
<p><code>dev tun</code> to <code>dev tap</code><br /><code>proto udp</code> to <code>port udp6</code></p>
<p>Changing udp to udp6 is something that will make it possible to connect with other ISP users with IPv6. The thing is many of the big ISPs here in Nepal have started deploying IPv6 to their customers, including Worldlink also.</p>
<p>Since IPv6 doesn't have NAT, every device gets its own unique public IPv6 address which can be used to communicate with other IPV6 devices on the internet. It's so easy to expose a port to the internet using IPv6. There is no need for port forwarding, you just expose a port and it's online on the internet. In Worldlink's case, they have not implemented any kind of firewall on their CPE. The only thing that stops or protects your devices with IPv6 addresses from being exposed to the internet is a firewall, which for some reason worldlink has decided to disable on their CPE. Meaning you will have to depend on your own device's firewall.</p>
<p>Currently, while I am writing this, as far as I know, ISPs that have IPv6 fully deployed are Worldlink Communications, Vianet, Classictech, and Dishhome.</p>
<p>But since IPv6 solves everything, why not use it for the connection instead of NAT? For some reason, while using IPv6 the latency goes around 80-90 ms. Looking at the tracert , it's clear that the request goes outside the country making it 80-90 ms. Maybe it can be fixed with some routing config from the ISP side, I don't know.</p>
<p><img src="https://scontent.fktm18-1.fna.fbcdn.net/v/t1.15752-9/376375486_655553159880506_3590366378739308086_n.png?_nc_cat=110&amp;ccb=1-7&amp;_nc_sid=ae9488&amp;_nc_ohc=aajY8glsqFoAX-C2XSK&amp;_nc_ht=scontent.fktm18-1.fna&amp;oh=03_AdTgIhxJ45ltjNZEe59OzlaGl78m-Iz9kGz6T9kP2WxDQg&amp;oe=652BAA9F" alt="No description available." /></p>
<p>The above IPv6 address is from a Vianet user and I get around 70-80 ms latency while doing a ping.</p>
<p>So, using the NAT IP to connect to the VPN server has its benefits but it is limited to the Worldlink users only. The good thing is that the VPN server can be connected using both IP versions, i.e. IPv4 and IPv6.</p>
<p>Leave the proto to udp6 in the server config.</p>
<p>Now we have explained the IPv6 part let's get to the setup process again.</p>
<p>Once you saved the config. Make sure you remember the port you set for the OpenVPN, the default is 1194. Because that is the port you want to forward for the NAT IP. Since I have router access, this is what it looks like when a port is forwarded inside the router. Ask your ISP to do it for you, they have access to your router.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694774657253/756c8ccd-a7e2-4177-bfc8-fe47b550b741.png" alt class="image--center mx-auto" /></p>
<p>Now on your server machine's terminal. Use the command <code>pivpn -a</code> to add a user. Once you add a user, it generates a config file. Get that config file and make some changes based on your connection.<br /><code>dev tap</code><br /><code>proto udp</code><br /><code>remote YOUR_SERVER_IP 1194</code><br /><code>route-nopull</code></p>
<p>Set the dev tun to dev tap</p>
<p>Set the proto to udp6 here only if you are trying to connect to the VPN server using IPV6 address, if you are trying to use NAT IP or IPv4 then leave it as udp</p>
<p>And make sure you add <code>route-nopull</code> . It stops routing of the server network to the users and fixes some IP conflicts as well.</p>
<p>It should look something like this in the image below. I am using a domain name instead of IP. You can do that as well by setting up a DDNS using scripts and automation.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694775355707/06e807f0-62f5-42c3-825a-ebe091e82b9a.png" alt class="image--center mx-auto" /></p>
<p>Once the config file is modified. Download the <a target="_blank" href="https://openvpn.net/community-downloads/">OpenVPN Client</a> program and import the config then connect.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694775667867/d11febc8-72b9-4e6f-b30a-3c7fe706c11b.png" alt class="image--center mx-auto" /></p>
<p>On the server terminal, you can use <code>pivpn -c</code> to view the connected users. Generate the config file for each user.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694775789948/9604624d-da9c-43da-b597-4d151c04b1f1.png" alt class="image--center mx-auto" /></p>
<p>Now start playing your favourite offline LAN multiplayer games with your friends.<br />Some of the games I play with my friends are :</p>
<ul>
<li><p>Far Cry 2</p>
</li>
<li><p>CS Warzone</p>
</li>
<li><p>Torchlight 2</p>
</li>
<li><p>Left 4 Dead 1/2</p>
</li>
<li><p>Need For Speed MW</p>
</li>
<li><p>Line of Sight Vietnam</p>
</li>
<li><p>Halo</p>
</li>
<li><p>Minecraft</p>
</li>
<li><p>etc</p>
</li>
</ul>
<p>Also, make sure to set your OpenVPN's TAP Network Interface metric to a lower value. E.g 10. The lower the value, the more priority the interface will get. Some games without direct IP connection automatically use the interface with higher priority.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1694776446561/854783d7-5937-4fa1-ad8b-5d5c6a90dae9.png" alt class="image--center mx-auto" /></p>
<p>Similarly, you can play games that support offline LAN multiplayer on Android as well. The tricky part on Android devices is getting the TAP interface to work. Fortunately, there is a VPN app called <a target="_blank" href="https://play.google.com/store/apps/details?id=it.colucciweb.vpnclientpro&amp;hl=en">VPN Client Pro</a>, which supports <code>.ovpn</code> config files and makes the process much easier. Just install the app, import the config, and connect. It's that easy. I tested this with BombSquad and Mini Militia. Worked great.</p>
]]></content:encoded></item></channel></rss>