<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Proxy on Haseeb Majid</title>
    <link>https://haseebmajid.dev/tags/proxy/</link>
    <description>Recent content in Proxy on Haseeb Majid</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en</language>
    <lastBuildDate>Sat, 10 Oct 2020 00:00:00 +0000</lastBuildDate><atom:link href="https://haseebmajid.dev/tags/proxy/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>How SOCKS proxies work and using ProxyChains</title>
      <link>https://haseebmajid.dev/posts/2020-10-10-how-socks-proxies-work-and-using-proxychains/</link>
      <pubDate>Sat, 10 Oct 2020 00:00:00 +0000</pubDate>
      
      <guid>https://haseebmajid.dev/posts/2020-10-10-how-socks-proxies-work-and-using-proxychains/</guid>
      <description>&lt;p&gt;In this article, we will go over how you can use &lt;code&gt;proxychains&lt;/code&gt; to proxy our traffic through a socks proxy.&lt;/p&gt;
&lt;h2 id=&#34;background&#34;&gt;Background&lt;/h2&gt;
&lt;p&gt;Recently, like everyone else, I&amp;rsquo;ve been working from home a lot more often. This means to access resources at work
I need to use a VPN. However, to access some resources, such as production servers from my local machine, I need to
use a SOCKS5 proxy. Without using a SOCKS proxy, I would need to do something shown in the diagram below.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>In this article, we will go over how you can use <code>proxychains</code> to proxy our traffic through a socks proxy.</p>
<h2 id="background">Background</h2>
<p>Recently, like everyone else, I&rsquo;ve been working from home a lot more often. This means to access resources at work
I need to use a VPN. However, to access some resources, such as production servers from my local machine, I need to
use a SOCKS5 proxy. Without using a SOCKS proxy, I would need to do something shown in the diagram below.</p>
<h3 id="example-setup">Example Setup</h3>
<div class="mermaid">graph LR
  A[Local Machine] -->|ssh| B[Server A]
  B -->|ssh| C[Server B]
  subgraph Firewall
    C
  end
</div>

<p>First, I would need to SSH onto an intermediate server (<code>Server A</code>), which I have connectivity to from my local machine.
Then on that intermediate server, I would need to SSH onto the production server. So this intermediate server needs
to have connectivity to the <code>Server B</code> as well. As you can see <code>Server B</code> is behind a firewall, in this example, the
firewall will only allow traffic from <code>Server A</code> to ingress to <code>Server B</code>. So we cannot connect directly from <code>Server A</code>.</p>
<p>Another reason this setup is sub-optimal is because, I lose all the development tools on my local machine. Say I wanted
to use terraform to deploy/upgrade a service running on <code>Server B</code> server. I need to make sure terraform exists
on the intermediate server. Now, this is fine for something simple like terraform which is a single binary file
but may get more complicated for other pieces of software, especially if you cannot install extra packages on
the intermediate server. Also, there are other advantages in using your local development environment: you have
all your shortcuts saved, perhaps you use a different shell zsh, fish vs bash on the server itself. For whatever
reason, it may be more convenient to access <code>Server B</code> directly from our local machine.</p>
<details
  class="notice warning"
  open="true"
>
    <summary class="notice-title">🔐 Production Access</summary>
  
  Now depending on where you work and how your policies work it may not be possible or a good idea to access
your production servers from your local machine. This is just a simple example of one reason you may
want to use a SOCKS proxy. There may be many others, such as accessing your test environment instead of
production.
</details>

<h2 id="socks-proxy">SOCKS Proxy</h2>
<p>In this section, I will show you how to solve the problem we described above. To solve this problem we will need to use,
a SOCKS (🧦 not this kinda socks) proxy. SOCKS is a layer 5 (on the OSI model, shown below) protocol. The protocol will allow
us to proxy to <code>Server A</code> and this server will then act as almost a middleman between the <code>Local Machine</code> and <code>Server B</code>.
The SOCKS proxy doesn&rsquo;t interpret any network traffic between the client (<code>Local Machine</code>) and the
server (<code>Server B</code>), it merely passes it onto between the two.</p>
<p>
  <img
    loading="lazy"
    src="https://upload.wikimedia.org/wikipedia/commons/2/2b/Osi-model.png"
    alt="OSI Model"
    
  /></p>
<details
  class="notice tip"
  open="true"
>
    <summary class="notice-title">SOCKS Proxy</summary>
  
  You can learn more about
<a href="https://securityintelligence.com/posts/socks-proxy-primer-what-is-socks5-and-why-should-you-use-it/">SOCKS proxies here</a>.
This article goes into much more detail than I do!
</details>

<h3 id="ssh-command">SSH Command</h3>
<p>So finally let&rsquo;s get onto how we can create a SOCKS proxy. To do this we will create an SSH tunnel.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">ssh -D <span class="m">8123</span> -f -C -q -N haseeb@10.10.10.10
</span></span></code></pre></div><ul>
<li><code>-D 8123</code>: Opens a SOCKS5 proxy on local port <code>8123</code></li>
<li><code>-f</code>: Requests SSH to go to the background itself before executing the command</li>
<li><code>-C</code>: Compresses data before sending it</li>
<li><code>-q</code>: Quiet mode doesn&rsquo;t show any output</li>
<li><code>-N</code>: Doesn&rsquo;t execute remote commands, useful for just port forward (protocol 2+)</li>
</ul>
<details
  class="notice tip"
  open="true"
>
    <summary class="notice-title">Multiple Proxies</summary>
  
  You can create multiple SOCKS proxies by running the SSH command binding to different local ports.
</details>

<p>If the command worked, you now have a SOCKS proxy. One common use case of a SOCKS proxy is for internet
browsing using very much the same logic described above. Maybe you can access a website at work which is
behind a firewall, such as an authentication server&rsquo;s GUI etc. You can read more about using a SOCKS
proxy, in your browser <a href="https://ma.ttias.be/socks-proxy-linux-ssh-bypass-content-filters/">here</a>.
The diagram gives us a visual of what we&rsquo;ve just done.</p>
<div class="mermaid">graph LR
    subgraph Local Machine
        A[TCP Port :8123]
        B[SSH Client]
    end

    subgraph Remote Server
        C[Server A]
    end

    B -->|Opens Port| A
    B -->|SSH Tunnel| C
</div>

<h2 id="proxychains">Proxychains</h2>
<p>Now that we have SOCKS proxy running on our local machine, how can we use it to connect to <code>Server B</code> and say
use terraform to deploy a new service? Well, that&rsquo;s where <code>proxychains</code> comes in, or rather more specifically
<code>proxychains-ng</code>. The latter being a version which still gets relatively frequent updates.
To install <code>proxychains</code> on an Ubuntu/Debian based distro you can do something like this:</p>
<h3 id="install">Install</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo apt install proxychains-ng
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">vim /etc/proxychains4.conf
</span></span><span class="line"><span class="cl"><span class="o">[</span>ProxyList<span class="o">]</span>
</span></span><span class="line"><span class="cl"><span class="c1"># add proxy here ...</span>
</span></span><span class="line"><span class="cl"><span class="c1"># meanwile</span>
</span></span><span class="line"><span class="cl"><span class="c1"># defaults set to &#34;tor&#34;</span>
</span></span><span class="line"><span class="cl">socks5 127.0.0.1 <span class="m">8123</span>
</span></span></code></pre></div><p>Edit the configuration file as shown above, <code>socks5 127.0.0.1 8123</code>. Adjust the port <code>8123</code> to whatever port you set above.
Now that <code>proxychains</code> is setup. This is what our setup now looks like:</p>
<div class="mermaid">graph LR
    subgraph Local Machine
      A[TCP Port :8123]
      B[SSH Client]
      D[Proxychains]
    end

    subgraph Remote Server
      C[Server A]
    end

    D -->|Connects to| A
    B -->|Opens Port| A
    B -->|SSH Tunnel| C
</div>

<h3 id="examples">Examples</h3>
<p>If <code>Server B</code> had an IP address of <code>10.10.10.11</code> we could do:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">proxychains ssh haseeb@10.10.10.11
</span></span></code></pre></div><p>This would allow us to connect directly using SSH. Or perhaps if you had a web service running on <code>Server B</code> and wanted to
check a <code>healthcheck</code> endpoint to see if your API was running correctly you might do:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">proxychains curl https://10.10.10.11/api/v1/healthcheck
</span></span></code></pre></div><p>Or if you wanted to use terraform to deploy something on <code>Server B</code>, you could do something like:</p>
<details
  class="notice tip"
  open="true"
>
    <summary class="notice-title">Terraform</summary>
  
  To get terraform to use our SOCKS proxy we need to export the <code>HTTP_PROXY</code> and <code>HTTPS_PROXY</code> variables.
</details>

<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="nb">export</span> <span class="nv">HTTP_PROXY</span><span class="o">=</span>socks5://127.0.0.1:8123
</span></span><span class="line"><span class="cl"><span class="nb">export</span> <span class="nv">HTTPS_PROXY</span><span class="o">=</span>socks5://127.0.0.1:8123
</span></span><span class="line"><span class="cl">proxychains terraform plan
</span></span><span class="line"><span class="cl">proxychains terraform apply
</span></span></code></pre></div><details
  class="notice warning"
  open="true"
>
    <summary class="notice-title">ProxyChains TCP</summary>
  
  proxychains will only proxy TCP connections from your <code>Local Machine</code>.
However, it can resolve DNS through the proxy as well.
</details>

<p>What is essentially going on here is that traffic is being sent from our <code>Local Machine</code> to <code>Server A</code> which can
connect to <code>Server B</code> and pass traffic to the server. This in effect makes it seem our <code>Local Machine</code> can connect
directly to <code>Server B</code>.</p>
<div class="mermaid">graph LR
    subgraph Local Machine
      A[TCP Port :8123]
      B[SSH Client]
      D[Proxychains]
    end

    subgraph Remote Server
      C[Server A]
      E[Server B]
    end

    subgraph Firewall
      E
    end

    D -->|Connects to| A
    B -->|Opens Port| A
    B -->|SSH Tunnel| C
    C -->|TCP Connection| E
</div>

<p>So overall we have something as described in the diagram above!</p>
<h2 id="appendix">Appendix</h2>
<ul>
<li>Read more about <a href="https://securityintelligence.com/posts/socks-proxy-primer-what-is-socks5-and-why-should-you-use-it/">SOCKS Proxies here</a></li>
<li>Read more about how to setup <a href="https://ma.ttias.be/socks-proxy-linux-ssh-bypass-content-filters/">a SOCKS here</a></li>
</ul>
]]></content:encoded>
    </item>
    
  </channel>
</rss>
