1#!/bin/sh - 2# Copyright (c) 1996 Poul-Henning Kamp 3# All rights reserved. 4# 5# Redistribution and use in source and binary forms, with or without 6# modification, are permitted provided that the following conditions 7# are met: 8# 1. Redistributions of source code must retain the above copyright 9# notice, this list of conditions and the following disclaimer. 10# 2. Redistributions in binary form must reproduce the above copyright 11# notice, this list of conditions and the following disclaimer in the 12# documentation and/or other materials provided with the distribution. 13# 14# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24# SUCH DAMAGE. 25# 26# 27 28# 29# Setup system for ipfw(4) firewall service. 30# 31 32# Suck in the configuration variables. 33if [ -z "${source_rc_confs_defined}" ]; then 34 if [ -r /etc/defaults/rc.conf ]; then 35 . /etc/defaults/rc.conf 36 source_rc_confs 37 elif [ -r /etc/rc.conf ]; then 38 . /etc/rc.conf 39 fi 40fi 41 42############ 43# Define the firewall type in /etc/rc.conf. Valid values are: 44# open - will allow anyone in 45# client - will try to protect just this machine 46# simple - will try to protect a whole network 47# closed - totally disables IP services except via lo0 interface 48# workstation - will try to protect just this machine using stateful 49# firewalling. See below for rc.conf variables used 50# UNKNOWN - disables the loading of firewall rules. 51# filename - will load the rules in the given filename (full path required) 52# 53# For ``client'' and ``simple'' the entries below should be customized 54# appropriately. 55 56############ 57# 58# If you don't know enough about packet filtering, we suggest that you 59# take time to read this book: 60# 61# Building Internet Firewalls, 2nd Edition 62# Brent Chapman and Elizabeth Zwicky 63# 64# O'Reilly & Associates, Inc 65# ISBN 1-56592-871-7 66# http://www.ora.com/ 67# http://www.oreilly.com/catalog/fire2/ 68# 69# For a more advanced treatment of Internet Security read: 70# 71# Firewalls and Internet Security: Repelling the Wily Hacker, 2nd Edition 72# William R. Cheswick, Steven M. Bellowin, Aviel D. Rubin 73# 74# Addison-Wesley / Prentice Hall 75# ISBN 0-201-63466-X 76# http://www.pearsonhighered.com/ 77# http://www.pearsonhighered.com/educator/academic/product/0,3110,020163466X,00.html 78# 79 80setup_loopback() { 81 ############ 82 # Only in rare cases do you want to change these rules 83 # 84 ${fwcmd} add 100 pass all from any to any via lo0 85 ${fwcmd} add 200 deny all from any to 127.0.0.0/8 86 ${fwcmd} add 300 deny ip from 127.0.0.0/8 to any 87 if [ $ipv6_available -eq 0 ]; then 88 ${fwcmd} add 400 deny all from any to ::1 89 ${fwcmd} add 500 deny all from ::1 to any 90 fi 91} 92 93setup_ipv6_mandatory() { 94 [ $ipv6_available -eq 0 ] || return 0 95 96 ############ 97 # Only in rare cases do you want to change these rules 98 # 99 # ND 100 # 101 # DAD 102 ${fwcmd} add pass ipv6-icmp from :: to ff02::/16 103 # RS, RA, NS, NA, redirect... 104 ${fwcmd} add pass ipv6-icmp from fe80::/10 to fe80::/10 105 ${fwcmd} add pass ipv6-icmp from fe80::/10 to ff02::/16 106 107 # Allow ICMPv6 destination unreachable 108 ${fwcmd} add pass ipv6-icmp from any to any icmp6types 1 109 110 # Allow NS/NA/toobig (don't filter it out) 111 ${fwcmd} add pass ipv6-icmp from any to any icmp6types 2,135,136 112} 113 114. /etc/rc.subr 115. /etc/network.subr 116 117if [ -n "${1}" ]; then 118 firewall_type="${1}" 119fi 120if [ -z "${firewall_rc_config_load}" ]; then 121 load_rc_config ipfw 122else 123 for i in ${firewall_rc_config_load}; do 124 load_rc_config $i 125 done 126fi 127 128afexists inet6 129ipv6_available=$? 130 131############ 132# Set quiet mode if requested 133# 134if checkyesno firewall_quiet; then 135 fwcmd="/sbin/ipfw -q" 136else 137 fwcmd="/sbin/ipfw" 138fi 139 140############ 141# Flush out the list before we begin. 142# 143${fwcmd} -f flush 144 145setup_loopback 146setup_ipv6_mandatory 147 148############ 149# Network Address Translation. All packets are passed to natd(8) 150# before they encounter your remaining rules. The firewall rules 151# will then be run again on each packet after translation by natd 152# starting at the rule number following the divert rule. 153# 154# For ``simple'' firewall type the divert rule should be put to a 155# different place to not interfere with address-checking rules. 156# 157case ${firewall_type} in 158[Oo][Pp][Ee][Nn]|[Cc][Ll][Ii][Ee][Nn][Tt]) 159 if [ -n "${natd_interface}" ] && checkyesno natd_enable; then 160 ${fwcmd} add 50 divert natd ip4 from any to any via ${natd_interface} 161 fi 162 if [ -n "${firewall_nat_interface}" ] && checkyesno firewall_nat_enable ; then 163 if echo "${firewall_nat_interface}" | \ 164 grep -q -E '^[0-9]+(\.[0-9]+){0,3}$'; then 165 firewall_nat_flags="ip ${firewall_nat_interface} ${firewall_nat_flags}" 166 else 167 firewall_nat_flags="if ${firewall_nat_interface} ${firewall_nat_flags}" 168 fi 169 ${fwcmd} nat 123 config log ${firewall_nat_flags} 170 ${fwcmd} add 50 nat 123 ip4 from any to any via ${firewall_nat_interface} 171 fi 172esac 173 174############ 175# If you just configured ipfw in the kernel as a tool to solve network 176# problems or you just want to disallow some particular kinds of traffic 177# then you will want to change the default policy to open. You can also 178# do this as your only action by setting the firewall_type to ``open''. 179# 180# ${fwcmd} add 65000 pass all from any to any 181 182 183# Prototype setups. 184# 185case ${firewall_type} in 186[Oo][Pp][Ee][Nn]) 187 ${fwcmd} add 65000 pass all from any to any 188 ;; 189 190[Cc][Ll][Ii][Ee][Nn][Tt]) 191 ############ 192 # This is a prototype setup that will protect your system somewhat 193 # against people from outside your own network. 194 # 195 # Configuration: 196 # firewall_client_net: Network address of local IPv4 network. 197 # firewall_client_net_ipv6: Network address of local IPv6 network. 198 ############ 199 200 # set this to your local network 201 net="$firewall_client_net" 202 net6="$firewall_client_net_ipv6" 203 204 # Allow limited broadcast traffic from my own net. 205 ${fwcmd} add pass all from ${net} to 255.255.255.255 206 207 # Allow any traffic to or from my own net. 208 ${fwcmd} add pass all from me to ${net} 209 ${fwcmd} add pass all from ${net} to me 210 if [ -n "$net6" ]; then 211 ${fwcmd} add pass all from me to ${net6} 212 ${fwcmd} add pass all from ${net6} to me 213 # Allow any link-local multicast traffic 214 ${fwcmd} add pass all from fe80::/10 to ff02::/16 215 ${fwcmd} add pass all from ${net6} to ff02::/16 216 # Allow DHCPv6 217 ${fwcmd} add pass udp from fe80::/10 to me 546 218 fi 219 220 # Allow TCP through if setup succeeded 221 ${fwcmd} add pass tcp from any to any established 222 223 # Allow IP fragments to pass through 224 ${fwcmd} add pass all from any to any frag 225 226 # Allow setup of incoming email 227 ${fwcmd} add pass tcp from any to me 25 setup 228 229 # Allow setup of outgoing TCP connections only 230 ${fwcmd} add pass tcp from me to any setup 231 232 # Disallow setup of all other TCP connections 233 ${fwcmd} add deny tcp from any to any setup 234 235 # Allow DNS queries out in the world 236 ${fwcmd} add pass udp from me to any 53 keep-state 237 238 # Allow NTP queries out in the world 239 ${fwcmd} add pass udp from me to any 123 keep-state 240 241 # Everything else is denied by default, unless the 242 # IPFIREWALL_DEFAULT_TO_ACCEPT option is set in your kernel 243 # config file. 244 ;; 245 246[Ss][Ii][Mm][Pp][Ll][Ee]) 247 ############ 248 # This is a prototype setup for a simple firewall. Configure this 249 # machine as a DNS and NTP server, and point all the machines 250 # on the inside at this machine for those services. 251 # 252 # Configuration: 253 # firewall_simple_iif: Inside IPv4 network interface. 254 # firewall_simple_inet: Inside IPv4 network address. 255 # firewall_simple_oif: Outside IPv4 network interface. 256 # firewall_simple_onet: Outside IPv4 network address. 257 # firewall_simple_iif_ipv6: Inside IPv6 network interface. 258 # firewall_simple_inet_ipv6: Inside IPv6 network prefix. 259 # firewall_simple_oif_ipv6: Outside IPv6 network interface. 260 # firewall_simple_onet_ipv6: Outside IPv6 network prefix. 261 ############ 262 BAD_ADDR_TBL=13 263 264 # set these to your outside interface network 265 oif="$firewall_simple_oif" 266 onet="$firewall_simple_onet" 267 oif6="${firewall_simple_oif_ipv6:-$firewall_simple_oif}" 268 onet6="$firewall_simple_onet_ipv6" 269 270 # set these to your inside interface network 271 iif="$firewall_simple_iif" 272 inet="$firewall_simple_inet" 273 iif6="${firewall_simple_iif_ipv6:-$firewall_simple_iif}" 274 inet6="$firewall_simple_inet_ipv6" 275 276 # Stop spoofing 277 ${fwcmd} add deny all from ${inet} to any in via ${oif} 278 ${fwcmd} add deny all from ${onet} to any in via ${iif} 279 if [ -n "$inet6" ]; then 280 ${fwcmd} add deny all from ${inet6} to any in via ${oif6} 281 if [ -n "$onet6" ]; then 282 ${fwcmd} add deny all from ${onet6} to any in \ 283 via ${iif6} 284 fi 285 fi 286 287 # Define stuff we should never send out or receive in. 288 # Stop RFC1918 nets on the outside interface 289 ${fwcmd} table ${BAD_ADDR_TBL} flush 290 ${fwcmd} table ${BAD_ADDR_TBL} add 10.0.0.0/8 291 ${fwcmd} table ${BAD_ADDR_TBL} add 172.16.0.0/12 292 ${fwcmd} table ${BAD_ADDR_TBL} add 192.168.0.0/16 293 294 # And stop draft-manning-dsua-03.txt (1 May 2000) nets (includes RESERVED-1, 295 # DHCP auto-configuration, NET-TEST, MULTICAST (class D), and class E) 296 # on the outside interface 297 ${fwcmd} table ${BAD_ADDR_TBL} add 0.0.0.0/8 298 ${fwcmd} table ${BAD_ADDR_TBL} add 169.254.0.0/16 299 ${fwcmd} table ${BAD_ADDR_TBL} add 192.0.2.0/24 300 ${fwcmd} table ${BAD_ADDR_TBL} add 224.0.0.0/4 301 ${fwcmd} table ${BAD_ADDR_TBL} add 240.0.0.0/4 302 303 ${fwcmd} add deny all from any to "table($BAD_ADDR_TBL)" via ${oif} 304 305 # Network Address Translation. This rule is placed here deliberately 306 # so that it does not interfere with the surrounding address-checking 307 # rules. If for example one of your internal LAN machines had its IP 308 # address set to 192.0.2.1 then an incoming packet for it after being 309 # translated by natd(8) would match the `deny' rule above. Similarly 310 # an outgoing packet originated from it before being translated would 311 # match the `deny' rule below. 312 if [ -n "${natd_interface}" ] && checkyesno natd_enable; then 313 ${fwcmd} add divert natd ip4 from any to any via ${natd_interface} 314 fi 315 316 ${fwcmd} add deny all from "table($BAD_ADDR_TBL)" to any via ${oif} 317 if [ -n "$inet6" ]; then 318 # Stop unique local unicast address on the outside interface 319 ${fwcmd} add deny all from fc00::/7 to any via ${oif6} 320 ${fwcmd} add deny all from any to fc00::/7 via ${oif6} 321 322 # Stop site-local on the outside interface 323 ${fwcmd} add deny all from fec0::/10 to any via ${oif6} 324 ${fwcmd} add deny all from any to fec0::/10 via ${oif6} 325 326 # Disallow "internal" addresses to appear on the wire. 327 ${fwcmd} add deny all from ::ffff:0.0.0.0/96 to any \ 328 via ${oif6} 329 ${fwcmd} add deny all from any to ::ffff:0.0.0.0/96 \ 330 via ${oif6} 331 332 # Disallow packets to malicious IPv4 compatible prefix. 333 ${fwcmd} add deny all from ::224.0.0.0/100 to any via ${oif6} 334 ${fwcmd} add deny all from any to ::224.0.0.0/100 via ${oif6} 335 ${fwcmd} add deny all from ::127.0.0.0/104 to any via ${oif6} 336 ${fwcmd} add deny all from any to ::127.0.0.0/104 via ${oif6} 337 ${fwcmd} add deny all from ::0.0.0.0/104 to any via ${oif6} 338 ${fwcmd} add deny all from any to ::0.0.0.0/104 via ${oif6} 339 ${fwcmd} add deny all from ::255.0.0.0/104 to any via ${oif6} 340 ${fwcmd} add deny all from any to ::255.0.0.0/104 via ${oif6} 341 342 ${fwcmd} add deny all from ::0.0.0.0/96 to any via ${oif6} 343 ${fwcmd} add deny all from any to ::0.0.0.0/96 via ${oif6} 344 345 # Disallow packets to malicious 6to4 prefix. 346 ${fwcmd} add deny all from 2002:e000::/20 to any via ${oif6} 347 ${fwcmd} add deny all from any to 2002:e000::/20 via ${oif6} 348 ${fwcmd} add deny all from 2002:7f00::/24 to any via ${oif6} 349 ${fwcmd} add deny all from any to 2002:7f00::/24 via ${oif6} 350 ${fwcmd} add deny all from 2002:0000::/24 to any via ${oif6} 351 ${fwcmd} add deny all from any to 2002:0000::/24 via ${oif6} 352 ${fwcmd} add deny all from 2002:ff00::/24 to any via ${oif6} 353 ${fwcmd} add deny all from any to 2002:ff00::/24 via ${oif6} 354 355 ${fwcmd} add deny all from 2002:0a00::/24 to any via ${oif6} 356 ${fwcmd} add deny all from any to 2002:0a00::/24 via ${oif6} 357 ${fwcmd} add deny all from 2002:ac10::/28 to any via ${oif6} 358 ${fwcmd} add deny all from any to 2002:ac10::/28 via ${oif6} 359 ${fwcmd} add deny all from 2002:c0a8::/32 to any via ${oif6} 360 ${fwcmd} add deny all from any to 2002:c0a8::/32 via ${oif6} 361 362 ${fwcmd} add deny all from ff05::/16 to any via ${oif6} 363 ${fwcmd} add deny all from any to ff05::/16 via ${oif6} 364 fi 365 366 # Allow TCP through if setup succeeded 367 ${fwcmd} add pass tcp from any to any established 368 369 # Allow IP fragments to pass through 370 ${fwcmd} add pass all from any to any frag 371 372 # Allow setup of incoming email 373 ${fwcmd} add pass tcp from any to me 25 setup 374 375 # Allow access to our DNS 376 ${fwcmd} add pass tcp from any to me 53 setup 377 ${fwcmd} add pass udp from any to me 53 378 ${fwcmd} add pass udp from me 53 to any 379 380 # Allow access to our WWW 381 ${fwcmd} add pass tcp from any to me 80 setup 382 383 # Reject&Log all setup of incoming connections from the outside 384 ${fwcmd} add deny log ip4 from any to any in via ${oif} setup proto tcp 385 if [ -n "$inet6" ]; then 386 ${fwcmd} add deny log ip6 from any to any in via ${oif6} \ 387 setup proto tcp 388 fi 389 390 # Allow setup of any other TCP connection 391 ${fwcmd} add pass tcp from any to any setup 392 393 # Allow DNS queries out in the world 394 ${fwcmd} add pass udp from me to any 53 keep-state 395 396 # Allow NTP queries out in the world 397 ${fwcmd} add pass udp from me to any 123 keep-state 398 399 # Everything else is denied by default, unless the 400 # IPFIREWALL_DEFAULT_TO_ACCEPT option is set in your kernel 401 # config file. 402 ;; 403 404[Ww][Oo][Rr][Kk][Ss][Tt][Aa][Tt][Ii][Oo][Nn]) 405 # Configuration: 406 # firewall_myservices: List of ports/protocols on which this 407 # host offers services. 408 # firewall_allowservices: List of IPv4 and/or IPv6 addresses 409 # or subnets that have access to 410 # $firewall_myservices, or files 411 # containing such address or subnets, 412 # one per line. 413 # firewall_trusted: List of IPv4 and/or IPv6 addresses 414 # or subnets that have full access to 415 # this host, or files containing such 416 # addresses or subnets, one per line. 417 # Be very careful when setting this. 418 # This option can seriously degrade 419 # the level of protection provided by 420 # the firewall. 421 # firewall_logdeny: Boolean (YES/NO) specifying if the 422 # default denied packets should be 423 # logged (in /var/log/security). 424 # firewall_nologports: List of TCP/UDP ports for which 425 # denied incoming packets are not 426 # logged. 427 428 # Allow packets for which a state has been built. 429 ${fwcmd} add check-state 430 431 # For services permitted below. 432 ${fwcmd} add pass tcp from me to any established 433 434 # Allow any connection out, adding state for each. 435 ${fwcmd} add pass tcp from me to any setup keep-state 436 ${fwcmd} add pass udp from me to any keep-state 437 ${fwcmd} add pass icmp from me to any keep-state 438 if [ $ipv6_available -eq 0 ]; then 439 ${fwcmd} add pass ipv6-icmp from me to any keep-state 440 fi 441 442 # Allow DHCP. 443 ${fwcmd} add pass udp from 0.0.0.0 68 to 255.255.255.255 67 out 444 ${fwcmd} add pass udp from any 67 to me 68 in 445 ${fwcmd} add pass udp from any 67 to 255.255.255.255 68 in 446 if [ $ipv6_available -eq 0 ]; then 447 ${fwcmd} add pass udp from fe80::/10 to me 546 in 448 fi 449 # Some servers will ping the IP while trying to decide if it's 450 # still in use. 451 ${fwcmd} add pass icmp from any to any icmptype 8 452 if [ $ipv6_available -eq 0 ]; then 453 ${fwcmd} add pass ipv6-icmp from any to any icmp6type 128,129 454 fi 455 456 # Allow "mandatory" ICMP in. 457 ${fwcmd} add pass icmp from any to any icmptype 3,4,11 458 if [ $ipv6_available -eq 0 ]; then 459 ${fwcmd} add pass ipv6-icmp from any to any icmp6type 3 460 fi 461 462 # Add permits for this workstations published services below 463 # Only IPs and nets in firewall_allowservices is allowed in. 464 # If you really wish to let anyone use services on your 465 # workstation, then set "firewall_allowservices='any'" in /etc/rc.conf 466 # 467 # Note: We don't use keep-state as that would allow DoS of 468 # our statetable. 469 # You can add 'keep-state' to the lines for slightly 470 # better performance if you fell that DoS of your 471 # workstation won't be a problem. 472 # 473 for i in ${firewall_allowservices} ; do 474 case $i in 475 /*) 476 grep '^[^#]' "$i" 477 ;; 478 *) 479 echo "$i" 480 ;; 481 esac 482 done | while read i _; do 483 for j in ${firewall_myservices} ; do 484 case $j in 485 [0-9A-Za-z]*/[Pp][Rr][Oo][Tt][Oo]) 486 ${fwcmd} add pass ${j%/[Pp][Rr][Oo][Tt][Oo]} from $i to me 487 ;; 488 [0-9A-Za-z]*/[Tt][Cc][Pp]) 489 ${fwcmd} add pass tcp from $i to me ${j%/[Tt][Cc][Pp]} 490 ;; 491 [0-9A-Za-z]*/[Uu][Dd][Pp]) 492 ${fwcmd} add pass udp from $i to me ${j%/[Uu][Dd][Pp]} 493 ;; 494 *[0-9A-Za-z]) 495 echo "Consider using ${j}/tcp in firewall_myservices." >&2 496 ${fwcmd} add pass tcp from $i to me $j 497 ;; 498 *) 499 echo "Invalid port in firewall_myservices: $j" >&2 500 ;; 501 esac 502 done 503 done 504 505 # Allow all connections from trusted IPs. 506 # Playing with the content of firewall_trusted could seriously 507 # degrade the level of protection provided by the firewall. 508 for i in ${firewall_trusted} ; do 509 case $i in 510 /*) 511 grep '^[^#]' "$i" 512 ;; 513 *) 514 echo "$i" 515 ;; 516 esac 517 done | while read i _ ; do 518 ${fwcmd} add pass ip from $i to me 519 done 520 521 ${fwcmd} add 65000 count ip from any to any 522 523 # Drop packets to ports where we don't want logging 524 for i in ${firewall_nologports} ; do 525 ${fwcmd} add deny { tcp or udp } from any to any $i in 526 done 527 528 # Broadcasts and multicasts 529 ${fwcmd} add deny ip from any to 255.255.255.255 530 ${fwcmd} add deny ip from any to 224.0.0.0/24 in # XXX 531 532 # Noise from routers 533 ${fwcmd} add deny udp from any to any 520 in 534 535 # Noise from webbrowsing. 536 # The stateful filter is a bit aggressive, and will cause some 537 # connection teardowns to be logged. 538 ${fwcmd} add deny tcp from any 80,443 to any 1024-65535 in 539 540 # Deny and (if wanted) log the rest unconditionally. 541 log="" 542 if checkyesno firewall_logdeny; then 543 log="log logamount 500" 544 sysctl net.inet.ip.fw.verbose=1 >/dev/null 545 fi 546 ${fwcmd} add deny $log ip from any to any 547 ;; 548 549[Cc][Ll][Oo][Ss][Ee][Dd]) 550 ${fwcmd} add 65000 deny ip from any to any 551 ;; 552[Uu][Nn][Kk][Nn][Oo][Ww][Nn]) 553 ;; 554*) 555 if [ -r "${firewall_type}" ]; then 556 ${fwcmd} ${firewall_flags} ${firewall_type} 557 fi 558 ;; 559esac 560