iptables

Block attacker IP addresses, four ways

If you run WordPress you’ve seen these in your web server logs:

132.232.46.230 - - [29/Oct/2020:13:58:41 -0500] "POST /xmlrpc.php HTTP/1.1" 200 259 "-" "Apache-HttpClient/4.5.2 (Java/1.8.0_151)" "-"
132.232.46.230 - - [29/Oct/2020:13:58:44 -0500] "POST /xmlrpc.php HTTP/1.1" 200 259 "-" "Apache-HttpClient/4.5.2 (Java/1.8.0_151)" "-"
132.232.46.230 - - [29/Oct/2020:13:58:48 -0500] "POST /xmlrpc.php HTTP/1.1" 200 259 "-" "Apache-HttpClient/4.5.2 (Java/1.8.0_151)" "-"
132.232.46.230 - - [29/Oct/2020:13:58:52 -0500] "POST /xmlrpc.php HTTP/1.1" 200 259 "-" "Apache-HttpClient/4.5.2 (Java/1.8.0_151)" "-"
132.232.46.230 - - [29/Oct/2020:13:58:55 -0500] "POST /xmlrpc.php HTTP/1.1" 200 259 "-" "Apache-HttpClient/4.5.2 (Java/1.8.0_151)" "-"
132.232.46.230 - - [29/Oct/2020:13:58:58 -0500] "POST /xmlrpc.php HTTP/1.1" 200 259 "-" "Apache-HttpClient/4.5.2 (Java/1.8.0_151)" "-"

Fucken scanners just slamming xmlrpc.php looking for a way in. When this happens CPU usage just goes through the roof for as long as the scan lasts and it could be five minutes, could be six hours, could be all week; before it ends. The gods help you if you’re paying by CPU usage.

So you have to block access to the file. You could just block all access to XML-RPC but doing this will prevent the WP mobile app from working.

We’ll just block that specific IP address but we need to be quick about it; just do a quick one liner on the terminal before the OS just topples over and becomes completely unresponsive or worse.

iptables

This should work for any Linux distribution that has iptables out of the box which is basically all of them.

# iptables -I INPUT -s 132.232.46.230 -j DROP
  • -I: Insert the rule as the first rule to be applied in the INPUT chain. You could use -A (append) but the sooner we get rid of that traffic the less work the CPU has to do.
  • -s: Source address, in this case 132.232.46.230, which belongs to Tencent.
  • -j: jump to the DROP target. If you use the REJECT target you’re just creating more work for the CPU.

Documentation here but the Ubuntu how-to is far more useful in getting people started.

pf

As it is part of both FreeBSD and OpenBSD base installations it should be enabled in /etc/rc.conf but from reading the (almost useless) documentation and looking around the web You need to fuck around with pf.conf first, then you can manipulate the table. This is the first result on the web when you search for “pf block ip address”. So no one-liner that can save your life.

Edit /etc/pf.conf and add

table <badhosts> persist
block on fxp0 from <badhosts> to any
  • Create table named badhosts, and set it to be persistent in kernel memory
  • Block, on interface fxp0 (you’ll want to change this), traffic from rules in the badhosts table to any destination.

Once you have this you can manipulate the table from the command line with pfctl

# pfctl -t badhosts -T add 132.232.46.230
  • -t means pfctl will manipulate the badhosts table
  • -T will show statistics
  • add address 132.232.46.230 to the table

Fucken hell FreeBSD documentation is the fucken worst. Dryer than Melania Trump’s libido. Now, reading through the OpenBSD pf documentation it looks like you can do

# pfctl -t badhosts -T add 203.0.113.0/24

Which will create the badhosts table automatically without having to fuck around with /etc/pf.conf. Don’t know if this will work on FreeBSD though.

ipfw

It is part of the FreeBSD base installation so it does depend on ipfw being enabled in /etc/rc.conf but it looks like you can go

# ipfw add deny all from 132.232.46.230 to any
  • Add rule denying any and all fraffic from 132.232.46.230 to any destination

At least these rules are succint and easy to read. Whomever wrote the documentation seemed to pay more attention to usage at least.

Still, fuck FreeBSD.

Windows

Super easy now that PowerShell is built into Windows itself:

PS C:\WINDOWS\system32> New-NetFirewallRule -DisplayName "Block traffic from 132.232.46.230" -Direction Inbound -LocalPort Any -Protocol Any - Action Block -RemoteAddress 132.232.46.230
  • -DisplayName: The human-readable name of the firewall rule
  • -Direction: Can be Outbound or Inbound. We want Inbound obviously.
  • -LocalPort: Going with any ports because fuck crackers.
  • -Protocol: Same, block all port
  • -Action: Block traffic
  • -RemoteAddress: Specifying only 132.232.46.230

The documentation for the commandlet is super nice. No, I’m not typing ‘cmdlet’.

The old way involved so, so manny clicks. PowerShell makes it easy.


Now all of the previous bits of code cease to have any effect after a system reboot so if you want the rules to be permanent… don’t. Blackhats will just scan from different hosts and different networks so blocking an IP address permanently is just unproductive.

A better solution is to use fail2ban:

There is also CrowdSec but I haven’t personally used them.

This post came to be cos I spent 30+ minutes trying to figure out how to block traffic on a FreeBSD host and their documentation is just… inscrutable. Should you ask for help in their forums you’ll just get told to RTFM.

You end up going in circles, consuming yourself in rage and frustration which does not feel nice. Rage-posting is where it’sat.

A Debian wifi router

The search of a living space has been over for over a month now and I’m more or less settled in. I had a bad experience with my previous landlord keeping my wireless router (an Asus AC-RT68U) cos he’s a fucking asshole so I decided to give this a shot. I’m actively trying to solve money now so it really wasn’t an option to just buy another one as my living costs are now much, much higher.

I’ve hoarded a bit of equipment so I did have a couple of computers available to me. With a bit of looking I found about hostapd and I got it to work more or less reliably on a Thinkpad X220 with an Intel Centrino chipset using the iwlwifi driver. The real problem started when I tried using my older Thinkpad T60 laptop for the same task. Mine has an Intel PRO/Wireless 3945ABG [Golan] chipset also using the iwlwifi driver but the crucial difference was that this chipset doesn’t support Master mode, so you can’t use it with hostapd to enable an AP. Looked around for a bit and tried using this Archer T2UH from Amazon but the support on Linux is a fucking joke, basically; they actually want you to compile the drivers from scratch to get everything going. Ended up with an Ubiquiti Networks SR71-C card using the ath9k chipset. I tried setting it up using the already-installed environment but I couldn’t get it work so I basically reinstalled everything from scratch to start fresh.

I pieced this together from instructions found on the Debian Wiki, this guide from Ars Technica on building your own router, hostapd documentation, and a whole host of blog posts detailing how to pull this off, most of them with information easy to mess up.

As it is right now I’m typing this up on a Windows 10 system connected to the laptop and the signal and throughput are good enough for extended sessions playing Unreal Tournament pre-alpha.

Install Operating System

Installed Debian Stable fresh on the system with no desktop environment. This computer will now be a router so we don’t need any kind of desktop environment. Most desktop environments now require NetworkManager or wicd to manage network connectivity and I wanted to avoid all that crap. It just makes things more complicated for something that will be complicated enough already. I used the netinst install media with the laptop connected to ISP through Ethernet and getting an IP address through DHCP, so I didn’t have to fiddle with any PPPoE clients to get online and install the stuff required.

# aptitude update
# aptitude install hostapd bridge-utils isc-dhcp-server bind9 rfkill vbetool vim-runtime vim-goodies tmux

Enable Wifi Adapter

For some weird and lame reason Debian didn’t enable the adapter after installation, so it has to be setup manually. These instructions are based on the Debian Wiki. Atheros card is wlan0 while built-in Intel adapter is wlan1.

# ip a
# rfkill unblock all
# iwconfig
# ip link set wlan0 up
# iwlist scan

The card scanned for networks around so it was working.

Edit /etc/network/interfaces so the WLAN interface doesn’t wait for an IP address. If you don’t do this it turns out the OS stops booting until it gets bored of waiting for an IP address.

auto wlan0
iface wlan0 inet static
    wireless-mode Master
    address 192.168.1.1
    netmask 255.255.255.0

You can use whatever IP address (like 10.0.0.1) but make sure the same subnet is used throughout the entire configuration. I went with 192.168.1.1 cos that’s what I like my networks to be on.

Configure iptables

Edit /etc/sysctl.conf and uncomment the line for IPV4 packet forwarding:

net.ipv4.ip_forward=1

Create /etc/network/if-pre-up.d/iptables with the following contents

#!/bin/sh
/sbin/iptables-restore < /etc/network/iptables

Then

# sudo chown root /etc/network/if-pre-up.d/iptables ; chmod 755 /etc/network/if-pre-up.d/iptables

Create /etc/network/iptables and put the following in it:

*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
# eth0 is WAN interface
-A POSTROUTING -o eth0 -j MASQUERADE

COMMIT

*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]

# Forward traffic from wlan0 (LAN) to eth0(WAN)
-A FORWARD -i wlan0 -o eth0 -j ACCEPT

# Service rules
-A INPUT -j ACCEPT

# Forwarding rules
-A FORWARD -j ACCEPT

COMMIT

At this point iptables will simply pass along all the traffic that his the computer. I’ve since changed my configuration but this is a starting point as I just wanted to get online at this point. iptables rules are a pain in the ass to type.

Configure DHCP

Edit /etc/dhcp/dhcpd.conf and add the following at the end of the file:

subnet 192.168.1.1 netmask 255.255.255.0 {
range 192.168.1.100 192.168.99.199;
option routers 192.168.1.1;
option domain-name-servers 192.168.1.1;
option broadcast-address 192.168.1.255;
}

Configure DNS

BIND works out of the box, thankfully enough.

Configure hostapd

Create and edit /etc/hostapd/hostapd.conf and put the following in it:

interface=wlan0
driver=nl80211
# SSID on 5GHz band
ssid="MY WIFI NETWORK"
hw_mode=a
channel=44

# Radar an' stuff
country_pre=US
ieee80211d=1
ieee80211h=0

# 802.11n goodness
wmm_enabled=1
ieee80211n=1

# wpa
auth_algs=1
wpa=3
wpa_passphrase=MyWifiPassword
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
rsn_pairwise=CCMP

ht_capab=[HT20][HT40+][SHORT-GI-40][TX-STBC][RX-STBC1][DSSS_CCK-40]

The ht_capab are the ones I’ve found work with the SR71-C card. I’ll keep playing with them.

At this point everything looked good and rebooted. I actually rebooted a whole bunch of times as I kept prodding and poking stuff every step of the way but I guess it all could be done in one go and just reboot at the end.

Actually be a Wifi Router

After rebooting do

$ sudo hostapd /etc/hostapd/hostapd.conf

Runs with the SSID, picks a channel, and starts the laptop as an AP. iptables is routing traffic from one interface to another, ISC DHCP gives out IP addresses and BIND does DNS. I did run into an issue where wlan0 kept sending out DHCP requests to which dhcpd would successfully assign a new IP address for wlan0. I got lazy and just set a static IP for the mac address of the interface on dhcp.conf. I’ll fix it… eventually.

There’s also the issue of tuning the kernel, firewall and a lot of other stuff since the computer is a single-purpose device rather than a multi-user computer. Most of the documentation I can find is for systems handling traffic at internet scale that would be overkill, so a lot of documentation will be read and a ton of adjustments made.

There will be also a lot of adjustments to hostapd itself to maximize throughput and signal stability. The SRC71C card only does 802.11n but the bitrate on this standard maxes out depending on the blue of the sky, the stage of the moon, how hot the dumpster fires are on twitter and how pissed off the boss is at work.

From what I’m getting this is relatively new stuff when it comes to DIY. People were doing this in the past but was way more costly (like this sweet setup right here). I’m doing this on the cheap and it seems to be working well enough.

nginx + hhvm, continued

So after my last post on this, HHVM stopped working again, making nginx give a 502 as usual.

This time, a comment on a forum (who knows which, I looked at a lot of pages) gave me a little snippet that helped me pinpoint the issue:
# netstat -plunt | grep hhvm

This should have told me that HHVM was listening on a TCP port (since that’s what the default for HHVM is). But netstat reported nothing. After checking my configuration, I had forgotten that I had iptables drop all traffic to 127/8 that doesn’t use loopback. Here’s the snippet I use in my iptables configuration file
-A INPUT -d 127.0.0.0/8 -j REJECT

Commented the line out, imported the new ruleset into iptables and iptables didn’t block traffic sent from nginx to HHVM anymore, letting everything work as is supposed to.

Now I’m hoping it doesn’t die again due to some other reason. This was really annoying.