Yesterday I had the privilege of dealing with a WordPress pingback DDoS attack
on one of my sites. My hosting company, whom I pay for access to a DDoS
protection appliance, didn’t even notice anything. They deployed the appliance
at my request and the spike in inbound bandwidth subsided. Unfortunately, that
didn’t necessarily resolve my site’s responsiveness.
Upon closer inspection, my nginx
access logs were filling up with pingback
requests from IP addresses publishing a user agent that started with
“Wordpress/” followed by a version number. Never experienced this before so I
went on the defensive since my hosting company’s protection wasn’t enough.
First thing, I went ahead and blocked all traffic from systems with the
offending WordPress user agent. Now my logs are filling up with 403 errors from
these systems. MySQL and Redis were both experiencing dropped connections by
what I assume was because of TCP/IP port exhaustion.
I remember the last time I was faced with a DDoS attack, my hosting company
said there were too many IP addresses involved for them to simply block them. I
never did like that answer and I figured, what the hell, I should just go about
blocking the IP addresses.
Not knowing how many systems were involved with this attack, I went ahead and
wrote a small shell script to sniff my access logs for the offending user
agents, extract their IP address and then feed that back into ufw
as block
rules. Ended up being a one-liner:
tail access.log -f | grep WordPress | cut -d ' ' -f 1 | sed -e 's/^/ufw insert 1 deny from /' | xargs -I {} sh -c '{}'`
Not the most elegant thing I’ve ever written but it sure as shit helped to
mitigate the issue. The only bug that came up was that IPv6 addresses don’t
like to be inserted first with ufw
. This is because IPv6 address must come
after all IPv4 addresses. I handled some of those manually as there weren’t
that many.
Within a few minutes of running this script my site recovered and we were back
in business. You check out the list of systems that were involved in the attack
here. A lot of the systems are AWS instances, thinking it may be worth
it to block them indefinitely at this point as it’s the second time I’ve
experienced issues from Amazon’s servers.
Hoping this script helps someone out. YMMV depending on your webserver’s log
format but I think it’s straight forward enough to allow for some tweaking.
Written something better to combat WordPress pingback DDoS attacks? You better
post a link in the comments!