Click to See Complete Forum and Search --> : Booting to something other than a login program


Craig McPherson
01-12-2001, 01:30 AM
You can do a lot of cool stuff with this. Read on.

Background: The /etc/inittab file instructs init (the superprocess which handles starting everything else) on what to do during startup. In addition to controlling daemons and other programs that run at startup (by defining calling the contents of the various RC directories, or some other method), it also spawns login programs (called gettys) on several ttys, and can also spawn an X display manager for a graphical login.

As an example, here's a few lines from the /etc/inittab on my home system:

1:2345:respawn:/sbin/getty 38400 tty1
2:23:respawn:/sbin/getty 38400 tty2
3:23:respawn:/sbin/getty 38400 tty3
x:3:respawn:/usr/X11R6/bin/Login.app >> /var/log/login.app.log 2>&1

The first three lines spawn getty programs (login screens) on the first three terminals (tty1 through tty3). I actually have 11 such lines to get 11 terminals, but they're all basically the same. Let's examine the structure of those lines.

The first number is an id number. The id number should be the same as the number of the tty that item starts on.

The numbers after the first colon indicate at what runlevels the item should be executed: for example, the first item in my example will be executed in runlevels 2, 3, 4, and 5, and the others will only be executed on 2 and 3. You can customize what kind of stuff your computer boots into at various runlevels using this stuff, but this is still background information I'm going over.

The "respawn" indicates that when the spawned process executes, it should be immediatley restarted. IE, when a getty process starts, you log in, and the getty program spawns a shell. When the shell exits -- ie you log out-- the getty program terminates and is automatically respawned -- aka you're dumped back to another login screen.

/sbin/getty is the name of the program to spawn. It's the console login program. Redhat and company by default use mingetty rather than getty, which is a simpler version of getty. It uses a bit less memory, but doesn't have all the features getty does. Anyway, that's beside the point. The 38400 is an argument to getty, and isn't of concern to us. Mingetty doesn't use an argument like it. The tty argument specifies what tty to spawn the getty process onto.

The fourth line above is what starts my graphical X login program... you'll note the 3 after the first colon, which means it only starts in runlevel 3.

THE GOOD STUFF

Now, what can you actually do with this knowledge?

To use a real example from my recent experiences, say that you want to have MP3 player software running on a system that you use as basically a public music jukebox. You don't want to have to log in and start the player software manually, AND you don't want the users to be able to break out of the program and into a shell -- that'd be bad. Running an interactive program from an init script is also a no-no, so we have to do some stuff less common. I also wanted to eliminate any hint of a login screen at all to keep people from poking around.

So... what I did.

STEP 1: I changed my LILO configuration so that there were two labels. One, called "music", is the default option, and boots into runlevel 2 (by appending the argument "2"). The other, called "maint", boots into runlevel 3 (by appending the argument "3"). There's no delay, so people don't even see the LILO login screen when the computer is starting up, but I can still get to it by holding down SHIFT. The "maint" option is password-protected. See the lilo.conf man page on how to password-protect a label so that nobody can boot into it without knowing a password.

STEP 2: So now I have LILO set up so that I can easily boot into either runlevel 2 or runlevel 3. But both runlevels do the same thing, so it's time to make some changes to inittab. To prepare, though, I make a script that executes my mp3 player software with the arguments I need. I saved this script as /usr/local/sbin/music

STEP 3: I go to the section of /etc/inittab where all the gettys are started, and I change it to this:

1:2:respawn:/usr/local/sbin/music tty1
1:3:respawn:/sbin/mingetty tty1
2:23:respawn:/sbin/mingetty tty2
3:3:respawn:/sbin/mingetty tty3
4:3:respawn:/sbin/mingetty tty4
5:3:respawn:/sbin/mingetty tty5

What this does:

In runlevel 2, my music software is started on tty1 (started by the first line). A mingetty is started on tty2 (started by the third line). Only a UNIX user would know how to switch to tty2 and see the login screen there, and even if someone did, the only account on the machine has a secure password, so there's not much concern. I just like being able to log in and do maintenance without rebooting. If I wanted to be really secure, I could change the third line to remove the "2" after the first colon, which would stop that login program from being spawned.

In runlevel 3, which I use for maintenance, five login screens are spawned, on each of the first five terminals.

NOTE #1: I use mingetty instead of getty on this machine to save memory.

NOTE #2: Here's what's REALLY cool about this: since my MP3 player software isn't running under a shell, it's IMPOSSIBLE for anyone using the computer to break out to a command line -- there's none to break out to. (For the pedants, yes, it's running under a shell because I'm running it from a script, but not an interactive shell, so it's impossible for the user to get to the shell), AND, because of the respawn, the init program automatically restarts the player software whenever it's exited, so it's impossible to a user to stuff up the system by exiting the player software.

So basically, you can have the system boot into just ONE program, and make it impossible for the user to do anything other than interact with that one program. This is cool for my MP3 player, for dedicated web browsers (using Lynx, of course -- doing X stuff would get a lot more complex), or for any other of "appliance" type stuff.

You can also, if you don't care about local physical security, have the system boot directly into a root shell without having to log in, by simply running /bin/bash from /etc/inittab instead of a getty.

One caveat: anything you spawn from inittab will be run as ROOT unless you do something special. If you're concerned about physical security of the machine, don't spawn any program that contains the ability to spawn a shell, or to selectively edit files, because someone with physical access to the machine could easily r00t it. It's safe to spawn something like an MP3 player that doesn't have any file management or shell-spawning capability written in to the program, but spawning something like a shell or a file manager program would give anyone who can physically get to the keyboard full access to the computer.

If the program you're spawning is a script, you should be able to run it as a non-root by using su, like this:

1:2:respawn:su peon /usr/local/sbin/music tty1

Since /usr/local/sbin/music is a script, and su lets you run a script rather than an interactive shell by passing the name of the script as an argument, this SHOULD run the player software as user "peon", so that you'll be safe no matter what the program could do. I haven't tried this, though.

I'm going to try to clean this document up, add some more details and background info, and turn it into a NHF. Please post any questions or comments or anything you didn't understand.

------------------
http://users.ipa.net/~cmcpher/paminv.gif DEBIAN (http://www.debian.org/) http://users.ipa.net/~cmcpher/paminv.gif
It turns girls into statues!

[This message has been edited by Craig McPherson (edited 12 January 2001).]

zGoRNz
01-13-2001, 06:22 AM
good write up!

the su thing will work, even for binaries like:
su gorn /bin/vi

or something

also if you setuid the binary (yea only binaries) when it is run by root, it imediatly switches to the user. so like in my case (i'm paranoid):
ls -l /usr/seti/setiathome
-rws--x--x 1 seti wheel 133816 Jan 11 05:00 /usr/seti/setiathome*

the s where an x would normal be means setuid. it could also be setgid (set group id)
s -l /usr/seti/setiathome
-rws--s--x 1 seti seti 133816 Jan 11 05:00 /usr/seti/setiathome*

now it's run as user seti group seti

i have /usr/seti/setiathome in my inittab (there was a reason i didn't put it in the rc scripts but i forgot, its backgrounded anyway but still...) and setiathome is run as user seti, not root


- out -

------------------
Dunt Dunt Duh...
GoRN To The Rescue,
Yet Again
zGoRNz@yahoo.com
aim: GoRNToTheRescue

Craig McPherson
01-13-2001, 06:43 PM
Originally posted by zGoRNz:
good write up!

the su thing will work, even for binaries like:
su gorn /bin/vi



Hey, you're right, it does -- but it didn't used to! I swear, the first time I tried something like that, probably more than a year ago now, if I tried to do that with a binary I'd always see "su: cannot execute binary file."

Maybe it had something to do with the switch to Pluggable Authentication Modules? I know that completely changed the way su worked. It was pre-PAM that I tried this -- I bet that was what changed it.

also if you setuid the binary (yea only binaries) when it is run by root, it imediatly switches to the user. so like in my case (i'm paranoid):

I didn't even think of that. Usually, setuid'ing is used to make a program run as root -- I've never thought about using the setuid bit to force root to run a program as a normal user.

That's brilliant. I can just make the binary that my script calls owned by "peon" or something, setuid it, and then it'll get run as "peon" even though root runs the script that calls it, right?

That's awesome, thanks, I wouldn't have thought of that.

zGoRNz
01-13-2001, 09:23 PM
yea now matter how the binary is run, from real bash or a script in bash, or ksh or tcsh or whatever if it's setuid it will run as that user

i still don't understand why scripts can't be setuid though, i think i remember hearing cause of security but you could have a binary that does system calls...

------------------
Dunt Dunt Duh...
GoRN To The Rescue,
Yet Again
zGoRNz@yahoo.com
aim: GoRNToTheRescue

Craig McPherson
02-14-2001, 01:51 AM
I'm going to submit an edited version of this as a NHF tomorrow. If you have any last-minute corrections, questions, or comments, speak now or forever hold your peace.

mangeli
02-14-2001, 04:28 PM
So this would work if I wanted to install a pc with linux on it in my car to play mp3's wouldn't it.....

Molecule Man
02-14-2001, 07:28 PM
There are a couple of Car Linux projects (http://cajun.sourceforge.net/) that basically build upon this. http://neon.mp3car.com/truck/index.html is the page from a guy in our LUG.


The running of programs from init script was something I was considering. I was getting tired of manually logging in and starting setiathome. Thanks guys.