[Pixiv] 真·反代P站
前言
本文所述的所有内容仅供交流学习,请勿实际做出任何违反国家法律的行为!
此方案为真的反代,而不是在本地反代以绕过 SNI 审查的方法(Mashiro - PIXIV网页版及客户端访问恢复指南)
请不要在互联网上公开自己搭建的反代站,P 站可能会发邮件到您的主机商投诉。如果您因为此种原因导致 VPS 服务等被终止,本人不负任何责任。
准备
一台没被P站屏蔽的主机
众所周知 Vultr 大部分IP段都被P站屏蔽
一个域名
可以使用新域名,也可以用自己域名的二级(只是域名会变得比较长)
后续均以example.com来指代我们使用的域名,请灵活代换
使用“不需要通过验证站点文件来签发/续签”并且最好还支持泛域名的 SSL 证书
这里我们自然首推 Let’s Encrypt,这是看起来唯一符合所有需求并且还免费的证书
需要使用的域名
在反代时我们需要用到以下几个域
如果使用一个新域名专门反代:
example.com
*.example.com
*.pximg.example.com
example.com
随意,你可以放点自己的东西做一些伪装或者说明,或者直接301到www.example.com
*.example.com
用于反代对齐*.pixiv.net
*.pximg.example.com
用于反代对齐*.pximg.net,其实该域名中的pximg也可以替换成其他的字符串,只要不与P站的二级域名服务产生冲突即可
各自作用同上,在后续配置上灵活修改即可
获取证书
如果你愿意套CloudFlare,你可以跳过这一节
使用 acme 的 DNS API 方式进行挑战验证来签发证书是最方便的
参考以下文章:
使用 acme.sh 申请 Let’s Encrypt 泛域名SSL证书详细教程
在配置好 API 之后我们使用这样的命令签发一个我们想要的三域名合一的证书,且还能自动续签
~/.acme.sh/acme.sh --issue --dns dns_dp -d example.com -d '*.example.com' -d '*.pximg.example.com
Nginx的配置与详解
Nginx的配置与详解
注:以下配置建议和本站中的配置一个好用的nginx搭配使用
主要配置与详解
#创建新文件:/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
监听80与443端口,并使用ssl
include
引入代理的证书文件
server_name与set
使用正则表达式匹配以方便直接提取出我们要反代的二级域名
resolver
必要,指定域名解析所用 DNS,因为在后续proxy_pass中我们要反代的域名是由$domain决定,本身是不定的,Nginx 必须被指定 DNS 才能处理域名解析
proxy_cookie_domain
改变反代后返回的 header 中set-cookie里cookie对应的域名,只在*.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运作的一些功能的异常
证书配置
#创建新文件:/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添加此句
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 导出,替换域名,然后导入反代站来进行登录
--------------------------------------
登陆问题可以通过proxy_set_header Cookie $cookies;解决
同时设置
location = /logout.php{
return 302 xxx;
}
以及各种/create使账号仅供浏览