长毛象很好,但是如果你所在的实例被墙了,那就不好了。 虽然可以爬梯子,但终究是有一点不方便。 这种不方便,在墙内推广自己实例时,体现的尤为明显。

本文将介绍如何通过 nginx 反代,让长毛象实例可以通过替代域名访问。

对于被墙实例可以通过反代,在新域名复活。对于没有被墙的实例,也可以通过反代为实例添加小号功能。


Chrome 不像 Firefox 不支持容器功能,所以对于同一个实例,Chrome 用户只能同时登录一个账号。 通过反代增加新域名后,用户便可使用不同域名同时登录多个账号,进而获得小号功能。

点击这里,体验小号功能。

nginx.conf

编辑你的站点配置文件,添加如下内容。

以下配置,使用时只需要将 bgme.memstdn.0x77.cf 根据自己的需求替换即可。

如果反代站点未使用 CDN 或使用 Cloudfare,请去除相应行的注释。(其它 CDN 请自行处理) 因为需要源站配合,所以并没有什么卵用。

map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=CACHE:10m inactive=7d max_size=1g;

server {
    listen 80;
    listen [::]:80;
    server_name mstdn.0x77.cf;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    set $origin_domain bgme.me;
    server_name mstdn.0x77.cf;

    ssl_protocols TLSv1.2;
    ssl_ciphers HIGH:!MEDIUM:!LOW:!aNULL:!NULL:!SHA;
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;

    keepalive_timeout    70;
    sendfile             on;
    client_max_body_size 80m;

    gzip on;
    gzip_disable "msie6";
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_buffers 16 8k;
    gzip_http_version 1.1;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

    resolver 8.8.8.8;

    location / {
        try_files $uri @proxy;
    }

    location @proxy {

        # 开启 SNI
        proxy_ssl_server_name on;
        proxy_ssl_protocols TLSv1.2;
        proxy_ssl_ciphers HIGH:!MEDIUM:!LOW:!aNULL:!NULL:!SHA;

        # 把返回的 302 重定向的域名替换成你的。
        proxy_redirect https://$origin_domain https://$server_name;

        # 替换指定字符串
        sub_filter '<a href="https://$origin_domain' '<a href="https://$server_name';
        sub_filter '<a target="sidekiq" href="https://$origin_domain' '<a target="sidekiq" href="https://$server_name';
        sub_filter '<a target="pghero" href="https://$origin_domain' '<a target="pghero" href="https://$server_name';
        sub_filter 'https://$origin_domain/system/' 'https://$server_name/system/';
        #字符串只进行一次替换,即只替换第一个被匹配的字符串。这里关闭。
        sub_filter_once off;
        #替换的请求类型,增加 application/json 。
        sub_filter_types application/json;

        # 指定头部:
        proxy_set_header Host $origin_domain;
        #未使用 CDN,请去除下两行的注释。需要源站配合,并没有什么卵用。
        #proxy_set_header X-Real-IP $remote_addr;
        #proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        #使用 Cloudflare,请去除下两行的注释。需要源站配合,并没有什么卵用。
        #proxy_set_header X-Real-IP $http_cf_connecting_ip;
        #proxy_set_header X-Forwarded-For $http_x_forwarded_for;
        proxy_set_header User-Agent $http_user_agent;
        proxy_set_header X-Forwarded-Proto https;
        #防止返回压缩的内容,因为压缩的内容无法替换字符串
        proxy_set_header Accept-Encoding "";

        # 传递相关字段
        proxy_pass_header Server;

        # 把 cookie 的作用域替换成你的域名
        proxy_cookie_domain $origin_domain $server_name;

        proxy_pass https://$origin_domain;

        # 开启缓存
        proxy_buffering on;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
        proxy_cache CACHE;
        proxy_cache_valid 200 7d;
        proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
        add_header X-Cached $upstream_cache_status;
        add_header Strict-Transport-Security "max-age=31536000";

        tcp_nodelay on;
    }

    # 将 inbox、.well-known 重定向至源站
    location ~ inbox$ {
        return 307 https://$origin_domain$request_uri;
    }

    location /.well-known {
        return 307 https://$origin_domain$request_uri;
    }
}

添加完成后,重载 nginx 服务。

nginx -s reload

为了方便部署,可使用下面的脚本,快速进行。

ORIGIN_DOMAIN=origin_site_domain
ALTER_DOMAIN=your_site_domain
cd /etc/nginx/sites-available
wget https://blog.bgme.me/listings/mastodon_reverser_proxy.conf -O ${ALTER_DOMAIN}
sed -i -e "s/bgme\.me/${ORIGIN_DOMAIN}/g" -e "s/mstdn\.0x77\.cf/${ALTER_DOMAIN}/g" ${ALTER_DOMAIN}
cd ../sites-enabled/
ln -s /etc/nginx/sites-available/${ALTER_DOMAIN} .
nginx -s reload

获取证书

写入上述配置文件之后,还需要获取证书。

certbot --nginx

将 DNS 直接指向反代的服务器,运行上述命令,根据交互提示一步步向下走就可以了。

certbot 将在配置文件中写入以下内容。

if ($host = mstdn.0x77.cf) {
    return 301 https://$host$request_uri;
} # managed by Certbot
ssl_certificate /etc/letsencrypt/live/mstdn.0x77.cf/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/mstdn.0x77.cf/privkey.pem; # managed by Certbot

Bingo!到此反代长毛象就完成了。

安全提醒

反代这种事情是谁都可以做的,并不需要官方的授权。所以很可能被人用于钓鱼攻击。

使用替代域名登录实例之前,请一定要确认这个替代域名是官方建立的。

上面两个地址是我反代的草莓县和邦站。感兴趣的可以使用不重要的小号来实验一下。

虽然我并不会对上面的两个反代动什么手脚,但是防人之心不可无。

为了安全起见,也请你不要放警戒之心。