Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/treehollow/install-doc
如何搭建一个树洞
https://github.com/treehollow/install-doc
Last synced: 12 days ago
JSON representation
如何搭建一个树洞
- Host: GitHub
- URL: https://github.com/treehollow/install-doc
- Owner: treehollow
- Created: 2021-04-27T10:48:42.000Z (over 3 years ago)
- Default Branch: main
- Last Pushed: 2021-11-21T04:08:58.000Z (almost 3 years ago)
- Last Synced: 2024-08-01T19:38:07.470Z (3 months ago)
- Size: 39.1 KB
- Stars: 141
- Watchers: 4
- Forks: 18
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
- awesome - treehollow/install-doc - 如何搭建一个树洞 (Others)
README
# 如何搭建一个树洞
## 0 开始搭建树洞之前
如果你在看这篇文章,可能或多或少你对搭建树洞有着一定的兴趣。因此,首先需要强调的是:**搭建并运营一个树洞是一个工作量巨大并且难度很高的事情**。树洞的运营是一个一定需要一支团队才可以胜任的任务,并且这个团队至少需要有以下几点能力:
- 技术:搭建树洞、树洞功能更新时都需要技术能力
- 网络安全:树洞的隐私保护是重中之重,也是树洞用户非常关心的问题
- 日常管理:团队中最好需要管理员7/24值班管理树洞,管理员还需要有极高的舆情处理能力,同时看得懂各种黑话
- 法务:日常管理中遇到的各种问题都可能需要法务帮忙**在你想要开始搭建树洞之前,请确保你身边有一群你们相互信任的伙伴,你们的合力可以覆盖上面几点能力**。
## 1 对技术人员的要求
树洞的技术栈目前已经较为复杂,后端使用的是Linux+Nginx+MySQL+Redis+Go;Web前端使用的是React;Android前端主要是Kotlin;iOS前端是SwiftUI。如果要完成树洞后端的搭建,技术人员至少需要掌握:
- Linux的基本使用方法和常用bash命令,比如vim、top、ps、tmux
- 基础网络协议知识,如HTTP协议等
- 基础的密码学知识,至少需要可以看懂https://github.com/treehollow/treehollow-v3-encryption-doc
- 熟悉git、cron如果你掌握了这些基础,那么请继续往下看吧!**搭建树洞至少需要1天的时间,请保持耐心。**
## 2 选择一个云服务器提供商和操作系统
树洞的后端需要运行在一个有公网IP的服务器中,至少需要1核2G内存,最好2核4G内存或以上。市面上现在有很多服务器提供商,国外大厂商有Amazon AWS、Google Cloud、Microsoft Azure等,小厂商有Digitalocean、Vultr、Linode等,国内知名的有阿里云、腾讯云、华为云等。它们之间的对比如下表:
| | 备案 | 价格 | 网络速度 |
| ---------- | ------ | -------- | -------------------- |
| 国外大厂商 | 不需要 | 比较贵 | 晚上国际出口可能很慢 |
| 国外小厂商 | 不需要 | 比较便宜 | 晚上国际出口可能很慢 |
| 国内厂商 | 需要 | 很贵 | 快 |选择完厂商之后,就选择一个操作系统吧,对于服务器来说,操作系统最重要的特性就是**稳定**。因此,我们推荐**CentOS 7**,它的官方支持将在2024年6月才结束。
## 3 注册一个域名
注册域名实在是太简单了,网上的教程很多。这里需要强调一下安全问题
### 【⚠必须采取的安全措施】:***请务必确保时刻没有子域名DNS解析到服务器真实IP,并且服务器真实IP必须始终保密!***
**服务器的IP如果泄露,DDoS等情况就有可能发生,同时还会极大地增加攻击面。因此,服务器的HTTP流量必须始终通过CDN(比如Cloudflare CDN)。在https://securitytrails.com/dns-trails 网站上,一个域名的全部子域名和DNS历史记录都可以轻松查到,因此不能有任何时刻让服务器真实IP暴露在外。**
### 【建议的安全措施】:请使用堡垒机登录ssh
堡垒机可以减少一定的攻击面,对服务器安全是很有益的。如果树洞运营团队有条件,请使用堡垒机。
## 4 在服务器上搭建后端
### 第一步:设置时区为Asia/Shanghai
```bash
sudo timedatectl set-timezone Asia/Shanghai
```请相信,这会节省很多麻烦的
### 第二步(可选):安装swap空间
有swap空间可以让服务器在内存吃紧的时候有着更好的表现。如果你的服务器硬盘是SSD的,那么swap会消耗SSD寿命;不过如果你是租的服务器,谁会在意寿命呢:)
参考教程:https://www.digitalocean.com/community/tutorials/how-to-add-swap-on-centos-7
### 第三步:安装并配置Nginx,同时配置firewalld或iptables防火墙
参考教程:https://www.digitalocean.com/community/tutorials/how-to-install-nginx-on-centos-7
### 【⚠必须采取的安全措施】:***请务必配置好iptables或firewalld或使用服务器提供商的安全组功能,仅允许CDN流量访问80/443端口***
**否则,攻击者可以通过全网扫描的方式获取服务器的真实IP,参考:https://cloud.tencent.com/developer/article/1079482**
如果你使用的是基于iptables的防火墙,那么我们在此提供一个示例脚本,你可以使用以下脚本方便地添加Cloudflare的节点进入iptables白名单:
```bash
#!/bin/bash
iptables -F
ipset destroy cf4
ipset create cf4 hash:net
for x in $(curl https://www.cloudflare.com/ips-v4); do ipset add cf4 $x; doneiptables -A INPUT -m set --match-set cf4 src -p tcp -m multiport --dports 80,443 -j ACCEPT
iptables -A INPUT -p tcp -m multiport --dports 80,443 -j DROP
iptables-save
```这个脚本要求ipset已经被安装。如果你看不懂这段脚本在干什么,请先搜索学习相关知识之后,再进行后续步骤。
### 第四步:安装并配置MySQL 8.0,Redis,Go
参考教程:
https://www.mysqltutorial.org/install-mysql-centos/
https://www.digitalocean.com/community/tutorials/how-to-install-secure-redis-centos-7
https://golang.org/doc/install
【注意】:MySQL的中文搜索引擎分词在默认情况下有bug,请参考https://github.com/treehollow/treehollow-backend/issues/43 解决
### 第五步(可选):安装并配置Nginx amplify
Nginx Amplify是一个可以监控服务器健康状态的免费平台,详细介绍和安装方法请见https://amplify.nginx.com/
### 第六步:注册Google reCAPTCHA
请到https://developers.google.com/recaptcha/intro 分别注册一个reCAPTCHA v3和reCAPTCHA v2 Checkbox,未来将会在后端和前端配置文件中用到
### 第七步:购买或搭建一个SMTP邮件发送服务器
国外有mailgun和sendgrid,国内有阿里云,也可以自己搭建(可能会很难),具体做法请你根据自身情况搜索
### 第八步:配置Nginx
本文假设读者已经对Nginx配置文件的结构和用法已经有了基本的了解,下面只介绍几个重点。
#### 重点1:如何让Nginx在CDN后面获取IP
由于服务器只和CDN边缘节点进行网络通信,获取客户IP时就会有难度。还好,几乎所有CDN都会在HTTP的**X-Forwarded-For** header中转发客户IP。请参考:https://support.cloudflare.com/hc/en-us/articles/200170986-How-does-Cloudflare-handle-HTTP-Request-headers-
但是我们不能完全信任X-Forwarded-For的结果,因为如果攻击者构造一个含X-Forwarded-For的包,就可以达到IP欺骗的效果。为此,Nginx的比较新的版本里都带一个叫ngx_http_realip_module的模块,只要将CDN的IP列表添加进Nginx信任的列表里,就可以正确解析出客户IP。参考:https://cloud.tencent.com/developer/article/1521273
我们在此提供一个脚本,以Cloudflare CDN为例,生成Nginx所需要的配置文件:
```bash
#!/bin/bash
echo "# generated by updateNginxWhitelist.sh" > /etc/nginx/whitelist.confecho "# Cloudflare IPs" >> /etc/nginx/whitelist.conf
for x in $(curl https://www.cloudflare.com/ips-v4); do echo "set_real_ip_from $x;" >> /etc/nginx/whitelist.conf; doneecho >> /etc/nginx/whitelist.conf
echo "real_ip_header X-Forwarded-For;" >> /etc/nginx/whitelist.conf
echo "real_ip_recursive on;" >> /etc/nginx/whitelist.conf
nginx -t
nginx -s reload
```运行此脚本前,在`nginx.conf`中加入`include whitelist.conf;`就可以了。如果你看不懂这段脚本在干什么,请先搜索学习相关知识之后,再进行后续步骤。
#### 重点2:如何让Go程序在Nginx后面获取IP
以T大树洞API的`/v3/security`块为例,Nginx配置文件会类似:
```
...
location /v3/security {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;proxy_pass http://unix:/somewhere/treehollow-security-api.sock;
error_page 502 = @fallback;
}
...
location @fallback {
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' 'https://web.thuhole.com';
add_header 'Access-Control-Allow-Headers' 'TOKEN';
add_header 'Content-Length' 0;
return 204;
}proxy_pass http://unix:/somewhere/treehollow-fallback.sock;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
add_header Access-Control-Allow-Origin "https://web.thuhole.com";
}
...
```如果你看不懂这段配置**大概**在干什么,请先搜索学习相关知识之后,再进行后续步骤。
#### 重点3:Nginx中Websocket的配置
树洞Android客户端的推送服务使用了Websocket协议的方式,Nginx处理Websocket时的配置应该类似这样:
```
...
server_name ws.thuhole.com;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header X-Forwarded-Proto http;
proxy_redirect http:// $scheme://;proxy_connect_timeout 3m;
proxy_send_timeout 3m;
proxy_read_timeout 3m;proxy_pass http://unix:/somewhere/treehollow-push-api.sock;
}
...
```这里如果看不懂没关系,后面会更仔细介绍T大树洞后端的结构
### 第九步:为树洞后端的运行环境添加新的用户
添加新的低权限Linux用户:
```bash
useradd -m username
```添加新的MySQL数据库及用户:https://matomo.org/faq/how-to-install/faq_23484/
### 第十步(可选):下载GeoIP库
T大树洞使用GeoIP库进行风控等操作,这里你如果不知道用什么库,就用免费的Maxmind数据库:https://dev.maxmind.com/geoip/geoipupdate/
安装并运行geoipupdate,然后把geoipupdate放到crontab里
### 第十一步:下载、编译运行树洞后端代码
树洞后端代码位于https://github.com/treehollow/treehollow-backend
安装方式:`git clone`下来之后,进入项目文件夹,然后运行:
```
go install ./...
```这时会在`$GOPATH/bin`生成几个可执行文件,有用的几个分别是:
`treehollow-v3-push-api`: 用于处理Android和iOS消息推送服务的可执行程序
`treehollow-v3-security-api`: 用于处理`/v3/security` 中所有API的可执行程序
`treehollow-v3-services-api`: 用于处理`/v3/` 中security以外API的可执行程序
`treehollow-v3-fallback`: 当服务更新时,用于向前端显示错误信息的可执行程序
将`example.config.yml`复制到`config.yml`之后修改参数即可运行。在生产环境中,这四个程序应该都在运行
### 第十二步【⚠必须采取的安全措施】:***配置SELinux***
SELinux也许是个讨厌的东西,但它对服务器安全至关重要。为了树洞服务的安全,树洞运营团队的技术人员应该花几个小时学习以下SELinux的使用。这里我们提供一些有用的资料:
学习资料:https://www.digitalocean.com/community/tutorials/an-introduction-to-selinux-on-centos-7-part-1-basic-concepts
实际用的时候其实基本就是用两次audit2allow:https://www.server-world.info/en/note?os=CentOS_7&p=selinux&f=9
(注:如果两次audit2allow不行,那就四次)
### 第十三步:检查各个域名的正常运行、配置前端的config
T大树洞前端代码位于:https://github.com/treehollow/webhole 配置环境变量之后通过GitHub Actions即可成功运行部署
Android和iOS客户端需要配置文件才能正常运行,请在这个模板下修改:https://github.com/treehollow/thuhole-config/blob/main/main.txt
在T大树洞的生产环境中,至少有8个域名会解析运行:
1. `thuhole.com`: 主页
2. `www.thuhole.com`: 跳转到`thuhole.com`
3. `tapi.thuhole.com`: 主要API都在这个域名
4. `ws.thuhole.com`: Android消息推送时的Websocket服务器
5. `re.thuhole.com`: 给app登录时显示reCAPTCHA界面的网页,参考https://github.com/treehollow/thuhole-recaptcha-v2/blob/main/recaptcha/index.html
6. `i.thuhole.com`: 显示图片用的域名
7. `web.thuhole.com`: 网页版树洞
8. `terms.thuhole.com`: 用于放用户协议、隐私政策、树洞规范把这些服务一个个上线是费时费力的事情,但是生产环境毕竟就是需要这么多服务。