- 购买云主机
- 购买对应的域名并完成备案注册
- 本站使用宝塔Linux发行版,除nginx之外使用宝塔Linux dnf 安装软件
配置编译参数选项
declare -x CC="gcc"
declare -x CFLAGS="-O2 -Wall -fstack-protector-all -mindirect-branch=thunk -mfunction-return=thunk"
使用
./configure --user=httpd --group=httpd --with-http_ssl_module
配置nginx
使用
make install 安装nginx到目标文件夹
- 为nginx服务添加基于nft的rate控制,下面的例子为一个基础防火墙配置
/etc/nft_protection.nft
table inet filter {
set synflood {
type ipv4_addr
size 65535
flags dynamic
}
set limitrate {
type ipv4_addr
size 65535
flags dynamic
}
chain input {
type filter hook input priority filter; policy accept;
tcp dport 80 ct state new update @synflood { ip saddr limit rate over 20/second burst 5 packets } counter reject with tcp reset
tcp dport 80 ct state new update @limitrate { ip saddr ct count over 100 } counter reject with tcp reset
tcp dport 443 ct state new update @synflood { ip saddr limit rate over 20/second burst 5 packets } counter reject with tcp reset
tcp dport 443 ct state new update @limitrate { ip saddr ct count over 100 } counter reject with tcp reset
}
}
- 修改默认的 nginx systemd service并配置letsencrypt的参数,删除nginx运行时使用root账号运行,由于nginx直接提供对外的https/https访问,所以在systemd.service中根据使用需要配置沙箱
/usr/lib/systemd/system/nginx.service
[Unit]
Description=The NGINX HTTP and reverse proxy server
After=network.target remote-fs.target nss-lookup.target
[Service]
Environment="LD_PRELOAD=/usr/lib64/libclang_rt.scudo_standalone.so"#根据需要配置,本站使用LLVM的libscudo替换glibc的内存分配器
Type=forking
ExecStartPre=+/usr/sbin/nft flush table inet filter # nft 需要root权限配置netfilter
ExecStartPre=+/usr/sbin/nft -f /etc/nft_protection.nft # nft 需要root权限配置netfilter
ExecStartPre=/usr/local/bin/nginx -t -e /var/log/nginx/logs/error.log -c /usr/local/nginx/conf/nginx.conf
ExecStart=/usr/local/bin/nginx -e /var/log/nginx/logs/error.log -c /usr/local/nginx/conf/nginx.conf
ExecReload=/usr/local/bin/nginx -s reload -e /var/log/nginx/logs/error.log -c /usr/local/nginx/conf/nginx.conf
ExecStartPost=/bin/chmod 664 /usr/local/nginx/logs/nginx.pid
PrivateTmp=true
User=httpd
Group=httpd
AmbientCapabilities=CAP_NET_BIND_SERVICE
ProtectSystem=full
ProtectHome=true
ProtectKernelTunables=true
ProtectKernelModules=true
LockPersonality=true
SystemCallFilter=~@chown @module @clock @privileged @keyring @reboot @swap @sync @debug @pkey @cpu-emulation @aio @mount
SystemCallErrorNumber=EPERM
InaccessiblePaths=/root /home /boot
BindPaths=/usr/local/nginx/etc:/etc
ReadOnlyPaths=/etc/letsencrypt
ReadWritePaths=/var/log/nginx/logs /usr/local/nginx/logs/ /usr/local/nginx/client_body_temp/ /usr/local/nginx/fastcgi_temp/ /usr/local/nginx/scgi_temp/ /usr/local/nginx/uwsgi_temp/ /usr/local/nginx/proxy_temp/
SystemCallArchitectures=native
NoNewPrivileges=true
MemoryDenyWriteExecute=true
PrivateDevices=true
[Install]
WantedBy=multi-user.target
- 配置nginx的配置文件/usr/local/nginx/etc/conf/nginx.conf, certbot会更新此配置文件添加对应的证书信息
/usr/local/nginx/etc/conf/nginx.conf
worker_processes 1;
error_log /var/log/nginx/logs/error.log;
error_log /var/log/nginx/logs/error.log notice;
error_log /var/log/nginx/logs/error.log info;
events {
worker_connections 1024;
}
http {
include mime.types;
include fastcgi.conf;
default_type application/octet-stream;
error_log /var/log/nginx/logs/error.log;
server_tokens off;
sendfile on;
fastcgi_buffering off;
keepalive_timeout 65;
upstream php {
server unix:/var/run/php-fpm/www.sock;
}
server {
server_name 对应的域名;
client_max_body_size 5m;
root /var/lib/www/html;
index index.php;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
try_files $uri =404;
include fastcgi.conf;
fastcgi_pass php;
}
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
expires 1d;
log_not_found on;
try_files $uri $uri/ /index.php?$args;
}
location ~* \.webm$ {
gzip off;
limit_rate 5m;
tcp_nopush on;
tcp_nodelay on;
sendfile on;
max_ranges 5;
}
# Deny access to hidden files (like .htaccess or .git)
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
# Security: Deny direct execution of PHP files in the uploads folder
location ~* /(?:uploads|files)/.*\.php$ {
deny all;
}
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
listen 443 ssl;
}
}
- 使用发行版安装php-fpm, mariadb和certbots
- 配置php-fpm服务和nginx配套工作
/usr/lib/systemd/system/php-fpm.service
[Unit]
Description=The PHP FastCGI Process Manager
After=syslog.target network.target
[Service]
Type=notify
ExecStart=/usr/sbin/php-fpm --nodaemonize
ExecReload=/bin/kill -USR2 $MAINPID
PrivateTmp=true
RuntimeDirectory=php-fpm
RuntimeDirectoryMode=0755
ProtectSystem=full
ProtectHome=true
ProtectKernelTunables=true
ProtectKernelModules=true
LockPersonality=true
SystemCallFilter=~@chown @module @clock @privileged @keyring @reboot @swap @sync @debug @pkey @cpu-emulation @aio @mount
SystemCallErrorNumber=EPERM
ReadWritePaths=/var/log/php-fpm
InaccessiblePaths=/root /home /boot
BindPaths=/var/lib/php/etc:/etc
SystemCallArchitectures=native
NoNewPrivileges=true
MemoryDenyWriteExecute=true
PrivateDevices=true
User=httpd
Group=httpd
RestrictAddressFamilies=AF_UNIX AF_INET
TasksMax=256
AmbientCapabilities=CAP_NET_ADMIN
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE
[Install]
WantedBy=multi-user.target
/var/lib/php/etc/php.ini
expose_php = Off
- 配置mariadb只使用unix socket通信
/usr/lib/systemd/system/mariadb.service
[Unit]
Description=MariaDB 10.11 database server
Documentation=man:mariadbd(8)
Documentation=https://mariadb.com/kb/en/library/systemd/
After=network.target
[Install]
WantedBy=multi-user.target
Alias=mysql.service
Alias=mysqld.service
[Service]
Environment="LD_PRELOAD=/usr/lib64/libclang_rt.scudo_standalone.so"
Type=notify
User=mysql
Group=mysql
ExecStartPre=/usr/libexec/mariadb-check-socket
# '%n' expands to 'Full unit name'; man systemd.unit
ExecStartPre=/usr/libexec/mariadb-prepare-db-dir %n
# MYSQLD_OPTS here is for users to set in /etc/systemd/system/mariadb@.service.d/MY_SPECIAL.conf
# Note: we set --basedir to prevent probes that might trigger SELinux alarms,
# per bug #547485
ExecStart=/usr/libexec/mariadbd --basedir=/usr $MYSQLD_OPTS $_WSREP_NEW_CLUSTER
ExecStartPost=/usr/libexec/mariadb-check-upgrade
# Setting this to true can break replication and the Type=notify settings
# See also bind-address MariaDB option.
PrivateNetwork=false
ProtectSystem=full
ProtectHome=true
ProtectKernelModules=true
LockPersonality=true
ReadWritePaths=/var/lib/mysql /var/log/mariadb /run/mariadb
SystemCallArchitectures=native
NoNewPrivileges=true
MemoryDenyWriteExecute=true
PrivateDevices=true
RestrictAddressFamilies=AF_UNIX
KillSignal=SIGTERM
# Don't want to see an automated SIGKILL ever
SendSIGKILL=no
# Restart crashed server only, on-failure would also restart, for example, when
# my.cnf contains unknown option
Restart=on-abort
RestartSec=5s
UMask=007
# Give a reasonable amount of time for the server to start up/shut down
TimeoutSec=300
# Place temp files in a secure directory, not /tmp
PrivateTmp=true
配置mariadb服务端配置
/etc/my.cnf.d/mariadb-server.cnf
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
log-error=/var/log/mariadb/mariadb.log
pid-file=/run/mariadb/mariadb.pid
[galera]
skip-networking
- 安装完成certbot之后配置自动更新/usr/lib/systemd/system/certbot-renew.service
[Unit]
Description=This service automatically renews any certbot certificates found
[Service]
EnvironmentFile=/etc/sysconfig/certbot
Type=oneshot
ExecStart=+/usr/bin/certbot renew --noninteractive --no-random-sleep-on-renew $PRE_HOOK $POST_HOOK $RENEW_HOOK $DEPLOY_HOOK $CERTBOT_ARGS # certbot需要root权限,使用systemctl操作nginx,本站未自定义hook,使用root运行certbot
User=certbot
Group=httpd
PrivateTmp=true
ProtectSystem=full
ProtectHome=true
AmbientCapabilities=CAP_NET_BIND_SERVICE
ProtectKernelTunables=true
ProtectKernelModules=true
LockPersonality=true
SystemCallFilter=~@chown @module @clock @privileged @keyring @reboot @swap @sync @debug @pkey @cpu-emulation @aio @mount
SystemCallErrorNumber=EPERM
BindPaths=/usr/local/nginx/etc:/etc
ReadWritePaths=/var/lib/letsencrypt /var/log/letsencrypt /etc/letsencrypt /usr/local/nginx/logs/ /var/log/nginx/ /usr/local/nginx/conf/
InaccessiblePaths=/root /home /boot /dev
SystemCallArchitectures=native
NoNewPrivileges=true
MemoryDenyWriteExecute=true
PrivateDevices=true
- 修改运行时需要的文件从/etc/复制到/usr/local/nginx/etc/
sudo cp /etc/group /usr/local/nginx/etc/
sudo cp /etc/passwd /usr/local/nginx/etc/
删除/usr/local/nginx/etc/group和/usr/local/nginx/etc/passwd文件内的账号只保留httpd和必要的账号
复制所有nginx相关的配置到 /usr/local/nginx/etc/
sudo cp -rf /etc/crypto-policies /usr/local/nginx/etc/
sudo cp -rf /etc/letsencrypt /usr/local/nginx/etc/
sudo cp -rf /etc/nginx /usr/local/nginx/etc/
sudo cp -rf /etc/pki /usr/local/nginx/etc/
sudo cp -rf /etc/ssl /usr/local/nginx/etc/
- 修改运行时需要的文件从/etc/复制到/var/lib/php/etc/
sudo cp /etc/passwd /var/lib/php/etc/
删除 /var/lib/php/etc/passwd 内的账号 只保留需要的httpd
复制所有php相关配置到 /var/lib/php/etc/
sudo cp -rf /etc/php.d /var/lib/php/etc/
sudo cp /etc/php.ini /var/lib/php/etc/
sudo cp -rf /etc/wordpress /var/lib/php/etc/
sudo cp -rf /etc/php-fpm.d /var/lib/php/etc/
- 使用systemctl 重启nginx, php-fpm
- 使用systemctl 测试 certbot-renew
发表回复