Files
download/apache/install.sh
耗子 758e1c8799
All checks were successful
Generate Checksums / checksums (push) Successful in 46s
feat: 清理提交
2026-01-31 07:03:45 +08:00

318 lines
14 KiB
Bash

#!/bin/bash
source <(curl -f -s --connect-timeout 10 --retry 3 https://dl.acepanel.net/public.sh)
if [ $? -ne 0 ]; then
echo "Download public.sh failed, please check the network or try again later."
exit 1
fi
channel=${1}
version=${2}
apache_path="${setup_path}/server/apache"
j=$(calculate_j)
# 安装依赖
if [ ${OS} == "rhel" ]; then
dnf makecache -y
dnf groupinstall "Development Tools" -y
dnf install cmake tar unzip pcre2-devel openssl-devel zlib-devel libxml2-devel expat-devel lua-devel libnghttp2-devel brotli-devel curl-devel jansson-devel libcurl-devel systemd-devel -y
elif [ ${OS} == "debian" ] || [ ${OS} == "ubuntu" ]; then
apt-get update
apt-get install build-essential cmake tar unzip libpcre2-dev libssl-dev zlib1g-dev libxml2-dev libexpat1-dev liblua5.4-dev libnghttp2-dev libbrotli-dev libcurl4-openssl-dev libjansson-dev libsystemd-dev -y
else
error "Unsupported operating system"
fi
if [ "$?" != "0" ]; then
error "Failed to install dependencies"
fi
# 准备目录
rm -rf ${apache_path}
mkdir -p ${apache_path}
cd ${apache_path}
# 下载源码
dl "${apache_path}" "/apache/httpd-${version}.tar.gz"
tar -zxvf httpd-${version}.tar.gz
rm -f httpd-${version}.tar.gz
mv httpd-${version} src
cd src
# 下载并解压 APR
dl "${apache_path}/src/srclib" "/apache/apr-1.7.6.tar.gz"
cd ${apache_path}/src/srclib
tar -zxvf apr-1.7.6.tar.gz
rm -f apr-1.7.6.tar.gz
mv apr-1.7.6 apr
# 下载并解压 APR-Util
dl "${apache_path}/src/srclib" "/apache/apr-util-1.6.3.tar.gz"
cd ${apache_path}/src/srclib
tar -zxvf apr-util-1.6.3.tar.gz
rm -f apr-util-1.6.3.tar.gz
mv apr-util-1.6.3 apr-util
cd ${apache_path}/src
# 配置编译
./configure --prefix=${apache_path} \
--enable-mods-shared=most \
--with-included-apr \
--enable-ssl \
--enable-http2 \
--enable-proxy \
--enable-brotli \
--enable-deflate \
--enable-rewrite \
--enable-remoteip \
--enable-lua \
--enable-dav \
--enable-dav-fs \
--enable-cache \
--enable-cache-disk \
--enable-socache-shmcb \
--enable-slotmem-shm \
--enable-watchdog \
--enable-md \
--enable-systemd
if [ "$?" != "0" ]; then
rm -rf ${apache_path}
error "Configure failed"
fi
make "-j${j}"
if [ "$?" != "0" ]; then
rm -rf ${apache_path}
error "Compilation failed"
fi
make install
if [ ! -f "${apache_path}/bin/httpd" ]; then
rm -rf ${apache_path}
error "Installation failed"
fi
cd ${apache_path}
# 设置软链接
ln -sf ${apache_path}/bin/httpd /usr/local/bin/httpd
ln -sf ${apache_path}/bin/apachectl /usr/local/bin/apachectl
# 创建站点目录
mkdir -p ${setup_path}/sites
chmod -R 755 ${setup_path}/sites
# 修改默认配置
sed -i "s|#ServerName www.example.com:80|ServerName 0.0.0.0:80|" ${apache_path}/conf/httpd.conf
sed -i "s|User daemon|User www|" ${apache_path}/conf/httpd.conf
sed -i "s|Group daemon|Group www|" ${apache_path}/conf/httpd.conf
sed -i "s|DirectoryIndex index.html|DirectoryIndex index.php index.html|" ${apache_path}/conf/httpd.conf
sed -i "s|AllowOverride none|AllowOverride All|" ${apache_path}/conf/httpd.conf
sed -i "s|AllowOverride None|AllowOverride All|" ${apache_path}/conf/httpd.conf
sed -i "s|Require all denied|Require all granted|" ${apache_path}/conf/httpd.conf
# 启用模块
sed -i "s|#LoadModule deflate_module|LoadModule deflate_module|" ${apache_path}/conf/httpd.conf
sed -i "s|#LoadModule brotli_module|LoadModule brotli_module|" ${apache_path}/conf/httpd.conf
sed -i "s|#LoadModule expires_module|LoadModule expires_module|" ${apache_path}/conf/httpd.conf
sed -i "s|#LoadModule rewrite_module|LoadModule rewrite_module|" ${apache_path}/conf/httpd.conf
sed -i "s|#LoadModule ssl_module|LoadModule ssl_module|" ${apache_path}/conf/httpd.conf
sed -i "s|#LoadModule socache_shmcb_module|LoadModule socache_shmcb_module|" ${apache_path}/conf/httpd.conf
sed -i "s|#LoadModule http2_module|LoadModule http2_module|" ${apache_path}/conf/httpd.conf
sed -i "s|#LoadModule proxy_module|LoadModule proxy_module|" ${apache_path}/conf/httpd.conf
sed -i "s|#LoadModule proxy_connect_module|LoadModule proxy_connect_module|" ${apache_path}/conf/httpd.conf
sed -i "s|#LoadModule proxy_http_module|LoadModule proxy_http_module|" ${apache_path}/conf/httpd.conf
sed -i "s|#LoadModule proxy_http2_module|LoadModule proxy_http2_module|" ${apache_path}/conf/httpd.conf
sed -i "s|#LoadModule proxy_fcgi_module|LoadModule proxy_fcgi_module|" ${apache_path}/conf/httpd.conf
sed -i "s|#LoadModule proxy_scgi_module|LoadModule proxy_scgi_module|" ${apache_path}/conf/httpd.conf
sed -i "s|#LoadModule proxy_uwsgi_module|LoadModule proxy_uwsgi_module|" ${apache_path}/conf/httpd.conf
sed -i "s|#LoadModule proxy_fdpass_module|LoadModule proxy_fdpass_module|" ${apache_path}/conf/httpd.conf
sed -i "s|#LoadModule proxy_wstunnel_module|LoadModule proxy_wstunnel_module|" ${apache_path}/conf/httpd.conf
sed -i "s|#LoadModule proxy_balancer_module|LoadModule proxy_balancer_module|" ${apache_path}/conf/httpd.conf
sed -i "s|#LoadModule proxy_hcheck_module|LoadModule proxy_hcheck_module|" ${apache_path}/conf/httpd.conf
sed -i "s|#LoadModule slotmem_shm_module|LoadModule slotmem_shm_module|" ${apache_path}/conf/httpd.conf
sed -i "s|#LoadModule remoteip_module|LoadModule remoteip_module|" ${apache_path}/conf/httpd.conf
sed -i "s|#LoadModule lua_module|LoadModule lua_module|" ${apache_path}/conf/httpd.conf
sed -i "s|#LoadModule dav_module|LoadModule dav_module|" ${apache_path}/conf/httpd.conf
sed -i "s|#LoadModule dav_fs_module|LoadModule dav_fs_module|" ${apache_path}/conf/httpd.conf
sed -i "s|#LoadModule dav_lock_module|LoadModule dav_lock_module|" ${apache_path}/conf/httpd.conf
sed -i "s|#LoadModule cache_module|LoadModule cache_module|" ${apache_path}/conf/httpd.conf
sed -i "s|#LoadModule cache_disk_module|LoadModule cache_disk_module|" ${apache_path}/conf/httpd.conf
sed -i "s|#LoadModule cache_socache_module|LoadModule cache_socache_module|" ${apache_path}/conf/httpd.conf
sed -i "s|#LoadModule lbmethod_byrequests_module|LoadModule lbmethod_byrequests_module|" ${apache_path}/conf/httpd.conf
sed -i "s|#LoadModule lbmethod_bytraffic_module|LoadModule lbmethod_bytraffic_module|" ${apache_path}/conf/httpd.conf
sed -i "s|#LoadModule lbmethod_bybusyness_module|LoadModule lbmethod_bybusyness_module|" ${apache_path}/conf/httpd.conf
sed -i "s|#LoadModule lbmethod_heartbeat_module|LoadModule lbmethod_heartbeat_module|" ${apache_path}/conf/httpd.conf
sed -i "s|#LoadModule watchdog_module|LoadModule watchdog_module|" ${apache_path}/conf/httpd.conf
sed -i "s|#LoadModule md_module|LoadModule md_module|" ${apache_path}/conf/httpd.conf
sed -i "s|#LoadModule systemd_module|LoadModule systemd_module|" ${apache_path}/conf/httpd.conf
# 安全增强
sed -i "s|^ServerTokens.*|ServerTokens Prod|" ${apache_path}/conf/extra/httpd-default.conf
sed -i "s|^ServerSignature.*|ServerSignature Off|" ${apache_path}/conf/extra/httpd-default.conf
echo "TraceEnable Off" >>${apache_path}/conf/extra/httpd-default.conf
# 启用额外配置
sed -i "s|#Include conf/extra/httpd-default.conf|Include conf/extra/httpd-default.conf|" ${apache_path}/conf/httpd.conf
sed -i "s|#Include conf/extra/httpd-mpm.conf|Include conf/extra/httpd-mpm.conf|" ${apache_path}/conf/httpd.conf
sed -i "s|#Include conf/extra/httpd-ssl.conf|Include conf/extra/httpd-ssl.conf|" ${apache_path}/conf/httpd.conf
# 生成自签名证书
openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \
-keyout ${apache_path}/conf/server.key \
-out ${apache_path}/conf/server.crt \
-subj "/C=US/ST=State/L=City/O=AcePanel/CN=localhost" \
-addext "basicConstraints=CA:FALSE" \
-addext "subjectAltName=DNS:localhost,IP:127.0.0.1"
# 修改 SSL 虚拟主机 ServerName
sed -i "s|ServerName www.example.com:443|ServerName localhost:443|" ${apache_path}/conf/extra/httpd-ssl.conf
# 追加自定义配置
cat >>${apache_path}/conf/httpd.conf <<CONF
<IfModule http2_module>
ProtocolsHonorOrder On
Protocols h2 h2c http/1.1
</IfModule>
<IfModule remoteip_module>
RemoteIPHeader X-Forwarded-For
RemoteIPInternalProxy 127.0.0.1
RemoteIPInternalProxy ::1
</IfModule>
<IfModule deflate_module>
SetOutputFilter DEFLATE
SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png|ico|webp|avif|bmp|tiff?)$ no-gzip dont-vary
SetEnvIfNoCase Request_URI \.(?:exe|t?gz|zip|bz2|sit|rar|7z|xz|lz|lzma|zst|br|cab|arj)$ no-gzip dont-vary
SetEnvIfNoCase Request_URI \.(?:iso|dmg|img|apk|ipa|deb|rpm|msi|pkg|appimage)$ no-gzip dont-vary
SetEnvIfNoCase Request_URI \.(?:pdf|mov|avi|mp[34]|rm|flv|swf|wmv|mkv|webm|m4[av]|ogg|ogv|opus)$ no-gzip dont-vary
SetEnvIfNoCase Request_URI \.(?:mp3|aac|flac|wav|wma|m4a|mid|midi)$ no-gzip dont-vary
SetEnvIfNoCase Request_URI \.(?:woff2?|ttf|otf|eot)$ no-gzip dont-vary
DeflateCompressionLevel 6
</IfModule>
<IfModule brotli_module>
SetOutputFilter BROTLI_COMPRESS
SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png|ico|webp|avif|bmp|tiff?)$ no-brotli
SetEnvIfNoCase Request_URI \.(?:exe|t?gz|zip|bz2|sit|rar|7z|xz|lz|lzma|zst|br|cab|arj)$ no-brotli
SetEnvIfNoCase Request_URI \.(?:iso|dmg|img|apk|ipa|deb|rpm|msi|pkg|appimage)$ no-brotli
SetEnvIfNoCase Request_URI \.(?:pdf|mov|avi|mp[34]|rm|flv|swf|wmv|mkv|webm|m4[av]|ogg|ogv|opus)$ no-brotli
SetEnvIfNoCase Request_URI \.(?:mp3|aac|flac|wav|wma|m4a|mid|midi)$ no-brotli
SetEnvIfNoCase Request_URI \.(?:woff2?|ttf|otf|eot)$ no-brotli
BrotliCompressionQuality 6
</IfModule>
<Location /server_status>
SetHandler server-status
Require ip 127.0.0.1 ::1
</Location>
<LocationMatch "^/phpfpm_status/(?<phpver>[0-9]+)$">
Require ip 127.0.0.1 ::1
SetHandler "proxy:unix:/tmp/php-cgi-%{env:MATCH_PHPVER}.sock|fcgi://localhost/"
ProxyFCGISetEnvIf "true" SCRIPT_NAME "/phpfpm_status/%{env:MATCH_PHPVER}"
ProxyFCGISetEnvIf "true" SCRIPT_FILENAME "/phpfpm_status/%{env:MATCH_PHPVER}"
</LocationMatch>
IncludeOptional conf/extra/acme.conf
IncludeOptional ${setup_path}/sites/*/config/*.conf
CONF
touch ${apache_path}/conf/extra/acme.conf
# 修改 SSL 配置
sed -i "s|^SSLProtocol.*|SSLProtocol -all +TLSv1.2 +TLSv1.3|" ${apache_path}/conf/extra/httpd-ssl.conf
sed -i "s|^SSLProxyProtocol.*|SSLProxyProtocol -all +TLSv1.2 +TLSv1.3|" ${apache_path}/conf/extra/httpd-ssl.conf
sed -i "s|^SSLCipherSuite.*|SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305|" ${apache_path}/conf/extra/httpd-ssl.conf
sed -i "s|^SSLProxyCipherSuite.*|SSLProxyCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305|" ${apache_path}/conf/extra/httpd-ssl.conf
sed -i "s|^SSLHonorCipherOrder.*|SSLHonorCipherOrder off|" ${apache_path}/conf/extra/httpd-ssl.conf
# 写入默认站点页
cat >${apache_path}/htdocs/index.html <<EOF
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AcePanel</title>
<style>body{background:#f2f3f5;margin:0;padding:20px;font-family:system-ui,sans-serif}.container{max-width:600px;margin:3em auto;background:#fff;padding:40px;border-radius:12px;box-shadow:0 4px 12px rgba(0,0,0,.05)}h1{font-size:3em;font-weight:600;margin:0 0 30px;color:#1a1a1a}p{color:#5a5a5a;line-height:1.6}a{text-decoration:none;color:#333;font-weight:600}</style>
</head>
<body>
<div class="container">
<h1>AcePanel</h1>
<p>This is the default page of AcePanel!</p>
<p>You see this page because the requested website was not found on this server.</p>
<p><em>Powered by <a target="_blank" href="https://acepanel.net">AcePanel</a></em></p>
</div>
</body>
</html>
EOF
# 写入站点停止页
cat >${apache_path}/htdocs/stop.html <<EOF
<!DOCTYPE html>
<html lang="zh-Hans">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AcePanel</title>
<style>body{background:#f2f3f5;margin:0;padding:20px;font-family:system-ui,sans-serif}.container{max-width:600px;margin:3em auto;background:#fff;padding:40px;border-radius:12px;box-shadow:0 4px 12px rgba(0,0,0,.05)}h1{font-size:3em;font-weight:600;margin:0 0 30px;color:#1a1a1a}p{color:#5a5a5a;line-height:1.6}a{text-decoration:none;color:#333;font-weight:600}</style>
</head>
<body>
<div class="container">
<h1>Website Suspended</h1>
<p>You see this page because the website has been stopped by the server administrator.</p>
<p><em>Powered by <a target="_blank" href="https://acepanel.net">AcePanel</a></em></p>
</div>
</body>
</html>
EOF
# 处理文件权限
chmod -R 755 ${apache_path}
chmod -R 600 ${apache_path}/conf
chown -R www:www ${apache_path}/logs
# 写入服务文件
cat >/etc/systemd/system/apache.service <<CONF
[Unit]
Description=The Apache HTTP Server
After=network.target remote-fs.target nss-lookup.target
Wants=network-online.target
[Service]
Type=notify
ExecStart=${apache_path}/bin/httpd -DFOREGROUND
ExecReload=${apache_path}/bin/httpd -k graceful
ExecStop=${apache_path}/bin/httpd -k graceful-stop
KillSignal=SIGWINCH
KillMode=mixed
PrivateTmp=false
LimitNOFILE=500000
Restart=on-failure
RestartSec=5s
[Install]
WantedBy=multi-user.target
CONF
chmod 644 /etc/systemd/system/apache.service
systemctl daemon-reload
systemctl enable --now apache
if [ "$?" != "0" ]; then
error "Failed to start"
fi
acepanel app write apache ${channel} ${version}
acepanel setting write webserver apache
echo -e $HR
echo "Installation successful"
echo -e $HR