使用 CloudFlare 和 Nginx 在 Ubuntu 中托管的 Nodejs 应用程序中有时未定义客户端 IP
Client IP is sometimes undefined in a Nodejs app hosted in Ubuntu with CloudFlare and Nginx
我的应用程序有一个不寻常的问题。该应用严重依赖客户端的 IP,有时是 undefined
。我的意思是,如果一天有 10 次访问我的应用程序,我可以看到 7 个客户的 IP,但其中有 3 个 returns undefined
.
该应用程序没有问题,我可以肯定地说,因为当它托管在具有 CloudFlare 且没有 Nginx 的共享主机中时,它运行得非常好。但是自从我迁移到 Ubuntu 20.04 VPS 并使用 Nginx 和 CloudFlare 后,这个问题就开始了。
我遵循了 CloudFlare 中的教程,希望它能解决问题,但事实并非如此。
现在我不知道我应该怎么做才能解决这个问题。所以在这里我希望有人能弄明白。
以下是我在应用端点中获取客户端 IP 的方式:
const clientIp = req.header( 'cf-connecting-ip' ) || req.header( 'true-client-ip' );
nginx.conf
文件如下所示:
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
server_tokens off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
gzip on;
proxy_hide_header X-Powered-By;
add_header X-Frame-Options SAMEORIGIN;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
这是应用配置文件:
server {
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
server_name example.com www.example.com;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $http_cf_connecting_ip;
proxy_set_header X-Forwarded-For $http_x_forwarded_for;
proxy_cache_bypass $http_upgrade;
}
location /blog/ {
access_log /var/log/nginx/blog-example.org_access.log;
error_log /var/log/nginx/blog-example.org_error.log;
root /var/www/html/example.com;
index index.php;
if (!-f $request_filename) {
rewrite [^/]$ $uri/ permanent;
}
try_files $uri $uri/ /blog/index.php?$args;
location ~ \.php {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_index index.php;
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
include fastcgi_params;
}
}
#CLOUDFLARE
set_real_ip_from 103.21.244.0/22;
set_real_ip_from 103.22.200.0/22;
set_real_ip_from 103.31.4.0/22;
set_real_ip_from 104.16.0.0/13;
set_real_ip_from 104.24.0.0/14;
set_real_ip_from 108.162.192.0/18;
set_real_ip_from 131.0.72.0/22;
set_real_ip_from 141.101.64.0/18;
set_real_ip_from 162.158.0.0/15;
set_real_ip_from 172.64.0.0/13;
set_real_ip_from 173.245.48.0/20;
set_real_ip_from 188.114.96.0/20;
set_real_ip_from 190.93.240.0/20;
set_real_ip_from 197.234.240.0/22;
set_real_ip_from 198.41.128.0/17;
set_real_ip_from 2400:cb00::/32;
set_real_ip_from 2606:4700::/32;
set_real_ip_from 2803:f800::/32;
set_real_ip_from 2405:b500::/32;
set_real_ip_from 2405:8100::/32;
set_real_ip_from 2a06:98c0::/29;
set_real_ip_from 2c0f:f248::/32;
real_ip_header CF-Connecting-IP;
listen [::]:443 ssl http2 ipv6only=on; # managed by Certbot
listen 443 ssl http2; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
# include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
}
server {
if ($host = www.example.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
if ($host = example.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80 default_server;
listen [::]:80 default_server;
server_name example.com www.example.com;
return 404; # managed by Certbot
}
更新
我不知道这是否是原因,但我收到 GET
到我主页的请求:/xdebug_session_start=phpstorm
。我真的不知道那是什么,我怀疑每当它发出请求时,IP 都会返回 undefined
。
更新
我分析了请求headers,客户端ip是undefined
。这里有 3 个请求'headers:
headers: {
connection: 'upgrade',
host: '63.250.33.76',
'user-agent': 'Mozilla/5.0 (compatible; CensysInspect/1.1; +https://about.censys.io/)',
accept: '*/*',
'accept-encoding': 'gzip'
}
headers: {
connection: 'upgrade',
host: '63.250.33.76'
}
headers: {
connection: 'upgrade',
host: 'www.example.com',
'user-agent': 'Expanse indexes the network perimeters of our customers. If you have any questions or concerns, please reach out to: scaninfo@expanseinc.com'
}
有人知道这些是什么意思吗?
我对 cloudflare 不太熟悉,但是你可以在你的代码中添加“x-real-ip”header 并检查一下吗?
const clientIp = req.header( 'cf-connecting-ip' ) || req.header( 'true-client-ip' ) || req.header( 'x-real-ip' );
这些客户端是否可能直接访问您的应用程序而不是通过 Cloudflare?例如,如果您的服务器未配置为接受来自 Cloudflare IP ranges 的流量 仅 ,那么有人可能会直接访问您的应用程序,这可以解释为什么 CF-Connecting-IP
部分场景不设置
更多信息在此 documentation page
我的应用程序有一个不寻常的问题。该应用严重依赖客户端的 IP,有时是 undefined
。我的意思是,如果一天有 10 次访问我的应用程序,我可以看到 7 个客户的 IP,但其中有 3 个 returns undefined
.
该应用程序没有问题,我可以肯定地说,因为当它托管在具有 CloudFlare 且没有 Nginx 的共享主机中时,它运行得非常好。但是自从我迁移到 Ubuntu 20.04 VPS 并使用 Nginx 和 CloudFlare 后,这个问题就开始了。
我遵循了 CloudFlare 中的教程,希望它能解决问题,但事实并非如此。 现在我不知道我应该怎么做才能解决这个问题。所以在这里我希望有人能弄明白。
以下是我在应用端点中获取客户端 IP 的方式:
const clientIp = req.header( 'cf-connecting-ip' ) || req.header( 'true-client-ip' );
nginx.conf
文件如下所示:
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
server_tokens off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
gzip on;
proxy_hide_header X-Powered-By;
add_header X-Frame-Options SAMEORIGIN;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
这是应用配置文件:
server {
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
server_name example.com www.example.com;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $http_cf_connecting_ip;
proxy_set_header X-Forwarded-For $http_x_forwarded_for;
proxy_cache_bypass $http_upgrade;
}
location /blog/ {
access_log /var/log/nginx/blog-example.org_access.log;
error_log /var/log/nginx/blog-example.org_error.log;
root /var/www/html/example.com;
index index.php;
if (!-f $request_filename) {
rewrite [^/]$ $uri/ permanent;
}
try_files $uri $uri/ /blog/index.php?$args;
location ~ \.php {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_index index.php;
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
include fastcgi_params;
}
}
#CLOUDFLARE
set_real_ip_from 103.21.244.0/22;
set_real_ip_from 103.22.200.0/22;
set_real_ip_from 103.31.4.0/22;
set_real_ip_from 104.16.0.0/13;
set_real_ip_from 104.24.0.0/14;
set_real_ip_from 108.162.192.0/18;
set_real_ip_from 131.0.72.0/22;
set_real_ip_from 141.101.64.0/18;
set_real_ip_from 162.158.0.0/15;
set_real_ip_from 172.64.0.0/13;
set_real_ip_from 173.245.48.0/20;
set_real_ip_from 188.114.96.0/20;
set_real_ip_from 190.93.240.0/20;
set_real_ip_from 197.234.240.0/22;
set_real_ip_from 198.41.128.0/17;
set_real_ip_from 2400:cb00::/32;
set_real_ip_from 2606:4700::/32;
set_real_ip_from 2803:f800::/32;
set_real_ip_from 2405:b500::/32;
set_real_ip_from 2405:8100::/32;
set_real_ip_from 2a06:98c0::/29;
set_real_ip_from 2c0f:f248::/32;
real_ip_header CF-Connecting-IP;
listen [::]:443 ssl http2 ipv6only=on; # managed by Certbot
listen 443 ssl http2; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
# include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
}
server {
if ($host = www.example.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
if ($host = example.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80 default_server;
listen [::]:80 default_server;
server_name example.com www.example.com;
return 404; # managed by Certbot
}
更新
我不知道这是否是原因,但我收到 GET
到我主页的请求:/xdebug_session_start=phpstorm
。我真的不知道那是什么,我怀疑每当它发出请求时,IP 都会返回 undefined
。
更新
我分析了请求headers,客户端ip是undefined
。这里有 3 个请求'headers:
headers: {
connection: 'upgrade',
host: '63.250.33.76',
'user-agent': 'Mozilla/5.0 (compatible; CensysInspect/1.1; +https://about.censys.io/)',
accept: '*/*',
'accept-encoding': 'gzip'
}
headers: {
connection: 'upgrade',
host: '63.250.33.76'
}
headers: {
connection: 'upgrade',
host: 'www.example.com',
'user-agent': 'Expanse indexes the network perimeters of our customers. If you have any questions or concerns, please reach out to: scaninfo@expanseinc.com'
}
有人知道这些是什么意思吗?
我对 cloudflare 不太熟悉,但是你可以在你的代码中添加“x-real-ip”header 并检查一下吗?
const clientIp = req.header( 'cf-connecting-ip' ) || req.header( 'true-client-ip' ) || req.header( 'x-real-ip' );
这些客户端是否可能直接访问您的应用程序而不是通过 Cloudflare?例如,如果您的服务器未配置为接受来自 Cloudflare IP ranges 的流量 仅 ,那么有人可能会直接访问您的应用程序,这可以解释为什么 CF-Connecting-IP
部分场景不设置
更多信息在此 documentation page