0

We run a CentOS Linux release 7.4 LAMP stack with Apache 2.4. On a monitoring dashboard, I keep track of various performance metrics, and one of those is "bad host requests" where the virtualhost does not match that of our server.

Manually, I use arin.net to look up bad host requests. Because the nature of our business is U.S., domestic only, we block foreign ip ranges that visit us without the proper virtualhost name. We do this using iptables; the following is a sample of that, fwiw.

$ sudo iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
DROP       all  --  187.0.0.0/8          anywhere             /* montevideo uruguay */
DROP       all  --  177.0.0.0/8          anywhere             /* vmontevideo uraguay */
DROP       all  --  164.77.0.0/16        anywhere             /* montevideo uraguay */
DROP       all  --  78-0-0-0.adsl.net.t-com.hr/8  anywhere             /* amsterdam */

This is effective at slowing all that "sniffer" traffic from overseas..


Almost suddenly, in the past 2 weeks, we have started receiving 3-6 requests per day that are from Chicago IL, Amazon AWS (Seattle WA), Fremont CA and etc.


Here are some log entries from apache's access_log:

./myurl.com-access.log:23.20.12.111 - - [16/Jan/2018:00:16:21 -0600] "HEAD / HTTP/1.1" 200 - "-" "Cloud mapping experiment. Contact research@pdrlabs.net"
./myurl.com-access.log:23.20.54.152 - - [16/Jan/2018:08:10:03 -0600] "HEAD / HTTP/1.1" 200 - "-" "Cloud mapping experiment. Contact research@pdrlabs.net"
./myurl.com-access.log-20180114:23.20.12.111 - - [13/Jan/2018:08:07:44 -0600] "HEAD / HTTP/1.1" 200 - "-" "Cloud mapping experiment. Contact research@pdrlabs.net"
./myurl.com-ssl-access.log:74.82.47.3 - - [14/Jan/2018:07:20:31 -0600] "GET / HTTP/1.1" 200 21 "-" "-"
./myurl.com-ssl-access.log:108.178.61.58 - - [15/Jan/2018:06:40:17 -0600] "GET / HTTP/1.1" 200 20 "-" "Mozilla/5.0 zgrab/0.x"
./myurl.com-ssl-access.log:184.154.189.90 - - [15/Jan/2018:07:54:29 -0600] "GET / HTTP/1.1" 200 21 "-" "Mozilla/5.0 zgrab/0.x"
./myurl.com-ssl-access.log:108.178.61.58 - - [16/Jan/2018:06:16:45 -0600] "GET / HTTP/1.1" 200 21 "-" "Mozilla/5.0 zgrab/0.x"
./myurl.com-ssl-access.log:184.154.189.90 - - [16/Jan/2018:06:51:18 -0600] "GET / HTTP/1.1" 200 21 "-" "Mozilla/5.0 zgrab/0.x"
./myurl.com-ssl-access.log:74.82.47.3 - - [16/Jan/2018:07:28:43 -0600] "GET / HTTP/1.1" 200 20 "-" "-"
./myurl.com-ssl-access.log-20180114:74.82.47.3 - - [08/Jan/2018:06:25:14 -0600] "GET / HTTP/1.1" 302 - "-" "-"

What methods are available to protect against (block outright as early as possible) requests to the server that do not have the single, proper virtualhost?


In response to a solution that fail2ban may help, I checked and fail2ban is running:

$ ps aux | grep fail2ban
root      2824  0.0  0.0 368832 53632 ?        Sl    2017  17:44 /usr/bin/python2 -s /usr/bin/fail2ban-server -s /var/run/fail2ban/fail2ban.sock -p /var/run/fail2ban/fail2ban.pid -x -b

I'll look into writing a rule for it - I cannot afford to block traffic that is legitimate - is it safe to assume that no valid traffic will request the host without the virtualhost (certainly the web app is written in a way that demands this to be truth).


update

fail2ban will not work since they only hit the server once with each ip address - they don't reuse them. let me state that i have effectively identified the traffic at line 2 of the web app. right now, i am sending them a status 200 with a random number, very small, very fast. but i need a way to "cloak" the server, somehow to simply not respond in a way that does not put any real load on the server.

  • fail2ban has several rules for blocking IP addresses that scan apache servers, and you can write your own rules or add to the existing ones. fail2ban is available pre-packaged for most linux distros. – cas Jan 16 '18 at 15:48
  • are there ever instances that legitimate traffic to the site could ping us without the host name though? – WEBjuju Jan 16 '18 at 15:49
  • 1
    Possibly, but unlikely. the most "legitimate" case would be some site-surveying / stats gathering org or similar. Any legitimate one will include a URL or contact address in their user agent string (like the cloud mapping one in your sample - note that I am not saying that they are definitely legit, I don't know. but at least they're doing the right thing by providing a contact address). You're not under any obligation to participate in their project. More commonly, it's some script kiddie sans clue. – cas Jan 16 '18 at 15:52
2

Okay, fail2ban doesn't work because the offending requests use a different ip address each time. 200, 403, 404 response all require the apache request to take up server resources.

Realizing that i wanted to just "drop the call" and have apache simply stop talking to the requestor, i was able to find that installing mod_security allows apache to be configured to drop all requests that match the virtual host of the server ip. Install mod_security on centos 7 was a breeze:

sudo yum install mod_security

Then i put these lines in the virtual host directive where the ServerName is the host ip address:

<VirtualHost *:80>
    ServerName 1xx.1xx.1xx.1xx

    SecRuleEngine On
    SecRule REMOTE_ADDR "^\d" "log,drop,phase:1,id:111,msg:'dropped bad host request'"
    ...

In firefox, accessing the server by ip now looks like this:

enter image description here

...good luck trying again!

in the server logs, the drop is being logged:

# tail -f 1xx.1xx.1xx.1xx-error.log
[Thu Jan 18 18:51:00.357113 2018] [:error] [pid 41716] [client 69.137.81.33] ModSecurity: Access denied with connection close (phase 1). Pattern match "^\\\\d" at REMOTE_ADDR. [file "/etc/httpd/vhost.d/ipaddyhost.conf"] [line "8"] [id "111"] [msg "dropped bad host access request"] [hostname "1xx.1xx.1xx.1xx"] [uri "/"] [unique_id "WmFA@q@5uqLACI9MKaxAAABbfwX"]

in other words, either you know my hostname, or you can talk to the ban

  • 1
    After reading your last comment to me about fail2ban not working due to too-dynamic ips I was going to suggest "well, now you have the traffic going to one spot, have apache do something about it with perhaps the require or similar parameter". Good to see you got a good solution worked out. – ivanivan Jan 19 '18 at 1:20
1

fail2ban has several rules for blocking IP addresses that scan or try to do bad things to apache servers, and you can write your own rules (e.g. to match "bad host requests" in the apache error logs) or add to the existing ones.

fail2ban is available pre-packaged for most linux distributions.

  • see my update on fail2ban and question about bad host requests potentially being valid. – WEBjuju Jan 16 '18 at 15:52
0

I would set up a new, fresh catch-all virtual host (ie, a default for any name that doesn't match your real/configured name). Set the custom 404 error to redirect to google or similar, and as mentioned by others here set up fail2ban to monitor the logs for that catch-all host.

  • i've wondered what to do with the traffic...i have the requests concretely identified now and can handle them within the current vhost. but redirecting them opens up the server to an attack. it would allow them to pummel us with requests that our server would then have to be busy redirecting, thus putting an extra load on it. – WEBjuju Jan 16 '18 at 15:55
  • @WEBjuju how would the redirect load (until fail2ban kicks in) be any different from the load of serving up the index file or a 404 error on the default host? – ivanivan Jan 19 '18 at 0:07
  • hmm, well, i suppose i'm thinking about reality and potential reality. the reality is that fail2ban won't fix my current problem. the potential reality is that redirecting the traffic, i believe, is more work on the server than just serving up a page (200 or 404). what i want to do is "cloak" - not even be there at all. is there a way to instruct that apache just ignore and stop processing that request? just like "drop the call"? – WEBjuju Jan 19 '18 at 0:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.