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).]
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).]