1、通过脚本安装Nginx以及Certbot
以下是一个完整的 Bash 脚本,用于在 Debian 12 系统上一键安装 Nginx(官方最新稳定版)和 Certbot(通过 Snap)。脚本会检查执行权限,逐步执行所有命令,并在最后给出后续配置的提示。
#!/bin/bash
# Nginx 和 Certbot 一键安装脚本(适用于 Debian 12)
# 请以 root 用户或使用 sudo 执行此脚本
set -e # 遇到错误立即退出
# 颜色定义(便于阅读输出)
GREEN='\033[0;32m'
RED='\033[0;31m'
NC='\033[0m' # 无颜色
# 检查是否以 root 身份运行
if [[ $EUID -ne 0 ]]; then
echo -e "${RED}请以 root 用户或使用 sudo 执行此脚本。${NC}"
exit 1
fi
echo -e "${GREEN}开始更新系统软件包列表...${NC}"
apt update && apt upgrade -y
echo -e "${GREEN}安装必要的依赖工具...${NC}"
apt install -y curl gnupg2 ca-certificates lsb-release
echo -e "${GREEN}添加 Nginx 官方稳定版仓库...${NC}"
curl -fsSL https://nginx.org/keys/nginx_signing.key | gpg --dearmor | tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] http://nginx.org/packages/debian $(lsb_release -cs) nginx" | tee /etc/apt/sources.list.d/nginx.list
echo -e "${GREEN}更新仓库索引并安装 Nginx...${NC}"
apt update
apt install -y nginx
# 显示 Nginx 版本
nginx_version=$(nginx -v 2>&1 | cut -d '/' -f2)
echo -e "${GREEN}Nginx 安装完成,版本:${nginx_version}${NC}"
echo -e "${GREEN}启动 Nginx 并设置开机自启...${NC}"
systemctl start nginx
systemctl enable nginx
echo -e "${GREEN}安装 Snapd 并更新...${NC}"
apt install -y snapd
snap install core
snap refresh core
echo -e "${GREEN}通过 Snap 安装 Certbot...${NC}"
snap install --classic certbot
ln -sf /snap/bin/certbot /usr/bin/certbot
# 验证 Certbot 安装
certbot_version=$(certbot --version 2>&1)
echo -e "${GREEN}Certbot 安装完成,版本:${certbot_version}${NC}"
echo -e "${GREEN}====================================================${NC}"
echo -e "${GREEN}Nginx 和 Certbot 已成功安装!${NC}"
echo -e "${GREEN}下一步操作:${NC}"
echo -e "1. 根据您的需求修改 Nginx 配置文件:/etc/nginx/nginx.conf"
echo -e " 请确保为 HTTP-01 验证添加 location /.well-known/acme-challenge/ 的配置。"
echo -e "2. 修改后使用 'nginx -t' 测试配置,并使用 'systemctl reload nginx' 重载。"
echo -e "3. 使用以下命令申请 SSL 证书(请替换域名为您的实际域名):"
echo -e " sudo certbot certonly --webroot -w /var/www/html -d example.com -d www.example.com"
echo -e "4. 申请成功后,更新 Nginx 配置中的证书路径,并启用 HTTPS。"
echo -e "${GREEN}====================================================${NC}"
使用方法
将上述内容保存为文件,例如 install-nginx-certbot.sh。
赋予执行权限:chmod +x install-nginx-certbot.sh。
以 root 用户或使用 sudo 执行:sudo ./install-nginx-certbot.sh。
2、修改Nginx配置。
使用编辑工具修改位于 /etc/nginx/conf.d/*.conf 配置。
server {
listen 80;
server_name yisroa.tongames.dpdns.org cangsroa.tongames.dpdns.org;
location /.well-known/acme-challenge/ {
root /var/www/html;
allow all;
}
location / {
return 301 https://$host$request_uri;
}
}
域名根据实际情况修改yisroa.tongames.dpdns.org cangsroa.tongames.dpdns.org。提示:域名与域名之间需用空格间隔。
默认路径为 /var/www/html,如果没有请手动创建
# 1. 创建目录(-p 参数确保如果父目录不存在也会一并创建,且如果目录已存在不会报错)
mkdir -p /var/www/html
# 2. 修改所有者为 www-data (Debian/Ubuntu 上 Nginx 的默认运行用户)
chown -R www-data:www-data /var/www/html
# 3. 设置权限为 755 (所有者可读写执行,其他人可读执行)
chmod -R 755 /var/www/html
修改配置之后,使用命令检查nginx配置,配置没提示报错的情况下,重载nginx配置。
nginx -t
nginx -s reload
之后使用Certbot以webroot模式为域名申请SSL证书。
在正式执行前,加上 --dry-run 参数。这会模拟整个获取流程,而不计入 Let’s Encrypt 的速率限制(Rate Limits)。
sudo certbot certonly --webroot -w /var/www/html -d yourdomain.com -d www.yourdomain.com --email your@email.com --agree-tos --no-eff-email --deploy-hook "systemctl reload nginx" --dry-run
sudo certbot certonly --webroot -w /var/www/html -d yourdomain.com -d www.yourdomain.com --email your@email.com --agree-tos --no-eff-email --deploy-hook "systemctl reload nginx"
- 域名申请成功之后会显示证书路径,如下示例:
/etc/letsencrypt/live/lingsroa.tongames.dpdns.org/fullchain.pem/etc/letsencrypt/live/lingsroa.tongames.dpdns.org/privkey.pem
3、再次为nginx修改配置,添加Https,需修改nginx.conf,以及位于conf.d目录下的配置文件。
nginx.conf配置示例如下:根据实际情况调整。
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /run/nginx.pid;
events {
worker_connections 1024;
}
stream {
map $ssl_preread_server_name $name {
yisroa.tongames.dpdns.org backend1;
cangsroa.tongames.dpdns.org backend2;
cousroa.tongames.dpdns.org backend3;
mensroa.tongames.dpdns.org backend4;
default default_backend;
}
upstream backend1 {
server 127.0.0.1:48001;
}
upstream backend2 {
server 127.0.0.1:48003;
}
upstream backend3 {
server 127.0.0.1:48005;
}
upstream backend4 {
server 127.0.0.1:48007;
}
upstream default_backend {
server 127.0.0.1:8011;
}
server {
listen 443;
proxy_pass $name;
ssl_preread on;
proxy_protocol on;
}
}
http {
# --- 1. 基础全局配置 ---
include mime.types;
default_type application/octet-stream;
log_format main '[$time_local] $proxy_protocol_addr "$http_referer" "$http_user_agent"';
access_log /var/log/nginx/access.log main;
server_tokens off;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# --- 2. 全局映射逻辑 (原子配置1) ---
# 这里的变量在所有 server 块中均可直接使用
# WebSocket 升级映射
map $http_upgrade $connection_upgrade {
default upgrade;
"" close;
}
# Proxy Protocol 地址格式化映射
map $proxy_protocol_addr $proxy_forwarded_elem {
~^[0-9.]+$ "for=$proxy_protocol_addr";
~^[0-9A-Fa-f:.]+$ "for=\"[$proxy_protocol_addr]\"";
default "for=unknown";
}
# 复杂的 RFC 7239 Forwarded 头部构造映射
map $http_forwarded $proxy_add_forwarded {
"~^(,[ \\t]*)*([!#$%&'*+.^_`|~0-9A-Za-z-]+=([!#$%&'*+.^_`|~0-9A-Za-z-]+|\"([\\t \\x21\\x23-\\x5B\\x5D-\\x7E\\x80-\\xFF]|\\\\[\\t \\x21-\\x7E\\x80-\\xFF])*\"))?(;([!#$%&'*+.^_`|~0-9A-Za-z-]+=([!#$%&'*+.^_`|~0-9A-Za-z-]+|\"([\\t \\x21\\x23-\\x5B\\x5D-\\x7E\\x80-\\xFF]|\\\\[\\t \\x21-\\x7E\\x80-\\xFF])*\"))?)*([ \\t]*,([ \\t]*([!#$%&'*+.^_`|~0-9A-Za-z-]+=([!#$%&'*+.^_`|~0-9A-Za-z-]+|\"([\\t \\x21\\x23-\\x5B\\x5D-\\x7E\\x80-\\xFF]|\\\\[\\t \\x21-\\x7E\\x80-\\xFF])*\"))?(;([!#$%&'*+.^_`|~0-9A-Za-z-]+=([!#$%&'*+.^_`|~0-9A-Za-z-]+|\"([\\t \\x21\\x23-\\x5B\\x5D-\\x7E\\x80-\\xFF]|\\\\[\\t \\x21-\\x7E\\x80-\\xFF])*\"))?)*)?)*$" "$http_forwarded, $proxy_forwarded_elem";
default "$proxy_forwarded_elem";
}
# --- 3. 包含业务子配置 ---
# 具体的 server 块依然建议放在独立文件中
include /etc/nginx/conf.d/*.conf;
}
conf.d目录示例配置如下:
server {
listen 80;
server_name yisroa.tongames.dpdns.org cangsroa.tongames.dpdns.org;
location /.well-known/acme-challenge/ {
root /var/www/html;
allow all;
}
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 127.0.0.1:8011 ssl proxy_protocol;
ssl_reject_handshake on;
ssl_protocols TLSv1.2 TLSv1.3;
}
server {
listen 127.0.0.1:8002 ssl proxy_protocol;
http2 on;
set_real_ip_from 127.0.0.1;
real_ip_header proxy_protocol;
ssl_certificate /etc/letsencrypt/live/lingsroa.tongames.dpdns.org/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/lingsroa.tongames.dpdns.org/privkey.pem;
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;
ssl_session_timeout 1h;
ssl_session_cache shared:SSL:10m;
ssl_stapling off;
ssl_stapling_verify off;
resolver 1.1.1.1 valid=60s;
resolver_timeout 2s;
location / {
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
root /var/www/html;
index index.html index.htm;
}
}
server {
listen 127.0.0.1:8004 ssl proxy_protocol;
http2 on;
set_real_ip_from 127.0.0.1;
real_ip_header proxy_protocol;
ssl_certificate /etc/letsencrypt/live/lingsroa.tongames.dpdns.org/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/lingsroa.tongames.dpdns.org/privkey.pem;
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;
ssl_session_timeout 1h;
ssl_session_cache shared:SSL:10m;
ssl_stapling off;
ssl_stapling_verify off;
resolver 1.1.1.1 valid=60s;
resolver_timeout 2s;
location / {
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
root /var/www/html;
index index.html index.htm;
}
}
server {
listen 127.0.0.1:8006 ssl proxy_protocol;
http2 on;
set_real_ip_from 127.0.0.1;
real_ip_header proxy_protocol;
ssl_certificate /etc/letsencrypt/live/lingsroa.tongames.dpdns.org/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/lingsroa.tongames.dpdns.org/privkey.pem;
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;
ssl_session_timeout 1h;
ssl_session_cache shared:SSL:10m;
ssl_stapling off;
ssl_stapling_verify off;
resolver 1.1.1.1 valid=60s;
resolver_timeout 2s;
location / {
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
root /var/www/html;
index index.html index.htm;
}
}
server {
listen 127.0.0.1:8008 ssl proxy_protocol;
http2 on;
set_real_ip_from 127.0.0.1;
real_ip_header proxy_protocol;
ssl_certificate /etc/letsencrypt/live/lingsroa.tongames.dpdns.org/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/lingsroa.tongames.dpdns.org/privkey.pem;
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;
ssl_session_timeout 1h;
ssl_session_cache shared:SSL:10m;
ssl_stapling off;
ssl_stapling_verify off;
resolver 1.1.1.1 valid=60s;
resolver_timeout 2s;
location / {
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
root /var/www/html;
index index.html index.htm;
}
}
修改配置之后,使用命令检查nginx配置,配置没提示报错的情况下,重载nginx配置。
nginx -t
nginx -s reload
4、使用v2node对接v2board,以Reality节点作为示例:
v2board 面板、Reality配置如下,与nginx中的stream sni配置相互对应
- 连接端口443,服务端口对应
nginx stream sni分流端口,例如48001; Reality配置对应nginx中的Server中的监听端口,例如 8002;- 传输协议TCP需添加如下配置:
{
"acceptProxyProtocol": true,
"header": {
"type": "none"
}
}

参考配置:
1、chika0801/Xray-examples: Xray 配置示例
正文完