Preface
For individuals who host their own websites (most commonly those running personal blogs), there may be circumstances where blocking access from China is desired (as certain content may not be intended for Chinese users). In such cases, blocking Chinese IP addresses becomes particularly important.
This guide demonstrates how to use iptables to implement system-level blocking of mainland Chinese IP access to ports 80 and 443.
Overview of Principles
iptables itself does not inherently recognize “which IPs belong to China”; therefore, it requires IP address range data. Common sources include:
- IPip.net
- APNIC allocation tables
- https://github.com/17mon/china_ip_list
- Or utilizing ipset for improved efficiency
Directly adding tens of thousands of rules to iptables will severely degrade system performance. The proper approach is: using ipset in conjunction with iptables.
ipset + iptables
1. Install Required Components
sudo apt update
sudo apt install ipset iptables -y
2. Create IP Set Using ipset
sudo ipset create china hash:net
3. Download Chinese IP Range List
wget -O /tmp/china_ip_list.txt https://raw.githubusercontent.com/17mon/china_ip_list/master/china_ip_list.txt
4. Import into ipset
while read ip; do
sudo ipset add china $ip
done < /tmp/china_ip_list.txt
5. Configure iptables Rules: Block china Set from Accessing Ports 80/443
sudo iptables -I INPUT -p tcp -m multiport --dports 80,443 -m set --match-set china src -j DROP
Saving Configuration
1. Save ipset
sudo ipset save > /etc/ipset.conf
2. Save iptables
sudo sh -c 'iptables-save > /etc/iptables/rules.v4'
3. Enable Automatic Loading on Boot
Edit /etc/rc.local (create it if it does not exist):
#!/bin/bash
ipset restore < /etc/ipset.conf
iptables-restore < /etc/iptables/rules.v4
exit 0
Grant execution permissions:
sudo chmod +x /etc/rc.local
Epilogue
-
If your server runs nginx / Caddy / Apache, you may utilize GeoIP modules at the application layer for more flexible control (such as allowing access from specific regions).
-
To block IPs outside of China (i.e., “allow access only from China”), reverse the rule to -j ACCEPT and add a default DROP rule.
-
For automated rule updates, implement a scheduled task:
crontab -e @weekly wget -O /tmp/china_ip_list.txt https://raw.githubusercontent.com/17mon/china_ip_list/master/china_ip_list.txt && \ ipset flush china && while read ip; do ipset add china $ip; done < /tmp/china_ip_list.txt