Nginx 配置HTTPS证书
Nginx 配置HTTPS证书
现在网站都要HTTPS,配置证书是必备技能。
1. 为什么要HTTPS
- 加密传输,防窃听
- 浏览器安全标识
- SEO 排名加分
- 现在主流浏览器都要求HTTPS
2. 证书文件
一般有两个文件:
.crt:证书文件.key:私钥文件
# 证书文件放在这里
/etc/nginx/ssl/
├── example.com.crt
└── example.com.key
3. 基本HTTPS配置
server {
listen 443 ssl;
server_name example.com;
# 证书配置
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
# 其他配置
location / {
root /var/www/html;
index index.html;
}
}
4. HTTP 跳转 HTTPS
# HTTP 重定向到 HTTPS
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}
5. 优化配置
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;
# 优化SSL配置
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
# 加密套件
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers off;
# HSTS
add_header Strict-Transport-Security "max-age=63072000" always;
}
6. 检查配置
# 检查配置语法
nginx -t
# 重载配置
nginx -s reload
7. 证书申请
免费证书:
- Let's Encrypt(用 certbot 申请)
- 阿里云免费证书
- 腾讯云免费证书
certbot 申请:
# 安装 certbot
yum install certbot python3-certbot-nginx
# 自动申请并配置
certbot --nginx -d example.com
自动续期:
# 测试续期
certbot renew --dry-run
# 加入定时任务
0 3 * * * certbot renew --quiet
8. 常见问题
1)证书不生效
- 检查证书路径对不对
- 检查文件权限
- 重载 Nginx
2)浏览器提示不安全
- 证书过期了
- 域名不匹配
- 中间证书没装全
3)HTTPS 访问慢
- 开启 HTTP/2
- 优化 SSL 会话缓存
4)证书续期失败
- 检查域名解析
- 检查80端口是否通
- 手动运行 certbot 看报错
9. 证书有效期
- 免费证书一般 3 个月
- 要设置自动续期
- 不然到期网站就挂了
10. 生产建议
1)强制 HTTPS
- HTTP 全部 301 跳转
- 开启 HSTS
2)开启 HTTP/2
- listen 443 ssl http2
- 提升访问速度
3)定期检查证书
- 监控证书到期时间
- 提前续期
4)中间证书
- 有些证书要把中间证书合并
- 不然浏览器不信任
总结
Nginx 配置HTTPS要点:
- 配置证书和私钥路径
- HTTP 跳转 HTTPS
- 开启 HTTP/2
- 优化 SSL 会话缓存
- 用 certbot 免费申请
- 设置自动续期
- 定期检查证书有效期
- 开启 HSTS
- 注意中间证书问题
HTTPS 是网站标配,一定要配置好。
PHP 过滤和验证数据
PHP 过滤和验证数据
用户输入不可信,必须过滤验证,这是Web开发的基本功。
1. 为什么要过滤验证
- 防止 SQL 注入
- 防止 XSS 攻击
- 保证数据格式正确
- 防止脏数据入库
2. filter_var 函数
PHP 内置过滤器,很好用。
验证邮箱
$email = 'test@example.com';
if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
echo '邮箱格式正确';
} else {
echo '邮箱格式错误';
}
验证数字
$age = '20abc';
if (filter_var($age, FILTER_VALIDATE_INT)) {
echo '是整数';
}
验证URL
$url = 'https://example.com';
if (filter_var($url, FILTER_VALIDATE_URL)) {
echo 'URL格式正确';
}
验证IP
$ip = '192.168.1.1';
if (filter_var($ip, FILTER_VALIDATE_IP)) {
echo 'IP格式正确';
}
3. filter_input 获取并过滤
从 GET/POST 获取并过滤:
// 获取并过滤GET参数
$id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT);
// 获取并过滤POST参数
$email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
4. 过滤输入
过滤HTML标签
$str = '<script>alert(1)</script>你好';
// 去除HTML标签
echo strip_tags($str);
// HTML转义(安全输出)
echo htmlspecialchars($str);
过滤特殊字符
$str = "hello ' world";
// 转义单引号
echo addslashes($str);
5. 常用验证场景
验证手机号
function checkPhone($phone) {
return preg_match('/^1[3-9]\d{9}$/', $phone);
}
if (checkPhone('13800138000')) {
echo '手机号正确';
}
验证身份证
function checkIdCard($idcard) {
return preg_match('/^\d{17}[\dXx]$/', $idcard);
}
验证用户名
// 4-16位,字母数字下划线
function checkUsername($name) {
return preg_match('/^\w{4,16}$/', $name);
}
6. 安全建议
1)所有外部输入都要验证
- GET、POST、COOKIE
- 不要相信任何用户输入
2)用预处理防SQL注入
- 不要自己拼接SQL
- 用 PDO 预处理
3)输出时转义
- 输出到HTML要 htmlspecialchars
- 防止 XSS 攻击
4)白名单验证
- 只接受允许的值
- 不要用黑名单
7. 完整示例
// 接收用户注册信息
$username = trim($_POST['username']);
$email = trim($_POST['email']);
$age = (int)$_POST['age'];
$errors = [];
// 验证用户名
if (!preg_match('/^\w{4,16}$/', $username)) {
$errors[] = '用户名4-16位字母数字下划线';
}
// 验证邮箱
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$errors[] = '邮箱格式错误';
}
// 验证年龄
if ($age < 18 || $age > 100) {
$errors[] = '年龄必须18-100岁';
}
if (empty($errors)) {
// 验证通过,入库
echo '注册成功';
} else {
print_r($errors);
}
总结
PHP 过滤和验证数据要点:
- 所有用户输入都不可信
- 用 filter_var 验证格式
- 用 filter_input 获取并过滤
- 输出用 htmlspecialchars 防XSS
- 用预处理防SQL注入
- 用正则验证手机号、用户名
- 白名单验证比黑名单好
- 不要自己拼接SQL字符串
做Web开发,安全永远第一位。
PHP 生成随机密码
PHP 生成随机密码
注册、重置密码功能经常要生成随机密码,这几种方法要会。
1. 简单随机字符串
function generatePassword($length = 8) {
$chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
$password = '';
for ($i = 0; $i < $length; $i++) {
$password .= $chars[mt_rand(0, strlen($chars) - 1)];
}
return $password;
}
// 生成8位密码
echo generatePassword(8);
2. 带特殊字符的密码
function generateStrongPassword($length = 12) {
$lower = 'abcdefghijklmnopqrstuvwxyz';
$upper = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
$numbers = '0123456789';
$special = '!@#$%^&*()';
$all = $lower . $upper . $numbers . $special;
$password = '';
// 确保至少包含每种字符
$password .= $lower[mt_rand(0, strlen($lower) - 1)];
$password .= $upper[mt_rand(0, strlen($upper) - 1)];
$password .= $numbers[mt_rand(0, strlen($numbers) - 1)];
$password .= $special[mt_rand(0, strlen($special) - 1)];
// 剩余随机
for ($i = 4; $i < $length; $i++) {
$password .= $all[mt_rand(0, strlen($all) - 1)];
}
// 打乱顺序
return str_shuffle($password);
}
echo generateStrongPassword(12);
3. 更安全的 random_bytes
PHP 7+ 推荐用 random_bytes,更安全:
function generateSecurePassword($length = 12) {
$chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*';
$max = strlen($chars) - 1;
$password = '';
for ($i = 0; $i < $length; $i++) {
$password .= $chars[random_int(0, $max)];
}
return $password;
}
echo generateSecurePassword(16);
4. 生成验证码
function generateCode($length = 6) {
$chars = '0123456789';
$code = '';
for ($i = 0; $i < $length; $i++) {
$code .= $chars[random_int(0, 9)];
}
return $code;
}
// 6位数字验证码
echo generateCode(6);
5. 生成随机 Token
function generateToken($length = 32) {
return bin2hex(random_bytes($length / 2));
}
// 32位随机token
echo generateToken();
6. 安全建议
1)用 random_int 不用 mt_rand
- random_int 是密码安全随机数
- mt_rand 不够安全
2)密码长度
- 普通密码:8-12位
- 强密码:12位以上
- Token:32位以上
3)密码强度
- 大小写字母+数字+特殊字符
- 避免纯数字或纯字母
4)不要自己写随机算法
- 用 PHP 内置函数
- 不要用时间戳做随机种子
总结
PHP 生成随机密码要点:
- 简单密码用 mt_rand 拼接
- 强密码包含大小写+数字+特殊字符
- 安全密码用 random_int
- Token 用 bin2hex(random_bytes())
- 验证码用纯数字
- 推荐用 PHP 7+ 的 random_int
- 不要自己写随机算法
做用户系统,生成密码和验证码是必备功能。
PHP 上传文件处理
PHP 上传文件处理
文件上传是 Web 开发常见功能,安全处理很重要。
1. HTML 表单
<form method="post" action="upload.php" enctype="multipart/form-data">
<input type="file" name="file">
<button type="submit">上传</button>
</form>
注意:必须加 enctype="multipart/form-data"。
2. PHP 接收文件
// $_FILES 接收上传文件
$file = $_FILES['file'];
// 文件信息
$name = $file['name']; // 文件名
$tmp = $file['tmp_name']; // 临时路径
$size = $file['size']; // 文件大小
$error = $file['error']; // 错误码
$type = $file['type']; // MIME类型
3. 错误码说明
- UPLOAD_ERR_OK (0): 上传成功
- UPLOAD_ERR_INI_SIZE (1): 超过 php.ini 限制
- UPLOAD_ERR_FORM_SIZE (2): 超过表单限制
- UPLOAD_ERR_PARTIAL (3): 部分上传
- UPLOAD_ERR_NO_FILE (4): 没有文件
4. 完整上传代码
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$file = $_FILES['file'];
// 检查错误
if ($file['error'] !== UPLOAD_ERR_OK) {
exit('上传失败');
}
// 检查大小(限制2M)
if ($file['size'] > 2 * 1024 * 1024) {
exit('文件太大');
}
// 允许的扩展名
$allowExt = ['jpg', 'png', 'gif'];
$ext = pathinfo($file['name'], PATHINFO_EXTENSION);
if (!in_array($ext, $allowExt)) {
exit('不允许的文件类型');
}
// 生成新文件名
$newName = uniqid() . '.' . $ext;
$uploadDir = 'uploads/';
// 移动文件
if (move_uploaded_file($file['tmp_name'], $uploadDir . $newName)) {
echo '上传成功';
} else {
echo '保存失败';
}
}
5. php.ini 配置
; 上传最大文件大小
upload_max_filesize = 2M
; 表单最大提交大小
post_max_size = 8M
; 允许上传
file_uploads = On
; 临时目录
upload_tmp_dir = /tmp
6. 安全注意事项
1)不要用原文件名
- 防止覆盖文件和路径穿越
- 用 uniqid 生成新文件名
2)验证文件类型
- 不要只看扩展名
- 用 finfo 检查 MIME 类型
$finfo = new Finfo(FILEINFO_MIME_TYPE);
$mime = $finfo->file($file['tmp_name']);
3)上传目录不可执行
- 上传目录关闭 PHP 执行
- 防止上传木马
4)重命名文件
- 不要保留用户上传的文件名
- 防止覆盖和目录穿越攻击
7. 常见问题
1)上传失败,$_FILES 为空
- 检查表单是否有 enctype
- 检查 post_max_size 够不够大
2)move_uploaded_file 失败
- 检查目录权限
- 检查目录是否存在
3)大文件上传超时
- 修改 max_execution_time
- 修改 memory_limit
总结
PHP 文件上传要点:
- 表单必须加 enctype
- 用 $_FILES 接收文件
- 检查错误码和文件大小
- 验证文件类型
- 重命名文件防止安全问题
- 上传目录关闭执行权限
- 注意 php.ini 配置
做上传功能,安全永远第一位。
Linux 防火墙配置详解
Linux 防火墙配置详解
服务器安全第一步就是防火墙,学会配置很重要。
1. firewalld(CentOS 7+)
查看状态:
systemctl status firewalld
开启/关闭:
# 开启
systemctl start firewalld
# 关闭
systemctl stop firewalld
# 开机自启
systemctl enable firewalld
2. 开放端口
开放单个端口:
firewall-cmd --zone=public --add-port=80/tcp --permanent
开放多个端口:
firewall-cmd --zone=public --add-port=80-90/tcp --permanent
重新加载生效:
firewall-cmd --reload
3. 查看端口
# 查看所有开放端口
firewall-cmd --list-ports
# 查看某个端口是否开放
firewall-cmd --query-port=80/tcp
4. 关闭端口
firewall-cmd --zone=public --remove-port=80/tcp --permanent
firewall-cmd --reload
5. iptables(旧版)
查看规则:
iptables -L -n
开放端口:
iptables -I INPUT -p tcp --dport 80 -j ACCEPT
保存规则:
service iptables save
6. 常用端口
# 常用端口
22 SSH
80 HTTP
443 HTTPS
3306 MySQL
6379 Redis
8080 Tomcat
7. 常见问题
1)端口开了还是访问不了:
- 检查云服务商安全组
- 检查服务器内部防火墙
2)远程连接不上:
- 检查 22 端口是否开放
- 检查 sshd 是否启动
总结
Linux 防火墙要点:
- firewalld 管理端口
- --permanent 永久生效
- --reload 重新加载
- 记得开放安全组
- 常用端口按需开放
做运维,防火墙是基本功。
Nginx HTTPS 配置详解
Nginx HTTPS 配置详解
现在网站都要上 HTTPS,Nginx 配置 SSL 很简单。
1. 准备证书
免费证书可以用:
- Let's Encrypt
- 阿里云免费证书
- 腾讯云免费证书
下载后有两个文件:
- 证书文件:xxx.pem
- 私钥文件:xxx.key
2. 基础配置
server {
listen 443 ssl;
server_name www.example.com;
ssl_certificate /etc/nginx/ssl/xxx.pem;
ssl_certificate_key /etc/nginx/ssl/xxx.key;
location / {
root /www/wwwroot/html;
index index.html;
}
}
3. HTTP 跳转 HTTPS
# HTTP 重定向到 HTTPS
server {
listen 80;
server_name www.example.com;
return 301 https://$server_name$request_uri;
}
4. 优化配置
server {
listen 443 ssl http2;
server_name www.example.com;
ssl_certificate /etc/nginx/ssl/xxx.pem;
ssl_certificate_key /etc/nginx/ssl/xxx.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;
location / {
root /www/wwwroot/html;
index index.html;
}
}
5. 验证配置
# 检查配置是否正确
nginx -t
# 重载配置
nginx -s reload
6. 常见问题
1)证书不生效:
- 检查证书路径对不对
- 检查证书文件名
- 重载 Nginx
2)浏览器提示不安全:
- 证书域名不对
- 证书过期了
- 缺少中间证书
3)HTTP 打不开:
- 检查 80 端口是否放行
- 检查防火墙
7. Let's Encrypt 免费证书
用 certbot 自动申请:
# 安装
yum install certbot python3-certbot-nginx
# 自动申请并配置
certbot --nginx -d www.example.com
# 自动续期
certbot renew
总结
Nginx HTTPS 配置要点:
- 443 端口监听 SSL
- 配置证书和私钥路径
- HTTP 跳转 HTTPS
- 开启 http2 提升性能
- 定期续期证书
现在做网站,HTTPS 是标配。
Nginx配置访问密码,限制后台访问
前言
网站后台地址公开,谁都能访问,容易被别人扫到然后暴力破解。给后台加一层 Nginx 访问密码,多一道防护。
什么是访问密码
就是访问某个目录前,浏览器先弹一个登录框,输入用户名密码才能进去。和网站本身的登录是两回事。
第一步:生成密码文件
用 htpasswd 命令生成密码文件:
htpasswd -c /etc/nginx/.htpasswd admin
第一次加 -c 创建文件,输入两次密码。
不加 -c 是追加新用户:
htpasswd /etc/nginx/.htpasswd user2
如果没有 htpasswd 命令,先装:
yum install -y httpd-tools
第二步:Nginx 配置
给后台目录加密码:
location /admin/ {
auth_basic "Admin Login";
auth_basic_user_file /etc/nginx/.htpasswd;
}
完整配置示例
server {
listen 80;
server_name www.example.com;
root /var/www/html;
index index.php index.html;
# 后台加密码
location /admin/ {
auth_basic "Admin Login";
auth_basic_user_file /etc/nginx/.htpasswd;
# 后台本身的 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;
}
}
# 前台正常访问
location / {
try_files $uri $uri/ =404;
}
}
重载生效
nginx -t
nginx -s reload
常见坑
坑1:.htpasswd 文件权限不对
Nginx 读不到密码文件。
解决: 确保文件权限是 644,属主是 www:
chown www:www /etc/nginx/.htpasswd
chmod 644 /etc/nginx/.htpasswd
坑2:PHP 文件不弹密码
访问 /admin/index.php 直接就进了,没弹密码框。
原因: PHP 的 location 把请求拦截了,没走 auth_basic。
解决: 把 auth_basic 配置放到 PHP 的 location 里,或者放到 server 级别。
坑3:忘记密码
自己把密码忘了。
解决: 重新生成:
htpasswd -b /etc/nginx/.htpasswd admin 新密码
坑4:密码文件放网站目录里
把 .htpasswd 放在了网站根目录下,别人能直接下载。
解决: 密码文件放在网站目录外面,比如 /etc/nginx/ 下面。
总结
两步搞定:
htpasswd生成密码文件- Nginx 加
auth_basic配置
记住: 密码文件别放网站目录里,放在外面安全。
遇到问题加QQ23979811 协助处理
Nginx防盗链配置,防止图片被别人盗用
前言
网站的图片被别人盗链了,他的网站直接用你的图片地址,流量全从你服务器走,白白消耗带宽。Nginx 可以配置防盗链,防止这种情况。
什么是盗链
就是别人在自己网站里直接引用你服务器上的图片。用户看他的网站,实际图片是从你服务器加载的。
防盗链原理
Nginx 检查请求头里的 Referer 字段,看是从哪个页面过来的。如果不是自己网站的 Referer,就拒绝或者返回一张提示图。
基础配置
location ~* \.(jpg|png|gif|jpeg)$ {
valid_referers none blocked www.example.com example.com;
if ($invalid_referer) {
return 403;
}
}
解释:
valid_referers:允许哪些来源访问none:允许直接输入地址访问blocked:允许伪装的 Refererwww.example.com:自己的域名
配置示例
server {
listen 80;
server_name www.example.com;
root /var/www/html;
index index.html;
# 防盗链
location ~* \.(jpg|png|gif|jpeg|webp)$ {
valid_referers none blocked www.example.com example.com *.example.com;
if ($invalid_referer) {
return 403;
}
}
}
替换成提示图
不想直接 403,可以返回一张"禁止盗链"的提示图:
location ~* \.(jpg|png|gif|jpeg)$ {
valid_referers none blocked www.example.com example.com;
if ($invalid_referer) {
rewrite ^/.*\.(jpg|png|gif)$ /no-hotlink.png last;
}
}
这样别人盗链就显示一张提示图。
常见坑
坑1:自己网站图片也加载不出来
配了防盗链,自己网站的图片也打不开了。
原因: valid_referers 里没写全自己的域名。
解决: 把 http 和 https 的域名都写上:
valid_referers none blocked www.example.com example.com;
坑2:搜索引擎图片也被挡了
百度图片搜不到你的图片了。
原因: 防盗链把搜索引擎也挡了。
解决: 加上搜索引擎的 Referer:
valid_referers none blocked www.example.com example.com *.baidu.com *.google.com;
坑3:CDN 后面防盗链不生效
用了 CDN,防盗链配置不生效。
原因: 请求经过 CDN,Referer 是 CDN 的。
解决: CDN 那边配置防盗链,或者把 CDN 的 Referer 加到白名单。
坑4:微信里打开图片不显示
在微信里打开自己的文章,图片显示不出来。
原因: 微信的 Referer 被挡了。
解决: 加上微信的 Referer:
valid_referers none blocked www.example.com example.com *.weixin.qq.com;
总结
防盗链就三行配置:
valid_referers none blocked www.example.com example.com;
if ($invalid_referer) {
return 403;
}
记住: 配完防盗链,先测试一下自己网站图片能不能正常打开。
遇到问题加QQ23979811 协助处理
Nginx限制请求速率,防止CC攻击配置
前言
网站被 CC 攻击,一个人疯狂刷页面,服务器直接卡死。Nginx 自带请求限速功能,能防止这种恶意刷接口、刷页面的行为。
什么是 CC 攻击
CC 攻击就是模拟正常用户,疯狂访问网站,把服务器资源耗尽,正常用户打不开网站。
Nginx 限速配置
用 limit_req_zone 定义限速规则,用 limit_req 应用到具体位置。
第一步:定义限速规则
在 http 块里(一般在 nginx.conf 或 conf.d 目录的配置文件里):
# 定义一个叫 "allips" 的区域,按 IP 限速,每秒允许 10 个请求
limit_req_zone $binary_remote_addr zone=allips:10m rate=10r/s;
解释:
$binary_remote_addr:按客户端 IP 限速zone=allips:10m:定义一个叫 allips 的内存区域,10M 大小rate=10r/s:每秒允许 10 个请求
第二步:在具体位置应用
server {
listen 80;
server_name www.example.com;
root /var/www/html;
index index.php index.html;
# 应用限速
limit_req zone=allips burst=20 nodelay;
location / {
try_files $uri $uri/ =404;
}
}
burst=20 意思是:允许突发 20 个请求排队,超过就拒绝。
完整配置示例
http {
# 定义限速区域
limit_req_zone $binary_remote_addr zone=allips:10m rate=10r/s;
server {
listen 80;
server_name www.example.com;
root /var/www/html;
index index.php index.html;
# 应用限速
limit_req zone=allips burst=20 nodelay;
location / {
try_files $uri $uri/ =404;
}
}
}
常用限速参数
| 参数 | 说明 |
|---|---|
rate=10r/s |
每秒 10 个请求 |
rate=30r/m |
每分钟 30 个请求 |
burst=20 |
允许 20 个突发请求排队 |
nodelay |
突发请求不延迟,立即处理 |
只限制某个接口
不想全站限速,只想限制某个接口?
location /api/login {
limit_req zone=allips burst=5 nodelay;
}
这样只有登录接口限速,其他接口不限。
常见坑
坑1:限速太严,正常用户也被拦了
设了 rate=1r/s,用户点一下按钮就 503。
解决: 把速率调宽一点,比如 rate=10r/s,burst=20。
坑2:用了 CDN,限速按 CDN IP 算了
用了 CDN,所有请求都从 CDN 过来,Nginx 看到的都是 CDN 的 IP,把 CDN 给限了。
解决: 用真实客户端 IP 来限速:
set_real_ip_from CDN的IP段;
real_ip_header X-Forwarded-For;
limit_req_zone $realip zone=allips:10m rate=10r/s;
坑3:报错 503 Too Many Requests
用户访问提示 503。
原因: 请求太快,被限速了。
解决: 调大 burst 和 rate。
坑4:limit_req_zone 写在 server 块里
把 limit_req_zone 写在 server 块里了,Nginx 报错。
原因: limit_req_zone 只能写在 http 块里。
解决: 挪到 nginx.conf 的 http 块里。
总结
防 CC 攻击就这三步:
- http 块里定义
limit_req_zone - server 块里加
limit_req nginx -s reload重载
记住: 限速别太严,正常用户别给拦了。
遇到问题加QQ23979811 协助处理
Linux 防火墙配置详解
Linux 防火墙配置详解
服务器安全第一关就是防火墙,配置错了就远程连不上了,这篇讲常用配置。
1. firewalld(CentOS7 默认)
查看状态:
# 查看防火墙状态
firewall-cmd --state
# 查看开放的端口
firewall-cmd --list-ports
# 查看开放的服务
firewall-cmd --list-services
开放端口:
# 开放 80 端口
firewall-cmd --permanent --add-port=80/tcp
# 开放 443 端口
firewall-cmd --permanent --add-port=443/tcp
# 开放多个端口范围
firewall-cmd --permanent --add-port=8000-9000/tcp
# 重载生效
firewall-cmd --reload
关闭端口:
# 关闭 80 端口
firewall-cmd --permanent --remove-port=80/tcp
# 重载
firewall-cmd --reload
开放服务:
# 开放 nginx 服务
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
# 重载
firewall-cmd --reload
2. iptables(老系统常用)
查看规则:
iptables -L -n
开放端口:
# 开放 22 端口
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# 开放 80 端口
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
# 保存规则
service iptables save
3. 常用安全配置
只允许指定 IP 访问 SSH:
# 只允许 192.168.1.100 访问 22 端口
firewall-cmd --permanent --add-rich-rule="rule family='ipv4' source address='192.168.1.100' port protocol='tcp' port='22' accept"
# 拒绝其他所有 IP
firewall-cmd --permanent --remove-service=ssh
firewall-cmd --reload
4. 常用端口说明
| 端口 | 服务 |
|---|---|
| 22 | SSH 远程连接 |
| 80 | HTTP 网站 |
| 443 | HTTPS 网站 |
| 3306 | MySQL 数据库 |
| 6379 | Redis 缓存 |
| 8080 | 应用服务 |
5. 常见问题
1)SSH 连不上了:
- 检查防火墙是不是把 22 端口关了
- 用控制台登录服务器重新开放
2)网站打不开:
- 检查 80/443 端口开了没
- 重载防火墙生效
3)数据库连不上:
- 3306 端口别对公网开放
- 只允许本地或指定 IP 访问
总结
防火墙配置记住三点:
- 先开 22 端口,不然自己都连不上
- 网站开 80 和 443
- 数据库别对外网开放
安全第一,别图省事直接关防火墙。
Linux 防火墙配置技巧
Linux 防火墙配置技巧
服务器安全第一步就是配好防火墙,只开需要的端口,其他全关。
1. firewalld(CentOS 7+ 默认)
# 查看状态
firewall-cmd --state
# 查看已开放端口
firewall-cmd --list-ports
# 开放端口
firewall-cmd --permanent --add-port=80/tcp
firewall-cmd --permanent --add-port=443/tcp
# 开放多个端口
firewall-cmd --permanent --add-port=8000-9000/tcp
# 开放指定 IP 访问
firewall-cmd --permanent --add-rich-rule="rule family='ipv4' source address='192.168.1.100' port protocol='tcp' port=3306 accept"
# 重载配置(必须重载才生效)
firewall-cmd --reload
# 删除端口
firewall-cmd --permanent --remove-port=8080/tcp
2. ufw(Ubuntu 默认)
# 查看状态
ufw status
# 开启防火墙
ufw enable
# 允许 SSH
ufw allow 22
# 允许 80 和 443
ufw allow 80
ufw allow 443
# 允许指定 IP
ufw allow from 192.168.1.100 to any port 3306
# 拒绝某个 IP
ufw deny from 1.2.3.4
# 删除规则
ufw delete allow 8080
3. iptables(经典)
# 查看规则
iptables -L -n
# 允许 22 端口
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# 允许 80 端口
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
# 允许本地回环
iptables -A INPUT -i lo -j ACCEPT
# 允许已建立的连接
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# 默认拒绝其他
iptables -P INPUT DROP
# 保存规则(CentOS)
service iptables save
4. 安全建议
- 只开必要端口:SSH、HTTP、HTTPS,其他全关
- SSH 改端口:不要用默认 22,改成其他端口
- 限制 SSH 登录 IP:只允许你的 IP 登录 SSH
- 数据库不对外暴露:MySQL、Redis 只允许本地访问
- 定期查看日志:/var/log/secure 看有没有暴力破解
5. 常用端口速查
- 22:SSH
- 80:HTTP
- 443:HTTPS
- 3306:MySQL
- 6379:Redis
- 8080:应用端口
总结
Linux 防火墙核心:
- CentOS 用 firewalld
- Ubuntu 用 ufw
- 只开必要端口
- 数据库不对外暴露
- SSH 限制 IP 访问
配好防火墙,服务器安全提升一大截。
PHP 安全最佳实践
PHP 开发必须注意的安全问题
PHP 开发最容易出安全问题,几个常见坑一定要避开。
1. SQL 注入
最常见的安全漏洞。用户输入拼接到 SQL 里,被注入恶意 SQL。
解决方案:用预处理语句
// 不要这样
$sql = "SELECT * FROM users WHERE id = " . $_GET['id'];
// 要这样
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = ?");
$stmt->execute([$_GET['id']]);
2. XSS 跨站脚本
用户输入直接输出到页面,被注入恶意 JS。
解决方案:输出时转义
echo htmlspecialchars($user_input);
3. CSRF 跨站请求伪造
别人伪造你的请求操作。
解决方案:加 Token 验证
// 表单里加 Token
<input type="hidden" name="csrf_token" value="<?php echo $_SESSION['token']; ?>">
// 后端验证
if ($_POST['csrf_token'] !== $_SESSION['token']) {
die('CSRF 攻击');
}
4. 文件上传漏洞
用户上传 PHP 文件,直接拿到 webshell。
解决方案:
- 限制文件类型
- 重命名文件
- 上传目录不执行 PHP
5. 密码明文存储
数据库被拖库,密码全泄露。
解决方案:用 password_hash
$hash = password_hash($password, PASSWORD_DEFAULT);
// 验证
password_verify($password, $hash);
6. 错误信息泄露
生产环境把报错直接展示给用户,暴露路径和代码。
解决方案:关闭 display_errors
display_errors = Off
log_errors = On
总结
PHP 安全的核心:用户输入都不可信,所有输出都要转义,数据库操作用预处理。安全开发意识比工具更重要。