Server
Table of Contents
这是关于本网站如何构建的一个doc. 本站主要包含两个服务: 博客和proxy relay (江湖人称”梯子”).
这两个服务可以说是毫无关联的: 你可以只搭博客, 不管梯子, 或者只搭梯子不管博客. 从结构上来讲, 博客和梯子应该分两篇文章来讲才更对一点, 放一篇来讲就太大了. 然而有些必须澄清的概念对二者而言都是共用的. 并且实际上, 本网站的诞生历史就是二者一起完成的, 自己就是在反复折腾这两个东西的过程中加深了对更多东西的理解 (作为过来人, 我觉得搭博客还更折腾一点, 梯子反而没什么难度).
如果你觉得本文看起来像缝合怪, 没错, 本文在2019年10月的时候确实是两篇博文 — 那时候本站刚刚建立没多久, 我为此写了两篇博客介绍自己怎么搭博客和梯. 但那时候我的观点还很稚嫩, 发出去没几个月我就自己删了, 原稿留着作为自己的私人笔记. 后来居然有个小伙伴特地加我去要这两篇博文, 我就感觉这确实在一定程度上造福了不少人. 所以就趁合同还没开始, 赶紧把这篇博文 缝 了出来, 其内容不反映我当前的认知程度.
另外我是重度Linux用户, 有不少命令我没有精力特地开Windows去查证是否这样用 (譬如说生成公钥那里), 但这些细节问题绝对可以百度找得到答案. 通常, 一篇介绍搭梯和搭博客的CSDN/cnblogs文都会顺便谈及这些细节的, 绝对不难查到. 如有不便请多多包涵.
如今的梯子已经支持在大陆地区使用ChatGPT, 只要你能自行解决一个境外电话卡即可 (TB/PDD有一大堆). 我在欧洲, 对梯子没有刚需, 梯子是搭了博客之后顺手搭的, 给家人朋友用, 没有借此盈利的考虑, 但是依然 欢迎打赏, 多少随意 😉
1. 服务器 域名 证书
1.1. 概念区分
1.1.1. 主机 & 服务器
你的PC就是一个Linux主机. 一个主机会运行各种服务 (俗称后台服务). 通过 systemctl status
或Windows的任务管理器你可以看到各式各样的服务:
- 提供网页浏览的 nginx.service;
- 执行定时任务的 cronie.service;
- 负责远程登录的 sshd.service;
- 负责翻墙的 v2ray.service 和/或 xray.service;
- …
甚至守护进程 emacs --daemon
本身也可以称作一个”服务”. 可见”服务器”这个词是个很泛化的概念. 你的一台不提供任何网页浏览服务的PC在上面所列的意义下其实也可以算作是”服务器”.
狭义的”服务器”是指在云端的提供网页浏览服务的主机. 其实如果单讲网页浏览服务的话, 这家伙甚至不需要部署在云, 你的PC就可以. 譬如说, 如果你给你的PC装了 Web服务 (Nginx 或 Apache2), 你就可以在浏览器里输入 localhost
看到它渲染出来的欢迎页; 接下来讲Hexo的时候, 也频繁用到 hexo s
作为本地预览你的博文
所以一个需要区分的地方就是, 云主机/云服务器, 跟本地主机(localhost)/本地服务器, 之间, 有什么不同, 前者多了什么?
1.1.2. 云主机 & 云服务器
加了”云”前缀的, 一言以蔽之, 就是 具有独立IP 的, 可被用户从世界上任何地方 访问 的主机/服务器. GitHub以及自购的VPS就是这种, PC就不是. 这里的”访问”, 可以指 通过浏览器进行Web访问 (需要安装 Web服务), 或者作为代理访问 (需要安装V2Ray或XRay) — 是的, 没装Web服务的云主机也可以称为云服务器, 只是它不提供网页浏览服务而已, 但可以提供翻墙服务.
没有独立IP的PC也当然可以装Web服务, 并把网页内容放在/var/www/html/, 但你只能在自己的电脑上打开, 自己阅读, 只为自己服务 (譬如说Hexo本地预览) — 但这也失去了”服务”的含义了. 其实PC并不是绝对不可以被外网登录的, 使用 内网穿透 这个功能即可. 但是我们一般不会拿自己的PC来被外网访问; instead, 作为一个toy model, 会拿 树莓派 作为内网穿透的尝试.
1.1.3. 配置文件 & 内容
Web服务的 配置文件 位于 /etc/nginx/
(for Nginx server) 或 /etc/apache2/
(for Apache2 server). 只需要修改 /etc/nginx/conf.d/index.conf
, 其他文件尽量保持别动.
Web服务的 内容 默认位于 /var/www/html/
. html或php等结尾的文件, 能被浏览器渲染出来成为我们在浏览器上看到的内容.
1.1.4. 域名
域名是跟IP地址绑定的较易识别的名字, 在浏览器里输入IP来访问网页很不方便因为IP是一串数字, 但是输入形如 "OChicken.net" 这样的英文名字就易记很多, 这就是域名. 可以理解域名为地名, 理解IP地址为地球上的地理位置. 地名有可能相同, 但在地球上的地理位置显然存在且唯一. 譬如说武汉有个柏林站, 显然不是德意志的柏林.
有各种各样的顶级域名: gov, com, cn, org, edu, 甚至 .monster… 域名抢注是很常见的事情.
1.1.5. 云服务器里的内容 & 域名地址
在浏览器地址栏里输入OChicken.net, 浏览器渲染出来的内容就是 /var/www/html/
里的东西. 举例:
. ├── static │ ├── Cola.png │ ├── header.html /* LAYOUT */ │ ├── postamble.html /* LAYOUT */ │ ├── preamble.html /* LAYOUT */ │ └── main.css /* CSS */ ├── index.org │── Makefile /* BUILD */ │── blog.el /* BUILD */ ├── projects │ ├── index.org │ └── server │ ├── Danke.gif │ ├── index.org │ └── path-to-files.org └── research ├── GPQHE │ └── index.md └── index.html
若你打开的是目录 (如 OChicken.net/research
, OChicken/projects
) 且该目录里有一个名为index.html的文件, 那么浏览器就会渲染此文件的内容. 如果打开的是文件, 如 OChicken.net/static/Cola.png
, 则浏览器就直接打开该文件. 文件类型也适用于html/php. 要想访问此目录内的其他html网页, 则就像打开文件那样去打开它. 这篇短小的 wiki 简要列举了几个例子.
1.1.6. 域名解析
域名解析就是将 域名 映射到 IP地址 的操作.
1.1.7. SSL 证书
SSL证书相当于一个网站的”身份证”, 证明这个网站是有一个真实存在的自然人所有的, 因为cyber space上有相当多的一部分网站并不是由自然人所有, 或者说是为不怀好意的黑客所有, 访问这些网站是不安全的. 没有”身份证”也不妨碍你的博客可以被访问, 但现在Google已经将没有证书的网站的搜索排序放到偏后的位置了.
GitHub本身就自带证书, 因为github/OChicken这个账号的所有者就是一个自然人. 自购的VPS需要自行搞定证书的申请.
1.2. 云主机的选择
GitHub服务器 是GitHub自带的, 你只需有一个GitHub账号即可在上面布局博客, 这个优势是显然的; 劣势在于不能被shell登录, 没法看到Linux的网页相关的配置, 所以不是一个很好的练习对象. 实际上, OChicken/OChicken.github.io (我已关闭此repo, 因为我自己不需要) 里面的内容就相当于 /var/www/html/
里的内容, 只是GitHub把这些都隐藏起来了. 如果用GitHub服务器来搭博客的话, 跟它绑定的域名就是OChicken.github.io, 这是GitHub博客要求这样做的; 而用自购的云VPS或者树莓派来做的话则需要自行购买一个域名.
自购的云VPS 跟 GitHub 的区别在于, 前者可以通过 shell 以输入用户名和密码的方式登录, 但是后者不行, 所以 GitHub 并不是一个足够好玩的 toy model. 况且, 前者还能配置翻墙服务.
树莓派 跟 自购的云VPS 都可以通过shell输入账户密码登录, 进而可以看到Linux的网页相关的配置并可以DIY设置, 所以都是个不错的toy model, 况且树莓派比VPS更难的一处是要摆平内网穿透, 有点挑战价值. 但树莓派终究是不适合实战的. 因为要搞定内网穿透, 你终究还是得买一个云VPS作为一个中间跳板, 才能让托管在树莓派上的网页内容展示给公网. 虽然云VPS能做的事情树莓派都能做, 但在绝大多数场合, 你都需要一个云VPS作为中间跳板. 更何况, 树莓派的性能还很不行.
总结起来, 按配置复杂度从低到高: GitHub, 自购VPS服务器, 树莓派. 但比较有训练和实战价值的是自购的云VPS. 我们将在本文主要讨论它.
1.3. VPS
在买VPS之前先使用如下命令生成公钥私钥对. 生成的东西位于 .ss/id_rsa
和 .ss/id_rsa.pub
.
ssh-keygen -t rsa -C "[email protected]"
VPS服务器的选择非常多, Vultr, DO(DigitalOcean), 搬瓦工, Linode, 阿里云, 百度云, … flyzy小站 - Learning on the way有做相关测评.
我用的是DO. 借助GitHub提供的DigitalOcean学生优惠还能褥一波羊毛. 2019年The code is 2019GITHUB50-83f52d0d. 下面这些链接讲述了褥羊毛:
- GitHub提供的DigitalOcean学生优惠 - 知乎
- GitHub Student Developer Pack - GitHub Education
- How to use github promo code (student developer pack) | DigitalOcean
有了IP之后, 就可以用 ssh [email protected]
登录 (Windows用户请使用PuTTY操作). 可以在 .ssh/config
添加快捷方式:
Host OChicken.net HostName 134.xxx.xxx.xxx TCPkeepalive yes Serveraliveinterval 30
登录时用 ssh [email protected]
即可. 后两行表示每30秒给服务器发一个心跳包, 以避免在本地连接服务器的时候因长时间 (只是几分钟而已) 无响应而断线.
登录成功之后立刻安装Nginx并启用服务
sudo apt install nginx-full sudo systemctl enable --now nginx.service systemctl status nginx.service
1.4. 域名
在Cloudflare上购买域名, 配置DNS, A记录 指向IPv4地址, 和 AAAA记录 指向IPv6地址. 提供域名出售服务的网站多如牛毛, 之所以推荐这家是因为它还能顺便搞定CDN.
完成以后, 在VPS的 /etc/nginx/conf.d/index.conf
上配置域名:
server { # ... server_name ochicken.net www.ochicken.net; root /var/www/html; error_page 404 = /404.html; # ... }
使用如下命令检查语法 (无错则应弹出OK) 以及重启Nginx服务:
sudo nginx -t sudo systemctl restart nginx.service systemctl status nginx.service
1.5. 证书
证书是由通信双方 (站长我本人, 以及诸访客) 以外的第三方机构, 作为证书发布者, certificate authority, 简称 CA. 全世界有大大小小的CA. 面向个人建站的场合, 往往也使用免费的自签名的证书. 证书包括公钥和私钥, 但格式不尽相同: 常见公钥后缀是pem, crt, key, 常见私钥后缀是pfx, p12, pem, key (证书之间的转换(crt pem key) - 何惜戈 - CSDN博客).
1.5.1. 在Cloudflare上自己申请自己部署
在Cloudflare->SSL/TLS->Origin Server完成申请之后, 下载公钥pem和私钥key, 上传到VPS的 /etc/ssl/
. 完成以后, 在 /etc/nginx/conf.d/index.conf
上配置证书:
server { # SSL configuration listen 443 ssl default_server; listen [::]:443 ssl default_server; ssl_certificate /etc/ssl/ochicken.net.pem; ssl_certificate_key /etc/ssl/ochicken.net.key; # ... }
1.5.2. 使用Certbot
Ref: 通过 Certbot 申请泛域名 HTTPS 证书及配置自动更新 - 简书
如果是个人建站, 使用自签名证书的话, 其实完全可以在VPS上解决, 只要有 域名和邮箱 即可, 也无需配置 /etc/nginx/conf.d/index.conf
. 在服务器上
sudo apt install python3-certbot-nginx sudo certbot --nginx -d www.inhoge.com sudo certbot --apache -d www.inhoge.com
然后启用以下两个服务:
sudo systemctl enable --now certbot.service sudo systemctl enable --now certbot.timer
这将在/lib/systemd/system/下生成了两个文件: 服务certbot.service和定时器certbot.timer. 更改后者 OnCalendar=*-*-* 00,12:00:00
为 OnCalendar=*-*-* 05:00:00
, 每天凌晨5点更新证书. 然后如下重启服务, 即可定时更新自签名证书.
sudo systemctl daemon-reload sudo systemctl restart certbot.timer
1.6. 安保措施
1.6.1. 防火墙
打开防火墙, 默认屏蔽所有浏览, 然后allow 22端口用于ssh登录, allow 443端口用于https访问. 而80端口因为用于不安全的http访问, 宜禁用.
sudo apt install ufw sudo ufw enable sudo ufw allow 22 # 登录专用端口, 必须设置 sudo ufw allow 443 # https 协议端口, 必须设置 sudo ufw status # 查看服务器防火墙状态
1.6.2. 禁止 IP 访问
在完成上述设置后, 可以尝试在浏览器地址栏直接输入IP 134.xxx.xxx.xxx: 因为没有allow 80端口, 这是打不开的. 但是有一种做法可以依然做到通过IP访问: 输入https://134.xxx.xxx.xxx, 这时浏览器会提示说有风险, 但 只要手动跳过所有风险警示, 就能够以这样的方式通过IP访问到网站了. 为此须在VPS的 /etc/nginx/conf.d/index.conf
上设置
server { if ($host != $server_name) { return 404; } }
1.6.3. 禁止非文文件访问
所谓”非文件访问” (我自己起的名字), 就是指在浏览器里输入的内容必须是对应于/var/www/html/目录里的一个文件, 否则就返回404.
server{ # ... location / { # First attempt to serve request as file, then # as directory, then fall back to displaying a 404. try_files $uri $uri/ =404; if (-f $request_filename) { rewrite ^/(.*)$ /$1 break; } } # ... }
2. Blog
如您在页脚处所见, 本站是由 Emacs Org mode 生成的, 虽然配色跟著名的 Hexo 博客框架的 NexT.Pisces 主题很像, 但并不是用 Hexo 生成的. 我会谈及如何做到这一点的.
2.1. 技术路线
2.1.1. 搭博客的方式
搭博客有很多种方式, 都可以在浏览器里输入IP地址看到发布的内容. 按易用程度来分, 大概分为图形界面的和依赖命令行的.
图形界面搭博客主要有 WordPress 和 Drupal. 你只需要在云服务器上安装它们指定的包, 就可以直接在 Chrome 上在线编辑博客, 就像写 QQ 空间那样简单. 这种方式完全 可以不去管Web网页服务器 的设置: 用shell进行最初一步的登录后, 直接把包的内容解压到 /var/www/html/
里, 配置好域名和证书, 然后浏览器点开IP就有东西了. 你会看到无论哪个包, 解压出来的东西都含有 index.php
或者 index.html
等类似的文件. 这个文件显然很重要, 因为它是被网页服务器的配置文件定向指定的, 但里面写的啥并不必关心.
但这种方式不便于做 VC (版本控制). 我们通常会建议在 md 文件里面把博客写好, 再 通过命令行 一键发布. 代表作是 Hexo 和 Hugo. 你可以发布到 GitHub Page, 也可以发布到自己的 VPS. md 是个很受非程序员欢迎的富文本笔记语言, 虽然用了一点命令行, 但你可以逐行 VC 做过什么改动, 这比基于图形界面的方式好很多. md 的优越性毋须多言, 用过都说好.
2.1.2. 动态 and/or 静态 博客
静态博客很”简单”: 因为访问者只能访问, 而不能作为用户登录这个网页并写comments. 这其实区分了读和写的两个权限, 访问者对网页的”写”过程要反馈到云服务器的 /var/www/html/
中, 这涉及到比较多的权限问题. 要实现访问者能够”写”网页的目的, 还需要MySQL和PHP, 加上Linux, 合起来就是LAMP或者LNMP — 不少介绍搭博客的博客都说用”宝塔LAMP”搭博客, 就是指这个东西.
WordPress是可以实现动态博客这个功能的, 但它是个高度封装好了的产品, 不适合作为玩具; 且作为academic purpose的个人展示页, 静态博客即可.
2.1.3. Hexo, Hugo & Emacs Org mode
Hexo 和 Hugo 是两个几乎平级的博客框架, 它们相比 WordPress 要说有什么更 "高级" 一点的话, 恐怕只有生成和发布那一步是要用一点点的命令行, 以及写 md 是纯文字的, 不像 WordPress 那样 WYSIWYG (所见即所得).
我之前用过很长一段时间的 Hexo. 工作方式是这样的: 本地写 md, 用 hexo g
生成 html 文件, 然后 hexo s
, 在浏览器的 http://localhost:4000/
预览, 明确无误就 hexo d
发布. 就这么简单的三连.
顺带一提: "博客" 这个词给人第一感觉是托管在 "云 服务器" 里的. 实际上如前面提到的, "云" 这个前缀只不过是有一个独立IP可供世界各地的人访问而已; 如果你只想自个儿看, 那在一个甚至不需要联网的 PC 里都可以完成, 这个东西就是 http://localhost
, 本地主机.
Emacs 的 Org mode 是比 md 更 "高级" 一点的笔记系统, 用过 Org mode 的都说它比 md 好. 所以一个考虑是, 能否像使用 "md + Hexo" 那样使用 "Org + Hexo"?
你确实可以在 Hexo 里使用 Org, 这需要安装 npm install --save hexo-renderer-org
这个插件, 之后就可以像使用md文件那样使用org文件并实时渲染网页了. Refs:
- 项目网站: coldnew/hexo-renderer-org: Hexo renderer plugin for emacs org-mode
- 项目作者写的文档: Getting Started with the Hexo and org-mode | hexo-org-example
但是 Hexo 对 Org mode 的支持很落后. 这个插件的作者几乎不维护了 (看最后的更新时间). 著名 Emacs 用户刘家财先生也提及到, 该插件对 Org mode 的支持很糟, 他因此转粉了 Hugo.
很多 Emacs 用户都安利 Hugo, 因为这个博客框架原生就支持 Org. 我曾考虑过 "Org + Hugo" 的方案. 但是 Hugo 没有 NexT. 我对 NexT.Pisces 粘性很大, 对 Hugo 没有什么感情.
然而我当时想实现的 request 是, 我希望的是用 Emacs Org 强大的 export 和索引功能去生成博客, 就像 Hexo 和 Hugo 所做的那样 (相比之下后两者其实算是第三方软件). 可是Emacs Org mode 生成的 TOC 总是位于文章开头, 而不像 Hexo & Hugo 那样可以放侧边. 这个 sidebar TOC 让我心心念念了好久.
所以当时想过这么些方案:
- 向 Hexo 低头, 发博客前把 Org 转为 md (但这样就不能像之前那样
md + Hexo
愉快地工作了) - 投身 Hugo, 可是 Hugo 的 NexT 主题做得并不好 (外观主题之类的虽然不是个事儿, 但又确实是个事儿)
- 使用 Org 生成博客, 接受那个总是摆在前面的 TOC.
没有一个是好的选择.
后来我意识到一个突破点是, 一个网页之所以 "好看", CSS 文件起了 90% 的作用. 只要你意识到这一点, 就不难发现, Hexo 和 Hugo 其实只是通过一系列易用的接口, 帮你把 CSS 生成出来了而已. 当你不确定自己喜欢哪个主题以及这个主题的哪一个子主题的时候, 是可以通过他们给定的配置文件自己慢慢调的; 而 当你选定了一个主题样式之后, 就可以在这个已经生成好的 main.css
文件上面魔改了, 改好之后把这一行加入到 Org 文件的开头即可:
#+html_head: <link rel="stylesheet" type="text/css" href="path/to/main.css"/>
2.1.4. Your Choices of CSS
当时启发我意识到找到CSS等于完成任务一大半的是来源于这几个链接:
- css - How to use display Table of Contents in sidebar with arbitrary HTML file? - Stack Overflow
- Transform your Org mode files into stunning HTML documents: 提供了神似 Read the Docs 主题的
readtheorg
, 完美实现侧边栏. - org mode - How to export an html file with a foldable & dynamic TOC from an org file? - Emacs Stack Exchange mentioned Worg 👍
也就是说你只要在 Org 文件开头加上下面任意一条:
#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="https://fniessen.github.io/org-html-themes/src/readtheorg_theme/css/readtheorg.css"/> #+HTML_HEAD: <link rel="stylesheet" type="text/css" href="fniessen.github.io_org-html-themes_src_readtheorg_theme_css_readtheorg.css"/> #+html_head: <link rel="stylesheet" type="text/css" href="https://orgmode.org/worg/style/worg.css"/> #+html_head: <link rel="stylesheet" type="text/css" href="/path/to/worg.css"/>
就可以使用 CSS. OlMon 分享了一系列用于 Org 文件的 CSS themes:
- Org HTML theme collection : emacs (also mentioned fniessen's
readtheorg
) - Org Themes collection 👍
- OlMon / org-themes · GitLab
- emacs - org-mode html export - Stack Overflow
此外也有 Dr. gongzhitao 的
可见现成的选择是很多的.
我自己这几天在重构博客的时候重点参考过的只有两个项目的 CSS:
- Hexo 的 NexT.Pisces 生成的 CSS, 文件是
./public/css/main.css
. 原因无他, 就是喜欢其配色. - Worg 官方指定的 "参考答案", 这个项目的
worg/style/worg.css
就能忠实复现出可以折叠显示的 sidebar TOC 的效果.
2.2. 用 Org mode 生成博客
我只推荐这两篇作为参考, 足够简单, 可以立刻上手
Worg 首页就提供了如何构建该网站的 repo (它们那个网站就是完全用 Org mode 生成的), 但项目很庞大, 个人不推荐.
你的本地博客目录应该有这些东西:
. ├── static │ ├── Cola.png │ ├── header.html /* LAYOUT */ │ ├── postamble.html /* LAYOUT */ │ ├── preamble.html /* LAYOUT */ │ └── main.css /* CSS */ ├── index.org ├── Makefile /* BUILD */ ├── blog.el /* BUILD */ └── projects ├── index.org └── server ├── Danke.gif ├── index.org └── path-to-files.org
我分三个小节去介绍它们. 这个图基本上就是本站的 sitemap, 从浏览器地址栏按图索骥地输入路径即可查看. blog.el
和 Makefile
是个人隐私, 不公开, 但我提供了 blog.el 的参考文件, 它跟我真正用的没有太大差别; Makefile
没有参考意义, 就不展示了.
2.2.1. Layout: header, preamble & postamble
Org mode 生成出来的 html 文件的结构如下所示. 把 head.html,
preamble.html
和 postamble.html
范围所在的内容写到你自己的 layout 即可, 内容自行设计.
1: <!-- head.html begins here (ends in line 7) --> 2: <meta charset="UTF-8"> 3: <meta name="generator" content="Emacs 29.1, Org mode 9.6.6"> 4: <link rel="icon" type="image/png" href="/images/Cola.png"> 5: <link rel="stylesheet" href="/css/main.css"> 6: <link rel="stylesheet" href="/lib/font-awesome/css/all.min.css"> 7: <!-- head.html ends here (begins in line 1) --> 8: <body> <!-- body begins here (ends in line 39) --> 9: <div id="preamble" class="status"> <!-- preamble.html begins here (ends in line 20) --> 10: <header class="header" itemscope itemtype="http://schema.org/WPHeader"> 11: Title 12: <nav> 13: <ul id="menu"> 14: <li><a href="/">Home</a></li> 15: <li><a href="/research/">Research</a></li> 16: <li><a href="/projects/">Personal Projects</a></li> 17: </ul> 18: </nav> 19: </header> 20: </div> <!-- preamble.html ends here (begins in line 9) --> 21: <div id="content" class="content"> <!-- contents begins here (ends in line 33) --> 22: <h1 class="title">The title of the post</h1> 23: <div id="table-of-contents" role="doc-toc"> <!-- TOC begins here (ends in line 31) --> 24: <h2>Table of Contents</h2> 25: <div id="text-table-of-contents" role="doc-toc"> 26: <ul> 27: <li><a href="#第1节">第1节</a></li> 28: <li><a href="#section-B">Section B</a></li> 29: </ul> 30: </div> 31: </div> <!-- TOC ends here (begins in line 23) --> 32: <!-- main matter --> 33: </div> <!-- contents ends here (begins in line 21) --> 34: <div id="postamble" class="status"> <!-- postamble.html begins here (ends in line 38) --> 35: <footer> 36: Powered by GNU Emacs 29.1 (Org mode 9.6.6) 37: </footer> 38: </div> <!-- postamble.html ends here (begins in line 34) --> 39: </body> <!-- body ends here (ends in line 8) -->
除了 shellcodes 提供的, 你还可以去找 Hexo ./public/
目录里面的 html 文件, 这些文件是适配于 NexT.Pisces 主题的. 但我依然建议你参考前者, 以及任何一个由 Org 生成的 html 文件. 原因在于二者生成的 html 有很多 tags 和 class 是不一样的.
2.2.2. Build: Makefile 和 blog.el
hexo g
, hexo s
, hexo d
三连可以类比为用 Makefile
去做 project build 的 make g
, make s
, make d
三连.
hexo g
的等价命令是 emacs --script blog.el
. blog.el
的核心内容如下, 这会把所有 Org 文件生成 html 在当前目录.
(package-initialize) (require 'ox-html) (require 'ox-publish) (setq org-publish-project-alist '(("blog" :base-directory "." :publishing-directory "." :recursive t :publishing-function org-html-publish-to-html))) (setq org-html-head (with-temp-buffer (insert-file-contents "static/head.html") (buffer-string)) org-html-preamble (with-temp-buffer (insert-file-contents "static/preamble.html") (buffer-string)) org-html-postamble (with-temp-buffer (insert-file-contents "static/postamble.html") (buffer-string))) (add-to-list 'org-html-mathjax-options '(path "https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_HTML")) (org-publish-project "blog")
hexo s
的等价命令是 python -m http.server -d ./
, 然后在浏览器里输入 http://localhost:8000/
以预览.
hexo d
, 也就是 deploy, 八仙过海各显神通, 本节开头提到的两个重点参考的博文就提及了 scp, rsync, Emacs Tramp, 甚至像 Hexo 党那样自建 git repo ([1], [2]) 都可以.
我的 blog.el 就在当前目录里, 读者可以自行下载. 但是它写得比较复杂, 因为为了特地适配于我自己的目录结构, 我对它进行了很多功能上的扩充, 用到了一点点 elisp
初步, 有一定的参考价值.
Makefile
你可以暂且把它理解为一个执行一系列 shell 命令的集锦 (当然它的真实用途比这强大得多, 不然大家都靠 .sh
文件干活了), 示例如下
g: @date emacs --script blog.el g
然后直接 make g
即可. 所以用在本博客的 Makefile
没有参考意义, 不作为附件展示.
2.2.3. CSS
既然你都能打开我的博客了, 那肯定能知道我这个博客的 CSS 长什么样了, 并且可以顺便知道把前面讲的三个 layout 文件 (我虽然基本上参考了 NexT.Pisces, 但砍掉了很多). 正如前面所述, 我只参考过两个 CSS:
- NexT.Pisces 生成的 CSS 文件. 它非常大, 足有 2000+ 行.
- Worg, 近 1000 行, 但最最值钱的就 第 74-110 这几行的涉及 TOC 的配置, 其他的相比就不那么重要.
只要有这两个, 就可以动手魔改 CSS 了.
首先去处理一下我心心念念的 sidebar TOC 的问题, 这花了点小 trick. 回顾前面的 layout, 我在魔改的时候发现, 如果把 TOC 的那片代码移到 nav tag 里面, 放在 menu 的 ul (unordered list) 后面, 那么它的位置是刚刚好的!
所以接下来的问题就是怎么让这片代码在每次生成 html 文件的时候都做这一步. ChatGPT 教我:
<script> var toc = document.getElementById('table-of-contents'); /* get TOC */ document.querySelector('nav').appendChild(toc); /* Append the TOC to the nav */ toc.querySelector("h2").innerHTML = "<i class=\"fa fa-list fa-fw\"></i> TOC"; /* change title */ </script>
把这个 js snippet 放到 footer tags 后面即可. 因为 footer 在 postamble.html
里面, 而 postamble 由也还在 body 里面, 所以这个 js 会检索文档里面的 TOC 和 nav tag, 做 nav.appendChild(toc);
. 代码后两行是把 TOC 的 "Table of Contents" 这一长串改为 "TOC" 这三个字母, 就是你现在看到的左上角的那一小块.
在魔改 CSS 文件时还有这些事情可以值得注意:
- Org 文件里的一星表示 h1, 二星表示 h2, 依此类推. 然而在它导出的 html 文件里, h1 tag 包住的是博文的 title, 而 h2 tag 包住的是文件里标一星的那些节.
- CSS 文件的 ul (unordered list), ol (ordered list) 之类的对象, 在 Org 生成的 html 里分别是叫
org-ul
和org-ol
.
暂时就这两个重要的, 其他不那么重要的自行摸索.
一个题外话是, 我的设计不像 NexT.Pisces 那样那么宽. 用宽页或窄页各有所爱, 我选后者的一个考虑是, 窄页的宽度正好是跟一个 A4 pdf 在 (几乎任何一个) 阅读器里用 Fit Page view 以适应屏幕高度的方式缩放所呈现出来的宽度是几乎一致的, 从而 阅读博客页面跟阅读文献的 pdf 有近乎一样的体验.
虽然 NexT.Pisces 生成的 CSS 文件很大, 但 (至少是我想要有的) 核心的那些 (如你在本站所见的配色和效果) 其实 不到 300 行, 也不需要任何 js. 而从 NexT 成品的 2000 行代码砍剩 300 行累计只花了不到一周的时间.
一想到这事我就想起了退钱哥的那句著名meme陈年老梗——███,退钱!
2.3. Empower your blog via Nginx config
声明: 因为本小节要频繁地对 /etc/nginx/conf.d/index.conf
进行改动, 每次改动之后都需要用以下命令重启Nginx Service:
sudo systemctl restart nginx.service
2.3.1. 对诸文件格式的log
设置文本, 图片, 视频的log的过期时间:
server { # ... location ~* ^.+\.(ico|gif|jpg|jpeg|png)$ { access_log off; expires 1d; } location ~* ^.+\.(css|js|txt|xml|swf|wav)$ { access_log off; expires 10m; } location /nginx_status { stub_status on; access_log off; } # ... }
2.3.2. 线上图书馆: autoindex & fancyindex
形如keyllo和Index of /download/cling那样, 我希望搭建一个个人的线上图书馆, 用的就是Nginx的autoindex and/or fancyindex功能.
首先在/var/www/html/library/里放入你想放在线上图书馆展示的书.
对 autoindex, 编辑 /etc/nginx/conf.d/index.conf
:
server { # ... location /library { autoindex on; # 开启目录文件列表 autoindex_exact_size off; # on: 显示出文件的确切大小, 单位是bytes; off: 显示出文件的大概大小, 单位是kB或者MB或者GB, human-readable autoindex_localtime on; # 显示的文件时间为文件的服务器时间 add_header Cache-Control no-store; # 让浏览器不保存临时文件 } # ... }
autoindex是nginx自带的索引, 界面并不十分美观; 美观与否倒是其次, 更糟糕的是其配置的文件名限制在50个字符, 后面就以省略号代之, 作为线上图书馆你看不到全名当然是很不好的, 如openbsd - nginx: Long filenames in directory listing - Unix & Linux Stack Exchange这个问题提到, autoindex并不提供调整列宽的功能. 幸好 nginx 有个插件叫fancyindex. 在configuration - Stop nginx from trimming file name in directory list? - Server Fault提到了fancyindex的apt安装包的名字叫 libnginx-mod-http-fancyindex
. 安装了这个包后, 检查软链接
/etc/nginx/modules-enabled/50-mod-http-fancyindex.conf -> /usr/share/nginx/modules-available/mod-http-fancyindex.conf
的存在有效性. 然后编辑 /etc/nginx/conf.d/index.conf
:
server { # ... location /library { fancyindex on; fancyindex_name_length 255; fancyindex_exact_size off; fancyindex_localtime on; fancyindex_css_href "/library/.styles.css"; add_header Cache-Control no-store; } # ... }
Refs:
2.3.3. 默认编码
这是在使用fancyindex的时候发现的一个问题: 打开图书馆, 里面的txt文件只要是含有非英文字符的, 全都乱码. 为此, 只须在 /etc/nginx/conf.d/index.con
f的server{}块外加上 charset utf-8
即可:
charset utf-8; server { # ... }
2.3.4. 特定目录的访问控制
所谓访问控制就是某些网站, 点开它, 有个弹窗, 要你输入用户名和密码, 以限制对该网站内的特定路径的访问. To this end,
sudo apt install apache2-utils sudo htpasswd -c /etc/nginx/.htpasswd OChicken # create passwd sudo htpasswd /etc/nginx/.htpasswd OChicken # modify passwd
八卦: 虽然限制访问的功能通常与 HTTP服务器 (如Nginx、Apache等) 相关, 但是用于管理密码文件的工具 htpasswd 是由 Apache 软件基金会开发的, 因此它是在 apache2-utils
里面。这个工具可以在许多不同的HTTP服务器中使用, 不仅限于 Apache. 在 Nginx 等其他 HTTP服务器中, 也可以使用 htpasswd 工具来创建和管理密码文件, 以实现基本身份验证功能. 这是因为 htpasswd 工具提供了一种通用的方式来管理密码文件, 可以在多个 HTTP服务器中共享使用.
完成账号密码设置之后编辑 /etc/nginx/conf.d/index.conf
:
server { # ... location /manuals { auth_basic "Administrator's Area"; auth_basic_user_file /etc/nginx/.htpasswd; } # ... }
Refs:
3. Bypass GFW
3.1. 基本使用: V2Ray / XRay
V2Ray 跟 XRay 是两个 (几乎可以说是兼容的) 项目, V2Ray是更出名一点, 因为它更早 (但比Shadowsocks晚一点), 而XRay是V2Ray的升级版, 我用的是XRay. 作为使用者其实不需要了解得太细; 而且就算你想了解关于这两个项目的更多信息, 那也得先出了墙才有可能.
3.1.1. Server
使用项目开发组提供的脚本进行安装和卸载 (注意是”安装”不是”配置”噢, 配置要自己动手.)
wget https://raw.githubusercontent.com/v2fly/fhs-install-v2ray/master/install-release.sh # V2Ray wget https://github.com/XTLS/Xray-install/raw/main/install-release.sh # X-Ray sudo bash install-release.sh sudo bash install-release.sh remove # if you want to remove sudo systemctl enable --now xray.service
最后一行表示开启 xray.service. 安装之后你的系统会多出这些文件 (script 会告诉你的):
/usr/local/bin/xray
/usr/local/share/xray/geoip.dat
/usr/local/share/xray/geosite.dat
/usr/local/etc/xray/config.json
/var/log/xray/
/var/log/xray/access.log
/var/log/xray/error.log
/etc/systemd/system/xray.service
/etc/systemd/system/[email protected]
V2Ray用户请自行更改为v2ray (反正二者在基本使用的层面是几乎兼容的). 下文我将以XRay为例讲解.
在Server端需要配置两个文件: XRay的 /usr/local/etc/xray/config.json
和Nginx的 /etc/nginx/conf.d/index.conf
.
编辑XRay的配置文件 /usr/local/etc/xray/config.json
. 本站用的是XRay, 但它同时支持 VMess (V2Ray首创) 和 VLess (XRay首创) 两种协议, 可以同时开启.
{ "log": { "access": "/var/log/xray/access.log", "error": "/var/log/xray/error.log", "loglevel": "warning" }, "inbounds": [ { "listen": "127.0.0.1", "port": 16388, "protocol": "vless", "settings": { "clients": [ { "email": "XRay User", "id": "2428e3bf-fa3d-456e-abb2-57e7cb796090", "alterId": 0 } ], "decryption": "none" }, "streamSettings": { "network": "ws", "wsSettings": { "path": "/6f1d804" } } }, { "listen": "127.0.0.1", "port": 16389, "protocol": "vmess", "settings": { "clients": [ { "email": "V2Ray User1", "id": "3b30d077-7c25-40af-ac15-bc210d2538e3", "alterId": 0 }, { "email": "V2Ray User2", "id": "2322c6f1-4e03-43a8-829e-df9c7398a0df", "alterid": 0 } ] }, "streamSettings": { "network": "ws", "wsSettings": { "path": "/7831ee2" } } } ], "outbounds": [ { "tag":"default", "protocol": "freedom" }, ] }
这个例子特地展现出多用户配置的特性: 可以某些用户使用 VLess, 某些用户使用 VMess, 井水不犯河水. "id"就相当于密钥; "path"则是跟”port”紧密关联的, 接下来配置Nginx就会讲到. 完成这个文件的配置后使用如下命令检查语法是否有错误:
sudo xray -test -c /usr/local/etc/xray/config.json
然后编辑Nginx的配置文件 /etc/nginx/conf.d/index.conf
:
server { # ... location /6f1d804 { proxy_redirect off; proxy_pass http://127.0.0.1:16388; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $http_host; # Show realip in v2ray access.log proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } location /7831ee2 { proxy_redirect off; proxy_pass http://127.0.0.1:16389; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $http_host; # Show realip in v2ray access.log proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } # ... }
端口16388和地址 6f1d804
都是随便设的. 虽然这里出现了port的概念, 初学者会以为这是跟22和443相似角色, 是对外的, 是要经过网卡的 — 实际上你 并不需要 到ufw那里开启16388端口和16389端口. Warum? 注意一下 http://127.0.0.1:16388
这种写法: 这表明端口16388是 本地端口, 表明Nginx会把对 OChicken.net/6f1d804
的访问做 本地端的端口转发, 转发给监听了16388这个端口的应用程序; 而监听 (listen) localhost (127.0.0.1) 端口16388的应用程序正是 xray.service. 这正是 进程间通信 的一个生动的例子.
完成好上面两个配置文件后 务必 用下面的命令重启对应的服务:
sudo systemctl restart xray.service sudo systemctl restart nginx.service
现在可以解释一下本节开头的那张图了, 以path 6f1d804
和16388端口为例. 从墙内访问Google的流量 (黑线) 经本地端的 xray.service 后, 伪装 成了访问 OChicken.net/6f1d804
的流量 (被灰线包裹的黑线). 该流量进入本站的443端口, 进入Nginx处理. 因为Nginx里有了上面这片代码, 它发现, 噢, 访问 OChicken.net/6f1d804
这个目录的流量应当转发给 本地端口 16388, 于是脱下灰线的大衣, 这些流量 (黑线) 就这么内部转发到XRay服务的inbound了. 经过其内部的身份验证 (验证id) 等操作, 就从outbound发出, 最终去到Google.
至此, Server上的基本配置就完成了, 你的云主机就成了一台”云服务器”, 即使你不安装博客, 浏览器里点开域名发现什么都没有, 它也是提供了服务: 翻墙服务.
3.1.2. Local
用于Windows和Android的客户端分别是 V2RayN 和 V2RayNG, 读者可以到那里直接下载.
但是GFW对GitHub做了限流, 从项目repo下载是很慢的. 本站提供两个最新版的文件以便读者直接下载: V2RayN-With-Core release 6.27 (2023.06.18) 以及 V2RayNG release 1.8.6 (2023.07.30). 它们的 sha256 校验码如下. 这两个文件跟你从项目repo直接下载的文件是一模一样的, 童叟无欺.
5ec0066ddff21407b00fe9ca40408642051eb2a3ceb5fc50c92f94adfd302668 # V2RayN-With-Core release 6.27 f3cd3835916066be647c5c5c334e15a77c5e1ddc2947b4635e765a2331447da2 # V2RayNG release 1.8.6
需要声明: 我只是把文件搬运到这里而已, 没有给本站设置自动镜像去更新最新版本的客户端: 我没这个义务这么做, 且本文发布以后估计至少一年不会更新它. 但我相信, 一, GitHub就算被限流, 你也还是可以下载的, 有点慢而已; 二, 即使是旧版的客户端都能跑起来, 在这方面要相信开发组的实力.
Windows和Android的配置内容是几乎一样的, 我就仅以Windows为例截图展示好了. (印象中) V2RayN打开后会 "闪退" — 其实它不是闪退, 而是缩小到右下角的system tray去了. 如下两幅图我用GIMP修改过, 跟前面Server部分的配置是一样的, 只须保证 用户ID 和 路径 这两个东西不填错即可. 记得左图下方的 "系统代理" 要选择 "自动配置系统代理".
有多年翻墙经验的老用户会问: 我是不是要在chrome下载Proxy SwitchySharp然后到浏览器里配置一番什么127.0.0.1啊端口号10808啊? 不需要的, V2RayN已经给你办好了.
到这一步, 你其实就已经出墙了, 可以用ifconfig.me和who.is来看看自己的IP, 应该就是VPS的IP. 先去喝杯可乐吧🎉
现在可以解释一下本节开头的那张图了, 刚才已经解释过服务器部分, 现在讲左边PC的部分. 开启梯子后, 你对Google的访问, 会先经过一番 本地端口转发, 默认端口都是10808 for socks和10809 for http. 而所谓 "开梯子" 就是指 xray.service 启动了, 该服务监听本地端口10808的消息, 收到你访问Google的流量后, 给这个流量套上一层灰色大衣 (图中灰线), 伪装 成了访问 OChicken.net/6f1d804
的流量 (被灰线包裹的黑线). OChicken.net是个人畜无害的个人博客, 所以很顺利地出墙了. 接下来就是上一小节服务器处理这段流量的故事.
本文应该也会有少部分Linux用户 (我本人就是, 重度的那种), 一定会很关心Linux上怎么翻墙. 第一步, 先像服务器配置那样, 下载 install-release.sh
安装XRay并开启 xray.service; 第二步就是编辑 /usr/local/etc/xray/config.json
, 其内容怎么来呢? 很简单. Android或Windows上配置好之后, 点 "Export full configuration to clipboard", 把这些东西粘贴到此文件里去即可. 你最终看到的文件将会长这样. 最后restart xray.service.
3.2. CDN保护
到这一步, 如果你在terminal或Windows Power Shell里做 ping OChicken.net
, 或你自己的域名, 会看到真实的IP, 就是那个在VPS供应商上面买的那个IP. 这种 "IP裸奔" 的做法是很不安全的. 并且更糟糕的是, 如果你的VPS供应商被墙掉, 那么你就没法打开OChicken.net, 也没法翻墙了, 因为DNS解析出来的IP是在被墙的IP段里面的. 在 Weißes Blatt Widerstand
- 2022.11.28
- 2022.11.29
- 2022.12.01
- 2022.12.02
- 2022.12.03
- 2022.12.04
- 2022.12.09
- 2022.12.10
- 2022.12.11
- 2022.12.13
- 2023.01.17
- 2023.01.19
- 2023.01.20
- 2023.01.23
- 2023.01.31
- 2023.02.03
- 2023.02.03
- 2023.02.03
- 2023.02.06
- 2023.02.09
- 2023.02.26
- 2023.03.10
- 2023.04.04
- 2023.04.09
- 2023.04.16
- CEAS
I saw that there were so many people around the same age as me who took part in the white paper movement with me, who have been arrested and imprisoned. So I feel that I will always be in pain and have uncontrollable anxiety if I don't stand up and speak out on their behalf, even though there are great risks involved in doing so.
的时候这个IP就被墙了, 行业黑话叫 ping不通 了. 大陆无法访问我的博客, 也不能使用我的梯子. 我在 2023.01.05 的时候使用CDN修复了博客, 从大陆可以访问, 并在随后几天里从原来的Shadowsocks转为现在的{V2/X}Ray, 修复了梯子给家人朋友用. 但这时候我的IP在大陆还是不能ping通的. 2023.03.09 这一天, 我发现可以ping通了. 也就是说2023.{01.05-03.09}这段时间, 博客+梯子之所以都能用, 得归功于CDN.
事后复盘IP被墙这事, 我认为是那段时间gov.ccp拉起了非常高级别的警戒, 把所有大陆以外的VPS供应商的IP都墙掉了, 行业黑话叫 屏蔽IP段. DigitalOcean是主流的VPS供应商之一, 就自然地在被墙的列表上了.
CDN是个很成熟的技术, 以至于你顺手点一下开关, 就配置了CDN了. 登录Cloudflare, 点开你买的域名, 左侧sidebar有个DNS, 在A记录那里, 把Proxy status打开, 小云朵变成橙色, 就表明启用CDN了. 在1.4节配置域名的时候应该见过这个界面, 我觉得就不必截了.
怎么知道是否已经启用CDN了呢? 同样是ping域名, 这时候弹出的IP就应该不是VPS的域名了, 而是变成了别的. 把这个IP复制到ipinfo.io或cip.cc, 就可以看到相应的信息, 会显示是Cloudflare节点.
现在可以解释一下CDN大致是怎么工作的. ping OChicken.net得到的是Cloudflare的节点IP这事表明, 披着灰色大衣的那个流量经大陆方面的DNS解析后, 会根据此IP先抵达Cloudflare的节点; Cloudflare 发现这个流量是要去OChicken.net的, 他们内部记录了OChicken.net的真实IP (这其实是你自己写在配置面板里的), 就把这个流量发到真实IP那里去. 疏理一下:
- 0个proxy: 大陆 -> Google, 直连. 这是不可能的.
- 1个proxy: 大陆 -> 你自己的梯子 -> Google.
- 2个proxy: 大陆 -> Cloudflare CDN节点 -> 你自己的梯子 -> Google.
Cloudflare CDN节点和你自己的梯子都是proxies, 而且都是必要存在的: 自己的proxy是用来伪装成访问合法网站, 使得大陆方面的DNS能够放行; Cloudflare 的proxy用于保护自己的梯子的真实IP, 这样就算发生了 Weißes Blatt Widerstand 这种团灭VPS IP的事情, 照样能访问自己的博客+梯子.
3.3. 借助 Cloudflare WARP 访问 ChatGPT
- 1.1.1.1 — The free app that makes your Internet faster.
- Linux desktop client · Cloudflare WARP client docs
OpenAI为了防止僵尸网络攻击以耗尽其计算资源, 认为所有的VPS的IP都是malicious的, 就把所有主流VPS供应商的IP段都列入黑名单里. 所以未配置此步时, 打开ChatGPT会发现access denied.
借助Cloudflare WARP可以解决这个问题. 大体思路跟用梯子类似: 在你的梯子跟ChatGPT之间, 又插入了一个proxy relay, 是Cloudflare的edge节点. 对比一下访问Google和ChatGPT:
- 访问Google, 要2个proxies: 大陆 -> Cloudflare CDN节点 -> 你自己的梯子 -> Google.
- 访问ChatGPT, 要3个proxies: 大陆 -> Cloudflare CDN节点 -> 你自己的梯子 -> Cloudflare edge节点 -> ChatGPT.
Cloudflare本身不提供VPS服务, 并不在ChatGPT的屏蔽列表当中, ChatGPT认为从Cloudflare edge发出的chat请求是innocuous的, 就不会拦截.
To this end, 你需要在你的梯子上配置WARP. 以下是三个比较有用的链接. 配置WARP只需要在VPS完成, 不用动PC的设置.
- willoong9559/XrayWarp: 使用WARP Client V2ray/Xray服务端流媒体解锁
- Woiden IPv4 IPv6双栈VPS V2Ray梯子 装Cloudflare WARP Socks代理 解决Google人机验证问题 Youtube不能评论的问题
- 宣布适用于 Linux 的 WARP 和代理模式
对这些连接稍微补充一点: 在涉及到WARP的tutorials里, 有一个令人一时半会转不过弯来的角色切换: 你的VPS, 对Cloudflare edge而言, 是客户端.
还有另一个可选的一步是对{V2/X}Ray的配置再细粒化. 你可以设置, 当你要访问ChatGPT时候, 就经WARP; 不访问ChatGPT的时候, 就不经WARP.
3.3.1. 配置WARP
登录VPS, 做如下命令安装WARP.
curl https://pkg.cloudflareclient.com/pubkey.gpg | sudo gpg --yes --dearmor --output /usr/share/keyrings/cloudflare-warp-archive-keyring.gpg echo "deb [arch=amd64 signed-by=/usr/share/keyrings/cloudflare-warp-archive-keyring.gpg] https://pkg.cloudflareclient.com/ $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/cloudflare-client.list sudo apt update sudo apt install cloudflare-warp
接下来在你自己的服务器上, 注册客户端并配置, 这样才能使用Cloudflare的节点:
warp-cli register # 注册客户端 warp-cli account # 查看账号信息 warp-cli settings # 查看设置信息
这些configurations位于 /var/lib/cloudflare-warp/
. 然后开启socks5 proxy:
warp-cli set-mode proxy
再查一遍 warp-cli settings
会看到 Mode: WarpProxy on port 40000
. 然后连接:
warp-cli connect warp-cli enable-always-on
最后, 测试socks代理,理检查IP是否改变. 期望结果是, 显示的是Cloudflare的IP而不是VPS的IP.
systemctl status warp-svc.service curl -x socks5://127.0.0.1:40000 ifconfig.me curl -x socks5://127.0.0.1:40000 cloudflare.com/cdn-cgi/trace
如果我印象中没记错的话, 到这一步, 你其实已经可以访问ChatGPT了. 这个原理跟配置proxy, proxy内部怎么运作, 是很相似的, 就不赘述了. 现在如果你登录Google, 如果还给你登录提示, 同样会发现, 你的IP变了.
3.3.2. 细粒化配置{V2/X}Ray
根据是否访问ChatGPT (以及别的网站) 而决定是否经由40000端口转发给WARP的这个功能可以在{V2/X}Ray里配置outbound的规则. 编辑 /usr/local/etc/xray/config.json
{ // 这是inbound等别的配置, 前面讲过 "outbounds": [ { "tag":"default", "protocol": "freedom" }, { "tag":"ChatGPT", "protocol":"socks", "settings":{ "servers": [ { "address": "127.0.0.1", "port": 40000 } ] } } ], "routing": { "domainStrategy": "AsIs", "rules": [ { "type": "field", "outboundTag": "ChatGPT", "domain": [ "domain:chat.openai.com", "domain:ifconfig.co" ] } ] } }
我这里还顺手加入了个ifconfig.co, 它跟ifconfig.me和who.is的角色是一样的. 这样配置时, 当打开ifconfig.me, 显示的IP是你VPS的IP; 当打开ifconfig.co, 显示的是Cloudflare节点的IP.
Remember, 因为你动过了 /usr/local/etc/xray/config.json
, 可别忘了restart xray.service 使配置生效.