This sound to me like a DoS attack, which means that you can't do anything except ignoring the attacker which you've already done. You might also want to ask your ISP to block him.
As for tcpdump still seeing those packets, this is normal. They still exist on the network, but the kernel makes sure that a regular application doesn't see them.
The fact that the client port is ephemeral isn't a problem, though as you say the mutability of the server-side port is.
Assuming you have successfully instructed the server to use only ports 4000-4004 for nfsd, you have three issues: clients must be able to talk to the RPC portmapper, the mount daemon, and the NFS service, on the server.
For the NFS service
Assuming you're right about having modified the NFS service to listen on 4000-4004, clients should add
iptables -A INPUT -d se.rv.er.ip -p udp --dport 4000:4004 -j ACCEPT
iptables -A OUTPUT -s se.rv.er.ip -p udp --sport 4000:4004 -j ACCEPT
while the server should add
iptables -A INPUT -p udp --dport 4000:4004 -j ACCEPT
iptables -A OUTPUT -p udp --sport 4000:4004 -j ACCEPT
If you want to permit NFS over TCP, repeat those rules with -p tcp
instead of -p udp
.
For the portmapper
Clients should add
iptables -A INPUT -d se.rv.er.ip -p udp --dport 111 -j ACCEPT
iptables -A OUTPUT -s se.rv.er.ip -p udp --sport 111 -j ACCEPT
while the server should add
iptables -A INPUT -p udp --dport 111 -j ACCEPT
iptables -A OUTPUT -p udp --sport 111 -j ACCEPT
You may need to add pairs of rules for -p tcp
as well, as the portmapper usually supports TCP as well. Check your rejection logs to see what's being DROP
ped and adjust accordingly.
For the mount daemon
You need to find out what port it's running on on the server, with server% rpcinfo -p | grep mount
; on my server it's UDP/32775 and TCP/32769. To allow those, clients should add
iptables -A INPUT -d se.rv.er.ip -p udp --dport 32775 -j ACCEPT
iptables -A OUTPUT -s se.rv.er.ip -p udp --sport 32775 -j ACCEPT
while the server should add
iptables -A INPUT -p udp --dport 32775 -j ACCEPT
iptables -A OUTPUT -p udp --sport 32775 -j ACCEPT
and two similar pairs with -p tcp --[ds]port 32769
.
It is your responsibility to get those lines in the right place in your INPUT
and OUTPUT
chains; near the beginning is probably a good idea.
Edit: in the light of your answer below, I have updated the rules above.
Best Answer
By the helpful comments from @Appleoddity I found where I now think the error was. Dropping the packets at the output can trigger errors at the application level, instead of only simulating a noisy channel.
By running the iptables drop against the input at the host B the problem is gone: