Cloudflare 是如何处理HTTP Request Headers的(How Does Cloudflare handle HTTP Request headers)?

我们都知道,cloudflare其实本质上就是一个反向代理(reverse proxy), 因此cloudflare 会把收到的所有的HTTP headers request原原本本的转发给你的源服务器,在此基础上还会添加一些CF自己的header.

这些header 都有一个共同的特性,就是以CF开头

CF-Connecting-IP: 

Provides the client (visitor) IP address (connecting to Cloudflare) to the origin web server. 
This header will only be sent on the traffic from Cloudflare's edge to your origin webserver.

True-Client-IP (Enterprise plan only):

企业用户专享

X-Forwarded-For:

Maintains proxy server and original visitor IP addresses. If there was no existing X-Forwarded-For header in the request sent to Cloudflare, 
X-Forwarded-For has an identical value to the CF-Connecting-IP header

CF-RAY:

The cf-ray header is a hashed value encoding information about the data center and the visitor’s request

CF-IPCountry:

Contains a two character country code of the originating visitor’s country. XX is used for unknown country information

CF-Vistor:

Currently, this header is a JSON object, containing only one key called “scheme”. The meaning is identical to that of X-Forwarded-Proto above - e.g. it will be either HTTP or HTTPS, 
and it is only really relevant if you need to enable Flexible SSL in your Cloudflare settings.

CDN-Loop:

Allows Cloudflare to specify how many times a request can enter Cloudflare's network before it is blocked as a looping request.

CF-Worker:

The CF-Worker request header is added to an edge Worker subrequest that identifies the host that spawned the subrequest. 
This is useful when you want to protect against cross-zone worker subrequests.
You can add CF-Worker header on server logs similar to the way you add the CF-RAY header. Just add "$http_cf_worker" in the log format file: log_format cf_custom "CF-Worker:$http_cf_worker"'

用phpinfo()函数测试了一下,发现多了以下几个fields:

$_SERVER['HTTP_CDN_LOOP']: cloudflare
$_SERVER['HTTP_CF_CONNECTING_IP']: 99.99.99.99
$_SERVER['HTTP_CF_VISITOR']: {"scheme":"https"}
$_SERVER['HTTP_CF_RAY']: 6a4247906e83762b-EWR
$_SERVER['HTTP_X_FORWARDED_FOR']: 99.99.99.99
$_SERVER['HTTP_CF_IPCOUNTRY']: US

同时,REMOTE_ADDR这个ip是CF的节点IP

$_SERVER['REMOTE_ADDR']: 174.245.52.215 (CF新泽西IP)

 

Nginx 使用多个map条件语句(conditionally block)

在Nginx 的location中,if is evil.

因此多个if条件语句可以转化为多个map条件语句.

一般有两种方式,一个是map中直接map 两个变量,变量之间用:间隔;另外一个就是使用多个map,后一个map里面直接使用前面一个map里的变量,形成map chain. 下面详细说明:

第一种方式:

map "$http_x_target:$arg_target" $destination {
default upstream0;
~something upstream1;
~something2 upstream1;
~something3 upstream2;
}
...
server {
location / {
proxy_pass https://$destination;
}
}

第二种方式:

map $arg_target $arg_destination {
default upstream0;
something upstream1;
something2 upstream1;
something3 upstream2;
}
map $http_x_target $destination {
default $arg_destination;
something upstream1;
something2 upstream1;
something3 upstream2;
}
...
server {
location / {
proxy_pass https://$destination;
}
}

参考文档:

https://stackoverflow.com/questions/59671623/conditionally-map-values-in-nginx-config
https://gock.net/blog/2020/nginx-conditional-logging-responses/

Nginx 禁止某些UA(User Agent)访问

一般来说,我们直接用nginx 的if 语句配合正则表达式就可以了,比如说

# case sensitive matching
if ($http_user_agent ~ (Antivirx|Arian)) {
return 403;
}

# case insensitive matching
if ($http_user_agent ~* (netcrawl|npbot|malicious)) {
return 403;
}

但是当我们需要禁止的user agent lists过长时,用if语句配合正则表达式就不是那么方便,而且性能上也会有影响,因此Nginx官方

多推荐使用map 来代替 if 语句

map $http_user_agent $badagent {
default 0;
~*malicious 1;
~*backdoor 1;
~*netcrawler 1;
~Antivirx 1;
~Arian 1;
~webbandit 1;
}

 if ($badagent) {
return 403;
}

Curl 常用commands

经常利用curl 来测试网站的一些301/302转向,检查代码什么的.

下面是常用的命令, 这里保存一下,经常用的上. 

curl -o vue-v2.6.10.js https://cdn.jsdelivr.net/npm/vue/dist/vue.js 
#vue.js 保存为vue-v2.6.10.js
curl -O https://cdn.jsdelivr.net/npm/vue/dist/vue.js  
# -O 直接保存为原文件名
curl -I  https://www.ubuntu.com/  
# 获得HTTP HEADER
curl -I --http2 https://www.ubuntu.com 
# --https2 检查是否支持http2协议
curl -L google 
# -L 命令curl 跟随跳转到final destination
curl -A "googlebot" https://www.ubuntu.com 
# -A 自定义UA
curl -x 192.168.66.1:8888 http://linux 
# -x 或者 --proxy 设定proxy
curl -H "X-Header: value" https://www.keycdn.com 
# -H 自定义header
curl -H "X-Header: value" https://www.keycdn.com -v 
# -v 表示 verbose
curl -h # -h 表示manual
curl --request GET/POST https://www.keycdn.com  
# curl 默认是GET, --request 可以自定为GET或者POST