How to avoid Funky Town – pet peeves on ‘sudo echo’ and pipelines #rsts11

I was reading about a Raspberry Pi supercomputer design at University of Southampton. Pretty cool stuff, but something bugged me about one of the later sections. it’s something that bites me sometimes when I’m trying to be good and use ‘sudo’ instead of ‘su’ or logging in as root.

For those of you who may not remember, ‘sudo‘ is a command that gives you some or all of the privileges of another user (often root, but not limited to that user). A sysadmin can define certain commands, options, and users that each user can “take over,” as it were. But I would guess most readers of this blog generally use ‘sudo’ to execute a command as root, or worse, to become root with ‘sudo su –

So what’s your bucket, Robert?

But anyway, Southampton’s document specifies the following command invocations to edit a system config file.

Hostname Script

If you want to rename each machine, you can do it from the Master node using:

ssh pi@ ‘sudo echo “iridispi002” | sudo tee /etc/hostname’

ssh pi@ ‘sudo echo “iridispi003” | sudo tee /etc/hostname’

ssh pi@ ‘sudo echo “iridispi004” | sudo tee /etc/hostname’

There’s a very good reason for part of that — the ‘pi’ user cannot edit files in /etc. So what you might do as root:

ssh root@ echo  iridispi002 > /etc/hostname

would fail if run as a non root account.

The eagle-eyed among you will want to write in and mention that the command above would replace /etc/hostname on the local system *after* sshing to, and you’d be right, assuming you run it as root on the local system. The way around that would be

ssh root@ 'echo iridispi002 > /etc/hostname'

But as a non-root user, you have to escalate your privilege to change most system config files. The suggested command:

ssh pi@ 'sudo echo "iridispi002" | sudo tee /etc/hostname'

is excessive for one reason.

echo‘ is not a privileged command. There is no reason to ‘sudo echo‘ — at least not that I can think of. It will not take you to Funkytown (even if you are more of a Lipps, Inc fan)

This won’t break anything, but it does execute another potentially auditable command, write another line to the sudo log file, and get you into a suboptimal habit. 


ssh pi@ 'echo iridispi002 | sudo tee /etc/hostname'

would do just what we want.

Tell me about this “tee” command

tee,’ by the way, is a command that takes standard input (STDIN), writes it both to standard output (STDOUT) *and* the filename specified as a parameter. Note that tee will create a file if it doesn’t already exist, and overwrite it if it does. If you want to append to an existing file, use something like ‘tee -a <filename>‘ … for example, this will propagate your hosts file with hostnames for a popular RFC1918 subnet:

for h in $(seq 1 255);
      echo 192.168.1.$h host$h.mydomain host$h |\
      tee -a /etc/hosts

There are other ways to execute non-privileged commands and use the output to affect priviliged files. One way is to use ‘dd‘ to pass data through. For example, creating a bootable USB drive in Linux from a boot image could be done with:

dd if=ubuntugolden.img | sudo dd of=/dev/sdf1

But note that dd doesn’t protect you from yourself, so check that command before you wreck it.

So where do we go from here?

If you’re going to keep to minimal privilege escalation, which is the Right Thing(tm) to do, even if it’s inconvenient… think about what you’re using sudo for, and keep it between the navigational beacons.

And by the way, am I the only one who thinks of Robotech when I use the sixth scsi device? Probably not the best way to party like it’s 1999.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s