A script for strict packet filter updates
Against the Wall
As soon as a machine becomes accessible over the Internet, attacks start to rain down on it. Tools such as Fail2ban help against brute force attacks but are not a panacea. A DIY script offers flexible and fault-tolerant protection.
Maintaining a Linux server's packet filtering rules is one of the routine tasks of any administrator. Often, carefully maintained scripts, white lists, and blacklists are used to protect the server from unauthorized access. Public blacklists (e.g., OpenBL.org [1]) distribute the IP addresses of honeypot systems that help document attacks and distribute the IP addresses of the attackers. The Fail2ban script [2] supports local defenses with early blocking of hosts that have made several unsuccessful access attempts, and although this might lock out the boss when they try a dozen passwords from their cheat sheet, it keeps the number of false positive lock-outs manageable. Besides SSH, Fail2ban supports all services that document failed login attempts in the Syslog. After a configurable time interval, the script removes the locks again – until the next wave of attacks.
Scripts such as Fail2ban and the use of blacklists are useful and initially provide effective protection against casual attackers. Many attackers are better organized, have access to entire subnets with many IP addresses, or control a botnet with innumerable zombies in the dynamic address ranges of Asian DSL providers. Changing the IP address then immediately opens up the option of more free tests for the attacker. Attempts made by the abusers' providers either come to nothing or fail for other reasons. This means that unmanageably long lists of individual IP addresses accumulate for the duration of the different attacks, many from the same subnet or different subnets belonging to the same service provider.
To restore peace in the longer term, it can be useful to configure the packet filter far more strictly and generously block not only conspicuous subnets, but whole autonomous systems. Before creating the matching Bash script for this, quickly review the structures of the Internet and the ways to detect these structures and use them in the "Autonomous Systems on the Internet" box.
Autonomous Systems on the Internet
The biggest success of the Internet lies in the autonomous structure of the connected systems. The term autonomous system (AS) relates to the independence of the local network operators – both in their choice of direct neighbors (peers) and upstream providers or the internal organization of the network. To participate in the Internet as a separate AS, the operator requires an AS number (ASN) assigned by one of the five regional Internet registries (RIRs). The American Registry for Internet Numbers (ARIN) [3] is responsible for the US, Canada, parts of the Caribbean, and Antarctica, whereas The RIPE Network Coordination Centre (NCC) [4] is responsible for the European arena.
In addition to ASNs, RIRs register the IP address spaces (prefixes) of their members. Well-known examples are the prefixes 8.8.8.0/24 and 8.8.4.0/24, which are home to public DNS servers by Google, among other things. A prefix always defines the network portion of an IP address, and the length specifies the bits of the IP address used. All IP addresses that share the same prefix belong to the same subnet. Private or reserved prefixes (e.g., 192.168.0.0/16) are not assigned on the Internet and not routed. This ensures safe simultaneous use on many local area networks. In addition to the ASN and at least one prefix, an AS needs peers and an upstream provider. The upstream provider is also technically a peer, but receives payment for forwarding the packets.
The source AS sends the appropriate announcements to all neighboring systems to communicate the availability of the prefixes. The Border Gateway Protocol (BGP) then ensures that these announcements reach all ASs on the Internet. The traversed ASs add themselves to the AS path of the announcements before forwarding them. This means that at least one path can be traced that a package can use from one AS to another. For each prefix that needs to be accessible on the Internet, an entry must thus exist in the routing table of the other AS.
Three Steps to Success
The goal of the planned script has three stages. Like Fail2ban, you will first block individual IP addresses. If a certain number of unsuccessful access attempts originate from the same subnet, then all addresses of this prefix are blocked. The script thus prevents the attacker the opportunity for more free attempts through the use of additional hosts or simply by changing the IP addresses at the DSL connection. If access attempts come from multiple prefixes of the same AS, the script blocks all prefixes of this AS as a third stage. The required information cannot readily be discovered on a Linux server. Instead of the full routing table, you typically configure a default gateway on the server that takes care of forwarding the packets. The corresponding prefix of an IP address can only be determined with additional information.
Routing information, assuming you have appropriate access, can be obtained directly by querying the boundary router of your own AS. It has a full routing table with information about the available prefixes. Routing archives, such as the RIPE routing information service (RIS) [5] collect routing tables and prefix announcements in selected ASs. Groups of the received announcements can be download at intervals of about five minutes.
Additional Services Can Help
It is not necessary to take care of processing and analyzing these archives yourself, because services on the Internet provide easily searchable lists of the required results. You can thus automatically receive the required information via simple interfaces, such as the IP-to-ASN mapping service by Team Cymru [6], by regularly querying the assignment of an IP address to a prefix. To do so, you can use bulk queries for a large number of IP addresses to receive the corresponding ASs and the corresponding prefixes. The cleartext response (in the form of an ASCII table) can be very easily parsed with a script.
However, the information necessary for the second stage of the script cannot be provided by the Team Cymru service. Fortunately, a project at the University of Bonn provides these data but through a web service [7]. As opposed to the Team Cymru service, you need to register first, although this is free of charge. After receiving an API key, you can then query all the AS prefixes with the supplied Python client. The text output (one row per prefix) is also suitable for automatic processing within the script. The third stage is optional and depends on whether the Python client exists in the current directory. If so, it provides the information you need. If it does not exist, the script ignores this step without an error message.
iptables and Rescue Rules
The Linux iptables packet filter is used here, because it is still found on many production systems; however, an adaption to the newer nftables is quite easy with some minor manual interventions. To handle the automatically generated rules without any trouble, you create separate chains for the individual stages. In this way, you everything is clear-cut and keeps the other chains tidy. To enforce the locks, iptables must go through the chain at an early stage of processing. Make sure it is as near as possible to the top of the INPUT
chain, which might require minor adjustments to existing scripts.
Automatic fire wall rule changes (e.g., packet filters or manual routing entries) can lead to unwanted side effects. The most dreaded side effect is completely locking yourself out of the server. For remote servers, especially, where you don't have console access, this is especially annoying and usually leads to additional costs for manual access by maintenance personnel. To prevent this, running small scripts as cron jobs should ensure that a rescue rule is always available.
A static route entry to another server or the standard prefix of the Internet service provider also reduces your worries, as well as the size of the white list when you first introduce the packet filtering rules. The script will allow IP addresses or prefixes to be set for which it always grants access to the server. The more precisely you define these permissions the better; otherwise, they could give potential attackers on your own network unlimited access attempts.
Buy this article as PDF
(incl. VAT)