date:
updated:

[Pixiv] 真·反代P站


前言

本文所述的所有内容仅供交流学习,请勿实际做出任何违反国家法律的行为!

此方案为真的反代,而不是在本地反代以绕过 SNI 审查的方法(Mashiro - PIXIV网页版及客户端访问恢复指南

请不要在互联网上公开自己搭建的反代站,P 站可能会发邮件到您的主机商投诉。如果您因为此种原因导致 VPS 服务等被终止,本人不负任何责任。

准备

  1. 一台没被P站屏蔽的主机
  2. 众所周知 Vultr 大部分IP段都被P站屏蔽
  3. 一个域名
    可以使用新域名,也可以用自己域名的二级(只是域名会变得比较长)
    后续均以example.com来指代我们使用的域名,请灵活代换
  4. 使用“不需要通过验证站点文件来签发/续签”并且最好还支持泛域名的 SSL 证书
    这里我们自然首推 Let’s Encrypt,这是看起来唯一符合所有需求并且还免费的证书

需要使用的域名

在反代时我们需要用到以下几个域

  • 如果使用一个新域名专门反代:

    1
    2
    3
    example.com
    *.example.com
    *.pximg.example.com
    • example.com
      随意,你可以放点自己的东西做一些伪装或者说明,或者直接301www.example.com
    • *.example.com
      用于反代对齐*.pixiv.net
    • *.pximg.example.com
      用于反代对齐*.pximg.net,其实该域名中的pximg也可以替换成其他的字符串,只要不与P站的二级域名服务产生冲突即可
  • 如果使用一个自己正在使用的域名反代,且不想影响该域名的其他服务:

1
2
3
pixiv.example.com
*.pixiv.example.com
*.pximg.example.com

各自作用同上,在后续配置上灵活修改即可

获取证书

如果你愿意套 CloudFlare,你可以跳过这一节
使用 acme 的 DNS API 方式进行挑战验证来签发证书是最方便的

参考以下文章:
使用 acme.sh 申请 Let’s Encrypt 泛域名SSL证书详细教程

在配置好 API 之后我们使用这样的命令签发一个我们想要的三域名合一的证书,且还能自动续签

1
~/.acme.sh/acme.sh --issue --dns dns_dp -d example.com -d '*.example.com' -d '*.pximg.example.com

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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#创建新文件:/etc/nginx/sites/pixiv0.conf

# *.example.com
server
{
listen 80;
listen 443 ssl;
include /etc/nginx/sites/phttps.conf;
server_name ~^([^.]+)\.example\.com$;
set $domain $1;
resolver 8.8.8.8;
location ~ .*
{
proxy_set_header Host $domain.pixiv.net;
proxy_set_header Referer "https://www.pixiv.net";
proxy_cookie_domain pixiv.net example.com;
proxy_pass https://$domain.pixiv.net;
proxy_ssl_server_name on;
proxy_set_header Accept-Encoding "";
proxy_redirect https://accounts.pixiv.net/ https://accounts.example.com/;

sub_filter "i-cf.pximg.net" "i.example.com";
sub_filter "pixiv.net" "example.top";
sub_filter "pximg.net" "pximg.example.com";
# 防止错误上报暴露站点
sub_filter "js_error.php" "block_js_error";
# 防止谷歌服务暴露站点,同时也可以加快网站加载
sub_filter "www.google" "block_google";
sub_filter_once off;
sub_filter_types *;
}
}

# *.pximg.example.com
server
{
listen 80;
listen 443 ssl;
include /etc/nginx/sites/phttps.conf;
server_name ~^([^.]+)\.pximg\.example\.com$;
set $domain $1;
resolver 8.8.8.8;
location ~ .*
{
proxy_set_header Host $domain.pximg.net;
proxy_set_header Referer "https://www.pixiv.net";
proxy_pass https://$domain.pximg.net;
proxy_ssl_server_name on;
proxy_set_header Accept-Encoding "";

sub_filter "www.google.com/recaptcha" "www.recaptcha.net/recaptcha";
sub_filter "i-cf.pximg.net" "i.example.com";
sub_filter "pixiv.net" "feilongproject.com";
sub_filter "pximg.net" "pximg.example.com";
# 防止错误上报暴露站点
sub_filter "js_error.php" "block_js_error";
# 防止谷歌服务暴露站点,同时也可以加快网站加载
sub_filter "www.google" "block_google";
sub_filter_once off;
sub_filter_types *;
}
}
  • listen
    监听80443端口,并使用ssl
  • include
    引入代理的证书文件
  • server_nameset
    使用正则表达式匹配以方便直接提取出我们要反代的二级域名
  • resolver
    必要,指定域名解析所用 DNS,因为在后续proxy_pass中我们要反代的域名是由$domain决定,本身是不定的,Nginx 必须被指定 DNS 才能处理域名解析
  • proxy_cookie_domain
    改变反代后返回的 header 中set-cookiecookie对应的域名,只在*.example.com中需要,是解决登陆问题的关键
  • proxy_ssl_server_name
    由于 P 站开始上 CF 了,其 TLS 启用了 SNI,因此必须指定此项为on,否则会握手失败
  • proxy_set_header Referer
    设置header中的 Referer,主要目的是解决i.pximg.net的防盗链问题,以及www.pixiv.net的部分 API 的 Referer 验证问题
  • proxy_set_header Accept-Encoding
    将接受的压缩编码设为空,即不接受压缩,因为sub_filter无法对压缩过的内容起效
  • proxy_redirect
    将返回原站 302 的请求进行重定向
  • sub_filter
    将反代后得到的内容进行字符串替换,以保证链接域名等与反代域名一致
  • sub_filter_types
    必须设置为*,否则默认对于 API 返回的 json 内容等不会进行替换,会导致依靠ajax运作的一些功能的异常

证书配置

1
2
3
4
#创建新文件:/etc/nginx/sites/phttps.conf
ssl_certificate /etc/nginx/cert/pixiv.cer;
ssl_certificate_key /etc/nginx/cert/pixiv.key;
ssl_trusted_certificate /etc/nginx/cert/pixiv.cer;

增强隐蔽性(建议)

防止被搜索引擎收录

在 Nginx 配置中向每个server添加此句

1
2
3
if ($http_user_agent ~* "qihoobot|Baiduspider|Googlebot|Googlebot-Mobile|Googlebot-Image|Mediapartners-Google|Adsbot-Google|Feedfetcher-Google|Yahoo! Slurp|Yahoo! Slurp China|YoudaoBot|Sosospider|Sogou spider|Sogou web spider|MSNBot|ia_archiver|Tomato Bot|^$") {
return 403;
}

请加到set $domain $1;这句之后,因为该配置也使用了正则表达式,会导致$1改变

禁止大陆外IP访问

由于反代P站的受众只可能为大陆内用户,因此我们完全可以禁止大陆外IP访问反代站,同时还能防止P站检测投诉

但请注意,这个方案是对整台 VPS 的80与443端口生效,这意味着你如果同时在 VPS 上布置了其他站点,他们也将无法被大陆外用户访问

如果需要仅对反代站点生效,请自行百度参考nginx geoip

结语

局限性

  • 不能使用绑定的社交账号的登录方式
  • 帐号可能会出现需要 reCAPTCHA 验证导致无法登录(目前无解),只能自己将原站已登录的 cookie 导出,替换域名,然后导入反代站来进行登录

配置一个好用的nginx Next →
生活不易,给点打赏可好?
支付宝 | Alipay
微信 | WeChat