Summary: | New netgraph nodetype: ng_antispoof | ||||||
---|---|---|---|---|---|---|---|
Product: | Base System | Reporter: | Markus Stoff <markus> | ||||
Component: | kern | Assignee: | freebsd-net (Nobody) <net> | ||||
Status: | Closed Overcome By Events | ||||||
Severity: | Affects Only Me | ||||||
Priority: | --- | ||||||
Version: | 12.1-RELEASE | ||||||
Hardware: | Any | ||||||
OS: | Any | ||||||
Attachments: |
|
Please let me also have your thoughts at review D26420. The proposed functionality is already provided by ng_bpf(4). |
Created attachment 217912 [details] New netgraph node type: ng_antispoof This introduces a new netgraph node type that prevents the upstream network from spoofing ethernet and IP addresses. It is called 'ng_antispoof' (name is open for debate, of course). What it does: It validates the upstream address each packet against a set of rules. If at least one rule matches, the packet is passed through, otherwise it is blocked. Each rule consists of a ethernet address and a IP or IPv6 address (in a simplified point of view). How it works: Each node provides three hooks: - 'filter': Where to connect the upstream node to be protected (e.g. a jail, a VM, ...). - 'downstream': Downstream node (e.g. a bridge device, the internet, ...). - 'nomatch': Useful for debugging with tcpdump. If connected, blocked traffic is forwarded on this hook instead of being discarded. This is output only, traffic arriving on this hook is immediately discarded. ___ +----------------+ __.( ).__ | | ( downstream )<------->| | .._ ( ) _ _.. | | I==========I | ng_antispoof |<------->I filter I | | I==========I nomatch <-------------| | | | +----------------+ Use Case: Prevent VNET jails from spoofing IP/MAC addresses while using pf(4) as the firewall on the host system. Example: Given a virtual network interface 'host_if' on the host system and 'jail_if' in a VNET enabled jail named 'malicious', restrict the jail to IP '192.168.1.42' on the MAC '1a:00:de:ad:be:ef': # Create ng_antispoof node and wire everything together ngctl mkpeer jail_if: antispoof ether filter ngctl name jail_if:ether as ngctl connect as: host_if: downstream ether # Add filter rule ngctl msg as: addinet '{ ether=1a:00:de:ad:be:ef ip_addr=192.168.1.42 }' More Details: Currently filter rules for IP and IPv6 address types can be created. The maximum number of rules is 65535 (UINT16_MAX). # For IPv4, subnets can be provided in CIDR or netmask notation ngctl msg as: addinet '{ ether=0a:00:de:ad:be:ef ip_addr=192.168.1.42 }' ngctl msg as: addinet '{ ether=0a:00:de:ad:be:ef ip_addr=192.168.1.0/24 }' ngctl msg as: addinet '{ ether=0a:00:de:ad:be:ef ip_addr=192.168.1.0 ip_mask=255.255.255.0 }' # For IPv6, subnets can be provided in CIDR notation ngctl msg as: addinet6 '{ ether=0a:00:de:ad:be:ef ip6_addr=::1 }' ngctl msg as: addinet6 '{ ether=0a:00:de:ad:be:ef ip6_addr=1:2::/32 }' Open Questions: - Is it correct to add the IPv6 parsing type should be added to ng_parse? - Should the IPv4 and IPv6 prefix types for CIDR notation also go into ng_parse? - What is the idiomatic way to provide tests for kernel modules? - Should VLAN tags be filtered as well (currently all VLAN tags are ignored)? - Filtering only the outermost tag would probably be the sensible approach here? - Should a single rule filter a single VID, a range of VIDs or a list of (ranges) of VIDs?