部署Gitea+Nginx+Xray服务
前言
众所周知部署VLESS+XTLS+Reality时,一般使用一个诸如microsoft.com的域名来进行TLS握手,达到伪装的目的。然而最近越来越多的用户反映,使用别人的域名有可能导致VPS被标记为滥用,体验也不一定稳定。考虑到XTLS已经可以尽可能消除TLS in TLS特征,将域名改成自己建立的网站也仍然能够保留隐蔽性。而对于配置不高的VPS,部署一个Gitea作为自己的网站是一个不错的选择。本文将介绍如何在VPS上部署Gitea+Nginx+Xray服务。
准备
- 一台VPS,有公网IP,推荐使用Debian/Ubuntu系统,本文将以Debian 13为例
- 域名,已解析到VPS的IP地址(CloudFlare中必须关闭黄云,否则Xray无法工作)
架构
使用Xray监听443端口,对于Xray认为合法的流量使用Reality握手,否则直接原封不动回落到本地的Nginx服务,实现同一个域名两个用途,同时保持隐蔽性。Nginx监听8001端口,在验证主机名合法后转发给3000端口上的Gitea。
选择:Xray还是sing-box?
Xray和sing-box都支持Reality协议,但在实际使用中,sing-box的性能和稳定性更好一些。然而为了让Nginx日志显示真实访客IP而不是127.0.0.1,必须要让Xray转发proxy protocol给Nginx,而sing-box目前不支持proxy protocol,因此本文选择使用Xray。此外,额外提供了sing-box的配置文件供参考。
部署:Xray
如果你希望使用sing-box,请跳过本节:#
安装
使用以下命令安装Xray,该命令自动适配所有架构:
1
sudo bash -c "$(curl -L https://github.com/XTLS/Xray-install/raw/main/install-release.sh)" @ install
安装完成后,使用以下命令启动Xray服务(如果脚本没有自动启动的话):
1
sudo systemctl enable --now xray
生成所需内容
使用以下命令生成UUID:
1
xray uuid
使用以下命令生成Reality所需的密钥对:
1
xray x25519
使用以下命令生成Reality所需的shortid:
1
openssl rand -hex 8
记下这几个内容,后续配置中需要使用,且请务必妥善保管,避免泄露。
配置
配置文件在/usr/local/etc/xray/config.json,使用以下命令编辑:
1
sudo vim /usr/local/etc/xray/config.json
输入dd删除全部内容,然后粘贴以下配置(注意将YOUR_UUID、YOUR_PRIVATE_KEY、YOUR_SHORT_ID和YOUR_DOMAIN替换为实际值):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
{
"log": {
"loglevel": "warning"
},
"dns": {
"servers": [
{
"address": "https://1.1.1.1/dns-query"
}
]
},
"inbounds": [
{
"listen": "::",
"port": 443,
"protocol": "vless",
"settings": {
"clients": [
{
"id": "YOUR_UUID",
"flow": "xtls-rprx-vision"
}
],
"decryption": "none"
},
"streamSettings": {
"network": "tcp",
"security": "reality",
"realitySettings": {
"show": false,
"target": "127.0.0.1:8001",
"xver": 1,
"serverNames": ["YOUR_DOMAIN"],
"privateKey": "YOUR_PRIVATE_KEY",
"shortIds": ["YOUR_SHORT_ID"]
}
},
"sniffing": {
"enabled": true,
"destOverride": ["http", "tls", "quic"]
}
}
],
"outbounds": [
{
"protocol": "freedom",
"tag": "direct"
},
{
"protocol": "blackhole",
"tag": "block"
}
],
"routing": {
"domainStrategy": "AsIs",
"rules": [
{
"type": "field",
"ip": ["geoip:private", "geoip:cn"],
"outboundTag": "block"
},
{
"type": "field",
"domain": ["geosite:cn"],
"outboundTag": "block"
},
{
"type": "field",
"protocol": ["bittorrent"],
"outboundTag": "block"
}
]
}
}
为了防止各种探测,该配置文件默认丢弃部分流量,而常规HTTPS流量将转发到Nginx服务。而xver=1则向Nginx传递了proxy protocol。配置完成后,使用以下命令重启Xray服务:
1
sudo systemctl restart xray
由于此时Nginx服务还没有配置,连不上是正常的。
部署: sing-box(可选)
如果你只需要Xray,请跳过本节:#
如果不在意Nginx日志中全都是127.0.0.1的问题,可以使用sing-box替代Xray,一般认为性能更好。由于共用端口,sing-box和Xray无法同时运行,因此需要先禁用Xray服务:
1
sudo systemctl disable --now xray
安装
使用官方apt仓库:
1
2
3
4
5
6
7
8
9
10
11
12
13
sudo mkdir -p /etc/apt/keyrings &&
sudo curl -fsSL https://sing-box.app/gpg.key -o /etc/apt/keyrings/sagernet.asc &&
sudo chmod a+r /etc/apt/keyrings/sagernet.asc &&
echo '
Types: deb
URIs: https://deb.sagernet.org/
Suites: *
Components: *
Enabled: yes
Signed-By: /etc/apt/keyrings/sagernet.asc
' | sudo tee /etc/apt/sources.list.d/sagernet.sources &&
sudo apt-get update &&
sudo apt-get install sing-box # or sing-box-beta
启用服务:
1
sudo systemctl enable --now sing-box
生成所需内容
sing-box生成的原理和Xray是一样的,如果已经生成过了可以跳过。 没有生成过的请使用以下命令生成UUID:
1
sing-box generate uuid
使用以下命令生成Reality所需的密钥对:
1
sing-box generate reality-keypair
使用以下命令生成Reality所需的shortid:
1
openssl rand -hex 8
记下这几个内容,后续配置中需要使用,且请务必妥善保管,避免泄露。
配置
1
vim /etc/sing-box/config.json
用上述方法安装sing-box时会自动创建配置文件/etc/sing-box/config.json,其中含有一个非空的示例配置,编辑时需要按住d全部删掉再粘贴。同样,记得将YOUR_UUID、YOUR_PRIVATE_KEY、YOUR_SHORT_ID和YOUR_DOMAIN替换为实际值:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
{
"log": {
"level": "warn",
"timestamp": true
},
"dns": {
"servers": [
{
"type": "https",
"tag": "local",
"server": "1.1.1.1"
}
],
"strategy": "prefer_ipv4"
},
"inbounds": [
{
"type": "vless",
"tag": "vless-in",
"listen": "::",
"listen_port": 443,
"users": [
{
"name": "YOUR_NAME",
"uuid": "YOUR_UUID",
"flow": "xtls-rprx-vision"
}
],
"tls": {
"enabled": true,
"server_name": "YOUR_DOMAIN",
"reality": {
"enabled": true,
"handshake": {
"server": "127.0.0.1",
"server_port": 8001
},
"private_key": "YOUR_PRIVATE_KEY",
"short_id": ["YOUR_SHORT_ID"]
}
}
}
],
"outbounds": [
{
"type": "direct",
"tag": "direct",
"domain_resolver": "local"
}
],
"route": {
"rules": [
{
"action": "sniff"
},
{
"ip_is_private": true,
"rule_set": ["geoip-cn", "geosite-cn"],
"action": "reject"
},
{
"protocol": "bittorrent",
"action": "reject"
}
],
"rule_set": [
{
"type": "remote",
"tag": "geosite-cn",
"format": "binary",
"url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-cn.srs"
},
{
"type": "remote",
"tag": "geoip-cn",
"format": "binary",
"url": "https://raw.githubusercontent.com/SagerNet/sing-geoip/rule-set/geoip-cn.srs"
}
],
"final": "direct"
}
}
和Xray配置一样,sing-box配置中默认丢弃部分流量,而常规HTTPS流量将转发到Nginx服务。配置完成后,使用以下命令重启sing-box服务:
1
sudo systemctl restart sing-box
部署:Nginx
Nginx用于提供证书和回落到Gitea服务,监听8001端口。在此之前,还需要获取证书,推荐使用Certbot等免费服务。下文将以CloudFlare的DNS 01验证方式为例,介绍如何获取证书。如果使用其他方式获取证书,请参考Certbot官方文档。
安装Nginx并申请证书
安装Nginx和Certbot的依赖:
1
2
3
sudo apt update
sudo apt install nginx
sudo apt install python3 python3-dev python3-venv libaugeas-dev gcc
创建Python虚拟环境并安装Certbot:
1
2
3
4
sudo python3 -m venv /opt/certbot/
sudo /opt/certbot/bin/pip install --upgrade pip
sudo /opt/certbot/bin/pip install certbot certbot-nginx
sudo ln -s /opt/certbot/bin/certbot /usr/local/bin/certbot
安装CloudFlare插件:
1
sudo /opt/certbot/bin/pip install certbot-dns-cloudflare
到CloudFlare网站创建一个API Token,必须开启的权限是该域名下的DNS Write,复制下来(应该为cfat_xxxxxxxxxxxxxxx的形式),保存到任意地方的文件中,内容如下:
1
dns_cloudflare_api_token = cfat_xxxxxxxxxxxxxxx
然后运行
1
sudo certbot certonly --dns-cloudflare --dns-cloudflare-credentials /path/to/your/cloudflare.ini -d YOUR_DOMAIN
这里域名支持通配符(例如*.example.com),可以用多个-d参数指定多个域名。证书将会保存在/etc/letsencrypt/live/YOUR_DOMAIN/目录下。 自动更新证书:
1
echo "0 0,12 * * * root /opt/certbot/bin/python -c 'import random; import time; time.sleep(random.random() * 3600)' && sudo certbot renew -q" | sudo tee -a /etc/crontab > /dev/null
配置Nginx
1
sudo vim /etc/nginx/conf.d/reality.conf
粘贴以下内容(注意将YOUR_DOMAIN替换为实际值):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# 1. 默认服务器:阻断未知 SNI 和直接 IP 扫描
server {
# 必须加上 proxy_protocol,因为 Xray 开启 xver: 1 后会无差别发送协议头
listen 127.0.0.1:8001 ssl proxy_protocol default_server;
# listen 127.0.0.1:8001 ssl default_server;
# 拒绝所有非白名单域名的 TLS 握手
ssl_reject_handshake on;
}
# 2. 真实网站:处理来自 Xray 的合法回落流量
server {
listen 127.0.0.1:8001 ssl proxy_protocol;
# listen 127.0.0.1:8001 ssl;
http2 on;
server_name YOUR_DOMAIN;
# 还原访客的真实 IP(用于 Nginx 日志)
set_real_ip_from 127.0.0.1;
real_ip_header proxy_protocol;
# 你的真实 SSL 证书路径(请根据你的实际路径修改)
ssl_certificate /etc/letsencrypt/live/YOUR_DOMAIN/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/YOUR_DOMAIN/privkey.pem;
# TLS 安全套件配置
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers TLS13_AES_128_GCM_SHA256:TLS13_AES_256_GCM_SHA384:TLS13_CHACHA20_POLY1305_SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305;
ssl_prefer_server_ciphers on;
# Gitea
location / {
proxy_pass http://127.0.0.1:3000;
# 传递客户端真实 IP 给 Gitea
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# 支持 WebSocket(Gitea 的实时通知功能需要)
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# 允许上传较大文件(例如代码包、附件)
client_max_body_size 512M;
}
}
如果你使用了sing-box,或者Xray配置中没有开启xver: 1,那么需要修改这些行为如下内容:
1
2
3
4
5
6
7
8
9
# listen 127.0.0.1:8001 ssl proxy_protocol default_server;
listen 127.0.0.1:8001 ssl default_server;
# listen 127.0.0.1:8001 ssl proxy_protocol;
listen 127.0.0.1:8001 ssl;
# real_ip_header proxy_protocol;
保存后重启Nginx:
1
2
sudo systemctl enable --now nginx
sudo systemctl restart nginx
客户端配置
对于Mihomo内核(注意将YOUR_UUID、YOUR_PUBLIC_KEY、YOUR_SHORT_ID、YOUR_IP和YOUR_DOMAIN替换为实际值):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
- name: proxy
type: vless
server: YOUR_IP
port: 443
udp: true
uuid: YOUR_UUID
flow: xtls-rprx-vision
packet-encoding: xudp
tls: true
servername: YOUR_DOMAIN
client-fingerprint: chrome
network: tcp
reality-opts:
public-key: YOUR_PUBLIC_KEY
short-id: "YOUR_SHORT_ID"
对于sing-box内核(注意将YOUR_UUID、YOUR_PUBLIC_KEY、YOUR_SHORT_ID、YOUR_IP和YOUR_DOMAIN替换为实际值):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
{
"type": "vless",
"tag": "proxy",
"server": "YOUR_IP",
"server_port": 443,
"uuid": "YOUR_UUID",
"flow": "xtls-rprx-vision",
"packet_encoding": "xudp",
"tls": {
"enabled": true,
"server_name": "YOUR_DOMAIN",
"utls": {
"enabled": true,
"fingerprint": "chrome"
},
"reality": {
"enabled": true,
"public_key": "YOUR_PUBLIC_KEY",
"short_id": "YOUR_SHORT_ID"
}
}
}
如果可以连接,且访问域名看到502 Bad Gateway,说明Xray和Nginx配置正确。如果无法连接,需要排查VPS是否开启443端口。
安装Gitea
Gitea其实并没有提供官方的一键安装脚本,但可以使用官方提供的二进制文件。下载最新版本的Gitea:
1
2
sudo wget -o /usr/local/bin/gitea https://dl.gitea.com/gitea/1.27.1/gitea-1.27.1-linux-amd64
sudo chmod +x /usr/local/bin/gitea
创建Gitea用户和目录:
1
2
3
4
5
6
7
sudo adduser --system --shell /bin/bash --gecos 'Git Version Control' --group --disabled-password --home /home/git git
sudo mkdir -p /var/lib/gitea/{custom,data,log}
sudo chown -R git:git /var/lib/gitea/
sudo chmod -R 750 /var/lib/gitea/
sudo mkdir -p /etc/gitea
sudo chown root:git /etc/gitea
sudo chmod 770 /etc/gitea
创建Gitea服务文件:
1
sudo vim /etc/systemd/system/gitea.service
写入以下内容:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[Unit]
Description=Gitea (Git with a cup of tea)
After=network.target
[Service]
RestartSec=2s
Type=simple
User=git
Group=git
WorkingDirectory=/var/lib/gitea/
ExecStart=/usr/local/bin/gitea web --config /etc/gitea/app.ini
Restart=always
Environment=USER=git HOME=/home/git GITEA_WORK_DIR=/var/lib/gitea/
[Install]
WantedBy=multi-user.target
保存后启动Gitea:
1
sudo systemctl enable --now gitea
无须重启Nginx或者Xray,直接访问https://YOUR_DOMAIN即可看到Gitea的安装界面。
后续步骤
Gitea和GitHub一样,支持使用PGP签名提交,且由于Gitea没有像gh-cli一样的官方命令行工具,因此推荐使用SSH访问。 如果需要让Gitea上的仓库提交使用和GitHub不同的邮件(例如开启了隐藏电子邮件),可以参考以下配置。 在~/.gitconfig中添加:
1
2
[includeIf "hasconfig:remote.*.url:git@YOUR_DOMAIN:*/**"]
path = ~/.gitconfig-gitea
在~/.gitconfig-gitea中添加:
1
2
3
[user]
name = YOUR_NAME
email = YOUR_GITEA_EMAIL
如果开启了电子邮件隐藏功能,Gitea会提供一个noreply邮箱地址,使用该邮箱地址即可隐藏真实邮箱,该地址形如:1+YOUR_NAME@noreply.YOUR_DOMAIN。
总结
作为托管服务,Gitea本身的流量特征和Xray有一定相似之处,比直接使用microsoft.com等域名更稳定,握手延迟更低,且不容易因为滥用而被封禁,是一个可行又实用的回落方案。