本教程初版于 https://www.nodeseek.comhttp://127.0.0.1:5001/post-37224-1, 由于坛内限制编辑故开新帖, 着重更新了配置文件部分, 同时引入 Non root 启动 Nginx 进一步确保安全.
参考配置文件 /etc/nginx/nginx.conf
# 是否以守护进程方式运行 Nginx
# 试图直接以 Nginx 用户启动(Type=exec)而不是 root 用户以 forking 模式启动时, 配置为 off
daemon on;
# 配置 PID 文件位置
# 默认保存于 /var/run/nginx/nginx.pid
# pid /run/nginx/nginx.pid;
# 配置 worker 进程启动用户组及用户
# 仅以 Root 用户启动 master 进程时生效
user nginx nginx;
# Worker 线程数, 自动即可
worker_processes auto;
# CPU 亲和性配置, 自动即可
worker_cpu_affinity auto;
# worker 进程优先级
worker_priority -20;
# ulimit -n, 尽量提前解除 ulimit 限制(虽然大部分情况下不是高并发)
worker_rlimit_nofile 51200;
events
{
use epoll;
worker_connections 10240;
multi_accept on;
}
http
{
include mime.types;
# set_real_ip_from 0.0.0.0/0;
# real_ip_header CF-Connecting-IP;
default_type application/octet-stream;
charset utf-8;
http2 on;
log_format details '[$time_local][$status]|[Client] "$remote_addr" |[Host] "$host" |[Refer] "$http_referer" |[UA] "$http_user_agent" |[REQ] "$request" |[CONNECT] "$connection_requests" |[TIME] "$request_time" |[LENGTH] "$bytes_sent" |[UPSTREAM] "$upstream_addr" |[U_HEAD_TIME] "$upstream_header_time" |[U_CON_TIME] "$upstream_connect_time" |[U_RSP_TIME] "$upstream_response_time" |[U_STATUS] "$upstream_status" |[U_LENGTH] "$upstream_response_length"';
server_names_hash_bucket_size 512;
client_header_buffer_size 32k;
large_client_header_buffers 4 32k;
client_max_body_size 50m;
# Perf
access_log off;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
reset_timedout_connection on;
client_body_timeout 10;
send_timeout 2;
keepalive_timeout 60;
# SSL
# Check https://sysin.org/blog/tlsv1-3-support/ for more details
# 确信你的设备完全支持 TLSv1.3 可舍弃 TLSv1.2 支持, 进一步提高 HTTPS 性能
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
# SSL 协议, 舍弃对极老旧设备/应用等的兼容性, 进一步提高 HTTPS 性能
# Ref: https://developers.cloudflare.com/ssl/reference/cipher-suites/recommendations/
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384';
ssl_ecdh_curve X25519:P-256:P-384:P-224:P-521;
ssl_session_cache shared:SSL:30m;
ssl_session_timeout 1d;
# 此处原教程有误, 复用 session 应当设置此项为 off, 特此纠正
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
# DNS, 根据机器实际情况设置
resolver 1.1.1.1 1.0.0.1 8.8.8.8 8.8.4.4 valid=60s;
resolver_timeout 2s;
ssl_early_data on;
ssl_buffer_size 8k;
##
# Connection header for WebSocket reverse proxy
##
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
# fastcgi
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
fastcgi_buffer_size 64k;
fastcgi_buffers 4 64k;
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 256k;
fastcgi_intercept_errors on;
# compress
gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_http_version 1.1;
gzip_comp_level 6;
gzip_types
# text/html
text/css
text/javascript
text/xml
text/plain
text/x-component
application/javascript
application/x-javascript
application/json
application/xml
application/rss xml
application/atom xml
font/truetype
font/opentype
application/vnd.ms-fontobject
image/svg xml;
gzip_vary on;
gzip_proxied expired no-cache no-store private auth;
gzip_disable "MSIE [1-6]\.";
brotli on;
brotli_comp_level 6;
brotli_types
# text/html
text/css
text/javascript
text/xml
text/plain
text/x-component
application/javascript
application/x-javascript
application/json
application/xml
application/rss xml
application/atom xml
font/truetype
font/opentype
application/vnd.ms-fontobject
image/svg xml;
# Others
limit_conn_zone $binary_remote_addr zone=perip:10m;
limit_conn_zone $server_name zone=perserver:10m;
server_tokens off;
## QUIC
http3 on;
http3_hq on;
quic_retry on;
add_header Alt-Svc 'h3=":443"; ma=86400';
# Default server
server
{
listen 80 default_server;
listen 443 ssl default_server;
listen 443 quic reuseport;
server_name _;
ssl_reject_handshake on;
location /connection-test {
default_type application/json;
return 200 '{"code":0, "message":""}';
}
location / {
return 444;
}
access_log /www/logs/nxdomain.com.log details;
}
# Include other conf
include /etc/nginx/conf.d/*.conf;
}
Non-root NGINX
https://www.nodeseek.comhttp://127.0.0.1:5001/post-59478-3 提到的 Non-root 启动 Nginx, 以下为安装流程和配置. 未说明详情则参考原教程.
需要指出: 以非 root 用户运行 Nginx 会有很多莫名其妙的权限问题, 实在不建议新手! 此处仅供参考, 算是为后来者排坑了.
-
编译安装 Nginx
- 更新系统
- 安装编译依赖
- 前置准备
- 下载源代码
- configure
- make
- make install
-
配置 systemd 持久化
此步内容和原教程不一致, 应当注意
Ref: https://www.sherbers.de/running-nginx-without-root/
[Unit] Description=The NGINX HTTP and reverse proxy server After=syslog.target network-online.tarnaget remote-fs.target nss-lookup.target Wants=network-online.target [Service] # 此处不再以 forking 方式启动 Nginx Type=exec # 指定使用用户组 nginx 内的用户 nginx 启动 master 进程, # 启动 worker 进程亦然 User=nginx Group=nginx # ===== 限制运行各类文件的目录 ====== # 在 /run 中创建一个名为 nginx 的目录, 并根据 User= 选项调整权限, # 存放 PID 文件. 虽然以 exec 方式启动不需要 PID 文件但是没有选项可以关闭 RuntimeDirectory=nginx # 由于 NGINX 不再以 root 身份启动, 无法创建自己的日志和缓存目录, # 需要指定以下两项, 以确保目录 /var/log/nginx 和 /var/cache/nginx # 存在且当前用户可读写 LogsDirectory=nginx CacheDirectory=nginx ConfigurationDirectory=nginx # ===== 启动相关 ====== ExecStartPre=/bin/rm -rf /dev/shm/nginx ExecStartPre=/bin/mkdir /dev/shm/nginx ExecStartPre=/bin/chmod 711 /dev/shm/nginx ExecStartPre=/bin/mkdir /dev/shm/nginx/tcmalloc ExecStartPre=/bin/chmod 0777 /dev/shm/nginx/tcmalloc ExecStart=/usr/sbin/nginx ExecStop=/usr/sbin/nginx -s stop ExecStopPost=/bin/rm -rf /dev/shm/nginx ExecReload=/bin/kill -HUP $MAINPID Restart=on-failure RestartSec=10s # ==== Filesystem access ==== # 文件系统权限 # 禁止对操作系统/配置文件/本地挂载点进行任何修改 # 开启此选项之后, 可使用 ReadWritePaths= 来将某些 # 特定的目录改为读写模式 ProtectSystem=strict # 对该单元内的进程屏蔽 /home, /root, /run/user 目录(内容为空且不可访问) ProtectHome=true # 在进程的文件系统名字空间中挂载私有的 /tmp 与 /var/tmp 目录 # 注意: 进程终止后会立即清除 PrivateTmp=true # 该单元内的进程设置一个全新的 /dev 挂载点, 阻止访问实际的设备 # Nginx 一般无需访问物理设备 PrivateDevices=true # 仅允许以只读模式访问 /sys/fs/cgroup # 除了容器管理程序, 其他服务不应该对 cgroups 拥有控制权 ProtectControlGroups=true # 禁止显式加载/卸载内核模块 # Nginx 正常情况下完全无操作内核模块的需求 ProtectKernelModules=true # 保护内核变量 # Nginx 正常情况下完全无操作内核变量的需求 ProtectKernelTunables=true # 需要注意, 由于后面我们将访问日志保存到 /www/logs 下 # 需要指定 /www, 至少 /www/logs 可读写, 否则默认只读 ReadWritePaths=/www # ==== network ==== # 非 root 用户需要指定允许监听 Unix Socket, IPv4, IPv6 RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 # ==== misc ==== # 安全杂项, 可以但是不建议忽略 SystemCallArchitectures=native # 确保服务进程及其所有子进程永远无法通过execve()获得任何新权限 NoNewPrivileges=true # 阻止程序启用实时调度(可用于长时间独占 CPU 时间)造成 DoS 攻击 RestrictRealtime=true # 禁止尝试创建同时可写和可执行的内存映射 MemoryDenyWriteExecute=true # 阻止访问内核日志 ProtectKernelLogs=true LockPersonality=true # 防止读取/更改当前主机名或域名 ProtectHostname=true RemoveIPC=true # 阻止 set-user-ID(SUI) 或 set-group-ID (SGID), # 以阻止当前程序提升权限并允许获取其他用户身份 RestrictSUIDSGID=true # 阻止写入硬件时钟或系统时钟 ProtectClock=true # ==== capabilities ==== # 允许非 root 时访问低位(<1024)端口 AmbientCapabilities=CAP_NET_BIND_SERVICE [Install] WantedBy=multi-user.target -
配置文件调优
在前面提到的配置文件的基础上, 需要进行如下修改
daemon配置为 off(前面配置了 exec 方式使用 nginx:nginx 用户组:用户启动 Nginx)- 去除
pid一行的注释, 将 PID 文件保存于 /run/nginx 下 - 注释掉
user nginx nginx;一行(虽然不注释也没事, 启动的时候 warn 一下the "user" directive makes sense only if the master process runs with super-user privileges, ignored而已 - 注释掉
worker_priority -20;一行, nginx 没有权限调整进程优先级
-
扫尾
需要尤其指出权限问题:
- 自定义的 nginx 需要读取的目录/文件, 如
/www,/etc/nginx/certs等, 必须是 700 或更高权限, 原因不清楚, 需要看源码(想不清楚为什么要执行的权限). 证书目录建议 700.
# 无需我们自己创建缓存目录 # mkdir /var/cache/nginx # 创建 Nginx 配置文件目录. 你的网站的配置文件就得存这里 mkdir /etc/nginx/conf.d # 创建证书目录, 记得把证书存这里别乱存 mkdir /etc/nginx/certs # 网站文件目录 mkdir /www # 网站日志目录 mkdir /www/logs # 新建 nginx 用户(用户组同名), 赋予最低权限 useradd -M -s /sbin/nologin nginx # 修改网页目录权限 chown -R nginx:nginx /www chmod -R 700 /www # 修改证书目录权限 # 如果采用 acme.sh 获取并安装证书到 /etc/nginx/certs, # 需要尤其注意权限问题. chown -R nginx:nginx /etc/nginx/certs chmod -R 700 /etc/nginx/certs - 自定义的 nginx 需要读取的目录/文件, 如
-
运行!!!
2024/02/07, Rev2.1, Copyright ©2024 Hantong Chen

帮顶
绑定