Recently, I posted about two screen lockers that I’ve used in the past (xtrlock
and slock
). There has been some great discussion about these lockers, and some potential security problems that come along with using them. One very prominent issue regarding using screen lockers without login managers was raised by a reader, and I want to address it in this separate post.
Just as some background information, many people prefer to use login managers (also known as display managers) in order to be greeted by a graphical login prompt. To use these managers, the X Window System must be started as one of the final steps of the boot process (either by setting the default runlevel to 5 in inittab
, setting the display manager to start via the rc system / a daemon, or another method). Some people don’t like the idea of a login manager starting automatically at the end of the boot process, and would prefer to simply be greeted with a terminal login prompt. For those users, it is obviously still necessary to log in as a valid user, but then to start an X session (for their respective graphic environment), one must issue the startx
command.
The problem with screen lockers and the startx
method of starting Xorg is that it presents a large security flaw. I mentioned in the previous post that one can switch to a different virtual terminal (by using the CTRL+ALT+F#
key combination) and log in as a different user. Unless that user can become root and kill the screen locker, though, there’s no problem. However, when Xorg is started using startx
, a person can switch to the virtual terminal that issued the startx
command, and just hit CTRL+C
to kill it. They will then be at the prompt for the user that issued the command, and won’t have to log in. Oops…
A good workaround for this problem is to start Xorg and make sure that the terminal is locked if X is killed. This workaround relies on the package vlock
, which is a terminal locking application. For it to work properly, instead of issuing the standard startx
command, one needs to issue startx ; vlock
. That way, if a person switches to the virtual terminal that started the X session, and hits CTRL+C
, it will kill X, but that will automatically start vlock
, and subsequently, present the person with nothing more than a login prompt. What’s more, that person will have to enter the password for the user that started the X session.
There might be more elegant methods for fixing this problem, including a script to disable virtual terminal switching when the screen locker is called, and I’ve been looking into such methods. If anyone has further suggestions regarding workarounds, or more permanent solutions, please feel free to comment.
Cheers,
Zach
50 comments
2 pings
Skip to comment form
I believe
exec startx
is definitely the simplest solution. I wouldn’t even call it a workaround as it provides the exact functionality you were looking for.
You can’t switch to your login TTY, kill X and thus circumvent the screen locker. At the same time it still allows you to switch to another TTY to login as a different user; very convenient if you have several people using the same pc… Why would you disable TTY switching? If one user locks his session, no one else can access the terminal. I don’t see a situation where this is desired. Unless you need an extremely secure box, but then you would have to do a lot more to secure it, including denying physical access to the power button etc…
I simply don’t see any downside to this solution. All the other solutions seem overly complicated and incomplete and don’t offer any advantage over “exec startx”.
Please, correct me if I’m wrong…
Author
I agree with you completely. ‘exec startx’ is definitely the solution that works best for me.
Cheers,
Zach
I agree with you, when someone change the tty to 1 and press CTRL+C the user would logout an he is loosing the login.
But i don’t really unterstand, when your Linux Distribution is not secure everyone could add following to your grub line:
rw init=/bin/bash
After that i can change the user password and have access to the computer.
I have encrypted my whole HDD, if someone use /bin/bash, he couldn’t encrypt the hdd, because he doesn’t have the password.
Also you could set you bios HD Password or something like that, to be more secure 😉
I hate login screens but see the need for them. I found that i could use xlsh as alternative for this. This way you could have a (optional) background with an xterm window and a very simpel login shell.
I also use this on my TTY’s because it looks cool 😛
Link to XLSH: https://github.com/Nadrin/xlsh
I don’t think that the screen locker should forbid function keys…
(think user switching… I know the locker could provide buttons / its own functionality for that, but I don’t like that much, when I just want to switch to a text console.. 😉
VT (console) switching is an integral part of linux, which for security assumes that each console is secured separately…
If you (from one console/VT) open up another and wish to keep up the former (security wise) open, you have to somehow lock them both (or of course, close the first one…)
BTW any X program disabling Ctrl-Alt-Fn through X wouldn’t work anyway… you can just unraw the keyboard (google for magic sysrq key) which will ‘take X’s ownership’ of the keyboard and then you could just use kernel’s plain Alt-Fn to switch to whatever console you can (as I said linux expects that you are allowed to switch consoles…)
Author
All completely valid points; thanks for sharing them!
Cheers,
Zach
Nice post, I’ve had this issue for month now. But locking or logging out right after startx wouldn’t do it for me, as I like to open a root session in tty2 :/ . How comes nobody made a screen locker that would lock the CTRL-ALT-Fn already? That would be the best solution. Having the keyboard completely locked while the screen is locked is definitely more secure.
Author
Hi Raphil,
I agree that having the screen locker itself forbid the function keys would likely be the most elegant solution. However, until that time, I’ve been using the workaround of:
exec startx
and that works for my needs.
Cheers,
Zach
How about this (works for zsh because of ‘disown’, won’t work for pure POSIX shell):
> startx &>xorg.log &; disown %1; exit
Of course, you should not have any other bg jobs (firstly, they will be killed; secondly, %1 must be changed accordingly).
This seems to do the trick:
stty -isig
startx
logout
The best thing since sliced bread for login manager haters (like me) is sys-apps/qingy. It replaces regular getty and is capable of starting Xorg session in the same VT where you’ve logged in.
Author
Thanks for the suggestion! I’ll have to look further into qingy as an option.
Cheers,
Zach
How about just disabling contr + alt +fn# keys?
in xorg.conf in serverflags section add Option DontVTSwitch and DontZap
http://www.x.org/archive/X11R6.8.1/doc/xorg.conf.5.html#sect4
Author
Hello Jo,
Yes, disabling those key combinations is certainly an option. I don’t like the idea of losing that functionality, but it would certainly resolve the security issue. I’m collecting all of the ideas presented in these comments, and will do another post with the pros and cons of each. Thank you again for your contribution.
Cheers,
Zach
No it won’t. For example, if X server would die of a segv one can get full access to the VT.
I just have alias startx=”exec startx”.
Author
Hello Laurent,
Thanks for the suggestion. I’ve been doing some testing with the
exec startx
, and so far it is the solution that works the best for me. I’m going to post something within the next few days with all of the options presented here in the comments, and let everyone decide which ones work for them.Cheers,
Zach
There is still a problem with startx; vlock.
1. Ctrl-Alt-F1
2. ^Z
3.
4. fg
I’d say log into the terminal, start a screen session (this is almost always useful anyway), startx. Then you can Ctrl-Alt-F1 and give a ^A-x to lock the screen. You could even give a ^A-d to detach from the first VT and log out of the terminal completely.
Author
Hello Adam,
Indeed, starting a screen session would be one way around the problem. I’m going to post all of the options sometime soon, and let everyone decide which ones work for them. I personally have been using
exec startx
for a bit, and it seems to work. I have some more testing to do, but I really appreciate your suggestion!Cheers,
Zach
Did i miss something? Wouldn’t `startx; logout` be as good? Also while not much likely, I would not be very surprised if multiple rapid ^C killed them before they did their job – bash is slow. Lastly, this is why startx lusers are all ricers.
Author
startx ; logout
would work in the same way asstartx ; vlock
, but unfortunately, neither of them work as intended. One can quickly pressCTRL+C
and considering BASH is a bit slow, it will nullify the latter command. I disagree with your assessment about people that usestartx
instead of a login manager. Many of us don’t necessarily use a graphic environment every time that we access our machines, and it seems silly to start a window manager just to start a terminal emulator. Also, booting into runlevel 5 by default can lead to problems if a problem occurs with X. In any case, the freedom of choice is one of the most appealing aspects of Linux.Cheers,
Zach
Why not just start X with ‘exec startx’ ? It will replace the running shell and when it finishes (ctrl-c, normally or with an error 😉 it will just exit and go back to the login prompt…
Author
Hello YoYo,
Thanks for the recommendation. I have tested this method in a few different ways, and it seems to work nicely. I’m going to make another post in the near future about the various workarounds presented here in the comments. At first I thought that it caused a zombie bash process, but I haven’t been able to replicate that problem since the first time that I tried it.
Cheers,
Zach
There wouldn’t be a zombie process because exec results in the running shell to be replaced with the startx process (literally – the PID of startx will be the same as that of the shell you started it from).
Author
Indeed, sir. I thought that it was, but it turned out to be completely unrelated. It was actually a problem with one of my crons.
Cheers,
Zach
How about the simple “startx & exit”.
This runs startx in the background and immediately logs out of the virtual terminal.
Author
Hello Leon,
I played around with this method, and it addresses the security problem but has a couple negative side effects. For instance, the instance of X (and associated applications [the WM, session, et cetera]) remain. I then had to kill those processes before logging in again. It also seemed to slow the subsequent X restart. Thank you for the suggestion though!
Cheers,
Zach
> startx ; vlock
Forget it – pressing Ctrl-C fast enough 2x in a row and the 2nd command won’t be executed 🙂
Author
Hello Toralf,
You are absolutely correct. I will soon be posting several of the workarounds listed in the comments section, and the pros / cons of each method. Thanks for your input.
Cheers,
Zach
I use:
exec startx …..
🙂
Author
Hello Enlik,
I’ve been testing this workaround today, and I believe it works for my needs. In the next few days I’m going to post a list of the workarounds presented in the comments, and the benefits / drawbacks of each method. Thank you for your suggestion!
Cheers,
Zach
If you run `startx` from within `screen`, you can change back to the virtual terminal yourself, detach from the screen, and exit the virtual terminal. I call this “treehouse X” (http://blog.tremily.us/posts/Screen/).
Author
Hello Trevor,
That is certainly one way to get around the security problem. Thank you for the recommendation!
Cheers,
Zach
Are you really sure that works properly? And if it does, whether it works all the time? If I run
sleep 10 ; vlock
in an xterm and then press Ctrl+C before the 10 seconds are up, the xterm session will not be locked. (If I just send it to background with Ctrl+Z, it will be however.)
Since I don’t use startx, I haven’t actually tested anything, but wouldn’t the following be more sensible?
startx & vlock
That would lock the current console immediately after startx is called. Then the VT from which startx is called is already locked, so nobody could do some tricks to try to prevent it from being launched. Since startx doesn’t expect any user input, it should be happy in the background unless your terminal is configured to stop background processes that output stuff to the terminal (by default background processes are only stopped when they try to read).
DISCLAIMER: Please do NOT take this as security-related advice on how to do this properly, as it is just an untested idea I’m throwing out there. I urge everybody to determine for themselves whether this (a) actually works and (b) is actually secure against threats.
Author
Hello Christian,
You’re correct in the your assessment that this method is easily circumvented. There are some negative side effects of issuing
startx
in the background like you mentioned. I’m going to mention the various workarounds in a blog post a couple days from now, and will go into more detail about each method. Thanks for the thorough suggestion!Cheers,
Zach
how about startx & ; logout
or openvt startx ; logout
instead of the vlock method… this has the advantage of closing the terminal as soon as the startx command is issued so it should solve other potential risks
Author
Hello Kitanatahu,
Yes, thank you for the suggestion. Your first method doesn’t require a terminal locker, and is, therefore, more universal.
Cheers,
Zach
I start X from a terminal with the following command:
(startx &); sleep 30; exit
It’s important to use () around startx so it’s started as a subshell.
Author
Hello Johan,
Thank you very much for the suggestion. I’m going to run some tests of starting X in a subshell, and will post my findings.
Cheers,
Zach
To avoid this, I use
# startx; exit
Author
Hello Andre,
Thanks for letting me know of your workaround. Unfortunately, both your way and the
vlock
way are easily circumvented by pressing CTRL+C quickly enough that BASH will not execute the latter command.Cheers,
Zach
An alternative command to use would be just:
$ startx ; exit
or ‘logout’ whatever you prefer. This does not require any additional packages and the option that vlock requires the password of the current user only works when there is just one virtual terminal, or when vlock actually also blocks the others.
Author
Hello Pim,
Thank you for the suggestion. Unfortunately both methods are easily circumvented by pressing
CTRL+C
quickly enough that BASH will not execute the latter command.Cheers,
Zach
I think you didn’t understand.
If person runs it from command line himself it’s impossible to push him away from the keyboard and press ctrl-c 😉
Here, I use a wrapper script that sets up some environment and does a bit of utility work before calling startx… in the background. I then disown all background jobs so when the wrapper script terminates it won’t terminate X as well, and then exit.
With this arrangement, I can simply source my startx wrapper script in my current login environment, so when it finishes with the backgrounded startx and the disown, it exits the VT login session as well. Thus, switching to that VT won’t help anyone trying to avoid a login, as all they’ll get is the usual getty login prompt. =:^)
FWIW my X DE of choice is kde, so that’s the session I call in my script, but that’s of course easily changed. Here’s the gist of it. I set a few kde specific vars, etc as well, but including that here would just confuse things, so I won’t: (Hope the line wraps stay correct.)
— cut here —
#!/bin/bash
# make sure I start in ~
cd
# sync, in case X crashes the system instead of starting
sync
# set the desired DE/xsession
export XSESSION=KDE-4
# backgrounde startx so the script continues to run
startx &
# disown background jobs so they won’t be killed
# when the script terminates
disown -a
# exit successfully
exit 0
— cut here —
Now, with that script placed in /usr/local/bin/k (which of course allows a similar /usr/bin/g script that sets a gnome xsession, etc) , I can simply do this:
. k
That executes the script in the current login session, so will exit after starting X, leaving that VT right back at the getting login prompt. =:^)
It’s worth noting that while I don’t seem to have the problem now, in the past, sometimes I’d have to add a “sleep 5” or some such, to sleep a few seconds after calling startx. Otherwise there was some sort of timing issue and the disown wouldn’t be fully processed before the script terminated, so X would still be a child of the invoking script and would be terminated with the script. But adding a few seconds of sleep allowed the disown to complete, and after that, the exiting script wouldn’t terminate X/kde.
It’s also worth noting that not keeping the CLI login used to cause pam-console permission issues and the like, so I could no longer control alsa from X, since it wasn’t considered a console login and pam-console would therefore reset device permissions to disallow that user access. The workaround for that was to ensure that the pam-console config didn’t mess with the permissions for the affected devices, so they stayed available to users in the audio group or whatever. However, I believe pam-console has been dead for quite some time, and at least here, simply ensuring that the user is in the audio group, etc, seems to be enough, these days.
But if either of these issues do appear, that should give people at least a hint of what’s going on and how to fix or work around it.
Oh, people who know bash should know this already, but in case it’s not obvious, in the…
. k
… there’s a SPACE between the dot and the command name (k).
Author
Duncan,
Thank you very much for your detailed workaround! I will be reviewing all of the methods listed in the comments here, and will post my findings.
Cheers,
Zach
My solution to this particular problem is starting startx in the background and logging out immediately after that. I have the following code in my .bash_profile:
if [ `tty` = “/dev/tty1” ]; then
echo “”
echo “Starting X in 3 seconds (type Ctrl-C to interrupt)”
sleep 3
startx &> ~/.Xstdouterr &
logout
fi
Author
Hello Stefan,
Thanks for mentioning your script. I’m going to do some tests against it, and will let you know what I find. I really appreciate you taking the time to let us know of your workaround!
Cheers,
Zach
This is the issue I was talking about in my comment, and I solved it using tmux. Also works with GNU screen. I simply enter tmux, call startx, then CTRL-ALT-F1, CTRL-A D to detach the terminal (which brings me back to the prompt, X is still running), CTRL-D to logout and ALT-F5 to switch back to X. From there I open xterm and type tmux attach, so I still have the console output from inside X. I know, not exactly practical but since I leave my pc on 24/7 I don’t have to do this every day. 🙂
I haven’t tried switching back, then CTRL-Z, then calling “bg” to leave X running in the background and CTRL-D to log out, this should work and it’s simpler, but you lose the console output.
[…] reviewing several solutions to a security problem regarding screen lockers, I’ve found that the easiest workaround for switching virtual terminals and killing the […]
[…] Be sure to view the update to this post for more information about a security problem with startx and screen lockers. This entry was […]