LFCE 83 đ§ ipset â Concepts
ipset is a kernel framework and userspace utility for storing collections of IP addresses, networks, ports, and other values in indexed data structuresâhash tables or bitmapsâso that iptables can match against the entire collection with a single rule instead of a long chain of individual rules . The previous chapters covered the iptables rules that match one packet at a time; this chapter covers the mechanism that makes matching against thousands of addresses as fast as matching against one.
The core problem that ipset solves is the linear lookup. A firewall that blocks 10,000 addresses with individual iptables rules has 10,000 rules in the chain, and every packet is compared against them in order until a match is found or the chain ends. The lookup time grows with the size of the list. An ipset stores the same 10,000 addresses in a hash table, and the lookup time is essentially constant regardless of the number of entries . The iptables rule references the set by name, and the kernel checks the set in a single operation.
Key point: An ipset is a named collection of elements that lives in the kernel and is referenced by an iptables rule through the set match or the SET target . The set has a type that determines what it can storeâIP addresses, networks, ports, or combinationsâand the type determines the data structure and the lookup performance . The set is created with ipset create, populated with ipset add, and referenced in iptables with -m set --match-set <name> src. The set survives independently of the iptables rules, and it can be updated without touching the rule that references it.
Why ipset exists
The linear-lookup problem.
An iptables chain is a linked list. Each rule is evaluated in order, and a packet that matches none of the rules is compared against every one of them. A chain with 10,000 rules performs 10,000 comparisons in the worst case, and the CPU cost grows linearly with the size of the list. The kernel developers introduced ipset to move the list into a data structure that supports constant-time or near-constant-time lookup, so that the firewall can block millions of addresses without degrading the throughput .
The update problem.
Adding a new address to a 10,000-rule chain requires inserting a rule, which may require rebuilding the chain or at least modifying it in place. Adding an address to an ipset is a single operation that does not touch the iptables rules at all. The rule references the set by name, and the set’s contents can change without the rule being reloaded. This is the mechanism that fail2ban and similar tools use: they add and remove addresses from an ipset as the behavior changes, and the iptables rule stays static.
The multiple-match problem.
A packet can be matched against several sets in different rules, and each set can be queried with a different direction (src or dst). The set match in iptables accepts the set name and the direction, and the kernel performs the lookup against the set’s data structure . The SET target can add the packet’s address to a set, which is how dynamic blocklists are populated. The combination of match and target makes ipset a general-purpose mechanism for storing and querying collections of addresses, not just a blocklist.
a. The set types
The set type determines what the set can store and how it is stored. The two families are bitmap and hash, and the subtypes determine the element dimensions.
Bitmap types use a fixed-size memory range where each bit represents an address or port. They are fast and memory-efficient for small, dense ranges, but they are limited to 65,535 entries and a single dimension .
| Type | Stores | Limit |
|---|---|---|
bitmap:ip | IPv4 addresses | 65,535 |
bitmap:ip,mac | IPv4 and MAC pairs | 65,535 |
bitmap:port | TCP/UDP ports | 65,535 |
Hash types use a hash table that grows dynamically as elements are added. They are the correct choice for large or sparse sets, and they support multiple dimensions .
| Type | Stores |
|---|---|
hash:ip | IPv4 or IPv6 addresses |
hash:net | CIDR network blocks of different sizes |
hash:ip,port | IP and protocol-port pairs |
hash:net,port | Network and port pairs |
hash:net,iface | Network and interface name pairs |
list:set | Other sets (ordered union) |
The hash:ip type is the most common for simple blocklists, and the hash:net type is the correct choice when the elements are networks rather than individual hosts . The hash:ip,port type is used when the blocklist is specific to a service, such as blocking an address only on port 22. The list:set type is a meta-set that contains other sets, which allows a rule to match against a union of sets without listing them individually .
b. The set lifecycle
A set is created with ipset create, populated with ipset add, and destroyed with ipset destroy. The ipset list command shows the set’s contents and statistics.
# Create a hash:net set with a maximum of 100000 elements
sudo ipset create blocklist hash:net maxelem 100000
# Add individual addresses and networks
sudo ipset add blocklist 203.0.113.5
sudo ipset add blocklist 192.0.2.0/24
# List the set
sudo ipset list blocklist
# Output shows the type, the members, and the number of entries
The maxelem option sets the maximum number of elements the set can hold. The hash table is sized to accommodate that many entries, and the set grows dynamically until the limit is reached . The timeout option sets a default expiration for every element, which is useful for temporary blocks.
The set is referenced in iptables with the set match.
# Drop packets from any address in the blocklist
sudo iptables -A INPUT -m set --match-set blocklist src -j DROP
The --match-set blocklist src option tells iptables to check the packet’s source address against the set named blocklist . If the address is in the set, the rule matches, and the DROP target is applied. The rule is a single line, regardless of how many addresses the set contains. The dst keyword checks the destination address instead of the source.
c. The SET target and dynamic updates
The SET target adds the packet’s address to a set. It is the mechanism that allows the firewall to learn addresses dynamically, such as adding an address to a blocklist after a failed login attempt.
# Add the source address to the blocklist when a condition is met
sudo iptables -A INPUT -p tcp --dport 22 -m recent --name ssh --update --seconds 60 --hitcount 4 -j SET --add-set blocklist src
The SET --add-set blocklist src target adds the packet’s source address to the blocklist set . The rule can be combined with a match that detects the condition, such as the recent match that counts connections within a time window. The set is updated at the kernel level, and the next packet from the same address is matched by the set rule and dropped.
The ipset command can also add and delete elements from userspace, which is how fail2ban and similar tools manage the blocklist. The set is persistent as long as the kernel module is loaded, and the ipset save and ipset restore commands write and read the set contents to a file for persistence across reboots .
Complete Example Session
# ============================================
# PART 1: CREATE THE SET
# ============================================
sudo ipset create blocklist hash:net maxelem 100000
# ============================================
# PART 2: POPULATE THE SET
# ============================================
sudo ipset add blocklist 203.0.113.5
sudo ipset add blocklist 198.51.100.0/24
sudo ipset add blocklist 192.0.2.10
# ============================================
# PART 3: VERIFY THE SET
# ============================================
sudo ipset list blocklist
# Output shows the type, the members, and the number of entries
# ============================================
# PART 4: REFERENCE THE SET IN IPTABLES
# ============================================
sudo iptables -A INPUT -m set --match-set blocklist src -j DROP
# ============================================
# PART 5: ADD A DYNAMIC UPDATE RULE
# ============================================
sudo iptables -A INPUT -p tcp --dport 22 -m recent --name ssh --update --seconds 60 --hitcount 4 -j SET --add-set blocklist src
# ============================================
# PART 6: TEST THE BLOCKLIST
# ============================================
# From a blocked address: the connection is dropped
# From an allowed address: the connection succeeds
# ============================================
# PART 7: SAVE THE SET
# ============================================
sudo ipset save blocklist > /etc/ipset.blocklist
# ============================================
# PART 8: RESTORE THE SET
# ============================================
sudo ipset restore < /etc/ipset.blocklist
# ============================================
# PART 9: REMOVE AN ELEMENT
# ============================================
sudo ipset del blocklist 203.0.113.5
# ============================================
# PART 10: DESTROY THE SET
# ============================================
sudo ipset destroy blocklist
The ten parts demonstrate the ipset lifecycle: creation, population, verification, iptables reference, dynamic update, testing, saving, restoring, element removal, and destruction. The critical distinction is between Parts 4 and 5: the set match reads from the set, and the SET target writes to it.
Quick Reference
Set Types
| Type | Stores | Use Case |
|---|---|---|
hash:ip | IP addresses | Simple blocklist |
hash:net | CIDR networks | Network blocklist |
hash:ip,port | IP and port pairs | Service-specific block |
bitmap:ip | IPv4 addresses (dense) | Small, fixed range |
list:set | Other sets | Union of sets |
Commands
| Command | Purpose |
|---|---|
ipset create <name> <type> | Create a set |
ipset add <name> <element> | Add an element |
ipset del <name> <element> | Remove an element |
ipset list <name> | Show the set |
ipset save | Save to stdout |
ipset restore | Restore from stdin |
ipset destroy <name> | Delete the set |
iptables Integration
| Option | Purpose |
|---|---|
-m set --match-set <name> src | Match source address |
-m set --match-set <name> dst | Match destination address |
-j SET --add-set <name> src | Add source address to set |
Best Practices
â Do This:
# Use hash:net for network blocklists
ipset create blocklist hash:net maxelem 100000 # â
# Use hash:ip for simple host blocklists
ipset create hosts hash:ip maxelem 65536 # â
# Reference the set in a single iptables rule
iptables -A INPUT -m set --match-set blocklist src -j DROP # â
# Save the set for persistence
ipset save blocklist > /etc/ipset.blocklist # â
# Use the SET target for dynamic updates
-j SET --add-set blocklist src # â
â Don’t Do This:
# Create 10,000 individual iptables rules
for ip in ...; do iptables -A INPUT -s $ip -j DROP; done # â
# Use bitmap:ip for a large or sparse set
ipset create blocklist bitmap:ip # Limited to 65,535 # â
# Forget to save the set
# The set is lost on reboot # â
# Use the set without the hashsize for a large set
ipset create blocklist hash:ip # Default hashsize may cause collisions # â
Common Pitfalls
| Pitfall | Why It Happens | Fix |
|---|---|---|
| Set not found in iptables | Set name typo or set not created | ipset list to verify |
| Set lost on reboot | Not saved | ipset save and restore at boot |
| Lookup slow | Used bitmap for a large set | Use hash type |
| Cannot delete element | Implicit membership in a network | Delete the explicit element |
| Hash collisions | hashsize too small | Increase hashsize |
Real-World Examples
1. Create a hash:net set
ipset create blocklist hash:net maxelem 100000
2. Add a network
ipset add blocklist 192.0.2.0/24
3. Add a host
ipset add blocklist 203.0.113.5
4. Reference in iptables
iptables -A INPUT -m set --match-set blocklist src -j DROP
5. Dynamic add with SET target
iptables -A INPUT -p tcp --dport 22 -j SET --add-set blocklist src
6. List the set
ipset list blocklist
7. Remove an element
ipset del blocklist 203.0.113.5
8. Save the set
ipset save blocklist > /etc/ipset.blocklist
9. Restore the set
ipset restore < /etc/ipset.blocklist
10. Destroy the set
ipset destroy blocklist
Visual
ipset vs Individual Rules
ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â IPSET REPLACES A LONG CHAIN WITH A SINGLE RULE â
â â
â Without ipset: â
â ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ â
â â iptables -A INPUT -s 203.0.113.5 -j DROP â â
â â iptables -A INPUT -s 198.51.100.10 -j DROP â â
â â iptables -A INPUT -s 192.0.2.0/24 -j DROP â â
â â ... (10,000 rules) â â
â â â â
â â Each packet compares against up to 10,000 rules â â
â ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ â
â â
â With ipset: â
â ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ â
â â ipset create blocklist hash:net â â
â â ipset add blocklist 203.0.113.5 â â
â â ipset add blocklist 198.51.100.10 â â
â â ipset add blocklist 192.0.2.0/24 â â
â â â â
â â iptables -A INPUT -m set --match-set blocklist src -j DROPâ
â â â â
â â One rule; constant-time lookup in the hash table â â
â ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ â
ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
The set Match and SET Target
ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â MATCH READS; TARGET WRITES â
â â
â set match: â
â ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ â
â â -m set --match-set blocklist src â â
â â â checks if the packet's source is in the set â â
â â â used in filtering rules â â
â ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ â
â â
â SET target: â
â ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ â
â â -j SET --add-set blocklist src â â
â â â adds the packet's source to the set â â
â â â used in dynamic blocklist rules â â
â ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ â
ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
Persistence
ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â SAVE AND RESTORE FOR PERSISTENCE â
â â
â ipset save blocklist > /etc/ipset.blocklist â
â â â
â âź â
â File contains the set definition and its members â
â â â
â âź â
â At boot: ipset restore < /etc/ipset.blocklist â
â â â
â âź â
â The set is recreated with the same members â
â â
â Without the save/restore, the set is lost on reboot. â
ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
Summary
| Item | Value |
|---|---|
| Purpose | Indexed set for fast iptables matching |
| Data structures | Hash table or bitmap |
| Lookup | Constant or near-constant time |
| iptables match | -m set --match-set <name> src |
| iptables target | -j SET --add-set <name> src |
| Common type | hash:net for networks, hash:ip for hosts |
| Limit | maxelem option |
| Persistence | ipset save / ipset restore |
| Created with | ipset create <name> <type> |
Key takeaways:
- ipset solves the linear-lookup problem. A chain of 10,000 iptables rules is a linked list that performs up to 10,000 comparisons per packet. An ipset stores the same addresses in a hash table, and the lookup time is essentially constant regardless of the set size .
- The set type determines the data structure and the element dimensions.
hash:ipandhash:netare the common types for address blocklists,bitmaptypes are for small dense ranges, and the multi-dimensional types store IP-port or IP-MAC combinations . - The
setmatch reads from the set, and theSETtarget writes to it. The match is used in filtering rules, and the target is used in rules that add addresses dynamically, such as fail2ban-style SSH protection . - The set is independent of the iptables rule. The rule references the set by name, and the set’s contents can be updated without reloading the rule. This is the mechanism that allows dynamic blocklists to grow and shrink without touching the firewall configuration.
- The set must be saved for persistence. The
ipset savecommand writes the set contents to a file, and theipset restorecommand reads it back. Without the save and restore, the set is lost on reboot . - The
hashsizeandmaxelemoptions control the performance. A largerhashsizereduces collisions for large sets, andmaxelemsets the upper bound on the number of entries. The defaults are adequate for small sets but should be raised for large blocklists .
Remember: ipset is the mechanism that makes large-scale matching practical. The set is a named collection of addresses or networks stored in a kernel data structure, and the iptables rule matches against the set in a single operation. The set type determines what can be stored, the set match reads from the set, and the SET target writes to it. The set is independent of the rule, so it can be updated dynamically, and it must be saved for persistence. The result is a firewall that can block millions of addresses without the linear-lookup penalty of a long rule chain.
Stop using slow, ad-bloated tool sites! đ¤Ž
đ Search “KandZ Tools” on Google to use many professional utilities for free.
KandZ.me is the ultimate minimalist hub for:
â
Finance (Mortgage, Interest, Inflation)
â
Tech (Base64, JSON, Dev Suite, IP)
â
Health (BMI, BMR, TDEE)
â
Productivity (Timer, Workspace, QR)
âĄď¸ Fast & Private
đ No data leaves your device
đ 100% Free
đ Use it now: https://tools.kandz.me
đ Bookmark itâyouâll need it later!