
My first DDoS attack for a $200 ransom - LaurentGh
http://ghirardotti.fr/symfony2/2016/04/04/DDoS-attack-for-ransom/
======
tyingq
Roughly, a somewhat lackluster response to a somewhat lackluster DDoS attempt.

They tried blocking specific ip addresses, which didn't work, because the
attack was somewhat distributed. They then just turned on some caching, which
allowed the site to function, albeit with an unknown excess bandwidth charge
pending.

And, the DDoS itself can't of been terribly impressive, as all it took to
mitigate was a bit of caching. He mentions 10 requests / sec as the scale of
the attack.

~~~
SomeCallMeTim
I was shocked that 12 requests/second could take down _any_ site.

I use async logic (previously OpenResty, more recently NodeJS and Go) and
largely pregenerated sites, so 2500 requests/second is a minimum baseline --
on a much lower end instance than an m4.xlarge.

There's a reason I don't use PHP (or any primarily synchronous language like
Ruby) any more.

~~~
WillPostForFood
The language used is meaningless absent the context of the whole application,
especially the database. I can do 2500 requests a second with ruby or php on a
micro instance on AWS. But that's meaningless after I plug into a mysql
database that's going to bottleneck at 2 requests a second after i try to
render abad wordpress theme out of MySql.

~~~
SomeCallMeTim
That 2500 is after taking into account relevant database queries. With async
servers (which, as far as I know, PHP _can 't_ be, at least with the way it
typically integrates into Apache) you can accept all the requests, forward off
the database requests each depends on, and still send back the pages to
everyone who requested one.

Of course I've avoided WordPress and similar frameworks for years for a reason
as well; I've seen front-end frameworks that require dozens if not hundreds of
database queries to render a page, which is such bad design that it makes my
brain hurt.

~~~
tyingq
node.js does have it's advantages, but it's possible to be very fast with php.

For example, the advantage of the "warm app" with node is often approximated
by using a shared memory kv store in php.

And, while an async io approach scales in a simpler way, you can typically
find an optimum tuning for fastcgi that scales very well.

Looking at this benchmark:
[https://www.techempower.com/benchmarks/#section=data-r12&hw=...](https://www.techempower.com/benchmarks/#section=data-r12&hw=peak&test=query)

There are php-fpm implementations running at the same clip as node, and an
hhvm implementation trouncing it.

Yes, benchmarks are sometimes bullshit, but the idea that node's approach is
somehow light years ahead just doesn't pan out in the real world.

~~~
SomeCallMeTim
>benchmarks are sometimes bullshit, but the idea that node's approach is
somehow light years ahead just doesn't pan out in the real world.

It's in the real world where you have database connections that can't always
scale to 186k/second with low latency on all responses, which is what's
required to get the performance out of HHVM in the linked benchmark. In a
typical architecture you may not have the database local to the PHP server,
meaning latency will be much higher. And it's upstream latency that kills a
synchronous connection.

And it's in the real world where a number of third party queries may be
involved with a request, and those queries may take 100ms to resolve, during
which time your thread is blocked in PHP whereas Node can be busy handling
other requests or even other aspects of the same request (a Promise.all of a
half dozen simultaneous database queries, for instance).

Async approaches _are_ light years ahead in the real world. I keep seeing
references to HHVM when people try to defend PHP, so I did a Google search to
find out if it supports async, and the answer is "a little bit." [1] Basically
it looks like, _within a single request_ , it can execute several queries in
parallel, like my Promise.all example above. So it looks like Hack, at least,
has that feature. But as far as I can tell it doesn't mix multiple connections
in a single thread. And you have to be careful to use only async-aware
operations or you lose the benefits; Node is designed around async behavior,
so everything you're likely to use supports it by default.

Those benchmarks are in fact unrealistic. And the Node implementation in that
benchmark uses a single connection to MySQL, so the 20 queries are actually
executed in series instead of in parallel. [0] If they used a connection pool
instead, they could all execute in parallel. Look at the numbers:

Queries 1 5 10 15 20 nodejs 85,490 22,917 12,083 8,250 6,254 hhvm 12,369
12,428 10,056 10,394 9,322

The NodeJS results shouldn't drop that fast off of the single query unless
they're all using the same MySQL connection; even using just 4 connections
from a pool should speed it up by a lot. Also, the HHVM source uses stored
procedures while the Node version recompiles the query every time. Finally,
Node can be faster when driven from Nginx, while it's using the internal Node
server instead.

Here's an article I just stumbled across that talks about the limits of HHVM
to accelerate PHP: [2] It touches on some of the same points. Async is the
important way to speed up real world apps, and it's not the default "PHP Way."

Aside from that, probably 90% of the people using PHP are using it "normal"
PHP on a hosted server in Apache and not HHVM at all. So you're basically
arguing hypotheticals: "IF they use HHVM, and IF they write the code exactly
right, and IF their upstream servers have really low latency all the time,
then PHP isn't much slower than Node."

Node is usually faster in the real world given common coding patterns. And
Node gives you Socket.IO, which pretty much kills the relevance of PHP no
matter how you slice it. Even long polling would slaughter a PHP server; you'd
be able to support at most one concurrent user per thread. Async servers are a
good at supporting long running connections.

[0]
[https://github.com/TechEmpower/FrameworkBenchmarks/blob/mast...](https://github.com/TechEmpower/FrameworkBenchmarks/blob/master/frameworks/JavaScript/nodejs/handlers/mysql-
raw.js)

[1]
[https://docs.hhvm.com/hack/async/introduction](https://docs.hhvm.com/hack/async/introduction)

[2] [http://www.infoworld.com/article/2948132/app-
servers/hhvm-38...](http://www.infoworld.com/article/2948132/app-
servers/hhvm-38-can-speed-up-php-but-only-so-much.html)

------
brbsix
The webpage[0] seems to be having issues. The best I could do was the Google
cache[1] or the Markdown source[2].

[0]: [http://lologhi.github.io/symfony2/2016/04/04/DDoS-attack-
for...](http://lologhi.github.io/symfony2/2016/04/04/DDoS-attack-for-ransom/)

[1]:
[https://webcache.googleusercontent.com/search?q=cache:J7lca_...](https://webcache.googleusercontent.com/search?q=cache:J7lca_k5dWcJ:ghirardotti.fr/symfony2/2016/04/04/DDoS-
attack-for-ransom/+&cd=2&hl=en&ct=clnk&gl=us)

[2]:
[https://github.com/lologhi/lologhi.github.com/blob/master/_p...](https://github.com/lologhi/lologhi.github.com/blob/master/_posts/2016-05-04-DDoS-
attack-for-ransom.md)

------
ultramancool
This is an amazingly weak DDoS, put your site behind CloudFlare or similar
free service and go take a nap. They'll tank this without raising an eyebrow.

~~~
ninjakeyboard
probably because I've been playing an mmo, but i like the use of the word
'tank' here

~~~
drostie
The etymology here is actually really interesting. The term "tank" was an
Americanism for a swimming pool once upon a time, and the etymology of that is
pretty well-known: it was imported from a Portuguese word meaning "pond" which
ultimately came from India [1]. The same source quotes a 1960s usage of the
term for "failure" in the sport of Tennis.

The term actually seems to come from a 1920s boxing euphemism [2]: when a
boxer is not actually knocked out but voluntarily lays down on the ground, it
was called "a dive" for obvious reasons; euphemistically some people called
this "going into the tank," since you'd dive into a pool.

How did this start referring to the vehicle? Again, back to [1], there was
once a memo "recommending the proposed "caterpillar machine-gun destroyer"
machines be entrusted to an organization "which, for secrecy, shall be called
the 'Tank Supply Committee,' ..." and the rest is history.

[1]
[http://www.etymonline.com/index.php?term=tank](http://www.etymonline.com/index.php?term=tank)

[2]
[http://www.slate.com/articles/news_and_politics/explainer/20...](http://www.slate.com/articles/news_and_politics/explainer/2008/10/explainer_goes_in_the_tank.html)

------
adrianpike
> 40 cores [m4.10xlarge], but still unable to process 10 requests/sec

my goodness.

~~~
cpncrunch
That's php for you. Although I use php myself quite often, it can be a
resource hog if you're lazy about optimization. A customer I was working with
was using wordpress, and their homepage took about 5 seconds to load due to a
hideously inefficient wordpress module that was doing the exact same sql query
thousands of times! With a little bit of optimization I managed to get it down
to about 1 or 2 seconds.

For my own sites, I mostly use static html or server-parsed html.

~~~
tcdent
The overhead of an SQL query has nothing to do with the language you're using.

~~~
cpncrunch
Of course I'm aware of that. I was just giving an example of a specific case I
came across. The point I was making is that there is a lot of inefficient php
code out there.

~~~
27182818284
Recently a colleague and I took a PHP+MySQL page that was taking 1-2 minutes
to load and were able to drop it down to 30 seconds after our first round of
revisions. After a second round of revisions, we got it under 15 seconds, then
after another round we got it to the 1-5 second range. Most of the
optimizations were in the PHP not in the SQL.

------
otto_ortega
Ummmm.... A cache layer for any web application is a must have, perhaps he
could have avoided the attack all along if it were present on the system since
day one?...

At least for this kind of attack, a more serious DDoS won't be tamed by "just
adding cache"

~~~
cortesoft
Well, when your DDOS is '10 requests a second', your site is probably not the
most sophisticated.

~~~
LaurentGh
Haha, true! But please share your personal DDoS experience is mine is not
large enough :p

~~~
cortesoft
I also hope I didn't sound too insulting. I know keeping any site up against
DDOS is hard!

~~~
LaurentGh
No it's ok! Thank you ;-)

------
woud420
For next time you don't want to have to copy and paste. No need for SED.

cat <file> | cut -d ' ' -f1 | sort | uniq -c | sort -nr

~~~
xlucas
no need for cat

~~~
woud420
You're correct, force of habit.

------
jasonlfunk
Apparently, it didn't work. :)

Site not installed The site ghirardotti.fr is not yet installed

[Edit: it's up now.]

~~~
jasonlfunk
Though, it is interesting how an article with a dead link made it on the
frontpage with 3 points.

~~~
LaurentGh
And there are 73 persons on it right now if I believe Google Analytics

~~~
barkingcat
[ Edit: I'm almost certain it's an ipv6 vs ipv4 issue. the ipv4 addresses
resolve to github pages land, the ipv6 address resolves to somewhere inside
OVH - the issue being that if the viewer's network infrastructure prefers
ipv6, they will get a holding page from OVH stating that that "Site not
installed / The site ghirardotti.fr is not yet installed" ]

Dig:

    
    
      dig ghirardotti.fr
      ;; ->>HEADER<<- opcode: QUERY, rcode: NOERROR, id: 19860
      ;; flags: qr rd ra ; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 0 
      ;; QUESTION SECTION:
      ;; ghirardotti.fr.	IN	A
    
      ;; ANSWER SECTION:
      ghirardotti.fr.	3112	IN	A	192.30.252.154
      ghirardotti.fr.	3112	IN	A	192.30.252.153
    
      ;; AUTHORITY SECTION:
      
      ;; ADDITIONAL SECTION:
    

Both ip's belong to Github, probably used as a failover/load balancing/round
robin pair of some kind.

reverse dns

dig -x 192.30.252.154

    
    
      ; <<>> DiG 9.8.3-P1 <<>> -x 192.30.252.154
      ;; global options: +cmd
      ;; Got answer:
      ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 46826
      ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
    
      ;; QUESTION SECTION:
      ;154.252.30.192.in-addr.arpa.	IN	PTR
    
      ;; ANSWER SECTION:
      154.252.30.192.in-addr.arpa. 3593 IN	PTR	pages.github.com.
    
    

dig ipv6:

    
    
      dig AAAA ghirardotti.fr
    
      ; <<>> DiG 9.8.3-P1 <<>> AAAA ghirardotti.fr
      ;; global options: +cmd
      ;; Got answer:
      ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 0
      ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
    
      ;; QUESTION SECTION:
      ;ghirardotti.fr.			IN	AAAA
    
      ;; ANSWER SECTION:
      ghirardotti.fr.		1613	IN	AAAA	2001:41d0:1:1b00:213:186:33:19
    
      ;; Query time: 91 msec
    

Reverse dns on that:

    
    
      dig -x 2001:41d0:1:1b00:213:186:33:19
    
      ; <<>> DiG 9.8.3-P1 <<>> -x 2001:41d0:1:1b00:213:186:33:19
      ;; global options: +cmd
      ;; Got answer:
      ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 25262
      ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
    
      ;; QUESTION SECTION:
      ;9.1.0.0.3.3.0.0.6.8.1.0.3.1.2.0.0.0.b.1.1.0.0.0.0.d.1.4.1.0.0.2.ip6.arpa. 
      IN PTR
    
      ;; ANSWER SECTION:
      9.1.0.0.3.3.0.0.6.8.1.0.3.1.2.0.0.0.b.1.1.0.0.0.0.d.1.4.1.0.0.2.ip6.arpa. 
      85728 IN PTR cluster010.ovh.net.

~~~
cpncrunch
If they're using OVH they already have free DDoS protection. I use OVH myself
and I've had a few mitigated DDoS attacks that I barely noticed.

Perhaps 10 requests/sec is below OVH's detection threshold. My last one was
8.4Gbps @ 1 million packets per sec. 10 requests/sec would be difficult to
even notice :)

~~~
LaurentGh
Nope, OVH is just for our domain name. Also is talking about my blog, not
[https://www.villa-bali.com](https://www.villa-bali.com) website, which is on
AWS.

------
st78
Well, typical SLA for server side is 500 ms, then you have a chance to load a
whole page under 3 seconds, which is recommended by google usability findings.

villa-bali is not even close to this, my bet that you (or your ORM) are making
too many requests to database. Try to record ALL requests to database during
page rendering and I bet you have about hundred. Check out following test
results:

8 test agents:
[http://loadme.socialtalents.com/Result/ViewById/57341f645b5f...](http://loadme.socialtalents.com/Result/ViewById/57341f645b5f160adca6c1bc)
\- 5% of users have to wait more than 2 seconds 16 test agents:
[http://loadme.socialtalents.com/Result/ViewById/57341f1a5b5f...](http://loadme.socialtalents.com/Result/ViewById/57341f1a5b5f160adca6c19b)
5% of users need to wait for more than 4 seconds.

Definitely, any bot can nuke your website easily​.

------
cft
How come the original post has 55 upvotes, but the karma of of original poster
is only 18 (6:33 PM GMT)?

~~~
kornish
Users receive one karma for one comment upvote, but one submission upvote
yields less than one karma for the user.

------
raverbashing
I wonder what would happen if GET / only returned a redirect to somewhere
(either an HTTP code or an HTML with
window.location='http:/yoursite.com/new_page'

------
placeybordeaux
> 40 cores, but still unable to process 10 requests/sec

Stopped reading after that.

