How echo in bash file using SSH and Sudo - bash

So here my code:
$ssh_primary "echo $primary_ssh_password | sudo -S rm /etc/mysql/my.cnf"
$ssh_primary "echo $primary_ssh_password | sudo -S touch /etc/mysql/my.cnf"
$ssh_primary "echo \"[client-server]\nsocket = /run/mysqld/mysqld.sock\n\n!includedir /etc/mysql/conf.d/\n!includedir /etc/mysql/mariadb.conf.d/\n[mariadb]\nlog-bin=/var/log/mysql/mysql-bin.log\nserver_id=1\nlog-basename=master1\nbinlog-format=mixed\nlog_error=mariadb_primary.err\nbind-address = 0.0.0.0\n\" > (echo $primary_ssh_password | sudo -S /etc/mysql/my.cnf)"
$ssh_primary "echo $primary_ssh_password | sudo -S systemctl restart mariadb"
and more here my problem:
$ssh_primary "echo \"[client-server]\nsocket = /run/mysqld/mysqld.sock\n\n!includedir /etc/mysql/conf.d/\n!includedir /etc/mysql/mariadb.conf.d/\n[mariadb]\nlog-bin=/var/log/mysql/mysql-bin.log\nserver_id=1\nlog-basename=master1\nbinlog-format=mixed\nlog_error=mariadb_primary.err\nbind-address = 0.0.0.0\n\" > (echo $primary_ssh_password | sudo -S /etc/mysql/my.cnf)"
Expect output: I would have full access on this file, without having a prompt for password, but I dont really know how.. Can someone help me please?
I tried to do the opposite of what I had, but it doesn't work at all.
I've done changes in /etc/sudoers.

Related

Remote execution of SSH command hangs in ruby using Net::SSH for a particular command

I found a similar question here, but the answer in such a question didn't work for me.
I am trying to connect the remote ssh server via ruby using Net::SSH.
It is working fine for me for all the commands provided via script and I could read the output of the command successfully.
But when I use the below command it is getting stuck in SSH.exec!(cmd) and control is not returned from the line. Only if i click Ctrl+c in command line the script is getting ended.
sudo -S su root -c 'cockroach start --advertise-addr=34.207.235.139:26257 --certs-dir=/home/ubuntu/certs --store=node0015 --listen-addr=172.31.17.244:26257 --http-addr=172.31.17.244:8080 --join=34.207.235.139:26257 --background --max-sql-memory=.25 --cache=.25;'
This is the script I run from a SSH terminal with no issue:
sudo -S su root -c 'pkill cockroach'
sudo -S su root -c '
cd ~;
mv /home/ubuntu/certs /home/ubuntu/certs.back.back;
mkdir /home/ubuntu/certs;
mkdir -p /home/ubuntu/my-safe-directory;
cockroach cert create-ca --allow-ca-key-reuse --certs-dir=/home/ubuntu/certs --ca-key=/home/ubuntu/my-safe-directory/ca.key;
cockroach cert create-node localhost 34.207.235.139 172.31.17.244 $(hostname) --certs-dir /home/ubuntu/certs --ca-key /home/ubuntu/my-safe-directory/ca.key;
cockroach cert create-client root --certs-dir=/home/ubuntu/certs --ca-key=/home/ubuntu/my-safe-directory/ca.key;
'
sudo -S su root -c 'cockroach start --advertise-addr=34.207.235.139:26257 --certs-dir=/home/ubuntu/certs --store=node0015 --listen-addr=172.31.17.244:26257 --http-addr=172.31.17.244:8080 --join=34.207.235.139:26257 --background --max-sql-memory=.25 --cache=.25;'
This is the Ruby script who attempts to do exactly the same, but it gets stuck:
require 'net/ssh'
ssh = Net::SSH.start('34.207.235.139', 'ubuntu', :keys => './plank.pem', :port => 22)
s = "sudo -S su root -c 'pkill cockroach'"
print "#{s}... "
puts ssh.exec!(s)
s = "sudo -S su root -c '
cd ~;
mv /home/ubuntu/certs /home/ubuntu/certs.back.#{rand(1000000)}};
mkdir /home/ubuntu/certs;
mkdir -p /home/ubuntu/my-safe-directory;
cockroach cert create-ca --allow-ca-key-reuse --certs-dir=/home/ubuntu/certs --ca-key=/home/ubuntu/my-safe-directory/ca.key;
cockroach cert create-node localhost 34.207.235.139 172.31.17.244 $(hostname) --certs-dir /home/ubuntu/certs --ca-key /home/ubuntu/my-safe-directory/ca.key;
cockroach cert create-client root --certs-dir=/home/ubuntu/certs --ca-key=/home/ubuntu/my-safe-directory/ca.key;
'"
print "Installing SSL certifications... "
puts "done (#{ssh.exec!(s)})"
s = "sudo -S su root -c 'cockroach start --advertise-addr=34.207.235.139:26257 --certs-dir=/home/ubuntu/certs --store=node0015 --listen-addr=172.31.17.244:26257 --http-addr=172.31.17.244:8080 --join=34.207.235.139:26257 --background --max-sql-memory=.25 --cache=.25;'"
print "Running start command... "
puts "done (#{ssh.exec!(s)})"
# Use this command to verify the node is running:
# ps ax | grep cockroach | grep -v grep
s = "ps ax | grep cockroach | grep -v grep"
print "#{s}... "
sleep(10)
puts "done (#{ssh.exec!(s)})"
ssh.close
exit(0)
Here is the put put of the ruby script:
C:\code2\blackstack-deployer\examples>ruby start-crdb-environment.rb
sudo -S su root -c 'pkill cockroach'...
Installing SSL certifications... done ()
Running start command...
As you can see, the command gets stuck in the line Running start command...
I tried putting the command in the background:
s = "sudo -S su root -c 'cockroach start --advertise-addr=34.207.235.139:26257 --certs-dir=/home/ubuntu/certs --store=node0015 --listen-addr=172.31.17.244:26257 --http-addr=172.31.17.244:8080 --join=34.207.235.139:26257 --background --max-sql-memory=.25 --cache=.25 &'"
print "Running start command... "
puts "done (#{ssh.exec!(s)})"
but what happned is that the cockroach process never starts (the ps ax | grep cockroach | grep -v grep returns nothing)
I figured out how to fix it.
I added > /dev/null 2>&1 at the end of the command, and it worked.
cockroach start --background --max-sql-memory=.25 --cache=.25 --advertise-addr=%net_remote_ip%:%crdb_database_port% --certs-dir=%crdb_database_certs_path%/certs --store=%name% --listen-addr=%eth0_ip%:%crdb_database_port% --http-addr=%eth0_ip%:%crdb_dashboard_port% --join=%net_remote_ip%:%crdb_database_port% > /dev/null 2>&1;
Are there any logs/output in the cockroach-data/logs directory (should be located where you are running the start command from).
Or perhaps try redirecting stdout+stderr to a file and seeing if there is any output there.
My hypothesis is that the CRDB process isn't starting correctly and so control isn't being returned to the terminal. The cockroachdb docs say that the --background flag only returns control when the crdb process is ready to accept connections. And the question/answer you linked noted that "SSH.exec! will block further execution until the command returns".

Execute commands as different user via sudo over SSH in a justfile

I have this justfile:
remote:
#!/usr/bin/env bash
read -p 'Password:' -s password
ssh -tt somewhere 'bash -l -s' << 'ENDSSH'
whoami
echo "$password" | sudo su someone 'bash -l -s' << 'ENDSUDO'
whoami
ENDSUDO
ENDSSH
It should:
Ask me for a password
SSH into somewhere
sudo to change the user
execute some scripts
What it does:
It asks for a password a second time.
It stucks on input (no error message).
How to solve this problem?
Update
As suggested by #xhienne, this does almost work, but it says, I use the wrong password:
remote:
#!/usr/bin/env bash
read -p 'Password:' -s password
ssh -tt somewhere 'bash -l -s' << 'ENDSSH'
sudo -S -i -u someone << ENDSUDO
$password
whoami
ENDSUDO
exit
ENDSSH
But this does work:
remote:
#!/usr/bin/env bash
read -p 'Password:' -s password
ssh -tt somewhere 'bash -l -s' << 'ENDSSH'
sudo -S -i -u someone << ENDSUDO
clear-text-password
whoami
ENDSUDO
exit
ENDSSH
Update 2
The answer of #xhienne does work.
With
echo "$password" | sudo su someone 'bash -l -s' << 'ENDSUDO'
whoami
ENDSUDO
You are redirecting stdin twice:
once with |
a second time with <<
Try this:
sudo -S -i -u someone << ENDSUDO
$password
whoami
ENDSUDO
sudo -S will read the password from stdin. sudo -i is a substitute for the ugly sudo su bash -l (but it needs that sudo be properly configured for -u someone)
Note that I removed the quotes around ENDSUDO. Beware of inadvertent substitutions. If you must keep ENDSUDO quoted, then you can try this instead:
{
echo "$password"
cat << 'ENDSUDO'
whoami
ENDSUDO
} | sudo -S -i -u someone
I believe the following will work, if you only want to run whoami instead of several commands:
#!/usr/bin/env bash
read -s -p 'Password: ' password
ssh somewhere whoami
echo "$password" | ssh somewhere sudo -S -u someone whoami
The -S tells sudo to read the password from stdin.
If you want to run several commands with a here-document, see #xhienne's answer.

How to prevent output for a shell script command

What does tee do and is it possible to run this command in a alternative way with suppressing the output?
#!/bin/bash
echo "deb https://apt.dockerproject.org/repo ubuntu-xenial main" | sudo tee /etc/apt/sources.list.d/docker.list
The command
echo "deb https://apt.dockerproject.org/repo ubuntu-xenial main" | sudo tee /etc/apt/sources.list.d/docker.list
is an indirect way of saying:
echo "deb https://apt.dockerproject.org/repo ubuntu-xenial main" > /etc/apt/sources.list.d/docker.list
as root.
You see the output on the terminal because of the tee command.
You can rewrite it as below, to suppress the output, while running as non-root user:
echo "deb https://apt.dockerproject.org/repo ubuntu-xenial main" | sudo sh -c "cat > /etc/apt/sources.list.d/docker.list"
See also:
How do I use sudo to redirect output to a location I don't have permission to write to?
https://askubuntu.com/questions/230476/when-using-sudo-with-redirection-i-get-permission-denied

How to enter sudo password from command line?

I want to enter sudo password from command line .
but i am facing problem in the script .
#!/bin/sh
ssh -tt server_name<<'EOSSH'
sudo su - user
cd /move-to-path/
echo "done"
EOSSH
exit
export password as environment variable
export PASS=yourpassword
echo $PASS
now you can use it in script like:
echo $PASS | sudo -S su
echo $PASS | sudo -S apt-get install update
the password will be passed to sudo su command via -S flag

Update root crontab remotely for many systems by script

I am trying to update the crontab file of 1000+ systems using a for loop from jump host.
The below doesn't work.
echo -e 'pass365\!\n' | sudo -S echo 'hello' >> /var/spool/cron/root
-bash: /var/spool/cron/root: Permission denied
I do have (ALL) ALL in the sudoers file.
This is another solution;
echo 'pass365\!' | sudo -S bash -c 'echo "hello">> /var/spool/cron/root'
The below worked for me.
echo 'pass365\!' | sudo -S echo 'hello' | sudo -S tee -a /var/spool/cron/root > /dev/null
Problem 1: You are trying to send the password via echo to sudo.
Problem 2: You can't use shell redirection in a sudo command like that.
Between the two of these, consider setting up ssh public key authorization and doing
ssh root#host "echo 'hello' \>\> /var/spool/cron/root"
You may eventually get sudo working but it will be so much more pain than this.

Resources