Doing sudo su with ssh on a remote server not working - bash

This seems to be a popular question on stackoverflow but nothing seems to be working for me
I will explain my problems first and then go the the solutions I have tried
What I need to do is to ssh to serverB from serverA. for this I have set up an rsa encryption on the servers and I can successfully ssh to serverB
I use
ssh user#hostname
Now I want execute certain commands on serverB. The first one is to switch to app user. For this I need to run sudo su - app command but I also want to provide the password in the same line so that it doesnt prompt for the password again.
So I have tried to first directly run sudo su - app command on serverB with password to test it out
I have tried the following
echo "password" | sudo su - app
sudo -S <<< "password" su - app
echo "password" | sudo -S su - app
echo 'passowrd' | sudo 'su -c - app'
However none of the above solutions work for me.
The closest I could get was with
echo "password" | script -c "sudo su - app"
where it accepts the password and shows me
app#hostname [/app]
$
however when I run the command whoami it still shows me user instead of app. however when I directly run sudo su - app and the provide pass and then run whoami it gives me app
I am trying to run command with ssh like
ssh user#hostname -t 'echo "password" | script -c "sudo su - app"'
P.S. the user user doesnt have root access and also I cannot make use of any plugin as I don't have permission to do the same
My server is Redhat 6.2
I hope I could explain it properly. Looking for some answers that can help.
Sorry for my bad English. Thanks for help.

If we set up ssh using rsa key encryption then we don't need to use the password.
In order to enable ssh with public/private key I follow
Genrate the public/private key for user on serverA
ssh-keygen -t rsa
Go to .ssh/id_rsa.pub file and copy the public key
Login to ServerB and then do sudo su - app to change to app user. Here in the file .ssh/authorized_key copy the public key.
Try ssh to serverB now from serverA like
ssh app#hostnameServerB
It works without asking for a password.

Related

Making an app using ssh to shutdown macbook

I have been trying to create an app that can shutdown my mac using ssh. I've tried ssh-copy-id -i ~/.ssh./id_rsa.pub ssh "my computer" | sudo shutdown -h now but I get an error message saying zsh:exit 1 and zsh: suspended (tty output) sudo shutdown -h now and I don't know what to do.
There are several issues with your command:
ssh-copy-id -i ~/.ssh./id_rsa.pub ssh "my computer" | sudo shutdown -h now
That's two commands. You need a semicolon or line break to separate them
ssh-copy-id needs the private key, but you've provided the public key
That key looks like it has an extra dot in the key path
You're running sudo shutdown -h now locally rather than remotely
Run this just one time. It will prompt you for your user's password on mycomputer:
ssh-copy-id -i ~/.ssh/id_rsa mycomputer
Then you can run this:
ssh -t mycomputer "sudo shutdown -h now"
This will be interactive since you need to enter your user password for sudo, but at least the key prevents you from needing to enter it a second time to gain access to the system.
You could reduce this by allowing your user to run that command without a password. From a shell on that computer (ssh mycomputer), run visudo (if the last line of that file looks like #includedir /etc/sudoers.d, quit and run something like visudo -f /etc/sudoers.d/local) and add this to the end:
gjwlsdnd224 ALL=(root) NOPASSWD: /sbin/shutdown -h now
where gjwlsdnd224 is your username. If you do this, you don't need -t passed to ssh.

How to connect via scp without password using a shell? [duplicate]

I know it is not recommended, but is it at all possible to pass the user's password to scp?
I'd like to copy a file via scp as part of a batch job and the receiving server does, of course, need a password and, no, I cannot easily change that to key-based authentication.
Use sshpass:
sshpass -p "password" scp -r user#example.com:/some/remote/path /some/local/path
or so the password does not show in the bash history
sshpass -f "/path/to/passwordfile" scp -r user#example.com:/some/remote/path /some/local/path
The above copies contents of path from the remote host to your local.
Install :
ubuntu/debian
apt install sshpass
centos/fedora
yum install sshpass
mac w/ macports
port install sshpass
mac w/ brew
brew install https://raw.githubusercontent.com/kadwanev/bigboybrew/master/Library/Formula/sshpass.rb
just generate a ssh key like:
ssh-keygen -t rsa -C "your_email#youremail.com"
copy the content of ~/.ssh/id_rsa.pub
and lastly add it to the remote machines ~/.ssh/authorized_keys
make sure remote machine have the permissions 0700 for ~./ssh folder and 0600 for ~/.ssh/authorized_keys
If you are connecting to the server from Windows, the Putty version of scp ("pscp") lets you pass the password with the -pw parameter.
This is mentioned in the documentation here.
curl can be used as a alternative to scp to copy a file and it supports a password on the commandline.
curl --insecure --user username:password -T /path/to/sourcefile sftp://desthost/path/
You can script it with a tool like expect (there are handy bindings too, like Pexpect for Python).
You can use the 'expect' script on unix/terminal
For example create 'test.exp' :
#!/usr/bin/expect
spawn scp /usr/bin/file.txt root#<ServerLocation>:/home
set pass "Your_Password"
expect {
password: {send "$pass\r"; exp_continue}
}
run the script
expect test.exp
I hope that helps.
You may use ssh-copy-id to add ssh key:
$which ssh-copy-id #check whether it exists
If exists:
ssh-copy-id "user#remote-system"
Here is an example of how you do it with expect tool:
sub copyover {
$scp = Expect->spawn("/usr/bin/scp ${srcpath}/$file $who:${destpath}/$file");
$scp->expect(30,"ssword: ") || die "Never got password prompt from $dest:$!\n";
print $scp 'password' . "\n";
$scp->expect(30,"-re",'$\s') || die "Never got prompt from parent system:$!\n";
$scp->soft_close();
return;
}
Nobody mentioned it, but Putty scp (pscp) has a -pw option for password.
Documentation can be found here: https://the.earth.li/~sgtatham/putty/0.67/htmldoc/Chapter5.html#pscp
Once you set up ssh-keygen as explained above, you can do
scp -i ~/.ssh/id_rsa /local/path/to/file remote#ip.com:/path/in/remote/server/
If you want to lessen typing each time, you can modify your .bash_profile file and put
alias remote_scp='scp -i ~/.ssh/id_rsa /local/path/to/file remote#ip.com:/path/in/remote/server/
Then from your terminal do source ~/.bash_profile. Afterwards if you type remote_scp in your terminal it should run the scp command without password.
Here's a poor man's Linux/Python/Expect-like example based on this blog post: Upgrading simple shells to fully interactive
TTYs. I needed this for old machines where I can't install Expect or add modules to Python.
Code:
(
echo 'scp jmudd#mysite.com:./install.sh .'
sleep 5
echo 'scp-passwd'
sleep 5
echo 'exit'
) |
python -c 'import pty; pty.spawn("/usr/bin/bash")'
Output:
scp jmudd#mysite.com:install.sh .
bash-4.2$ scp jmudd#mysite.com:install.sh .
Password:
install.sh 100% 15KB 236.2KB/s 00:00
bash-4.2$ exit
exit
Make sure password authentication is enabled on the target server. If it runs Ubuntu, then open /etc/ssh/sshd_config on the server, find lines PasswordAuthentication=no and comment all them out (put # at the start of the line), save the file and run sudo systemctl restart ssh to apply the configuration. If there is no such line then you're done.
Add -o PreferredAuthentications="password" to your scp command, e.g.:
scp -o PreferredAuthentications="password" /path/to/file user#server:/destination/directory
make sure you have "expect" tool before, if not, do it
# apt-get install expect
create the a script file with following content. (# vi /root/scriptfile)
spawn scp /path_from/file_name user_name_here#to_host_name:/path_to
expect "password:"
send put_password_here\n;
interact
execute the script file with "expect" tool
# expect /root/scriptfile
copy files from one server to other server ( on scripts)
Install putty on ubuntu or other Linux machines. putty comes with pscp. we can copy files with pscp.
apt-get update
apt-get install putty
echo n | pscp -pw "Password#1234" -r user_name#source_server_IP:/copy_file_path/files /path_to_copy/files
For more options see pscp help.
Using SCP non interactively from Windows:
Install the community Edition of netcmdlets
Import Module
Use Send-PowerShellServerFile -AuthMode password -User MyUser -Password not-secure -Server YourServer -LocalFile C:\downloads\test.txt -RemoteFile C:\temp\test.txt for sending File with non-interactive password
In case if you observe a strict host key check error then use -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null options.
The complete example is as follows
sshpass -p "password" scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null root#domain-name.com:/tmp/from/psoutput /tmp/to/psoutput
You can use below steps. This works for me!
Step1-
create a normal file suppose "fileWithScpPassword" which contains the ssh password for the destination server.
Step2- use sshpaas -f followed by password file name and then normal scp command.
sshpass -f "fileWithScpPassword" scp /filePathToUpload user#ip:/destinationPath/
One easy way I do this:
Use the same scp cmd as you use with ssh keys i.e
scp -C -i <path_to opens sshkey> <'local file_path'> user#<ip_address_VM>: <'remote file_path’>
for transferring file from local to remote
but instead of providing the correct <path_to_opensshkey>, use some garbage path. Due to wrong key path you will be asked for password instead and you can simply pass the password now to get the work done!
An alternative would be add the public half of the user's key to the authorized-keys file on the target system. On the system you are initiating the transfer from, you can run an ssh-agent daemon and add the private half of the key to the agent. The batch job can then be configured to use the agent to get the private key, rather than prompting for the key's password.
This should be do-able on either a UNIX/Linux system or on Windows platform using pageant and pscp.
All the solutions mentioned above can work only if you the app installed or you should have the admin rights to install except or sshpass.
I found this very useful link to simply start the scp in Background.
$ nohup scp file_to_copy user#server:/path/to/copy/the/file > nohup.out 2>&1
https://charmyin.github.io/scp/2014/10/07/run-scp-in-background/
I found this really helpful answer here.
rsync -r -v --progress -e ssh user#remote-system:/address/to/remote/file /home/user/
Not only you can pass there the password, but also it will show the progress bar when copying. Really awesome.

SSH sudo inside script different behaviour

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.

Automatic login using PUTTY.EXE with Sudo command

I am using below command to open putty through windows command prompt:
PUTTY.EXE -ssh -pw "mypass" user#IP -m C:/my.sh -t
Where my.sh mentioned in above command file contains:
sudo su - rootuser
After executing the command, putty console is opened and it prompts for password.
Is there any way where I can provide this password automatically without typing it?
There's a bit of a horrible workaround using Expect and embedding a password.
This is a bad idea.
As an alternative:
Configure sudo to allow NOPASSWD.
Login directly as root using public-private key auth.
Both these introduce a degree of vulnerability, so should be used with caution - but any passwordless auth has this flaw.
Finally, after struggling for almost whole day, I got the way to get this working.
Below command can be executed from windows machine:
PLINK.EXE -t -ssh -pw "password" user#IP /home/mydir/master.sh
master.sh file is located on remote machine. And this file contains below command to execute script with sudo command without prompting password.
echo password | sudo u user -S script.sh
Here, password should be replaced with your password. user should be replaced with your actual user and script.sh is the script on remote machine that you want to fire after sudo login.

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