SSH sudo inside script different behaviour - shell

I'm trying to set some automation inside local network and started working with some shell scripting and something that I saw - very strange behaviour SSH inside script according to how script running(with or without sudo):
What I have:
ComputerA and ComputerB.
Inside ComputerA:
A shell script script.sh:
cp /dir1/file1 /dir2/file2
ssh username#ComputerB "sudo reboot"
/etc/ssh/ssh_config file with some configurations to work without ssh-keys (they always changes on ComputerB):
StrictHostKeyChecking no
UserKnownHostsFile=/dev/null
GlobalKnownHostsFile=/dev/null
Inside ComputerB:
In /etc/sudoers file:
username ALL=(ALL:ALL) NOPASSWD:ALL
When I connecting through SSH to ComputerA and running script.sh without sudo, I get permission error to write to /dir2 (it's OK) and next command on ComputerB executes normally (reboots ComputerB), but I'm running sudo script.sh. It copy file and then I got strange - SSH asks me username password. Tried different variants to change ssh command to something like:
ssh -t username#ComputerB "echo user_pass | sudo -S reboot"
but nothing helped.
So I need help to figure out what happens and what to do to execute sudo script.sh without entering password for ssh command inside.
Thanks!

Don't run script.sh with sudo on computerA; instead modify the script like so:
sudo cp /dir1/file1 /dir2/file2
ssh username#ComputerB "sudo reboot"
The reason that you're seeing the strange behaviour is that you're actually becoming root on computerA (I assume you have a keypair set-up for your regular user and expect to connect to computerB passwordless?), and that root on computerA doesn't have a keypair that computerB knows about.

Related

Sudo SU in Bash script without asking user for password

My user is in root group. I canot ssh to server as root because is says Permission denied, please try again. What I usualy do is I ssh as my user and once I'm logged in i type sudo su and I proivde my user's password to become root.
I want to automate part of my job so I want to write a bash script which would ssh as my user, switch to root and then call set of commands.
So far I came with following script but I am unable to switch to root user without asking user for password:
while read p; do
p=$(echo $p|tr -d '\r')
sshpass -p "myPasswd" ssh -T -o StrictHostKeyChecking=no myUser#remoteServer << EOT
cd /var/log/jboss/ #here I am getting 'permission denied' message as only root has access
exit
EOT
done < $nodes
I also tried:
sshpass -p "myPasswd" ssh -tt -o StrictHostKeyChecking=no myUser#remoteServer 'cd /var/log/jboss/'
but I got the same permission denied error message
For security reasons, root users are typically not allowed ssh access.
PermitRootLogin no # value in /etc/ssh/sshd_config
The above setting is preventing you from logging in as root in the first place. If you are "comfortable" with you network's security, you can consider modifying that setting. If you ever make modifications to the sshd config, you'll need to restart the ssh service:
sudo service sshd restart
Of course, if you want to adhere to common wisdom, you may want to make changes to your sudoers file (as recommended by chepner and Nic3500). Here's a reasonable configuration change to make:
Add the following line to the bottom of your /etc/sudoers file:
#includedir /etc/sudoers.d
And add the following files to your /etc/sudoers.d directory:
cat /etc/sudoers.d/10_wheel:
%wheel ALL=(ALL) NOPASSWD: ALL
The above example configures sudo to allow access to all commands to members of the wheel group, without a password. You may want to change the group name to a group that your user is a member of.
You can determine your groups by issuing the command:
groups
Also, to avoid the use of sshpass, you can deploy ssh public keys to the remote host. Lastly, if you don't want to change the server at all, you can achieve what you are trying to do with expect. If you are comfortable with python coding, I recommend pexpect - I find it soooo much easier than the TCL based expect that is typically discussed.

Shell Script to run on Local and Remote machine

I am new to shell scripting,
I am trying to write a script that'll run on my local machine.
Few of it's commands are to run on my local and then a few on the remote server.
Below is a sample script -
The 1st two will run on my local system,
rest of them are to run on the remote server.
eg -
scp -i permissions.pem someJar.jar ubuntu#ip:/var/tmp
ssh -i permissions.pem ubuntu#ip
sudo su
service someService stop
rm -rf /home/ubuntu/someJar.jar
rm -rf /home/ubuntu/loggingFile.log
mv /var/tmp/someJar.jar .
service someService start
As the script will run on my local machine,
How do make sure the 3rd and further commands take effect on the remote server and not on my machine?
Here's my sample.sh file -
scp -i permissions.pem someJar.jar ubuntu#ip:/var/tmp
SCRIPT="sudo su; ps aux | grep java; service someService stop; ps aux | grep java; service someService start; ps aux | grep java;"
ssh -i permissions.pem ubuntu#ip $SCRIPT
The scp is working, nothing is displayed after that.
You need to pass the reset of the script as a parameter to SSH. Try this format:
SCRIPT="sudo su; command1; command2; command3;"
ssh -i permissions.pem ubuntu#ip $SCRIPT
See: http://linuxcommand.org/man_pages/ssh1.html
Hope this helps.
Update:
The reason why you don't see anything after running the command is because sudo expects the password. To avoid this there are three solutions:
Give ubuntu user needed permissions to perform all the tasks in the script.
Pass the password to sudo under SCRIPT: echo 'password' | sudo su; ...
Modify sudo-er file and allow ubuntu user to sudo without prompting for password. Run sudo visudo and add the following line: ubuntu ALL = NOPASSWD : ALL
Each system admin will have a different approach to this problem. I think everyone will agree that option 2 is the least secure. The reset is up to debate. In my opinion option 3 is slightly more secure. Yet, entire server is compromised if your key is compromised. The most secure is option 1. While it is painful to assign individual permissions, by doing so you are limiting your exposure to assigned permissions in case if your key is compromised.
One more note: It might be beneficial to replace ; with && in the SCRIPT. By doing so you will ensure that second command will run only if the first one finished successfully, third will run only if second finished successfully and so on.

How to return to the script once sudo is done

I am on a server and running a script file that has following code.
ssh username#servername
sudo su - root
cd /abc/xyz
mkdir asdfg
I am able to ssh... but then the next command is not working.. the script is not sudo-ing. any idea?
Edit: Able to create a mech id and then do the things.. though still looking for the answer to above question :|
First of all your command will "stuck" on the first line because it will go into an interactive mode. The ssh command will require a password to be provided by a user (unless there is an sshkey being used) . And if the ssh is logged into the remote server then it will wait for user commands from standard input.
Secondly the lines following the ssh command will be executed only when the first process has exited. This is why your script is not "sudoing" - it's waiting for the ssh to end.
So if your point is to run a command on a remote server then put the command as a parameter into the same line as ssh connection. In your case:
ssh user#server sudo su - root
But this will not be of satisfaction for you. I suggest you create a script of what you want to execute on the remote server and then execute the script.
ssh user#server scriptName
The sudo thing here is very tricky because again your script might get stuck in the interactive mode waiting for a password to be inserted so I suggest you think again on the basis of the script.
mb47!
You want to run the script on the remote computer, correct?
On the remote machine, create a file containing the commands you would like to execute.
Then, on the other machine, run ssh user#machine /path/to/script/you/created/earlier
I hope this helps!
ALinuxLover

Why is rsync prompting for password in bash script, but runs fine when executed outside of script?

I have a shared SSH keys with another server so I can login without a password. Executing:
rsync -avze ssh --blocking-io --delete --rsh='ssh -p2020' user#XXX.XX.XXX.XX:/foo/* /bar/;
Runs fine. No password prompt. But that command in a bash file:
#!/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
rsync -avze ssh --blocking-io --delete --rsh='ssh -p2020' user#XXX.XX.XXX.XX:/foo/* /bar/;
Run like so:
sudo ./copyfiles.sh
Gives me this:
user#XXX.XX.XXX.XX's password:
Any ideas why?
You seem to be running the script as root (sudo) but run the command line as some other user (this is just a guess). Most likely, the public key of the root user is not present on the destination machine.
The sudo program is probably creating a new shell without some SSH environment variables.
Try
sudo -E ./copyfiles.sh

How to run the sftp command with a password from Bash script?

I need to transfer a log file to a remote host using sftp from a Linux host. I have been provided credentials for the same from my operations group. However, since I don't have control over other host, I cannot generate and share RSA keys with the other host.
So is there a way to run the sftp command (with the username/password provided) from inside the Bash script through a cron job?
I found a similar Stack Overflow question, Specify password to sftp in a Bash script, but there was no satisfactory answer to my problem.
You have a few options other than using public key authentication:
Use keychain
Use sshpass (less secured but probably that meets your requirement)
Use expect (least secured and more coding needed)
If you decide to give sshpass a chance here is a working script snippet to do so:
export SSHPASS=your-password-here
sshpass -e sftp -oBatchMode=no -b - sftp-user#remote-host << !
cd incoming
put your-log-file.log
bye
!
Another way would be to use lftp:
lftp sftp://user:password#host -e "put local-file.name; bye"
The disadvantage of this method is that other users on the computer can read the password from tools like ps and that the password can become part of your shell history.
A more secure alternative which is available since LFTP 4.5.0 is setting the LFTP_PASSWORD environment variable and executing lftp with --env-password. Here's a full example:
export LFTP_PASSWORD="just_an_example"
lftp --env-password sftp://user#host -e "put local-file.name; bye"
# Destroy password after use
export LFTP_PASSWORD=""
LFTP also includes a cool mirroring feature (can include delete after confirmed transfer --Remove-source-files):
lftp -e 'mirror -R /local/log/path/ /remote/path/' --env-password -u user sftp.foo.com
EXPECT is a great program to use.
On Ubuntu install it with:
sudo apt-get install expect
On a CentOS Machine install it with:
yum install expect
Lets say you want to make a connection to a sftp server and then upload a local file from your local machine to the remote sftp server
#!/usr/bin/expect
spawn sftp username#hostname.com
expect "password:"
send "yourpasswordhere\n"
expect "sftp>"
send "cd logdirectory\n"
expect "sftp>"
send "put /var/log/file.log\n"
expect "sftp>"
send "exit\n"
interact
This opens a sftp connection with your password to the server.
Then it goes to the directory where you want to upload your file, in this case "logdirectory"
This uploads a log file from the local directory found at /var/log/ with the files name being file.log to the "logdirectory" on the remote server
You can use lftp interactively in a shell script so the password not saved in .bash_history or similar by doing the following:
vi test_script.sh
Add the following to your file:
#!/bin/sh
HOST=<yourhostname>
USER=<someusername>
PASSWD=<yourpasswd>
cd <base directory for your put file>
lftp<<END_SCRIPT
open sftp://$HOST
user $USER $PASSWD
put local-file.name
bye
END_SCRIPT
And write/quit the vi editor after you edit the host, user, pass, and directory for your put file typing :wq .Then make your script executable chmod +x test_script.sh and execute it ./test_script.sh.
I was recently asked to switch over from ftp to sftp, in order to secure the file transmission between servers. We are using Tectia SSH package, which has an option --password to pass the password on the command line.
example : sftp --password="password" "userid"#"servername"
Batch example :
(
echo "
ascii
cd pub
lcd dir_name
put filename
close
quit
"
) | sftp --password="password" "userid"#"servername"
I thought I should share this information, since I was looking at various websites, before running the help command (sftp -h), and was i surprised to see the password option.
You can override by enabling Password less authentication. But you should install keys (pub, priv) before going for that.
Execute the following commands at local server.
Local $> ssh-keygen -t rsa
Press ENTER for all options prompted. No values need to be typed.
Local $> cd .ssh
Local $> scp .ssh/id_rsa.pub user#targetmachine:
Prompts for pwd$> ENTERPASSWORD
Connect to remote server using the following command
Local $> ssh user#targetmachine
Prompts for pwd$> ENTERPASSWORD
Execute the following commands at remote server
Remote $> mkdir .ssh
Remote $> chmod 700 .ssh
Remote $> cat id_rsa.pub >> .ssh/authorized_keys
Remote $> chmod 600 .ssh/authorized_keys
Remote $> exit
Execute the following command at local server to test password-less authentication.
It should be connected without password.
$> ssh user#targetmachine
The easiest way I found to accomplish this, without installing any third-party library like Expect, SSHPASS...etc, is by using a combination of CURL, and SFTP. Those two are almost in every Linux machine.
This is the command you should execute, after changing the values.
curl -k "sftp://SERVER_IP:SERVER_PORT/FULL_PATH_OF_THE_FILE" --user "SERVER_USER:SERVER_PASSOWRD" -o "THE_NAME_OF_THE_FILE_AFTER_DOWNLOADING_IT"
Example:
curl -k "sftp://10.10.10.10:77/home/admin/test.txt" --user "admin:123456" -o "test.txt"
Explanation:
We are connecting to the server 10.10.10.10:77 using the username admin and password 123456, to move the file /home/admin/test.txt from that server to the server you are using currently to execute the above command.
Combine sshpass with a locked-down credentials file and, in practice, it's as secure as anything - if you've got root on the box to read the credentials file, all bets are off anyway.
Bash program to wait for sftp to ask for a password then send it along:
#!/bin/bash
expect -c "
spawn sftp username#your_host
expect \"Password\"
send \"your_password_here\r\"
interact "
You may need to install expect, change the wording of 'Password' to lowercase 'p' to match what your prompt receives. The problems here is that it exposes your password in plain text in the file as well as in the command history. Which nearly defeats the purpose of having a password in the first place.
You can use sshpass for it. Below are the steps
Install sshpass For Ubuntu - sudo apt-get install sshpass
Add the Remote IP to your known-host file if it is first time
For Ubuntu -> ssh user#IP -> enter 'yes'
give a combined command of scp and sshpass for it.
Below is a sample code for war coping to remote tomcat
sshpass -p '#Password_For_remote_machine' scp /home/ubuntu/latest_build/abc.war #user##RemoteIP:/var/lib/tomcat7/webapps
You can use a Python script with scp and os library to make a system call.
ssh-keygen -t rsa -b 2048 (local machine)
ssh-copy-id user#remote_server_address
create a Python script like:
import os
cmd = 'scp user#remote_server_address:remote_file_path local_file_path'
os.system(cmd)
create a rule in crontab to automate your script
done
A few people have mentioned sshpass but not many clear coding examples...
This is how we are doing it with bash scripts for rsync backups:
sshpass -p "${RSYNC_PASSWORD}" sftp "${RSYNC_USER}"#"${RSYNC_REMOTE_HOST}"
Keep in mind you will have to sudo apt install sshpass before this works properly.

Resources