Nginx 反向代理 Sci-Hub

前言

  • Sci-Hub 是科研民工重要的学术工具,但是 Sci-Hub 特殊的情况导致其服务器的网络并不是很好,为了解决此问题,自建镜像站点以优化 Sci-Hub 的访问是十分有意义的;
  • 本教程基于 Ubuntu 18.04.6 LTS 制作,在阅读本教程前,希望您已具备 Linux 和 Nginx 相关知识

环境准备

  1. Nginx
  2. PCRE library: 本例中请使用 PCRE v1
  3. zlib
  4. OpenSSL

模块解析

  1. ngx_http_sub_module: 用于进行关键字替换;
  2. ngx_http_gunzip_module: 用于解决 gzip 后无法进行关键字替换的问题。

Nginx 编译

基础依赖

1
2
apt-get install build-essential
# 其他的缺什么补什么

所需依赖

1
2
3
> ls /usr/local/src

nginx-1.20.2 openssl-3.0.1 pcre-8.45 zlib-1.2.11

开始编译

1
2
3
4
5
6
7
8
9
10
11
12
13
14
> cd nginx-1.20.2
> ./configure \
--sbin-path=/usr/local/nginx/nginx \
--conf-path=/usr/local/nginx/nginx.conf \
--pid-path=/usr/local/nginx/nginx.pid \
--with-http_ssl_module \
--with-http_gzip_static_module \
--with-http_v2_module \
--with-http_sub_module\
--with-http_gunzip_module\
--with-pcre=../pcre-8.45 \
--with-zlib=../zlib-1.2.11 \
--with-openssl=../openssl-3.0.1
> make install

编译检查

1
2
3
4
5
6
7
> /usr/local/nginx/nginx -V

nginx version: nginx/1.20.2
built by gcc 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04)
built with OpenSSL 3.0.1 14 Dec 2021
TLS SNI support enabled
configure arguments: --sbin-path=/usr/local/nginx/nginx --conf-path=/usr/local/nginx/nginx.conf --pid-path=/usr/local/nginx/nginx.pid --with-http_ssl_module --with-http_gzip_static_module --with-http_v2_module --with-http_sub_module --with-http_gunzip_module --with-pcre=../pcre-8.45 --with-zlib=../zlib-1.2.11 --with-openssl=../openssl-3.0.1

环境变量

1
2
3
4
> ln -s /usr/local/nginx/nginx /usr/local/bin
> nginx -v

nginx version: nginx/1.20.2

开机自启

参考:https://www.nginx.com/resources/wiki/start/topics/examples/systemd/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[Unit]
Description=The NGINX HTTP and reverse proxy server
After=syslog.target network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target

[Service]
Type=forking
PIDFile=/usr/local/nginx/nginx/nginx.pid
ExecStartPre=/usr/local/nginx/nginx -t
ExecStart=/usr/local/nginx/nginx
ExecReload=/usr/local/nginx/nginx -s reload
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true

[Install]
WantedBy=multi-user.target

反向代理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
server {
resolver 8.8.8.8;
location / {
proxy_pass https://sci-hub.se;
proxy_set_header Host sci-hub.se;
proxy_set_header X-Forwarded-Proto "";
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass_request_headers on;
proxy_ssl_name sci-hub.se;
proxy_ssl_server_name on;
gunzip on;
gzip_disable ".";
sub_filter 'sci-hub.se' 'sci.example.com';
sub_filter_once off;
}
}

本代码参考自 Sci-Hub nginx reverse proxy setup,但该代码只是反代了主界面,而数据量最大的资源文件依然从原始站点获取,实际上并不能起到效果。

我这里加入了 sub_filter ,将全页面的所有原始站点链接全部替换为 sci.example.com,以达到良好的效果。需要注意的是,sub_filter 无法修改 gzip 后的页面,所以本例中使用 gunzipgzip_disable 来处理。

1
2
3
4
gunzip on;
gzip_disable ".";
sub_filter 'sci-hub.se' 'sci.example.com';
sub_filter_once off;

追加模块

Nginx 编译完成后,如果需要更新程序或者追加编译模块,只需要在原编译命令的基础上,增加你想要的模块,采用 make 而不是 make install 来编译即可。编译后的文件为 objs/nginx,将其替换原先的文件就可以啦。

1
2
3
4
5
6
7
8
9
> ./configure \
--sbin-path=/usr/local/nginx/nginx \
--conf-path=/usr/local/nginx/nginx.conf \
--pid-path=/usr/local/nginx/nginx.pid \
--with-http_ssl_module \
--... \
-- <modules you want to add>
> make
> cp -f objs/nginx /usr/local/nginx/nginx