I write on, and

Cyber wars: Defending your server

Photo by Saksham Gangwar on Unsplash

My contact forms don't work anymore?

I maintain my own mail-server using postfix & dovecot on an amazon ec2 linux instance. Sure, I could use amazon's SES service, but not only am I cheap, but a geek. Such a service is a commitment: next to the obvious security challenge, one get's to become familiar with things like dmarc and spf, as well as protocols like imap.

First slow, then impossible

It started a few days ago: My server became slower and slower. It took me a while to suspect something going on, as traffic to some of my sites was high recently and I am using a nano-instance. So my first instinct was to scale the instance. Due diligence let me to first check some logs, though.

Ireland & Russia: intercontinental rockets coming in

What I saw was astonishing. From various different IP addresses associated with Irish and Russian server farms my server was targeted with brute-force attempts both to see what email addresses exist (checking for rejected recipient addresses) as well as SASL login attempts. As soon as the quota for unsuccessful attempts was reached, the next attempt came from a different IP.

Someone is looking to take over my server to send out spam?

Although my fort held, the massive traffic brought my server to it's knees. Service interruptions and slow delivery was the least of my problems. At the end of the day, it was only a question of time: brute-force always works. It's just a question of how long it takes. And needless to say, with aws I pay for computing.

First counter: block IPs for a longer period after the second unsuccessful login attempt and limit simultaneous connections from the same client

It seemed like a logical first step, but you probably already guessed it: the remote IPs just changed more frequently. I suppose whatever script they use is adaptive.

Let's go Confucius on them

Have you ever wondered why your bounces take so long to be reported back to you? I always wondered why I receive a "failed to deliver" notification hours after I tried to reach someone. But in this context, it all of a sudden made sense. Your script wants to know whether the email "" exists? How about I just accept that email for now. I was aware that I had to take into account that legitimate senders must eventually be informed, but first I had to see if this actually works.

Rockets are stupid

Well, so the behavior didn't adapt, but it also didn't stop raining incommings on my server. As a matter of fact, now it was assumed that emails were found so login attempts on these (non-existing accounts) started to ramp up. Uff. So traffic got even worse.

The emperor's new clothes

Hold on! I am thinking defensive. Attack is the best defense, isn't it? So what's the endgame here? The attack is likely targeted at using a mail server to send out spam. And the mails will likely include links to malicious pages using email addresses bought in the dark net. With many options to report sites to blacklists and to inform about leaked emails, wouldn't it be interesting to know what those emails contain and simply report any hyperlink in them directly without these emails ever reaching the victims?

A different kind of honeypot

My plan was simple: Let's create the accounts they are trying to log in with on the fly (or at least almost, am fighting with some delays here and there) and use a rainbow table to give these accounts the most common passwords possible. They will be able to generate a successful login fast. However, instead of letting these accounts send out emails, let's limit their quota to 0 and put those emails in a folder for further processing. However, in order for this to work, we must influence the smpt response appropriately to keep the impression that the mail has been sent out.

NOTE: While I would love to go into more detail here, I cannot share some modifications until I am certain such activity isn't traceable or poses any other kind of risk or negative effect.

The battle is over, but the war goes on

Not even a day later they successfully logged in. To my surprise, no emails have been sent out yet. I don't know the business model, but maybe at that point these credentials are sold and another group or individual does the actual mailings. However, that gives me some time. I still need to process the emails and automatically report the links and recipients.

Join the rebels

So here is the long-term plan: If this works out, I want to lift such methods to an open source level and enable webmasters to join forces. What I don't know at this point is how expensive this is going to get for me. I applied common limits but who knows how much data is going to be sent to my server. I'll let you know...

Install PHP 8 on Ubuntu

PHP8 has finally been released and it is FAAAAST! Time to update.


6 Technologies to look at in 2021

2020 wasn't the best year humans can look back to. but what does 2021 bring for coders?


CSS Grid or CSS framework - are they really exclusive?

Grid-based or framework - there are many articles about this choice. But why is that even a thing?


Scaffolding REST APIs with JWT authentication

Ever had the need for your own backend while developing your web-app?


What is composer?

Composer has become PHP's package & dependency manager. Why you should use it.


MySQL: ERROR1364 fix

The painful realization of why people use containers.


Cyber wars: Defending your server

Maintaining your own server can be a thrill. High security standards can protect you from data leakage, injection attacks and DDoS attempts. But what about adaptive brute force?

Git: globally change GitHub-remotes from git@ to https

Does your IDE or composer set remote repositories to ssh rather than https? Or are repositories you are using set up that way? You are not alone. Let's fix it once and for all!

VueJS & neoan3: a love story.

Setting up neoan3 to play nice with Vue isn't hard. Here is how the two frameworks are combined to support fast, dynamic and rapid development.


MySQL in PHP - how to deal with databases

How I handle MYSQL database transactions in PHP

Install PHP 7.4 on Ubuntu

Finally PHP 7.4 is out! You have read about the new features, you have followed externals, you have gathered ideas on how new capabilities will save time. Let's get it running.

How to install global npm packages without sudo on Ubuntu

Running npm on a server can be painful. Privileges are there for a reason, and so is sudo. Running npm with sudo is not the solution.


Static content pages - still the fastest web-experience

Tutorial: How to utilize to generate static content for your website.

image PHP SDK

Create your own blog.

image plugin for headless CMS (part 2)

A solution to supplying plugins to


Cross publishing to

How to publish your content to from - hopefully

Transformer - falling in love with PHP's magic methods all over again

PHP's magic functions have been around for a long time. But there were always good reasons to avoid them. Transformer is a practical and reliable way to make use of the most common operations we program: CRUD operations.

The Uselessness of Pre-Assessment

After almost two decades in the industry, new jobs will still ask you for "assessment tests". A little rant...


SEO strategies for

How to get your content listed where you want it to.


How to Build an Express App in Node That Reads From a Headless CMS

A headless CMS lets you design your own front-end, sometimes your own back-end. Let's set up a small application to get us started. Beginner friendly. Approx. 20 min. to reproduce / follow along


Help us document neoan3

Over 4000 brave developers are exploring the framework on their own.


When politics kill innovation

How misunderstood diversity killed the PHP Central Europe Conference for good.