download/panel/nginx/install.sh
耗子 7a0048ae8a
Some checks failed
Generate Checksums / checksums (push) Has been cancelled
fix: nginx update
2025-04-18 15:14:23 +08:00

596 lines
20 KiB (Stored with Git LFS)
Bash
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
: '
Copyright (C) 2022 - now HaoZi Technology Co., Ltd.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
'
source <(curl -f -s --connect-timeout 10 --retry 3 https://dl.cdn.haozi.net/panel/public.sh)
if [ $? -ne 0 ]; then
echo "下载 public.sh 失败,请检查网络或稍后重试。"
echo "Download public.sh failed, please check the network or try again later."
exit 1
fi
channel=${1}
version=${2}
nginx_path="${setup_path}/server/nginx"
j=$(calculate_j)
# 安装依赖
if [ ${OS} == "rhel" ]; then
dnf makecache -y
dnf groupinstall "Development Tools" -y
dnf install cmake tar unzip gd gd-devel git-core flex perl oniguruma oniguruma-devel libsodium-devel libxml2-devel libxslt-devel bison yajl yajl-devel curl curl-devel ncurses-devel libevent-devel readline-devel libuuid-devel brotli-devel icu libicu libicu-devel openssl openssl-devel libzstd-devel -y
elif [ ${OS} == "debian" ] || [ ${OS} == "ubuntu" ]; then
apt-get update
apt-get install build-essential cmake tar unzip libgd3 libgd-dev git flex perl libonig-dev libsodium-dev libxml2-dev libxslt1-dev bison libyajl-dev curl libcurl4-openssl-dev libncurses5-dev libevent-dev libreadline-dev uuid-dev libbrotli-dev icu-devtools libicu-dev openssl libssl-dev libzstd-dev -y
else
error "不支持的操作系统"
fi
if [ "$?" != "0" ]; then
error "安装依赖软件失败"
fi
# 准备目录
rm -rf ${nginx_path}
mkdir -p ${nginx_path}
cd ${nginx_path}
# 下载源码
wget --retry-connrefused --retry-on-host-error --retry-on-http-error=429,500,502,503,504 -t 10 -T 120 -O ${nginx_path}/openresty-${version}.tar.gz ${download_url}/nginx/openresty-${version}.tar.gz
wget --retry-connrefused --retry-on-host-error --retry-on-http-error=429,500,502,503,504 -t 10 -T 120 -O ${nginx_path}/openresty-${version}.tar.gz.sha256 ${download_url}/nginx/openresty-${version}.tar.gz.sha256
if ! sha256sum --status -c openresty-${version}.tar.gz.sha256; then
rm -rf ${nginx_path}
error "nginx 校验失败"
fi
tar -zxvf openresty-${version}.tar.gz
rm -f openresty-${version}.tar.gz
rm -f openresty-${version}.tar.gz.sha256
mv openresty-${version} src
cd src
# tls library
wget --retry-connrefused --retry-on-host-error --retry-on-http-error=429,500,502,503,504 -t 10 -T 120 -O openssl-3.5.0.7z ${download_url}/tls/openssl-3.5.0.7z
wget --retry-connrefused --retry-on-host-error --retry-on-http-error=429,500,502,503,504 -t 10 -T 120 -O openssl-3.5.0.7z.sha256 ${download_url}/tls/openssl-3.5.0.7z.sha256
if ! sha256sum --status -c openssl-3.5.0.7z.sha256; then
rm -rf ${nginx_path}
error "openssl 校验失败"
fi
7z x openssl-3.5.0.7z
rm -f openssl-3.5.0.7z
rm -f openssl-3.5.0.7z.sha256
mv openssl-3.5.0 openssl
chmod -R 700 openssl
# 加载 tls 模块ktls 需要
modprobe tls
# TODO OpenSSL 3.5.0 已经打过补丁,下次更新不要忘记在这里打补丁哦
# pcre2
wget --retry-connrefused --retry-on-host-error --retry-on-http-error=429,500,502,503,504 -t 10 -T 120 -O pcre2-10.45.7z ${download_url}/nginx/pcre/pcre2-10.45.7z
wget --retry-connrefused --retry-on-host-error --retry-on-http-error=429,500,502,503,504 -t 10 -T 120 -O pcre2-10.45.7z.sha256 ${download_url}/nginx/pcre/pcre2-10.45.7z.sha256
if ! sha256sum --status -c pcre2-10.45.7z.sha256; then
rm -rf ${nginx_path}
error "pcre 校验失败"
fi
7z x pcre2-10.45.7z
rm -f pcre2-10.45.7z
rm -f pcre2-10.45.7z.sha256
mv pcre2-10.45 pcre2
chmod -R 700 pcre2
# ngx_cache_purge
wget --retry-connrefused --retry-on-host-error --retry-on-http-error=429,500,502,503,504 -t 10 -T 120 -O ngx_cache_purge-2.3.tar.gz ${download_url}/nginx/modules/ngx_cache_purge-2.3.tar.gz
wget --retry-connrefused --retry-on-host-error --retry-on-http-error=429,500,502,503,504 -t 10 -T 120 -O ngx_cache_purge-2.3.tar.gz.sha256 ${download_url}/nginx/modules/ngx_cache_purge-2.3.tar.gz.sha256
if ! sha256sum --status -c ngx_cache_purge-2.3.tar.gz.sha256; then
rm -rf ${nginx_path}
error "ngx_cache_purge 校验失败"
fi
tar -zxvf ngx_cache_purge-2.3.tar.gz
rm -f ngx_cache_purge-2.3.tar.gz
rm -f ngx_cache_purge-2.3.tar.gz.sha256
mv ngx_cache_purge-2.3 ngx_cache_purge
# nginx-sticky-module
wget --retry-connrefused --retry-on-host-error --retry-on-http-error=429,500,502,503,504 -t 10 -T 120 -O nginx-sticky-module.zip ${download_url}/nginx/modules/nginx-sticky-module.zip
wget --retry-connrefused --retry-on-host-error --retry-on-http-error=429,500,502,503,504 -t 10 -T 120 -O nginx-sticky-module.zip.sha256 ${download_url}/nginx/modules/nginx-sticky-module.zip.sha256
if ! sha256sum --status -c nginx-sticky-module.zip.sha256; then
rm -rf ${nginx_path}
error "nginx-sticky-module 校验失败"
fi
unzip -o nginx-sticky-module.zip
rm -f nginx-sticky-module.zip
rm -f nginx-sticky-module.zip.sha256
# nginx-dav-ext-module
wget --retry-connrefused --retry-on-host-error --retry-on-http-error=429,500,502,503,504 -t 10 -T 120 -O nginx-dav-ext-module-3.0.0.tar.gz ${download_url}/nginx/modules/nginx-dav-ext-module-3.0.0.tar.gz
wget --retry-connrefused --retry-on-host-error --retry-on-http-error=429,500,502,503,504 -t 10 -T 120 -O nginx-dav-ext-module-3.0.0.tar.gz.sha256 ${download_url}/nginx/modules/nginx-dav-ext-module-3.0.0.tar.gz.sha256
if ! sha256sum --status -c nginx-dav-ext-module-3.0.0.tar.gz.sha256; then
rm -rf ${nginx_path}
error "nginx-dav-ext-module 校验失败"
fi
tar -xvf nginx-dav-ext-module-3.0.0.tar.gz
rm -f nginx-dav-ext-module-3.0.0.tar.gz
rm -f nginx-dav-ext-module-3.0.0.tar.gz.sha256
mv nginx-dav-ext-module-3.0.0 nginx-dav-ext-module
# ngx_http_security_headers_module
wget --retry-connrefused --retry-on-host-error --retry-on-http-error=429,500,502,503,504 -t 10 -T 120 -O ngx_http_security_headers_module.zip ${download_url}/nginx/modules/ngx_http_security_headers_module.zip
wget --retry-connrefused --retry-on-host-error --retry-on-http-error=429,500,502,503,504 -t 10 -T 120 -O ngx_http_security_headers_module.zip.sha256 ${download_url}/nginx/modules/ngx_http_security_headers_module.zip.sha256
if ! sha256sum --status -c ngx_http_security_headers_module.zip.sha256; then
rm -rf ${nginx_path}
error "ngx_http_security_headers_module 校验失败"
fi
unzip -o ngx_http_security_headers_module.zip
rm -f ngx_http_security_headers_module.zip
rm -f ngx_http_security_headers_module.zip.sha256
# ngx_http_trim_filter_module
wget --retry-connrefused --retry-on-host-error --retry-on-http-error=429,500,502,503,504 -t 10 -T 120 -O ngx_http_trim_filter_module.zip ${download_url}/nginx/modules/ngx_http_trim_filter_module.zip
wget --retry-connrefused --retry-on-host-error --retry-on-http-error=429,500,502,503,504 -t 10 -T 120 -O ngx_http_trim_filter_module.zip.sha256 ${download_url}/nginx/modules/ngx_http_trim_filter_module.zip.sha256
if ! sha256sum --status -c ngx_http_trim_filter_module.zip.sha256; then
rm -rf ${nginx_path}
error "ngx_http_trim_filter_module 校验失败"
fi
unzip -o ngx_http_trim_filter_module.zip
rm -f ngx_http_trim_filter_module.zip
rm -f ngx_http_trim_filter_module.zip.sha256
# ngx_http_zstd_module
wget --retry-connrefused --retry-on-host-error --retry-on-http-error=429,500,502,503,504 -t 10 -T 120 -O ngx_http_zstd_module.zip ${download_url}/nginx/modules/ngx_http_zstd_module.zip
wget --retry-connrefused --retry-on-host-error --retry-on-http-error=429,500,502,503,504 -t 10 -T 120 -O ngx_http_zstd_module.zip.sha256 ${download_url}/nginx/modules/ngx_http_zstd_module.zip.sha256
if ! sha256sum --status -c ngx_http_zstd_module.zip.sha256; then
rm -rf ${nginx_path}
error "ngx_http_zstd_module 校验失败"
fi
unzip -o ngx_http_zstd_module.zip
rm -f ngx_http_zstd_module.zip
rm -f ngx_http_zstd_module.zip.sha256
# ngx_brotli
wget --retry-connrefused --retry-on-host-error --retry-on-http-error=429,500,502,503,504 -t 10 -T 120 -O ngx_brotli-a71f931.zip ${download_url}/nginx/modules/ngx_brotli-a71f931.zip
wget --retry-connrefused --retry-on-host-error --retry-on-http-error=429,500,502,503,504 -t 10 -T 120 -O ngx_brotli-a71f931.zip.sha256 ${download_url}/nginx/modules/ngx_brotli-a71f931.zip.sha256
if ! sha256sum --status -c ngx_brotli-a71f931.zip.sha256; then
rm -rf ${nginx_path}
error "ngx_brotli 校验失败"
fi
unzip -o ngx_brotli-a71f931.zip
mv ngx_brotli-a71f931 ngx_brotli
rm -f ngx_brotli-a71f931.zip
rm -f ngx_brotli-a71f931.zip.sha256
cd ngx_brotli/deps/brotli
mkdir out && cd out
cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DCMAKE_C_FLAGS="-Ofast -march=native -mtune=native -funroll-loops -ffunction-sections -fdata-sections -Wl,--gc-sections" -DCMAKE_CXX_FLAGS="-Ofast -march=native -mtune=native -funroll-loops -ffunction-sections -fdata-sections -Wl,--gc-sections" -DCMAKE_INSTALL_PREFIX=./installed ..
cmake --build . --config Release --target brotlienc
if [ "$?" != "0" ]; then
rm -rf ${nginx_path}
error "ngx_brotli 编译失败"
fi
cd ${nginx_path}/src
./configure --user=www --group=www \
--prefix=${nginx_path} --with-luajit \
--add-module=${nginx_path}/src/ngx_cache_purge \
--add-module=${nginx_path}/src/nginx-sticky-module \
--with-openssl=${nginx_path}/src/openssl \
--with-openssl-opt=enable-ktls \
--with-pcre=${nginx_path}/src/pcre2 --with-pcre-jit \
--with-ld-opt="-Wl,-s -Wl,-Bsymbolic -Wl,--gc-sections" \
--with-cc-opt="-DNGX_LUA_ABORT_AT_PANIC -march=native -mtune=native -Ofast -funroll-loops -ffunction-sections -fdata-sections -Wl,--gc-sections" \
--with-luajit-xcflags="-DLUAJIT_NUMMODE=2 -DLUAJIT_ENABLE_LUA52COMPAT" \
--with-file-aio \
--with-threads \
--with-compat \
--with-http_v2_module --with-http_v3_module \
--with-http_slice_module \
--with-stream --with-stream_ssl_module --with-stream_realip_module --with-stream_ssl_preread_module \
--with-http_stub_status_module \
--with-http_ssl_module \
--with-http_image_filter_module \
--with-http_gzip_static_module --with-http_gunzip_module \
--with-http_sub_module \
--with-http_flv_module \
--with-http_addition_module \
--with-http_realip_module \
--with-http_mp4_module \
--with-http_auth_request_module \
--with-http_secure_link_module \
--with-http_random_index_module \
--with-http_dav_module \
--add-module=${nginx_path}/src/nginx-dav-ext-module \
--add-module=${nginx_path}/src/ngx_http_security_headers_module \
--add-module=${nginx_path}/src/ngx_http_trim_filter_module \
--add-module=${nginx_path}/src/ngx_brotli \
--add-module=${nginx_path}/src/ngx_http_zstd_module
make "-j${j}"
if [ "$?" != "0" ]; then
rm -rf ${nginx_path}
error "编译失败"
fi
make install
if [ ! -f "${nginx_path}/nginx/sbin/nginx" ]; then
rm -rf ${nginx_path}
error "安装失败"
fi
cd ${nginx_path}
# 设置软链接
ln -sf ${nginx_path}/nginx/html ${nginx_path}/html
ln -sf ${nginx_path}/nginx/conf ${nginx_path}/conf
ln -sf ${nginx_path}/nginx/logs ${nginx_path}/logs
ln -sf ${nginx_path}/nginx/sbin ${nginx_path}/sbin
ln -sf ${nginx_path}/nginx/sbin/nginx /usr/bin/nginx
# 创建配置目录
mkdir -p ${setup_path}/wwwroot/default
mkdir -p ${setup_path}/wwwlogs
mkdir -p ${setup_path}/server/vhost
mkdir -p ${setup_path}/server/vhost
mkdir -p ${setup_path}/server/vhost/rewrite
mkdir -p ${setup_path}/server/vhost/cert
mkdir -p ${setup_path}/server/vhost/acme
# 写入主配置文件
cat >${nginx_path}/conf/nginx.conf <<EOF
user www www;
worker_processes auto;
worker_cpu_affinity auto;
worker_rlimit_nofile 65535;
pcre_jit on;
quic_bpf on;
error_log ${setup_path}/wwwlogs/nginx-error.log crit;
pid ${setup_path}/server/nginx/nginx.pid;
stream {
log_format tcp_format '\$time_local|\$remote_addr|\$protocol|\$status|\$bytes_sent|\$bytes_received|\$session_time|\$upstream_addr|\$upstream_bytes_sent|\$upstream_bytes_received|\$upstream_connect_time';
access_log ${setup_path}/wwwlogs/tcp-access.log tcp_format;
error_log ${setup_path}/wwwlogs/tcp-error.log;
}
events {
use epoll;
worker_connections 65535;
multi_accept on;
}
http {
include mime.types;
include proxy.conf;
include default.conf;
default_type application/octet-stream;
keepalive_timeout 60;
server_names_hash_bucket_size 512;
client_header_buffer_size 32k;
large_client_header_buffers 4 32k;
client_max_body_size 200m;
client_body_buffer_size 10M;
client_body_in_file_only off;
variables_hash_max_size 2048;
variables_hash_bucket_size 128;
http2 on;
http3 on;
quic_gso on;
aio threads;
aio_write on;
directio 512k;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
fastcgi_buffer_size 64k;
fastcgi_buffers 8 64k;
fastcgi_busy_buffers_size 256k;
fastcgi_temp_file_write_size 256k;
fastcgi_intercept_errors on;
zstd on;
zstd_min_length 1k;
zstd_comp_level 10;
zstd_types *;
zstd_static on;
brotli on;
brotli_min_length 1k;
brotli_comp_level 6;
brotli_window 1m;
brotli_types *;
brotli_static on;
gzip on;
gzip_min_length 1k;
gzip_http_version 1.1;
gzip_comp_level 6;
gzip_types *;
gzip_vary on;
gzip_proxied any;
limit_conn_zone \$binary_remote_addr zone=perip:10m;
limit_conn_zone \$server_name zone=perserver:10m;
server_tokens off;
access_log off;
# status page
server {
listen 80;
server_name 127.0.0.1;
allow 127.0.0.1;
location /nginx_status {
stub_status on;
access_log off;
}
location ~ ^/phpfpm_status/(?<version>\d+)$ {
fastcgi_pass unix:/tmp/php-cgi-\$version.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME \$fastcgi_script_name;
}
}
include ${setup_path}/server/vhost/*.conf;
}
EOF
# 写入pathinfo配置文件
cat >${nginx_path}/conf/pathinfo.conf <<EOF
set \$real_script_name \$fastcgi_script_name;
if (\$fastcgi_script_name ~ "^(.+?\.php)(/.+)$") {
set \$real_script_name \$1;
set \$path_info \$2;
}
fastcgi_param SCRIPT_FILENAME \$document_root\$real_script_name;
fastcgi_param SCRIPT_NAME \$real_script_name;
fastcgi_param PATH_INFO \$path_info;
EOF
# 写入默认站点页
cat >${nginx_path}/html/index.html <<EOF
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>未找到网站 - 耗子面板</title>
<style>
body {
background-color: #f9f9f9;
margin: 0;
padding: 0;
}
.container {
max-width: 800px;
margin: 2em auto;
background-color: #ffffff;
padding: 20px;
border-radius: 12px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
h1 {
font-size: 2.5em;
margin-top: 0;
margin-bottom: 20px;
text-align: center;
color: #333;
border-bottom: 2px solid #ddd;
padding-bottom: 0.5em;
}
p {
color: #555;
line-height: 1.8;
text-align: center;
}
a {
text-decoration: none;
color: #007bff;
}
@media screen and (max-width: 768px) {
.container {
padding: 15px;
margin: 2em 15px;
}
h1 {
font-size: 1.8em;
}
}
</style>
</head>
<body>
<div class="container">
<h1>耗子面板</h1>
<p>这是耗子面板的默认页面!</p>
<p>您看到此页面是因为服务器上未能找到与该域名对应的网站。</p>
<p>由<a target="_blank" href="https://panel.haozi.net">耗子面板</a>强力驱动</p>
</div>
</body>
</html>
EOF
# 写入站点停止页
cat >${nginx_path}/html/stop.html <<EOF
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>网站已停止 - 耗子面板</title>
<style>
body {
background-color: #f9f9f9;
margin: 0;
padding: 0;
}
.container {
max-width: 800px;
margin: 2em auto;
background-color: #ffffff;
padding: 20px;
border-radius: 12px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
h1 {
font-size: 2.5em;
margin-top: 0;
margin-bottom: 20px;
text-align: center;
color: #333;
border-bottom: 2px solid #ddd;
padding-bottom: 0.5em;
}
p {
color: #555;
line-height: 1.8;
text-align: center;
}
a {
text-decoration: none;
color: #007bff;
}
@media screen and (max-width: 768px) {
.container {
padding: 15px;
margin: 2em 15px;
}
h1 {
font-size: 1.8em;
}
}
</style>
</head>
<body>
<div class="container">
<h1>耗子面板</h1>
<p>该网站已被管理员停止访问!</p>
<p>您看到此页面是因为该网站已被服务器管理员停止对外访问。</p>
<p>由<a target="_blank" href="https://panel.haozi.net">耗子面板</a>强力驱动</p>
</div>
</body>
</html>
EOF
# 写入无php配置文件
echo "" >${nginx_path}/conf/enable-php-0.conf
# 自动为所有PHP版本创建配置文件
if [ -d "${setup_path}/server/php" ]; then
cd ${setup_path}/server/php
phpList=$(ls -l | grep ^d | awk '{print $NF}')
for phpVersion in ${phpList}; do
if [ -d "${setup_path}/server/php/${phpVersion}" ]; then
# 写入PHP配置文件
cat >${nginx_path}/conf/enable-php-${phpVersion}.conf <<EOF
location ~ \.php$ {
try_files \$uri =404;
fastcgi_pass unix:/tmp/php-cgi-${phpVersion}.sock;
fastcgi_index index.php;
include fastcgi.conf;
include pathinfo.conf;
}
EOF
fi
done
fi
# 写入代理默认配置文件
cat >${nginx_path}/conf/proxy.conf <<EOF
proxy_temp_path ${nginx_path}/proxy_temp_dir;
proxy_cache_path ${nginx_path}/proxy_cache_dir levels=1:2 keys_zone=cache_one:20m inactive=1d max_size=5g;
proxy_connect_timeout 10;
proxy_read_timeout 60;
proxy_send_timeout 60;
proxy_buffer_size 32k;
proxy_buffers 4 64k;
proxy_busy_buffers_size 128k;
proxy_temp_file_write_size 128k;
proxy_next_upstream error timeout invalid_header http_500 http_503 http_404;
proxy_cache cache_one;
EOF
# 写入默认站点配置文件
cat >${nginx_path}/conf/default.conf <<EOF
server
{
listen 80 default_server reuseport;
listen [::]:80 default_server reuseport;
listen 443 ssl default_server reuseport;
listen [::]:443 ssl default_server reuseport;
server_name _;
index index.html;
root ${nginx_path}/html;
ssl_reject_handshake on;
}
EOF
# 处理文件权限
chmod -R 755 ${nginx_path}
chmod -R 644 ${setup_path}/server/vhost
# 写入服务文件
cat >/etc/systemd/system/nginx.service <<EOF
[Unit]
Description=The OpenResty Application Platform
After=syslog.target network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target
[Service]
Type=forking
PIDFile=${nginx_path}/nginx.pid
ExecStartPre=${nginx_path}/sbin/nginx -t -c ${nginx_path}/conf/nginx.conf
ExecStart=${nginx_path}/sbin/nginx -c ${nginx_path}/conf/nginx.conf
ExecReload=${nginx_path}/sbin/nginx -s reload
ExecStop=${nginx_path}/sbin/nginx -s quit
LimitNOFILE=500000
Restart=on-failure
RestartSec=5s
[Install]
WantedBy=multi-user.target
EOF
chmod 644 /etc/systemd/system/nginx.service
systemctl daemon-reload
systemctl enable --now nginx
if [ "$?" != "0" ]; then
error "启动失败"
fi
panel-cli app write nginx ${channel} ${version}
echo -e $HR
echo "安装完成"
echo -e $HR