From: terry@cs.weber.edu (A Wizard of Earth C)
Subject: Re: Limiting Telnet access.
Organization: Weber State University  (Ogden, UT)
Date: Wed, 23 Dec 92 02:52:39 GMT

In article <1992Dec22.183213.10002@mtu.edu> tony@mtu.edu (Tony Dal Santo) writes:
>tony@mtu.edu (Tony Dal Santo) writes:
>>
>>Along these lines, I am curious if anyone has an idea how to allow
>>certain users access to the network, and deny others.  Something
>>like putting the user in group "network" to grant them access.  By
>>access, I mean system call level access like socket().  Even better
>>would be to provide a list of addresses/networks that are restricted/
>>allowed.
>>
>>I imagine with a streams implementation of tcp/ip, you could change
>>the perms on /dev/ip or /dev/tcp.
>>
>>Does anyone have any utilities for tracing a TCP port to a process number?
>>
>Evidently I was not too clear since I have received a few pointers
>directing me to inetd wrappers.  I am interested in restricting/granting
>users access TO the network FROM my hosts.  I can restrict access to
>the binaries (telnet, ftp, etc), but this doesn't stop them from compiling
>their own copies of these utilities.  The only way I see to filter access
>is to control system calls like socket(), bind(), accept().  I can limit
>access to networks via routing tables, but this doesn't provide user-level
>granularity.
>
>While inetd wrappers are nice, I don't see them addressing the problem.
>Once I get access to your machine, I will bring my own set of utilities
>with me (inetd), and avoid the administrators attempts at logging.
>Granted that some of the users "daemons" (e.g. ftpd) won't be as functional
>as the real ones because they don't run as root, but they will certainly
>let me gain access and avoid being logged.  Sure, as an administrator I
>can see these processes, and kill them off.  Then the users will restart
>them via cron(8) and at(1).  I don't have the time to play hide and seek
>with users.

There is no way to do this short of implementing it in the kernel.  Whether
this is a mod you make to a streams stack or to the Net/2 TCP/IP code is
irrelevant -- as long as it is in the kernel.


As long as users are allowed access to the C compiler/tools, no matter
what you do, they will be able to directly make system calls; therefore
a user space implementation is not useful.

Another implementation doomed to failure is an autopush streams module that
sits between /dev/tcp and the tcp driver.  This is because of the fact that,
even though you may be able to autopush it, the user can I_PEEK and I_POP
it.  An additional difficulty is maintaining the socket assignment state
information for the top layer, since there would not be direct communication
of state information between it and the real TCP stack.

This basically leaves real kernel mods as your only choice, unless you are
willing to go to group limitation and have a streams implementation; even
then, if you allow user mountable devices (floppies, tapes in UFS format,
etc.), the user can make their own device nodes.


Assuming you have a streams implementation, and are willing to go SGID on
all your network utilities, a group "netutil" will work; you can implement
it by removing general permissions to the devices; users will not be able
to implement SGID programs in the "netutil" group without being a member
of the group or superuser.

You might also set group membership for those users allowed unrestricted
access to the devices.


An alternate method is the use of "exclusion groups".  Basically, you set
group ownerships to group "png" of the devices, chmod 606 them.  Since
group access is checked *before* general access, access will be denied
to any member of the group "png".


Finally, you _can_ modify the system calls used for networking (there are
a lot of them) and rebuild your kernel.  This will do little good if you
have streams in any form at all, since it is still possible to build up
utilities from raw I/O to the streams devices or duplicates of the streams
device nodes.

Happy kernel hacking!


------------------
All in all, this generally isn't a reasonable thing to want to do.

An alternate that everyone else uses is to buy a Cisco (or similar box)
and put it between you and the net.  Use the Cisco to limit outgoing
connects to the standard ports

------------------

Tracing a TCP port (or UDP port, since UDP is usable for TFTP style utilities
in user land) is possible, but requires detailed knowledge of the kernel and
the TCP implementation.  If it is a streams implementation, you'd be better
off providing an instrumentation interface in the streams driver itself to
allow you to do this.  Even then, the information would be unreliable, since
the state of /dev/kmem (where you will be getting at least some of the data)
is not fixed for the duration of your access to it; you will end up with
more of a "snapshot", similar to the "ps" command.

------------------


					Terry Lambert
					terry@icarus.weber.edu
					terry_lambert@novell.com
---
Any opinions in this posting are my own and not those of my present
or previous employers.
-- 
-------------------------------------------------------------------------------
                                        "I have an 8 user poetic license" - me
 Get the 386bsd FAQ from agate.berkeley.edu:/pub/386BSD/386bsd-0.1/unofficial
-------------------------------------------------------------------------------
Newsgroups: comp.protocols.tcp-ip