<?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>nginx &#8211; ChaBug安全</title>
	<atom:link href="/tags/nginx/feed" rel="self" type="application/rss+xml" />
	<link>/</link>
	<description>一个分享知识、结识伙伴、资源共享的博客</description>
	<lastBuildDate>Sun, 07 Jul 2019 12:03:23 +0000</lastBuildDate>
	<language>zh-CN</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=5.5.5</generator>
	<item>
		<title>Nginx URL Rewrite</title>
		<link>/safeprotect/663.html</link>
		
		<dc:creator><![CDATA[Y4er]]></dc:creator>
		<pubDate>Sun, 07 Jul 2019 12:03:23 +0000</pubDate>
				<category><![CDATA[安全运维]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[伪静态]]></category>
		<category><![CDATA[重定向]]></category>
		<guid isPermaLink="false">/?p=663</guid>

					<description><![CDATA[总结下nginx的重写规则用法。 url重写是指通过配置conf文件，以让网站的url中达到某种状态时则定向/跳转到某个规则，比如常见的伪静态、301重定向、浏览器定向等。 con...]]></description>
										<content:encoded><![CDATA[<p>总结下<span class="wpcom_tag_link"><a href="/tags/nginx" title="nginx" target="_blank">nginx</a></span>的重写规则用法。</p>
<p>url重写是指通过配置conf文件，以让网站的url中达到某种状态时则定向/跳转到某个规则，比如常见的<span class="wpcom_tag_link"><a href="/tags/%e4%bc%aa%e9%9d%99%e6%80%81" title="伪静态" target="_blank">伪静态</a></span>、301<span class="wpcom_tag_link"><a href="/tags/%e9%87%8d%e5%ae%9a%e5%90%91" title="重定向" target="_blank">重定向</a></span>、浏览器定向等。</p>
<p>conf配置文件的路径可以通过命令来查看</p>
<div class="highlight highlight-source-shell">
<pre>[root@VM_100_94_centos <span class="pl-k">~</span>]<span class="pl-c"># nginx -t</span>
nginx: the configuration file /www/server/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /www/server/nginx/conf/nginx.conf <span class="pl-c1">test</span> is successful</pre>
</div>
<p>但是如果你有多个conf文件，这个命令并不适用。</p>
<p>在宝塔面板中conf是在<code>/www/server/panel/vhost/nginx</code>路径下。</p>
<h1><a id="user-content-rewrite" class="anchor" href="https://github.com/Y4er/MyBlog/blob/master/content/post/nginx-rewrite.md#rewrite" aria-hidden="true"></a>rewrite</h1>
<div class="highlight highlight-source-shell">
<pre>server {
    rewrite 规则 定向路径 重写类型<span class="pl-k">;</span>
}</pre>
</div>
<ol>
<li>规则：可以是字符串或者正则来表示想匹配的目标url</li>
<li>定向路径：表示匹配到规则后要定向的路径，如果规则里有正则，则可以使用$index来表示正则里的捕获分组</li>
<li>重写类型：
<ul>
<li>last：相当于Apache里德(L)标记，表示完成rewrite，浏览器地址栏URL地址不变</li>
<li>break：本条规则匹配完成后，终止匹配，不再匹配后面的规则，浏览器地址栏URL地址不变</li>
<li>redirect：返回302临时重定向，浏览器地址会显示跳转后的URL地址</li>
<li>permanent：返回301永久重定向，浏览器地址栏会显示跳转后的URL地址</li>
</ul>
</li>
</ol>
<p>看一个例子</p>
<div class="highlight highlight-source-shell">
<pre>server {
    <span class="pl-c"># 访问 /last.html 的时候，页面内容重写到 /index.html 中</span>
    rewrite /last.html /index.html last<span class="pl-k">;</span>
    <span class="pl-c"># 访问 /break.html 的时候，页面内容重写到 /index.html 中，并停止后续的匹配</span>
    rewrite /break.html /index.html <span class="pl-c1">break</span><span class="pl-k">;</span>
    <span class="pl-c"># 访问 /redirect.html 的时候，页面直接302定向到 /index.html中</span>
    rewrite /redirect.html /index.html redirect<span class="pl-k">;</span>
    <span class="pl-c"># 访问 /permanent.html 的时候，页面直接301定向到 /index.html中</span>
    rewrite /permanent.html /index.html permanent<span class="pl-k">;</span>
    <span class="pl-c"># 把 /html/*.html =&gt; /post/*.html ，301定向</span>
    rewrite ^/html/(.+<span class="pl-k">?</span>).html$ /post/<span class="pl-smi">$1</span>.html permanent<span class="pl-k">;</span>
    <span class="pl-c"># 把 /search/key =&gt; /search.html?keyword=key</span>
    rewrite ^/search<span class="pl-cce">\/</span>([^<span class="pl-cce">\/</span>]+<span class="pl-k">?</span>)(<span class="pl-cce">\/</span><span class="pl-k">|</span>$) /search.html<span class="pl-k">?</span>keyword=<span class="pl-smi">$1</span> permanent<span class="pl-k">;</span>
}</pre>
</div>
<p>last和break的区别 因为301和302不能简单的只返回状态码，还必须有重定向的URL，这就是return指令无法返回301,302的原因了。这里 last 和 break 区别有点难以理解：</p>
<ul>
<li>last一般写在server和if中，而break一般使用在location中</li>
<li>last不终止重写后的url匹配，即新的url会再从server走一遍匹配流程，而break终止重写后的匹配</li>
<li>break和last都能组织继续执行后面的rewrite指令</li>
</ul>
<p>在<code>location</code>里一旦返回<code>break</code>则直接生效并<strong>停止后续的匹配</strong><code>location</code></p>
<div class="highlight highlight-source-shell">
<pre>server {
    location / {
        rewrite /last/ /q.html last<span class="pl-k">;</span>
        rewrite /break/ /q.html <span class="pl-c1">break</span><span class="pl-k">;</span>
    }
    location = /q.html {
        <span class="pl-k">return</span> 400<span class="pl-k">;</span>
    }
}</pre>
</div>
<ul>
<li>访问/last/时重写到/q.html，然后使用新的uri再匹配，正好匹配到locatoin = /q.html然后返回了400</li>
<li>访问/break时重写到/q.html，由于返回了break，则直接停止了</li>
</ul>
<h1><a id="user-content-if判断" class="anchor" href="https://github.com/Y4er/MyBlog/blob/master/content/post/nginx-rewrite.md#if%E5%88%A4%E6%96%AD" aria-hidden="true"></a>if判断</h1>
<p>只是上面的简单重写很多时候满足不了需求，比如需要判断当文件不存在时、当路径包含xx时等条件，则需要用到if 当表达式只是一个变量时，如果值为空或任何以0开头的字符串都会当做false 直接比较变量和内容时，使用=或!= <del>正则表达式匹配，</del>*不区分大小写的匹配，!~区分大小写的不匹配 一些内置的条件判断：</p>
<ul>
<li>-f和!-f用来判断是否存在文件</li>
<li>-d和!-d用来判断是否存在目录</li>
<li>-e和!-e用来判断是否存在文件或目录</li>
<li>-x和!-x用来判断文件是否可执行</li>
</ul>
<p>内置的全局变量</p>
<div class="highlight highlight-source-shell">
<pre><span class="pl-smi">$args</span> ：这个变量等于请求行中的参数，同<span class="pl-smi">$query_string</span>
<span class="pl-smi">$content_length</span> ： 请求头中的Content-length字段。
<span class="pl-smi">$content_type</span> ： 请求头中的Content-Type字段。
<span class="pl-smi">$document_root</span> ： 当前请求在root指令中指定的值。
<span class="pl-smi">$host</span> ： 请求主机头字段，否则为服务器名称。
<span class="pl-smi">$http_user_agent</span> ： 客户端agent信息
<span class="pl-smi">$http_cookie</span> ： 客户端cookie信息
<span class="pl-smi">$limit_rate</span> ： 这个变量可以限制连接速率。
<span class="pl-smi">$request_method</span> ： 客户端请求的动作，通常为GET或POST。
<span class="pl-smi">$remote_addr</span> ： 客户端的IP地址。
<span class="pl-smi">$remote_port</span> ： 客户端的端口。
<span class="pl-smi">$remote_user</span> ： 已经经过Auth Basic Module验证的用户名。
<span class="pl-smi">$request_filename</span> ： 当前请求的文件路径，由root或alias指令与URI请求生成。
<span class="pl-smi">$scheme</span> ： HTTP方法（如http，https）。
<span class="pl-smi">$server_protocol</span> ： 请求使用的协议，通常是HTTP/1.0或HTTP/1.1。
<span class="pl-smi">$server_addr</span> ： 服务器地址，在完成一次系统调用后可以确定这个值。
<span class="pl-smi">$server_name</span> ： 服务器名称。
<span class="pl-smi">$server_port</span> ： 请求到达服务器的端口号。
<span class="pl-smi">$request_uri</span> ： 包含请求参数的原始URI，不包含主机名，如：”/foo/bar.php<span class="pl-k">?</span>arg=baz”。
<span class="pl-smi">$uri</span> ： 不带请求参数的当前URI，<span class="pl-smi">$uri</span>不包含主机名，如”/foo/bar.html”。
<span class="pl-smi">$document_uri</span> ： 与<span class="pl-smi">$uri</span>相同。</pre>
</div>
<p>举个例子</p>
<div class="highlight highlight-source-shell">
<pre><span class="pl-c"># 如果文件不存在则返回400</span>
<span class="pl-k">if</span> (<span class="pl-k">!</span>-f <span class="pl-smi">$request_filename</span>) {
    <span class="pl-k">return</span> 400<span class="pl-k">;</span>
}
<span class="pl-c"># 如果host不是example.com，则301到example.com中</span>
<span class="pl-k">if</span> ( <span class="pl-smi">$host</span> <span class="pl-k">!</span>= <span class="pl-s"><span class="pl-pds">'</span>example.com<span class="pl-pds">'</span></span> ){
    rewrite ^/(.<span class="pl-k">*</span>)$ https://example.com/<span class="pl-smi">$1</span> permanent<span class="pl-k">;</span>
}
<span class="pl-c"># 如果请求类型不是POST则返回405</span>
<span class="pl-k">if</span> (<span class="pl-smi">$request_method</span> = POST) {
    <span class="pl-k">return</span> 405<span class="pl-k">;</span>
}
<span class="pl-c"># 如果参数中有 a=1 则301到指定域名</span>
<span class="pl-k">if</span> (<span class="pl-smi">$args</span> <span class="pl-k">~</span> a=1) {
    rewrite ^ http://example.com/ permanent<span class="pl-k">;</span>
}</pre>
</div>
<h1><a id="user-content-location" class="anchor" href="https://github.com/Y4er/MyBlog/blob/master/content/post/nginx-rewrite.md#location" aria-hidden="true"></a>location</h1>
<p>在server块中使用，如：</p>
<div class="highlight highlight-source-shell">
<pre>server {
    location 表达式 {
    }
}</pre>
</div>
<p>location表达式类型</p>
<ul>
<li>如果直接写一个路径，则匹配该路径下的</li>
<li>~ 表示执行一个正则匹配，区分大小写</li>
<li>~* 表示执行一个正则匹配，不区分大小写</li>
<li>^~ 表示普通字符匹配。使用前缀匹配。如果匹配成功，则不再匹配其他location。</li>
<li>= 进行普通字符精确匹配。也就是完全匹配。 优先级</li>
</ul>
<ol>
<li>等号类型（=）的优先级最高。一旦匹配成功，则不再查找其他匹配项。</li>
<li>^~类型表达式。一旦匹配成功，则不再查找其他匹配项。</li>
<li>正则表达式类型（~ ~*）的优先级次之。如果有多个location的正则能匹配的话，则使用正则表达式最长的那个。</li>
<li>常规字符串匹配类型。按前缀匹配。</li>
</ol>
<p>例子 &#8211; 假地址掩饰真地址</p>
<div class="highlight highlight-source-shell">
<pre>server {
    <span class="pl-c"># 用 test_admin 来掩饰 admin</span>
    location / {
        <span class="pl-c"># 使用break拿一旦匹配成功则忽略后续location</span>
        rewrite /test_admin /admin <span class="pl-c1">break</span><span class="pl-k">;</span>
    }
    <span class="pl-c"># 访问真实地址直接报没权限</span>
    location /admin {
        <span class="pl-k">return</span> 403<span class="pl-k">;</span>
    }
}</pre>
</div>
<h1><a id="user-content-实际应用" class="anchor" href="https://github.com/Y4er/MyBlog/blob/master/content/post/nginx-rewrite.md#%E5%AE%9E%E9%99%85%E5%BA%94%E7%94%A8" aria-hidden="true"></a>实际应用</h1>
<p>在上篇文章中auxpi图床直接访问是本地的图床，而且在后台即使关闭本地图床，也仍然会显示在首页，用户直接上传会报错，那么我们要做的就是让访问的时候跳转到别的图床。</p>
<p>要求</p>
<ul>
<li>直接访问 <a href="https://static.chabug.org/" rel="nofollow">https://static.chabug.org/</a> 跳转到 <a href="https://static.chabug.org/Ali" rel="nofollow">https://static.chabug.org/Ali</a></li>
<li>别的url例如<a href="https://static.chabug.org/Jd" rel="nofollow">https://static.chabug.org/Jd</a> 不跳转</li>
<li>不能更改网页的其他url地址。</li>
</ul>
<p>直接放上我的配置文件</p>
<div class="highlight highlight-source-shell">
<pre>server
{
    listen 80<span class="pl-k">;</span>
    listen 443 ssl http2<span class="pl-k">;</span>
    server_name static.chabug.org<span class="pl-k">;</span>
    index index.php index.html index.htm default.php default.htm default.html<span class="pl-k">;</span>
    root /www/wwwroot/static.chabug.org<span class="pl-k">;</span>
    rewrite <span class="pl-s"><span class="pl-pds">"</span>^/$<span class="pl-pds">"</span></span> https://static.chabug.org/Ali <span class="pl-c1">break</span><span class="pl-k">;</span>
    <span class="pl-c">#SSL-START SSL相关配置，请勿删除或修改下一行带注释的404规则</span>
    <span class="pl-c">#error_page 404/404.html;</span>
    <span class="pl-c">#HTTP_TO_HTTPS_START</span>
    <span class="pl-k">if</span> (<span class="pl-smi">$server_port</span> <span class="pl-k">!</span>~ 443){
        rewrite ^(/.<span class="pl-k">*</span>)$ https://<span class="pl-smi">$host</span><span class="pl-smi">$1</span> permanent<span class="pl-k">;</span>
    }
    <span class="pl-c">#HTTP_TO_HTTPS_END</span>
    ssl_certificate    /www/server/panel/vhost/cert/static.chabug.org/fullchain.pem<span class="pl-k">;</span>
    ssl_certificate_key    /www/server/panel/vhost/cert/static.chabug.org/privkey.pem<span class="pl-k">;</span>
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3<span class="pl-k">;</span>
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:<span class="pl-k">!</span>aNULL:<span class="pl-k">!</span>MD5:<span class="pl-k">!</span>RC4:<span class="pl-k">!</span>DHE<span class="pl-k">;</span>
    ssl_prefer_server_ciphers on<span class="pl-k">;</span>
    ssl_session_cache shared:SSL:10m<span class="pl-k">;</span>
    ssl_session_timeout 10m<span class="pl-k">;</span>
    error_page 497  https://<span class="pl-smi">$host$request_uri</span><span class="pl-k">;</span>

    <span class="pl-c">#SSL-END</span>
    
    <span class="pl-c">#ERROR-PAGE-START  错误页配置，可以注释、删除或修改</span>
    <span class="pl-c">#error_page 404 /404.html;</span>
    <span class="pl-c">#error_page 502 /502.html;</span>
    <span class="pl-c">#ERROR-PAGE-END</span>
    
    <span class="pl-c">#PHP-INFO-START  PHP引用配置，可以注释或修改</span>
    <span class="pl-c">#清理缓存规则</span>
    location <span class="pl-k">~</span> /purge(/.<span class="pl-k">*</span>) {
        proxy_cache_purge cache_one <span class="pl-smi">$host</span><span class="pl-smi">$1</span><span class="pl-smi">$is_args$args</span><span class="pl-k">;</span>
        <span class="pl-c">#access_log  /www/wwwlogs/static.chabug.org_purge_cache.log;</span>
    }
	<span class="pl-c">#引用反向代理规则，注释后配置的反向代理将无效</span>
	include /www/server/panel/vhost/nginx/proxy/static.chabug.org/<span class="pl-k">*</span>.conf<span class="pl-k">;</span>

	<span class="pl-c">#include enable-php-00.conf;</span>
    <span class="pl-c">#PHP-INFO-END</span>
    
    <span class="pl-c">#REWRITE-START URL重写规则引用,修改后将导致面板设置的伪静态规则失效</span>
    <span class="pl-c">#include /www/server/panel/vhost/rewrite/static.chabug.org.conf;</span>
    <span class="pl-c">#REWRITE-END</span>
    
    <span class="pl-c">#禁止访问的文件或目录</span>
    location <span class="pl-k">~</span> ^/(<span class="pl-cce">\.</span>user.ini<span class="pl-k">|</span><span class="pl-cce">\.</span>htaccess<span class="pl-k">|</span><span class="pl-cce">\.</span>git<span class="pl-k">|</span><span class="pl-cce">\.</span>svn<span class="pl-k">|</span><span class="pl-cce">\.</span>project<span class="pl-k">|</span>LICENSE<span class="pl-k">|</span>README.md)
    {
        <span class="pl-k">return</span> 404<span class="pl-k">;</span>
    }
    
    <span class="pl-c">#一键申请SSL证书验证目录相关设置</span>
    location <span class="pl-k">~</span> <span class="pl-cce">\.</span>well-known{
        allow all<span class="pl-k">;</span>
    }
    
    access_log  /www/wwwlogs/static.chabug.org.log<span class="pl-k">;</span>
    error_log  /www/wwwlogs/static.chabug.org.error.log<span class="pl-k">;</span>
}</pre>
</div>
<p>重点就在于<code>rewrite "^/$" https://static.chabug.org/Ali break;</code> break的使用</p>
<p>本文参考链接:</p>
<ul>
<li><a href="https://github.com/aimerforreimu/auxpi/wiki/%E4%BD%BF%E7%94%A8%E5%AE%9D%E5%A1%94%E8%BF%9B%E8%A1%8C%E5%AE%89%E8%A3%85">使用宝塔进行安装auxpi图床</a></li>
<li><a href="http://www.linuxeye.com/configuration/2657.html" rel="nofollow">http://www.linuxeye.com/configuration/2657.html</a></li>
<li><a href="http://seanlook.com/2015/05/17/nginx-location-rewrite/" rel="nofollow">http://seanlook.com/2015/05/17/nginx-location-rewrite/</a></li>
</ul>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
