Apache 模块

mod_rewrite

把 http 请求重定向到 https:

RewriteEngine on
RewriteCond %{HTTPS} !on
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}

把 example.com 重定向到 www.example.com,即 SEO 中重要的 301 重定向:

RewriteEngine on
RewriteCond %{HTTP_HOST} ^example\.com$ [NC]
RewriteRule ^(.*)$ http://www.example.com/$1 [R=301,L] 

如果你更钟爱 example.com 的形式,可以把 www.example.com 重定向到 example.com:

RewriteEngine on
RewriteCond %{HTTP_HOST} ^www\.example\.com$ [NC]
RewriteRule ^(.*)$ http://example.com/$1 [R=301,L] 

说明:

  • NC: No Case
  • R: Redirect, 表示重定向,默认是 302 重定向
  • L: Last, 如果匹配,则不往下执行其他 Rewrite Rules

RewriteCond 指令

只有符合 RewriteCond 指令声明的条件,才会继续往下执行 RewriteRule 指令。

RewriteCond TestString CondPattern

一、TestString 是条件判断的对象,常见的 TestString:

server-variables,以 %{NAME} 的形式,如:

  • %{HTTP_HOST}
  • %{HTTPS}
  • %{REQUEST_URI}

二、CondPatter 是用来匹配 TestString 的正则表达式,如果匹配成功,往下执行 RewriteRule 指令。

三、可以在 CondPattern 后附加 [flags],如:

  • NC: No Case
  • OR: OR next condition

RewriteRule 指令

RewriteRule 指令会执行实际的 URL 改写:

RewriteRule Pattern Substitution [flags]

一、Pattern 是正则表达式,用来匹配目标 URL。

二、Substitution 是你要用来替换目标 URL 的新 URL,可以用:

  • back-references($n), 引用 Pattern 中的模式。
  • server-variables

三、flags

  • L: Last, 如果匹配的话,就不往下执行啦
  • R: Redirect, 重定向,默认 302 重定向,可以设置 R=301
  • N: Next, 跳转到 Rules 开始的地方,相当于 goto-start,易导致无限循环,务必小心使用
  • NE: No Escape, 不对特殊字符转义

NE 表示 No Escape,不对特殊字符转义,如:

RewriteRule /anchor/(.+) /page.html#$1 [NE,R]

以上配置会将 /anchor/abc 重定向到 /page.html#abc,如果没有 NE,# 会被转为 %23,这可不是你想要的。

mod_proxy

mod_proxy 可以将 Apache 配置为一个代理服务器或使之成为一个网关,或让 Apache 扮演负债均衡的角色。通常而言,mod_proxy 需要和其他一些具体的代理实现模块搭配使用,这些模块用 LoadModule 指令加载,例如:

  • mod_proxy_balancer
  • mod_proxy_http
  • mod_proxy_http2
  • mod_proxy_uwsgi
  • mod_proxy_html

当需要缓存或安全链接时,应该搭配相应的模块使用:

  • mod_cache
  • mod_ssl 以及 SSLProxy* 指令

注意,mod_rewrite 也可将 Apache 配置为代理服务器,我们可以同时使用 mod_proxy 和 mod_rewrite。

概述

Apache 可以配置为代理服务(forward proxy)或反向代理(reverse proxy / gateway) 服务器。

代理服务(forward proxy)的场景,例如一个客户端要访问一个被防火墙屏蔽的网站 X,他可以先链接一个代理服务器 P,通过向代理服务器 P 访问 X。例如我们购买一个代理软件,它就会为我们提供一系列的服务器地址,这些服务器都叫代理服务器。

  • 使用 ProxyRequests 指令

反向代理(reverse proxy / gateway)的场景,例如我们有一堆服务,但只对客户开放一个访问入口 R,当 R 收到客户请求后将请求转发至最终的服务器 S,并在收到处理输出后发送给客户。

  • 使用 ProxyPass 指令,或
  • 使用 RewriteRule 指令加 [P]

-

一个最简单的示例:

ProxyPass           /mirror/foo/ http://backend.example.com/
ProxyPassReverse    /mirror/foo/ http://backend.example.com/

第一行,ProxyPass 将一个 URL 访问转发到后台,例如:

http://example.com/mirror/foo/bar

将被转发到:

http://backend.example.com/bar

第二行,ProxyPassReverse 指示 Apache 改写后台服务器发回的 HTTP 头,包括:Location, Content-Location, URI 这几部分。如果 HTML 代码里有 URL 需要改写,则应该搭配 mod_proxy_html 服用。这个指令会负责重定向,例如:

http://backend.example.com/bar

被重定向到:

http://backend.example.com/qux

那么客户端也将被重定向到新的 URL:

http://example.com/mirror/foo/qux

-

一个较为完整的示例:

LoadModule              proxy_module            modules/mod_proxy.so
LoadModule              proxy_http_module       modules/mod_proxy_http.so

ProxyRequests Off

ProxyPass           /images !
Alias               /images /var/local/www/images

ProxyPass           /mirror/foo/ http://backend.example.com/
ProxyPassReverse    /mirror/foo/ http://backend.example.com/

<Proxy http://backend.example.com/>
    Require all granted
    Options None
</Proxy>

解读:

  • ProxyRequests 表示关闭代理(forward proxy),因为我们配置的是反向代理(reverse proxy)
  • ProxyPass /images ! 表示这个路径的访问不转发,搭配 Alias 指令使用

搭配其他模块

mod_proxy_uwsgi

ProxyPass /uwsgi-bin/ uwsgi://localhost:4000/

mod_proxy 参考