Date: Tue, 17 Nov 1998 10:46:29 -0500 (EST) From: Robert Watson <robert@cyrus.watson.org> To: freebsd-security@FreeBSD.ORG Subject: Alternative approaach: Re: Would this make FreeBSD more secure? Message-ID: <Pine.BSF.3.96.981117102200.24312A-100000@fledge.watson.org> In-Reply-To: <19981117084523.A17686@weathership.homeport.org>
next in thread | previous in thread | raw e-mail | index | archive | help
In my view, inetd provides most of the services we already require, in the TCP case. That is, inetd allows us to run unpriveledged server software in such a way that it has access to priveledged ports (although *only* for the purpose of receiving connections, and only on a specific port with specific properties). Additionally, I allows us to place wrappers in between and perform filtering etc. The only really reasonably argument against inetd in all cases is that some high frequency connection events load the system because of the constant fork/exec and subsequent loading of the system. In a few cases, such as sendmail, it is also nice to have the daemon sticking around for the purposes of queue management and redelivery events. It seems to me that we could retain the benefits of inetd at the same time as reducing the cost of its approach. That is, with only minor modification to inetd and the daemons, we could use the SCM_RIGHTS file descriptor over socket mechanism to provide daemons with their connections as they come in. This is not quite as low in cost as having the daemon sit around spinning on an accept(), and then forking as needed or passing it on, as it requires inetd to be involved. But it does not require inetd to be very involved -- certainly not to the point of fork()/exec(). Here are the details as I envision it, and any criticisms are welcome: a new 'type' is added in inetd.conf -- presumably replacing the 'wait'/'nowait' field, perhaps 'socktrans' or such. At start-time, inetd forks and execs all daemons that are of this type, except that it leaves open a socket as fd 3 for the child process, that can be read on. Instead of spinning on accept(), the child will now spin on recvmsg() with appropriate arguments to receive up to N file descriptors. Inetd now binds the ports as it normally would, awaiting connections. When a connection comes in, inetd evaluates whether it is a valid connection (possibly taking advantage of wrapper code, perhaps an allow/deny file of some kind, perhaps logging it), and then transfers it over the socket to the child. In the event that the child closes the file socket, it can always be restarted, improving reliability (if desired). This solution, of course, is oriented at the TCP crowd -- sendmail, httpd, the normal suspects. Given the cost of a TCP setup, and the light-weight-ness of inetd, I do not think there will be that much of a performance impact on most systems. Clearly, there is no real benefit for daemons such as sshd, other than providing a standard way for daemons to listen -- sshd has to run as root so that it can switch to the account of the user when required. I'm not sure that this can address the UDP case. I believe that in the case of DNS (bind), the UDP responses have to come from the same port that they are sent to; also, the resolution of interest is not 'connection' but 'packet'. The cost of forwarding the packets to the process is higher per-packet and therefore more likely to impede performance. Similarly, inetd would probably have to send the packet for the daemon. The easier approach might simply be to bind the socket, and then pass it off to the child for further use. Any time the child died (or released the socket), presumably it could be restarted. I'm not as satisfied with this case, as it doesn't allow inetd to filter the 'connections'. On the other hand, it no longer requires the daemon to run as root. This solution requires no potentially suspect modifications to the kernel, and no modification to the standard set of groups that would no doubt upset people. Mapping uids to port numbers is also a somewhat problematic approach -- not very scalable, and no fun if you use a portmapper :). Actually, that does raise the case of the RPC-based NFS suite. In that case, perhaps there could be an indication that 'any port will do' for the port passed to the daemons, except the portmapper where only the appropriate port will do. In the general case though, the NFS suite probably does require root access on both the client and the server, so perhaps it is not a biggy. And I'm not sure that we want to munge our heads into the RPC code to rewrite it to use this mechanism? :) Presumably we would also have to address the case where a daemon listens on multiple ports (UDP and TCP, such as Bind). Perhaps a solution might in fact be to have a protocol by which daemons talk to bind using the socket, such that they can in effect ask inetd to proxy bindings for them; inetd.conf would be more of an ACL file on what it was willing to proxy. That is a more serious change, however, and as it does not affect many daemons, is something that could be overlooked for greater simplicity for now. My belief is that this should certainly perform well enough, and require only minor modifications to sendmail. For many web servers, I imagine it would not represent a serious performance impact. At the rate of a few hits a second for a low-end web server (400,000 hits a day is only 5 a second on average), transfering a few ancillary data packets has low cost. Addressing the dual udp/tcp case by passing two sockets would deal with some additional daemons, such as syslog and bind. All existing daemons would continue to function unmodified, of course. Robert N Watson robert@fledge.watson.org http://www.watson.org/~robert/ PGP key fingerprint: 03 01 DD 8E 15 67 48 73 25 6D 10 FC EC 68 C1 1C Carnegie Mellon University http://www.cmu.edu/ TIS Labs at Network Associates, Inc. http://www.tis.com/ SafePort Network Services http://www.safeport.com/ To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-security" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.3.96.981117102200.24312A-100000>