1

I am under DDoS. What can I do? already addresses this kind of "canonical question", but I think I'm asking a distinguishable variant, as described below. But please advise if this post inappropriate.

The attacks I'm getting are from various and ever-changing ip's; in the last few minutes from 66.135.63.82. All attacks are against a cgi I'm using on my site that I wrote myself (it's gpl'ed http://www.forkosh.com/nutshell.html but not really of much interest to anybody but me (and, apparently, the hacker)). Attacks run my cgi with a goofy-looking ?query_string, and I added a qvalidate() function that seems to be reliably identifying them, so far. And for invalid queries, I now sleep(15) and then emit a ~25MB page to the attacker (just to show I can be annoying, too:). And they do seem to wait -- rather than multiple attacks per second, they're now spread out at approximately those 15-sec intervals.

But this semi-fix seems silly and ultimately ineffective in the long run. And it wastes lots of my time checking up on things several times a day, and occasionally tweaking the procedure. So what I'm asking is -- what can I code into my cgi to better deal with these attacks as they occur??? I have the attack in my hand, so to speak, in realtime as it occurs. And I have the ip from a getenv("REMOTE_ADDR"). So I can do pretty much whatever I want at this point (except bleep the bleep out of him, which is what I'd really like to do, but don't know how to code that:). What would be the best thing to be doing? Thanks.

edit -- Thanks for replies, guys. I should have mentioned my site is on shared host dreamhost.com so some suggestions are unavailable to me. And I'm waiting for a reply from isp. But since it's my own cgi that's targetted, I was hoping that gave me an opportunity to do something not usually possible.

edit -- @HBruijn Why off-topic? At the very top of this post, I gave a link to this site's "canonical question" also on this very same topic. And then I went on to explain why I thought I was asking a "distinguishable variant" of that (apparently on-topic) question. Moreover, I originally posted https://softwareengineering.stackexchange.com/questions/316052/how-to-best-deal-with-ddos-attack-against-your-my-site and they told me to post it here. Go figure:)

John Forkosh
  • 113
  • 6
  • 1
    If you send them a 25 MB document you will end up DoSing yourself. Define what constitutes a valid query string and stop processing as soon as you find an invalid query string. Then blacklist the IP address for some time to avoid it from using up your resources. – Oliver Apr 18 '16 at 12:32
  • 1
    It seems question is about general hacking (that is, trying to access stuff that you are not authorized to), not DDoS. DoS means denial of service - attacker is trying to prevent legitimate users from accessing the service. DDoS is distributed DoS: attack made by multiple devices from multiple networks. – kubanczyk Apr 18 '16 at 12:33
  • @Oliver Thanks. Yeah, don't know what, if any, good/bad 25MB document accomplishes -- it just made me feel better:) And for ip aaa.bbb.ccc.ddd I'm already adding a deny from aaa.bbb. to .htaccess after >100 consecutive invalid queries from that ip. But now I've got hundreds of such deny froms, so it's not really a long-term solution. – John Forkosh Apr 18 '16 at 13:03
  • @kubanczyk Thanks, but I think it's more of a (d)dos attack. Attacker doesn't really seem to be trying to "access" anything -- ?query_strings are all just goofy-looking. He might be hoping to segfault the cgi and then do something, but without the sleep() I'm getting dozens of hits per second for maybe 400-500 hits from one ip. Then the same from several more different ip's. Then quiet for an hour or two. Then the same thing all over again from all-new ip's. Seems more like ddos to me, though not as fierce as most (not that I'm complaining). – John Forkosh Apr 18 '16 at 13:11
  • Actually, what is it exactly that bothers you? Is it just the fact that you have these entries in the log file or do these attacks cause any other harm to you? – Oliver Apr 18 '16 at 13:37
  • @Oliver Harm before I added sleep(). Before sleep() I was getting dozens, up to maybe 100-200_hits/sec. I first noticed that when ssh'ed into site's shell account, and everything stopped/hung. And then I further tested and found web access also timed out during these attack periods. And besides that, I'd plain-and-simple like to stop attacks -- now, before things maybe get worse ("a stitch in time" and all that). – John Forkosh Apr 18 '16 at 13:50
  • I see! I think you did pretty well actually. – Oliver Apr 18 '16 at 13:58
  • @Oliver "did pretty well"? Isn't that what they told the captain of the Titanic? – John Forkosh Apr 18 '16 at 14:05
  • 1
    @JohnForkosh : Your edit that you're using **shared hosting** means you don't have the required root/administrator privileges that the ServerFault community expects. **That** is what makes your question of-topic. You simply won't be able to follow recommendations you'll get here on ServerFault, such as the one below to install `fail2ban`, as those almost always will assume and require that you're the actual person managing the server or network. – HBruijn Apr 19 '16 at 09:40
  • @HBruijn Okay, fair enough, thanks. But mcOe's comment below does seem to have solved the problem about as well as I can imagine it being solvable under these (non-root) circumstances. Also, I think stackoverflow would've been maybe even more off-topic: I wasn't asking >>how<< to code anything, but rather >>what<< functionality to code. And I've seen stackoverflow stuff downvoted/put-on-hold with remarks like "It's not clear what you want to do." And that's my problem -- I didn't know what to do. Once mcOe suggested >>what<< to do, I coded it in <30mins; no stackoverflow help needed. – John Forkosh Apr 19 '16 at 10:04

1 Answers1

2

I'd first use fail2ban to watch the web server log, and any time it sees a dodgy hit, firewall that ip for the next hour or something along those lines. However that relies on having root access to your server to manipulate the firewall.

There are third party services like cloudflare who can clean up your traffic before it gets to you. Their services range from free to expensive. Look over the options and see if anything useful fits your budget.

You might also want to talk to your hosting provider, who presumably have root access to your server if you don't, and may have a range of other ddos mitigation options, either through running the servers and network, our through subscription to third party ddos services along the lines if cloudflare.

Don't bother putting a sleep in your code. It hurts you more than them (if they issue requests in parallel, you run out of memory faster). Drop bad connections as fast as you can.

mc0e
  • 5,786
  • 17
  • 31
  • Thanks, mcOe. fail2ban.org looks great, but I'm on a shared host (no root access). And budget=0; site's basically just a wrapper for my resume (I'm an independent s-corp consultant), so cloudflare's out-of-reach -- I didn't check them out carefully, but am guessing any "free" service is just a gateway to their for-fee service. Meanwhile, I'm awaiting an isp reply, as per edit above. And I'll double-check sleep() effect. It didn't seem to put any added load on server, or spawn lots of processes, etc. But I'll try to check more carefully. – John Forkosh Apr 18 '16 at 12:57
  • Oh, I forgot to reply to parallel/memory. Attack seems to be sequential. The cgi always kept its own log, and now I have two more logs for invalid queries -- one log with timestamp and complete info, as usual, second log with just one line containing "timestamp ### ip address ### aaa.bbb. part". Then I have a bash script to awk/split|sort|uniq -c|sort so I get a short list of unique attacking ip's with the worst ones on top. But the logged timestamps (that are awk/split away) show sequential requests -- so far, at least. And sleep() spreads them out -- so far, at least. – John Forkosh Apr 18 '16 at 13:32
  • 1
    Without write permissions, you could still look at automatically updating an `.htaccess` file to block by IP, which lets you drop the request that little bit quicker. I do recommend though that you track how long each IP has been blocked, and remove the rule after a while since attackers may use proxies, VPNs etc with shared IPs, and others may subsequently be assigned the same dynamic IP they had. – mc0e Apr 19 '16 at 04:22
  • 1
    Are the attacking IPs servers or compromised systems on ADSL and similar connections? – mc0e Apr 19 '16 at 04:23
  • Thanks again, mcOe. Don't know type of connections -- how would I go about finding that out (couldn't get google to cough up an answer)? And, yeah, I'm already updating .htaccess, but manually, although that awk|sort|uniq stuff leaves me with a file I can just cat to the end of existing .htaccess. But I haven't felt comfortable automatically modifying .htaccess yet, but maybe you're right that's what's needed. And such a program could keep track of times when "deny from"'s were added, to be later removed. I haven't been manually doing that at all. The more I think about it, the more I like it! – John Forkosh Apr 19 '16 at 06:37
  • Continued... I especially like it because, in my case the 15-sec sleep() delay I've imposed on sequential attacks (as long as they remain sequential) leaves the program plenty of time to modify .htaccess while the attacker is waiting for his first hit to complete. Then his second and subsequent hits will just fail. And, like you say, I can automatically remove stale "deny from ip"'s after awhile... Still liking it more and more! – John Forkosh Apr 19 '16 at 06:44
  • Okay, I "checked" your answer, but it's mostly your "automatically updating .htaccess" comment that the check refers to. Took some 10 minutes (how hard is an appendline(file,line) C function?:). Then made an .htaccess-template file containing all my usual stuff, but without all the "deny from"'s. Then cp'ed that to (working copy) .htaccess and put the modified cgi in place. Fifteen seconds later it had five new "deny from"'s. But one and only one hack attempt from each ip, not hundreds and hundreds. Great!!! No automatic remove stale deny's yet (I'll start over with the template daily). Thanks – John Forkosh Apr 19 '16 at 08:07
  • 1
    You might find it useful to put a timestamp in a comment after each ip in the .htaccess file. It's then easy to write a cron script which removes stale entries, without needing separate storage for the expiry data. – mc0e Apr 20 '16 at 14:36
  • Yeah, "deny from a.b.c.d ###HACKEDAT date/timestamp" would make it pretty simple to parse through .htaccess (where keyword HACKEDAT signals lines to be checked). I didn't originally bother to save time -- not coding time so much as quality assurance, since there's more opportunity for small blunders to creep in. Moreover, it may not be necessary at all. Now that I've had more time to carefully study the logs, it looks like the actual hacker has acquired a smallish stable of maybe several hundred ip's he's using over and over. So, for now I'll just leave them all denied. – John Forkosh Apr 21 '16 at 03:42