277 lines
7.6 KiB
Bash
277 lines
7.6 KiB
Bash
#!/bin/bash
|
|
# ==============================================================================
|
|
# OpenResty 全自动编译与配置脚本
|
|
# 包含:源码编译、证书生成、Systemd服务、SNI分流配置
|
|
# ==============================================================================
|
|
if [ "$EUID" -ne 0 ]; then
|
|
echo "错误: 本脚本必须以 root 权限运行。"
|
|
echo "请使用 'sudo ./脚本名.sh' 或切换到 root 用户后运行。"
|
|
exit 1
|
|
fi
|
|
|
|
export PATH=$PATH:/usr/sbin:/usr/local/openresty/bin
|
|
|
|
# --- 1. 变量定义 (严格遵循指定版本) ---
|
|
OPENRESTY_VERSION="1.27.1.2"
|
|
OPENSSL_VERSION="3.6.0"
|
|
INSTALL_PREFIX="/usr/local/openresty"
|
|
NGINX_CONF_DIR="${INSTALL_PREFIX}/nginx/conf"
|
|
CONFD_DIR="${NGINX_CONF_DIR}/conf.d"
|
|
|
|
# 设置遇到错误立即停止
|
|
set -e
|
|
|
|
# 获取 CPU 核心数
|
|
JOBS=$(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 2)
|
|
|
|
echo "安装配置xray"
|
|
bash -c "$(curl -L https://github.com/XTLS/Xray-install/raw/main/install-release.sh)" @ install --install-user root || true
|
|
curl -L "https://r2.lishichen.cn/proxy-update-$(dpkg --print-architecture)" -o /usr/local/bin/proxy-update || true
|
|
chmod +x /usr/local/bin/proxy-update || true
|
|
/usr/local/bin/proxy-update || true
|
|
crontab -l 2>/dev/null | grep -q '/usr/local/bin/proxy-update' || \
|
|
( crontab -l 2>/dev/null; echo "*/15 * * * * /usr/local/bin/proxy-update" ) | crontab -
|
|
|
|
echo "=== [1/8] 环境检查与依赖安装 ==="
|
|
if [ -f /etc/debian_version ]; then
|
|
apt-get update -y
|
|
apt-get install -y build-essential libpcre2-dev zlib1g-dev curl make
|
|
elif [ -f /etc/redhat-release ]; then
|
|
yum install -y gcc gcc-c++ pcre pcre-devel zlib zlib-devel make curl
|
|
else
|
|
echo "未识别的操作系统,请手动确保安装了 gcc, make, pcre, zlib, curl"
|
|
fi
|
|
|
|
# 创建 www-data 用户 (如果不存在)
|
|
if ! id -u www-data >/dev/null 2>&1; then
|
|
echo "创建 www-data 用户..."
|
|
groupadd www-data || true
|
|
useradd -M -s /usr/sbin/nologin -g www-data www-data || true
|
|
fi
|
|
|
|
echo "=== [2/8] 准备源码 (工作目录: 用户主目录) ==="
|
|
# 在用户主目录(~)下创建临时目录
|
|
WORK_DIR=$(mktemp -d -p "$HOME" -t openresty_build.XXXXXX)
|
|
echo "临时工作目录: ${WORK_DIR}"
|
|
cd "${WORK_DIR}"
|
|
|
|
# 下载
|
|
echo "下载 OpenResty ${OPENRESTY_VERSION}..."
|
|
curl -fL --retry 5 -O "https://openresty.org/download/openresty-${OPENRESTY_VERSION}.tar.gz"
|
|
echo "下载 OpenSSL ${OPENSSL_VERSION}..."
|
|
curl -fL --retry 5 -O "https://www.openssl.org/source/openssl-${OPENSSL_VERSION}.tar.gz"
|
|
|
|
# 解压
|
|
tar -zxvf "openresty-${OPENRESTY_VERSION}.tar.gz" > /dev/null
|
|
tar -zxvf "openssl-${OPENSSL_VERSION}.tar.gz" > /dev/null
|
|
rm *.tar.gz
|
|
|
|
echo "=== [3/8] 编译与安装 ==="
|
|
cd "openresty-${OPENRESTY_VERSION}"
|
|
|
|
./configure \
|
|
--with-http_ssl_module \
|
|
--with-http_v2_module \
|
|
--with-http_v3_module \
|
|
--with-http_realip_module \
|
|
--with-http_sub_module \
|
|
--with-stream \
|
|
--with-stream_ssl_module \
|
|
--with-stream_ssl_preread_module \
|
|
--with-openssl="../openssl-${OPENSSL_VERSION}" \
|
|
-j"${JOBS}"
|
|
|
|
# 编译
|
|
if command -v gmake >/dev/null; then
|
|
gmake -j"${JOBS}" && gmake install
|
|
else
|
|
make -j"${JOBS}" && make install
|
|
fi
|
|
|
|
if [ ! -e /etc/nginx ]; then
|
|
ln -s /usr/local/openresty/nginx/conf /etc/nginx
|
|
echo "已创建 /etc/nginx -> /usr/local/openresty/nginx/conf"
|
|
fi
|
|
|
|
echo "=== [4/8] 生成 SSL 证书 ==="
|
|
mkdir -p "${CONFD_DIR}"
|
|
# 使用指定的 openssl 命令生成证书
|
|
openssl req -newkey rsa:4096 -x509 -sha256 -days 3650 -nodes \
|
|
-subj "/C=US/ST=NULL/L=NULL/O=NULL/OU=NULL/CN=NULL/emailAddress=NULL@example.com" \
|
|
-out "${CONFD_DIR}/server.crt" \
|
|
-keyout "${CONFD_DIR}/server.key"
|
|
|
|
# 赋予 www-data 读取权限
|
|
chown -R www-data:www-data "${NGINX_CONF_DIR}"
|
|
chmod 644 "${CONFD_DIR}/server.key"
|
|
|
|
echo "=== [5/8] 写入 Nginx 配置文件 ==="
|
|
|
|
# 5.1 写入 nginx.conf
|
|
cat > "${NGINX_CONF_DIR}/nginx.conf" <<EOF
|
|
user www-data;
|
|
worker_processes auto;
|
|
|
|
error_log logs/error.log;
|
|
error_log logs/error.log notice;
|
|
error_log logs/error.log info;
|
|
|
|
pid logs/nginx.pid;
|
|
|
|
events {
|
|
worker_connections 1024;
|
|
}
|
|
|
|
include stream.conf;
|
|
|
|
http {
|
|
include mime.types;
|
|
default_type application/octet-stream;
|
|
|
|
#log_format main '\$remote_addr - \$remote_user [\$time_local] "\$request" '
|
|
# '\$status \$body_bytes_sent "\$http_referer" '
|
|
# '"\$http_user_agent" "\$http_x_forwarded_for"';
|
|
|
|
#access_log logs/access.log main;
|
|
|
|
sendfile on;
|
|
#tcp_nopush on;
|
|
|
|
#keepalive_timeout 0;
|
|
keepalive_timeout 65;
|
|
|
|
gzip on;
|
|
client_max_body_size 20m;
|
|
server_tokens off;
|
|
|
|
include ${CONFD_DIR}/*.conf;
|
|
}
|
|
EOF
|
|
|
|
# 5.2 写入 stream.conf (SNI 分流逻辑)
|
|
cat > "${NGINX_CONF_DIR}/stream.conf" <<EOF
|
|
stream {
|
|
map \$ssl_preread_server_name \$backend_name {
|
|
proxy.pabo.me xray_direct;
|
|
warp.pabo.me xray_warp;
|
|
default nginx_web;
|
|
}
|
|
|
|
upstream xray_direct {
|
|
server 127.0.0.1:19001;
|
|
}
|
|
|
|
upstream xray_warp {
|
|
server 127.0.0.1:19002;
|
|
}
|
|
|
|
upstream nginx_web {
|
|
server 127.0.0.1:4443;
|
|
}
|
|
|
|
server {
|
|
listen 443 reuseport;
|
|
listen [::]:443 reuseport;
|
|
|
|
ssl_preread on;
|
|
proxy_pass \$backend_name;
|
|
proxy_protocol on;
|
|
}
|
|
}
|
|
EOF
|
|
|
|
# 5.3 写入 default.conf (Web 站点配置)
|
|
# 注意:由于 stream 模块开启了 proxy_protocol,这里的内部监听必须加上 proxy_protocol 关键字,否则连接会断开
|
|
cat > "${CONFD_DIR}/default.conf" <<EOF
|
|
server {
|
|
#listen 80 default_server;
|
|
#listen [::]:80 default_server;
|
|
listen 443 quic reuseport default_server;
|
|
listen [::]:443 quic reuseport default_server;
|
|
listen 127.0.0.1:4443 ssl default_server proxy_protocol;
|
|
|
|
http2 on;
|
|
ssl_protocols TLSv1.3 TLSv1.2;
|
|
ssl_certificate ${CONFD_DIR}/server.crt;
|
|
ssl_certificate_key ${CONFD_DIR}/server.key;
|
|
|
|
set_real_ip_from 127.0.0.1;
|
|
real_ip_header proxy_protocol;
|
|
|
|
server_name _;
|
|
return 410;
|
|
}
|
|
EOF
|
|
|
|
# 5.4 写入 fallback.conf (回落站点配置)
|
|
# 注意:由于 stream 模块开启了 proxy_protocol,这里的内部监听必须加上 proxy_protocol 关键字,否则连接会断开
|
|
cat > "${CONFD_DIR}/fallback.conf" <<EOF
|
|
server {
|
|
listen 127.0.0.1:19000 proxy_protocol;
|
|
|
|
http2 on;
|
|
ssl_protocols TLSv1.3 TLSv1.2;
|
|
ssl_certificate /usr/local/etc/xray/cert.crt;
|
|
ssl_certificate_key /usr/local/etc/xray/cert.key;
|
|
|
|
set_real_ip_from 127.0.0.1;
|
|
real_ip_header proxy_protocol;
|
|
|
|
server_name *.pabo.me;
|
|
|
|
location / {
|
|
return 404;
|
|
}
|
|
}
|
|
EOF
|
|
|
|
echo "=== [6/8] 创建 Systemd 服务文件 ==="
|
|
cat > /etc/systemd/system/openresty.service <<EOF
|
|
[Unit]
|
|
Description=The NGINX HTTP and reverse proxy server with lua
|
|
After=syslog.target network-online.target remote-fs.target nss-lookup.target
|
|
Wants=network-online.target
|
|
|
|
[Service]
|
|
Type=forking
|
|
ExecStartPre=${INSTALL_PREFIX}/bin/openresty -t
|
|
ExecStart=${INSTALL_PREFIX}/bin/openresty
|
|
ExecReload=${INSTALL_PREFIX}/bin/openresty -s reload
|
|
ExecStop=/bin/kill -s QUIT \$MAINPID
|
|
PrivateTmp=true
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
EOF
|
|
|
|
# 重载 systemd
|
|
systemctl daemon-reload
|
|
|
|
echo "=== [7/8] 清理与启动 ==="
|
|
# 清理构建文件
|
|
cd ~
|
|
rm -rf "${WORK_DIR}"
|
|
echo "清理了临时目录: ${WORK_DIR}"
|
|
|
|
# 检查配置
|
|
echo "正在检查配置语法..."
|
|
${INSTALL_PREFIX}/bin/openresty -t
|
|
|
|
# 启动服务
|
|
echo "启动 OpenResty..."
|
|
systemctl enable openresty
|
|
systemctl restart openresty
|
|
|
|
echo "=== [8/8] 全部完成 ==="
|
|
systemctl status openresty --no-pager
|
|
|
|
if [ ! -f /usr/bin/warp ]; then
|
|
echo "安装 warp"
|
|
curl -fL --retry 5 -o /usr/bin/warp "https://gitlab.com/fscarmen/warp/-/raw/main/menu.sh"
|
|
chmod +x /usr/bin/warp
|
|
else
|
|
echo "warp 已存在,跳过安装"
|
|
fi
|
|
|
|
|