7

Linux: ubuntu 14.04.3 LTS

cat /tmp/passfile
ABCxyz123

sshpass -f /tmp/passfile parallel-ssh -I -A -h hostlist.txt "sudo -S ls -l /root" < /tmp/passfile

and the method described here in google discussion groups.google outputs the error as:

[1] 01:07:25 [FAILURE] 10.0.4.194 Exited with error code 255
[2] 01:07:25 [FAILURE] 10.0.4.205 Exited with error code 255

in the remote server I'm trying to connect its /var/log/auth.log has below message

Sep 24 19:20:52 ubu1401 sshd[5765]: Accepted password for ubuntu from 10.0.4.1 port 55019 ssh2
Sep 24 19:20:52 ubu1401 sshd[5765]: pam_unix(sshd:session): session opened for user ubuntu by (uid=0)
Sep 24 19:21:26 ubu1401 sshd[5765]: pam_unix(sshd:session): session closed for user ubuntu
Sep 24 19:21:26 ubu1401 sudo: pam_unix(sudo:auth): conversation failed
Sep 24 19:21:26 ubu1401 sudo: pam_unix(sudo:auth): auth could not identify password for [ubuntu]
Sep 24 19:22:25 ubu1401 sshd[5791]: Connection closed by 10.0.4.1 [preauth]
1
  • try adding -i -v to parallel-ssh to see if it provides any further clues.
    – meuh
    Commented Sep 25, 2016 at 19:43

5 Answers 5

5

To provide the password as securely, as possible, try this version (pssh on CentOS, Fedora and parallel-ssh on Ubuntu, Debian):

stty -echo; printf "Password: "; read PASS; stty echo; echo "${PASS}" | \ ssh <USER>@localhost "sudo -S dmesg"

Update (thanks @chutz):

read -s -p "Password: "; echo "${REPLY}" | \ ssh <USER>@localhost "sudo -S dmesg"

and then adapt it to pssh like this (updated accordingly):

read -s -p "Password: "; echo "${REPLY}" | \ pssh -H <USER>@localhost -o /tmp/output -I "sudo -S dmesg"

I use the same for ad-hoc collection of dumps from multiple servers. Stop it using Ctrl + C as usual. It will show [FAILURE] <HOST> Interrupted, but that is just because tcpdump would otherwise run infinitely - the output is still in the usual location. The -t 0 option is so the connection doesn't time out. I could also use tmux or screen and collect the dumps later.

read -s -p "Password: "; echo "${REPLY}" | \ pssh -h <HOSTFILE> -o /tmp/output -t 0 -I "sudo -S tcpdump -l -nn -vv -i any not port 22"

Make sure to include the correct ssh user and that you connected to those servers before. Testing things locally usually prevents taking down the entire fleet of servers. You can use the 127.0.0.X addresses instead of localhost to approximate multiple hosts.

8
  • 3
    For our Ubuntu 18.04 network, I had to add -x '-tt'; otherwise this was perfect. Commented Jun 6, 2019 at 19:20
  • What does -tt do? I haven't seen this in the manual page (man parallel-ssh on Debian, Ubuntu). The -x option provides SSH connection arguments. A single "string" of arguments to SSH can also be provided with -X.
    – AdamKalisz
    Commented Jun 10, 2019 at 21:31
  • 2
    -x '-tt' instructs pssh to send the -tt parameter to ssh, where it forces a pseudo-terminal allocation. This was necessary to get ssh to receive the password. Commented Jun 10, 2019 at 23:08
  • 1
    The problem is if you have echo $PASS it will be visible for someone running ps aux. It is not a problem if you are the only user on this server.
    – Ole Tange
    Commented Sep 25, 2020 at 21:36
  • 1
    You can avoid all the stty convolution with the following shortcut: echo -n Password:; read -s; echo "$REPLY". Or with bash it is only one command: read -s -p Password:; echo "$REPLY".
    – chutz
    Commented Aug 18, 2021 at 13:11
0

have you tried running this via echoing the password in the shell?

echo "echo 'yourpassword'; sudo -S -c 'ls -l /root'"|pssh -I -H hostlist.txt

3
  • 1
    This does not provide an answer to the question. To critique or request clarification from an author, leave a comment below their post. - From Review Commented Oct 21, 2016 at 14:58
  • @countermode this is how I run pssh sudo. That basically answers the question in the headline: "How to run sudo with parallel ssh" Commented Oct 21, 2016 at 16:26
  • 3
    i used ansible instead of the parallel ssh (i wanted to check disk usage ,free memory etc) Commented Oct 22, 2016 at 17:23
0

I would like to recommend my simple tool "spssh.sh" ( https://github.com/tangruize/spssh ) , which is simple (only 36 sloc) but useful enough. Unlike parallel-ssh, spssh.sh is interactive, and supports parallel/separate cmd executing. Hope it helps!

2
  • Looking at the code it looks as if you are running one process in parallel per server. So if you have more server than you have processes, this will not work. Correct?
    – Ole Tange
    Commented Sep 25, 2020 at 21:22
  • Do you mean the number of servers exceeds the number of system process limit? In that circumstance, the scripts won't work. On the other hand, the script is not fit for too many servers because it opens a window for a server, and too many windows make the layout messy. If you don't have the demand for interactive shell for each individual server, I would like to recommend this repo: github.com/six-ddc/hss . It is interactive and featured in auto-completion. And it declares that it can run a command on hundreds of servers at the same time.
    – William
    Commented Sep 26, 2020 at 12:32
0

Using GNU Parallel you can do something like:

#!/bin/bash

runsshsudo() {
  cat /tmp/passfile |
    sshpass -f /tmp/passfile ssh "$@" sudo -S ls -l /root
}
export -f runsshsudo

cat hostlist.txt | parallel runsshsudo

This avoids putting the password on the command line (e.g. echo $PASS) which can be intercepted by an attacker by running ps aux.

0

I agree with @satch_boogie comment above - use ansible when you need SUDO and use pssh when you don't - its cleaner to SUDO in ansible IMO although initial setup is more involved.

Short answer: Example updating and upgrading package with apt:

ansible myservers -a "sudo apt -y update" --become -K

ansible myservers -a "sudo apt -y upgrade" --become -K

Long answer and setup: For my situation, I was using MacOS locally to manage my remote Linux machines. I did the following which may vary slightly if your using Linux:

  1. make sure you have the same user created locally and on all target machines: sudo adduser username
  2. add the user to the SUDO group on each target machine: usermod -aG sudo username
  3. (maybe optional) Setup passwordless ssh though I'm unclear if this is needed but my environment was already setup with this. Try steps below first as it might not be necessary for passwordless ssh.
  4. Install ansible on your local machine: brew install ansible (or linux sudo apt install ansible)
  5. create the default hosts file for ansible on your local machine: sudo mkdir /etc/ansible && sudo touch /etc/ansible/hosts
  6. edit the file sudo nano /etc/ansible/hosts
  7. Add the target machines under a group (ip or machine name):
[myservers]
blah1.local
blah2.local
blah3.local
  1. (Optional) I had a second user in the SUDO group on all target machines so I had to temporarily remove this user from the SUDO group to avoid a prompt (like when using sudo systemctl it asks to pick a SUDO user): ansible myservers -a "sudo deluser otheruser sudo" --become -K
  2. Now run the actual SUDO command you want. Example: ansible myservers -a "sudo apt -y update" --become -K
  3. (Optional) re-add the otheruser back to the SUDO group: ansible myservers -a "sudo adduser otheruser sudo" --become -K

Now every time I need to run a SUDO command across machines, I simply repeat steps 8-10.

2
  • Since the OP asked about parallel ssh in particular: some versions of pssh can be used with -X -tt to allow sudo to work if virt terminal is required. I have used this with significant success although I will point out that redirections after a sudo command do not receive the rights escalation. $ sudo -X -tt -h somefile "sudo <do something>" will run 'do something' on all servers listed in "somefile". Commented Jul 24, 2021 at 23:08
  • @PatrickTaylor will give that a try Commented Jul 25, 2021 at 15:04

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .