Nginx限制IP访问,拉黑恶意爬虫IP配置

前言

网站被恶意爬虫狂刷,服务器CPU跑满?或者有人恶意攻击你的网站?可以用 Nginx 直接把这些 IP 拉黑,不让他们访问。本文讲一下怎么配置 IP 访问控制。

怎么找到恶意 IP

先看 Nginx 访问日志,找出访问最频繁的 IP:

# 统计访问次数最多的前 20 个 IP
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -20

如果某个 IP 访问量特别大,可能就是恶意爬虫或者攻击。

拉黑单个 IP

在 Nginx 配置里加:

server {
    listen       80;
    server_name  www.example.com;

    root  /var/www/html;

    # 拉黑某个 IP
    location / {
        deny 192.168.1.100;
        allow all;
    }
}

被拉黑的 IP 访问会返回 403 Forbidden。

拉黑 IP 段

拉黑整个 C 段

deny 192.168.1.0/24;

就是拉黑 192.168.1.1 到 192.168.1.255。

拉黑多个 IP

deny 192.168.1.100;
deny 192.168.1.101;
deny 192.168.1.102;

白名单模式(只允许某些 IP 访问)

如果想只允许特定 IP 访问(比如后台管理页面):

# 只允许内网 IP 访问 /admin
location /admin {
    allow 127.0.0.1;
    allow 192.168.1.0/24;
    deny all;
}

其他 IP 访问 /admin 都会返回 403。

用 include 单独管理黑名单

IP 多了不想写在主配置里,可以单独放一个文件:

第一步:创建黑名单文件

vi /etc/nginx/conf.d/blacklist.conf

内容:

deny 192.168.1.100;
deny 192.168.1.101;
deny 10.0.0.0/8;

第二步:在主配置里引入

server {
    listen       80;
    server_name  www.example.com;

    root  /var/www/html;

    # 引入黑名单
    include /etc/nginx/conf.d/blacklist.conf;

    location / {
        try_files $uri $uri/ =404;
    }
}

这样以后加黑名单只要改 blacklist.conf 文件,然后重载 Nginx 就行。

对某个目录单独限制

比如只对 /admin 目录限制:

location /admin {
    allow 127.0.0.1;
    allow 192.168.1.0/24;
    deny all;

    root /var/www/html;
    index index.php;
}

检查配置并重载

nginx -t
nginx -s reload

用防火墙拉黑(更彻底)

如果想在系统层面拉黑,用 firewall-cmd:

# 拉黑单个 IP
firewall-cmd --permanent --add-rich-rule="rule family='ipv4' source address='192.168.1.100' reject"

# 重新加载
firewall-cmd --reload

或者用 iptables:

iptables -I INPUT -s 192.168.1.100 -j DROP

常见坑

坑1:改了黑名单忘了 reload

加了黑名单,但 IP 还能访问。

原因: Nginx 没重载。

解决:

nginx -s reload

坑2:把自己 IP 拉黑了

测试的时候不小心把自己 IP 也拉黑了,自己也访问不了了。

解决: 先从服务器上用 curl 测试:

curl -I http://127.0.0.1

确认没问题再 reload。

坑3:CDN 后面拿不到真实 IP

用了 CDN 之后,日志里全是 CDN 的 IP,看不到用户真实 IP。

解决: 先配置 Nginx 获取真实 IP:

set_real_ip_from CDN的IP段;
real_ip_header X-Forwarded-For;

这样日志里才能看到用户真实 IP,才能正确拉黑。

总结

操作 命令/配置
拉黑单个 IP deny 192.168.1.100;
拉黑 IP 段 deny 192.168.1.0/24;
白名单模式 allow 127.0.0.1; deny all;
单独黑名单文件 include /etc/nginx/conf.d/blacklist.conf;
重载生效 nginx -s reload

提醒: 拉黑 IP 之前先确认是不是真的恶意,别误杀正常用户。

遇到问题加QQ23979811 协助处理


emer 发布于  2026-10-7 07:30 

Nginx反向代理配置,代理后端PHP服务

前言

LNMP 架构里,Nginx 收到 PHP 请求之后,要转发给 PHP-FPM 处理。这个转发的配置就是 fastcgi_pass。本文讲一下完整的 Nginx 代理 PHP 服务配置。

两种代理方式

Nginx 代理后端服务有两种方式:

  1. proxy_pass:代理 HTTP 服务(比如 Node.js、Java、Python)
  2. fastcgi_pass:代理 FastCGI 服务(就是 PHP-FPM)

PHP 用的是 fastcgi_pass,不是 proxy_pass,别搞混了。

基础配置

完整 LNMP 配置示例

server {
    listen       80;
    server_name  www.example.com;

    root  /var/www/html;
    index index.php index.html;

    # 访问根目录
    location / {
        try_files $uri $uri/ =404;
    }

    # PHP 请求转发给 PHP-FPM
    location ~ \.php$ {
        root           /var/www/html;
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        fastcgi_params;
    }
}

关键参数说明

参数 作用
fastcgi_pass 127.0.0.1:9000 PHP-FPM 监听的地址和端口
fastcgi_pass unix:/run/php-fpm/www.sock 用 socket 文件方式(更高效)
fastcgi_index index.php 默认首页
SCRIPT_FILENAME PHP 文件的完整路径
include fastcgi_params 引入其他参数

socket 方式 vs 端口方式

端口方式(TCP)

fastcgi_pass 127.0.0.1:9000;

优点:跨服务器可以用
缺点:多了一层 TCP 开销,稍微慢一点

Socket 方式(Unix Domain Socket)

fastcgi_pass unix:/run/php-fpm/www.sock;

优点:更快,少了 TCP 开销
缺点:只能在同一台服务器上用

生产环境推荐用 socket 方式,更快。

完整生产环境配置

server {
    listen       443 ssl http2;
    server_name  www.example.com;

    ssl_certificate      /etc/nginx/ssl/www.crt;
    ssl_certificate_key  /etc/nginx/ssl/www.key;

    root  /var/www/html;
    index index.php index.html;

    # 日志
    access_log  /var/log/nginx/www.access.log;
    error_log   /var/log/nginx/www.error.log;

    # 静态资源直接返回
    location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
        expires 30d;
    }

    # PHP 请求转发
    location ~ \.php$ {
        fastcgi_pass   unix:/run/php-fpm/www.sock;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        fastcgi_params;

        # 超时设置
        fastcgi_connect_timeout 300;
        fastcgi_send_timeout 300;
        fastcgi_read_timeout 300;
    }

    # 禁止访问 .ht 等文件
    location ~ /\.ht {
        deny  all;
    }
}

常见坑

坑1:SCRIPT_FILENAME 路径不对

配置了 SCRIPT_FILENAME /var/www/html$fastcgi_script_name;,但 root 不是这个路径。

原因: 写死了路径,换个目录就错了。

解决: 用 $document_root:

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

坑2:socket 路径不一致

Nginx 配置里写的 socket 路径和 PHP-FPM 实际的不一致。

检查 PHP-FPM 的 socket 路径:

grep listen /etc/php-fpm.d/www.conf

确保两边路径一模一样。

坑3:PHP 不解析,直接下载

访问 index.php,浏览器直接下载了文件,没解析。

原因: Nginx 没把 .php 请求转发给 PHP-FPM。

检查: 配置里有没有 location ~ \.php$ 这一段,有没有 fastcgi_pass。

坑4:404 Not Found

访问 PHP 文件报 404。

原因: SCRIPT_FILENAME 路径不对,PHP-FPM 找不到文件。

解决: 确认 root 和 SCRIPT_FILENAME 配置正确。

检查配置并重载

nginx -t
nginx -s reload

总结

配置项 说明
fastcgi_pass PHP-FPM 地址(端口或socket)
SCRIPT_FILENAME PHP 文件完整路径
fastcgi_params 其他参数集合
expires 静态资源缓存
超时设置 fastcgi_connect_timeout 等

记住: PHP 用 fastcgi_pass,不是 proxy_pass,别搞混了。

遇到问题加QQ23979811 协助处理


emer 发布于  2026-10-7 07:29 

Nginx 403 Forbidden权限不足原因与解决

前言

打开网站突然报 403 Forbidden,权限不足。这是 Nginx 最常见的报错之一。本文讲一下 403 的常见原因和解决办法。

403 是什么意思

403 Forbidden 表示服务器理解请求,但拒绝执行。说白了就是 Nginx 不让你访问这个文件/目录。

常见原因和解决办法

原因1:文件/目录权限不对

最常见的原因。Nginx 运行的用户(一般是 www)没有权限读文件。

检查权限:

ls -l /var/www/html/index.html

如果是 644 以下,或者属主是 root,Nginx 就读不了。

解决:

# 改文件权限
chmod 644 /var/www/html/index.html

# 改目录权限
chmod 755 /var/www/html

# 改属主
chown -R www:www /var/www/html

原因2:首页文件不存在

访问网站根目录,但没有 index 首页文件。

检查:

ls /var/www/html/

看看有没有 index.html 或 index.php。

解决:

  • 把首页文件名改成 index.html 或 index.php
  • 或者在 Nginx 配置里指定 index
index index.html index.php;

原因3:目录没有索引权限

访问一个目录,目录里没有首页文件,Nginx 又没开目录列表。

解决方法一: 放一个 index.html 进去

解决方法二: 开目录列表(不推荐,不安全)

location /uploads/ {
    autoindex on;
}

原因4:SELinux 没关

CentOS7 默认开了 SELinux,会拦截 Nginx 访问文件。

检查 SELinux 状态:

getenforce

如果是 Enforcing,说明开着。

解决:

# 临时关闭
setenforce 0

# 永久关闭
vi /etc/selinux/config
# 改成 SELINUX=disabled

原因5:Nginx 配置了访问控制

Nginx 配置里限制了 IP 访问,或者需要密码。

检查配置:

grep -i "deny\|allow\|auth_basic" /etc/nginx/conf.d/*.conf

如果有 deny all 或者 IP 白名单,把你的 IP 加上或者去掉限制。

原因6:文件路径不对

Nginx 配置的 root 路径和实际文件路径不一致。

检查配置:

grep root /etc/nginx/conf.d/*.conf

确认 root 指向的目录里确实有你的文件。

排查步骤

  1. 先看错误日志
tail -f /var/log/nginx/error.log

日志里会写得很清楚是什么原因。

  1. 检查文件权限
ls -l /var/www/html/
  1. 检查 SELinux
getenforce
  1. 检查 Nginx 配置
nginx -t

常见坑

坑1:只改了文件权限没改目录权限

文件权限是 644,但上级目录权限不对,Nginx 还是进不去。

解决: 一级一级改目录权限:

chmod 755 /var
chmod 755 /var/www
chmod 755 /var/www/html

坑2:上传的文件是 root 创建的

用 root 上传了文件,文件属主是 root,Nginx 用户读不了。

解决:

chown -R www:www /var/www/html

坑3:SELinux 改了没重启

临时关了 SELinux,但重启服务器又开了。

解决: 改配置文件永久关闭,别只 setenforce 0。

坑4:用了 CDN 或 WAF

前面有 CDN 或 WAF,它们拦截了请求。

解决: 直接用服务器 IP 访问,看看是不是还是 403。如果直接 IP 访问没问题,就是 CDN/WAF 的问题。

总结

原因 解决办法
文件权限不对 chmod 644 文件、chmod 755 目录
首页不存在 放个 index.html 进去
SELinux 拦截 关闭 SELinux
IP 被限制 检查 Nginx allow/deny 配置
路径不对 检查 root 配置
属主不对 chown www:www 目录

记住: 403 先看错误日志,大部分问题日志里都写得很清楚。

遇到问题加QQ23979811 协助处理


emer 发布于  2026-10-7 07:28 

Nginx静态资源缓存配置,提升网站访问速度

前言

网站访问慢?很大一部分原因是静态资源(图片、CSS、JS)每次都要重新从服务器下载。配置浏览器缓存之后,用户第二次访问就直接从本地缓存读了,速度快很多。本文讲一下 Nginx 怎么配置静态资源缓存。

缓存原理

浏览器第一次访问网站,服务器返回静态资源的时候,加上 Cache-Control 头,告诉浏览器"这个文件你缓存多久"。

第二次访问的时候,浏览器发现本地有缓存,且还没过期,就直接用本地的,不用再请求服务器了。

配置方法

按文件类型设置缓存时间

在 Nginx 配置里加:

server {
    listen       443 ssl http2;
    server_name  www.example.com;

    root  /var/www/html;
    index index.html;

    # 静态资源缓存
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|swf|woff|woff2|ttf|eot)$ {
        expires 30d;
        add_header Cache-Control "public, no-transform";
    }

    # HTML 文件不缓存
    location ~* \.html$ {
        expires -1;
    }
}

缓存时间说明

文件类型 建议缓存时间 说明
图片(jpg/png/gif) 30天 图片一般不怎么改
CSS/JS 7天 改了文件版本号就能更新
HTML 不缓存 保证用户看到最新页面
字体文件 30天 基本不变

更精细的配置

# 图片缓存 30 天
location ~* \.(jpg|jpeg|png|gif|ico)$ {
    expires 30d;
    add_header Cache-Control "public, immutable";
}

# CSS JS 缓存 7 天
location ~* \.(css|js)$ {
    expires 7d;
    add_header Cache-Control "public";
}

# 字体文件缓存 30 天
location ~* \.(woff|woff2|ttf|eot)$ {
    expires 30d;
    add_header Cache-Control "public, immutable";
}

# HTML 不缓存
location ~* \.html$ {
    expires -1;
    add_header Cache-Control "no-cache, no-store, must-revalidate";
}

参数说明

参数 作用
expires 30d 缓存30天
expires 1h 缓存1小时
expires -1 不缓存
Cache-Control public 允许所有缓存(浏览器、CDN)
Cache-Control private 只允许浏览器缓存
Cache-Control no-cache 不缓存(每次都要验证)
Cache-Control no-store 完全不缓存
immutable 文件永远不变(不用问服务器了)

怎么验证缓存生效了

打开浏览器 F12 → Network → 点一个静态资源 → 看 Response Headers:

Cache-Control: max-age=2592000
Expires: xxx

有这两个头就说明缓存生效了。

常见坑

坑1:改了 CSS 但页面没更新

更新了 CSS 文件,但用户看到的还是老版本。

原因: 浏览器缓存了老 CSS。

解决:

  • 改文件名:style.css → style.v2.css
  • 或者加版本号:style.css?v=20261007

这样浏览器就会当成新文件重新下载。

坑2:HTML 也被缓存了

页面内容更新了,但用户看到的还是老页面。

原因: HTML 文件也被缓存了。

解决: HTML 文件设置不缓存:

location ~* \.html$ {
    expires -1;
}

坑3:缓存时间太长

设置了一年缓存,万一文件要改怎么办?

解决: 用文件指纹(版本号)的方式,比如:

  • app.3a7b2c.js
  • style.8d9e1f.css

文件内容变了,文件名就变了,缓存自然就失效了。

坑4:配置了缓存但不生效

加了 expires 但浏览器还是每次都请求。

原因1: 开发模式下浏览器禁用了缓存。

解决: F12 → Network → 把 "Disable cache" 的勾去掉。

原因2: Nginx 没重载。

解决:

nginx -t
nginx -s reload

总结

步骤 操作
图片缓存 expires 30d
CSS/JS 缓存 expires 7d
HTML 不缓存 expires -1
改了文件怎么更新 加版本号或改文件名
验证生效 F12 看 Response Headers

提醒: 缓存配置好之后,网站打开速度能快好几倍,特别是图片多的网站。

遇到问题加QQ23979811 协助处理


emer 发布于  2026-10-7 07:27 

Nginx设置跨域,前端请求接口跨域配置示例

前言

前端页面和后端接口不在同一个域名下,浏览器报跨域错误。这是前后端分离开发最常见的问题。本文讲一下怎么用 Nginx 配置跨域。

什么是跨域

浏览器的同源策略:协议、域名、端口有一个不一样,就是跨域。

比如:

  • 前端:https://www.example.com
  • 后端接口:https://api.example.com

这两个域名不一样,浏览器就不让前端直接请求后端接口。

Nginx 配置跨域

简单配置(允许所有域名)

在接口的 server 块里加:

server {
    listen       443 ssl http2;
    server_name  api.example.com;

    # 跨域配置
    add_header Access-Control-Allow-Origin *;
    add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
    add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';

    # 处理 OPTIONS 预检请求
    if ($request_method = 'OPTIONS') {
        return 204;
    }

    root  /var/www/api;
    index index.php;
}

指定允许的域名(推荐)

生产环境不要用 *,指定具体域名更安全:

# 允许单个域名
add_header Access-Control-Allow-Origin https://www.example.com;

# 允许多个域名
set $cors_origin "";
if ($http_origin ~* "^https://(www\.example\.com|m\.example\.com)$") {
    set $cors_origin $http_origin;
}
add_header Access-Control-Allow-Origin $cors_origin;

带 Cookie 的跨域

如果跨域请求要带 Cookie,光加 * 不行:

add_header Access-Control-Allow-Origin $http_origin;
add_header Access-Control-Allow-Credentials true;

注意: 带 Cookie 的时候,Allow-Origin 不能用 *,必须指定具体域名。

完整配置示例

server {
    listen       443 ssl http2;
    server_name  api.example.com;

    ssl_certificate      /etc/nginx/ssl/api.crt;
    ssl_certificate_key  /etc/nginx/ssl/api.key;

    # 跨域配置
    set $cors_origin "";
    if ($http_origin ~* "^https://(www\.example\.com|admin\.example\.com)$") {
        set $cors_origin $http_origin;
    }

    add_header Access-Control-Allow-Origin $cors_origin;
    add_header Access-Control-Allow-Credentials true;
    add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE, OPTIONS';
    add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';

    # 处理 OPTIONS 预检请求
    if ($request_method = 'OPTIONS') {
        add_header Access-Control-Allow-Origin $cors_origin;
        add_header Access-Control-Allow-Credentials true;
        add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE, OPTIONS';
        add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
        add_header Access-Control-Max-Age 86400;
        return 204;
    }

    root  /var/www/api;
    index index.php;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }
}

检查配置并重载

nginx -t
nginx -s reload

常见坑

坑1:OPTIONS 请求 404

浏览器发 OPTIONS 预检请求,Nginx 直接返回 404。

原因: 没处理 OPTIONS 请求。

解决: 加上面那个 if ($request_method = 'OPTIONS') 的判断,直接返回 204。

坑2:跨域配置不生效

加了跨域配置还是报跨域错误。

原因1: PHP 后端也输出了跨域头,两边冲突了。

解决: 只留一处跨域配置,要么在 Nginx 配,要么在后端代码里配,不要两边都配。

原因2: Nginx 重载失败了。

解决: 确认 nginx -t 没问题,再 nginx -s reload。

坑3:带 Cookie 的跨域失败

配置了跨域,但是带 Cookie 请求还是失败。

原因: Allow-Origin 用了 *,浏览器不允许。

解决: 改成具体域名,加上 Access-Control-Allow-Credentials true。

坑4:POST 请求跨域失败

GET 请求没问题,POST 请求跨域了。

原因: 没允许 POST 方法或者 Content-Type 头。

解决: 把 POST 和 Content-Type 加到 Allow-Methods 和 Allow-Headers 里。

总结

配置项 作用
Access-Control-Allow-Origin 允许哪个域名访问
Access-Control-Allow-Methods 允许哪些请求方法
Access-Control-Allow-Headers 允许哪些请求头
Access-Control-Allow-Credentials 是否允许带 Cookie
Access-Control-Max-Age 预检请求缓存时间

生产环境建议: 不要用 *,指定具体域名更安全。

遇到问题加QQ23979811 协助处理


emer 发布于  2026-10-7 07:26 

Nginx 负载均衡配置

Nginx 负载均衡配置

网站流量大了,单台服务器扛不住,就需要负载均衡。这篇讲 Nginx 怎么配负载均衡。

1. 什么是负载均衡

简单说就是把请求分发到多台服务器上,分担压力,提高网站可用性。

2. 基础配置

http {
    # 定义后端服务器组
    upstream backend {
        server 192.168.1.101:80;
        server 192.168.1.102:80;
        server 192.168.1.103:80;
    }

    server {
        listen 80;
        server_name www.example.com;

        location / {
            proxy_pass http://backend;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
        }
    }
}

3. 负载均衡策略

轮询(默认):
按顺序逐个分发,每台服务器轮流来。

加权轮询:
服务器性能不一样,给好的服务器多分点流量。

upstream backend {
    server 192.168.1.101 weight=3;
    server 192.168.1.102 weight=2;
    server 192.168.1.103 weight=1;
}

ip_hash(会话保持):
同一个 IP 的请求永远分发到同一台服务器,保持登录状态。

upstream backend {
    ip_hash;
    server 192.168.1.101;
    server 192.168.1.102;
}

4. 健康检查

服务器挂了自动跳过,不把请求发过去。

upstream backend {
    server 192.168.1.101 max_fails=3 fail_timeout=30s;
    server 192.168.1.102 max_fails=3 fail_timeout=30s;
}
  • max_fails:失败几次标记为下线
  • fail_timeout:多久后重新检查

5. 常用配置说明

location / {
    proxy_pass http://backend;

    # 传递真实IP
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    # 超时时间
    proxy_connect_timeout 5s;
    proxy_read_timeout 60s;
}

6. 常见问题

1)Session 丢失:

  • 多台服务器 Session 不共享
  • 解决方案:Session 存 Redis,或者用 ip_hash

2)静态文件 404:

  • 每台服务器都要有静态文件
  • 或者用共享存储

3)服务器性能不均:

  • 用 weighted 加权轮询

总结

Nginx 负载均衡要点:

  • upstream 定义后端服务器组
  • 轮询、加权、ip_hash 三种策略
  • 配置健康检查自动下线故障服务器
  • Session 要共享或用 ip_hash

做网站架构,负载均衡是必备技能。


emer 发布于  2026-10-7 07:20 

Nginx 配置 HTTPS 详解

Nginx 配置 HTTPS 详解

现在网站都要求上 HTTPS,Nginx 配置 HTTPS 是运维必备技能。

1. 申请 SSL 证书

免费证书推荐:

  • Let's Encrypt(免费 90 天)
  • 阿里云/腾讯云免费 DV 证书

用 acme.sh 申请 Let's Encrypt:

# 安装 acme.sh
curl https://get.acme.sh | sh

# 申请证书
~/.acme.sh/acme.sh --issue -d www.example.com --webroot /www/wwwroot/example.com/

# 安装证书
~/.acme.sh/acme.sh --install-cert -d www.example.com \
  --key-file /www/server/ssl/private.key \
  --fullchain-file /www/server/ssl/cert.crt

2. Nginx 基础 HTTPS 配置

server {
    listen 443 ssl;
    server_name www.example.com;

    # 证书文件
    ssl_certificate     /www/server/ssl/cert.crt;
    ssl_certificate_key /www/server/ssl/private.key;

    # SSL 优化
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;

    root /www/wwwroot/example.com;
    index index.html index.php;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}

3. HTTP 自动跳转 HTTPS

server {
    listen 80;
    server_name www.example.com;
    return 301 https://$server_name$request_uri;
}

4. 优化 HTTPS 性能

开启 HTTP/2:

listen 443 ssl http2;

HSTS 强制 HTTPS:

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

开启 OCSP Stapling:

ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 114.114.114.114 valid=300s;

5. 常见问题

1)证书不生效:

  • 检查证书路径对不对
  • 证书文件格式是否正确
  • Nginx 配置重载了吗

2)混合内容问题:

  • 页面里有 http:// 的资源,浏览器会拦截
  • 全部改成 https:// 或 // 协议相对路径

3)证书过期:

  • 免费证书 90 天过期
  • 用 acme.sh 自动续期
# acme.sh 自动安装了定时任务
crontab -l | grep acme

6. 检查配置

# 检查 Nginx 配置
nginx -t

# 重载配置
nginx -s reload

# 测试证书
curl -I https://www.example.com

总结

Nginx 配置 HTTPS 要点:

  • 申请 SSL 证书
  • 配置 443 端口和证书路径
  • HTTP 跳转 HTTPS
  • 开启 HTTP/2 和 SSL 优化
  • 设置自动续期

现在没有 HTTPS 的网站浏览器都标"不安全",赶紧给网站配上。


emer 发布于  2026-10-7 07:10 

Nginx配置HTTPS证书,http自动跳转https

前言

现在网站都要上 HTTPS,搜索引擎也更喜欢 HTTPS 的网站。本文讲一下 Nginx 怎么配置 HTTPS 证书,以及怎么把 HTTP 请求自动跳转到 HTTPS。

第一步:申请 SSL 证书

免费证书(Let's Encrypt)

用 certbot 自动申请:

# 安装 certbot
yum install certbot python3-certbot-nginx -y

# 自动申请并配置
certbot --nginx -d www.example.com -d example.com

certbot 会自动修改 Nginx 配置,不用手动改。

自己上传证书

如果是从阿里云、腾讯云申请的证书,下载 Nginx 版本的,一般有两个文件:

  • xxx.crt(证书文件)
  • xxx.key(私钥文件)

上传到服务器:

mkdir -p /etc/nginx/ssl

把两个文件传到 /etc/nginx/ssl/ 目录下。

第二步:Nginx 配置 HTTPS

编辑 Nginx 配置文件:

vi /etc/nginx/conf.d/example.conf

配置内容:

server {
    listen       443 ssl http2;
    server_name  www.example.com example.com;

    # 证书路径
    ssl_certificate      /etc/nginx/ssl/xxx.crt;
    ssl_certificate_key  /etc/nginx/ssl/xxx.key;

    # SSL 优化配置
    ssl_session_cache    shared:SSL:10m;
    ssl_session_timeout  10m;
    ssl_ciphers  HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers  on;

    # 网站根目录
    root  /var/www/html;
    index index.html index.php;

    location / {
        try_files $uri $uri/ =404;
    }
}

第三步:HTTP 自动跳转 HTTPS

在同一个配置文件里,加一个 80 端口的 server:

# HTTP 跳转 HTTPS
server {
    listen       80;
    server_name  www.example.com example.com;
    return 301 https://$host$request_uri;
}

这样访问 http://www.example.com 就会自动跳转到 https://www.example.com。

第四步:检查配置并重载

检查 Nginx 配置有没有语法错误:

nginx -t

没问题就重载:

nginx -s reload

完整配置示例

# HTTP 跳转 HTTPS
server {
    listen       80;
    server_name  www.example.com example.com;
    return 301 https://$host$request_uri;
}

# HTTPS 配置
server {
    listen       443 ssl http2;
    server_name  www.example.com example.com;

    ssl_certificate      /etc/nginx/ssl/xxx.crt;
    ssl_certificate_key  /etc/nginx/ssl/xxx.key;

    ssl_session_cache    shared:SSL:10m;
    ssl_session_timeout  10m;
    ssl_ciphers  HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers  on;

    root  /var/www/html;
    index index.html index.php;

    location / {
        try_files $uri $uri/ =404;
    }
}

常见坑

坑1:证书文件路径不对

配置里写的证书路径和实际路径不一致,Nginx 启动报错。

解决: 确认证书文件确实在配置写的那个位置。

坑2:443 端口没开放

配置了 HTTPS 但访问不了。

原因: 防火墙没开 443 端口。

解决:

firewall-cmd --permanent --add-service=https
firewall-cmd --reload

坑3:跳转死循环

HTTP 跳 HTTPS 后又跳回 HTTP,无限循环。

原因: 用了 CDN 或者负载均衡,后端以为还是 HTTP。

解决: Nginx 配置里加:

set $flag 0;
if ($http_x_forwarded_proto = 'http') {
    set $flag 1;
}
if ($flag = 1) {
    return 301 https://$host$request_uri;
}

坑4:证书过期了

HTTPS 证书一般一年有效期,忘了续签就会过期。

解决: 用 certbot 的话自动续签:

certbot renew

加个定时任务自动续签:

0 3 1 * * certbot renew --quiet

总结

步骤 命令/操作
申请证书 certbot --nginx -d 域名
配置 HTTPS 写 443 端口的 server 块
HTTP 跳转 return 301 https://$host$request_uri
检查配置 nginx -t
重载 nginx -s reload
开防火墙 firewall-cmd --permanent --add-service=https

提醒: HTTPS 证书要定期续签,别等过期了才想起。

遇到问题加QQ23979811 协助处理


emer 发布于  2026-10-6 08:07 

Nginx报502 Bad Gateway完整排查思路(PHP-FPM场景)

前言

502 Bad Gateway 是 Nginx 最常见的报错之一,尤其是 LNMP 架构下,Nginx 把 PHP 请求转发给 PHP-FPM,PHP-FPM 出问题了 Nginx 就报 502。本文讲一下完整的排查思路。

502 是什么意思

502 表示 Nginx 作为反向代理,去请求后端服务(PHP-FPM)的时候,后端没响应或者报错了。

注意: 502 不是 Nginx 的问题,是后端 PHP-FPM 的问题。

排查步骤

第一步:检查 PHP-FPM 服务是否在运行

systemctl status php-fpm

如果显示 inactive (dead),说明 PHP-FPM 挂了,启动它:

systemctl start php-fpm
systemctl enable php-fpm

第二步:检查 Nginx 和 PHP-FPM 的通信配置

看 Nginx 配置里的 fastcgi_pass 对不对:

grep fastcgi_pass /etc/nginx/nginx.conf

常见的配置:

# 用 socket 文件
fastcgi_pass unix:/run/php-fpm/www.sock;

# 用 TCP 端口
fastcgi_pass 127.0.0.1:9000;

问题1:socket 文件路径不对

Nginx 配置里写的 socket 路径和 PHP-FPM 实际的不一致。

PHP-FPM 的 socket 路径在 /etc/php-fpm.d/www.conf 里:

grep listen /etc/php-fpm.d/www.conf

确保两边路径一致。

问题2:端口被占

如果用 9000 端口,检查一下是不是被别的进程占了:

lsof -i:9000

第三步:看错误日志

Nginx 错误日志:

tail -f /var/log/nginx/error.log

PHP-FPM 错误日志:

tail -f /var/log/php-fpm/error.log

PHP 慢日志:

tail -f /var/log/php-fpm/www-slow.log

根据日志里的报错信息找原因。

第四步:常见原因

原因1:PHP-FPM 进程数不够

访问量大的时候,PHP-FPM 进程都被占满了,新请求排队超时。

解决: 增加 PHP-FPM 进程数。

编辑 /etc/php-fpm.d/www.conf:

pm.max_children = 50
pm.start_servers = 20
pm.min_spare_servers = 10
pm.max_spare_servers = 30

改完重启:

systemctl restart php-fpm

原因2:PHP 脚本执行超时

PHP 脚本执行时间太长,超过了 Nginx 的超时时间。

解决: 调大超时时间。

Nginx 配置里:

fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;

PHP 配置里:

max_execution_time = 300

原因3:PHP 内存不足

PHP-FPM 进程内存溢出,导致进程崩溃。

解决: 调大 PHP 内存限制:

memory_limit = 256M

或者减少 PHP-FPM 进程数,避免内存不够。

原因4:文件权限不对

Nginx 运行的用户和 PHP-FPM 运行的用户不一致,导致 PHP-FPM 读不到文件。

解决: 确保 Nginx 和 PHP-FPM 用同一个用户(一般是 www)。

PHP-FPM 配置 /etc/php-fpm.d/www.conf:

user = www
group = www

然后把网站文件的属主改成 www:

chown -R www:www /var/www/html

第五步:重启所有服务

改完配置后重启:

systemctl restart php-fpm
systemctl restart nginx

常见坑

坑1:只重启了 Nginx

改了 PHP 配置但只重启了 Nginx,PHP-FPM 还是老配置。

解决: PHP 配置改了要重启 PHP-FPM,Nginx 配置改了要重启 Nginx。

坑2:socket 文件权限不对

PHP-FPM 的 socket 文件权限是 600,Nginx 用户读不到。

解决: 改 socket 文件权限:

listen.mode = 0666

或者改 socket 文件的属主:

listen.owner = www
listen.group = www

坑3:PHP-FPM 挂了但没自动重启

PHP-FPM 进程崩溃了,没人自动拉起来。

解决: 配置 systemd 自动重启:

systemctl edit php-fpm

加:

[Service]
Restart=always
RestartSec=2

总结

502 排查步骤:

  1. 先看 PHP-FPM 是不是挂了 → systemctl status php-fpm
  2. 再看 Nginx 配置对不对 → fastcgi_pass 路径/端口
  3. 看错误日志 → Nginx error.log + PHP-FPM error.log
  4. 常见原因 → 进程数不够、超时太短、权限不对、内存不足

记住:502 问题出在后端,不是 Nginx 的锅。

遇到问题加QQ23979811 协助处理


emer 发布于  2026-10-6 08:06 

Nginx配置gzip压缩,提高网站加载速度

前言

网站加载慢,很大原因是没开压缩。CSS、JS 文件动辄几百 KB,开了 gzip 之后能压缩到原来的 1/3,加载速度提升明显。本文就讲一下怎么在 Nginx 里配置 gzip 压缩。

为什么要开 gzip

举个例子:

  • 一个 CSS 文件原始大小 100KB
  • 开了 gzip 之后变成 20KB
  • 传输体积减少 80%

浏览器收到压缩内容后自动解压,用户无感知。

基础配置

在 nginx.conf 的 http 块里加上:

http {
    gzip on;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml;
    gzip_min_length 1k;
    gzip_comp_level 6;
    gzip_vary on;
}

配置项说明

gzip on:
开启 gzip 压缩。

gzip_types:
哪些类型的文件需要压缩。

  • text/plain:文本
  • text/css:CSS
  • application/json:JSON
  • application/javascript:JS
  • image/svg+xml:SVG 图片

gzip_min_length:
小于 1KB 的文件不压缩(压缩本身也占 CPU,小文件不值得压)。

gzip_comp_level:
压缩级别,1 到 9,6 比较合适(越大压得越狠,但越占 CPU)。

gzip_vary on:
给响应头加 Vary: Accept-Encoding,告诉 CDN 和缓存,这个内容是压缩过的。

完整示例

http {
    gzip on;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml;
    gzip_min_length 1k;
    gzip_comp_level 6;
    gzip_vary on;
    gzip_buffers 16 8k;
    gzip_http_version 1.1;
}

检查并重载

nginx -t
systemctl reload nginx

验证 gzip 是否生效

用 curl 测试

curl -H "Accept-Encoding: gzip" -I https://www.example.com

如果返回头里有:

Content-Encoding: gzip

说明 gzip 生效了。

用浏览器 F12 测试

打开浏览器 F12 → Network → 点一个 JS/CSS 文件 → Response Headers,看有没有 Content-Encoding: gzip。

注意事项

不要压缩图片

JPG、PNG 这些图片本身已经是压缩过的,再压 gzip 没什么效果,还浪费 CPU。所以 gzip_types 里不要加 image/jpeg、image/png 这些。

不要压缩太小的文件

太小的文件(比如小于 1KB)压缩完反而可能变大,所以用 gzip_min_length 过滤掉。

压缩级别不要太高

gzip_comp_level 设到 9 没意义,压不了多少,CPU 占用还高。6 就够了。

常见坑

坑1:开了 gzip 但没生效

配置写了,但浏览器看到的还是没压缩的。

排查:

  1. 看文件大小是不是小于 gzip_min_length
  2. 看 gzip_types 里有没有包含这种类型
  3. 看浏览器请求头里有没有 Accept-Encoding: gzip

坑2:HTML 没压缩

只压缩了 CSS 和 JS,HTML 没压缩。

原因: gzip_types 里没写 text/html。

注意: text/html 是默认就压缩的,不用写在 gzip_types 里。

坑3:CDN 缓存了没压缩的版本

开了 gzip,但 CDN 上缓存的还是旧的没压缩的文件。

解决: 清一下 CDN 缓存,或者等 CDN 自动更新。

总结

gzip 配置很简单,就几行:

配置项 推荐值 作用
gzip on 开启压缩
gzip_types text/css application/javascript ... 压缩哪些文件
gzip_min_length 1k 小于多少不压
gzip_comp_level 6 压缩级别
gzip_vary on 加 Vary 头

开了 gzip 网站加载速度立马快一截,零成本优化,一定要开。

遇到问题加QQ23979811 协助处理


emer 发布于  2026-10-5 07:59 

Nginx配置访问日志,日志切割和分析

前言

Nginx 默认就会记录访问日志,放在 /var/log/nginx/ 目录下。但日志每天都在涨,时间长了占满磁盘,还不好查。本文就讲一下 Nginx 日志配置、切割和分析方法。

默认日志位置

Nginx 默认日志文件:

/var/log/nginx/
├── access.log    # 访问日志
└── error.log     # 错误日志

日志格式

Nginx 默认的日志格式叫 combined,记录这些信息:

  • 客户端 IP
  • 访问时间
  • 请求方法和路径
  • 状态码
  • 响应大小
  • Referer
  • User-Agent

自定义日志格式

在 nginx.conf 的 http 块里可以自定义日志格式:

http {
    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  /var/log/nginx/access.log  main;
}

常用变量

变量 说明
$remote_addr 客户端 IP
$time_local 本地时间
$request 请求行
$status 状态码
$body_bytes_sent 响应大小
$http_referer 来源页面
$http_user_agent 浏览器信息
$request_time 请求耗时

按站点分日志

不同站点的日志分开存,方便排查问题:

server {
    listen 80;
    server_name www.example.com;

    access_log  /var/log/nginx/example.com.access.log;
    error_log   /var/log/nginx/example.com.error.log;
}

日志切割

用 logrotate 切割

CentOS7 装完 Nginx 就自动配了 logrotate,不用管。配置文件在:

/etc/logrotate.d/nginx

内容大概是:

/var/log/nginx/*.log {
    daily
    missingok
    rotate 14
    compress
    notifempty
    create 0640 nginx adm
    sharedscripts
    postrotate
        if [ -f /var/run/nginx.pid ]; then
            kill -USR1 `cat /var/run/nginx.pid`
        fi
    endscript
}

意思是:

  • 每天切割一次
  • 保留 14 天
  • 压缩旧日志
  • 空日志不切割

手动测试切割

logrotate -f /etc/logrotate.d/nginx

日志分析常用命令

查看访问量前 10 的 IP

awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -10

查看访问量前 10 的页面

awk '{print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -10

查看状态码统计

awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -nr

查看爬虫访问

grep 'Googlebot' /var/log/nginx/access.log

查看某个 IP 的访问

grep '192.168.1.1' /var/log/nginx/access.log

常见坑

坑1:日志越来越大占满磁盘

日志不切割,时间长了把磁盘占满。

解决: 确认 logrotate 在运行:

cat /var/lib/logrotate.status

或者手动执行一次:

logrotate -f /etc/logrotate.d/nginx

坑2:日志里 IP 不对

日志里全是 127.0.0.1,不是真实用户 IP。

原因: Nginx 前面还有一层代理(比如 CDN),或者配了反向代理。

解决: 用 $http_x_forwarded_for 代替 $remote_addr:

log_format main '$http_x_forwarded_for - $remote_user [$time_local] "$request" '
                '$status $body_bytes_sent "$http_referer" "$http_user_agent"';

坑3:日志级别太高

错误日志里全是 notice,没用还占空间。

解决: 把错误日志级别调高一点:

error_log /var/log/nginx/error.log warn;

可选级别:debug、info、notice、warn、error、crit。

总结

Nginx 日志的常用操作:

操作 命令
看访问日志 tail -f /var/log/nginx/access.log
看错误日志 tail -f /var/log/nginx/error.log
统计 IP awk '{print $1}' access.log \| sort \| uniq -c
统计页面 awk '{print $7}' access.log \| sort \| uniq -c
手动切割 logrotate -f /etc/logrotate.d/nginx

日志是排查问题的第一手资料,学会看日志比什么都重要。

遇到问题加QQ23979811 协助处理


emer 发布于  2026-10-5 07:58 

Nginx配置静态网站,前端项目部署到服务器

前言

前端项目写完了,怎么部署到服务器上让别人访问?现在前端都是 Vue、React 这种单页应用,打包出来一堆静态文件,扔到 Nginx 上就能跑。本文就讲一下怎么用 Nginx 部署前端静态网站。

第一步:打包前端项目

前端项目一般用 npm 或 yarn 打包:

npm run build

打包完会生成一个 dist 目录,里面就是所有静态文件(HTML、CSS、JS)。

第二步:上传到服务器

把 dist 目录上传到服务器上,比如放到 /var/www/html/my-app:

# 用 scp 上传
scp -r dist/ root@你的服务器IP:/var/www/html/my-app

或者用 FTP 工具上传。

第三步:配置 Nginx

最简单的配置

server {
    listen 80;
    server_name www.example.com;

    root /var/www/html/my-app;
    index index.html;

    location / {
        try_files $uri $uri/ /index.html;
    }
}

关键配置说明

root 网站根目录:

root /var/www/html/my-app;

就是你上传静态文件的目录。

index 默认首页:

index index.html;

用户访问网站根目录的时候,默认打开 index.html。

try_files 路由支持:

try_files $uri $uri/ /index.html;

这个很重要!Vue/React 这种单页应用,前端路由是靠 H5 History API 实现的。如果用户直接访问 /about 这种路径,Nginx 找不到对应的文件,就会 404。

加了 try_files 之后,Nginx 找不到文件就返回 index.html,交给前端路由处理。

检查并重载

nginx -t
systemctl reload nginx

测试

浏览器访问 www.example.com,应该能看到你的前端页面了。

加上 HTTPS

如果要配 HTTPS,加上 SSL 配置:

server {
    listen 80;
    server_name www.example.com;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl;
    server_name www.example.com;

    ssl_certificate /etc/letsencrypt/live/www.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/www.example.com/privkey.pem;

    root /var/www/html/my-app;
    index index.html;

    location / {
        try_files $uri $uri/ /index.html;
    }
}

常见优化配置

开启 gzip 压缩

server {
    # ... 其他配置

    gzip on;
    gzip_types text/css application/javascript application/json image/svg+xml;
    gzip_min_length 1k;
    gzip_comp_level 6;
}

开启 gzip 之后,文件传输体积小很多,加载更快。

静态资源缓存

location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
    expires 30d;
    add_header Cache-Control "public, immutable";
}

静态资源缓存 30 天,不用每次都重新下载。

隐藏 Nginx 版本号

http {
    server_tokens off;
}

在 nginx.conf 的 http 块里加上这行,安全一点。

常见坑

坑1:刷新页面 404

路由是 /about,刷新就 404。

原因: Nginx 找不到 /about 对应的文件。

解决: 加 try_files:

location / {
    try_files $uri $uri/ /index.html;
}

坑2:JS/CSS 404

打包完访问页面,JS 和 CSS 全 404。

原因: 打包的时候 publicPath 没配对。

解决: Vue 项目在 vue.config.js 里配:

module.exports = {
  publicPath: '/'
}

React 项目在 .env 里配:

PUBLIC_URL=/

坑3:跨域问题

前端调后端接口,浏览器报跨域错误。

解决: 用 Nginx 反向代理把接口请求转发到后端,不要让前端直接请求后端地址。

location /api/ {
    proxy_pass http://后端地址;
}

坑4:权限不够

访问报 403 Forbidden。

原因: Nginx 没有读取文件的权限。

解决:

chown -R nginx:nginx /var/www/html/my-app
chmod -R 755 /var/www/html/my-app

总结

前端项目部署到 Nginx 的完整流程:

  1. 打包:npm run build
  2. 上传:把 dist 目录传到服务器
  3. 配置 Nginx:root 指向静态文件目录,加 try_files
  4. 重载:nginx -t && systemctl reload nginx
  5. 测试:浏览器访问域名

部署静态网站是前端开发的必备技能,记住 try_files 那行就不会踩刷新 404 的坑了。

遇到问题加QQ23979811 协助处理


emer 发布于  2026-10-5 07:57 

Nginx反向代理配置,把请求转发到后端服务

前言

现在做后端开发,后端服务一般跑在 3000、8080 这种端口上,总不能让用户直接访问 IP:端口 吧?这时候就需要 Nginx 反向代理,把 80 端口的请求转发到后端服务。本文就讲一下 Nginx 反向代理的配置方法。

什么是反向代理

简单说,反向代理就是:

  • 用户访问 Nginx(80 端口)
  • Nginx 把请求转发给后端服务(比如 3000 端口)
  • 后端服务返回结果给 Nginx
  • Nginx 再返回给用户

用户不知道后端服务的存在,只跟 Nginx 打交道。

基本配置

最简单的反向代理

server {
    listen 80;
    server_name www.example.com;

    location / {
        proxy_pass http://127.0.0.1:3000;
    }
}

就这么简单,所有访问 www.example.com 的请求都会被转发到 http://127.0.0.1:3000。

检查并重载

nginx -t
systemctl reload nginx

常用配置项

proxy_pass 后端地址

proxy_pass http://127.0.0.1:3000;

后端服务的地址,可以是 IP 加端口,也可以是域名。

传递真实客户端 IP

默认情况下,后端服务看到的是 Nginx 的 IP,不是真实用户的 IP。需要加上几个请求头:

location / {
    proxy_pass http://127.0.0.1:3000;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
}

这样后端服务就能拿到真实用户的 IP 了。

代理 WebSocket

如果后端服务用了 WebSocket,需要额外配置:

location /ws {
    proxy_pass http://127.0.0.1:3000;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
}

超时设置

location / {
    proxy_pass http://127.0.0.1:3000;
    proxy_connect_timeout 60s;
    proxy_read_timeout 60s;
    proxy_send_timeout 60s;
}

如果后端服务响应慢,可以把超时时间调大一点。

按路径分流

不同路径转发到不同后端服务:

server {
    listen 80;
    server_name www.example.com;

    location /api/ {
        proxy_pass http://127.0.0.1:3000;
    }

    location /admin/ {
        proxy_pass http://127.0.0.1:8080;
    }

    location / {
        root /var/www/html;
        index index.html;
    }
}

这样:

  • /api/ 开头的请求 → 3000 端口
  • /admin/ 开头的请求 → 8080 端口
  • 其他请求 → 静态文件

常见坑

坑1:502 Bad Gateway

访问报 502,说明 Nginx 连不上后端服务。

排查:

  1. 看后端服务有没有启动:curl http://127.0.0.1:3000
  2. 看后端服务监听的地址对不对,是不是只监听了 127.0.0.1
  3. 看防火墙有没有挡住

坑2:后端拿不到真实 IP

日志里全是 Nginx 的 IP,不是用户真实 IP。

解决: 加上那几个请求头:

proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

坑3:静态资源 404

前端是 Vue/React 这种单页应用,刷新页面就 404。

原因: Nginx 找不到对应的静态文件。

解决: 加个 try_files:

location / {
    root /var/www/html;
    index index.html;
    try_files $uri $uri/ /index.html;
}

所有找不到的路径都返回 index.html,交给前端路由处理。

坑4:HTTPS 代理后端 HTTP

前端是 HTTPS,后端是 HTTP,浏览器报混合内容错误。

解决: 确保 Nginx 和后端之间是 HTTP 没问题,但要让后端知道原始请求是 HTTPS:

proxy_set_header X-Forwarded-Proto $scheme;

总结

Nginx 反向代理的核心就是 proxy_pass,把请求转发到后端服务。常用配置:

配置项 作用
proxy_pass 后端服务地址
proxy_set_header Host 传递域名
proxy_set_header X-Real-IP 传递真实 IP
proxy_set_header X-Forwarded-For 传递完整 IP 链
proxy_read_timeout 读取超时时间

反向代理是 Nginx 最常用的功能之一,做 Web 开发必备。

遇到问题加QQ23979811 协助处理


emer 发布于  2026-10-5 07:55 

Nginx配置HTTPS,Let's Encrypt免费SSL证书申请

前言

现在网站没个 HTTPS 都不好意思拿出来,浏览器直接标"不安全"。申请 SSL 证书以前要花钱买,现在有了 Let's Encrypt,免费申请,90天有效期,还能自动续期。本文就讲一下怎么用 Let's Encrypt 给 Nginx 配 HTTPS。

前提条件

申请 SSL 证书之前,先确认:

  1. 域名已经解析到服务器 IP
  2. 80 端口已经开放(防火墙、安全组都要开)
  3. Nginx 已经能正常跑 HTTP

这三个条件满足了才能申请成功。

第一步:安装 certbot

certbot 是 Let's Encrypt 官方的证书申请工具。

yum install certbot python2-certbot-nginx -y

这个包会自动装 certbot 和 Nginx 插件。

第二步:申请证书

自动申请并配置

certbot --nginx -d www.example.com -d example.com

参数说明:

  • --nginx:自动修改 Nginx 配置
  • -d:指定域名,可以写多个

执行过程中会问你:

  1. 邮箱地址:填你的邮箱,证书过期了会提醒你
  2. 同意服务条款:输入 A
  3. 是否接收邮件:输入 N
  4. 是否把 HTTP 跳转到 HTTPS:选 2(跳转)

等待申请完成,一般几秒钟就好。

第三步:测试 HTTPS

浏览器访问 https://www.example.com,应该能看到小锁标志了。

HTTP 访问 http://www.example.com 会自动跳转到 HTTPS。

证书文件位置

申请完的证书文件都在 /etc/letsencrypt/live/域名/ 目录下:

/etc/letsencrypt/live/www.example.com/
├── cert.pem          # 证书
├── chain.pem         # 中间证书
├── fullchain.pem     # 证书+中间证书(Nginx用这个)
└── privkey.pem       # 私钥

Nginx 配置里用的是:

  • ssl_certificate /etc/letsencrypt/live/域名/fullchain.pem;
  • ssl_certificate_key /etc/letsencrypt/live/域名/privkey.pem;

自动续期

Let's Encrypt 证书有效期只有 90 天,需要定期续期。

测试自动续期

certbot renew --dry-run

如果没报错,说明自动续期配置没问题。

自动续期定时任务

certbot 装完会自动加一个定时任务,不用管。可以看看:

crontab -l

或者:

systemctl list-timers | grep certbot

手动配置 HTTPS

如果不想用 certbot 自动改配置,也可以手动写 Nginx 配置。

Nginx HTTPS 配置示例

server {
    listen 80;
    server_name www.example.com;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl;
    server_name www.example.com;

    ssl_certificate /etc/letsencrypt/live/www.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/www.example.com/privkey.pem;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;

    root   /var/www/html/test;
    index  index.html index.htm;

    location / {
        try_files $uri $uri/ =404;
    }
}

检查并重载

nginx -t
systemctl reload nginx

常见坑

坑1:域名没解析就申请

域名还没解析到服务器,就开始申请证书,结果申请失败。

解决: 先 ping 一下域名,确认解析到你服务器 IP 了再申请。

坑2:80 端口没开

防火墙或安全组没开 80 端口,Let's Encrypt 验证不了你的域名,申请失败。

解决: 先开 80 端口:

firewall-cmd --permanent --add-service=http
firewall-cmd --reload

云服务器还要在安全组里开 80 端口。

坑3:证书到期了没续期

忘了续期,证书过期了,浏览器报不安全。

解决: certbot 会自动续期,不用管。但要确认自动续期服务在运行:

systemctl status certbot-renew.timer

坑4:HTTPS 配置完了 404

配完 HTTPS 访问 404,一般是 root 目录或者 server_name 写错了。

排查:

  1. 看 Nginx 配置里的 server_name 对不对
  2. 看 root 目录对不对
  3. nginx -t 检查配置语法

总结

Nginx 配置 HTTPS 的完整流程:

  1. 装 certbot:yum install certbot python2-certbot-nginx -y
  2. 申请证书:certbot --nginx -d www.example.com
  3. 自动续期:certbot 自动搞定,不用管
  4. 测试:浏览器访问 HTTPS,看小锁标志

Let's Encrypt 免费证书是现在最流行的方案,不用花钱就能给网站上 HTTPS。

遇到问题加QQ23979811 协助处理


emer 发布于  2026-10-5 07:54 

Nginx安装配置完整教程,从安装到运行

前言

刚装好 CentOS 服务器,想跑个网站,第一步就是装 Nginx。Nginx 是目前最流行的 Web 服务器,性能高、占用资源少,还能做反向代理和负载均衡。本文就从安装 Nginx 开始,一步步讲怎么配置一个能跑的网站。

第一步:安装 Nginx

1. 安装 EPEL 源

CentOS7 默认源里的 Nginx 版本比较老,先装 EPEL 源:

yum install epel-release -y

2. 安装 Nginx

yum install nginx -y

3. 启动 Nginx

systemctl start nginx

4. 设置开机自启

systemctl enable nginx

5. 开放防火墙

firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
firewall-cmd --reload

6. 测试

浏览器访问你的服务器 IP,应该能看到 Nginx 默认欢迎页面。

第二步:Nginx 配置文件结构

Nginx 的配置文件都在 /etc/nginx/ 目录下:

/etc/nginx/
├── nginx.conf          # 主配置文件
├── conf.d/             # 子配置文件目录
│   └── default.conf   # 默认站点配置
├── fastcgi.conf
├── mime.types
└── ...

一般我们写站点配置,都放在 conf.d/ 目录下,每个站点一个文件。

第三步:配置第一个站点

1. 创建网站根目录

mkdir -p /var/www/html/test

2. 写一个测试页面

echo "Hello Nginx" > /var/www/html/test/index.html

3. 创建站点配置文件

vi /etc/nginx/conf.d/test.conf

写入:

server {
    listen       80;
    server_name  www.example.com;

    root   /var/www/html/test;
    index  index.html index.htm;

    location / {
        try_files $uri $uri/ =404;
    }
}

4. 检查配置是否正确

nginx -t

输出 test is successful 就是没问题。

5. 重新加载 Nginx

systemctl reload nginx

6. 测试

浏览器访问 www.example.com,应该能看到 "Hello Nginx"。

注意: 要把域名解析到你服务器的 IP 上,或者在本地 hosts 文件里加一条记录。

常用配置说明

listen 监听端口

listen 80;

监听 80 端口,HTTP 默认端口。

如果要监听 HTTPS 的 443 端口:

listen 443 ssl;

server_name 域名

server_name www.example.com example.com;

可以写多个域名,用空格隔开。

root 网站根目录

root /var/www/html/test;

网站文件放在这个目录下。

index 默认首页

index index.html index.htm;

用户访问网站根目录的时候,默认找哪个文件。

配置 PHP 支持

如果要跑 PHP 网站,还需要配置 PHP-FPM。

1. 安装 PHP-FPM

yum install php-fpm php-mysql -y

2. 启动 PHP-FPM

systemctl start php-fpm
systemctl enable php-fpm

3. 修改 Nginx 配置

在站点配置里加上 PHP 支持:

server {
    listen       80;
    server_name  www.example.com;

    root   /var/www/html/test;
    index  index.php index.html index.htm;

    location / {
        try_files $uri $uri/ =404;
    }

    location ~ \.php$ {
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        fastcgi_params;
    }
}

4. 重启 Nginx

systemctl restart nginx

5. 测试 PHP

创建一个 info.php 文件:

echo "<?php phpinfo(); ?>" > /var/www/html/test/info.php

浏览器访问 www.example.com/info.php,应该能看到 PHP 信息页面。

常见坑

坑1:403 Forbidden

访问网站报 403,一般是权限问题。

排查:

  1. 看文件权限是不是 644,目录是不是 755
  2. 看所有者是不是 nginx
  3. 看 SELinux 是不是开着
chown -R nginx:nginx /var/www/html/test
chmod -R 755 /var/www/html/test

坑2:502 Bad Gateway

访问网站报 502,说明 Nginx 连不上 PHP-FPM。

排查:

  1. 看 PHP-FPM 有没有启动:systemctl status php-fpm
  2. 看配置里的 fastcgi_pass 地址对不对

坑3:配置改完不生效

改了 Nginx 配置,没 reload,结果配置没生效。

解决: 改完配置记得 reload:

nginx -t
systemctl reload nginx

坑4:域名解析了还是打不开

域名解析了,但还是打不开。

排查:

  1. 看防火墙有没有开 80 端口
  2. 看安全组有没有开 80 端口(云服务器)
  3. 看域名解析有没有生效:ping www.example.com

总结

Nginx 安装配置的完整流程:

  1. 安装 Nginx:yum install nginx -y
  2. 启动并开机自启:systemctl start nginx && systemctl enable nginx
  3. 开放防火墙:80 和 443 端口
  4. 写站点配置:在 conf.d/ 下创建配置文件
  5. 检查并重载:nginx -t && systemctl reload nginx

Nginx 是 Web 服务器的入门必备,装完这个就能跑网站了。

遇到问题加QQ23979811 协助处理


emer 发布于  2026-10-5 07:52 

Nginx报502 Bad Gateway完整排查思路(PHP-FPM场景)

Nginx 出现 502 Bad Gateway 是最常见的报错之一,90% 的情况都是 PHP-FPM 出了问题。下面是完整的排查思路,按顺序一步步来,基本都能解决。

1. 先看 PHP-FPM 是否在运行

systemctl status php-fpm

如果显示 failed 或 inactive,直接重启:

systemctl restart php-fpm

注意:CentOS 7 一般是 php-fpm,Ubuntu 可能是 php7.4-fpm 之类的,看你装的版本。

2. 看 Nginx 错误日志(最关键)

tail -f /var/log/nginx/error.log

常见错误信息:

错误1:connect() failed (111: Connection refused) while connecting to upstream
说明 PHP-FPM 没启动,或者监听地址不对。

错误2:upstream timed out
PHP 脚本执行超时了,或者 PHP-FPM 进程不够用。

错误3:Primary script unknown
Nginx 配置里的 SCRIPT_FILENAME 路径不对,找不到 PHP 文件。

3. 检查 Nginx 配置是否正确

nginx -t

如果显示 test is successful 说明配置语法没问题。

重点检查 fastcgi_pass 这一行:

location ~ \.php$ {
    fastcgi_pass   127.0.0.1:9000;  # 或者 unix:/run/php-fpm/www.sock
    fastcgi_index  index.php;
    fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
    include        fastcgi_params;
}

常见问题:

  • fastcgi_pass 地址和 PHP-FPM 实际监听地址不一致
  • SCRIPT_FILENAME 路径写错了

4. 检查 PHP-FPM 监听地址

netstat -tlnp | grep php-fpm

或者:

ss -tlnp | grep php-fpm

看 PHP-FPM 是监听在 9000 端口还是 unix sock 文件,然后和 Nginx 配置里的 fastcgi_pass 对应上。

5. 检查 PHP-FPM 进程数是否够

看 PHP-FPM 配置:

vi /etc/php-fpm.d/www.conf

重点参数:

pm = dynamic
pm.max_children = 50
pm.start_servers = 20
pm.min_spare_servers = 10
pm.max_spare_servers = 30

如果访问量大,进程数不够就会 502。

6. 检查 PHP 错误日志

tail -f /var/log/php-fpm/www-error.log

有时候 PHP 代码本身报错,也会导致 502。

7. 其他常见原因

磁盘满了

df -h

内存不够

free -h

如果内存不足,PHP-FPM 进程会被杀掉,也会 502。

SELinux 没关
参考我之前的文章,关掉 SELinux 试试。

排查顺序总结

  1. 重启 PHP-FPM → 看能不能恢复
  2. 看 Nginx 错误日志 → 定位具体错误
  3. 检查 Nginx 配置 → fastcgi_pass 和 SCRIPT_FILENAME
  4. 检查 PHP-FPM 状态 → 监听地址、进程数
  5. 检查系统资源 → 磁盘、内存
  6. 检查 SELinux

遇到服务器、Nginx、MySQL 报错,可以加微信远程协助排查问题。


emer 发布于  2026-10-4 19:27 

Nginx 日志分析技巧

Nginx 日志分析技巧

Nginx 日志是排查问题、分析流量的重要工具。学会看日志,网站问题排查效率翻倍。

1. 日志位置

# 默认访问日志
/var/log/nginx/access.log

# 默认错误日志
/var/log/nginx/error.log

可以在 nginx.conf 里自定义:

access_log /var/log/nginx/www.access.log;
error_log /var/log/nginx/www.error.log;

2. 日志格式

默认日志格式:

127.0.0.1 - - [04/Oct/2026:10:00:00 +0800] "GET / HTTP/1.1" 200 612 "https://www.baidu.com/" "Mozilla/5.0..."

各字段含义:

  • IP 地址
  • 请求时间
  • 请求方法和路径
  • 状态码
  • 响应大小
  • 来源页面
  • User-Agent

3. 常用分析命令

# 查看访问量前10的IP
awk '{print $1}' access.log | sort | uniq -c | sort -nr | head 10

# 查看访问量前10的页面
awk '{print $7}' access.log | sort | uniq -c | sort -nr | head 10

# 查看状态码分布
awk '{print $9}' access.log | sort | uniq -c | sort -nr

# 查看 404 请求
grep ' 404 ' access.log

# 查看 502 错误
grep ' 502 ' access.log

4. 排查问题

排查 502 错误:

grep ' 502 ' access.log | tail 20

排查慢请求:
开启慢日志:

slow_request_log /var/log/nginx/slow.log;
slow_request_time 5s;

排查爬虫:

grep 'Baiduspider' access.log
grep 'Googlebot' access.log

5. 流量统计

# 今天总访问量
grep '04/Oct/2026' access.log | wc -l

# 今天总流量
grep '04/Oct/2026' access.log | awk '{sum+=$10} END {print sum/1024/1024 " MB"}'

# 每小时访问量
awk '{print $4}' access.log | cut -d: -f2 | uniq -c

6. 日志切割

日志太大要切割,用 logrotate:

# /etc/logrotate.d/nginx
/var/log/nginx/*.log {
    daily
    missingok
    rotate 30
    compress
    notifempty
    create 0640 nginx adm
    postrotate
        systemctl reload nginx
    endscript
}

7. 常用工具

  • GoAccess:实时日志分析工具
  • ELK:Elasticsearch + Logstash + Kibana
  • Zabbix:监控告警

总结

Nginx 日志分析核心:

  • 位置:/var/log/nginx/
  • 命令:awk + sort + uniq
  • 排查:看状态码、看慢请求
  • 切割:用 logrotate

学会这些,日常日志分析基本够用了。


emer 发布于  2026-10-4 11:08 

Nginx 负载均衡配置

Nginx 负载均衡配置实战

网站流量大了,单台服务器扛不住,就得用负载均衡。Nginx 做负载均衡很简单,几行配置就行。

1. 基本配置

http {
    upstream backend {
        server 192.168.1.101:80;
        server 192.168.1.102:80;
        server 192.168.1.103:80;
    }

    server {
        listen 80;
        server_name www.example.com;

        location / {
            proxy_pass http://backend;
        }
    }
}

默认是轮询(round robin),请求轮流分到三台服务器。

2. 四种分配策略

轮询(默认):一个一个来。

权重(weight):按比例分配,性能好的服务器多分担。

upstream backend {
    server 192.168.1.101 weight=3;
    server 192.168.1.102 weight=2;
    server 192.168.1.103 weight=1;
}

3:2:1 的比例,第一台分一半请求。

ip_hash:同一个 IP 固定分到同一台服务器,解决 session 问题。

upstream backend {
    ip_hash;
    server 192.168.1.101;
    server 192.168.1.102;
}

least_conn:最少连接数优先,分给当前最闲的服务器。

upstream backend {
    least_conn;
    server 192.168.1.101;
    server 192.168.1.102;
}

3. 健康检查

upstream backend {
    server 192.168.1.101 max_fails=3 fail_timeout=30s;
    server 192.168.1.102 max_fails=3 fail_timeout=30s;
}

一台服务器挂了,自动从列表里摘掉,恢复了再加回来。

4. 常用参数

  • max_fails:失败几次算挂了,默认1次
  • fail_timeout:挂了多久再重试,默认10秒
  • down:标记服务器下线,不分配请求
  • backup:备用服务器,其他都挂了才用

5. 完整示例

upstream backend {
    server 192.168.1.101 weight=3 max_fails=3 fail_timeout=30s;
    server 192.168.1.102 weight=2 max_fails=3 fail_timeout=30s;
    server 192.168.1.103 backup;
}

server {
    listen 80;
    location / {
        proxy_pass http://backend;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

总结

Nginx 负载均衡核心:

  • upstream 定义服务器组
  • 四种策略:轮询、权重、ip_hash、最少连接
  • 健康检查自动摘除故障节点
  • 生产环境用权重 + 健康检查就够了

搞懂这些,多台服务器集群就跑起来了。


emer 发布于  2026-10-4 10:51 

Nginx 反向代理配置

Nginx 反向代理配置详解

Nginx 反向代理是最常用的服务器配置之一,把请求转发给后端服务。本文讲清楚核心配置。

1. 基本配置

server {
    listen 80;
    server_name example.com;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

2. 传递真实IP

后端服务要拿到用户真实IP,需要配置:

proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

3. 负载均衡

多台后端服务器,用 upstream 做负载均衡:

upstream backend {
    server 127.0.0.1:8080 weight=1;
    server 127.0.0.1:8081 weight=2;
}

server {
    location / {
        proxy_pass http://backend;
    }
}

4. 超时设置

proxy_connect_timeout 60s;
proxy_read_timeout 60s;
proxy_send_timeout 60s;

5. 静态文件处理

静态文件直接由 Nginx 处理,不用转发给后端:

location ~* \.(js|css|png|jpg|gif)$ {
    root /data/www;
    expires 30d;
}

6. HTTPS 反向代理

server {
    listen 443 ssl;
    server_name example.com;

    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;

    location / {
        proxy_pass http://127.0.0.1:8080;
    }
}

总结

Nginx 反向代理的核心就是 proxy_pass,配上 proxy_set_header 传递必要信息,再加上超时和静态文件处理,基本够用了。


emer 发布于  2026-10-4 10:42 

Nginx 日志分析技巧

Nginx 日志分析常用命令

Nginx 日志是排查问题、分析流量的重要工具。掌握几个常用命令,线上排查效率翻倍。

1. 查看访问量

# 总请求数
wc -l access.log

# 今天的请求数
grep "04/Oct/2026" access.log | wc -l

2. 分析 IP 访问量

# 访问最多的前10个IP
awk '{print $1}' access.log | sort | uniq -c | sort -nr | head -10

3. 分析 URL 访问量

# 访问最多的前10个URL
awk '{print $7}' access.log | sort | uniq -c | sort -nr | head -10

4. 分析状态码

# 统计各状态码数量
awk '{print $9}' access.log | sort | uniq -c | sort -nr

# 404错误数量
grep " 404 " access.log | wc -l

5. 分析流量

# 总流量
awk '{sum += $10} END {print sum/1024/1024 " MB"}' access.log

6. 实时监控

# 实时查看最新日志
tail -f access.log

# 实时查看502错误
tail -f access.log | grep " 502 "

7. 查找慢请求

# 响应时间超过1秒的请求
awk '$NF > 1' access.log | head -10

8. 排查爬虫

# 百度爬虫访问量
grep "Baiduspider" access.log | wc -l

总结

Nginx 日志分析主要靠 awk + sort + uniq 组合,掌握这几个命令,日常排查基本够用。复杂分析可以用 GoAccess 等可视化工具。


emer 发布于  2026-10-4 10:31 
'); })();