I have rather an unusual problem with my app. The app heavily depends on the client’s IP which is sometimes undefined
. What I mean is, if there are, say 10 visits to my app in a day, I can see 7 of my clients’ IP but 3 of them returns undefined
.
The app doesn’t have a problem which I can say for sure because it was working perfectly fine when it was hosted in a shared hosting with CloudFlare and without Nginx. But this issue started since I migrated to Ubuntu 20.04 VPS and with Nginx and CloudFlare.
I followed this tutorial from CloudFlare hoping that it would solve the problem but it didn’t.
Now I don’t know what I should do to fix this. So here I am hoping someone would figure it out.
Here’s how I am getting the client IP in an app endpoint:
const clientIp = req.header( 'cf-connecting-ip' ) || req.header( 'true-client-ip' );
Here’s how the nginx.conf
file looks like:
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/*;
}
Here’s the app config file:
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
}
UPDATE
I don’t know if this is the reason or not but I am getting GET
requests to my homepage with this: /xdebug_session_start=phpstorm
. I really don’t know what that is and I’m doubting that whenever its making the request, the IP is returning undefined
.
UPDATE
I have analyzed the request headers when client ip was undefined
. Here are 3 requests’ 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: [email protected]'
}
Does anybody know what these mean?
2
Answers
I am not familiar with cloudflare that much but can you add "x-real-ip" header in your code and check.
Is it possible that these clients are reaching directly your application and not via Cloudflare? For example, if your server is not configured to accept traffic only from the Cloudflare IP ranges, then someone could be reaching your app directly and it could explain why
CF-Connecting-IP
is not set in some scenarios.More information at this documentation page