View previous topic :: View next topic |
Author |
Message |
Auka Tux's lil' helper
Joined: 01 Jul 2002 Posts: 110 Location: Germany
|
Posted: Sun Aug 24, 2003 7:23 pm Post subject: [FAQ / HOWTO] NFS with firewalling |
|
|
NFS with firewalling
Category: Networking & Security | Firewalling
** Edit:
- 2005-02-20: Edit /etc/sysctl.conf to add a static port-mapping for lockd (i.e. assign port 4001 for tcp and udp)
# TCP Port for lock manager
sys.fs.nfs.nlm_tcpport = 4001
# UDP Port for lock manager
sys.fs.nfs.nlm_udpport = 4001
Abstract
When trying to use NFS over a firewall (such as an iptables setup) you will encounter difficulties because some of the TCP/IP and UDP ports which are beeing used by nfs components, are "randomly assigned" as part of the "SunRPC" mechanism.
The following explanations will show you how to set up NFS in such a way that it is possible to configure a meaningful and tight firewall policy.
This guide will not cover how to configure and set up NFS and neither does it explain how to create firewall rulesets with iptables.
status quo
Without any reconfiguration, when issuing rpcinfo -p you will get an output similar to this:
Code: | # rpcinfo -p
program vers proto port
100000 2 tcp 111 portmapper
100000 2 udp 111 portmapper
100024 1 udp 656 status
100024 1 tcp 659 status
100003 2 udp 2049 nfs
100003 3 udp 2049 nfs
100003 2 tcp 2049 nfs
100003 3 tcp 2049 nfs
100021 1 udp 40273 nlockmgr
100021 3 udp 40273 nlockmgr
100021 4 udp 40273 nlockmgr
100021 1 tcp 37807 nlockmgr
100021 3 tcp 37807 nlockmgr
100021 4 tcp 37807 nlockmgr
100005 1 udp 675 mountd
100005 1 tcp 678 mountd
100005 2 udp 675 mountd
100005 2 tcp 678 mountd
100005 3 udp 675 mountd
100005 3 tcp 678 mountd
|
basic nfs and portmap theory
The ports for nfs (2049) as well as portmap (111) are statically assigned, these are well know ports, and defined in /etc/services. Yet the ports for mountd, nlockmgr and status are not well known ports but are beeing dynamically assigned by the portmapper - and that is exactly what is causing problems with firewall setups. (To be exact the portmapper doesn't really allocate ports. A server binds to a port and then registers the port with the portmapper/rpcbind). But we will get back to this and what to do later on in detail.
First lets have a second short look at the table above. You will see that portmapper as well as nfs use both tcp as well as udp ports. Depending on your NFS kernel setup you might use NFS over udp (which is the default) or NFS over tcp only. If you have enabled NFS tcp support in the kernel you can mount your NFS partitions over tcp by adding "tcp" to your mount options on the client.
So what should be obvious so far is that both the portmapper (111 udp/tcp) as well as the NFS port (2049 for the moment lets also say both udp/tcp) should be enabled at you firewall.
hands-on experiences
Now lets come to what this is all about: Instead of having rpc.statd, rpc.mountd and rpc.nlockmgr register dynamic ports with the portmapper we tell them to always bind to the same port. Then we can use these ports for our firewall setup. Yes, it is really just as simple as it seems.
1.) First of all you have to edit /etc/conf.d/nfs which should look similar to this:
Code: | # Config file for /etc/init.d/nfs
# Number of servers to be started up by default
RPCNFSDCOUNT=8
# Options to pass to rpc.mountd
# ex. RPCMOUNTDOPTS="-p 32767
RPCMOUNTDOPTS=""
# Options to pass to rpc.statd
# ex. RPCSTATDOPTS="-p 32765 -o 32766"
RPCSTATDOPTS=""
# OPTIONS to pass to rpc.rquotad
# ex. RPCRQUOTADOPTS="-p 32764"
RPCRQUOTADOPTS=""
|
Have a look at the lines where you can add options to rpcmountd, rpcstatd and rpcquotad. See the comments? Gentoo Developers rule, don't they? As man rpc.mountd and the other manpages would tell you, -p (and -o) are exactly the options you will need to have these services use static ports. If you don't explicitly want, or have to, use different tcp ports, you can just stick to the default tcp port range 32764-32767. Then just add the options exactly as shown in the comments above.
2.) Time to restart you NFS services on your NFS server. Code: | /etc/init.d/nfs restart |
3.) Now check the RPC port assignments by issuing the ports should have changed:
Code: |
100000 2 tcp 111 portmapper
100000 2 udp 111 portmapper
100024 1 udp 32765 status
100024 1 tcp 32765 status
100003 2 udp 2049 nfs
100003 3 udp 2049 nfs
100003 2 tcp 2049 nfs
100003 3 tcp 2049 nfs
100021 1 udp 40315 nlockmgr
100021 3 udp 40315 nlockmgr
100021 4 udp 40315 nlockmgr
100021 1 tcp 55755 nlockmgr
100021 3 tcp 55755 nlockmgr
100021 4 tcp 55755 nlockmgr
100005 1 udp 32767 mountd
100005 1 tcp 32767 mountd
100005 2 udp 32767 mountd
100005 2 tcp 32767 mountd
100005 3 udp 32767 mountd
100005 3 tcp 32767 mountd
|
That's it! The ports are what we just defined. Now you can add your firewall rules.
4.) Now simply add your firewall rules for the ports listed above. I prefer using the excellent Firewall Builder GUI (net-firewall/fwbuilder), if you also do, then generate a group of services for these ports:
Code: |
- udp port 111 (portmap)
- tcp port 111 (portmap)
- tcp port 2049 (nfs over TCP)
- udp port 2049 (nfs over UDP)
- tcp port 32764 (rpc.quotad)
- tcp port 32765 and 32766 (rpc.statd)
- tcp port 32767 (rpc.mountd)
|
Have fun...
Last edited by Auka on Sun Feb 20, 2005 12:01 pm; edited 3 times in total |
|
Back to top |
|
|
irony Tux's lil' helper
Joined: 10 Jul 2002 Posts: 129 Location: CT
|
Posted: Wed Feb 11, 2004 7:32 pm Post subject: |
|
|
Won't there still be problems with the lockd ports?
I found a howto that suggests passing lockd port options at boot:
Code: |
root=/dev/hda1 lockd.udpport=32768 lockd.tcpport=32768
|
Is there a simpler way? _________________ "and if rain brings winds of change, let it rain on us forever..." |
|
Back to top |
|
|
irony Tux's lil' helper
Joined: 10 Jul 2002 Posts: 129 Location: CT
|
Posted: Wed Feb 11, 2004 8:08 pm Post subject: |
|
|
Apparently, passing the lockd.udpport and lockd.tcpport options at boot doesn't seem to work, it still assigns them to different ports every time nfs starts and stops. _________________ "and if rain brings winds of change, let it rain on us forever..." |
|
Back to top |
|
|
Auka Tux's lil' helper
Joined: 01 Jul 2002 Posts: 110 Location: Germany
|
Posted: Fri Feb 13, 2004 8:19 pm Post subject: |
|
|
Hmm...lockd...so far I didn't think about that one to be honest.
A quick glance tells me that I don't have rpc.lockd running, just kernel lockd. Also "man lockd" says:
Code: | The rpc.lockd program starts the NFS lock manager (NLM) on kernels that don't start it automatically. However, since most kernels do start it automatically, rpc.lockd. is usually not required. Even so, running it anyway is harmless. |
lsof -i shows that on my machine lockd doesn't seem to open or use any ports at all. |
|
Back to top |
|
|
Cocker68 Apprentice
Joined: 16 Jan 2003 Posts: 227 Location: Germany
|
Posted: Thu Feb 19, 2004 11:21 am Post subject: |
|
|
The lockd can be bound to a specific port via /etc/modules.conf:
options lockd nlm_udpport=32768 nlm_tcpport=32768
edit:
Or better: Create a file named /etc/modules.d/nfs with this content. (This way it will survive a modules-update)
- Cocker :wq
Last edited by Cocker68 on Tue Oct 05, 2004 11:13 am; edited 1 time in total |
|
Back to top |
|
|
primero.gentoo Guru
Joined: 23 Dec 2003 Posts: 402
|
Posted: Wed Mar 24, 2004 9:24 pm Post subject: |
|
|
irony wrote: | Apparently, passing the lockd.udpport and lockd.tcpport options at boot doesn't seem to work, it still assigns them to different ports every time nfs starts and stops. |
lockd port configuration depends on kernel configuration, if it is compiled as module or statically in the kernel
Code: |
(compiled as modules)
add "options lockd nlm_udpport=4001 nlm_tcpport=4001" in /etc/modules.conf
(compiled in kernel)
add "lockd.udpport=4001 lockd.tcpport=4001" to kernel line in the bootloader
|
For quotad instead you need at least 3.08 version (that is in portage) and need to modify "/etc/services" adding the following lines
Code: |
rquotad 4003/tcp
rquotad 4003/udp
|
and (if ther is not yet) to /etc/rpc
Code: |
rquotad 100011 rquotaprog quota rquota
|
configuring the others daemon via /etc/init.d/nfs you'll have alll your nfs-related daemon statically linked to the ports you choose and you'll be able to configure the firewall in the right way.
Bye
Primero |
|
Back to top |
|
|
violatr n00b
Joined: 21 Mar 2004 Posts: 5 Location: Aussie
|
Posted: Sun Apr 11, 2004 9:26 am Post subject: NFS+IPTABLES=Headache |
|
|
Hey,
I've been looking through the gentoo forums for awhile concerning iptables and NFS, I have been trying to get things functional for quite a while now, but no matter how I modify this script I can't seem to get things right.. it always hangs when attempting to mount shares I'm not sure exactly what the problem is, something to do with sunrpc I think...
Anyways here is the script.. and any ideas would be very much appreciated
#!/sbin/runscript
IPTABLES=/sbin/iptables
IPTABLESSAVE=/sbin/iptables-save
IPTABLESRESTORE=/sbin/iptables-restore
FIREWALL=/etc/firewall.rules
DNS1=203.123.69.15
DNS2=203.123.73.59
#inside
IIP=192.168.0.250
IINTERFACE=eth0
LOCAL_NETWORK=192.168.0.0/24
#outside
OIP="`$IFCONFIG $PPP0`"
OINTERFACE=ppp0
opts="${opts} showstatus panic save restore showoptions rules"
depend() {
need net
}
rules() {
stop
ebegin "Setting internal rules"
einfo "Setting default rule to drop"
$IPTABLES -P FORWARD DROP
$IPTABLES -P INPUT DROP
$IPTABLES -P OUTPUT DROP
#default rule
einfo "Creating states chain"
$IPTABLES -N allowed-connection
$IPTABLES -F allowed-connection
$IPTABLES -A allowed-connection -m state --state ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A allowed-connection -i $IINTERFACE -m limit -j LOG --log-prefix \
"Bad packet from ${IINTERFACE}:"
$IPTABLES -A allowed-connection -j DROP
#ICMP traffic
einfo "Creating icmp chain"
$IPTABLES -N icmp_allowed
$IPTABLES -F icmp_allowed
$IPTABLES -A icmp_allowed -m state --state NEW -p icmp --icmp-type \
time-exceeded -j ACCEPT
$IPTABLES -A icmp_allowed -m state --state NEW -p icmp --icmp-type \
destination-unreachable -j ACCEPT
$IPTABLES -A icmp_allowed -p icmp -j LOG --log-prefix "Bad ICMP traffic:"
$IPTABLES -A icmp_allowed -p icmp -j DROP
#Incoming traffic
einfo "Creating incoming ssh traffic chain"
$IPTABLES -N allow-ssh-traffic-in
$IPTABLES -F allow-ssh-traffic-in
#Flood protection
$IPTABLES -A allow-ssh-traffic-in -m limit --limit 1/second -p tcp --tcp-flags \
ALL RST --dport ssh -j ACCEPT
$IPTABLES -A allow-ssh-traffic-in -m limit --limit 1/second -p tcp --tcp-flags \
ALL FIN --dport ssh -j ACCEPT
$IPTABLES -A allow-ssh-traffic-in -m limit --limit 1/second -p tcp --tcp-flags \
ALL SYN --dport ssh -j ACCEPT
$IPTABLES -A allow-ssh-traffic-in -m state --state RELATED,ESTABLISHED -p tcp --dport ssh -j ACCEPT
einfo "Creating incoming nfs chain"
$IPTABLES -N allow-nfs
$IPTABLES -F allow-nfs
$IPTABLES -A allow-nfs -s 192.168.0.1 -d 0/0 -p tcp --dport 111 -j ACCEPT
$IPTABLES -A allow-nfs -s 192.168.0.1 -d 0/0 -p udp --dport 111 -j ACCEPT
$IPTABLES -A allow-nfs -s 192.168.0.1 -d 0/0 -p tcp --dport 1034 -j ACCEPT
$IPTABLES -A allow-nfs -s 192.168.0.1 -d 0/0 -p udp --dport 1034 -j ACCEPT
$IPTABLES -A allow-nfs -s 192.168.0.1 -d 0/0 -p tcp --dport 2049 -j ACCEPT
$IPTABLES -A allow-nfs -s 192.168.0.1 -d 0/0 -p udp --dport 2049 -j ACCEPT
$IPTABLES -A allow-nfs -s 192.168.0.1 -d 0/0 -p udp --dport 32767 -j ACCEPT
$IPTABLES -A allow-nfs -s 192.168.0.1 -d 0/0 -p tcp --dport 32767 -j ACCEPT
#outgoing traffic
einfo "Creating outgoing ssh traffic chain"
$IPTABLES -N allow-ssh-traffic-out
$IPTABLES -F allow-ssh-traffic-out
$IPTABLES -A allow-ssh-traffic-out -p tcp --dport ssh -j ACCEPT
einfo "Creating outgoing dns traffic chain"
$IPTABLES -N allow-dns-traffic-out
$IPTABLES -F allow-dns-traffic-out
$IPTABLES -A allow-dns-traffic-out -p udp -d $DNS1 --dport domain \
-j ACCEPT
$IPTABLES -A allow-dns-traffic-out -p udp -d $DNS2 --dport domain \
-j ACCEPT
einfo "Creating outgoing http/https traffic chain"
$IPTABLES -N allow-www-traffic-out
$IPTABLES -F allow-www-traffic-out
$IPTABLES -A allow-www-traffic-out -p tcp --dport www -j ACCEPT
$IPTABLES -A allow-www-traffic-out -p tcp --dport https -j ACCEPT
#Catch portscanners
einfo "Creating portscan detection chain"
$IPTABLES -N check-flags
$IPTABLES -F check-flags
$IPTABLES -A check-flags -p tcp --tcp-flags ALL FIN,URG,PSH -m limit \
--limit 5/minute -j LOG --log-level alert --log-prefix "NMAP-XMAS:"
$IPTABLES -A check-flags -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP
$IPTABLES -A check-flags -p tcp --tcp-flags ALL ALL -m limit --limit \
5/minute -j LOG --log-level 1 --log-prefix "XMAS:"
$IPTABLES -A check-flags -p tcp --tcp-flags ALL ALL -j DROP
$IPTABLES -A check-flags -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG \
-m limit --limit 5/minute -j LOG --log-level 1 --log-prefix "XMAS-PSH:"
$IPTABLES -A check-flags -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j DROP
$IPTABLES -A check-flags -p tcp --tcp-flags ALL NONE -m limit \
--limit 5/minute -j LOG --log-level 1 --log-prefix "NULL_SCAN:"
$IPTABLES -A check-flags -p tcp --tcp-flags ALL NONE -j DROP
$IPTABLES -A check-flags -p tcp --tcp-flags SYN,RST SYN,RST -m limit \
--limit 5/minute -j LOG --log-level 5 --log-prefix "SYN/RST:"
$IPTABLES -A check-flags -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
$IPTABLES -A check-flags -p tcp --tcp-flags SYN,FIN SYN,FIN -m limit \
--limit 5/minute -j LOG --log-level 5 --log-prefix "SYN/FIN:"
$IPTABLES -A check-flags -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
# Apply and add invalid states to the chains
einfo "Applying chains to INPUT"
$IPTABLES -A INPUT -m state --state INVALID -j DROP
$IPTABLES -A INPUT -j icmp_allowed
$IPTABLES -A INPUT -j check-flags
$IPTABLES -A INPUT -i lo -j ACCEPT
$IPTABLES -A INPUT -j allow-ssh-traffic-in
$IPTABLES -A INPUT -j allowed-connection
$IPTABLES -A INPUT -j allow-nfs
einfo "Applying chains to FORWARD"
$IPTABLES -A FORWARD -m state --state INVALID -j DROP
$IPTABLES -A FORWARD -j icmp_allowed
$IPTABLES -A FORWARD -j check-flags
$IPTABLES -A FORWARD -o lo -j ACCEPT
$IPTABLES -A FORWARD -j allow-ssh-traffic-in
$IPTABLES -A FORWARD -j allow-www-traffic-out
$IPTABLES -A FORWARD -j allowed-connection
einfo "Applying chains to OUTPUT"
$IPTABLES -A OUTPUT -m state --state INVALID -j DROP
$IPTABLES -A OUTPUT -j icmp_allowed
$IPTABLES -A OUTPUT -j check-flags
$IPTABLES -A OUTPUT -o lo -j ACCEPT
$IPTABLES -A OUTPUT -j allow-ssh-traffic-out
$IPTABLES -A OUTPUT -j allow-dns-traffic-out
$IPTABLES -A OUTPUT -j allow-www-traffic-out
$IPTABLES -A OUTPUT -j allowed-connection
#Allow client to route through via NAT (Network Address Translation)
$IPTABLES -t nat -A POSTROUTING -o $IINTERFACE -j MASQUERADE
eend $?
}
start() {
ebegin "Starting firewall"
if [ -e "${FIREWALL}" ]; then
restore
else
einfo "${FIREWALL} does not exists. Using default rules."
rules
fi
eend $?
}
stop() {
ebegin "Stopping firewall"
$IPTABLES -F
$IPTABLES -t nat -F
$IPTABLES -X
$IPTABLES -P FORWARD ACCEPT
$IPTABLES -P INPUT ACCEPT
$IPTABLES -P OUTPUT ACCEPT
eend $?
}
showstatus() {
ebegin "Status"
$IPTABLES -L -n -v --line-numbers
einfo "NAT status"
$IPTABLES -L -n -v --line-numbers -t nat
eend $?
}
panic() {
ebegin "Setting panic rules"
$IPTABLES -F
$IPTABLES -X
$IPTABLES -t nat -F
$IPTABLES -P FORWARD DROP
$IPTABLES -P INPUT DROP
$IPTABLES -P OUTPUT DROP
$IPTABLES -A INPUT -i lo -j ACCEPT
$IPTABLES -A OUTPUT -o lo -j ACCEPT
eend $?
}
save() {
ebegin "Saving Firewall rules"
$IPTABLESSAVE > $FIREWALL
eend $?
}
restore() {
ebegin "Restoring Firewall rules"
$IPTABLESRESTORE < $FIREWALL
eend $?
}
restart() {
svc_stop; svc_start
}
showoptions() {
echo "Usage: $0 {start|save|restore|panic|stop|restart|showstatus}"
echo "start) will restore setting if exists else force rules"
echo "stop) delete all rules and set all to accept"
echo "rules) force settings of new rules"
echo "save) will store settings in ${FIREWALL}"
echo "restore) will restore settings from ${FIREWALL}"
echo "showstatus) Shows the status"
} |
|
Back to top |
|
|
Hagar Guru
Joined: 11 Feb 2003 Posts: 445
|
Posted: Thu May 13, 2004 12:35 am Post subject: |
|
|
The correct parameters depend on the kernel version.
2.4.*: lockd.udpport=4001 lockd.tcpport=4001
2.6.*: lockd.nlm_udpport=4001 lockd.nlm_tcpport=4001 |
|
Back to top |
|
|
solarium_rider Tux's lil' helper
Joined: 23 Jun 2003 Posts: 88 Location: San Francisco
|
Posted: Mon Mar 14, 2005 10:22 pm Post subject: Re: NFS+IPTABLES=Headache |
|
|
violatr wrote: | Hey,
Anyways here is the script.. and any ideas would be very much appreciated
...
# Apply and add invalid states to the chains
einfo "Applying chains to INPUT"
$IPTABLES -A INPUT -m state --state INVALID -j DROP
$IPTABLES -A INPUT -j icmp_allowed
$IPTABLES -A INPUT -j check-flags
$IPTABLES -A INPUT -i lo -j ACCEPT
$IPTABLES -A INPUT -j allow-ssh-traffic-in
$IPTABLES -A INPUT -j allowed-connection
$IPTABLES -A INPUT -j allow-nfs
...
|
I know this thread has been dead for a while, but at least one of the reasons why your this script isn't working for nfs is because you have allow-nfs after the allowed-connection chain. The allowed-connection chain must be last (for reasons I don't fully understand.)
I'm currently try to lockdown nfs to certain ports and ran across this thread =) |
|
Back to top |
|
|
ikke Apprentice
Joined: 14 Jan 2005 Posts: 225 Location: Belgium
|
Posted: Sat Mar 19, 2005 12:52 pm Post subject: |
|
|
Thanks for this great tutorial. I was confronted with this problem yesterday, thanks to this howto I was able to fix it, and now I understand better how NFS works. It'd have taken me several hours to find out what to do without this howto. _________________ Working day and night to enhance your Linux Desktop experience
Blog |
|
Back to top |
|
|
flipnode Apprentice
Joined: 03 Oct 2004 Posts: 172 Location: USA
|
Posted: Sat Jul 09, 2005 6:43 am Post subject: Fix to the above, NFS -Lock and a Firewall |
|
|
Auka wrote: | NFS with firewalling
** Edit:
- 2005-02-20: Edit /etc/sysctl.conf to add a static port-mapping for lockd (i.e. assign port 4001 for tcp and udp)
# TCP Port for lock manager
sys.fs.nfs.nlm_tcpport = 4001
# UDP Port for lock manager
sys.fs.nfs.nlm_udpport = 4001
|
The above isn't correct, it should be
Code: |
# TCP Port for lock manager
fs.nfs.nlm_tcpport = 4001
# UDP Port for lock manager
fs.nfs.nlm_udpport = 4001
|
After you make the change then run the command
for some reason the sysctl.conf file has the wrong or old variables defined. _________________ I think Gentoo is great! |
|
Back to top |
|
|
jamapii l33t
Joined: 16 Sep 2004 Posts: 637
|
Posted: Sun Jul 10, 2005 12:31 am Post subject: |
|
|
I use "rpcinfo -p | grep $j | grep $i | cut -b 22-29" to find the real ports, where i and j are protocol (tcp or udp) and rpcinfo's "Program" number or name, e.g. "i=tcp; j=portmapper" or "i=tcp; j=100000".
You could even write a wrapper function and specify "if portnumber >= 100000 then it's rpc" and possibly "if the port string isn't in /etc/services then it's rpc". Also there's /etc/rpc |
|
Back to top |
|
|
GuyPaddock n00b
Joined: 18 Aug 2010 Posts: 2 Location: Rochester, NY
|
Posted: Wed Aug 18, 2010 10:15 pm Post subject: |
|
|
Good tutorial that provided almost exactly what I needed, but I wanted to let you know you're missing one command during step 2:
Code: |
/etc/init.d/rpc.statd restart
|
Without that, "status" doesn't pick up the port changes. |
|
Back to top |
|
|
|