#!/usr/bin/perl # # $Id: rpcports.pl,v 1.5 2009/12/09 09:31:46 mattieu Exp $ # # Copyright (c) 2009 Mattieu Baptiste # # Permission to use, copy, modify, and distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. # This script enables you to find NFS and RPC ports in use on a machine and # populate a PF anchor which will open these ports on the machine. # # PF must be enabled with a proper: # anchor nfs # present in your pf.conf file. # # You can for example run it at startup. Edit your /etc/rc.local and add before # the "echo '.'": # # RPC script # if [ -x /home/scripts/rpcports.pl ] ; then # /home/scripts/rpcports.pl # echo -n ' rpcports.pl' # fi use strict; use warnings; sub trim($) { my $string = shift; $string =~ s/^\s+//; $string =~ s/\s+$//; return $string; } my ($line, @tcp, @udp); my $rule = ""; my %seentcp; my %seenudp; my ($tcp, $udp); open I, "/usr/bin/rpcinfo -p|"; while ($line = ) { unless (grep /program/, $line) { my $proto = trim(substr $line, 15, 6); my $port = trim(substr $line, 21, 7); if ($proto eq "tcp") { push @tcp,$port; } elsif ($proto eq "udp") { push @udp,$port; } } } close(I); @tcp = grep !$seentcp{$_}++, @tcp; @udp = grep !$seenudp{$_}++, @udp; foreach $tcp (@tcp) { $rule .= "pass in on egress proto tcp to any port $tcp\n"; } foreach $udp (@udp) { $rule .= "pass in on egress proto udp to any port $udp\n"; } my $cmd = `echo "$rule" | pfctl -a nfs -f -`; system $cmd;