<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Ebrahim Shafiei</title>
    <description>The latest articles on DEV Community by Ebrahim Shafiei (@ebrasha).</description>
    <link>https://dev.to/ebrasha</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3976161%2F64b916eb-0d72-444a-91d3-9e4dcc8e6805.png</url>
      <title>DEV Community: Ebrahim Shafiei</title>
      <link>https://dev.to/ebrasha</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ebrasha"/>
    <language>en</language>
    <item>
      <title>Wireshark Alternative Android</title>
      <dc:creator>Ebrahim Shafiei</dc:creator>
      <pubDate>Sun, 12 Jul 2026 02:48:16 +0000</pubDate>
      <link>https://dev.to/ebrasha/wireshark-alternative-android-d18</link>
      <guid>https://dev.to/ebrasha/wireshark-alternative-android-d18</guid>
      <description>&lt;h2&gt;
  
  
  Wireshark Alternative Android
&lt;/h2&gt;

&lt;p&gt;You need to debug an Android application's network behavior, but you do not want to root the phone, configure a desktop proxy, or rebuild the entire test environment around a laptop.&lt;/p&gt;

&lt;p&gt;This tutorial shows a practical &lt;strong&gt;wireshark alternative android&lt;/strong&gt; workflow using Abdal PacketView. The capture runs on the Android device through &lt;code&gt;VpnService&lt;/code&gt;, traffic can be limited to selected applications, packets can be filtered in real time, and the final session can be exported as PCAPNG for Wireshark or tshark.&lt;/p&gt;

&lt;p&gt;The goal is not to replace every feature in desktop Wireshark. The goal is to make the first half of the investigation easier: collect relevant Android traffic, preserve application context, and hand the capture to a mature desktop analyzer when deeper work is required.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you will build as a workflow
&lt;/h2&gt;

&lt;p&gt;By the end, you will have a repeatable process for:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Capturing Android IP traffic without root.&lt;/li&gt;
&lt;li&gt;Limiting capture to a target application.&lt;/li&gt;
&lt;li&gt;Filtering DNS, HTTPS, UDP, QUIC, addresses, and ports.&lt;/li&gt;
&lt;li&gt;Identifying the Android package associated with traffic.&lt;/li&gt;
&lt;li&gt;Saving a ZIP bundle containing PCAPNG and &lt;code&gt;statistics.json&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Opening the same capture in Wireshark for deeper analysis.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frum4887s648i9wp8qcda.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frum4887s648i9wp8qcda.jpg" alt="Abdal PacketView Wireshark Alternative Android" width="619" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Before you start
&lt;/h2&gt;

&lt;p&gt;You need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An Android device with Abdal PacketView installed.&lt;/li&gt;
&lt;li&gt;A target application that you own or are authorized to test.&lt;/li&gt;
&lt;li&gt;Wireshark or tshark on a desktop if you want offline analysis.&lt;/li&gt;
&lt;li&gt;Enough storage for the capture archive.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You should also disconnect any other active VPN. Android permits only one active VPN service per user or profile, and Abdal PacketView uses &lt;code&gt;VpnService&lt;/code&gt; to create its local capture tunnel.&lt;/p&gt;

&lt;p&gt;Do not capture traffic from devices, accounts, or applications without authorization. Packet captures can contain sensitive metadata and, when protocols are unencrypted, sensitive payload data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Understand what is being captured
&lt;/h2&gt;

&lt;p&gt;Abdal PacketView uses Android's supported VPN API to create a local TUN interface. After you approve the system VPN dialog, Android routes selected IP traffic through that interface.&lt;/p&gt;

&lt;p&gt;Conceptually, the path looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Target Android app
        |
        v
Android VpnService routing
        |
        v
Local TUN interface
        |
        +--&amp;gt; packet metadata decoding
        +--&amp;gt; app attribution
        +--&amp;gt; live filtering
        +--&amp;gt; session statistics
        +--&amp;gt; forwarding
        |
        v
Internet
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A TUN interface works at the IP layer. This means the workflow can inspect routed IPv4 and IPv6 packets, but it is not Wi-Fi monitor mode and does not capture frames from other devices on the network.&lt;/p&gt;

&lt;p&gt;This distinction prevents a common misunderstanding. A &lt;strong&gt;wireshark alternative android&lt;/strong&gt; application based on &lt;code&gt;VpnService&lt;/code&gt; is a local device traffic analyzer, not a passive wireless sniffer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Select the application with App Split
&lt;/h2&gt;

&lt;p&gt;Whole-device captures become noisy quickly. Before starting, open the App Split section and choose the mode that matches your test.&lt;/p&gt;

&lt;p&gt;Use &lt;strong&gt;Route via Tunnel&lt;/strong&gt; when you want only selected applications to enter the capture path. This is usually the best mode for debugging one application.&lt;/p&gt;

&lt;p&gt;Use &lt;strong&gt;Bypass Tunnel&lt;/strong&gt; when you want to capture most device traffic but exclude specific applications.&lt;/p&gt;

&lt;p&gt;For a focused test:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Choose Route via Tunnel.&lt;/li&gt;
&lt;li&gt;Select only the application under test.&lt;/li&gt;
&lt;li&gt;Apply the configuration.&lt;/li&gt;
&lt;li&gt;Return to the Capture screen.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;App Split is not merely a visual filter. It controls which application traffic Android routes through the VPN interface. Display filters, used later, only control which captured packets are shown.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Start a short capture
&lt;/h2&gt;

&lt;p&gt;Tap &lt;strong&gt;Start&lt;/strong&gt; and approve the Android VPN consent dialog.&lt;/p&gt;

&lt;p&gt;Do not immediately browse through several screens or perform many unrelated actions. A useful packet capture is a controlled experiment.&lt;/p&gt;

&lt;p&gt;Use this pattern:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Start capture.&lt;/li&gt;
&lt;li&gt;Perform one action in the target app.&lt;/li&gt;
&lt;li&gt;Wait for success or failure.&lt;/li&gt;
&lt;li&gt;Return to Abdal PacketView.&lt;/li&gt;
&lt;li&gt;Stop capture.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Examples of one-action tests:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sign in once.&lt;/li&gt;
&lt;li&gt;Refresh one data screen.&lt;/li&gt;
&lt;li&gt;Upload one file.&lt;/li&gt;
&lt;li&gt;Send one message.&lt;/li&gt;
&lt;li&gt;Trigger one synchronization attempt.&lt;/li&gt;
&lt;li&gt;Reproduce one API timeout.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A 20-second capture with a precise purpose is often more useful than a 20-minute capture filled with background traffic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Filter the packet table
&lt;/h2&gt;

&lt;p&gt;Abdal PacketView documents Wireshark-style display filters for protocols, fields, comparison operators, containment, Boolean logic, and parentheses.&lt;/p&gt;

&lt;p&gt;Start with simple filters.&lt;/p&gt;

&lt;h3&gt;
  
  
  Find DNS traffic
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;udp &amp;amp;&amp;amp; port == 53
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use this when the application cannot resolve a hostname, connects to an unexpected resolver, or appears to stall before establishing a connection.&lt;/p&gt;

&lt;h3&gt;
  
  
  Find traffic involving a specific IP address
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ip.addr == 8.8.8.8
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace the address with the endpoint you are investigating.&lt;/p&gt;

&lt;h3&gt;
  
  
  Find HTTPS-related flows
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This helps locate encrypted web traffic. It does not decrypt TLS payloads.&lt;/p&gt;

&lt;h3&gt;
  
  
  Combine conditions
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;tcp &amp;amp;&amp;amp; port == 443 &amp;amp;&amp;amp; frame.len &amp;gt; 500
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use combined conditions to reduce the table to the flows that matter.&lt;/p&gt;

&lt;p&gt;The syntax is described as Wireshark-style, not necessarily a complete implementation of every Wireshark display-filter field and function. Treat the application's built-in help as the source of truth for supported expressions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Use app attribution
&lt;/h2&gt;

&lt;p&gt;A capture from a phone may include traffic from several sources. Abdal PacketView documents UID-based attribution that associates connections with an application name and package name.&lt;/p&gt;

&lt;p&gt;When reviewing a suspicious endpoint, verify the application identity instead of assuming that every packet belongs to the foreground app.&lt;/p&gt;

&lt;p&gt;This is useful when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Several applications use the same cloud provider.&lt;/li&gt;
&lt;li&gt;The operating system creates background connections.&lt;/li&gt;
&lt;li&gt;An SDK sends telemetry independently of the main API flow.&lt;/li&gt;
&lt;li&gt;A test device contains unrelated messaging or synchronization apps.&lt;/li&gt;
&lt;li&gt;A package contacts an undocumented endpoint.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Application attribution is one of the main reasons this workflow is more practical than a generic packet dump.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 6: Save the capture
&lt;/h2&gt;

&lt;p&gt;Use &lt;strong&gt;Save Capture&lt;/strong&gt; after the test is complete.&lt;/p&gt;

&lt;p&gt;The documented output is a ZIP package with this structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Abdal_PacketView_&amp;lt;timestamp&amp;gt;.zip
├── Abdal_PacketView_&amp;lt;timestamp&amp;gt;.pcapng
└── statistics.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The PCAPNG file stores the packet capture for Wireshark and tshark. The JSON file stores a session summary such as packet count, captured data size, duration, generation time, and active App Split mode.&lt;/p&gt;

&lt;p&gt;The project also states that application attribution can be carried in custom PCAPNG options identified by IANA Private Enterprise Number 66033 for Abdal Security Group. PCAPNG supports custom options associated with a Private Enterprise Number, allowing Android-specific metadata to accompany standard packet data.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fq5fbk9eusaa05anpm3ui.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fq5fbk9eusaa05anpm3ui.png" alt="Wireshark Alternative Android - Abdal PacketView PCAPNG file opened and analyzed in Wireshark" width="800" height="445"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 7: Open the capture in Wireshark
&lt;/h2&gt;

&lt;p&gt;Move the ZIP archive to your workstation and extract it. Open the &lt;code&gt;.pcapng&lt;/code&gt; file in Wireshark.&lt;/p&gt;

&lt;p&gt;At this stage, you can use the larger desktop toolset for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Detailed protocol trees.&lt;/li&gt;
&lt;li&gt;TCP stream analysis.&lt;/li&gt;
&lt;li&gt;Packet timing and retransmission analysis.&lt;/li&gt;
&lt;li&gt;Advanced display filters.&lt;/li&gt;
&lt;li&gt;Endpoint and conversation statistics.&lt;/li&gt;
&lt;li&gt;I/O graphs.&lt;/li&gt;
&lt;li&gt;Exporting selected packet ranges.&lt;/li&gt;
&lt;li&gt;TLS decryption when you have authorized session secrets.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A simple command-line verification with tshark is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# -------------------------------------------------------------------&lt;/span&gt;
&lt;span class="c"&gt;# Programmer       : Ebrahim Shafiei (EbraSha)&lt;/span&gt;
&lt;span class="c"&gt;# Email            : Prof.Shafiei@Gmail.com&lt;/span&gt;
&lt;span class="c"&gt;# -------------------------------------------------------------------&lt;/span&gt;

tshark &lt;span class="nt"&gt;-r&lt;/span&gt; Abdal_PacketView_&amp;lt;timestamp&amp;gt;.pcapng &lt;span class="nt"&gt;-c&lt;/span&gt; 20
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To inspect DNS packets:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# -------------------------------------------------------------------&lt;/span&gt;
&lt;span class="c"&gt;# Programmer       : Ebrahim Shafiei (EbraSha)&lt;/span&gt;
&lt;span class="c"&gt;# Email            : Prof.Shafiei@Gmail.com&lt;/span&gt;
&lt;span class="c"&gt;# -------------------------------------------------------------------&lt;/span&gt;

tshark &lt;span class="nt"&gt;-r&lt;/span&gt; Abdal_PacketView_&amp;lt;timestamp&amp;gt;.pcapng &lt;span class="nt"&gt;-Y&lt;/span&gt; &lt;span class="s2"&gt;"dns"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To list traffic involving a known address:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# -------------------------------------------------------------------&lt;/span&gt;
&lt;span class="c"&gt;# Programmer       : Ebrahim Shafiei (EbraSha)&lt;/span&gt;
&lt;span class="c"&gt;# Email            : Prof.Shafiei@Gmail.com&lt;/span&gt;
&lt;span class="c"&gt;# -------------------------------------------------------------------&lt;/span&gt;

tshark &lt;span class="nt"&gt;-r&lt;/span&gt; Abdal_PacketView_&amp;lt;timestamp&amp;gt;.pcapng &lt;span class="nt"&gt;-Y&lt;/span&gt; &lt;span class="s2"&gt;"ip.addr == 203.0.113.10"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace the placeholder filename and test address with values from your capture.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 8: Read &lt;code&gt;statistics.json&lt;/code&gt; as test context
&lt;/h2&gt;

&lt;p&gt;Do not ignore the JSON file. Packet captures answer what happened on the wire, while session metadata helps explain the conditions under which the capture was created.&lt;/p&gt;

&lt;p&gt;A conceptual structure might resemble this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"packetCount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1240&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"capturedBytes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;987654&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"durationSeconds"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"appSplitMode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"route_via_tunnel"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"generatedAt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-07-12T10:30:00Z"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This example is illustrative. Use the actual fields generated by your installed version of Abdal PacketView rather than assuming an undocumented schema.&lt;/p&gt;

&lt;p&gt;For bug reports, include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The action that was performed.&lt;/li&gt;
&lt;li&gt;The expected result.&lt;/li&gt;
&lt;li&gt;The actual result.&lt;/li&gt;
&lt;li&gt;The capture start and stop conditions.&lt;/li&gt;
&lt;li&gt;The selected App Split mode.&lt;/li&gt;
&lt;li&gt;The display filter used during review.&lt;/li&gt;
&lt;li&gt;The PCAPNG file.&lt;/li&gt;
&lt;li&gt;The original &lt;code&gt;statistics.json&lt;/code&gt; file.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That creates a more reproducible diagnostic package than a screenshot of an error message alone.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this workflow can reveal
&lt;/h2&gt;

&lt;p&gt;Even when application payloads are encrypted, the capture can reveal useful behavior:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;DNS queries and responses.&lt;/li&gt;
&lt;li&gt;Destination IP addresses and ports.&lt;/li&gt;
&lt;li&gt;TCP connection attempts and resets.&lt;/li&gt;
&lt;li&gt;UDP and QUIC usage.&lt;/li&gt;
&lt;li&gt;Retry patterns.&lt;/li&gt;
&lt;li&gt;Packet sizes and timing.&lt;/li&gt;
&lt;li&gt;Connections to unexpected infrastructure.&lt;/li&gt;
&lt;li&gt;The Android package responsible for a flow.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, an application timeout may be caused by DNS failure, unreachable IPv6 routing, repeated TCP retransmissions, a QUIC fallback, or a connection to an obsolete endpoint. You do not always need decrypted payloads to identify the failing layer.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this workflow cannot do
&lt;/h2&gt;

&lt;p&gt;A technically accurate &lt;strong&gt;wireshark alternative android&lt;/strong&gt; tutorial should also cover the limits.&lt;/p&gt;

&lt;p&gt;Abdal PacketView does not turn a normal phone into a Wi-Fi monitor-mode adapter. It does not capture traffic from nearby devices. It does not automatically decrypt TLS or QUIC payloads. It does not reproduce every Wireshark dissector, graph, statistic, or expert-analysis feature on Android.&lt;/p&gt;

&lt;p&gt;It also uses the Android VPN slot. If another VPN is active, the two services normally cannot operate simultaneously for the same user or profile.&lt;/p&gt;

&lt;p&gt;These limitations are expected for a no-root, &lt;code&gt;VpnService&lt;/code&gt;-based architecture.&lt;/p&gt;

&lt;h2&gt;
  
  
  A debugging checklist
&lt;/h2&gt;

&lt;p&gt;Use this checklist for your next mobile network issue:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Confirm that you are authorized to capture the traffic.&lt;/li&gt;
&lt;li&gt;[ ] Disconnect another active VPN.&lt;/li&gt;
&lt;li&gt;[ ] Select the target application with App Split.&lt;/li&gt;
&lt;li&gt;[ ] Start capture immediately before the test action.&lt;/li&gt;
&lt;li&gt;[ ] Reproduce only one issue.&lt;/li&gt;
&lt;li&gt;[ ] Stop capture immediately afterward.&lt;/li&gt;
&lt;li&gt;[ ] Filter by protocol, endpoint, or port.&lt;/li&gt;
&lt;li&gt;[ ] Verify the attributed package.&lt;/li&gt;
&lt;li&gt;[ ] Save the ZIP archive.&lt;/li&gt;
&lt;li&gt;[ ] Keep &lt;code&gt;statistics.json&lt;/code&gt; with the PCAPNG file.&lt;/li&gt;
&lt;li&gt;[ ] Continue advanced analysis in Wireshark or tshark.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Abdal PacketView provides a practical &lt;strong&gt;wireshark alternative android&lt;/strong&gt; capture workflow for developers, QA engineers, network analysts, students, and authorized security researchers.&lt;/p&gt;

&lt;p&gt;Its value comes from combining Android's supported &lt;code&gt;VpnService&lt;/code&gt; and TUN model with live packet metadata, UID-based application attribution, App Split routing, familiar filters, session statistics, and PCAPNG export.&lt;/p&gt;

&lt;p&gt;The phone handles collection and first-pass triage. Wireshark handles deep offline analysis. Instead of forcing one tool to do everything, the workflow uses each environment for what it does best.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Does Abdal PacketView require root?
&lt;/h3&gt;

&lt;p&gt;No. Its documented architecture uses Android &lt;code&gt;VpnService&lt;/code&gt; and requires approval through the system VPN consent dialog.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is it a full Wireshark port for Android?
&lt;/h3&gt;

&lt;p&gt;No. It is an on-device packet capture and traffic-analysis tool with Wireshark-style filtering and PCAPNG export. Wireshark remains more capable for deep desktop analysis.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I capture only one Android application?
&lt;/h3&gt;

&lt;p&gt;The App Split Route via Tunnel mode is designed to route selected applications through the capture tunnel.&lt;/p&gt;

&lt;h3&gt;
  
  
  What files are exported?
&lt;/h3&gt;

&lt;p&gt;The documented ZIP bundle contains a &lt;code&gt;.pcapng&lt;/code&gt; capture and a &lt;code&gt;statistics.json&lt;/code&gt; session summary.&lt;/p&gt;

&lt;h2&gt;
  
  
  Project Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/ebrasha/abdal-packetview" rel="noopener noreferrer"&gt;https://github.com/ebrasha/abdal-packetview&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Developer
&lt;/h2&gt;

&lt;p&gt;Abdal PacketView was designed and developed by &lt;strong&gt;Ebrahim Shafiei (EbraSha)&lt;/strong&gt;, a software developer and cybersecurity researcher focused on network analysis, security engineering, and open-source tools.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/ebrasha" rel="noopener noreferrer"&gt;https://github.com/ebrasha&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Telegram: &lt;a href="https://t.me/ProfShafiei" rel="noopener noreferrer"&gt;https://t.me/ProfShafiei&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;LinkedIn: &lt;a href="https://www.linkedin.com/in/profshafiei/" rel="noopener noreferrer"&gt;https://www.linkedin.com/in/profshafiei/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;X: &lt;a href="https://x.com/ProfShafiei" rel="noopener noreferrer"&gt;https://x.com/ProfShafiei&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Email: &lt;a href="mailto:Prof.Shafiei@Gmail.com"&gt;Prof.Shafiei@Gmail.com&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>android</category>
      <category>wireshark</category>
      <category>security</category>
      <category>hackathon</category>
    </item>
    <item>
      <title>Android Packet Capture Without Root Using Abdal PacketView</title>
      <dc:creator>Ebrahim Shafiei</dc:creator>
      <pubDate>Mon, 06 Jul 2026 02:49:28 +0000</pubDate>
      <link>https://dev.to/ebrasha/android-packet-capture-without-root-using-abdal-packetview-3d51</link>
      <guid>https://dev.to/ebrasha/android-packet-capture-without-root-using-abdal-packetview-3d51</guid>
      <description>&lt;h1&gt;
  
  
  Android Packet Capture Without Root Using Abdal PacketView
&lt;/h1&gt;

&lt;p&gt;If you have ever tried to inspect Android traffic the same way you inspect desktop traffic, you already know the pain.&lt;/p&gt;

&lt;p&gt;On desktop, Wireshark is usually the obvious answer. On Android, packet capture often turns into a setup problem before it becomes an analysis problem. Do you root the device? Do you proxy traffic? Do you route everything through a computer? Do you accept that some UDP or non-HTTP behavior will be harder to inspect?&lt;/p&gt;

&lt;p&gt;Abdal PacketView takes a more direct route: it performs Android packet capture on the device itself using Android &lt;code&gt;VpnService&lt;/code&gt; and a local TUN interface. No root. No external capture server. No desktop proxy required.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqlv7ge1z16tbcer1g5yx.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqlv7ge1z16tbcer1g5yx.jpg" alt=" " width="799" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Project Author, Source Code and Download
&lt;/h2&gt;

&lt;p&gt;Abdal PacketView is designed, developed and maintained by &lt;strong&gt;Ebrahim Shafiei (EbraSha)&lt;/strong&gt;, the programmer behind the project and Head of Abdal Security Group.&lt;/p&gt;

&lt;p&gt;This project was built to give Android users, developers, security researchers and network analysts a practical packet capture workflow directly on Android, without root access and without relying on an external capture server or desktop proxy.&lt;/p&gt;

&lt;p&gt;The source code, latest releases, project documentation and download information are available on GitHub:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Download and Source Code:&lt;/strong&gt; &lt;a href="https://github.com/ebrasha/abdal-packetview" rel="noopener noreferrer"&gt;Abdal PacketView on GitHub&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you find the project useful, you can support its growth by starring the repository, sharing it with other developers, reporting issues, or contributing improvements.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Abdal PacketView Does
&lt;/h2&gt;

&lt;p&gt;Abdal PacketView is an Android network packet capture and traffic analysis tool. It captures raw IP packets locally, decodes network metadata, shows packets in a live interface, and exports captures in PCAPNG format for tools like Wireshark and tshark.&lt;/p&gt;

&lt;p&gt;The core workflow looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Start capture
Approve Android VPN consent
Use the device normally
Inspect packets live
Apply filters
Save capture
Open PCAPNG in Wireshark or tshark
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes it useful for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Android developers debugging app traffic&lt;/li&gt;
&lt;li&gt;Security researchers reviewing suspicious connections&lt;/li&gt;
&lt;li&gt;QA engineers collecting network evidence&lt;/li&gt;
&lt;li&gt;Network analysts inspecting mobile behavior&lt;/li&gt;
&lt;li&gt;Advanced users learning real protocol behavior&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How the Capture Works
&lt;/h2&gt;

&lt;p&gt;The app uses Android &lt;code&gt;VpnService&lt;/code&gt; to create a local TUN interface. After the user approves the VPN consent dialog, traffic can pass through that local capture path.&lt;/p&gt;

&lt;p&gt;Conceptually, the flow is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;App traffic
  -&amp;gt; VpnService
  -&amp;gt; Local TUN interface
  -&amp;gt; Packet capture
  -&amp;gt; Metadata decoding
  -&amp;gt; App attribution
  -&amp;gt; Live table and export
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This architecture is important because it avoids root access while still giving practical packet visibility. The README lists decoding support for IPv4, IPv6, TCP, UDP, and ICMP traffic.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffbe7omiw5sc2qlbl8dml.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffbe7omiw5sc2qlbl8dml.jpg" alt=" " width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Is Useful
&lt;/h2&gt;

&lt;p&gt;A proxy is not the same thing as packet capture. Proxies are excellent for some HTTP and HTTPS debugging workflows, but they do not give the same general packet-level view.&lt;/p&gt;

&lt;p&gt;Abdal PacketView is closer to a mobile capture companion for Wireshark. It captures traffic where the traffic happens, then exports the result for deeper analysis.&lt;/p&gt;

&lt;p&gt;The app saves captures as a ZIP package containing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Abdal_PacketView_&amp;lt;timestamp&amp;gt;.pcapng
statistics.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;.pcapng&lt;/code&gt; file is compatible with Wireshark and tshark. The &lt;code&gt;statistics.json&lt;/code&gt; file stores session data such as packet count, captured data size, duration, generation time, and active App Split mode.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Start a Capture
&lt;/h2&gt;

&lt;p&gt;Open Abdal PacketView and go to the Capture tab. Tap Start and approve the Android VPN consent dialog.&lt;/p&gt;

&lt;p&gt;Once capture is active, use your Android device normally. Packets appear in the live capture table as traffic is generated.&lt;/p&gt;

&lt;p&gt;This is the key advantage of the tool: the capture happens inside the mobile workflow instead of forcing the workflow to move to a desktop setup.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Inspect Packets
&lt;/h2&gt;

&lt;p&gt;Tap a packet row to inspect decoded details. This gives you a closer look at the traffic metadata.&lt;/p&gt;

&lt;p&gt;The app can decode common network layers and protocols listed in the README:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;IPv4
IPv6
TCP
UDP
ICMP
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For Android app testing, that is enough to answer many practical questions: which endpoints are contacted, what protocol is used, whether UDP is active, whether DNS-like traffic appears, and how traffic changes during a specific action.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F08w80ta906mvyc5bf3cc.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F08w80ta906mvyc5bf3cc.jpg" alt=" " width="800" height="1678"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Use Filters
&lt;/h2&gt;

&lt;p&gt;Abdal PacketView supports Wireshark-style display filters for protocols, fields, ports, packet length, and Boolean logic.&lt;/p&gt;

&lt;p&gt;Example filters:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https
udp &amp;amp;&amp;amp; port == 53
ip.addr == 8.8.8.8
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is especially helpful because Android traffic can get noisy very quickly. Filtering lets you move from “everything the device is doing” to “the exact traffic I care about.”&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Use App Split Tunnel
&lt;/h2&gt;

&lt;p&gt;The app includes App Split Tunnel with two modes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Route via Tunnel
Bypass Tunnel
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Route via Tunnel is useful when you want to capture selected apps. Bypass Tunnel is useful when you want to exclude selected apps.&lt;/p&gt;

&lt;p&gt;For example, if you are testing one Android app, you can focus on that app instead of capturing unrelated background traffic. If another app is creating too much noise, you can bypass it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Export for Wireshark
&lt;/h2&gt;

&lt;p&gt;When you save a capture, Abdal PacketView creates a ZIP package with the PCAPNG file and &lt;code&gt;statistics.json&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This export step is what makes the tool fit into a professional workflow. You can capture traffic on Android, then continue analysis in Wireshark or tshark.&lt;/p&gt;

&lt;p&gt;The project also uses custom PCAPNG options under IANA Private Enterprise Number 66033 registered for Abdal Security Group. This is used for project-specific metadata, including app attribution context.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Makes It Different
&lt;/h2&gt;

&lt;p&gt;The strongest feature set is the combination:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No-root Android packet capture&lt;/li&gt;
&lt;li&gt;Local &lt;code&gt;VpnService&lt;/code&gt; and TUN interface workflow&lt;/li&gt;
&lt;li&gt;Internet connectivity preservation during capture&lt;/li&gt;
&lt;li&gt;IPv4, IPv6, TCP, UDP, and ICMP decoding&lt;/li&gt;
&lt;li&gt;UID-based app attribution&lt;/li&gt;
&lt;li&gt;App Split Tunnel modes&lt;/li&gt;
&lt;li&gt;Wireshark-style display filters&lt;/li&gt;
&lt;li&gt;PCAPNG export with session statistics&lt;/li&gt;
&lt;li&gt;Kotlin and Jetpack Compose UI&lt;/li&gt;
&lt;li&gt;Built-in Help Center and Proto Tuts+ learning content&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Individually, some of these features are useful. Together, they create a serious Android packet capture workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Abdal PacketView should not be described as a full Wireshark clone. That is not the right framing. Wireshark remains the deeper desktop packet analysis tool.&lt;/p&gt;

&lt;p&gt;The better framing is this: Abdal PacketView brings practical Android packet capture to the device itself and then exports clean PCAPNG files for Wireshark and tshark.&lt;/p&gt;

&lt;p&gt;For developers, hackers, security researchers, and network analysts who need packet-level visibility on Android without root, Abdal PacketView is a strong and practical tool.&lt;/p&gt;

&lt;h2&gt;
  
  
  Project Author, Source Code and Download
&lt;/h2&gt;

&lt;p&gt;Abdal PacketView is designed, developed and maintained by &lt;strong&gt;Ebrahim Shafiei (EbraSha)&lt;/strong&gt;, the programmer behind the project and Head of Abdal Security Group.&lt;/p&gt;

&lt;p&gt;This project was built to give Android users, developers, security researchers and network analysts a practical packet capture workflow directly on Android, without root access and without relying on an external capture server or desktop proxy.&lt;/p&gt;

&lt;p&gt;The source code, latest releases, project documentation and download information are available on GitHub:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Download and Source Code:&lt;/strong&gt; &lt;a href="https://github.com/ebrasha/abdal-packetview" rel="noopener noreferrer"&gt;Abdal PacketView on GitHub&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you find the project useful, you can support its growth by starring the repository, sharing it with other developers, reporting issues, or contributing improvements.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Does Abdal PacketView require root?
&lt;/h3&gt;

&lt;p&gt;No. It uses Android &lt;code&gt;VpnService&lt;/code&gt; and a local TUN interface.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I use the exported file in Wireshark?
&lt;/h3&gt;

&lt;p&gt;Yes. The capture is exported as &lt;code&gt;.pcapng&lt;/code&gt;, which is compatible with Wireshark and tshark.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can it show which app generated a packet?
&lt;/h3&gt;

&lt;p&gt;Yes. It supports UID-based app attribution with app name and package name metadata.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is this only for security researchers?
&lt;/h3&gt;

&lt;p&gt;No. It is also useful for Android developers, QA engineers, network analysts, and advanced users.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is it a full Wireshark replacement?
&lt;/h3&gt;

&lt;p&gt;No. It is better described as an Android packet capture tool that works with Wireshark-style workflows and PCAPNG export.&lt;/p&gt;

</description>
      <category>wireshark</category>
      <category>android</category>
      <category>cybersecurity</category>
      <category>networking</category>
    </item>
    <item>
      <title>One Binary to Manage an SSH Tunnel Server: Abdal 4iProto Panel</title>
      <dc:creator>Ebrahim Shafiei</dc:creator>
      <pubDate>Tue, 09 Jun 2026 22:49:40 +0000</pubDate>
      <link>https://dev.to/ebrasha/one-binary-to-manage-an-ssh-tunnel-server-abdal-4iproto-panel-1ndm</link>
      <guid>https://dev.to/ebrasha/one-binary-to-manage-an-ssh-tunnel-server-abdal-4iproto-panel-1ndm</guid>
      <description>&lt;h2&gt;
  
  
  Why a single binary matters for tunnel administration
&lt;/h2&gt;

&lt;p&gt;If you have ever stood up an SSH tunnel server on a fresh VPS, you know the real cost is not the server—it is everything around it. You need a way to add and revoke users, cap their bandwidth, watch sessions in real time, block abusive IPs, and survive a reboot without a 12-step runbook. The usual answer is a stack: a runtime, a web framework, a database, a reverse proxy, a process manager. Each layer is one more thing that breaks at 2 a.m.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Abdal 4iProto Panel&lt;/strong&gt; takes the opposite bet. It is a web-based management interface for the &lt;a href="https://github.com/ebrasha/abdal-4iproto-server" rel="noopener noreferrer"&gt;Abdal 4iProto Server&lt;/a&gt;—a dedicated SSH tunnel server—written in &lt;strong&gt;Go&lt;/strong&gt; and compiled to a &lt;strong&gt;single executable with embedded resources&lt;/strong&gt;. CSS, JS, HTML templates, and translation files all live inside the binary. There is no runtime to install, no external dependency to pin, no asset directory to ship. You drop one file on Windows or Linux, optionally register it as a service, and you have a full admin console. This article walks through how it is built and how an expert operator would actually use it.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;🔗 &lt;strong&gt;Panel repo:&lt;/strong&gt; &lt;a href="https://github.com/ebrasha/abdal-4iproto-panel" rel="noopener noreferrer"&gt;https://github.com/ebrasha/abdal-4iproto-panel&lt;/a&gt;&lt;br&gt;
🔗 &lt;strong&gt;Server repo:&lt;/strong&gt; &lt;a href="https://github.com/ebrasha/abdal-4iproto-server" rel="noopener noreferrer"&gt;https://github.com/ebrasha/abdal-4iproto-server&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The architecture in one sentence
&lt;/h2&gt;

&lt;p&gt;The panel is a Go process that embeds its own web assets, persists configuration as flat JSON files, talks to the 4iProto SSH tunnel server it manages, and can run as a Windows Service or a Linux &lt;code&gt;systemd&lt;/code&gt; unit. That is the whole shape of it—and the simplicity is the point.&lt;/p&gt;

&lt;p&gt;Configuration lives in plain JSON, not a database engine. On first run the panel writes &lt;code&gt;abdal-4iproto-panel.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;52202&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"username"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ebrasha"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"password"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ebrasha1309"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"logging"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"blocked_ips"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"max_login_attempts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"login_attempt_window"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"block_duration"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3600&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a tunnel management surface, JSON state is a defensible choice: the data set (users, blocked IPs, server config) is small, human-auditable, trivially backed up with &lt;code&gt;cp&lt;/code&gt;, and never introduces a separate failure domain. You can inspect or diff the live state with tools you already have. Note the SSH-native footprint of the install set, too—&lt;code&gt;id_ed25519&lt;/code&gt; and &lt;code&gt;id_ed25519.pub&lt;/code&gt; ship alongside the binaries, since the server is doing real SSH tunneling.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ Change &lt;code&gt;ebrasha1309&lt;/code&gt; immediately after first login. Defaults are for first boot, not production.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The administrative workflow
&lt;/h2&gt;

&lt;p&gt;Point a browser at &lt;code&gt;http://localhost:52202&lt;/code&gt; (or your configured port), authenticate, and you land on a dashboard summarizing users, sessions, and traffic. From there the work is organized around the lifecycle of a tunnel deployment rather than a flat settings dump.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;User provisioning&lt;/strong&gt; is full CRUD, but the interesting part is per-user policy. Each account carries far more than a username and password: a role (&lt;code&gt;admin&lt;/code&gt;/&lt;code&gt;user&lt;/code&gt;), blocked domains and IPs scoped to that user, concurrent session limits and TTL, a speed cap in KB/s, a traffic quota in MB, and individual logging preferences. This is enough to run differentiated tiers—a throttled trial account and an uncapped admin account—without touching the server binary.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Server configuration&lt;/strong&gt; is edited from the same UI: listening ports (multiple are supported), the default shell for Windows/Linux targets, the maximum authentication attempts, and even the server's advertised version signature. The panel writes these to the server's config and the change takes effect on the managed service.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Security&lt;/strong&gt; is handled at two layers. There is straightforward IP blocking, and there is an automatic brute-force defense with a configurable attempt ceiling, a sliding time window, and a block duration. Cross the threshold inside the window and the offending IP is blocked automatically for the configured period—no manual intervention.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Monitoring&lt;/strong&gt; is where an operator spends real time. User access logs update over Ajax without a full page reload. Traffic monitoring tracks consumption per user—session-based and cumulative—and surfaces warnings as accounts approach their quota. The sessions view reflects live state from the server: session ID, username, source IP, client version, creation time, and last-seen timestamp, with the ability to revoke a session.&lt;/p&gt;

&lt;p&gt;The whole console is bilingual (English and Persian), responsive down to a mobile hamburger menu, and—because configuration changes can require a clean reload—the panel &lt;strong&gt;auto-restarts its own service&lt;/strong&gt; after you save, so applied settings are never half-live.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Telegram bot: a study in isolation
&lt;/h2&gt;

&lt;p&gt;The feature most worth dissecting is the optional Telegram bot, which mirrors every administrative action from the web UI. Enabling it is a config flow: create a bot via &lt;code&gt;@BotFather&lt;/code&gt;, grab your numeric ID from &lt;code&gt;@userinfobot&lt;/code&gt;, then in &lt;strong&gt;Panel Configuration → 🤖 Telegram Bot&lt;/strong&gt; tick enable, paste the token, and list admin IDs. Settings persist under a &lt;code&gt;telegram_bot&lt;/code&gt; key:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"telegram_bot"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"enabled"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"token"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"123456789:AA...your-bot-token"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"admins"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;111111111&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;222222222&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The security model is deliberately blunt: the bot drops every update that does not originate from an admin Telegram ID and replies with a short "not authorized" message, so an attacker cannot silently probe behavior.&lt;/p&gt;

&lt;p&gt;What makes the bot worth studying is its concurrency design. It is not a side thread bolted onto the request handler—it is a &lt;strong&gt;fully isolated subsystem&lt;/strong&gt; inside the panel process, with its own HTTP connection pool, dispatcher worker pool, asynchronous log channel, and a debounced restart queue. The explicit goal: a busy panel UI or slow disk I/O can never slow the bot down. The update pipeline:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────────────────────┐      ┌──────────────────────┐
│ Telegram getUpdates     │ ───► │ updates channel      │
│ (1 goroutine)           │      │ (cap 1024)           │
└─────────────────────────┘      └──────────┬───────────┘
                                            │
                          ┌─────────────────┼─────────────────┐
                          ▼                 ▼                 ▼
                   ┌──────────┐      ┌──────────┐      ┌──────────┐
                   │ worker 1 │ ...  │ worker N │      │ worker N │ (NumCPU*2, ≥8)
                   └────┬─────┘      └────┬─────┘      └────┬─────┘
                        │                 │                 │
                        ▼ (go r(ctx,b,u)) ▼                 ▼
                   ┌────────────────────────────────────────────┐
                   │ Per-handler goroutine                       │
                   │  → trackerMiddleware (WaitGroup +1)         │
                   │  → adminOnly                                │
                   │  → recover                                  │
                   │  → handler (sendText via HTTP/2 conn pool)  │
                   └────────────────────────────────────────────┘
                        │
                        ▼ (svc.Info/Warning/Error)
                   ┌────────────────┐
                   │ async log chan │ ──► dedicated writer ──► panelLogger
                   │ (cap 1024)     │
                   └────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A single goroutine long-polls &lt;code&gt;getUpdates&lt;/code&gt; and pushes into a buffered channel (capacity 1024). A worker pool sized at &lt;code&gt;NumCPU*2&lt;/code&gt; (floor of 8) drains it. Each update spawns a per-handler goroutine wrapped in a middleware chain: a &lt;code&gt;trackerMiddleware&lt;/code&gt; that increments a &lt;code&gt;WaitGroup&lt;/code&gt; for clean shutdown, an &lt;code&gt;adminOnly&lt;/code&gt; gate, a &lt;code&gt;recover&lt;/code&gt; so one panicking handler never takes down the pool, and finally the handler itself sending replies through the shared HTTP/2 connection pool. Logging is fire-and-forget into another 1024-cap channel drained by a dedicated writer—so logging never blocks a handler. This is textbook Go: bounded channels for backpressure, a fixed worker pool to cap concurrency, &lt;code&gt;recover&lt;/code&gt; per goroutine for fault isolation, and a &lt;code&gt;WaitGroup&lt;/code&gt; for graceful drain.&lt;/p&gt;

&lt;p&gt;The command surface is registered automatically via &lt;code&gt;SetMyCommands&lt;/code&gt;, so everything shows up in Telegram's &lt;code&gt;/&lt;/code&gt; menu. Highlights:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/start&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Start the bot; first-time users pick a language (🇬🇧 / 🇮🇷).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;/menu&lt;/code&gt;, &lt;code&gt;/help&lt;/code&gt;, &lt;code&gt;/cancel&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Navigation and flow control.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;/users&lt;/code&gt;, &lt;code&gt;/adduser&lt;/code&gt;, &lt;code&gt;/adduser_interactive&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Paginated user list; quick or step-by-step user creation.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/server&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;View/edit server config field by field.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;/blockedips&lt;/code&gt;, &lt;code&gt;/blockedaccess&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Manage blocked IPs and browse blocked-access logs.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/logs&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Browse access logs (last 20 per user).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;/traffic&lt;/code&gt;, &lt;code&gt;/sessions&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Per-user traffic; list and revoke sessions.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;/restart_server&lt;/code&gt;, &lt;code&gt;/restart_panel&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Restart either service, with confirmation.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Build and deploy
&lt;/h2&gt;

&lt;p&gt;From source you need Go 1.21+:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/ebrasha/abdal-4iproto-panel.git
&lt;span class="nb"&gt;cd &lt;/span&gt;abdal-4iproto-panel
go build &lt;span class="nt"&gt;-o&lt;/span&gt; abdal-4iproto-panel main.go      &lt;span class="c"&gt;# Linux&lt;/span&gt;
go build &lt;span class="nt"&gt;-o&lt;/span&gt; abdal-4iproto-panel.exe main.go  &lt;span class="c"&gt;# Windows&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As a service, the binary self-registers. On Windows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;abdal-4iproto-panel.exe install
abdal-4iproto-panel.exe start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On Linux with &lt;code&gt;systemd&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo&lt;/span&gt; ./install-abdal-4iproto-panel.sh
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;abdal-4iproto-panel
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl status abdal-4iproto-panel
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a hands-off setup, the &lt;a href="https://github.com/ebrasha/abdal-4iproto-cli" rel="noopener noreferrer"&gt;Abdal 4iProto Cli&lt;/a&gt; detects your OS/architecture, verifies SHA-256 checksums, configures ports, generates SSH keys, and registers persistent services.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Does the panel need a database?&lt;/strong&gt; No. State is stored in flat JSON files, which keeps deployment to a single binary and makes backups a file copy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I cap individual users?&lt;/strong&gt; Yes—per-user speed limits (KB/s), traffic quotas (MB), session limits, and TTL are all configurable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is the Telegram bot safe to expose?&lt;/strong&gt; It only accepts updates from explicitly listed admin IDs and rejects everything else. Treat the token like a secret and restrict admins tightly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Windows and Linux both?&lt;/strong&gt; Yes—single binary per platform, installable as a Windows Service or a Linux &lt;code&gt;systemd&lt;/code&gt; unit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing thought
&lt;/h2&gt;

&lt;p&gt;The design philosophy behind Abdal 4iProto Panel is that operational tooling should reduce moving parts, not add them. One binary, embedded assets, JSON state, and a concurrency model that isolates the bot from the UI—each decision trades novelty for fewer 2 a.m. surprises.&lt;/p&gt;

&lt;p&gt;Handcrafted with passion by &lt;strong&gt;Ebrahim Shafiei (EbraSha)&lt;/strong&gt; — 📧 &lt;a href="mailto:Prof.Shafiei@Gmail.com"&gt;Prof.Shafiei@Gmail.com&lt;/a&gt; · ✈️ &lt;a href="https://t.me/ProfShafiei" rel="noopener noreferrer"&gt;@ProfShafiei&lt;/a&gt;&lt;/p&gt;

</description>
      <category>go</category>
      <category>vpn</category>
      <category>4iproto</category>
      <category>ssh</category>
    </item>
    <item>
      <title>Build a Self-Hosted SSH Tunneling Server with Per-User Accounting (Abdal 4iProto)</title>
      <dc:creator>Ebrahim Shafiei</dc:creator>
      <pubDate>Tue, 09 Jun 2026 22:02:29 +0000</pubDate>
      <link>https://dev.to/ebrasha/build-a-self-hosted-ssh-tunneling-server-with-per-user-accounting-abdal-4iproto-4c0k</link>
      <guid>https://dev.to/ebrasha/build-a-self-hosted-ssh-tunneling-server-with-per-user-accounting-abdal-4iproto-4c0k</guid>
      <description>&lt;h1&gt;
  
  
  Build a Self-Hosted SSH Tunneling Server with Per-User Accounting
&lt;/h1&gt;

&lt;p&gt;If you want a &lt;strong&gt;self-hosted SSH tunneling server&lt;/strong&gt; that handles bandwidth limits, session control, and brute-force protection without you scripting any of it, this walkthrough is for you. We'll set up Abdal 4iProto Server — a Go-based tunnel by &lt;strong&gt;Ebrahim Shafiei (EbraSha)&lt;/strong&gt; — from build to first connection, and I'll explain the config decisions along the way so you're not just copy-pasting blindly.&lt;/p&gt;

&lt;p&gt;Heads up: this server is part of the broader &lt;strong&gt;Abdal 4iProto&lt;/strong&gt; ecosystem (&lt;a href="https://github.com/4iProto" rel="noopener noreferrer"&gt;https://github.com/4iProto&lt;/a&gt;), so there are matching clients and tools once your server is up.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you'll have at the end
&lt;/h2&gt;

&lt;p&gt;A running tunnel server with per-user speed caps, total-traffic quotas, concurrent-session limits, automatic IP blocking on failed logins, and a SOCKS5 endpoint your apps can use. Let's go.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Prerequisites
&lt;/h2&gt;

&lt;p&gt;You need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go 1.25.10 or higher&lt;/li&gt;
&lt;li&gt;An SSH private key (&lt;code&gt;id_rsa&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;A Linux or Windows host&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 2: Generate your host key
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh-keygen &lt;span class="nt"&gt;-t&lt;/span&gt; rsa &lt;span class="nt"&gt;-b&lt;/span&gt; 4096 &lt;span class="nt"&gt;-f&lt;/span&gt; id_rsa
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Drop the resulting &lt;code&gt;id_rsa&lt;/code&gt; in the project directory.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Write the server config
&lt;/h2&gt;

&lt;p&gt;Create &lt;code&gt;server_config.json&lt;/code&gt;. On Linux:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"ports"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;64235&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;64236&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;64237&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"shell"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/bin/bash"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"max_auth_attempts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"server_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"SSH-2.0-Abdal-4iProto-Server"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On Windows, swap the shell:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"ports"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;64235&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;64236&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;64237&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"shell"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cmd.exe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"max_auth_attempts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"server_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"SSH-2.0-Abdal-4iProto-Server"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;ports&lt;/code&gt; array makes the server listen on several ports at once. &lt;code&gt;max_auth_attempts: 3&lt;/code&gt; means three strikes and the IP is auto-blocked. &lt;code&gt;server_version&lt;/code&gt; customizes the banner.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Define your users
&lt;/h2&gt;

&lt;p&gt;Create &lt;code&gt;users.json&lt;/code&gt;. Here's an admin and a rate-limited user:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"username"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ebrasha"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"password"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"change-me"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"role"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"admin"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"blocked_domains"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"blocked_ips"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"log"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"no"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"max_sessions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"session_ttl_seconds"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"username"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"user1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"password"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"change-me-too"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"role"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"user"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"blocked_domains"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"facebook.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"*.facebook.com"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"blocked_ips"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"10.0.0.*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"172.16.*.*"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"log"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"yes"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"max_sessions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"session_ttl_seconds"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Key fields to understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;role&lt;/code&gt;: &lt;code&gt;admin&lt;/code&gt; gets host shell access; &lt;code&gt;user&lt;/code&gt; is tunnel-only. Keep day-to-day accounts as &lt;code&gt;user&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;blocked_domains&lt;/code&gt; / &lt;code&gt;blocked_ips&lt;/code&gt;: support wildcards (&lt;code&gt;*.facebook.com&lt;/code&gt;) and ranges (&lt;code&gt;10.0.0.*&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;log&lt;/code&gt;: per-user visited-site tracking — &lt;code&gt;"yes"&lt;/code&gt; or &lt;code&gt;"no"&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;max_sessions&lt;/code&gt;: concurrent session ceiling.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;session_ttl_seconds&lt;/code&gt;: hard session lifetime before auto-reap.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To add bandwidth control, set &lt;code&gt;max_speed_kbps&lt;/code&gt; (e.g. &lt;code&gt;1024&lt;/code&gt; = 1 MB/s, enforced via token bucket on both directions) and &lt;code&gt;max_total_mb&lt;/code&gt; (e.g. &lt;code&gt;10240&lt;/code&gt; = 10 GB total quota). Quotas are checked every 1–2 seconds, and over-quota sessions are disconnected immediately — not just refused at next login.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Build and run
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go mod tidy
go build &lt;span class="nt"&gt;-o&lt;/span&gt; abdal-4iproto-server
./abdal-4iproto-server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it — the server is listening.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 6: Connect
&lt;/h2&gt;

&lt;p&gt;The quickest test is a standard dynamic-forwarding SSH client:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh &lt;span class="nt"&gt;-D&lt;/span&gt; 1080 username@server_ip &lt;span class="nt"&gt;-p&lt;/span&gt; 22
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now point any app at the local SOCKS5 proxy and your traffic tunnels through. On Linux you can route everything with &lt;code&gt;sshuttle&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sshuttle &lt;span class="nt"&gt;--dns&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; ebrasha@SERVER_IP:2222 0.0.0.0/0 &lt;span class="nt"&gt;-vv&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a GUI experience, grab the official clients: &lt;a href="https://github.com/ebrasha/abdal-4iproto-client" rel="noopener noreferrer"&gt;Windows&lt;/a&gt; and &lt;a href="https://github.com/ebrasha/abdal-4iproto-client-android" rel="noopener noreferrer"&gt;Android&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Optional: relay traffic through another host with iptables NAT
&lt;/h2&gt;

&lt;p&gt;If you need a relay in front of your server, enable forwarding and NAT:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"net.ipv4.ip_forward=1"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; /etc/sysctl.conf
sysctl &lt;span class="nt"&gt;-p&lt;/span&gt;
iptables &lt;span class="nt"&gt;-t&lt;/span&gt; nat &lt;span class="nt"&gt;-A&lt;/span&gt; PREROUTING &lt;span class="nt"&gt;-p&lt;/span&gt; tcp &lt;span class="nt"&gt;--dport&lt;/span&gt; 22 &lt;span class="nt"&gt;-j&lt;/span&gt; DNAT &lt;span class="nt"&gt;--to-destination&lt;/span&gt; IRAN_IP
iptables &lt;span class="nt"&gt;-t&lt;/span&gt; nat &lt;span class="nt"&gt;-A&lt;/span&gt; PREROUTING &lt;span class="nt"&gt;-j&lt;/span&gt; DNAT &lt;span class="nt"&gt;--to-destination&lt;/span&gt; 4iProto_IP
iptables &lt;span class="nt"&gt;-t&lt;/span&gt; nat &lt;span class="nt"&gt;-A&lt;/span&gt; POSTROUTING &lt;span class="nt"&gt;-j&lt;/span&gt; MASQUERADE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;⚠️ &lt;strong&gt;Gotcha:&lt;/strong&gt; the SSH-port DNAT rule must come &lt;em&gt;before&lt;/em&gt; the general PREROUTING rule, and confirm you have alternate SSH access before applying these — it's an easy way to lock yourself out.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's happening under the hood
&lt;/h2&gt;

&lt;p&gt;A few implementation notes worth knowing as you operate this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rate limiting uses a &lt;strong&gt;token-bucket&lt;/strong&gt; algorithm, which smooths throughput while allowing short bursts — friendlier to interactive sessions than a hard window.&lt;/li&gt;
&lt;li&gt;Traffic accounting flushes to &lt;code&gt;traffic_&amp;lt;username&amp;gt;.json&lt;/code&gt; every 10 seconds, so a crash costs at most a few seconds of stats.&lt;/li&gt;
&lt;li&gt;Failed logins go to &lt;code&gt;invalid_logins.log&lt;/code&gt; with the attempted credentials and IP; blocked IPs persist in &lt;code&gt;blocked_ips.json&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;TCP and UDP forwarding are both supported, plus DNSTT for DNS tunneling on hostile networks.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The full ecosystem
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Component&lt;/th&gt;
&lt;th&gt;Repository&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;🔐 Server&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/ebrasha/abdal-4iproto-server" rel="noopener noreferrer"&gt;abdal-4iproto-server&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;⚙️ Web Panel&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/ebrasha/abdal-4iproto-panel" rel="noopener noreferrer"&gt;abdal-4iproto-panel&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;💻 Windows Client&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/ebrasha/abdal-4iproto-client" rel="noopener noreferrer"&gt;abdal-4iproto-client&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;📱 Android Client&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/ebrasha/abdal-4iproto-client-android" rel="noopener noreferrer"&gt;abdal-4iproto-client-android&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🖱️ CLI Installer&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/ebrasha/abdal-4iproto-cli" rel="noopener noreferrer"&gt;abdal-4iproto-cli&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🗝️ SSH KeyGen&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/ebrasha/abdal-4iproto-server-ssh-keygen" rel="noopener noreferrer"&gt;abdal-4iproto-server-ssh-keygen&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Tip: the &lt;a href="https://github.com/ebrasha/abdal-4iproto-cli" rel="noopener noreferrer"&gt;CLI installer&lt;/a&gt; automates OS/arch detection, SHA-256 verification, port config, key generation, and service registration if you'd rather skip the manual build.&lt;/p&gt;

&lt;p&gt;🔗 &lt;strong&gt;Source:&lt;/strong&gt; &lt;a href="https://github.com/ebrasha/abdal-4iproto-server" rel="noopener noreferrer"&gt;https://github.com/ebrasha/abdal-4iproto-server&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Do I need the GUI clients?&lt;/strong&gt; No — any SSH client with &lt;code&gt;-D&lt;/code&gt; dynamic forwarding works. The clients just make it nicer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do I cap a user's speed?&lt;/strong&gt; Add &lt;code&gt;max_speed_kbps&lt;/code&gt; to their &lt;code&gt;users.json&lt;/code&gt; entry (&lt;code&gt;1024&lt;/code&gt; = 1 MB/s).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What happens when a user hits their data quota?&lt;/strong&gt; They're disconnected mid-session within 1–2 seconds and refused at next login until the quota resets.&lt;/p&gt;

</description>
      <category>socks5</category>
      <category>4iproto</category>
      <category>abdal</category>
      <category>ssh</category>
    </item>
    <item>
      <title>Build a Device-Wide SSH Tunnel on Android with Abdal 4iProto Android</title>
      <dc:creator>Ebrahim Shafiei</dc:creator>
      <pubDate>Tue, 09 Jun 2026 20:52:46 +0000</pubDate>
      <link>https://dev.to/ebrasha/build-a-device-wide-ssh-tunnel-on-android-with-abdal-4iproto-25a4</link>
      <guid>https://dev.to/ebrasha/build-a-device-wide-ssh-tunnel-on-android-with-abdal-4iproto-25a4</guid>
      <description>&lt;p&gt;Build a Device-Wide SSH Tunnel on Android with Abdal 4iProto&lt;br&gt;
If you've ever run ssh -D 1080 and pointed your browser at a local SOCKS5 proxy, you already understand half of what this app does. The other half is the interesting part: doing it for every app on your phone, with no root, and with leak protection that actually holds up. Let's walk through it hands-on.&lt;br&gt;
Abdal 4iProto Android is the Android client of the open-source Abdal 4iProto ecosystem by Ebrahim Shafiei (EbraSha). It builds a device-wide SSH tunnel on Android, routing all traffic through an encrypted connection to your own server. No third-party VPN provider, no per-app juggling.&lt;br&gt;
TL;DR of the data flow&lt;br&gt;
Here's the path a packet takes, start to finish:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; App → VpnService (TUN, raw IP packets)
    → hev-socks5-tunnel (native tun2socks via JNI)
    → local SOCKS5 bridge
    → SSH direct-tcpip channel (JSch)
    → your Abdal 4iProto Server → Internet
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fetf2lwoqpe7kh3jolvly.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fetf2lwoqpe7kh3jolvly.jpg" alt=" " width="800" height="1778"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The trick is that SSH forwards TCP streams, but the OS gives you raw IP packets. The native tun2socks engine bridges that gap by turning packets into SOCKS5 connections, which then get forwarded over SSH.&lt;br&gt;
Step 1: Stand up a server&lt;br&gt;
This is a client, so you need the other end. Grab the server component from the ecosystem repo and get it running first. You'll need its IP/hostname, port, and an SSH username/password.&lt;br&gt;
Step 2: Install and add a server&lt;br&gt;
Open the app, then:&lt;/p&gt;

&lt;p&gt;Hamburger menu → Server Management → Add Server&lt;br&gt;
Enter a friendly name, your server's IP/hostname, port, username, and password&lt;br&gt;
Select the server on the main screen&lt;/p&gt;

&lt;p&gt;You can store multiple named servers and switch between them — handy if you run more than one.&lt;br&gt;
Step 3: Configure before connecting&lt;br&gt;
A gotcha worth flagging up front: connection options are applied at connect time, so toggle them before you tap Connect.&lt;br&gt;
The ones worth knowing:&lt;/p&gt;

&lt;p&gt;Fake-IP / FakeDNS — resolves domains on the server (remote DNS) so no real DNS query leaves your device. Turn this on to close the DNS-leak gap. With it off, you still get tunneled DNS-over-TCP.&lt;br&gt;
Kill Switch — blocks all traffic if the tunnel drops unexpectedly, with no leak gap, until it reconnects or you disconnect.&lt;br&gt;
Advanced Settings → Whitelist IPs / CIDR — comma-separated IPs or CIDR blocks that should bypass the tunnel.&lt;/p&gt;

&lt;p&gt;Step 4: Per-app split tunneling (optional)&lt;br&gt;
Open the Per-App Split Tun screen and pick a mode:&lt;/p&gt;

&lt;p&gt;Route via Tunnel → only the apps you select are tunneled.&lt;br&gt;
Bypass Tunnel → everything is tunneled except the apps you select.&lt;/p&gt;

&lt;p&gt;The list is searchable and each app gets its own toggle. Apps kept off the tunnel are also exempt from the kill switch, so they keep normal connectivity.&lt;br&gt;
Step 5: Connect&lt;br&gt;
Tap Connect and grant the VPN permission when Android prompts. That permission is what lets the app stand up its VpnService TUN interface. Once it's up, your whole device is tunneled. Watch the real-time logs from the menu to confirm what's happening.&lt;br&gt;
Tap Disconnect to tear it down.&lt;br&gt;
Why it doesn't leak&lt;br&gt;
Two implementation details do the heavy lifting here, and they're worth understanding if you build networking apps yourself:&lt;/p&gt;

&lt;p&gt;The control socket is protected. The SSH connection itself is wrapped in VpnService.protect() so it doesn't get routed back into the TUN interface. Skip this and you get a routing loop that kills reconnects.&lt;br&gt;
Local ranges bypass automatically. Private/LAN ranges (192.168.x.x, 10.x.x.x) skip the tunnel, so your router, printer, and any phone-hosted services keep working. On API 33+ this uses excludeRoute().&lt;/p&gt;

&lt;p&gt;The stack, quickly&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="err"&gt;minSdk&lt;/span&gt; &lt;span class="err"&gt;24&lt;/span&gt; &lt;span class="err"&gt;(Android&lt;/span&gt; &lt;span class="err"&gt;7.0)&lt;/span&gt;  &lt;span class="err"&gt;·&lt;/span&gt;  &lt;span class="err"&gt;compileSdk/targetSdk&lt;/span&gt; &lt;span class="err"&gt;36&lt;/span&gt; &lt;span class="err"&gt;(Android&lt;/span&gt; &lt;span class="err"&gt;16)&lt;/span&gt;
&lt;span class="err"&gt;applicationId&lt;/span&gt; &lt;span class="err"&gt;net.abdal.abdal4iproto.client&lt;/span&gt;  &lt;span class="err"&gt;·&lt;/span&gt;  &lt;span class="err"&gt;versionName&lt;/span&gt; &lt;span class="err"&gt;5.2&lt;/span&gt;

&lt;span class="err"&gt;Kotlin&lt;/span&gt; &lt;span class="err"&gt;2.2.10&lt;/span&gt; &lt;span class="err"&gt;·&lt;/span&gt; &lt;span class="err"&gt;AGP&lt;/span&gt; &lt;span class="err"&gt;9.1.1&lt;/span&gt; &lt;span class="err"&gt;·&lt;/span&gt; &lt;span class="err"&gt;Gradle&lt;/span&gt; &lt;span class="err"&gt;9.3.1&lt;/span&gt; &lt;span class="err"&gt;·&lt;/span&gt; &lt;span class="err"&gt;KSP&lt;/span&gt; &lt;span class="err"&gt;2.3.5&lt;/span&gt; &lt;span class="err"&gt;·&lt;/span&gt; &lt;span class="err"&gt;Java&lt;/span&gt; &lt;span class="err"&gt;11&lt;/span&gt;
&lt;span class="py"&gt;UI&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Jetpack Compose (Material 3), Navigation Compose 2.8.9&lt;/span&gt;
&lt;span class="py"&gt;SSH&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;JSch (mwiede fork) 0.2.21&lt;/span&gt;
&lt;span class="py"&gt;Crypto&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Bouncy Castle bcprov-jdk18on 1.84  → ssh-ed25519 host keys&lt;/span&gt;
&lt;span class="py"&gt;Coroutines&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;kotlinx-coroutines 1.10.2&lt;/span&gt;
&lt;span class="py"&gt;Persistence&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Room 2.7.0 (KSP)&lt;/span&gt;
&lt;span class="py"&gt;Native&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;hev-socks5-tunnel (.so) tun2socks via JNI (TProxyService)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The native tun2socks engine is the deliberate performance call — packet translation stays in compiled native code instead of crossing the JNI boundary per packet in managed Kotlin.&lt;br&gt;
Wrapping up&lt;br&gt;
The whole design comes down to one principle: capture everything, leak nothing, and keep the trust boundary at your server. No telemetry, open source, auditable via live logs. If you've been meaning to graduate from per-app proxies to a real device-wide tunnel you actually control, this is a clean way to do it.&lt;br&gt;
FAQ&lt;br&gt;
Do I need root? No — it uses VpnService.&lt;br&gt;
Why does my home network still work while connected? Private/LAN ranges bypass the tunnel by design.&lt;br&gt;
What's the minimum Android version? API 24. Some routing features need API 33+.&lt;br&gt;
Can I tunnel only specific apps? Yes — use the Per-App Split Tun screen's "Route via Tunnel" mode.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/ebrasha/abdal-4iproto-client-android" rel="noopener noreferrer"&gt;https://github.com/ebrasha/abdal-4iproto-client-android&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🤵 Programmer&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Handcrafted with Passion by Ebrahim Shafiei (EbraSha)&lt;/p&gt;

</description>
      <category>android</category>
      <category>ssh</category>
      <category>security</category>
      <category>networking</category>
    </item>
  </channel>
</rss>
