分类 默认分类 下的文章

nginx使用limit_req模块
nginx使用limit_req模块时,如果使用CDN的话,能按真实的用户IP来限流吗?如果使用的是CDN的IP,从而把CDN直接限流了,影响正常访问:

http_limit_req 模块文档:
https://nginx.org/en/docs/http/ngx_http_limit_req_module.html

limit_req 模块配置实例:

http {

        limit_conn_zone $binary_remote_addr zone=perip:10m;
    limit_conn_zone $server_name zone=perserver:10m;

server {
...
    limit_conn perserver 300;
    limit_conn perip 25;
    limit_rate 512k;

...
}

}

在使用 Nginx 的 limit_req 模块时,如果你使用了 CDN,默认情况下限流是基于 CDN 的 IP 地址的,而不是真实用户的 IP 地址。这是因为 CDN 会将请求转发到你的 Nginx 服务器时,源 IP 地址通常是 CDN 的 IP。

要按真实用户 IP 限流,你需要配置 Nginx 以正确识别用户的真实 IP 地址。通常,这可以通过设置 real_ip 模块来实现。你需要确保 Nginx 从 CDN 请求头(如 X-Forwarded-For 或 X-Real-IP)中提取真实用户 IP 地址,并将其用于限流。

http_realip 模块文档:
https://nginx.org/en/docs/http/ngx_http_realip_module.html
确保nginx有这个模块,查看命令(包含有 --with-http_realip_module 字样):

nginx -V

nginx version: nginx/1.18.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC) 
built with OpenSSL 1.1.1g  21 Apr 2020
TLS SNI support enabled
configure arguments: --user=www --group=www --prefix=/www/server/nginx --add-module=srclib/ngx_devel_kit --add-module=srclib/lua_nginx_module --add-module=srclib/ngx_cache_purge --add-module=srclib/nginx-sticky-module --with-openssl=srclib/openssl --with-pcre=srclib/pcre-8.43 --with-http_v2_module --with-stream --with-stream_ssl_module --with-stream_ssl_preread_module --with-http_stub_status_module --with-http_ssl_module --with-http_image_filter_module --with-http_gzip_static_module --with-http_gunzip_module --with-ipv6 --with-http_sub_module --with-http_flv_module --with-http_addition_module --with-http_realip_module --with-http_mp4_module --with-ld-opt=-Wl,-E --with-cc-opt=-Wno-error --with-http_dav_module --add-module=srclib/nginx-dav-ext-module

示例配置

set_real_ip_from  192.168.1.0/24;
set_real_ip_from  192.168.2.1;
set_real_ip_from  2001:0db8::/32;
real_ip_header    X-Forwarded-For;
real_ip_recursive on;

匹配项说明:

  • set_real_ip_from 指定了哪些 IP 地址可以作为信任的代理来源,通常可以设置为 CDN 提供的 IP 范围。 0.0.0.0/0; # 允许所有 IP 的 CDN 代理
  • real_ip_header 设置了使用哪个请求头来获取真实 IP 地址。
  • real_ip_recursive 使 Nginx 从请求头链中递归提取真实 IP 地址。

嵌入变量
$realip_remote_addr
保留原始客户端地址 (1.9.7)
$realip_remote_port
保留原始客户端端口 (1.11.0)

常见配置实例:

http {
    # 信任的代理 IP 范围
    set_real_ip_from 192.168.0.0/24;  # 负载均衡器或 CDN 的 IP 范围
    set_real_ip_from 10.0.0.0/8;
    real_ip_header X-Forwarded-For;
    real_ip_recursive on;

    server {
        location / {
            # 其他配置
        }
    }
}

当使用 real_ip 模块时,$remote_addr 变量将反映真实的客户端 IP 地址,而不是中间代理或负载均衡器的 IP 地址。这是因为 real_ip 模块会根据你配置的规则修改 $remote_addr 变量的值。

**如何工作**
没有代理的情况: $remote_addr 直接表示客户端的 IP 地址,无需 real_ip 模块的干预。

有代理或 CDN 的情况: 当你配置了 real_ip 模块并正确设置了信任的代理 IP 地址和请求头(如 X-Forwarded-For),Nginx 会从这些请求头中提取真实的客户端 IP 地址,并将其赋值给 $remote_addr。这使得 $remote_addr 始终反映真实的客户端 IP,而不是代理或负载均衡器的 IP。
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;

另一种得到真实IP的方法

  map $http_x_forwarded_for  $clientRealIp {
                ""      $remote_addr;
                ~^(?P<firstAddr>[0-9\.]+),?.*$  $firstAddr;
        }

$clientRealIp就得到了真实IP

进制和整型
整型值可以使用十进制,十六进制,八进制或二进制表示,前面可以加上可选的符号(- 或者 +)。

注意:要使用八进制表达,数字前必须加上 0。要使用十六进制表达,数字前必须加上 0x。要使用二进制表达,数字前必须加上 0b。

<?php
$a = 1234; // 十进制数
$b = -123; // 负数
$c = 0123; // 八进制数 (等于十进制 83)
$d = 0x1A; // 十六进制数 (等于十进制 26)
?>

整数溢出
如果给定的一个数超出了 integer 的范围,将会被解释为 float。同样如果执行的运算结果超出了 integer 范围,也会返回 float。
对于32位的操作系统,最大的整型是2147483647,即2的31次方,最小为-2的31次方。本次实验环境:PHP 7.2,Ubuntu 14.04。

<?php

$a = 123445566;
$b = 9223372036854775807;
$c = 9223372036854775808;
$d = 50000000000000 * 1000000;

var_dump($a);
var_dump($b);
var_dump($c);
var_dump($d);

执行得到结果为:

int(123445566)
int(9223372036854775807)
float(9.2233720368548E+18)
float(5.0E+19)

ubuntu版本是22.04.3 安装的 mysql-server 是 mysql 8.0

默认账号密码:

sudo cat /etc/mysql/debian.cnf

[client]
host     = localhost
user     = debian-sys-maint
password = xezrqqkk9Dely8hv
socket   = /var/run/mysqld/mysqld.sock
[mysql_upgrade]
host     = localhost
user     = debian-sys-maint
password = xezrqqkk9Dely8hv
socket   = /var/run/mysqld/mysqld.sock

连接数据库,并修改密码(账户密码替换成你自己的):

mysql -u debian-sys-maint -p xezrqqkk9Dely8hv
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '123456';FLUSH PRIVILEGES;

报错问题:

ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)

修改mysql配置文件,原本是空的只有[mysql]一行,增加如下配置,重启mysql服务

sudo vim /etc/mysql/conf.d/mysql.cnf

[mysql]

[client]
socket=/var/run/mysqld/mysqld.sock

[mysqld]
socket=/var/run/mysqld/mysqld.sock