# [solved] NFS and iptables

## Jimini

Hey there,

I have 2 servers here: my file-server (A) and my router (B). A works as the nfs-server, B is my nfs-client. Every night, B runs a script, backs up a few files, mounts a nfs share from A and moves the backup-tarball there. Now I have the problem, that my iptables-script on B closes every port that I have not opened explicitly - so nfs cannot mount the folder. I edited the following files to set static ports for rpc.lockd, rpc.mountd and rpc.statd.:

/etc/conf.d/nfs (shortened)

```
OPTS_RPC_MOUNTD="-p 4001"

# ex. OPTS_RPC_STATD="-p 32765 -o 32766"

OPTS_RPC_STATD="-p 4002"
```

What is the "-o"-parameter good for?

/etc/sysctl.conf (shortened)

```
fs.nfs.nlm_tcpport = 4000

fs.nfs.nlm_udpport = 4000
```

So I have the involved ports as following:

nfs tcp 2049

nfs udp 2049

portmap tcp 111

portmap udp 111

rpc.lockd tcp 4000

rpc.lockd udp 4000

rpc.mountd tcp 4001

rpc.mountd udp 4001

rpc.statd tcp 4002

rpc.statd udp 4002

How do I have to edit my iptables-rules then? For testing, I have added the following rules:

```
### NFSD

iptables -A INPUT -p tcp --sport 2049 -m state --state NEW -j ACCEPT

iptables -A INPUT -p udp --sport 2049 -m state --state NEW -j ACCEPT

### PORTMAP

iptables -A OUTPUT -p tcp --dport 111 -m state --state NEW -j ACCEPT

iptables -A OUTPUT -p udp --dport 111 -m state --state NEW -j ACCEPT

iptables -A OUTPUT -p tcp --sport 111 -m state --state NEW -j ACCEPT

iptables -A OUTPUT -p udp --sport 111 -m state --state NEW -j ACCEPT

iptables -A INPUT -p tcp --dport 111 -m state --state NEW -j ACCEPT

iptables -A INPUT -p udp --dport 111 -m state --state NEW -j ACCEPT

iptables -A INPUT -p tcp --sport 111 -m state --state NEW -j ACCEPT

iptables -A INPUT -p udp --sport 111 -m state --state NEW -j ACCEPT

### RPC.LOCKD

iptables -A OUTPUT -p tcp --sport 4000 -m state --state NEW -j ACCEPT

iptables -A OUTPUT -p udp --sport 4000 -m state --state NEW -j ACCEPT

iptables -A OUTPUT -p tcp --sport 4000 -m state --state NEW -j ACCEPT

iptables -A OUTPUT -p udp --sport 4000 -m state --state NEW -j ACCEPT

iptables -A INPUT -p tcp --dport 4000 -m state --state NEW -j ACCEPT

iptables -A INPUT -p udp --dport 4000 -m state --state NEW -j ACCEPT

iptables -A INPUT -p tcp --sport 4000 -m state --state NEW -j ACCEPT

iptables -A INPUT -p udp --sport 4000 -m state --state NEW -j ACCEPT

### RPC.MOUNTD

iptables -A OUTPUT -p tcp --sport 4001 -m state --state NEW -j ACCEPT

iptables -A OUTPUT -p udp --sport 4001 -m state --state NEW -j ACCEPT

iptables -A OUTPUT -p tcp --sport 4001 -m state --state NEW -j ACCEPT

iptables -A OUTPUT -p udp --sport 4001 -m state --state NEW -j ACCEPT

iptables -A INPUT -p tcp --dport 4001 -m state --state NEW -j ACCEPT

iptables -A INPUT -p udp --dport 4001 -m state --state NEW -j ACCEPT

iptables -A INPUT -p tcp --sport 4001 -m state --state NEW -j ACCEPT

iptables -A INPUT -p udp --sport 4001 -m state --state NEW -j ACCEPT

### RPC.STATD

iptables -A OUTPUT -p tcp --sport 4002 -m state --state NEW -j ACCEPT

iptables -A OUTPUT -p udp --sport 4002 -m state --state NEW -j ACCEPT

iptables -A OUTPUT -p tcp --sport 4002 -m state --state NEW -j ACCEPT

iptables -A OUTPUT -p udp --sport 4002 -m state --state NEW -j ACCEPT

iptables -A INPUT -p tcp --dport 4002 -m state --state NEW -j ACCEPT

iptables -A INPUT -p udp --dport 4002 -m state --state NEW -j ACCEPT

iptables -A INPUT -p tcp --sport 4002 -m state --state NEW -j ACCEPT

iptables -A INPUT -p udp --sport 4002 -m state --state NEW -j ACCEPT
```

Best regards,

Jimini

----------

## bendeguz

I'm not very experienced in iptables, but i guess this script is overcomplicated.

Is this the script for A or B?

----------

## mokia

So the router is the client. 

lines for the router:

iptables -A INPUT  -m multiport -i LAN_interface -p tcp --dports 111,2049,4000:4002 -j ACCEPT

iptables -A INPUT  -m multiport -i LAN_interface -p udp --dports 111,2049,4000:4002 -j ACCEPT

LAN iterface is recommented . You did not want to open these ports for the internet.

I think the output policy is not realy needed, And not even any port.

----------

## Jimini

As I wrote, the script is for testing-purpose only. Of course these rules were not written for everyday-use :)

I've replaced my rules with

```
iptables -A INPUT -m multiport -i $lan -p tcp --dports 111,2049,4000:4002 -j ACCEPT

iptables -A INPUT -m multiport -i $lan -p udp --dports 111,2049,4000:4002 -j ACCEPT
```

Then I try to start nfs:

etc/init.d/nfs start

```
 * Starting NFS statd ...                                                               [ !! ]

 * ERROR:  cannot start nfs as rpc.statd could not start
```

/etc/init.d/rpc.statd start

```
 * Starting NFS statd ...                                                               [ !! ]
```

tail /var/log/messages

```
[2010-06-23 22:07:37] notice daemon rpc.statd Version 1.1.4 Starting

[2010-06-23 22:07:37] notice daemon rpc.statd Version 1.1.4 Starting

[2010-06-23 22:07:37] notice daemon rpc.statd Flags:

[2010-06-23 22:07:37] notice daemon rpc.statd Flags:

[2010-06-23 22:07:37] err daemon rpc.statd unable to register (statd, 1, udp).

[2010-06-23 22:07:37] err daemon rc-scripts ERROR:  cannot start nfs as rpc.statd could not start

[2010-06-23 22:07:40] notice daemon rpc.statd Version 1.1.4 Starting

[2010-06-23 22:07:40] notice daemon rpc.statd Version 1.1.4 Starting

[2010-06-23 22:07:40] notice daemon rpc.statd Flags:

[2010-06-23 22:07:40] notice daemon rpc.statd Flags:

[2010-06-23 22:07:40] err daemon rpc.statd unable to register (statd, 1, udp).
```

I really can't find my mistake. Any ideas?

Best regards,

Jimini

----------

## mokia

Loks like portmap is not running.

This is the server?

----------

## Jimini

I'm sorry, I forgot to mention, that portmap is running, but I can't restart it:

/etc/init.d/portmap restart

 * Saving portmap table ...

...for minutes without any errors or anything else.

Everything I am doing here, happens on my router (B), which works as a nfs-client in this setup. 

Best regards,

Jimini

----------

## mokia

On client side is NFS deamon not necessary, just portmap.

If portmapp runs you be able to mount NFS shares

test portmapp on the router

rpcinfo -p localhost 

if it returns something like

 program vers proto   port

    100000    2   tcp    111  portmapper

    100000    2   udp    111  portmapper

try to mount the share.

-[edit]-

If not, try to restart the portmap (kill 9)

----------

## Jimini

Okay, portmap needs a loooooong time, if I restart it, but "stop" and "start" work. So portmap is definitely running. But rpc.statd still does not want to start. Then, when I execute "rpcinfo -p localhost":

```
rpcinfo: Portmapper kann nicht erreicht werden: RPC: Fehler des entfernten Systems - Die Wartezeit für die Verbindung ist abgelaufen
```

Translation: "rpcinfo: Portmapper unreachable: RPC: Error at remote system - connection timeout"

Best regards,

Jimini

----------

## mokia

Iptables blocks conections from localhost too? Hmm.

Try to change the $lan to !$wan in the rules.

Also try to reload the testconfig. 

Do you have some Dropping lines for OUTPUT In your iptables config?

----------

## Jimini

My default policy DROPs everything (INPUT, OUTPUT, FORWARD). That's why I set up these strange rules before :)

Now I added these ones:

```
iptables -A INPUT -m multiport -p tcp --dports 111,2049,4000:4002 -j ACCEPT

iptables -A INPUT -m multiport -p udp --dports 111,2049,4000:4002 -j ACCEPT

iptables -A OUTPUT -m multiport -p tcp --sport 111,2049,4000:4002 -j ACCEPT

iptables -A OUTPUT -m multiport -p udp --sport 111,2049,4000:4002 -j ACCEPT
```

But the problem stays the same - "rpcinfo -p localhost" doesn't work.

I'll take a nap and face the problem tomorrow again, thanks so long for your help!

Best regards,

Jimini

----------

## Jimini

I've tried a new bunch of rules and now rpcinfo-shows something:

```
iptables -A INPUT -m multiport -p tcp --dports 111,2049,4000:4002 -j ACCEPT

iptables -A INPUT -m multiport -p udp --dports 111,2049,4000:4002 -j ACCEPT

iptables -A OUTPUT -m multiport -p tcp --dports 111,2049,4000:4002 -j ACCEPT

iptables -A OUTPUT -m multiport -p udp --dports 111,2049,4000:4002 -j ACCEPT
```

Portmap and rpc.statd are running:

```
   Program Vers Proto   Port

    100000    2   tcp    111  portmapper

    100000    2   udp    111  portmapper

    100024    1   udp  47436  status

    100024    1   tcp  52974  status
```

Anyway, I still cannot mount the share:

```
mount.nfs: rpc.statd is not running but is required for remote locking.

mount.nfs: Either use '-o nolock' to keep locks local, or start statd.
```

But rpc.statd is definitely running:

```
ps -A | grep rpc

 7008 ?        00:00:00 rpc.statd

 7068 ?        00:00:00 rpc.statd
```

Do I perhaps have to change the nfs-setup from random ports to static ports from on the nfs-server, too?

Best regards,

Jimini

Edit: I have opened my firewall and can now mount the nfs-share.

These are my current connections from the nfs-client to the nfs-server.

10.0.0.1:861           10.0.0.2:36473        tcp   TIME_WAIT     0:01:13

10.0.0.1:34182         10.0.0.2:111          tcp   TIME_WAIT     0:01:13

10.0.0.1:875           10.0.0.2:2049         tcp   TIME_WAIT     0:01:30

10.0.0.1:815           10.0.0.2:36991        udp                 0:00:00

10.0.0.1:44491         10.0.0.2:111          udp                 0:00:00

10.0.0.1:38545         10.0.0.2:111          tcp   TIME_WAIT     0:01:13

10.0.0.1:56524         10.0.0.2:36991        udp                 0:00:00

I have highlighted the traffic from/to ports I know. But where does the other stuff belong to? I have set all rpc-related stuff on static ports (/etc/sysctl and /etc/conf.d/nfs). And why can't I mount the nfs-share, when my firewall is in normal state, e.g. everything closed and only a number of ports opened?

```
iptables -A OUTPUT -m multiport -p tcp --dports 111,2049,4000:4002 -j ACCEPT

iptables -A OUTPUT -m multiport -p udp --dports 111,2049,4000:4002 -j ACCEPT
```

----------

## mokia

set

iptables -A INPUT -s 10.0.0.2 -p all -j ACCEPT (ip of fileserver) this will allow your fileserver to connect to the router on any ports. And try to mount it. 

If not working set

iptables -A OUTPUT -d 10.0.0.2 -p all -j ACCEPT for the backward conection.

This must work!

This is not a solution, just a way to split the problem in two half (input and output)

----------

## Jimini

1) iptables -A INPUT -s 10.0.0.2 -p all -j ACCEPT

```
mount -a

mount.nfs: mount system call failed
```

2) iptables -A OUTPUT -d 10.0.0.2 -p all -j ACCEPT:

```
mount -a

mount

10.0.0.2:/some/shared/dir on /mount/point type nfs (rw,hard,intr,addr=10.0.0.2)
```

3) I commented the first rule (INPUT) out and can still mount the share. For me, that makes sense. The nfs-client initiates the sharing-process, so I have to get the OUTPUT-thing open. Afterwards, the connection is established, so it is not blocked anymore by my script.

Best regards,

Jimini

----------

## mokia

 *Jimini wrote:*   

> 
> 
> /etc/conf.d/nfs (shortened)
> 
> ```
> ...

 

You maked this changes in the file server. Right?

----------

## Jimini

No, everything was changed on the nfs-client only. The fileserver / nfs-server is in the same state as a few days or weeks ago.

Best regards,

Jimini

----------

## mokia

This ist the problem. XD

[Edit]

The changes must be made on the server side 

Make the changes, stop the NFS server, reload the nfsd kernel module if not compiled in & reload supported by your kernel. (if not reboot needed  :Sad: ).

And start NFS server.

rpcinfo -p localhost on the server side.

You must see that status mountd nfs nlockmgr running on the right port 

after insert 

iptables -A OUTPUT -m multiport -p udp --dports 111,2049,4000:4002 -j ACCEPT 

iptables -A OUTPUT -m multiport -p tcp --dports 111,2049,4000:4002 -j ACCEPT 

on the client and you'r ready to mount the share.

----------

## Jimini

 *mokia wrote:*   

> This ist the problem. XD

 

Hehe, I wrote that yesterday yet, but perhaps not clearly enough :)

Now it finally works. Here is the summary of the steps I made (as far as I could remember them, so I can not guarantee their function):

1) On nfs-server and nfs-client, I set static ports for rpc.lockd, rpc.mountd and rpc.statd. 

/etc/sysctl

```
fs.nfs.nlm_tcpport = 4000

fs.nfs.nlm_udpport = 4000
```

Perhaps it is necessary to set the ports for rpc.lockd in /boot/grub/grub.conf (lockd.nlm_udpport=4000 lockd.nlm_tcpport=4000) or lilo.conf. I have built everything into the kernel, so I did not need to do this.

/etc/conf.d/nfs

```
OPTS_RPC_MOUNTD="-p 4001"

OPTS_RPC_STATD="-p 4002 -o 4003"

```

2) Restart the involved services (on server: nfs, portmap, rpc.statd / on client: portmap, rpc.statd) or reboot.

3) Control the ports by executing "rpcinfo -p localhost". It should show up something like this:

nfs-server:

```
   Program Vers Proto   Port

    100000    2   tcp    111  portmapper

    100000    2   udp    111  portmapper

    100024    1   udp   4002  status

    100024    1   tcp   4002  status

    100005    1   udp   4001  mountd

    100005    1   tcp   4001  mountd

    100005    2   udp   4001  mountd

    100005    2   tcp   4001  mountd

    100005    3   udp   4001  mountd

    100005    3   tcp   4001  mountd

    100021    1   udp   4000  nlockmgr

    100021    3   udp   4000  nlockmgr

    100021    4   udp   4000  nlockmgr

    100021    1   tcp   4000  nlockmgr

    100021    3   tcp   4000  nlockmgr

    100021    4   tcp   4000  nlockmgr

    100003    2   udp   2049  nfs

    100003    3   udp   2049  nfs

    100003    2   tcp   2049  nfs

    100003    3   tcp   2049  nfs
```

nfs-client:

```
   Program Vers Proto   Port

    100000    2   tcp    111  portmapper

    100000    2   udp    111  portmapper

    100024    1   udp   4002  status

    100024    1   tcp   4002  status
```

4) Edit the iptables-rules. My rules (on the nfs-client) are quite strict, so I needed a few more rules. I also prefer seperate rules for every port.

```
iptables -A INPUT -i lo -d 127.0.0.1 -p tcp --dport 111 -j ACCEPT

iptables -A INPUT -i lo -d 127.0.0.1 -p udp --dport 111 -j ACCEPT

iptables -A OUTPUT -s $intern -p tcp --dport 111 -j ACCEPT       

iptables -A OUTPUT -s $intern -p udp --dport 111 -j ACCEPT       

iptables -A INPUT -i $lan -s $intern -p tcp --dport 2049 -j ACCEPT

iptables -A INPUT -i $lan -s $intern -p udp --dport 2049 -j ACCEPT

iptables -A OUTPUT -d $intern -p tcp --dport 2049 -j ACCEPT       

iptables -A OUTPUT -d $intern -p udp --dport 2049 -j ACCEPT       

iptables -A INPUT -i $lan -s $intern -p tcp --dport 4000 -j ACCEPT

iptables -A INPUT -i $lan -s $intern -p udp --dport 4000 -j ACCEPT

iptables -A OUTPUT -d $intern -p tcp --dport 4000 -j ACCEPT       

iptables -A OUTPUT -d $intern -p udp --dport 4000 -j ACCEPT       

iptables -A INPUT -i $lan -s $intern -p tcp --dport 4001 -j ACCEPT

iptables -A INPUT -i $lan -s $intern -p udp --dport 4001 -j ACCEPT

iptables -A OUTPUT -d $intern -p tcp --dport 4001 -j ACCEPT       

iptables -A OUTPUT -d $intern -p udp --dport 4001 -j ACCEPT       

iptables -A INPUT -i lo -p tcp --dport 4002 -j ACCEPT             

iptables -A INPUT -i lo -p udp --dport 4002 -j ACCEPT             

iptables -A OUTPUT -d $intern -p tcp --dport 4002 -j ACCEPT       

iptables -A OUTPUT -d $intern -p udp --dport 4002 -j ACCEPT 
```

$lan stands for my internal nic, $intern stands for the addresses in my private network.

And finally of course a big "thank you" for your help, mokia! :)

Best regards,

Jimini

----------

## DaggyStyle

which nfs version is that?

when I tried to get nfs 3 and iptables to coexists, I never were able to get it to work because nfs kept changing the port it was using no matter what I've putted in the conf files, I've went around it by using nfs4 (which has other problems but works with iptables).

----------

## Jimini

I use nfs-utils-1.1.4-r1 on both machines. My only mount-options in /etc/fstab are "hard,intr", so the share should be mounted with nfs 4, I assume.

Best regards,

Jimini

----------

## DaggyStyle

ok, nice to see you solved it.

----------

