Diary and notebook of whatever tech problems are irritating me at the moment.


A slightly less open Ubuntu recovery mode

Ubuntu recovery mode is a basic boot configuration for repairing a broken system. In this mode it skips most configuration files and daemons in order to achieve a functioning root prompt. For the security-conscious administrator this itself is a problem.

There have been complaints about unchallenged root access in recovery mode. Ubuntu uses sudo for root access and the root account is disabled via a "*" password. If you forget the passwords of the admins (any user account in the admin group) then this makes it possible to easily reset it.

Originally, recovery mode went straight to a root prompt which wasn't useful to non-technical types. With the addition of Friendly Recovery, a menu is displayed with a list of repair options. The menu is just a Whiptail selection dialog driven by the "/usr/share/recovery-mode/recovery-menu" script which queries other scripts in the "./options" subdirectory. The sub-scripts provide simple repair options like failsafeX, apt-get clean, and update-grub. These are useful to non-technical types for attempting simple repairs to problems. They won't fix complicated problems like gdm crash loops but may save the administrator an on-site visit or two. The root and netroot scripts provide root shell access which is where security becomes a concern, not just because of black hats, but also fools blindly using repair commands like ":(){ :|:& };:" and "rm -rf /".

There are several options for limiting root access.

1. Set a grub password that prevents running recovery mode or editing menu entries. This means the administrator has to make any repairs. If the network is failing then that means on-site.

2. Set a root password with "sudo passwd". The password will then be required to access the shell from the Friendly Recovery screen but this also allows direct root logins during normal operation (although you might not care about that).

3. Disable the shell options in Friendly Recovery. These commands remove the options from the menu and prevents them from reappearing if the friendly-recovery package is updated. This allows users to run the automated commands but makes it more difficult for the administrator to get root access in recovery mode. You'll need to use sudo before these or start a root shell with "sudo su" first.

mkdir /usr/share/recovery-mode/disabled
dpkg-divert --divert /usr/share/recovery-mode/disabled/root \
--rename /usr/share/recovery-mode/options/root
dpkg-divert --divert /usr/share/recovery-mode/disabled/netroot \
--rename /usr/share/recovery-mode/options/netroot

4. Set a root password only in recovery mode. To do this I wrote rootlock.conf. This is a job configuration for Upstart that is added to the "/etc/init" directory (with root:root ownership and -rw-r--r-- permissions). It is triggered by runlevel changes. Within is a script that when the runlevel is "S" (single) mode, which indicates recovery mode, it copies the password from the first admin group member to the root account in /etc/shadow. In runlevels 2-5, it changes the root password back to "*". This allows root logins from the Friendly Recovery menu if the password of the first admin is entered. In normal operations direct root login is disabled. This makes a lost admin password more difficult to fix but for a capable administrator that is only a minor annoyance.

Don't use it if you have set a root password previously because you want a normal root login available. It will be disabled by this job.

I've tested this on Ubuntu 10.04 (Lucid Lynx) extensively and it seems robust but I'm awaiting feedback on the ubuntu-devel mailing list. Check back for updates.

Disabling unchallenged root logins in recovery mode will not keep a knowledgeable hacker out. This is only possible if you use full-disk encryption like LUKS/dm-crypt for which only the administrator has the key. This will prevent the user from booting with a LiveCD and editing shadow directly but will require the administrator to start the system every time it is powered on or rebooted.


quote-count: A debugging tool for shell scripts

I've been doing a lot of shell scripting lately with Dash and Bash. Complicated scripts with lots of text handling make debugging difficult, especially when they are being used in sub-shells which obfuscate line numbers in error messages. One of my more common mistakes is an unmatched quote. These can be rather difficult to find so I wrote quote-count, a simple analysis tool that counts quotes in lines.

It just accepts a single filename as a parameter and counts single, double, and back quotes on each line and prints their totals. It prints out a warning if the any of the counts is odd-numbered which may indicate a mismatched quote. It also warns if the line is a comment so you easily ignore those. It isn't brilliant as it doesn't handle escaped newlines, in-line comments, escaped quotes or quotes encapsulated within other quotes. It could be enhanced to handle these cases but it's already saved me a lot of debugging time as is. The output from running it on itself looks like this:

1 Q:0 DQ:0 BQ:0 # COMMENT
2 Q:0 DQ:0 BQ:0 # COMMENT
3 Q:0 DQ:0 BQ:0 # COMMENT
4 Q:0 DQ:0 BQ:0 # COMMENT
5 Q:0 DQ:0 BQ:0 # COMMENT
6 Q:0 DQ:0 BQ:0 # COMMENT
7 Q:0 DQ:0 BQ:0 # COMMENT
8 Q:0 DQ:0 BQ:0
9 Q:0 DQ:8 BQ:0
10 Q:0 DQ:2 BQ:0
11 Q:0 DQ:2 BQ:0
12 Q:0 DQ:2 BQ:0
13 Q:0 DQ:2 BQ:0
14 Q:0 DQ:2 BQ:0
15 Q:0 DQ:0 BQ:0
16 Q:0 DQ:0 BQ:0
17 Q:0 DQ:0 BQ:0
18 Q:0 DQ:0 BQ:0
19 Q:0 DQ:0 BQ:0
20 Q:0 DQ:0 BQ:0
21 Q:0 DQ:2 BQ:0
22 Q:4 DQ:5 BQ:1 # ODD
23 Q:0 DQ:2 BQ:0
24 Q:5 DQ:4 BQ:1 # ODD
25 Q:0 DQ:2 BQ:0
26 Q:5 DQ:3 BQ:2 # ODD
27 Q:0 DQ:2 BQ:0
28 Q:0 DQ:4 BQ:0
29 Q:0 DQ:2 BQ:0
30 Q:0 DQ:2 BQ:0
31 Q:0 DQ:0 BQ:0
32 Q:0 DQ:0 BQ:0
33 Q:0 DQ:0 BQ:0

I've tested it with both Dash and Bash on Ubuntu 9.10 and Mandriva 2010.1 so it should work with most systems.

Another typo I occasionally encounter is escaped whitespace at the end of a line. The intent always is to escape a newline but sometimes in my editing I end up with a space or tab after the backslash. These can easily be found with grep:

grep -E -r -n '\\[[:space:]]+$'<filename>

I wanted to add this check to quote-count v1.0 but found that the "while read" loop removes everything after the trailing backslash. Richard Bos sent me a modified version that included the check as a pre-processor utilizing a simple grep trick. I added it in although it used an array which Dash doesn't support.

UPDATE: v1.2 released and link updated. I found some bugs in v1.1 with the TEW check. I also cleaned up the report output a bit.

Reading through the quote-count report for my larger scripts was tedious so I wrote quote-count-query which compares the original source file with the quote-count report and shows the affected lines with two preceding and following lines for context.

About Me

Omnifarious Implementer = I do just about everything. With my usual occupations this means anything an electrical engineer does not feel like doing including PCB design, electronic troubleshooting and repair, part sourcing, inventory control, enclosure machining, label design, PC support, network administration, plant maintenance, janitorial, etc. Non-occupational includes residential plumbing, heating, electrical, farming, automotive and small engine repair. There is plenty more but you get the idea.