Messages in this thread | | | Date | Mon, 22 Feb 1999 12:32:03 +0100 | From | Andi Kleen <> | Subject | Re: [PATCH (untested)] Subnet support in knfsd. |
| |
On Mon, Feb 22, 1999 at 11:58:56AM +0100, David Woodhouse wrote: > > ak@muc.de said: > > And this only covers the special case of subnet exports, not NIS > > group exports, dns domain wildcard exports, ..... Adding all these to > > the kernel is not possible (and not desirable). Matching the > > traditional Unix kernel design rule of providing "mechanism not > > policy" I think it is best to add some call back mechanism, where the > > kernel can ask user space to reauthenticate before refusing a file > > handle. mountd could handle this too, e.g. via a netlink socket. > > That was my initial idea. I considered the way kerneld used to work, and > thought it would be too complex, though. > > The callback to the user space authentication would be very slow. Can we wait > that long in exp_getclient(), even for a request that we would otherwise have > rejected?
Not in exp_getclient, but somewhere else. It would require a redo list for NFS (similar to what IP uses when a socket is locked). Not very complicated. Also needs a simple timeout mechanism. > > We add a character device /dev/nfsauth, for kernel->user communication. This > is not a netlink socket for two reasons: > 1. I can't find any documentation on netlink sockets. > 2. Using a locally-defined character device will allow us to notice > immediately if the user-space daemon dies and closes it, saving > us from waiting forever.
I would propose using netlink sockets, because they do already supply a very nice framework for non blocking pseudo reliable kernel<->user space communication. No need to reinvent the flat tire.
(2) can be easily done by checking for sk->dead on the kernel netlink socket.
> We add a new kind of client entry, the 'negative' client. This is extremely > similar to the negative dentry, and prevents up from looking up > non-authenticated hosts repeatedly.
Sounds good.
> In exp_getclient(), upon finding that an address has no corresponding client > entry, we...
I thought more like:
1. Check nlsk->dead, if true return NULL 2. Initialize a simple structure with IP address 3. Use netlink_broadcast to send it to any listening clients. 5. Return -1
(Not waiting because you don't want to block a nfsd thread - otherwise a very simple DOS would be possible).
In the nfsd main loop:
If -1 is returned put the complete request on a timeout list (with resource checks)
Before the svc_recv():
Check if anything is in the redo list, if yes process that.
Netlink input callback is called with an IP address in packet: 1. Search it in timeout list. 2. Unqueue the old request from the timeout list. If the answer is positive: Put it into the redo list (with maximum length and tail drop) Otherwise Free request Add negative lookup entry (again with strict memory resource limits)
Periodic GC timer:
- Remove all negative client entries that are too old and all old packets in the timeout list.
> Q: How do we combat the potential DoS attack caused by flooding the kernel with > requests from unknown IP addresses? Once they're given negative centries, it's > fine, but while the authentication is happening, the server thread is blocked. > Do we need some way of queueing the request for later, and letting the server > thread go back to serve other requests while it's waiting for an answer?
Blocking the server thread is not acceptable. Netlink solves it nicely.
> Would it be permissible to return EAGAIN to the remote client if there's > already a host (or nrservs/2 hosts) waiting for authentication? Or just to > reject the request and hope that they try again anyway?
For UDP it is easy, just drop it - the other end just will retransmit. For TCP I am not sure. Unfortunately NFS has no EAGAIN.
-Andi
-- This is like TV. I don't like TV.
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
| |