Automatically blocking botnet scanners from a subnet?

Hi, I’m running a PPtP VPN server on my Omnia, with pretty strong passwords. It is the only service with a port open to the whole internet. Thus, I see regularly in the log that some botnets are trying to scan my network and login with some (probably dictionary-based) passwords. I’m pretty sure my passwords are strong enough to withstand these dictionary-based attacks.

However, if somebody started brute-forcing, there’s no rate-limiting on the side of Omnia. My passwords should also be strong enough to withstand brute-forcing, but I’d like to minimize the chance of bad luck (or the attackers good luck).

Is there a simple way to temporarily ban connections from a subnet that evidently acts as a botnet?

I only connect to the VPN from my other Omnia (which creates a persistent VPN bridge), and occasionally from my own devices when I’m travelling. I definitely use saved passwords in all of my devices, so even a rule banning somebody on the first unsuccessful login would be good enough.

Do you know of a good solution, either on the level of the ppptp daemon, or more generally, at the firewall level?

I offered Turris team to add the unsuccessful PPtP VPN logins to the distributed threat recognition model, but they said they’re not interested (so far).

And for those of you commenting on PPtP VPN as a technology - please don’t comment. I don’t care about confidentiality of the data. I only use it as a geoblocking proxy.

  • packet rate limiting via firewall
  • banip package
  • port knocking with knockd

Thanks for the tips.

Rate-limiting would decrease the speed for my devices, wouldn’t it? The botnets aren’t really intensive, it is a few tries per hour.

banip is for manually adding a set of IPs? I’m seeking an automated solution…

port knocking - that would probably complicate connection from devices like windows or android, wouldn’t it?

It should not:

  • assuming the VPN server instance runs on the router (not a client or in a lxc container)
    • rate limiting would need to be applied to:
      • INPUT chain
      • destination interface WAN
      • destination port VPN
      • new connections (not established, related)

Cannot say really since not leveraging it, just had a brief glance here [1]. Utilizing some of the supported block/black list may already prevent those malicious actors

Way back I used this script set [2] on Linux boxes and that provides the functionality you are seeking - you may have a look at their code and construct a script that serves your purpose. Basically it needs reading the firewall log, sort the bad IP (subnet, ASN) and add those to an IPset (permanently or temporarily for some time).

Then there is the Sentinel project by NIC.CZ which may also offer such functionality, but I have not looked into it.

On my nodes I leverage nftables with rate ingress limiting on the WAN netdev (prior it reaches the kernel for processing) plus sets of block/black lists from public sources plus scripting bans into sets for whatever still gets through.

As it often is the case when increasing security… …indeed the client would need to be able to perform portknocking…

[1] banIP support thread - Community Builds, Projects & Packages - OpenWrt Forum
[2] ConfigServer Security and Firewall (csf) – ConfigServer Services

I’m thinking of the rate-limiting solution as you stated it, and if it were only applied to new connections, it should not slow down the regular traffic. However, I’m still a bit concerned if there is a good constant for the rate limit. As I said, the attackers are trying pretty slow. And sometimes I travel by train and need to reconnect after every tunnel (every 10 minutes or so). But setting a rate limit to something like 10 connections per hour would really at least stop the possible brute-force attacks.

I am using Sentinel, and I wouldn’t like to re-implement its behavior using other blacklists, because I think it already is a good source of blacklists. So I’d only use the banip package to ban the IPs which prove to be VPN attackers…

The configserver looks like a pretty big thing for the small functionality I want. And it doesn’t say it supports VPN failed logins. But you’re right I might get inspired in their code. I was also thinking that (unfortunately) log parsing would be the way to go.

If I’ll come up with something, I’ll post it here. But other ideas are still welcome, too.

If the VPN client app supports packet marking then the clients would be distinguishable and could be exempted from the rate limiting - it would make uneconomic/unattractive for the malicious actor to probe with packets marks.

Consider running the VPN server on a UDP port instead of TCP, it is not a silver bullet but more difficult to probe. Use a port from the range 49152 to 65535, also less attractive than well known ports.

Consider WireGuard as VPN solution - no passwords involved just sets of public/private keys that have to match.

I’m afraid PPtP doesn’t allow anything else than 1723/TCP. It’s hardcoded in the protocol :frowning: Otherwise I’d change the port already. I’m thinking about switching to OpenVPN/Wireguard, but I’ll need to make sure all my possible client devices (Windows, old Androids, Linux…) support it.

OpenVPN should not be an issue with any client. WG on Linux client should be fine, have not tested with W, Android may depend on the OS version and/or the kernel implementation from the handset vendor.

Take a look at fail2ban. I have no experience with it for a pptp server and on Turris OS/OpenWRT but it may fit your needs :).

1 Like

I’m looking into it :slight_smile: I found, however it bans also authorized connections once they disconnect :smiley: But I’m working on a log postprocessor that would help this…

… running that tunel behind dnat won’t help with easier trafic control ?
… also why not just ban all and allow only those few trusted ones ?
… i would switch to openvpn or wireguard if possible.
… that fail2ban seems promising (i might use it for my openvpn instance as well)

btw: that botnet knows your username or is it brute-forcing it as well (so you can create also very strong username :slight_smile: )

What do you mean by DNATting the tunnel?

There is no canonical list of trusted IPs - I need to connect from mobile networks, hotels etc.

I’m working on the fail2ban solution right now.

For PPtP, you also need a username, and I use a “nondefault” one, so this is one of the things that will also make it possible to write more strict blocking rules (i.e. give him 3 attempts when username is correct, but block him instantly if username is wrong).

i just read it while browsing about this topic,… so i just mention it… i can’t find that post anymore :smiley: , but maybe this is nice article Running a PPTP Server Behind a NAT Firewall | Troubleshooting Linux Firewalls

Sources’ (clients’) stable MAC addresses are known however and since being transmitted in the packet data are filterable via IPT. Whilst MAC addresses are spoofable it would be rather uneconomic for the probing party to run a brute force attack with variables of spoofed MAC + username + password.

Potential caveat is Android, contemporary versions seem to assign temporary MAC instead of stable.

I invested some time and the result is a fully working fail2ban installation on Turris OS 3.x and 5.x.

Moreover, I added essential support for banning PPtP VPN failed authentication attempts. It is also possible to block the whole /24 subnet of the attacker (as a rough rule of thumb).

You’ll find the necessary software and manual at .