Bash library for executing remote sudo commands while preserving the tty.
See the latest release for instructions.
ssh_sudo
works by creating 3 temporary files on the remote.
The first 2 are owned and only readable by $SSH_USER
.
The third is owned and only readable by $SSH_SUDO_USER
.
All 3 files are deleted after the commands have completed.
- A fifo (named pipe) that outputs the sudo password
- A sudo
askpass
script that reads from the fifo and outputs to stdout - The commands or script that should be run by
$SSH_SUDO_USER
The sudo password is only ever transmitted to the remote (and any child process) via stdin piping, meaning it will not be visible in the processlist as an argument at any point in time and is never saved to disk.
When used from bash, none of the variables need to be exported, meaning none of the childprocesses your script runs will be able to see the sudo password.
The executables ssh-sudo
and ssh-sudo-cmd
"un-export" the variables.
A possible exploit is to read the password from the fifo socket that is written
to right before sudo
is executed. However, the socket is only readable by the
current SSH user, meaning the attacker would have to have access to the login
user account, in which case a slew of other exploits would be possible
regardless (such as aliasing sudo
or placing a wrapper script in
~/.local/bin
).
Performance can be increased considerably by using an SSH control master:
SSH_OPTS=(
-o ControlMaster=auto
-o ControlPath="$HOME/.ssh/control/myscript-%r@%h:%p"
-o ControlPersist=120s
-o ConnectTimeout=10s
)
Do note that the control master decides the SSH options. Meaning if the SSH
connection is started without -t
, any subsequent connections of the same
control master will not have a pseudo-terminal allocation even if -t
is used.
In that case a connection on a separate ControlPath
must be established.
Run a command as root on the remote while preserving stdin, stdout, and stderr.
Run a command as root on the remote but do not preserve stdin (quicker).
Run a command as $SSH_USER
on the remote.
A wrapper script for ssh_sudo
. Expects the necessary
variables to be exported. See $_SSH_OPTS
for how to pass SSH
options.
A wrapper script for ssh_sudo_cmd
. Expects the necessary
variables to be exported. See $_SSH_OPTS
for how to pass SSH
options.
These variables do not need to be exported, you can define them in your script as global variables and then use the above functions.
Remote SSH user, defaults to $USER
(optional)
Remote SSH host (required)
sudo password for $SSH_USER
(required)
Remote user to sudo to, defaults to root
(optional)
An array of options to pass to all ssh invocations (optional)
Command version of $SSH_OPTS
(optional). Bash arrays cannot be exported as
environment variables, instead $_SSH_OPTS
must be a string where each
parameter is separated by the record separator char (RS
or \x1e
in hex).
In bash it would look like this:
export _SSH_OPTS=$'-o\x1eForwardAgent=yes\x1e-t\x1e-q'
.