文章851
标签121
分类10

X-Forwarded-For IP伪造问题处理

这个文章放在云笔记里面半年多了, 出现问题场景是我们从 aws 迁移至 阿里云 之后;
优化 api服务 发现有大量用户通过 X-Forwarded-For 仿造客户端IP 从而跨过我们后端对IP做的频率限制.

原理很简单 一般公司服务器都是 在服务最前端放 slb/lvs 这种负载均衡服务, 用户请求的IP 插入 X-Forwarded-For 前面

我们使用加速通道 多层的代理 ;

后端按照如下顺序获取客户端的真实IP

HTTP_ALI_CDN_REAL_IP;
HTTP_CF_CONNECTING_IP;
HTTP_X_CONNECTING_IP;
XXXX_Client_IP;
USER_REAL_IP; (通过nodejs 将用户的真实ip 透传给用户中心内网)

上述变量详解

HTTP_ALI_CDN_REAL_IP 链路配置了阿里云CDN,则阿里云CDN会传递此变量给后端,变量内的值就是客户端的真实IP地址。

HTTP_CF_CONNECTING_IP 如上,该值是cloudflare提供的客户端真实IP地址。

HTTP_X_CONNECTING_IP 如上,该值是加速乐提供的客户端真实IP地址。

XXXX_Client_IP 该值适用场景是SLB-->Nginx直连情况下,Nginx层启用了递归搜索。并且需要OP手动添加上层SLB的IP段为信任IP,通过判断X-Forwarded-For内最右侧的一个非信任IP值认定为客户端的真实IP地址并把此IP赋值给remote_addr,再由remote_addr赋值给XXXX_Client_IP。后端配置该配置前,请先跟OP确认上层是否配置。

XXXX_Client_IP 后端的应用服务(proxy_pass)赋值变量:

location / {
    ... ...
    proxy_set_header XXXX_Client_IP $remote_addr;
     ... ...
}

转发到后端的FastCGI服务(fastcgi_param)赋值变量:

location ~ \.php$ {
    ... ...
    fastcgi_param   XXXX_Client_IP  $remote_addr;
    ... ...
}

下面是客户端代理的IP 捕获文章 与 上文没有关系 ...

参考地址: https://www.cnblogs.com/rendd/p/6183094.html

1、没有代理服务器

  
HTTP_X_FORWARDED_FOR = 没数值或不显示 (X-Forwarded-For)
REMOTE_ADDR = 客户端IP

$ip = $_SERVER['REMOTE_ADDR'];

2、透明代理

REMOTE_ADDR = 最后一个代理服务器 IP
HTTP_X_FORWARDED_FOR = 客户端真实 IP (经过多个代理服务器时,这个值类似:221.5.252.160, 203.98.182.163, 203.129.72.215)

这类代理还会将客户真实ip发送到请求对象,无法隐藏真实ip

$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];

三、使用普通匿名代理服务器,

REMOTE_ADDR = 最后一个代理服务器 IP
HTTP_X_FORWARDED_FOR = 代理服务器 IP (经过多个代理服务器时,这个值类似:203.98.182.163, 203.98.182.163, 203.129.72.215)

  这样就隐藏了客户端的真实ip,但服务器会知道客户端是通过代理服务器去访问的。

四、使用欺骗性代理服务器,

REMOTE_ADDR = 代理服务器 IP
HTTP_X_FORWARDED_FOR = 随机的 IP(经过多个代理服务器时,这个值类似:220.4.251.159, 203.98.182.163, 203.129.72.215)

  服务器可以识别到时通过代理服务器访问的,但发送给目标服务器的是虚假ip。

五、使用高匿名代理,

REMOTE_ADDR = 代理服务器 IP
HTTP_X_FORWARDED_FOR = 没数值或不显示

  使用这种代理时,不同浏览器不同设备会返回不同的ip头信息,因此PHP使用$_SERVER["REMOTE_ADDR"]$_SERVER["HTTP_X_FORWARDED_FOR"] 获取的值可能是空值也可能是“unknown”值。

上面 五类IP获取方式 总结下 前2种都是可以真实获取客户端IP 后面 3种方式 基本服务端是抓瞎的. 主要介绍的是纯客户端的捕捉ip 方式

一句话总结总结

通过 X-Forwarded-For 获取用户真实 IP 时,最好不要取第一个 IP,以防止用户伪造 IP

基于acme.sh从Let's encrypt生成免费SSL证书

基于acme.sh从Let's encrypt生成免费且自动更新的SSL证书

0x01 安装 acme.sh

$ curl https://get.acme.sh | sh
# Or
$ wget -O -  https://get.acme.sh | sh

执行上面的命令,它会:
从 GitHub 上下载 sh 脚本并执行
把文件解压到用户的 ~/.acme.sh目录下
给命令行设置一个acme.sh的 alias 别名
最后注册一个 cron 定时任务来自动更新证书。

安装完成后要自行重启命令行,或者重新加载一下.bashrc文件(source ~/.bashrc)。
然后看一下有没有生效。

$ acme.sh -h
https://github.com/acmesh-official/acme.sh
v2.8.6
Usage: acme.sh  command ...[parameters]....
Commands:
  --help, -h               Show this help message.
  --version, -v            Show version info.
  --install                Install acme.sh to your system.
  --uninstall              Uninstall acme.sh, and uninstall the cron job.
  --upgrade                Upgrade acme.sh to the latest code from https://github.com/acmesh-official/acme.sh.
  --issue                  Issue a cert.
  --signcsr                Issue a cert from an existing csr.
  --deploy                 Deploy the cert to your server.
  --install-cert           Install the issued cert to apache/nginx or any other server.

0x02 签发 SSL 证书

签发 SSL 证书需要证明这个域名是属于你的,即域名所有权,一般有两种方式验证:httpdns 验证。
通过 acme.sh 可以签发单域名、多域名、泛域名证书,还可以签发 ECC 证书。为了简单起见,这里以单域名证书为例,后面再拓展一下好了。
下面任意一种方式只要安装成功了就行!

Standalone mode

这种方式下,acme.sh 会自己建立一个服务器来完成签发。主要适合的是没有建立服务器的情况,不过其实有服务器的话只要暂时关闭,不造成端口冲突就能使用。

acme.sh --issue -d www.3pub.cn --standalone

签发 ECC 证书

默认签发的都是基于 RSA 密钥加密的证书,而 ECC (Elliptic Curve Cryptography, 椭圆曲线密码) 密钥的保密性比 RSA 更好,密钥长度更短,更能对抗量子解密等,目前现代的操作系统和浏览器都支持 ECC 证书了(Windows XP 及其之前的就算了)。
Let's Encrypt 提供了 ECDSA 证书的签发,且 acme.sh 也支持。
我看网上的教程基本没讲 ECC 证书的签发,这里就来整一下呗!
其实只需要加上一个以 ec- 为前缀的 --keylength 参数(或 -k)就可以了。理论上上面的各种验证方式都适用。

 acme.sh --issue -w /opt/webserver/typecho -d www.3pub.cn -k ec-256 --force

支持以下长度的证书,一般就用 ec-256 就行了。

创建 SSL 目录 将生成的keycer , cp 至 新建目录

 mkdir -p /usr/local/nginx/ssl
 chmod -R 777 /usr/local/nginx/ssl
 cp  /root/.acme.sh/www.3pub.cn_ecc/www.3pub.cn.key /usr/local/nginx/ssl/3pub.key
 cp  /root/.acme.sh/www.3pub.cn_ecc/www.3pub.cn.cer /usr/local/nginx/ssl/3pub.cer
 vim /usr/local/nginx/conf/conf.d/typecho.conf 

修改 nginx 配置

server
{
        listen 80;
        server_name www.3pub.cn;
        # 重定向到https
        rewrite ^(.*)$ https://$host$request_uri;
}


server {
        listen 443;
        server_name www.3pub.cn;
        set $root /typecho;
        root $root;

        ssl on;
        ssl_certificate /usr/local/nginx/ssl/3pub.cer;
        ssl_certificate_key /usr/local/nginx/ssl/3pub.key;


        # 下面直接照写
        location / {
                try_files $uri $uri/ /index.php$is_args$args;
        }

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

很无语 通过 占用 80端口 启动服务 自己检测通过

acme.sh --issue -d www.3pub.cn --standalone --force
[root@xxx ~]# acme.sh --issue -d www.3pub.cn --standalone --force
[Mon Feb 19 11:21:32 CST 2024] Using CA: https://acme.zerossl.com/v2/DV90
[Mon Feb 19 11:21:32 CST 2024] Standalone mode.
[Mon Feb 19 11:21:32 CST 2024] LISTEN     0      128          *:80                       *:*                   users:(("nginx",pid=21719,fd=15),("nginx",pid=8041,fd=15))
[Mon Feb 19 11:21:32 CST 2024] tcp port 80 is already used by (("nginx",pid=21719,fd=15),("nginx",pid=8041,fd=15))
[Mon Feb 19 11:21:32 CST 2024] Please stop it first
[Mon Feb 19 11:21:32 CST 2024] _on_before_issue.

如果用了反代之类的不是 80 端口,则可以手动指定。

acme.sh --issue -d www.3pub.cn --standalone --force --httpport 88
[Mon Feb 19 11:24:20 CST 2024] get authz objec with invalid status, please try again later.
[Mon Feb 19 11:24:20 CST 2024] _authorizations_seg='https://acme.zerossl.com/v2/DV90/authz/nzrGorBqTconk20mHFUZ2g'
[Mon Feb 19 11:24:20 CST 2024] {"identifier":{"type":"dns","value":"www.3pub.cn"},"status":"invalid","expires":"2024-03-20T01:47:24Z","challenges":[{"type":"http-01","url":"https://acme.zerossl.com/v2/DV90/chall/61vb2C969GYiHZP06eZuHg","status":"invalid","error":{},"token":"ehiTpZgfvtlh5jzWAJXkpsnjaElut_1KKlh9tcTSboQ"}]}
[Mon Feb 19 11:24:20 CST 2024] Please add '--debug' or '--log' to check more details.
[Mon Feb 19 11:24:20 CST 2024] See: https://github.com/acmesh-official/acme.sh/wiki/How-to-debug-acme.sh

自动更新并没研究米哦你告白

参考文献 :

https://miaotony.xyz/2020/03/28/Server_IssueACertWithACME/#toc-heading-14
https://moe.best/tutorial/acme-le-wc.html
https://juejin.cn/post/7136001093720342542

yum 安装 Redis

YUM安装Redis:

由于Centos官方yum源里面没有Redis,我们需要安装一个第三方的yum源,这里用了Fedoraepel仓库,执行命令安装,这里要注意一点,yum 安装的redis 版本不一定是最新的,可以用 yum search redis 来查询安装源中的 redis 版本,默认情况,版本较老。

安装epel仓库:

yum install -y epel-release

然后使用 yum install -y redis 安装 redisyum 安装操作非常简单。

下面使用 cetnos7 systemctl 启动 redis,命令如下:

systemctl start redis
">