Virtual Consoles in Linux
Stale links are one of my Internet pet peeves. Often there's a great article "out there", but the links to it have gone stale.Therefore, instead of posting just a link to George Hansper's great article "Vitual Consoles in Linux", I decided to post the link AND reproduce the entire article.
Unfortunately, the Google Blogger CSS make this document somewhat difficult to read. One simple option is to open the page source code, copy the pure HTML out to a file, and open that in your browser. But Google Blogger mangles the links, so that isn't ideal. Another option is to read the original, which might be at the following link (if it hasn't gone stale in the meantime):
Contents
- Introduction
- Mouse support
- Banners and Prompts
- Practical Uses for Virtual Consoles
- Changing Fonts
- Keyboard mapping
- Keyboard LEDs
Introduction
Virtual Consoles are a key feature of Linux (and FreeBSD etc) and possibly the most undersold feature of the whole operating system. You get the same effect as a screenful of xterms, without running up a X11 server!What is a "Virtual Console" ?
When the any Unix system first boots up, you get a normal Unixlogin:
prompt, so you can log in, and start X11 or do whatever else you would do with a single Unix shell. Linux is pretty much the same, except that instead of just one such login:
, you get several. These are accessed using the 2-key combinations <ALT><F1>, <ALT><F2>, <ALT><F3> etc. Each of the "screens" with you see is known as a "Virtual Console". Virtual Consoles are Independant
Apart from the fact that you use the same screen and keyboard, each virtual console is quite independant of the others. It's a lot like having several VT100-terminals connected (except that it's much easier to switch between them). This point is emphasised by the fact that each console has it's own CAPS LOCK, NUM LOCK and SCROLL LOCK states, and this is reflected in the LED's too. Try it: if you set CAPS LOCK on in one console, and then switch to another, the led goes out, and you're back to lower case. When you switch back, presto, you're back in CAPS LOCK mode.Mouse support for Copy and Paste - Introducing gpm
Virtual Consoles have one feature which you just can't get on a regular VT100 terminal: mouse support. Most Linux systems come bundled with a program called gpm This allows you to copy and paste text within a console, and even between different consoles. By default, the buttons are usually set up to mimic those of an Xterm. (Left=select, Middle=paste, Right=adjust). The gpm program used to be called "selection".GPM and X11
The problem with having a program like gpm which reads the mouse-device, is that you cannot have more than one such program running at a time. So if, for example, you are running gpm, and want to run X11 (which also reads the mouse device), you are in trouble. Or rather, you used to be in trouble. The current release of gpm supports a Repeater Mode where it will write mouse-data to a named pipe,/dev/gpmdata
in addition to it's normal operation. Any other program, such as an X11 server, can be read this pipe as if it were a regular mouse-device. To utilise this feature, you should: - Start gpm with the -R parameter
- Use the following mouse-configuration in the
"Pointer"
section your XF86config:
Protocol "MouseSystems" Device "/dev/gpmdata"
Distinguishing between Virtual Consoles
The only problem with having a lot of virtual consoles is that you can get lost. There are two things I like to do to distinguish virtual consoles.- add the tty name to the login message
- set the color of the prompt
Putting the tty in the login message
The login message consists of a banner which put up by thegetty
program (or mgetty
or agetty
etc), plus the login-prompt supplied by the login
program. The banner which is supplied by getty
consists of the contents of the file /etc/issue
. This file may also contain "escapes". These allow us to include some variable-text in the /etc/issue
file, such as the hostname, or (you guessed it) the tty name. If you are using agetty
, use \l
to insert the tty name. If you are using mgetty
, use @L
to insert the tty name. For example, you /etc/issue file make look like this: Welcome to \l on \nSee the man page for your getty program for details of escapes which may be used in
/etc/issue
Setting a color prompt
The linux console also supports escape sequences for rendering color text. These are used by the commandls --color
These escape sequences are common to both linux consoles and (color) xterms, so we can use the same prompt for both environments. The complete range of escape sequences supported by the console is described in the man page console_codes(4)
The following line, when included in, say, /etc/csh.cshrc
will set a color-prompt for the tcsh: set prompt = "%{\e[0;3${tty:s/tty//:s/p//}m%}%n@%m %C2 %\! %#%{\e[0;0m%} "However, for the sake of completeness, we'll include some provision for xterm-escapes, too.
if ( $?tcsh ) then if ($term == xterm ) then set xterm_hdr = '\e]2\;%m:%/\a\e]1\;%c\a' else set xterm_hdr endif set color_s = "\e[0;3${tty:s/tty//:s/p//}m" set color_e = '\e[0;0m' set prompt = "%{$xterm_hdr$color_s%}%n@%m %C2 %\! %#%{$color_e%} " unset xterm_hdr color_s color_e endifSimilarly, for bash, you can use the following in
~/.bashrc
if [ "$BASH" != "" ]; then if [ "$TERM" == "xterm" ]; then XTERM_HDR='\e]2;\h:\w\a\e]1;\W\a' else XTERM_HDR='' fi TTY="`tty`" COLOR_S="\e[0;3${TTY/*[^0-9]/}m" COLOR_E='\e[0;0m' PS1="\[$XTERM_HDR$COLOR_S\]\u@\h \w \\! \\$\[$COLOR_E\] " unset XTERM_HDR COLOR_S COLOR_E fi
Practical Uses for Virtual Consoles
So far, we've only considered virtual consoles as being additional login terminals. By default, this is the way they are setup. In fact, virtual consoles can be used for other things, too.Logging to a virtual console
One of the best uses for spare virtual consoles is to display system messages. The Unix system generates quite an array of possible messages, most of which are sent to the syslog facility. These messages may be anything from a simple information message that a particular kernel-module is being loaded or unloaded, to important notices, such as "the system is going down". The syslog is handled by a deamon,syslogd
which controls the distribution of these messages based on their facility and priority. The syslogd
reads the file /etc/syslog.conf
to determine how to distribute these messages. Priority
The priority is an indication of the "urgency" of a message. The following eight priorities are defined (in order of priority):emerg
orpanic
alert
crit
error
orerr
warning
orwarn
notice
info
debug
syslogd
generally treats priorities as meaning "equal or greater than" the stated priority. Consider the /etc/syslog.conf
entry: *.error /var/log/error.logThis will log messages from all facilities which have a priority of
error
or greater to the file /var/log/error.log
If we wanted only the messages with priority error (and not the higher priority messages), we could specify: *.=error /var/log/error.log
Facility
The "facility" of a message is a means of categorising messages, so that we can divide them into "broad areas of interest". The following facilities are defined:auth
authpriv
cron
daemon
kern
lpr
mail
news
security
syslog
user
uucp
local0
local1
local2
local3
local4
local5
local6
local7
mail.warning /dev/tty10refers to messages of priority warning or higher, but only for the facility
mail
, and no others.
Sample /etc/syslog.conf
file
It is quite simple to divide our different syslog messages amongst a number of different, otherwise unused, virtual consoles. I like to use tty9-tty12 for this purpose, as it doesn't interfer with my normal "login" consoles on tty1-tty6, or the default X11 console, tty7 Note also, that directing messages towards virtual consoles does not divert these messages away from log files. The syslogd
lets you direct messages as many (multiple) destinations as you ,like. Here's an example of some useful additions to your default /etc/syslog.conf
: daemon.info /dev/tty9 kern.info /dev/tty10 *.info;daemon.none;kern.none;auth.none;authpriv.none \ /dev/tty11Don't forget to 'kill -1' your
syslogd
after changing syslog.conf
I have been told that, when directing syslog output directly to a tty like this, that pressing ^S
or Scroll Lock
in the tty can "block" the syslog daemon, and any daemons which subscribe to the syslog service. I haven't had the problem myself, probably because I rarely use Scroll Lock
. Caution is advised, particularly if your system is being used in a multi-user role. Using tail -f logfile
may be preferable, although it would be more complex to set up. Logs and Security
You may notice that, by default,/var/log
is not world-readable. This is because log files can contain security-sensitive information, especially if debugging is turned on. One example of happens when you type an incorrect password during login. This results is a message to the syslog, notifying of the bad login attempt, and quoting the userid. If it just so happens that you've pressed Enter
once too often, you may end up entering your password in the userid field. Some versions of login
may log this faithfully - and your password inadvertently ends up in a log file! Or, just as bad, in plain view on a virtual console! So, convinient as it is to log messages to virtual consoles, it is important to be aware of what kind of information is openly visible on your virtual consoles. This applies particularly if your computer is being shared amongst several users, or is located anywhere other than a locked room. Adding things like auth.none;authpriv.none
(in the above example) allows us to keep sensitive information out of plain sight. Likewise, it's best not to display debug
messages, unless you are actively debugging your system. Isolating logs from specific daemons
Given that there are 8 "spare" facility categories (local0-7
), it would be nice if we could, for example, devote one virtual console to the tcpd messages, and another to ppp mesages, etc. Unfortunately, most programs are hard-wired to report their messages to a specific facility (eg daemon). This means that you would need to recompile the program in question in order to make it use a different syslog facility. Running processes from Init
By default, most Linux systems are set up to run onlygetty
or xdm processes on virtual consoles. There is no technical reason why you can't run something else. For example, if you just want to run top, so that it's always "there", right from boot-up, you just have to modify your /etc/inittab
to include a line like this: 5:2345:respawn:/bin/open -c 5 -w -- /usr/bin/top -sWhich will run
top
on tty5. Don't forget to 'kill -1' the init
process after modifying /etc/inittab
. Note in particular the use of the -s flag on top. This put top into "secure mode". This mode disables the interactive commands 'kill' and 'renice'. This makes it "safe" to run in this mode. Without the '-s' flag, anyone could walk up to the computer and use top to kill other people's processes. The "secure mode" of top is just ideal for running top in this way. Init and Security
The biggest problem starting processes frominit
(as we did the above example) is that the process runs with the userid root. This is not a problem for programs like getty
, which are designed to run as root, and top
, which has a special mode for this case. But what do we do when we want to run something that wasn't designed for this kind of thing? There is a solution, though it's not a pretty one. Let's say that we want to run a lynx
web-browser in the same way as we have done with top
. Lynx does not have a "secure-mode". It can write files to the disk, and can even spawn shells (using the ! keystroke). One solution is to run lynx as another user (other than root) by using: 6:23:respawn:/bin/open -c 5 -w -- /bin/su nobody --command="/usr/bin/lynx http://www.luv.asn.au/"This runs lynx as user "nobody", by executing it via the su program. Even this may be considered "insecure", as lynx is capable of "escaping" to an
sh(1)
shell (using the ! keystroke). Once an "unfriendly" has access to a shell, they have a "foot in the door", and can hunt for any weak-spots in your system's security. The best solution is to isolate such "anonymous" users, in the same way that the ftpd does with it's anonymous users. That is, by using chroot
to isolate them in a subdirectory. First, we create a minimal directory tree where our program can run: mkdir /home/sandpit mkdir /home/sandpit/bin cp /usr/bin/lynx /home/sandpit/bin cp /bin/su /home/sandpit/bin mkdir /home/sandpit/etc cat <<EOF > /home/sandpit/etc/passwd root:*:0:0:root:/root:/bin/bash lynxuser:*:65534:65534:lynxuser:/:/bin/lynx EOF cat <<EOF > /home/sandpit/etc/group root:*:0:root EOF cat <<EOF > /home/sandpit/etc/hosts 127.0.0.1 localhost EOF cat <<EOF > /home/sandpit/etc/host.conf order hosts EOF mkdir -p /home/sandpit/usr/lib/terminfo/l cp /usr/lib/terminfo/l/linux /home/sandpit/usr/lib/terminfo/lNext we copy the files needed to run our program into our newly created directory tree, and set up the most restrictive permissions we can.
cp /etc/lynx.cfg /home/sandpit/etc mkdir /home/sandpit/lib cp /lib/ld-linux.so.1 /lib/libc.so.5 /home/sandpit/lib cp /lib/libm.so.5 /usr/lib/libslang.so.0.99.34 /home/sandpit/lib chown -R root.root /home/sandpit chmod -R go= /home/sandpit chmod a+x /home/sandpit /home/sandpit/* /home/sandpit/bin/* chmod a+r /home/sandpit/etc/* /home/sandpit/lib/* chmod -R a+rX /home/sandpit/usrNote: you may require slightly different runtime libraries for your particular version of
lynx
. Now we can safely spawn a lynx browser from init
, without compromising our system security. Our inittab entry would look like this: 6:23:respawn:/bin/open -c 6 -w -- /usr/sbin/chroot /home/sandpit /bin/su lynxuser http://www.luv.asn.au/
The open(1)
command
If you like the idea of virtual consoles, but do not like going through the login process more than once, the open
command if for you. The open
command starts a new shell on the next available virtual console, without giving a login prompt first. This is not a security risk, as you have to login before you can use the open
command in the first place. The only complication arises from what is considered the "next available" virtual console. If a getty is being run on a console, it is unavailable. Likewise, if you are logging syslog messages to a console, it is also unavailable. So, if you are using the open
command a lot, you may wish to disable some of the getty processes in your /etc/inittab
file. (Note: I had to start both top
and lynx
by way of the open
command, since they had a tendancy to use the wrong tty if I just ran them directly from init) Changing Fonts
A number of different fonts are available for virtual consoles, and these are to be found in the directory:/usr/share/consolefonts -- or -- /usr/lib/kbd/consolefontsand are invoked by the program:
setfontNote that there some fonts have different pixel dimensions. If you are running in EXTENDED VGA mode (ie by using the boot paramter "
vga=2
"), you will get an 8x8 font (which has quite ugly descenders). A better option is to use some of the SVGA modes that your video card may support. First, you should boot your system, specifying vga=ask
. Then try the different modes one by one, until you find one that suits you. After booting up in a particular mode, you may want to "save" that mode by using the command: restoretextmode -w COLSxROWSThis will save the parameters of the current video mode in the file named
COLSxROWS
, such that you can switch back to that mode without rebooting, by using: restoretextmode -r COLSxROWSYou will still have to go through the boot-it-and-see process at least once for each video mode. Once you have a suitable set of video mode files, named according to the
COLSxROWS
convention, you can use the command: resizecons COLSxROWSThis will invoke
restoretextmode
and invoke the appropriate stty
command to ensure that the tty driver is "aware" of the new size. (Try changing from an 80-column mode to an 132-column mode using just restoretextmode
, and you'll see what I mean). Keyboard mapping in virtual consoles
The default keyboard map in the Linux console is defined by the file:/usr/src/linux/drivers/char/defkeymap.mapHowever, it is not necessary (or desirable) to edit this file directly. If you want to load a completely new map (such as a dvorak keymap) you only have to use the command:
loadkeymap /usr/share/keytables/dvorak.mapThere are numerous different keymaps already available, including all the common European ones. Use the
dumpkeys
command to view the current keyboard map. If you just want to change a few keys, you should use the command loadkeys
For example, if you have a 104-key keyboard, you will have the special "windows" keys. You can put these to good use, by mapping them onto special functions. loadkeys - << EOF keycode 125 = Decr_Console # Left ~# key keycode 126 = Incr_Console # Right ~# key EOFThis will remap the left and right "windows" keys, such that they will step through the range of virtual consoles which have been activated. To find out what the keycodes are for any given key, use the command
showkey
The other situation you may encounter is that you have some keys on your keyboard which do not generate a keycode when pressed. For example, I have a "multimedia" keyboard, which has 12 rubber buttons in addition to the 104-keys. With the default keyboard mapping, these do not generate keycodes at all. We can assign them keycodes, but first we have to find out what codes the keyboard is sending out. This is done using the command: showkey -sThis will tell us the "scancodes" generated by our unmapped keys. Each key generates a one- or two-byte scancode when it is pressed. When the key is released, it sends the same code, but with the most significant bit set (for two-byte codes, the MSB is set on the second byte). Next, we have to assign the scancode to a keycode. This is done using the command
setkeycodes
. This requires some care, as it is not obvious which keycodes are actually free for use. You can get some idea by looking in the defkeymap.map
file. All the keycodes up to 83 are in use. Above that, some are used, some aren't. For my multimedia keyboard, I use the following command to set up the keycodes: #!/bin/sh # # front<->back www Calculator Xfer # alt-shift-tab e032 e021 e023 # 120 121 122 # # |<< |>|| [] >>| # e010 e022 e024 e019 # 92 93 94 95 # # Coffee Menu Mute Vol- Vol+ # e07a e026 e020 e02e e030 # 123 124 89 90 91 # setkeycodes e010 92 e019 95 e020 89 e021 121 \ e022 93 e023 122 e024 94 e026 124 \ e02e 90 e030 91 e032 120 e07a 123
Special keyboard actions
Once I have assigned keycodes, I can map the keys to some of the special keyboard functions, or arbitrary characters or strings.loadkeys - << EOF Alt ShiftL keycode 15 = Incr_Console Control Alt Shift keycode 15 = Decr_Console keycode 124 = Spawn_Console keycode 120 = Show_Memory keycode 121 = Show_State keycode 89 = F100 # Mute string F100 = " Mute " keycode 90 = Scroll_Forward # VolDown keycode 91 = Scroll_Backward # VolUp keycode 92 = Decr_Console # CdPrev keycode 93 = F104 # CdPlay string F104 = " CdPlay " keycode 94 = F105 # CdStop string F105 = " CdStop " keycode 90 = Scroll_Forward # VolDown keycode 91 = Scroll_Backward # VolUp keycode 92 = Decr_Console # CdPrev keycode 95 = Incr_Console # CdNext EOFIn this example, I have mapped some keys to special functions, and some to strings. For a full description of the syntax, see the man page
keytables(5)
. There is no convinient summary of what special keyboard functions are available. You need to look at: - the table
spec_fn_table[]
in the source file
/usr/src/linux/drivers/char/keyboard.c
- The output from
dumpkeys
- The result of:
strings `which loadkeys`
Bare_Num_Lock
- Like Num Lock, but...
Boot
- ie the "three-fingered-salute"
Break
- Send "break" to tty
Caps_Lock
- Toggle Caps_Lock (ie the usual one)
Caps_On
- Turn ON Caps_Lock, (not a toggle)
CapsShift
- Same as
Shift
, but also releasesCaps_Lock
Compose
- for unusual characters
Console_
n
- Go straight to virtual console n This is the default mapping for
<ALT><F1> <ALT><F2>
etc Decr_Console
- Go to the previous virtual console, ie n
-1
Incr_Console
- Go to the next virtual console, ie n
+1
KeyboardSignal
- Runs the command specified by the
kb:
line in/etc/inittab
Last_Console
- Previous console used
Num_Lock
- The keypad Num Lock
SAK
- The "Secure Attention Key". See
/usr/src/linux/drivers/char/tty_io.c
"Kills all processes associated with this tty". Can be used as a "Panic Button" if you think you've run a trojan-horse. By pressing this key before logging on, you can be resonably sure that the login banner is not just a user-program masquerading as a login, for the purpose of capturing passwords. Scroll_Backward
- Scroll up within a virtual console (same as
<SHIFT><PageUp>
) Scroll_Forward
- Scroll down within a virtual console (same as
<SHIFT><PageDown>
) Scroll_Lock
- Normal mapping for
Scroll Lock
key Suspends tty output and input (buffering still takes place). Shift_Lock
- Similar to
Caps_Lock
, but more like theShift_Lock
on a mechanical typewriter. It also shifts the numeric keys (where asCaps_Lock
doesn't). To work properly,Shift_Lock
should be assigned to a shifted key. It is activated by pressing<Shift><Shift_Lock>
and is released by pressing<Shift_Lock>
Show_Memory
- Prints some memory stats
Show_Registers
- Prints some CPU registers
Show_State
- Prints some ps-like information
Spawn_Console
- Same as
KeyboardSignal
VoidSymbol
- Does nothing. Useful for un-assigning a key.
mappings. It just covers some of the more exotic ones.
I had some trouble making sense of
Shift_Lock
. There's probably more to it than the above brief note. I noticed
that
Shift_Lock
and Caps_Lock
do notco-operate: their results are additive.
Shift_Lock
does notaffect the Caps_Lock LED.
Control of Keyboard leds
Virtual consoles under Linux have one more feature which youshould be aware of:
- the ability to place the keyboard leds under
software or kernel control.
By use of the
ioctl()
calls KDGETLED/KDSETLED
it is possible to arbitrarily control the keyboard leds
from within an application
Alternately, by use of the internal kernel function
register_leds()
it is possible to use the keyboard ledsto monitor an arbitrary location in memory.
Unfortunately, direct manipulation of the keyboard
leds by either of these methods defeats the normal operation
of the leds in all of the virtual consoles.
Nevertheless, the benefits of this control may be worth
the cost, especially if you rarely use CAPS_LOCK (like
myself).
One example of such a program is the tleds program,
which uses the keyboard leds to monitor network activity.
The program comes in two flavors: tleds for running under the
virtual consoles, and xtleds for running under X11 (additionally).
The tleds program is available from:
http://www.iki.fi/Jouni.Lohikoski/tleds.html
This document may be freely distributed.
The information contained in this document was correct
at the time of writing, but may be out-of-date by the time you
are reading it.
Author: George_Hansper@apana.org.au
Last modified: 8th July 1998
No comments:
Post a Comment