Reducing vulnerability scanners - my solution

I've got my web server set up and live on the IP address, but not quite live on the domain name yet. I get pretty consistent traffic from people trying to use my server as a proxy, trying to scan for vulnerabilities (hit after hit to wp-admin stuff, various .php files, etc.), and some innocuous mapping projects.

I'm running nginx with a mostly static web page as the frontend. The very few scripts I do have to run are hosted on a local (otherwise inaccessible) lighttpd instance, and are written largely in python. There are no php endpoints, although I could work around it if there were. This means that any attempt to hit a page ending in .php are clearly unwanted.

I wrote a quick shell script that I'm hosting on the lighttpd side. Here's that script:
Code:
#!/bin/sh
echo Content-Type: text/plain
echo
echo $HTTP_X_REAL_IP
/usr/local/bin/sudo /sbin/pfctl -t banip -T add ${HTTP_X_REAL_IP}/32 2>&1
/usr/local/bin/sudo /sbin/pfctl -k ${HTTP_X_REAL_IP}/32 2>&1
echo "complete"

The pf table banip is set to block in quick. I have sudoers set up to allow www to execute /sbin/pfctl with no password.

Here's the relevant section of my nginx config:
Code:
server {
        listen       80 default_server;
        server_name  _;
        root /var/www/prod;
        server_tokens off;
        rewrite ^(.*)php(.*)$ /help.sh last;
        location /help.sh {
                proxy_set_header X-Real-IP $remote_addr;
                proxy_pass http://127.0.0.1:8000/banip/doit.sh;
        }
(...)

I've had this setup for 24 hours, and I already have 7 IP addresses in the table. Again, this is only hosted on the IP address itself, which is unpublished anywhere else.

Anyway, I thought this was a pretty funny solution to this "problem" - not that it's really a problem, since I have everything set up pretty secure otherwise, and I obviously don't have any php-based vulnerabilities (since there is no php), but I like to discourage this kind of behavior, especially when they're using (a small amount of) my traffic. Any thoughts?
 
but I like to discourage this kind of behavior, especially when they're using (a small amount of) my traffic. Any thoughts?
You can't stop, prevent or discourage it from happening. The only thing you can do is accept it's going to happen. About 99% of these scans are made by dumb bots running on infected hosts. As soon as you open a port to the internet bots are going to find and probe it. There's just no way to prevent this from happening as most bots simply scan random addresses or whole ranges of IP addresses. That's an unfortunate reality these days.

There are some "solutions" around that try to "tarpit" them. But again, that's not going to stop or even discourage them. They're bots, automated programs, that simply don't care how long a scan takes. It's not going to do anything, they won't be discouraged and it won't stop them from scanning other servers.
 
It's a very similar solution to security/py27-fail2ban, although that parses logs for specific entries and blocks the relevant addresses after X attempts for Y minutes/hours.

But yes, everyone gets these requests and it's very common to use something to block them automatically. It's more of an issue for services such as FTP/SMTP/etc as you don't really want bots being able to just keep trying to brute force accounts. Attempts to access stuff like wordpress or known web vulnerabilities are a bit easier to ignore if you know you don't have them (although I still prefer to block hosts making dodgy requests)
 
If the web server is not intended to be public, but for a limited group of users, it might help to put it on a non-standard port. Many bots only scan the standard ports (80, 443, 3128, 8000, 8080 and a few others).

By the way, those “fail2ban” and similar things are not completely without risk. If an attacker manages to spoof your IP address, he will be able to lock you out of your own machine. Spoofing IP addresses is difficult, but under certain circumstances it can be done, e.g. if you use a hosting service, and the attacker is on another host within the same subnet (and he is sufficiently clever). I can't be done by a dumb bot, though.
 
You can't stop, prevent or discourage it from happening.
True, and I don't have the misconception that I'm "improving the internet" or anything - but after a couple of host unreachables, they should stop using my traffic at least!

If an attacker manages to spoof your IP address, he will be able to lock you out of your own machine.
Not an issue on my setup - they can't spoof the private IPs I'm using on this end, since my firewall blocks all incoming traffic on my WANs that have private IP addresses. Plus, I can always go upstairs for physical access to the machine in the worst case.

Oh, and this will (soon) become our company's actual website, so it is intended for public view. All the private stuff I run on that server is on an alternative port, and inaccessible from the WAN. The only ports I have open to the public are the web server, soon I'll have my authoritative-only DNS, and the openvpn ports. Private services belong on a private network.
 
but after a couple of host unreachables, they should stop using my traffic at least!
Yeah, not going to happen. They're dumb bots that don't care about error messages, timeouts or unreachables. Heck, they don't even care which webserver it actually is (I've seen Apache exploits being sent to an IIS server and vice versa). All they do is open connection, send garbage. Next IP, open connection, send garbage. Next IP, etc. repeated indefinitely.
 
Switching to a different port isn't going to help : I am a pentester and routinely scan every port on a given machine to see what looks interesting. Security through obscurity never works, ask Microsoft :) I know bots may not do that but even though...

In all seriousness, if possible to have the site hosted by a company, then the network security is their problem. Not sure if that's possible in your case but may be worth a look.
 
For certain protocols (ssh in particular), alternative ports do help the traffic - any time in the past that I've had publicly open ssh ports, I've put them on 2201, and while the number of break-in attempts (thwarted by key-only security or similar, of course) never dropped to 0, it came damn close - better than thousands of log entries per day from those damn botnets. Obviously if someone wants to get in, that alone won't stop them!

In the context of my internal use of alternative ports, that's mostly to keep things 1:1 in terms of ports - i.e. this web server is open on 80 (production web server), 8000 (lighttpd for internal apps and scripts for the web side), 8080 (staging web server), and several other services on standard ports, but only 80 is open to the WAN (but it's 80->80, no PAT). That'll include 443 as well when it's actually up and running.

We're currently hosting through an outside company - this will be us switching away from that entirely. First off, for how little traffic we get, we're going to save a ton of money doing it ourselves. Plus, they're using wordpress to do a simple static page, and seem to be super over-provisioned - our page consistently takes 7 seconds or more to load. And after having to hold their admins hand through the process of adding SPF/DKIM/DMARC entries to the DNS records, I've basically lost faith in them entirely.

I should mention, I'm 100% of the technical side of this company, and I do trust myself to do things right. We're not a tech company, and although I take security very seriously, the baseline for comparison is not even having a backup system in place!
 
That will stave off the bot attempts as olli@ mentioned but not the real humans, if anyone real actually attempts. Just make sure your network infrastructure is secure and you check logs daily, both web server and OS level.

Just one point, because it is fresh in my mind: make sure the minimum methods on your web server are allowed: GET, HEAD, OPTIONS, and POST if you need it. For the love of all things holy, do not enable PUT. I just p0wned (legally) a Sharepoint site today because they enabled PUT.

Sorry, getting off topic there...
 
Just one point, because it is fresh in my mind: make sure the minimum methods on your web server are allowed: GET, HEAD, OPTIONS, and POST if you need it. For the love of all things holy, do not enable PUT. I just p0wned (legally) a Sharepoint site today because they enabled PUT.

Good call, but way ahead of you :p
Code:
        if ($request_method !~ ^(GET|HEAD|POST)$ ) {
                return 405;
        }

This is in my nginx.conf. Nobody actually uses OPTIONS, right?
 
Right, I just grabbed that off the web ,was more concerned about PUT. I am not a genius at securing web servers, just breaking into them, lol.
 
Plus, they're using wordpress to do a simple static page, and seem to be super over-provisioned - our page consistently takes 7 seconds or more to load. And after having to hold their admins hand through the process of adding SPF/DKIM/DMARC entries to the DNS records, I've basically lost faith in them entirely.

That's not the way the company that hosts my sites operate. I pay them and they turn me loose, though they have always been prompt and polite anytime I've had a question. They don't design my site for me and the option to use Wordpress or not is mine.

Your page is probably much prettier than mine but it loads in 1.9 seconds using a test of 9 requests with Firefox 64 as the browser from New York to Sofia, Bulgaria:

Resolve 101 ms / 9 requests ~ 11.2 ms (average)
TCP Connect 243 ms / 9 requests ~ 27.0 ms (average)
HTTPS Handshake 419 ms / 9 requests ~ 46.6 ms (average)
Send 0 ms / 9 requests ~ 0.0 ms (average)
Wait 691 ms / 9 requests ~ 76.8 ms (average)
Receive 6 ms / 9 requests ~ 87.3 ms (average)

 
For certain protocols (ssh in particular), alternative ports do help the traffic - any time in the past that I've had publicly open ssh ports, I've put them on 2201
Same here. Of course it's not a security measure (“security by obscurity”), but it reduces the clutter in the log file considerably.

By the way, I recommend to use a port number below 1024 (e.g. 1022), because only root processes can bind to it. If you run it on a non-privileged port, there is the theoretical possibility for a privilege-escalation attack under certain circumstances. It's not very likely, but still it's a good idea to close every hole, even if it's a very small one.

Alternatively you can increase the value of the sysctl net.inet.ip.portrange.reservedhigh (default 1023) to cover the port number you've chosen. For a more fine-grained control over port binding permissions, see the mac_portacl(4) manual page.
 
Back
Top