Skip to content

Instantly share code, notes, and snippets.

@grugnog
Last active May 27, 2021 10:03
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save grugnog/0e0a6eb2a887fd226339b463e58332f6 to your computer and use it in GitHub Desktop.
Save grugnog/0e0a6eb2a887fd226339b463e58332f6 to your computer and use it in GitHub Desktop.
Simple expect script to get an interactive root shell using a password from the Lastpass "lpass" tool. Assumes a ssh public key authentication. This allows usage of long, secure passwords to sudo whilst avoiding copy-paste (risky) and passing credentials as command line options (insecure).
#!/usr/bin/expect
set timeout 600
set lpass [lindex $argv 0]
set arguments [lrange $argv 1 end]
if {$lpass eq "" || $arguments eq ""} {
puts "sussh: Login to interactive root shell using sudo password from lpass."
puts "The credential is sent via expect, not via any command line option.\n"
puts "Usage: sussh <lpass-key> <ssh-args ...>"
puts " lpass-key: Suffix of a lpass record with the prefix 'ssh-'"
puts " ssh-args: username, hostname, port, alias or other ssh options\n"
puts "Example: 'sussh client me@client.com'"
puts "ssh to me@client.com and use the 'ssh-client' lpass record to sudo."
exit
}
set credential_old [exec lpass show --password ssh-$lpass-old]
set credential [exec lpass show --password ssh-$lpass]
spawn ssh {*}$arguments
expect {
"Are you sure you want to continue connecting (yes/no)?" {
send_user "Check signature and confirm manually then retry.\n"
exit
}
"You must change your password now and login again" {
expect "(current) UNIX password:"
send "$credential_old\n"
expect "New password:"
send "$credential\n"
expect "Retype new password:"
send "$credential\n"
expect "closed."
send_user "Password changed - rerun to connect.\n"
exit
}
"]$ " {
send "sudo -s && exit\n"
expect "assword"
send "$credential\n"
interact
}
}
@maelvls
Copy link

maelvls commented Feb 21, 2021

Hi! Thank you for the expect script!

Not sure why but I get an error related to lpass show --password ssh-$lpass-old; do I also need to have the ssh-${lpass}-old set in lpass?

% sussh client foo@bar
Error: Could not find specified account(s).
    while executing
"exec lpass show --password ssh-$lpass-old"
    invoked from within
"set credential_old [exec lpass show --password ssh-$lpass-old]"
    (file "~/bin/sussh" line 15)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment