gluon-ebtables-limit-arp: switch to nftables
This commit is contained in:
parent
3a7115149c
commit
72a9a2a042
@ -1,3 +0,0 @@
|
||||
chain('ARP_LIMIT', 'DROP')
|
||||
chain('ARP_LIMIT_DATCHECK', 'RETURN')
|
||||
chain('ARP_LIMIT_TLCHECK', 'RETURN')
|
@ -1,6 +0,0 @@
|
||||
rule('ARP_LIMIT -j ARP_LIMIT_DATCHECK')
|
||||
rule('ARP_LIMIT --mark 0x2/0x2 -j RETURN')
|
||||
rule('ARP_LIMIT -j ARP_LIMIT_TLCHECK')
|
||||
rule('ARP_LIMIT --limit 1/sec --limit-burst 50 -j RETURN')
|
||||
|
||||
rule('FORWARD -p ARP --logical-out br-client -o bat0 --arp-op Request -j ARP_LIMIT')
|
@ -1,4 +1,4 @@
|
||||
include('mesh_vpn_dns', {
|
||||
position = 'chain-prepend',
|
||||
position = 'chain-pre',
|
||||
chain = 'dstnat',
|
||||
})
|
||||
|
@ -1,16 +1,16 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=gluon-ebtables-limit-arp
|
||||
PKG_NAME:=gluon-nftables-limit-arp
|
||||
|
||||
include ../gluon.mk
|
||||
|
||||
define Package/gluon-ebtables-limit-arp
|
||||
TITLE:=Ebtables limiter for ARP packets
|
||||
DEPENDS:=+gluon-core +gluon-ebtables gluon-mesh-batman-adv
|
||||
define Package/gluon-nftables-limit-arp
|
||||
TITLE:=nftables limiter for ARP packets
|
||||
DEPENDS:=+gluon-core +gluon-nftables +gluon-mesh-batman-adv
|
||||
endef
|
||||
|
||||
define Package/gluon-ebtables-limit-arp/description
|
||||
Gluon community wifi mesh firmware framework: Ebtables rules to
|
||||
define Package/gluon-nftables-limit-arp/description
|
||||
Gluon community wifi mesh firmware framework: nftables rules to
|
||||
rate-limit ARP packets.
|
||||
|
||||
This package adds filters to limit the amount of ARP Requests
|
||||
@ -19,7 +19,7 @@ define Package/gluon-ebtables-limit-arp/description
|
||||
node in total.
|
||||
|
||||
A burst of up to 50 ARP Requests is allowed until the rate-limiting
|
||||
takes effect (see --limit-burst in the ebtables manpage).
|
||||
takes effect (see burst in the nft manpage).
|
||||
|
||||
Furthermore, ARP Requests with a target IP already present in the
|
||||
batman-adv DAT Cache are excluded from the rate-limiting,
|
||||
@ -30,13 +30,15 @@ define Package/gluon-ebtables-limit-arp/description
|
||||
However it should mitigate the problem of curious people or
|
||||
smart devices scanning the whole IP range. Which could create
|
||||
a significant amount of overhead for all participants so far.
|
||||
|
||||
Note that this package currently only supports batman.
|
||||
endef
|
||||
|
||||
define Package/gluon-ebtables-limit-arp/install
|
||||
define Package/gluon-nftables-limit-arp/install
|
||||
$(Gluon/Build/Install)
|
||||
|
||||
$(INSTALL_DIR) $(1)/usr/sbin/
|
||||
$(CP) $(PKG_BUILD_DIR)/gluon-arp-limiter $(1)/usr/sbin/gluon-arp-limiter
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackageGluon,gluon-ebtables-limit-arp))
|
||||
$(eval $(call BuildPackageGluon,gluon-nftables-limit-arp))
|
@ -0,0 +1,61 @@
|
||||
set limitmac {
|
||||
type ether_addr
|
||||
}
|
||||
|
||||
set datips {
|
||||
type ipv4_addr
|
||||
}
|
||||
|
||||
# Rewrite arp packet target hardware address if target protocol address matches a given address.
|
||||
# input meta iifname enp2s0 arp ptype 0x0800 arp htype 1 arp hlen 6 arp plen 4 @nh,192,32 0xc0a88f10 @nh,144,48 set 0x112233445566 accept
|
||||
|
||||
# chain('ARP_LIMIT', 'DROP')
|
||||
chain arplimit {
|
||||
# obrname "br-client" \
|
||||
# oifname "bat0" \
|
||||
# arp operation request \
|
||||
# counter
|
||||
|
||||
# match everything which will land on bridge br-client
|
||||
# protocol type: ipv4
|
||||
# hardware type: ethernet
|
||||
# hardware address length: 6 byte mac
|
||||
# protocol address length: 4 byte ipv4
|
||||
# arp request
|
||||
# source address is mac to be limited
|
||||
# target address is not in DAT
|
||||
# we're over the limit
|
||||
# count
|
||||
# obrname "br-client" \
|
||||
# oifname "bat0" \
|
||||
arp ptype 0x0800 \
|
||||
arp htype 1 \
|
||||
arp hlen 6 \
|
||||
arp plen 4 \
|
||||
arp operation request \
|
||||
arp saddr ether @limitmac \
|
||||
arp daddr ip != @datips \
|
||||
limit rate over 6/minute burst 50 packets \
|
||||
counter \
|
||||
drop
|
||||
|
||||
# obrname "br-client" \
|
||||
# oifname "bat0" \
|
||||
arp ptype 0x0800 \
|
||||
arp htype 1 \
|
||||
arp hlen 6 \
|
||||
arp plen 4 \
|
||||
arp operation request \
|
||||
arp saddr ether != @limitmac \
|
||||
arp daddr ip != @datips \
|
||||
limit rate over 1/second burst 50 packets \
|
||||
counter \
|
||||
drop
|
||||
}
|
||||
|
||||
# chain('ARP_LIMIT_DATCHECK', 'RETURN')
|
||||
# %s ARP_LIMIT_DATCHECK -p ARP --arp-ip-dst %s -j mark --mark-or 0x2 --mark-target RETURN
|
||||
|
||||
# chain('ARP_LIMIT_TLCHECK', 'RETURN')
|
||||
# %s ARP_LIMIT_TLCHECK --source %s --limit 6/min --limit-burst 50 -j RETURN"
|
||||
# %s ARP_LIMIT_TLCHECK (add ? "2" : "") --source %s -j DROP
|
@ -0,0 +1,6 @@
|
||||
-- include('limit_arp', {
|
||||
-- position = 'ruleset-pre'
|
||||
-- })
|
||||
|
||||
bridge_include_table('pre', 'limit_arp_chain')
|
||||
bridge_rule('FORWARD', 'oifname "bat0" obrname "br-client" arp operation request counter jump arplimit')
|
@ -14,7 +14,7 @@
|
||||
|
||||
#define BATCTL_DC "/usr/sbin/batctl dc -H -n"
|
||||
#define BATCTL_TL "/usr/sbin/batctl tl -H -n"
|
||||
#define EBTABLES "/usr/sbin/ebtables"
|
||||
#define NFTABLES "/usr/sbin/nft"
|
||||
|
||||
#define BUILD_BUG_ON(check) ((void)sizeof(int[1-2*!!(check)]))
|
||||
|
||||
@ -39,13 +39,13 @@ static void ebt_ip_call(char *mod, struct in_addr ip)
|
||||
int ret;
|
||||
|
||||
snprintf(str, sizeof(str),
|
||||
EBTABLES " %s ARP_LIMIT_DATCHECK -p ARP --arp-ip-dst %s -j mark --mark-or 0x2 --mark-target RETURN",
|
||||
NFTABLES " %s element bridge gluon datips { %s }",
|
||||
mod, inet_ntoa(ip));
|
||||
|
||||
ret = system(str);
|
||||
if (ret)
|
||||
fprintf(stderr,
|
||||
"%i: Calling ebtables for DAT failed with status %i\n",
|
||||
"%i: Calling nft for DAT failed with status %i\n",
|
||||
clock, ret);
|
||||
}
|
||||
|
||||
@ -53,7 +53,7 @@ static void ip_node_destructor(struct addr_list *node)
|
||||
{
|
||||
struct in_addr *ip = (struct in_addr *)node->addr;
|
||||
|
||||
ebt_ip_call("-D", *ip);
|
||||
ebt_ip_call("delete", *ip);
|
||||
}
|
||||
|
||||
static void ebt_mac_limit_call(char *mod, struct mac_addr *mac)
|
||||
@ -62,40 +62,22 @@ static void ebt_mac_limit_call(char *mod, struct mac_addr *mac)
|
||||
int ret;
|
||||
|
||||
snprintf(str, sizeof(str),
|
||||
EBTABLES " %s ARP_LIMIT_TLCHECK --source %s --limit 6/min --limit-burst 50 -j RETURN",
|
||||
NFTABLES " %s element bridge gluon limitmac { %s }",
|
||||
mod, mac_ntoa(mac));
|
||||
|
||||
ret = system(str);
|
||||
if (ret)
|
||||
fprintf(stderr,
|
||||
"%i: Calling ebtables for TL failed with status %i\n",
|
||||
clock, ret);
|
||||
}
|
||||
|
||||
static void ebt_mac_ret_call(char *mod, struct mac_addr *mac, int add)
|
||||
{
|
||||
char str[128];
|
||||
int ret;
|
||||
|
||||
snprintf(str, sizeof(str),
|
||||
EBTABLES " %s ARP_LIMIT_TLCHECK %s --source %s -j DROP",
|
||||
mod, add ? "2" : "", mac_ntoa(mac));
|
||||
|
||||
ret = system(str);
|
||||
if (ret)
|
||||
fprintf(stderr,
|
||||
"%i: Calling ebtables for TL failed with status %i\n",
|
||||
"%i: Calling nft for TL failed with status %i\n",
|
||||
clock, ret);
|
||||
}
|
||||
|
||||
static void ebt_mac_call(char *mod, struct mac_addr *mac)
|
||||
{
|
||||
if (!strncmp(mod, "-D", strlen(mod))) {
|
||||
ebt_mac_ret_call(mod, mac, 0);
|
||||
if (!strncmp(mod, "delete", strlen(mod))) {
|
||||
ebt_mac_limit_call(mod, mac);
|
||||
} else {
|
||||
ebt_mac_limit_call(mod, mac);
|
||||
ebt_mac_ret_call(mod, mac, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -103,7 +85,7 @@ static void mac_node_destructor(struct addr_list *node)
|
||||
{
|
||||
struct mac_addr *mac = (struct mac_addr *)node->addr;
|
||||
|
||||
ebt_mac_call("-D", mac);
|
||||
ebt_mac_call("delete", mac);
|
||||
}
|
||||
|
||||
static int dat_parse_line(const char *line, struct in_addr *ip)
|
||||
@ -141,7 +123,7 @@ static void ebt_add_ip(struct in_addr ip)
|
||||
if (ret)
|
||||
return;
|
||||
|
||||
ebt_ip_call("-I", ip);
|
||||
ebt_ip_call("add", ip);
|
||||
}
|
||||
|
||||
static void ebt_add_mac(struct mac_addr *mac)
|
||||
@ -152,7 +134,7 @@ static void ebt_add_mac(struct mac_addr *mac)
|
||||
if (ret)
|
||||
return;
|
||||
|
||||
ebt_mac_call("-I", mac);
|
||||
ebt_mac_call("add", mac);
|
||||
}
|
||||
|
||||
static void ebt_dat_update(void)
|
||||
@ -168,7 +150,7 @@ static void ebt_dat_update(void)
|
||||
fprintf(stderr, "%i: Error: Could not call batctl dc\n", clock);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
while (1) {
|
||||
pline = fgets(line, sizeof(line), fp);
|
||||
if (!pline) {
|
||||
@ -257,18 +239,18 @@ static void ebt_tl_update(void)
|
||||
|
||||
static void ebt_dat_flush(void)
|
||||
{
|
||||
int ret = system(EBTABLES " -F ARP_LIMIT_DATCHECK");
|
||||
int ret = system(NFTABLES " flush set bridge gluon datips");
|
||||
|
||||
if (ret)
|
||||
fprintf(stderr, "Error flushing ARP_LIMIT_DATCHECK\n");
|
||||
fprintf(stderr, "Error flushing arplimit datips set\n");
|
||||
}
|
||||
|
||||
static void ebt_tl_flush(void)
|
||||
{
|
||||
int ret = system(EBTABLES " -F ARP_LIMIT_TLCHECK");
|
||||
int ret = system(NFTABLES " flush set bridge gluon limitmac");
|
||||
|
||||
if (ret)
|
||||
fprintf(stderr, "Error flushing ARP_LIMIT_TLCHECK\n");
|
||||
fprintf(stderr, "Error flushing arplimit limitmac\n");
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
Loading…
Reference in New Issue
Block a user