From Scott Bulau on Tue, 26 Jan 1999
I am in need of a way to secure a modem line (serial) of an assigned tty port, from dial out. This seems like an impossible task. Do you have any suggestions, words of wisdom? I'm running 2.0.35 currently, a Slackware 3.5 distribution.
You want to prevent some or all of your users from dialing out a modem that's on one of your serial ports?
That's easy. Just change the ownership on the device node (/dev/ttyS* and/or the deprecated /dev/cua*) and (possibly) on every installed program that uses the modem
Actually there is a minor complication here. Conventionally modem using programs are SGID to the "uucp" or "modem" group. That is to say that these programs execute as members of that group regardless of whether the user that started them was in the group or not. So the question becomes:
"How does one limit execution of SGID" programs?
If you strip off the world-execute bit with a command like chmod o-x, then you'd have to add the users who do need access to this program to the "modem" group. But then they wouldn't need to access your modem using the SGID program --- and they wouldn't have to respect the modem lock files or any other restrictions on the use of the device. So, we can't limit it that way.
We could make these programs SUID and change the ownership (rather than just the group assignment) of the device node. Then the devices wouldn't have to be group writable, and we could create a special group of modem users, assign our modem programs to that and add our authorized modem users to that group. However this poses a greater security risk. If someone subverts (tricks) an SGID program they can only do relatively limited damage. If they subvert an SUID program they can change the permissions and executable files owned by that program's account.
Hmm. Such a conundrum. The answer is pretty easy --- but I had to invent it myself. I've never seen it written up in any book or article (other than the ones that I've written).
THE WHOLE PATCH IS A SET OF ACCESS CONTROL POLICIES!
So, you create a directory full of your SGID programs. you can asign it to any arbitrary group. Make the directory inaccessible to "others" (mode 550 or 750 for example). Now, only the owner of the directory and members of the associated group can access any of the links (filenames) in that directory. You can replace the original file link (under /usr/bin or wherever) with a symlink to the restricted directory. That symbolic link can only be followed by members of the associated group.
You can even make two different "group restricted" directories --- associated with different groups. Each can contain HARD links to the same SGID world executable file. Members of either group can then access their link to the program, and thus execute it. Other users can "see" (or access or execute) the program.
You could also require that a user concurrently be a member of multiple different groups to access a program or other file. You just put one group limited directory under another. The whole path is a set of access controls.
Of course there is a downside to this. Let's say that you wanted to grant 'minicom' access to members of "staff" and of "wheel." So you create a /usr/bin/staff/ and a /usr/bin/wheel. Each is set to mode 750 and each as a hard link to the minicom program. You ensure that now other (world accessible) links exist to the program). Now these users have to use different paths to access the same program. This suggests that members of each group needs additional entries on their $PATH environment string.
Even though its not explicitly covered in any of the books I've read I'm sure some sysadmins sometimes use a scheme such as I've described.
That's not so bad. It's a bit confusing --- but then, so are "access control lists" (ACLs) as supported by Netware, NT, and some other versions of Unix. I note that the versions of Unix which support ACLs (Solaris, HP-UX, AIX, etc) make no use of them by default. Professional sysadmins almost never use them. This suggests that the stock Unix "permissions" scheme is enough for almost all practical purposes.
You have to do this for every program which is SUID or SGID to the "modem" group (or whatever group you assigned your /dev/ttyS node to). Many sites use the "uucp" group for this (since the 'uucico' command, from the UUCP subsystem was one of the first commands used for this sort of thing).
Thanks for a response, I know how popular you are.