0

I'm writing a script that should create a public RSA key and push it to the authorized_keys.

Here is the function that I use in Python:

def push_key():
    auth_keys_contents = None
    with open('/tmp/{}/public.pub'.format(args.username), 'r') as f:
        auth_keys_contents = f.read()
    print(auth_keys_contents) #just for testing
    os.system('ssh -l root server2 -i ~/.ssh/id_rsa "bash -s" < /home/scripts/script.sh {} {}'.format(args.username, auth_keys_contents))

The bash script that you see me running with the ssh line is simple. Here's a short version of it:

ssh_dir="/home/${1}/.ssh"
auth_keys_file="/home/${1}/.ssh/authorized_keys"
su $1 -c 'bash -s' <<EOL
...
...
...
echo "$2" > $auth_keys_file
EOL

For some reason, when it gets to this line: echo "$2" > $auth_keys_file the output is not as I expect it to be:

user@server2 ~/.ssh [54]> cat authorized_keys
ssh-rsa
user@server2 ~/.ssh [55]>

I don't understand why it's only getting the ssh-rsa instead of the full public key. I tried different switches for echo, I tried printf but the result is the same.


Seems like @Thomas solved it. Another approach that solved it was replacing this:

os.system(' ssh -l root server2 -i ~/.ssh/sid_rsa "bash -s" < /home/scripts/script.sh {} {}'.format(args.username, auth_keys_contents))

With this:

ssh_cmd = "bash -s {} {}".format(shlex.quote(args.username), shlex.quote(auth_key_contents)) os.system('ssh -l root server2 -i ~/.ssh/sid_rsa {} < /home/scripts/script.sh'.format(shlex.quote(ssh_cmd)))

Issue was that I have 2 nested shells and that I needed to quote twice as well.

3
  • 1
    /home/scripts/script.sh {} {} You need double quotes around the second {}. Commented Jun 10, 2021 at 13:36
  • @JohnGordon thanks for the reply. I tried adding double quotes but got the same result: os.system('ssh -l root server2 -i ~/.ssh/id_rsa "bash -s" < /home/scripts/script.sh {} "{}"'.format(args.username, auth_keys_contents)) Commented Jun 10, 2021 at 13:43
  • Try double backslashs before these double quote characters. Commented Jun 10, 2021 at 14:01

1 Answer 1

2

The problem is that there is a space character after ssh-rsa in a public key, so when you pass it unquoted to a shell script, it will split the different space-separated parts into separate parameters.

Try replacing your current line

echo "$2" > $auth_keys_file

with

echo "${@:2}" > $auth_keys_file

This is not ideal because multiple consecutive whitespace characters will get collapsed into a single space, but I believe that is no problem in your specific case.

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you, that worked! One some issue though, when the file is written, it's also passing the first argument . so here: < /home/scripts/script.sh {} {}'.format(args.username, auth_keys_contents)). This causes my file to be written with user ssh-rsa...... Is there a way around it?
Yes, the shift line is also included.
Indeed, that solved the issue. I've also solved it by using a different approach in the Python script. I'll edit my post with it just for future knowledge but definitely your solution is simpler and working!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.