I want to speed up creation of user accounts on some Linux VMs that I am creating, and wondered if I could simplify the process of writing to the new user's ~/.ssh/authorized_keys or ~/.ssh/authorized_keys2 file.

My manual process is, approximately (logged in as the new user):

ssh-keygen -t rsa -N "" -f ~/.ssh/id_rsa
touch ~/.ssh/authorized_keys
chmod go-rwx ~/.ssh/authorized_keys
echo '... me@machine' >> ~/.ssh/authorized_keys

Is there any way, with a Bash command, a standard GNU command, or any program easily installed on Ubuntu, to condense the touch, chmod, and echo into one command?

Part of the reason I would like to reduce it to one command is so that I can make a shell script that I can run as the initial sudo-capable user on the VM.

Something like:

sudo su - me -c 'ssh-keygen -t rsa -N "" -f ~/.ssh/id_rsa'
echo '... me@machine' | sudo su - me -c 'xyz 0600 ~/.ssh/authorized_keys'

Where xyz is the hypothetical command that creates, sets permissions, and writes the file all in one fell swoop.

  • Looks like maybe unix.stackexchange.com/questions/47178/… can help me. – amacleod Jan 20 '15 at 15:31
  • 1
    You can do echo '...' >> somefile without touch directly. To avoid using chmod set apropriate right for directory via umask or setfacl – Costas Jan 20 '15 at 15:37
  • @Costas, you are right, I can write the file first and then change its permissions. I will probably do that. Changing the directory permission would not reduce the number of commands, but only change the order. – amacleod Jan 20 '15 at 15:47
  • You change acl only one time but script can be invoked many times. – Costas Jan 20 '15 at 15:58
  • Ok. I am less familiar with umask. It is a built-in Bash command, right? Is setfacl from a different shell? If I want to only set umask for specific files, I think I should do it as Stéphane described, in a compound command, yes? – amacleod Jan 20 '15 at 16:47

Note that

touch ~/.ssh/authorized_keys
chmod go-rwx ~/.ssh/authorized_keys
echo '... me@machine' >> ~/.ssh/authorized_keys

offers no benefit over:

echo '... me@machine' >> ~/.ssh/authorized_keys
chmod go-rwx ~/.ssh/authorized_keys

Permissions are checked upon opening a file, not upon reading or writing to it.

So it doesn't matter whether you do the chmod before or after adding the content. Someone could still open the file before you do the chmod but wait for you to add content before reading it.

Here you want to make sure the file has the right permissions from the start:

sudo -u user sh -c '
  umask 077 && printf "%s\n" "$1" >> ~/.ssh/authorized_keys
' sh "$key user@host"
  • Good point about the permission checking. I had not thought of that. – amacleod Jan 20 '15 at 16:28
  • I'm not sure I follow the syntax of the third line of your last example. Why is sh in the command twice? – amacleod Jan 20 '15 at 16:52
  • 1
    The second sh is to give a name ($0) to that inline script. See here for details – Stéphane Chazelas Jan 20 '15 at 16:58
  • Slight problem: unlike sudo su - user, sudo -u user doesn't create a new login shell, so it interprets tilde as the first user's home directory. I found that if I use sudo su - then I have to omit the second sh in the command. – amacleod Jan 20 '15 at 20:48
  • 1
    @amacleod, then add -H. – Stéphane Chazelas Jan 20 '15 at 21:30

You might look into ssh-copy-id

Reference: 3 Steps to Perform SSH Login Without Password Using ssh-keygen & ssh-copy-id

  • 1
    These links might be very helpful, but it is also strongly encouraged for answerers to in-line the most helpful bits of information from a given source link. – HalosGhost Jan 20 '15 at 20:36

For your specific example this is the best I could do.

ssh-keygen -t rsa -N "" -f ~/.ssh/id_rsa -y > ~/.ssh/authorized_keys && chmod 0600 ~/.ssh/authorized_keys

An important option was the -y flag for ssh-keygen which allows the public key to be printed to stdout which avoids two steps of creating and reading a file.

To create, set permissions, and write from an existing file you can use the install command

install -m 0600 ~/.ssh/id_rsa ~/.ssh/authorized_keys

The downside to the install command is that it does not work with redirection from stdout, meaning you have to copy the contents of an entire file.

  • That would suffer from the same gap between file creation and permission change as my original, right? I ended up using umask as Stéphane suggested. – amacleod Dec 9 '16 at 20:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.