Hello,
On Fri, Mar 03, 2023 at 09:14:38PM +0100, Alexander Bluhm wrote:
> On Fri, Mar 03, 2023 at 08:54:51AM +0100, Luca Di Gregorio wrote:
> > Hi, just another bit of info about this issue.
>
> Instead of implementing more and more details of RFC, we should
> discuss what the goal is.
>
> We had a pf that dropped valid IGMP packets due to router-alert
> option. So I added code to pass them, but still block other options.
> This is neccessary for working multicast.
>
> Then sashan@ commited a diff that blocks packets with bad TTL or
> destination address. This was too strict for some use cases as we
> see now. But it may improve security.
>
> What are the IGMP illegal packets that an attacker might use? We
> should drop them. This IGMP logic is deep down in pf that a user
> cannot override. So we should be careful not to destroy valid use
> cases. Replacing || with && somehow in the if condition looks
> reasonalbe to me.
>
My commit was wrong. It makes pf(4) to drop all IGMP packets which
either have TTL other than 1
or are not sent to multicast address
this is what we currently have in pf_walk_header()
6849 /* IGMP packets have router alert options, allow them */
6850 if (pd->proto == IPPROTO_IGMP) {
6851 /* According to RFC 1112 ttl must be set to 1. */
6852 if ((h->ip_ttl != 1) || !IN_MULTICAST(h->ip_dst.s_addr)) {
6853 DPFPRINTF(LOG_NOTICE, "Invalid IGMP");
6854 REASON_SET(reason, PFRES_IPOPTIONS);
6855 return (PF_DROP);
6856 }
6857 CLR(pd->badopts, PF_OPT_ROUTER_ALERT);
6858 }
I think Luca is right pf(4) is too paranoid breaking IGMP. The RFC 1112.
This is what 'Informal Protocol Description' section says:
Multicast routers send Host Membership Query messages (hereinafter
called Queries) to discover which host groups have members on their
attached local networks. Queries are addressed to the all-hosts
group (address 224.0.0.1), and carry an IP time-to-live of 1.
In my commit I confused any multicast address with 'all-hosts' group
(224.0.0.1)
So we either want to revert that commit or fix it. I think the condition at
line 6850 should read as follows:
6847 /* IGMP packets have router alert options, allow them */
6848 if (pd->proto == IPPROTO_IGMP) {
6849 /*
6850 * According to RFC 1112 ttl must be set to 1 in all IGMP
6851 * packets sent do 224.0.0.1
6852 */
6853 if ((h->ip_ttl != 1) &&
6854 (h->ip_dst.s_addr == INADDR_ALLHOSTS_GROUP)) {
6855 DPFPRINTF(LOG_NOTICE, "Invalid IGMP");
6856 REASON_SET(reason, PFRES_IPOPTIONS);
6857 return (PF_DROP);
6858 }
6859 CLR(pd->badopts, PF_OPT_ROUTER_ALERT);
This change should make pf(4) reasonably paranoid while keeping IGMP working.
thanks and
regards
sashan