<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>易博云天 &#187; Nginx</title>
	<atom:link href="http://www.eavea.com/blog/index.php/tag/nginx/feed" rel="self" type="application/rss+xml" />
	<link>http://www.eavea.com/blog</link>
	<description>专注技术：学习、交流、分享、免费，每天进步一点点！</description>
	<lastBuildDate>Mon, 13 Mar 2023 07:04:16 +0000</lastBuildDate>
	<language>zh-CN</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.6.1</generator>
		<item>
		<title>Nginx正向代理与反向代理</title>
		<link>http://www.eavea.com/blog/index.php/nginxzhengxiangdailiyufanxiangdaili.html</link>
		<comments>http://www.eavea.com/blog/index.php/nginxzhengxiangdailiyufanxiangdaili.html#comments</comments>
		<pubDate>Tue, 14 Apr 2020 07:48:28 +0000</pubDate>
		<dc:creator>eavea</dc:creator>
				<category><![CDATA[运维知识]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Nginx]]></category>

		<guid isPermaLink="false">http://www.eavea.com/blog/?p=62</guid>
		<description><![CDATA[Nginx正向代理与反向代理 正向代理与反向代理的区别，以及用Nginx配置实现代理服务。 一、正向代理与反向 [&#8230;]]]></description>
				<content:encoded><![CDATA[<div>Nginx正向代理与反向代理</div>
<blockquote><p>正向代理与反向代理的区别，以及用Nginx配置实现代理服务。</p></blockquote>
<h2 id="toc-heading-1">一、正向代理与反向代理</h2>
<h3 id="toc-heading-2">1. 正向代理</h3>
<p>正向代理其实相当于请求的中继，比如说，如果某个网站国内无法访问，也就是被墙了，我可以选择两种方式：<br />
一个是配置代理服务器，第二种就是 VPN。</p>
<p>其实两种技术原理差不太多，如果说我自己访问不到这个网站，而这时可以通过一台可以访问到这个网站的服务器，也就是代理服务器，来进行访问，这台代理服务器，分析我们请求的信息，然后去对应的要去的网站上将内容取回来发给我，这样我就能读到想要访问的网站上的内容了，通过一下图片，可以很清晰的看出其原理：</p>
<div><img alt="forward_proxy.png" src="https://www.wenyuanblog.com/medias/blogimages/forward_proxy.png" width="500" height="300" align="center" data-original="/medias/blogimages/forward_proxy.png" /></div>
<p>&nbsp;</p>
<h3 id="toc-heading-3">2. 反向代理</h3>
<p>反向代理比正向代理更加透明，客户端并不知道访问的是代理服务器，当客户端请求一个网址的时候，会经过反向代理服务器，而这台反向代理服务器，会根据客户端的请求，将请求转发到内网服务器中，内网服务器处理请求并返回结果到反向代理服务器上，通过反向代理服务器，将结果最终返回到客户端，详情如图：</p>
<div><img alt="reverse_proxy.png" src="https://www.wenyuanblog.com/medias/blogimages/reverse_proxy.png" width="500" height="300" align="center" data-original="/medias/blogimages/reverse_proxy.png" /></div>
<p>&nbsp;</p>
<p><strong>简单来说：</strong><br />
正向代理代理的是客户端（如通过代理访问谷歌），而反向代理代理的是服务器（如 Nginx 代理 PHP 服务器）。</p>
<h2 id="toc-heading-4">二、通过SSH反向代理实现内网穿透</h2>
<h3 id="toc-heading-5">1. 背景</h3>
<p>我用学校实验室的一台服务器在跑数据，但是这台服务器没有公网 ip，只有学校内网 ip，故我只能到实验室登录。但有时候，需要在宿舍或者家里远程连接这台服务器。</p>
<p>于是，我就用到了<strong>反向代理</strong>。前提是我有一台公网 ip 的服务器（例如，阿里的学生机，或者 vultr 的 VPS 都可以）。</p>
<p>首先，准备好这两台服务器：</p>
<ul>
<li>学校实验室服务器（SchoolServer）
<ul>
<li>IP：192.168.10.50</li>
<li>ssh端口：22</li>
<li>用户：student</li>
<li>密码：helloworld</li>
</ul>
</li>
<li>我的外网服务器（MyServer）
<ul>
<li>IP：111.13.100.91</li>
<li>ssh端口：22</li>
<li>用户：wenyuanblog</li>
<li>密码：<a href="http://www.wenyuanblog.com/" target="_0">www.wenyuanblog.com</a></li>
</ul>
</li>
</ul>
<h3 id="toc-heading-6">2. 实现原理</h3>
<p>在学校内网服务器（以下简称 SchoolServer）中，通过 SSH 设置反向代理，指向我的公网服务器（以下简称 MyServer，该服务器作为反向代理服务器），之后用客户端连接 MyServer 时，MyServer 会把请求转交给 SchoolServer，从而间接登录学校的内网服务器。</p>
<p><strong>整个过程，我们作为客户端是感知不到代理服务器的存在的。客户端是否能感知代理服务器的存在，是区别正向代理和反向代理的关键。</strong></p>
<p>SSH 参数介绍</p>
<div>bash<i></i><i></i></div>
<pre><code># 反向代理命令
ssh -fCNR

# 正向代理命令
ssh -fCNL
</code></pre>
<p>参数说明</p>
<table>
<thead>
<tr>
<th>参数</th>
<th>含义</th>
</tr>
</thead>
<tbody>
<tr>
<td>-f</td>
<td>后台执行 ssh 指令</td>
</tr>
<tr>
<td>-C</td>
<td>允许压缩数据</td>
</tr>
<tr>
<td>-N</td>
<td>不执行远程指令</td>
</tr>
<tr>
<td>-R</td>
<td>将远程服务器的某个端口转发到本地服务器的指定端口</td>
</tr>
<tr>
<td>-L</td>
<td>将本地服务器的某个端口转发到远程服务器的指定端口</td>
</tr>
<tr>
<td>-p</td>
<td>指定远程服务器的端口</td>
</tr>
</tbody>
</table>
<h3 id="toc-heading-7">3. 内网服务器操作</h3>
<p>登录 SchoolServer，进行如下操作：</p>
<div>bash<i></i><i></i></div>
<pre><code># ssh -N -f -R MyServer端口:127.0.0.1:本地端口 MyServer用户@MyServerIP
ssh -N -f -R 20022:127.0.0.1:22 wenyuanblog@111.13.100.91
</code></pre>
<p>这句命令的意思是，将 MyServer 的 20022 端口转发至 SchoolServer 22 端口，最后是 MyServer 用户名和 IP。<br />
使用 <code>ps aux | grep ssh</code> 来查看是否运行。</p>
<h3 id="toc-heading-8">4. 公网服务器操作</h3>
<p>登录 MyServer，进行如下操作：</p>
<div>bash<i></i><i></i></div>
<pre><code># ssh SchoolServer用户名@127.0.0.1 -p 代理端口 -L MyServerIP:代理端口:127.0.0.1:22
ssh student@127.0.0.1 -p 20022 -L 111.13.100.91:20022:127.0.0.1:22
</code></pre>
<p>执行这条命名，输入 student 用户的密码，现在就已经跳转登录到内网服务器了。</p>
<p>保持当前窗口的登录状态，这时候使用 xshell、beyondcompare，就只要在登录的配置项里 IP 填 MyServer 的 IP，端口填 20022 就好了。</p>
<h2 id="toc-heading-9">三、Nginx配置实现代理服务</h2>
<h3 id="toc-heading-10">1. 背景</h3>
<p>到目前为止，我们都还没有用到 Nginx 的代理服务。那什么时候会需要呢，现在有了如下需求：</p>
<p>在学校内网服务器上跑了一个网页（实验室代码库 GitLab），我们需要在宿舍或者家里访问这个内部网页。</p>
<p>该项目是部署在内网的，所以在内网直接访问不会有问题，而从外网访问当然也就访问不到。</p>
<ul>
<li>学校实验室服务器（SchoolServer）
<ul>
<li>IP：192.168.10.50</li>
<li>页面 url：192.168.10.50:8000</li>
</ul>
</li>
<li>我的外网服务器（MyServer）
<ul>
<li>IP：111.13.100.91</li>
<li>站点域名：<a href="http://www.wenyuanblog.com/" target="_0">www.wenyuanblog.com</a></li>
</ul>
</li>
</ul>
<h3 id="toc-heading-11">2. 实现原理</h3>
<p>还是通过反向代理来实现。</p>
<p>通过 Nginx 实现端口转发，最后可以通过公网服务器的域名+端口号访问学校内网服务器的页面。<br />
即访问 <a href="http://www.wenyuanblog.com:28000/" target="_0">www.wenyuanblog.com:28000</a> 时，将得到 192.168.10.50:8000（实验室代码库）的页面。<br />
当然了，这样配置的话，我不得不记住 28000 这个端口号，显然不方便。</p>
<p>所以下面的配置，我将配置成二级域名的形式，即 gitlab.wenyuanblog.com -&gt; 192.168.10.50:8000</p>
<h3 id="toc-heading-12">3. 内网服务器操作</h3>
<p>登录 SchoolServer，进行如下操作（和二&gt;中一样）：</p>
<div>bash<i></i><i></i></div>
<pre><code># ssh -N -f -R MyServer端口:127.0.0.1:本地端口 MyServer用户@MyServerIP
ssh -N -f -R 28000:127.0.0.1:8000 wenyuanblog@111.13.100.91
</code></pre>
<p>这句命令的意思是，将 MyServer 的 28000 端口转发至 SchoolServer 8000 端口，最后是 MyServer 用户名和 IP。</p>
<p>使用 <code>ps aux | grep ssh</code> 来查看是否运行。</p>
<h3 id="toc-heading-13">4. 公网服务器操作</h3>
<p>登录 MyServer，增加一份 Nginx 的配置文件，我习惯放于 <code>/usr/local/nginx/conf/vhosts</code> 目录下，考虑到是代理的配置文件，我取名为 <code>school.proxy</code>。</p>
<p><code>vim school.proxy</code>，配置如下：</p>
<div>bash<i></i><i></i></div>
<pre><code>upstream school_gitlab {
        server 127.0.0.1:28000;
}
server {
        listen       80;
        server_name   gitlab.wenyuanblog.com;
        location / {
            proxy_pass http://school_gitlab;
            proxy_set_header Host $host;
        }
        access_log  /var/log/nginx/access/school_gitlab.log;
}
</code></pre>
<p>现在，我就可以通过二级域名访问学校实验室的 GitLab 了。</p>
<p>整个过程中，在 MyServer 的数据流向如下：<br />
<strong>二级域名访问</strong> -&gt; <strong>MyServer:80</strong> -&gt; <strong>nginx 分发</strong> -&gt; <strong>MyServer:28000</strong> -&gt; <strong>SchoolServer:8080</strong></p>
<h2 id="toc-heading-14">四、补充：用autossh代替ssh</h2>
<h3 id="toc-heading-15">1. 背景</h3>
<p>其实整个过程到上面为止已经结束了，目前已经通过反向代理实现内网穿透，平时肯定够用了。<br />
如果想追求更进一步的配置，可以继续往下看。</p>
<p>什么是更进一步的配置呢？</p>
<p>在前面二、三两部分内容的「内网服务器操作」时，我们使用 ssh 建立的反向连接其实很不稳定，长时间不使用连接就会自动释放，这个时候就需要使用 autossh。<br />
autossh 的参数与 ssh 的参数是一致的，但是不同的是，在隧道断开的时候，autossh 会自动重新连接而 ssh 不会。</p>
<h3 id="toc-heading-16">2. 步骤修改</h3>
<p>只需改动一个地方，那就是上面二和三里面的「3. 内网服务器操作」，其他操作不变。</p>
<p><strong>现在如下操作：</strong></p>
<p><strong>Step1. 配置公钥和私钥，实现免密码登录</strong>（为后面的脚本做准备）</p>
<ul>
<li>登录内网服务器（SchoolServer）<br />
切换到普通用户 student，不建议用 root。<br />
执行命令：<code>ssh-keygen -t rsa -P ''</code>，直接 ssh-keygen 然后三次回车就可以了。</p>
<ul>
<li><code>-P</code> 表示密码，<code>-P ''</code> 就表示空密码，也可以不用 <code>-P</code> 参数，这样就要三车回车，用 <code>-P</code> 就一次回车。</li>
<li>它在 <code>/home/student</code> 下生成 <code>.ssh</code> 目录，<code>.ssh</code> 下有 <code>id_rsa</code> 和 <code>id_rsa.pub</code>。（这样就生成了公钥/私钥对）</li>
</ul>
</li>
<li>把内网服务器（SchoolServer）下的 <code>id_rsa.pub</code> 复制到公网服务器（MyServer）下<br />
执行命令：<code>scp .ssh/id_rsa.pub wenyuanblog@111.13.100.91:/home/wenyuanblog/id_rsa.pub</code><br />
由于还没有免密码登录的，所以要输入密码。</li>
<li>公网服务器（MyServer）加入内网服务器（SchoolServer）的公钥<br />
登录公网服务器（MyServer），切换到 wenyuanblog 账户（下面的步骤不要用 root）。<br />
如果公网服务器的 wenyuanblog 目录下没有 <code>.ssh</code> 和 <code>authorized_keys</code> 文件则创建这个文件夹和文件。<br />
把从内网服务器复制的 <code>id_rsa.pub</code> 添加到 <code>.ssh/authorzied_keys</code> 文件里，即执行命令：<br />
<code>cat id_rsa.pub &gt;&gt; .ssh/authorized_keys</code><br />
<code>cat .ssh/authorized_keys</code><br />
<code>chmod 644 .ssh/authorized_keys</code></p>
<ul>
<li>authorized_keys 的权限要是 644 。</li>
</ul>
</li>
<li>内网服务器（SchoolServer）登录公网服务器（MyServer）试试<br />
回到内网服务器（SchoolServer），用之前的普通用户 student，执行：<code>ssh wenyuanblog@111.13.100.91</code><br />
第一次登录要 yes，现在内网机器就可以免密码登录公网机器了。</li>
</ul>
<p><strong>Step2. 登录内网服务器，启动 autossh，维持 ssh 连接</strong></p>
<p>上面提过，使用 ssh 建立的反向连接很不稳定，长时间不使用连接就会自动释放，这个时候就需要使用 autossh。</p>
<p>一般新机器需要安装 autossh：<br />
<code>yum install autossh</code>（CentOS）<br />
<code>apt-get install autossh</code>（Ubuntu）</p>
<p>切换到 wenyuanblog 用户（非 root 用户），在其 <code>home</code> 目录下创建一个 <code>autossh.sh</code> 脚本，开辟连接到公网服务器的隧道。<br />
<code>autossh.sh</code> 脚本内写入要开辟的端口：</p>
<div>bash<i></i><i></i></div>
<pre><code>#!/bin/bash
/usr/bin/autossh -NR 0.0.0.0:20022:127.0.0.1:22  -i ~/.ssh/id_rsa wenyuanblog@公网IP -p 22 &gt;&gt; ~/log/ssh_nat.log 2&gt;&amp;1 &amp;
/usr/bin/autossh -NR 0.0.0.0:28000:127.0.0.1:8000 -i ~/.ssh/id_rsa wenyuanblog@公网IP -p 22 &gt;&gt; ~/log/ssh_nat.log 2&gt;&amp;1 &amp;
</code></pre>
<p>这两行就分别代替了上面二和三中「3. 内网服务器操作」里的内容。</p>
<p>运行脚本：<br />
<code>chmod +x autossh.sh</code><br />
<code>sh autossh.sh</code></p>
<p>使用 <code>ps -ef|grep autossh</code> 和 <code>ps -ef|grep ssh</code> 查看当前运行中的 autossh 任务进程。</p>
<p>其余步骤不变，完成。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.eavea.com/blog/index.php/nginxzhengxiangdailiyufanxiangdaili.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
