Iptables string matching to block ips behind Reverse Proxy? - nginx

I have nginx server behind reverse proxy (Cloudflare) and want to block ips based on the xforwarded ip sent in the header.
I have tried the following iptables string matching rule :
iptables -A INPUT -m string --string "1.1.1.1" --algo bm --to 1024 -j DROP
However this doesn't seem to do anything.
Why isn't the string matching working ? I'm sure the real ip is sent in the packet , either as X-Forwarded-For or CF-Connecting-IP.
Kernel is 3.4.x and iptables 1.4.7, so no issues there .

As you mention CF-Connecting-IP is the best way to get the real IP behind CloudFlare. This is better than X-Forwarded-For as that can be changed if your server is then placed behind a load balancer or another reverse proxy (X-Forwarded-For even supports a comma separated list in it's RFC).
CloudFlare should only pass secure traffic and only web traffic to CloudFlare supported web server ports, therefore you can whitelist CloudFlare IPs and enable IPTables on other IPs. You can then block IPs in the Firewall tab of the CloudFlare site in question, then looking under IP Firewall. Non-CloudFlare traffic can then have IPTables applied to it.
We use the official Mod_CloudFlare on our Apache servers in order to correctly get the IP Address to our web server and ultimately into the web application itself. On NGinX you can try the ngx_http_realip_module.

Related

Restrict access to website using wireguard VPN

I set up a wireguard instance in a docker container and use nginx proxy manager to set up all reverse proxy settings. Now I want the website to be only accessible when I am connected to the VPN.
I tried to add localhost as the forward address and set the only allow to the local server ip, but it doesn't work and just displays a cant connect to server message in my browser.
Add this to a server block (or a location or http block) in your nginx configuration:
allow IP_ADDRESS_OR_NETWORK; # allow only connections from Wireguard VPN network
deny all; # block the rest of the world
The allowed network has to match your specific Wireguard VPN network. All peer IP addresses which should have access must be part of the network range. Depending on your NAT settings, you should verify the actual IP address or network by checking the access log: tail -f /var/log/nginx/access.log
Be sure to reload your nginx config to apply changes: service nginx reload
See also http://nginx.org/en/docs/http/ngx_http_access_module.html for usage hints on the HTTP access module.

How can we block X-Fordward-For header IP (https request) with IPtables

Basic Overview
We are trying to set up Rate Limiting on our server. we are using Nginx as a webserver and fail2ban for blocking IPs with Iptables.
IPtables can block IPs if a request hits direct our Nginx server(in this case $remote_addr is client IP).
But if it comes via some proxy server then proxy server passes client IP in X-Fordwarded-For header and Iptables unable to detect that(in this case $remote_addr is proxy server IP).
Is their some other ways we can block X-Fordwarded-For header IP?
any help will be appreciable
IPtable IP block commmand - iptables -A INPUT -s 111.112.212.112 -j DROP
You can not do that using iptables (especially if the packets are encrypted due to https traffic).
But if you use fail2ban and nginx, you can try the action nginx-block-map. Just use variable $http_x_forwarded_for in the map (see action description) and provide it in log, fail2ban will monitor, so the filter would be able to capture it as an ID to ban.

Block proxy server clients from accessing local devices on the server

I'm running a public proxy server and would like to block clients from accessing local devices on the server.
Local devices are on 10.0.0.0/8.
The proxy server runs on 127.0.0.1:31336. Access to the proxy server is made by reverse proxy on nginx which is listening on a public IP address.
Would an iptables rule like "reject 127.0.0.1:31336 from accessing 10.0.0.0/8" work? If so can I get an example iptables command to do so?
If not, would I have to work with network namespaces to achieve what I am seeking for?
why would you even use iptables for blocking client of a nginx, anyway follow this tutorial it will show you how you can allow or deny an ip or range ip : https://docs.nginx.com/nginx/admin-guide/security-controls/controlling-access-proxied-tcp/

Block IP from accessing Google Compute Engine instance

I'm trying to block a certain IP address or range to reach my WordPress server that's configured on my Google Compute Engine server.
I know I can block it via Apache, but even if I do my access_logs will still be filled with 403 error from requests from this IP.
Is there any way to block the IP entirely and don't even let it reach Apache?
Thanks in advance for any help.
If you want to block a single IP address, but allow all other traffic, the simplest option is probably to use iptables on the host. The GCE firewall rules are designed to control which IP addresses can reach your instance, but allowing everything on the internet except one address would probably be annoying to write.
To block a single IP address with iptables:
iptables -A INPUT -s $IP_ADDRESS -j DROP
or to just drop HTTP (but not HTTPS or other protocols):
iptables -A INPUT -s $IP_ADDRESS -p tcp --destination-port 80 -j DROP
Note that you'll need to run the above command as root in either case.
By default all incoming traffic to GCE is blocked except for the ports and range of IPs that are allowed to have access. Allowing everything to connect except a specific IP or a range of IP addresses is not supported on GCE firewall. As a workaround, you can setup a Load Balancer and allow incoming traffic from the LB IP address only to the instance. You can have more information in this Help Center article.
Yes you can block it using Gcloud Firewall.
Try creating the firewall rule from the command line or by logging into Google Cloud.
Example:
gcloud compute firewall-rules create tcp-deny --network example-network --source-ranges 10.0.0.0/8 --deny tcp:80
Above Rule will block the range 10.0.0.0/8 to port 80 (tcp).
Same can be done to block other IP Ranges over tcp and udp.
For more info check this: glcoud network config
Bitnami developer here
If you want to block a certain IP, you can use iptables as it's pointed in this post.
Also, if you want to have your iptables rules active when you reboot your machine you have to do the following:
sudo su
iptables-save > /opt/bitnami/iptables-rules
crontab -e
Now edit the file and include this line at the end:
#reboot /sbin/iptables-restore < /opt/bitnami/iptables-rules
This way, in every boot, the system will load the iptables rules and apply them.
To block offending IP, there are some methods on different levels to do it. From performance perspective, generally :
Network firewall > VM iptables > VM web server > VM application.
Google cloud has build-in firewall that no cost.
For example, this gcloud command create one firewall rule that can block 1 or more ips.
gcloud compute --project=your-project-id firewall-rules create your-firewall-rule-name --direction=INGRESS --priority=900 --network=default --action=DENY --rules=all --source-ranges=ip1,ip2,ip3…
Command parameters' reference see here https://cloud.google.com/sdk/gcloud/reference/compute/firewall-rules/create
You can also use Google cloud console or rest api to create it, but on console it's not easy to input lots of ips.
Build-in firewall's current limit:
One project can create 100 firewall rules.
One firewall rule can block 256 ip sources.
If there are 10 other firewall rules, you can block 90x256=23040 standalone ips, that is enough for general case.
Note: Google cloud app engine firewall is separated from build-in firewall.
Linux iptables
See other answers.
Web server
Apache, Nginx can also block ip.
Application
Not recommended block ip here. But application can help analysis which ip need to block, for example login failed many times.
If you want your system to automatically block all bad ip addresses in the GCP Firewall you can check out the Gatekeeper for Google Cloud Firewall.
It analyses your network connections and WordPress/Apache logs dynamically and creates approprate rules to ward off DoS and DDoS attacks as well as spying bots.

Having multiple HTTP-Server running next to nginx on the same machine

I have multiple HTTP servers running on the same machine. Only the nginx is listening to the HTTP port and forwards the requests to the other programs.
Now I'm adding a service that needs to receive post requests directly (without them being buffered). I already read that this isn't possible, though the posts are about a year old so I'm hoping there's a way to accomplish this in nginx 1.5.
Is there another way to have multiple HTTP server running on the same machine?
Edit: Every server has to answer requests from the http port. Which server handles the request is determined by the Hostname in the URL.
When your server has multiple IP's, You can bind services to explictly selected IP instead of default '*' or 0.0.0.0
When your clients can be segregated by their IP's, You can bind services to different ports and route packets using iptables:
iptables -A INPUT -p tcp --dport 80 -s 10.20.30.0/24 -j REDIRECT --to-port 81
Iptables can check not only headers, but also content via "-m string" extension.
You can have multiple processes on the same machine, call them HTTP servers, or anything else, the only "limit" is that they cannot listen in on the same port, they will each need to listen on a different port to work.
Otherwise they will complain that the port is already in use and "die".

Resources