How to make ipfw filter DHCP packets

Karl Dunn kdunn at acm.org
Mon Jul 8 00:53:53 UTC 2019


I noticed recently ( after about 25 years of FreeBSD newbie-ism ) that
the ipfw rules recommended in the FreeBSD manual for DHCP 
DISCOVER/OFFER/REQUEST/ACK do not get hit.  I wanted them to, so:

  Load the ipfw module from loader.conf, so the system will block
  everything until the rules load.  (I hope and assume.)

  Force ipfw to load rules BEFORE devd starts dhclient.

Below you can see that the DHCP rules now indeed get hit.

Client system: Dell Optiplex 755, FreeBSD 11.2-RELEASE-p10 amd64
Network: RFC 1918 (192.168.LAN.MACHINE) behind a gateway that runs
   FreeBSD 11.2-RELEASE-p10 amd64 and isc-dhcp44-server-4.4.1_3

Now to my question(s):

   Is this a good way to "fix" the system so the DHCP traffic gets
   filtered?

   Is therer a right/better way?

   Do these fixes break something else, and if so, what and how?

Here are the fixes:

  ==> patch_etc_rc.d_devd <==
  *** ../oldetc/devd	Thu Jun 21 23:34:52 2018
  --- /etc/rc.d/devd	Fri Jun 14 09:29:01 2019
  ***************
  *** 4,10 ****
    #

    # PROVIDE: devd
  ! # REQUIRE: netif ldconfig
    # BEFORE: NETWORKING mountcritremote
    # KEYWORD: nojail shutdown

  --- 4,10 ----
    #

    # PROVIDE: devd
  ! # REQUIRE: netif ldconfig ipfw
    # BEFORE: NETWORKING mountcritremote
    # KEYWORD: nojail shutdown


  ==> boot_loader.conf <==
  kern.vty=vt
  ipfw_load="YES"

I later found this in the archives, but it didn't come to any useful 
answer, so I kept the two above changes:
  https://www.mail-archive.com/freebsd-ipfw@freebsd.org/msg03956.html

Here is a little more info:

In the ipfw rules:
    I took out rule 00600 because it would have blocked my own LAN:
      #${fwcmd} add 00600 deny log all from any to 192.168.0.0/16
    Note the counts for 00130 and 00150

In rc.conf:
    I use neither SYNCDHCP nor synchronous_dhclient.  That is
    because it looks as if the test at about line 237 in network.subr
    (inside function ifconfig_up) would try to start dhclient, and
    devd will already have started it.  BTW: Is that test backwards?

  ==> sanitized_CLIENT_ipfw_show <==
  00100    32    1920 allow ip from any to any via lo0
  00110     0       0 deny log ip from any to 127.0.0.0/8
  00120     0       0 deny log ip from 127.0.0.0/8 to any
  00130     2     656 allow log udp from any 68 to any 67 out via em0 keep-state :default
  00150     4    1324 allow log udp from 192.168.LAN.GW 67 to any 68 in via em0 keep-state :default
  00400     0       0 deny log ip from any to 10.0.0.0/8
  00500     0       0 deny log ip from any to 172.16.0.0/12
  00700     0       0 deny log ip from any to 0.0.0.0/8 via em0
  00800     0       0 deny log ip from any to 169.254.0.0/16 via em0
  00900     0       0 deny log ip from any to 192.0.2.0/24 via em0
  01000     0       0 deny log ip from any to 224.0.0.0/4 via em0
  01100     0       0 deny log ip from any to 240.0.0.0/4 via em0
  01700    27    1380 allow tcp from any to any established
  01800     0       0 allow ip from any to any frag
  02000     0       0 allow tcp from any to me 20,21,22,23,53,80,123,137,138,139,445,1024-65535 in via em0 setup keep-state :default
  02100    11    2696 allow log udp from any to any 137,138 in via em0 keep-state :default
  02200 10867 3045358 allow tcp from me to any 20,21,22,23,25,43,53,80,110,123,137,138,139,143,443,445,465,554,587,993,1024-65535 out via em0 setup keep-state :default
  02300   416   37650 allow log udp from me to any 53,123,137,138 out via em0 keep-state :default
  02400     0       0 allow log udp from me 137 to 192.168.LAN.GW 1024-65535 out via em0 keep-state :default
  02450     0       0 allow log udp from any 137 to me 1024-65535 in via em0 keep-state :default
  02500     0       0 allow log icmp from any to any icmptypes 0,3,4,8,11,12 via em0
  02600     0       0 allow log udp from me to any 33434-33534 out via em0
  05000     0       0 allow log icmp from any to any icmptypes 4
  65534     0       0 deny log ip from any to any
  65535     0       0 deny ip from any to any

  ==> sanitized_CLIENT_all_log <==
  Jul  2 10:57:02 CLIENT kernel: Firewall rules loaded.
  Jul  2 10:57:02 CLIENT kernel: Firewall logging enabled.
  Jul  2 10:57:02 CLIENT kernel: Starting devd.
  Jul  2 10:57:02 CLIENT kernel: em0: link state changed to UP
  Jul  2 10:57:02 CLIENT kernel: Starting dhclient.
  Jul  2 10:57:02 CLIENT kernel: uhid0 on uhub6
  Jul  2 10:57:02 CLIENT kernel: uhid0: <USB Keyboard> on usbus0
  Jul  2 10:57:02 CLIENT kernel: ums0 on uhub6
  Jul  2 10:57:02 CLIENT kernel: ums0: <Dell Dell USB Mouse, class 0/0, rev 1.10/29.10, addr 3> on usbus0
  Jul  2 10:57:02 CLIENT kernel: ums0: 3 buttons and [XYZ] coordinates ID=0
  Jul  2 10:57:02 CLIENT kernel: DHCPDISCOVER on em0 to 255.255.255.255 port 67 interval 6
  Jul  2 10:57:02 CLIENT kernel: ipfw: 130 Accept UDP 0.0.0.0:68 255.255.255.255:67 out via em0
  Jul  2 10:57:02 CLIENT kernel: ipfw: 150 Accept UDP 192.168.LAN.GW:67 192.168.LAN.CLIENT:68 in via em0
  Jul  2 10:57:02 CLIENT kernel: DHCPOFFER from 192.168.LAN.GW
  Jul  2 10:57:02 CLIENT kernel: ipfw: 150 Accept UDP 192.168.LAN.GW:67 192.168.LAN.CLIENT:68 in via em0
  Jul  2 10:57:02 CLIENT kernel:
  Jul  2 10:57:02 CLIENT kernel: DHCPREQUEST on em0 to 255.255.255.255 port 67
  Jul  2 10:57:02 CLIENT kernel: ipfw: 130 Accept UDP 0.0.0.0:68 255.255.255.255:67 out via em0
  Jul  2 10:57:02 CLIENT kernel: ipfw: 150 Accept UDP 192.168.LAN.GW:67 192.168.LAN.CLIENT:68 in via em0
  Jul  2 10:57:02 CLIENT kernel: ipfw: 150 Accept UDP 192.168.LAN.GW:67 192.168.LAN.CLIENT:68 in via em0
  Jul  2 10:57:02 CLIENT kernel: DHCPACK from 192.168.LAN.GW
  Jul  2 10:57:02 CLIENT kernel: bound to 192.168.LAN.CLIENT -- renewal in 21600 seconds.

  ==> sanitized_CLIENT_rc.conf <==
  hostname="CLIENT.mydomain"
  ifconfig_em0="DHCP"
  #synchronous_dhclient="YES"
  defaultroute_delay="120"		# Time to wait for a default route on a DHCP interface.
  #rc_debug="YES"
  sshd_enable="YES"
  moused_enable="YES"
  ntpd_enable="YES"
  powerd_enable="YES"
  # Set dumpdev to "AUTO" to enable crash dumps, "NO" to disable
  dumpdev="AUTO"
  #
  inetd_enable="YES"
  #
  # Prevent syslogd from using ipv6
  syslogd_flags="-s -4"		# Flags to syslogd (if enabled).
  #
  ntpd_sync_on_start="YES"  # Sync time on ntpd startup, even if offset is high
  ntpd_config="/etc/ntp_OURCLIENTS.conf"      # ntpd(8) configuration file
  #
  fixxf86intel_enable="YES"		# Mitigate i915kms/xf86-intel-driver bug
  #
  devfs_system_ruleset="localrules"	# Custom ruleset for devfs
  #
  # Disable IPV6 routing altogether
  ipv6_network_interfaces="none"	# List of IPv6 network interfaces
  				# (or "auto" or "none").
  ip6addrctl_enable="NO"		# Set to YES to enable default address selection
  ip6addrctl_policy="ipv4_prefer"	# A pre-defined address selection policy
  				# (ipv4_prefer, ipv6_prefer, or AUTO)
  #
  # Firewall
  ipv6_ipv4mapping="NO"	# Leave empty to disable IPv4 mapped IPv6 addr
  			# communication. (like ::ffff:a.b.c.d)
  firewall_enable="YES"	# Set to YES to enable firewall functionality
  firewall_script="/etc/OURCLIENTS.fw"	# Script to run to set up the firewall
  firewall_quiet="YES"	# Set to YES to suppress rule display
  firewall_logging="YES"	# Set to YES to enable events logging
  firewall_flags=""	# Flags passed to ipfw when type is a file
  #
  # Enable Linux compatibility at boot via /etc/rc.d/abi
  linux_enable="YES"
  #
  # Run Samba
  #samba_server_enable="YES"
  #
  # Apache httpd
  #apache24_enable="YES"

Karl Dunn
kdunn at acm.org

  "If it ain't broke, don't fix it."


More information about the freebsd-questions mailing list