搭建适用于notion的国内HTTPS代理

家里网络线路不太好, 使用用notion简直劝退, 偶然之中发现阿里云连接notion不丢包, 于是选择了阿里云来搭建代理, 建好之后, 连接简直飞速, 于是写下这个教程, 希望能对同样热爱notion的你我有所帮助. 若自己觉得搭建太麻烦, 也可以使用现成的代理. 如何配置HTTPS代理, 也见此页面.

云服务器

首先你得有一台云服务器, 唯一对云服务器的要求即是宽带, 一方面是足够大的宽带, 一般而言, 若有5Mbps, 则够好几人一起用了, 若只有1Mbps, 一个人用的都够呛. 另一方面是线路的选择, 初步经验的判断, 阿里云上海的服务器连接notion延迟较低(140ms), 因此我选择阿里云上海的服务器, 也可以根据自己的喜好和条件选择合适的云服务商.
购买云服务器的步骤略过, SSH连接的方法这里也不赘述, 可以自行百度搜索, 有很多教程.
接下来我将选择系统版本为 Ubuntu 20.04 作为例子, 其他的Linux发行版与此类似
拿到一台新的云服务器之后, SSH连接, 先更新系统, 输入

sudo apt update && sudo apt upgrade -y

如果你是用非root用户登录, 则需要输入密码, 直接输入就行了, 不过你是看不到的.
然后你会看到很多很多的英文字符和数字. 如果中间出现了什么特殊的画面, 直接回车就行. 等到最下面的progress完成后, 输入如下命令重启远程服务器

reboot

然后, 再次SSH登录

安装tinyproxy并配置

输入以下命令安装tinyproxy

sudo apt install tinyproxy -y

进入tinyproxy的配置文件夹

cd /etc/tinyproxy

此时我们进入了tinyproxy的文件夹, 你会看到终端的显示由 [email protected]:~# 变成了 [email protected]/xxxxx: etc/tinyproxy# , 查看当前目录下的文件

[email protected]:/etc/tinyproxy# dir
tinyproxy.conf

发现只有一个tinyproxy.conf 这一配置文件, 于是打开它并编辑它, 在SSH中, 只能使用命令行界面编辑文件, 我用的是 vim . 操作上用的其实也不是传统的vim方法, 也比较简单. 编辑tinyproxy.conf文件(因为我用的root用户登录的, 所以不存在权限问题)

vim tinyproxy.conf

然后会看到这样一个界面

配置文件中, 每一行都是独立的, 若一行前面有#, 则表示这一行是注释, 不起任何效果.
接下来, 切换到英文输入法, 方便操作
输入 i , 就会发现左下角多了个INSERT, 表明此时你可以用一般word的方法输入或修改了, 但是只能用键盘.

按键盘中的 上下左右的 "下" 键 可以往下滚动查看文件
找到 MaxSpareServers 20 改为 MaxSpareServers 1024 , 改这一项的目的好像是为了方便更多的人访问, 如果你一个人用, 可以不改
找到 Allow 这里, 这一部分表示可以访问此代理的ip地址, 如果你想开放http代理, 则把 Allow 127.0.0.1 前面输入一个# , 以达到允许所有ip地址的效果. 我这里没有更改(因为我选择不开放http代理

找到 Filter 这里, 这一部分的意思是tinyproxy 可访问目标的配置文件地址, 直接取消前面的 # 以达到开启过滤的效果

找到 FilterDefualtDeny 这里, 去掉最后一行前面的 # (前面的几行都是说明注释, 不可去掉). 如果不去掉 # 或者改为 FilterDefualtDeny No , 表明你上面的过滤文件是黑名单(只不能访问这些地址). 而改成FilterDefualtDeny Yes 即是白名单(只能访问这些地址, 以防自己的代理被滥用)

编辑好之后, 先按一下Esc , 你会发现, 左下角的Insert 消失了, 然后按shift : 会发现左下角出现了一个: , 然后 输入 wq , 然后回车, 以便达到保存和退出出的效果.

接下来, 我们由回到了命令行界面, 然后编辑过滤文件(这个文件本身是不存在的, 但是vim会自动创建)

vim /etc/tinyproxy/filter

同样输入i开始编辑, 写入我们需要允许访问的域名, 如果你的ssh工具支持粘贴, 直接粘贴就可以了, 如下, 这里的规则表示了主域名和其所有子域名. 你也可以根据自己的需要进行配置

amplitude.com
intercom.io
notion.so
loggly.com
segment.com
intercomcdn.com
unsplash.com
amazonaws.com

然后Esc, shift :,wq, 回车退出保存. 重启tinyproxy以使配置文件生效

service tinyproxy restart

安装Stunnel并配置

输入如下命令安装stunnel

sudo apt install stunnel -y

进入stunnel的配置文件目录

cd /etc/stunnel

查看当前文件夹下的内容

dir

发现只有一个README, 因此我们要创建配置文件

vim stunnel.conf

输入

[https]
accept = 443
connect = 127.0.0.1:8888
cert = /etc/stunnel/tls/cert.pem
key = /etc/stunnel/tls/key.pem

这表明, 我们建立的这个服务的名字叫做https(理论上你叫什么名字都可以), 输出的是443端口, 输入的是本地的8888端口(tinyproxyhttp端口), 下面两个是证书和密钥的位置(tls加密需要). 网上很多教程是自己本地生成证书, 这要求使用者需要自行导入证书, 太麻烦了, 因此我选择申请证书机构颁发的证书, 因为穷, 只能选择免费证书, 教程在这里.
得到证书后, 我们会有两个文件, 一个是full_chain.pem, 我们称之为证书, 另一个是 private.key我们称之为密钥. 然后我们进入我们预先选择的证书目录(目录不存在, 需要创建)

mkdir /etc/stunnel/tls && cd /etc/stunnel/tls

先粘贴我们的证书, 再粘贴我们的密钥, 在自己的电脑上, 选择用txt文本编辑器打开复制, 如果无法用文本编辑器打开, 则把文件的后缀改成txt再尝试

vim  /etc/stunnel/tls/cert.pem
vim /etc/stunnel/tls/key.pem

然后选择重启服务以使得配置生效

service stunnel4 restart 

完成后, 需要对你申请证书的域名增加A解析到你服务器的ip地址, 这里也不再赘述. 解析生效的时间最多10分钟.

开端口和验证

我所使用的阿里云服务器, 貌似没有用Linux自带的防火墙软件, 要在阿里云的界面开端口才有效. 而我用的是443端口, 其默认是开启的, 所有我也不用额外开端口. 直接验证即可
我选择的是chrome 浏览器的swithyoemga插件以实现验证. 新增一个代理模式. 选择https 协议, 输入地址和端口, 我代理服务器像这样

然后切换为该代理的全局模式

访问https://notion.so,未出现问题, 则表示白名单验证成功.
然而, 我们还是会发现有一些域名无法加载, 即使已经允许它访问了, 这就不是国内代理所不能解决的了, 但是并不影响使用

在同样的模式下, 访问 https://www.baidu.com出现此页面, 表示tinyproxy 的过滤规则有效, 你也可以访问其他页面以验证

编写pac文件

因为此https代理能只能访问notion 相关页面, 作为全局代理是很不合适的, 如果没有Swichyomega , 则会比较尴尬. 因此有一种方法叫做proxy auto config, 即通过一个pac文件实现代理自动配置. 然而我并不会会写pac文件(我不会javascript), 因此就选择选择用swichyoemga生成pac文件. 但是无论我怎么尝试, 怎么改变~~pac~~文件的写法, pac文件无法在我的安卓手机上起作用. 以下是Swichyomega导出的一个例子

var FindProxyForURL = function(init, profiles) {
    return function(url, host) {
        "use strict";
        var result = init, scheme = url.substr(0, url.indexOf(":"));
        do {
            result = profiles[result];
            if (typeof result === "function") result = result(url, host, scheme);
        } while (typeof result !== "string" || result.charCodeAt(0) === 43);
        return result;
    };
}("+notion", {
    "+notion": function(url, host, scheme) {
        "use strict";
        if (/(?:^|\.)notion\.so$/.test(host)) return "+ali_tiny_tls";
        if (/(?:^|\.)amplitude\.com$/.test(host)) return "+ali_tiny_tls";
        if (/(?:^|\.)intercom\.io$/.test(host)) return "+ali_tiny_tls";
        if (/(?:^|\.)loggly\.com$/.test(host)) return "+ali_tiny_tls";
        if (/(?:^|\.)segment\.com$/.test(host)) return "+ali_tiny_tls";
        if (/(?:^|\.)intercomcdn\.com$/.test(host)) return "+ali_tiny_tls";
        if (/(?:^|\.)unsplash\.com$/.test(host)) return "+ali_tiny_tls";
        if (/(?:^|\.)amazonaws\.com$/.test(host)) return "+ali_tiny_tls";
        return "DIRECT";
    },
    "+ali_tiny_tls": function(url, host, scheme) {
        "use strict";
        if (/^127\.0\.0\.1$/.test(host) || /^::1$/.test(host) || /^localhost$/.test(host)) return "DIRECT";
        return "HTTPS proxy2.jerrywang.top:443";
    }
});