Linux迷+Python粉 - 加密隧道https://blog.pythonwood.com/2017-11-27T22:12:00+08:00ssh命令:隧道代理+本地端口转发+远程端口转发2016-02-15T11:29:00+08:002017-11-27T22:12:00+08:00pythonwoodtag:blog.pythonwood.com,2016-02-15:/2016/02/ssh命令:隧道代理+本地端口转发+远程端口转发/<h3 id="0">0、前言<a class="headerlink" href="#0" title="Permanent link">&para;</a></h3> <p>nc是一个在网络连接两端的好工具,同时也是也个临时的端口转发的好工具。(永久的端口转发用什么?用iptables)</p> <p>ssh也是这方面的好工具,好处是加密可靠可复用在一端操作即可,代价是要有登录帐号。</p> <p>我们知道,<span class="caps">SSH</span> 会自动加密和解密所有 <span class="caps">SSH</span> 客户端与服务端之间的网络数据。但是,<span class="caps">SSH</span> 还同时提供了一个非常有用的功能,这就是端口转发。它能够将其他 <span class="caps">TCP …</span></p><h3 id="0">0、前言<a class="headerlink" href="#0" title="Permanent link">&para;</a></h3> <p>nc是一个在网络连接两端的好工具,同时也是也个临时的端口转发的好工具。(永久的端口转发用什么?用iptables)</p> <p>ssh也是这方面的好工具,好处是加密可靠可复用在一端操作即可,代价是要有登录帐号。</p> <p>我们知道,<span class="caps">SSH</span> 会自动加密和解密所有 <span class="caps">SSH</span> 客户端与服务端之间的网络数据。但是,<span class="caps">SSH</span> 还同时提供了一个非常有用的功能,这就是端口转发。它能够将其他 <span class="caps">TCP</span> 端口的网络数据通过 <span class="caps">SSH</span>&nbsp;链接来转发,并且自动提供了相应的加密及解密服务。</p> <h3 id="1">1、隧道带理<a class="headerlink" href="#1" title="Permanent link">&para;</a></h3> <p>典型应用:翻越高墙</p> <p>需要条件:一个国外vps,一个不需要登录(安全)的帐号,一个命令。</p> <p>vps新建帐号:</p> <div class="highlight"><pre><span></span>useradd -g nobody -s /sbin/nologin gfw &amp;&amp; echo gfw_Passw0rd | passwd --stdin gfw </pre></div> <p>本地ssh连接:</p> <div class="highlight"><pre><span></span>ssh -NfD 6666 gfw@vps -p 2222 </pre></div> <p>可选转换:使用privoxy把socks5代理变成http代理供svn,pip,gem,curl等工具使用。</p> <h3 id="2">2、本地端口转发<a class="headerlink" href="#2" title="Permanent link">&para;</a></h3> <p><img alt="tu2" src="https://blog.pythonwood.com/uploads/2016/本地端口转发.jpg" title="2"></p> <p>我们可以将远程机器(LdapClientHost)上的应用直接配置到本机的 7001 端口上(而不是 <span class="caps">LDAP</span> 服务器的 389 端口上)。在 LdapClientHost 上执行如下命令即可建立一个 <span class="caps">SSH</span>&nbsp;的本地端口转发,例如:</p> <div class="highlight"><pre><span></span>ssh -L 7001:localhost:389 LdapServerHost </pre></div> <p>之后的数据流将会是下面这个样子:</p> <p>我们在 LdapClientHost 上的应用将数据发送到本机的 7001 端口上, 而本机的 <span class="caps">SSH</span> Client 会将 7001 端口收到的数据加密并转发到 LdapServertHost 的 <span class="caps">SSH</span> Server 上。 <span class="caps">SSH</span> Server 会解密收到的数据并将之转发到监听的 <span class="caps">LDAP</span> 389 端口上, 最后再将从 <span class="caps">LDAP</span>&nbsp;返回的数据原路返回以完成整个流程。</p> <h3 id="3">3、远程端口转发<a class="headerlink" href="#3" title="Permanent link">&para;</a></h3> <p><img alt="tu3" src="https://blog.pythonwood.com/uploads/2016/远程端口转发.jpg" title="3"></p> <p>我们在 LdapClientHost 上的应用将数据发送到本机的 7001 端口上,而本机的 <span class="caps">SSH</span> Server 会将 7001 端口收到的数据加密并转发到 LdapServertHost 的 <span class="caps">SSH</span> Client&nbsp;上。</p> <p>在 <span class="caps">LDAP</span>&nbsp;服务器(LdapServertHost)端执行如下命令:</p> <div class="highlight"><pre><span></span>ssh -R 7001:localhost:389 LdapClientHost </pre></div> <h4 id="_1">区别:<a class="headerlink" href="#_1" title="Permanent link">&para;</a></h4> <p><span class="caps">SSH</span> 端口转发自然需要 <span class="caps">SSH</span> 连接,而 <span class="caps">SSH</span> 连接是有方向的,从 <span class="caps">SSH</span> Client 到 <span class="caps">SSH</span> Server 。而我们的应用也是有方向的,比如需要连接 <span class="caps">LDAP</span> Server 时,<span class="caps">LDAP</span> Server 自然就是 Server 端,我们应用连接的方向也是从应用的 Client 端连接到应用的 Server&nbsp;端。如果这两个连接的方向一致,那我们就说它是本地转发。而如果两个方向不一致,我们就说它是远程转发。</p> <h3 id="4autosshsupervisior">4、使用autossh防网络抖动+supervisior进程守护。<a class="headerlink" href="#4autosshsupervisior" title="Permanent link">&para;</a></h3> <p>autossh解决的问题:远程端口转发一旦端口,很难再次建立。</p> <div class="highlight"><pre><span></span>autossh -M 1932 -NR 1922:localhost:1122 user@vps -p 1122 </pre></div> <p>ps可以看到实质是这样的:</p> <div class="highlight"><pre><span></span>ssh -L 1932:127.0.0.1:1932 -R 1932:127.0.0.1:1933 -NR 1922:localhost:1122 -p 1122 user@vps </pre></div> <p>分析:使用回路,将本地1933端口,(远程转发)映射到远端1932,(本地转发)到本机的1932。形成回路。</p> <p>supervisior解决的问题:autossh的进程守护</p> <p>因此,使用supervisior守护autossh,autossh守护ssh。达到自动启动和守护端口转发的目的。</p> <h3 id="5">5、综合使用<a class="headerlink" href="#5" title="Permanent link">&para;</a></h3> <p>案例一、如何2222端口被封,如果绕过封死2222端口的防火墙直接ssh到内网机器。(就是说限某几个端口是有局限的)</p> <p>1、登录最重要的机器把2222端口映射到12222端口:</p> <div class="highlight"><pre><span></span>ssh -gfNL 12222:0.0.0.0:2222 localhost -p2222 </pre></div> <p>2、使用该机器做隧道代理访问其他内网机器:</p> <div class="highlight"><pre><span></span>ssh -NfD 10000 user@host -p12222 </pre></div> <p>3、ssh绕道访问其他内网机器:</p> <div class="highlight"><pre><span></span>ssh -o &quot;ProxyCommand=nc -x localhost:10000 %h %p&quot; user@host -p2222 </pre></div> <p>巧妙结合的ssh和nc,都是linux自带工具,没有依赖。</p> <p>案例二、借助远程vps让两台不能直接相通的机器相互能访问。</p> <p>有主机vps和主机A、B。A、B无法直连,通过“中介”搭桥相连。(两台机器都能主动ssh到vps就能完成。)</p> <p>A要ssh到B(B要ssh到A是同理):</p> <p>1、主机B用ssh远程转发自己的2222端口到vps的127.0.0.1:12222</p> <div class="highlight"><pre><span></span>ssh -NfR 12222:127.0.0.1:2222 user@vps -p2222 </pre></div> <p>2、主机A用ssh本地转发vps的127.0.0.1:12222到本地的127.0.0.1:12222</p> <div class="highlight"><pre><span></span>ssh -NfL 12222:127.0.0.1:12222 user@vps -p2222 </pre></div> <p>3、主机A登录主机B</p> <div class="highlight"><pre><span></span>ssh user@localhost -p12222 </pre></div> <p>参考:</p> <p>实战 <span class="caps">SSH</span>&nbsp;端口转发</p> <p><a href="https://www.ibm.com/developerworks/cn/linux/l-cn-sshforward/">https://www.ibm.com/developerworks/cn/linux/l-cn-sshforward/</a></p> <p>使用supervisor托管shadowsocks</p> <p><a href="https://blog.phpgao.com/supervisor_shadowsocks.html">https://blog.phpgao.com/supervisor_shadowsocks.html</a></p> <p><span class="caps">SSH</span>反向连接及Autossh</p> <p><a href="http://www.cnblogs.com/eshizhan/archive/2012/07/16/2592902.html">http://www.cnblogs.com/eshizhan/archive/2012/07/16/2592902.html</a></p>