<?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[Harsh's Writings]]></title><description><![CDATA[Harsh's Writings]]></description><link>https://blogs.harshbansal.in</link><generator>RSS for Node</generator><lastBuildDate>Sat, 16 May 2026 23:38:34 GMT</lastBuildDate><atom:link href="https://blogs.harshbansal.in/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Secure SSH Access via TLS/HTTPS Proxy using stunnel]]></title><description><![CDATA[How to Bypass Institute WiFi SSH Restrictions Using stunnel
At IIT Kharagpur and many other institutes or workplaces, WiFi networks often block SSH altogether. This means you can’t git clone, deploy code, or connect to remote servers. Even switching ...]]></description><link>https://blogs.harshbansal.in/ssh-proxy-via-https-using-stunnel</link><guid isPermaLink="true">https://blogs.harshbansal.in/ssh-proxy-via-https-using-stunnel</guid><category><![CDATA[ssh]]></category><category><![CDATA[proxy]]></category><category><![CDATA[AWS]]></category><category><![CDATA[server]]></category><dc:creator><![CDATA[Harsh Bansal]]></dc:creator><pubDate>Mon, 15 Sep 2025 12:48:33 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1757940706012/d1740167-d3f0-4fa7-b783-bc1645eef822.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1 id="heading-how-to-bypass-institute-wifi-ssh-restrictions-using-stunnel">How to Bypass Institute WiFi SSH Restrictions Using stunnel</h1>
<p>At IIT Kharagpur and many other institutes or workplaces, WiFi networks often block SSH altogether. This means you can’t git clone, deploy code, or connect to remote servers. Even switching SSH from port 22 to port 443 doesn’t help, since <strong>Deep Packet Inspection (DPI)</strong> can still detect and terminate SSH traffic.</p>
<p>The solution is <code>stunnel</code>. It wraps your SSH traffic inside TLS/SSL, making it look like HTTPS. Firewalls see a normal HTTPS handshake and encrypted packets, not SSH. Here’s the architecture and step-by-step guide.</p>
<hr />
<h2 id="heading-architecture">Architecture</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1757938866298/1bd8da16-4778-46c6-980f-244625c2190f.png" alt class="image--center mx-auto" /></p>
<p>This architecture uses <code>stunnel</code> to wrap SSH traffic inside a secure TLS/SSL tunnel, making it appear as standard HTTPS traffic. This allows the connection to bypass firewalls that block SSH by sending it over port 443. A remote <code>stunnel</code> instance then receives the encrypted traffic, unwraps it, and forwards the original SSH connection to the target server.</p>
<p><strong>Why this works:</strong></p>
<ul>
<li><p><strong>Port:</strong> Firewalls must allow 443 (otherwise HTTPS breaks).</p>
</li>
<li><p><strong>Protocol disguise:</strong> DPI sees TLS handshakes, not SSH fingerprints.</p>
</li>
<li><p><strong>Preservation:</strong> SSH authentication and features remain unchanged.</p>
</li>
</ul>
<hr />
<h2 id="heading-step-1-server-setup">Step 1: Server Setup ☁️</h2>
<h3 id="heading-1-provision-a-server">1. Provision a server</h3>
<p>Use an AWS EC2 or any cloud VM. Open inbound TCP 443 in security groups so that it can receive HTTPS requests.</p>
<h3 id="heading-2-install-stunnel">2. Install <code>stunnel</code></h3>
<p>It'll be used to unwrap incoming HTTPS requests and wrap the SSH response back to HTTPS</p>
<pre><code class="lang-bash">sudo apt update
sudo apt install stunnel4 -y
</code></pre>
<h3 id="heading-3-generate-an-ssl-certificate-required-by-stunnel-to-work">3. Generate an SSL certificate required by stunnel to work</h3>
<pre><code class="lang-bash">sudo openssl req -x509 -newkey rsa:4096 \
  -keyout /etc/stunnel/stunnel.key \
  -out /etc/stunnel/stunnel.pem \
  -nodes -days 365
sudo chmod 600 /etc/stunnel/stunnel.key
</code></pre>
<h3 id="heading-4-configure-stunnel">4. Configure stunnel</h3>
<p>Create <code>/etc/stunnel/ssh-tunnel.conf</code>:</p>
<pre><code class="lang-plaintext">pid = /var/run/stunnel4/stunnel.pid
cert = /etc/stunnel/stunnel.pem
key = /etc/stunnel/stunnel.key

[ssh-proxy]
accept = 443
connect = 127.0.0.1:22
</code></pre>
<h3 id="heading-5-enable-service">5. Enable service</h3>
<pre><code class="lang-bash">sudo systemctl <span class="hljs-built_in">enable</span> stunnel4.service
sudo systemctl restart stunnel4.service
</code></pre>
<hr />
<h2 id="heading-step-2-client-setup-laptop">Step 2: Client Setup (Laptop) 💻</h2>
<h3 id="heading-1-install-stunnel">1. Install <code>stunnel</code></h3>
<ul>
<li><p>macOS: <code>brew install stunnel</code></p>
</li>
<li><p>Ubuntu/Debian: <code>sudo apt install stunnel4</code></p>
</li>
<li><p>Arch: <code>sudo pacman -S stunnel</code></p>
</li>
<li><p>Windows: <a target="_blank" href="https://www.stunnel.org/downloads.html">Download Installer</a></p>
</li>
</ul>
<h3 id="heading-2-create-config">2. Create config</h3>
<p>File: <code>/etc/stunnel/stunnel.conf</code></p>
<pre><code class="lang-plaintext">client = yes

[ssh-proxy]
accept = 127.0.0.1:2222
connect = YOUR_SERVER_PUBLIC_IP:443
</code></pre>
<h3 id="heading-3-start-service">3. Start service</h3>
<pre><code class="lang-bash">sudo systemctl <span class="hljs-built_in">enable</span> stunnel4.service
sudo systemctl restart stunnel4.service
</code></pre>
<hr />
<h2 id="heading-step-3-ssh-config">Step 3: SSH Config ⚡</h2>
<h3 id="heading-1-manual-test">1. Manual test</h3>
<p>You can use this command to connect to the proxy server via stunnel and check whether stunnel is configured correctly.</p>
<pre><code class="lang-bash">ssh -p 2222 ubuntu@127.0.0.1
</code></pre>
<p>Note that we're connecting to localhost here. stunnel listens for SSH requests on port 2222 and forwards them to the proxy server after wrapping them in HTTPS.</p>
<h3 id="heading-2-automate-with-sshconfig">2. Automate with <code>~/.ssh/config</code></h3>
<p>This step configures all SSH requests to route through the proxy server.</p>
<pre><code class="lang-plaintext">Host jump-server
  HostName 127.0.0.1
  Port 2222
  User ubuntu
  IdentityFile /path/to/identity-file.pem

Host * !jump-server
  ProxyJump jump-server
</code></pre>
<hr />
<h2 id="heading-why-this-works-so-well">Why This Works So Well</h2>
<ul>
<li><p><strong>Right port:</strong> 443 is always open.</p>
</li>
<li><p><strong>Right protocol:</strong> TLS looks like HTTPS.</p>
</li>
<li><p><strong>Right behavior:</strong> Standard SSL handshake, no SSH signature visible.</p>
</li>
</ul>
<hr />
<h2 id="heading-conclusion">Conclusion</h2>
<p>With just a small setup, <code>stunnel</code> makes your SSH sessions look like HTTPS. Architecture is simple:</p>
<p><strong>SSH → Local TLS → Remote TLS → SSH.</strong></p>
<p>Now you can code, deploy, and push without your firewall even noticing.</p>
]]></content:encoded></item></channel></rss>