# Configure profile
mkdir -p /etc/profile.d
cat << "EOF" > /etc/profile.d/ipset.sh
ipset() {
local IPSET_CMD="${1}"
case "${IPSET_CMD}" in
(setup|unset) ipset_proc ;;
(*) command ipset "${@}" ;;
esac
}
ipset_proc() {
. /lib/functions.sh
config_load dhcp
config_foreach ipset_proc_"${IPSET_CMD}" ipset
uci_commit firewall
service firewall reload
fw4 reload-sets
}
ipset_proc_setup() {
local IPSET_CONF="${1}"
local IPSET_TEMP="$(mktemp -t ipset.XXXXXX)"
{
config_list_foreach "${IPSET_CONF}" domain ipset_domain
config_list_foreach "${IPSET_CONF}" cidr ipset_cidr
config_list_foreach "${IPSET_CONF}" asn ipset_asn
config_list_foreach "${IPSET_CONF}" geoip ipset_geoip
} | sort -u > "${IPSET_TEMP}"
config_list_foreach "${IPSET_CONF}" name ipset_"${IPSET_CMD}"
rm -f "${IPSET_TEMP}"
}
ipset_proc_unset() {
local IPSET_CONF="${1}"
config_list_foreach "${IPSET_CONF}" name ipset_"${IPSET_CMD}"
}
ipset_setup() {
local IPSET_NAME="${1}"
local IPSET_FILE="/var/ipset-${IPSET_NAME}"
local IPSET_FAMILY
case "${IPSET_NAME}" in
(*6) IPSET_FAMILY="ipv6"
sed -e "/\./d" ;;
(*) IPSET_FAMILY="ipv4"
sed -e "/:/d" ;;
esac < "${IPSET_TEMP}" > "${IPSET_FILE}"
uci -q batch << EOI
set firewall.'${IPSET_NAME//-/_}'='ipset'
set firewall.'${IPSET_NAME//-/_}'.name='${IPSET_NAME}'
set firewall.'${IPSET_NAME//-/_}'.family='${IPSET_FAMILY}'
set firewall.'${IPSET_NAME//-/_}'.match='net'
set firewall.'${IPSET_NAME//-/_}'.loadfile='${IPSET_FILE}'
EOI
}
ipset_unset() {
local IPSET_NAME="${1}"
local IPSET_FILE="/var/ipset-${IPSET_NAME}"
rm -f "${IPSET_FILE}"
uci -q batch << EOI
delete firewall.'${IPSET_NAME//-/_}'.loadfile
EOI
}
ipset_domain() {
local IPSET_ENTRY="${1}"
resolveip "${IPSET_ENTRY}"
}
ipset_cidr() {
local IPSET_ENTRY="${1}"
echo "${IPSET_ENTRY}"
}
ipset_asn() {
local IPSET_ENTRY="${1}"
wget -O - "https://stat.ripe.net/data/\
announced-prefixes/data.json?resource=${IPSET_ENTRY}" \
| jsonfilter -e "@['data']['prefixes'][*]['prefix']"
}
ipset_geoip() {
local IPSET_ENTRY="${1}"
wget -O - "https://www.ipdeny.com/ipblocks/data/\
aggregated/${IPSET_ENTRY}-aggregated.zone" \
"https://www.ipdeny.com/ipv6/ipaddresses/\
aggregated/${IPSET_ENTRY}-aggregated.zone"
}
EOF
. /etc/profile.d/ipset.sh
# Configure hotplug
mkdir -p /etc/hotplug.d/online
cat << "EOF" > /etc/hotplug.d/online/70-ipset-setup
if [ -z "${TERM}" ] \
&& [ ! -e /var/lock/ipset-setup ] \
|| [ -n "${TERM}" ] \
&& lock -n /var/lock/ipset-setup \
&& sleep 10
then . /etc/profile.d/ipset.sh
ipset setup
lock -u /var/lock/ipset-setup
fi
EOF
cat << "EOF" >> /etc/sysupgrade.conf
/etc/hotplug.d/online/70-ipset-setup
EOF
# Configure cron
cat << "EOF" >> /etc/crontabs/root
0 */3 * * * . /etc/hotplug.d/online/70-ipset-setup
EOF
service cron restart
# Install packages
opkg update
opkg install resolveip
# Configure IP sets, domains, CIDRs and ASNs
uci set dhcp.example="ipset"
uci add_list dhcp.example.name="example"
uci add_list dhcp.example.name="example6"
uci add_list dhcp.example.domain="example.com"
uci add_list dhcp.example.domain="example.net"
uci add_list dhcp.example.cidr="9.9.9.9/32"
uci add_list dhcp.example.cidr="2620:fe::fe/128"
uci add_list dhcp.example.asn="2906"
uci add_list dhcp.example.asn="40027"
uci add_list dhcp.example.geoip="cn"
uci add_list dhcp.example.geoip="ru"
uci commit dhcp
# Populate IP sets
ipset setup