Friday, November 15, 2024

network – Configure macOS firewall to receive packets (udp ipv6)

Crossposted from stackoverflow

I’m trying to receive a udp ipv6 packet on a MacBook (macOS Sonoma 14.6) on a residential internet connection.

Disclaimer: I am a networking noob and most of the work below is me trying to learn.

I’m following Beej’s networking guide to learn how to send packets using the BSD sockets API. I’m running listener.c on Mac and talker.c on a cloud instance (aws ec2).

I don’t want to use port forwarding or NAT unless absolutely necessary. Ideally residential machines on ipv6 should be able to directly connect peer-to-peer without all that.

  • talker is successfully sending a single ipv6 udp packet from aws ec2 instance, but listener on macOS is not receiving them.
  • The connection works the other way round, sending an ipv6 udp packet from MacBook to aws ec2 instance works fine using talker and listener. (After following the aws guides on configuring aws VPC, subnet, security groups – aws manages firewalls, auto assigns ipv6 addresses if you ask it, etc. so no firewall or network configuration needed on the box itself)
  • I’m able to ping the ipv6 address of the MacBook from the aws ec2 instance, and receive successful response.

The primary question here is Apple does not allow this (incoming ipv6 udp on MacBook), or whether Apple allows it but I can’t figure out how to do it.

I haven’t tested it myself, but from the docs it does seem Windows Firewall is a lot easier to configure.

My guess is this has something to do with the macOS pf firewall. Mac has both Application firewall and Packet firewall, I could not find docs for either of them.

I have tried recording using tcpdump and then running talker. I am not able to find any UDP packets on the specified port, so I’m assuming the packets are being filtered somewhere in between. (Most likely on the packet firewall of the MacBook.)

I have tried using multiple different internet connections – both residential (fibre optic) and mobile, to confirm the problem is not with a specific ISP’s firewall.

Application Firewall

I have switched on Settings > Firewall, and switched on the Firewall. (I also tried with switched off, that didn’t work either)

I’m not sure at a low-level exactly which firewalls this GUI switches on, there was a previous stackoverflow answer that was also confused about this. (Sorry I can’t find the link right now, will add once I do.)

My current settings below. (I have also tried with other settings such as disabling stealth mode)

auto allow builtin software, auto allow downloaded signed software, enable stealth mode, whitelist: talker, listener

I’m assuming gcc-compiled binaries (gcc -o talker talker.c) are accepted for whitelisting by macOS on this setting page, I have not made a .app file. The GUI didn’t stop me from picking it.

Packet firewall

macOS seems to use pf from BSD to manage its firewall.

By default there are 6 lines in /etc/pf.conf

scrub-anchor "com.apple/*"
nat-anchor "com.apple/*"
rdr-anchor "com.apple/*"
dummynet-anchor "com.apple/*"
anchor "com.apple/*"
load anchor "com.apple" from "/etc/pf.anchors/com.apple"

Of these only 2 lines are packet filtering rules

Surprisingly commenting all 6 of these lines out seems to do basically nothing, atleast for outgoing connections. Still able to browse websites (http ipv4 and ipv6), ssh into cloud machines etc.

For incoming connections, I am able to ping the ipv6 address of the MacBook from aws ec2 instance

(If there’s a good test using nmap for example, please let me know. I would like to find out why these 6 lines seem to have no effect.)

If I add something like block all then ipv4 ipv6 outgoing does get blocked, showing this /etc/pf.conf file is not being ignored completely.

/etc/pf.anchors/com.apple is not accessible, so I do not know what pf rules macOS uses by default.

Commands I’m using to load new configs of my own and check whether the rules were actually loaded or not:

sudo pfctl -f /etc/pf.conf
sudo pfctl -E
sudo pfctl -sa

Mostly any custom rules I write are being successfully loaded if I check using sudo pfctl -sa

Lots of different commands I have tried that all didn’t work:

pass in inet6 proto udp to port 59999 no state
pass in inet6 proto udp to port 59999 keep state
pass in proto udp to port 4950 keep state
pass in proto udp from any to any port 4950 no state

And so on. I tried with and without keep state, with and without mentioning inet6, with and without mentioning from and to, with and without mentioning specific UDP ports. I’m pretty confident my rules are getting loaded correctly.

I have tried this both, while keeping the macOS pf rules as well, and without them.

Some posts on BSD forum for BSD suggest also setting up pf rules for other stuff like icmp:
https://forums.freebsd.org/threads/ipv6-not-working-with-pf.66772/

ping is successfully working so I’m not sure any of this is needed. I did try blindly copy-pasting some of the rules without fully understanding them, I could not get this to work either.

Please let me know if pf rules for ipv6 also require pf rules other stuff like icmp, and if yes, if there’s a ready-made minimum pf.conf I can find for this.

Scanning the UDP ports of MacBook from the aws ec2 instance using nmap shows ports as open|filtered which doesn’t help.

I will try doing tcp packets instead of udp, main benefit being atleast nmap will tell clearly if ports are open. I will also try using ipv4.

Please let me know if you’d like me to run any specific tests.

Related Articles

Latest Articles