proxy-to-subpath-with-nginx

使用nginx将网站反代值二级目录。

问题描述

现有一个不能增加二级域名的的网站,希望使用该域名完整代理其他一个网站到一个二级路径,同时保证现有的服务仍然可用。

同时还有一个问题,需要将 https 的内容反代到 http,(登录 cookie有secure flag)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
unsecure_cookie *; # 这个需要自己编译附加模块
location ^~ /hudbt {
proxy_pass https://hudbt.hust.edu.cn/;
unsecure_cookie *;
proxy_cookie_path / /hudbt;
proxy_cookie_domain hudbt.hust.edu.cn $host;
sub_filter "hudbt.hust.edu.cn" $host;
proxy_redirect https://$host/index.php http://$host/hudbt/index.php;
proxy_redirect https://$host/login.php http://$host/hudbt/login.php;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 允许客户端请求的最大单文件字节数
client_max_body_size 10m;
# 缓冲区代理缓冲用户端请求的最大字节数
client_body_buffer_size 128k;
# nginx跟后端服务器连接超时时间(代理连接超时)
proxy_connect_timeout 300;
# 后端服务器数据回传时间(代理发送超时)
proxy_send_timeout 300;
# 连接成功后,后端服务器响应时间(代理接收 超时)
proxy_read_timeout 300;
# 设置代理服务器(nginx)保存用户头信息的缓冲区大小
proxy_buffer_size 4k;
#proxy_buffers缓冲区,网页平均在32k以下的话,这样设置
proxy_buffers 4 32k;
#高负荷下缓冲大小(proxy_buffers*2)
proxy_busy_buffers_size 64k;
#设定缓存文件夹大小,大于这个值,将从upstream服务器传
proxy_temp_file_write_size 64k;
# https to http
if ($scheme = https) {
rewrite ^(.*)? http://$http_host$1 permanent;
}
}
if ( $request_uri ~* ^/(cache|attachments|pic|styles)/ ) {
rewrite ^/(cache|attachments|pic|styles)/(.*)$ /hudbt/$1/$2 permanent;
}
if ( $request_uri ~* ^/([a-z0-9]+\.php[a-z0-9&+?-_%@#=\.]*)$ ){
rewrite ^/(.*)$ /hudbt/$1 permanent;
}

unsecure_cookie *; 为编译附加其他模块引入,后面会提到。

location 用来将所有以hudbt开头的请求定向到反代域名https://hudbt.hust.edu.cn/

proxy_cookie_path 指定cookie有效链接范围,两个proxy_redirect用于修改登录后 301 跳转链接中的https,以及重定向至反代路径。

后面的 http to http 使用rewrite重定向至http链接,permanentflag表示地址栏也改成重定向后的链接。

后面两个 if 语句用于改写反代网站url至二级路径链接。第一个处理反代网站文件夹链接,第二个处理反代网站的所有php文件(包括含有参数的请求),这就要求原本网站不能有直接裸露在更目录的php文件。只需使用其他二级路径放原本裸露的php就能避免和反代冲突。

Secure Flag

如果Cookie中有此flag,则表示这个cookie只有用在https请求中,如果改成http,那么cookie就会丢失。还在有人提供了这个模块,nginx_unsecure_cookie_module,自己编译nginx,得到这个可以去掉 proxy cookie中secure的feature。

编译需要把必要的需求模块参数都加上,否则可能会提示很多功能不能用。

这里我直接查看 arch 源里面nginx的编译参数,加上上面模块即可,编译完成后 直接 替换nginx二进制可执行文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
./config --prefix=/etc/nginx \
--conf-path=/etc/nginx/nginx.conf \
--sbin-path=/usr/bin/nginx \
--pid-path=/run/nginx.pid \
--lock-path=/run/lock/nginx.lock \
--user=http \
--group=http \
--http-log-path=/var/log/nginx/access.log \
--error-log-path=stderr \
--http-client-body-temp-path=/var/lib/nginx/client-body \
--http-proxy-temp-path=/var/lib/nginx/proxy \
--http-fastcgi-temp-path=/var/lib/nginx/fastcgi \
--http-scgi-temp-path=/var/lib/nginx/scgi \
--http-uwsgi-temp-path=/var/lib/nginx/uwsgi \
--with-cc-opt='-march=x86-64 -mtune=generic -O2 -pipe -fno-plt -D_FORTIFY_SOURCE=2' \
--with-ld-opt=-Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now \
--with-compat \
--with-debug \
--with-file-aio \
--with-http_addition_module \
--with-http_auth_request_module \
--with-http_dav_module \
--with-http_degradation_module \
--with-http_flv_module \
--with-http_geoip_module \
--with-http_gunzip_module \
--with-http_gzip_static_module \
--with-http_mp4_module \
--with-http_realip_module \
--with-http_secure_link_module \
--with-http_slice_module \
--with-http_ssl_module \
--with-http_stub_status_module \
--with-http_sub_module \
--with-http_v2_module \
--with-mail \
--with-mail_ssl_module \
--with-pcre-jit \
--with-stream \
--with-stream_geoip_module \
--with-stream_realip_module \
--with-stream_ssl_module \
--with-stream_ssl_preread_module \
--with-threads \
--add-module=nginx_unsecure_cookie_module

后面的 --add-module即是额外的去除secure的模块。

如第二部分配置第一行所示,就可去除所有cookie中的额外 flag。

至此,使用http二级路径反代https网站成功。

参考文档