Fish shell new function : "ssh: command not found " - ssh

I'm trying to create a function that connects me to a ssh server then become su, and then ssh into another server so I did the following:
function test
ssh -t testuser#server1 'sudo ssh -t testuser#server2'
end
When I execute it I get the following error ssh: command not found
But when I execute it straight to the terminal it works with no problems.

This sounds like a path issue on server1.
From the command line, what do you see if you type the following?
ssh -t testuser#server1 sudo which ssh
If SSH is not in the path for root, you might need to specify full paths, such as something like:
ssh -t testuser#server1 sudo /usr/bin/ssh testuser#server2
You may need to adjust the paths to match your environment, of course.
Also, if you're trying to connect from root at server1 to server2, can you just ssh directly to root#server1? If so, you could perhaps use the "ProxyJump" functionality that was added with OpenSSH 7.3. This depends upon the ability to remotely login as root, which may not be an option, depending on your environment.
ssh -J root#server1 testuser#server2

My problem was solved when I added each one of them to the fish functions folder:
~/.config/fish/functions
I just created a file called myfunction.fish and inside of that file I pasted the function definition:
function myfunction
ssh -t testuser#server1 'sudo ssh -t testuser#server2'
end
saved it, exited fish and now that function is permanent.

Related

Pass ssh options to ssh-copy-id

I'm stuck in the Permission denied (publickey) hell trying to copy public key to a remote server so Jenkins can rsync files during builds.
Running:
sudo ssh-copy-id -i id_rsa.pub ubuntu#xx.xx.xx.xx
I have done this for another server, but that one has a separate key pair for SSH assigned by EC2, and my current guess is that ssh-copy-id is trying to use wrong private key for this connection. Is there a way to pass -vv to ssh-copy-id so I can see what jey it's trying to use. I've looked into the -o switch, but can't seem to get it right.
Thank you.
So here's what I've done:
added following to /etc/ssh/ssh_config:
Host xx.xx.xx.xx
User ubuntu
IdentityFile ~/.ssh/key-name-for-that-machine.pem
Then copied key-name-for-that-machine.pem into /var/lib/jenkins/.ssh
Didn't run ssh-copy-id again, simply have rsync use that key file when moving stuff, here's the rsync script:
rsync -rvh -e 'ssh -v' "/tmp/project-DEV-${BUILD_ID}/" ubuntu#xx.xx.xx.xx:"/www/www.project-dir.net/"
my guess would by running it without sudo. But that's depending on how you normally log into the server.
If you normally login by using ssh ubuntu#xx.xx.xx.xx then lose the
sudo.
If not than try to login with sudo ssh ubuntu#xx.xx.xx.xx
Reading your question, at least one of these should fail.

rsync remote files over SSH to my local machine, using sudo privileges on local side, and my personal SSH key

I want to sync a directory /var/sites/example.net/ from a remote machine to a directory at the same path on my local machine.
The remote machine only authenticates SSH connections with keys, not passwords.
On my local machine I have an alias set up in ~/.ssh/config so that I can easily run ssh myserver to get in.
I'm trying rsync -a myserver:/var/sites/example.net/ /var/sites/example.net/ but it fails because my local user does not have permission to edit the local directory /var/sites/example.net/.
If I try sudo rsync -a myserver:/var/sites/example.net/ /var/sites/example.net/ (just adding sudo), I can fix the local permission issue, but then I encounter a different issue -- my local root user does not see the proper ssh key or ssh alias.
Is there a way I can accomplish this file sync by modifying this rsync command? I'd like to avoid changing anything else (e.g. no changes to file perms or ssh setup)
Try this:
sudo rsync -e "sudo -u localuser ssh" -a myserver:/var/sites/example.net/ /var/sites/example.net/
This runs rsync as root, but the -e flag causes rsync to run ssh as your local user (using sudo -u localuser), so the ssh command has access to the necessary credentials. Rsync itself is still running as root, so it has the necessary filesystem permissions.
Just improving on top of larsks's response:
sudo rsync -e "sudo -u $USER ssh" ...
So in your case change rsync -a myserver:/var/sites/example.net/ /var/sites/example.net/ to sudo rsync -e "sudo -u $USER ssh" -a myserver:/var/sites/example.net/ /var/sites/example.net/.
With regards to #larsks' answer, If you have your key loaded into the ssh agent, which is my use case, you can instead do:
sudo rsync -e "env SSH_AUTH_SOCK=$SSH_AUTH_SOCK ssh" /source/path /destination/path
Instead of the double sudo.
My use case, if anyone is interested in replicating, is that I'm SSHing to a non-root sudo-er account on remote A, and need to rsync root-owned files between remote A and remote B. Authentication to both remotes is done using keys I have on my real local machine and I use -A to forward the ssh-agent authentication socket to remote A.
Guss's answer works well if you want to use sudo rsync for local file permissions but want to utilise your user's SSH session. However, it falls short when you also want to use your SSH config file.
You can follow Wernight's approach by using sudo to switch the user for the SSH connection and supplying a path to the config file, but this won't work if you have to enter a passphrase. So, you can combine both approaches by making use of the --preserve-env flag:
sudo --preserve-env=SSH_AUTH_SOCK rsync -e "sudo --preserve-env=SSH_AUTH_SOCK -u $USER ssh" hostname:/source/path /destination/path
Note that it's necessary to cascade this flag through both sudo commands so it does look a bit messy!
As requested by Derek above:
when sudo asks for a password then you need to modify the sudoers config with sudo visudo and add a entry with NOPASSWD: in front of the rsync command.
For details you could consult man sudoers.
this will work in every mode, even via cron, at, systemd.service+timer, etc.
test it with: ssh <user>#<your-server> "sudo <your-rsync-command>"

How to do remote ssh non-interactively

I am trying to connect to a remote host from my local host through the below command.But there was a setting in the remote host that soon after we login it will prompt to enter a badge ID,password and reason for logging in, because it was coded like that in profile file on remote-host How can I overcome those steps and login directly non-interactively, without disturbing the code in profile.
jsmith#local-host$ ssh -t -t generic_userID#remote-host
Enter your badgeID, < exit > to abort:
Enter your password for <badgeID> :
Enter a one line justification for your interactive login to generic_userID
Small amendment: to overcome remote server expect approach is required, but in case local script connects to bunch of remote servers, which configuration may be broken, just use SSH options:
ssh -f -q -o BatchMode=yes -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null USER#TARGETSYSTEM
This will omit ask for password in case there is no ssh_key setup, exit silently and continue with script/other hosts.
Puts ssh to background with -f, which is required when calling ssh command from sh (batch) file to remove local console redirect to remote input (implies -n).
Look into setting up a wrapper script around expect. This should do exactly what you're looking for.
Here are a few examples you can work from.
I have upvoted Marvin Pinto's answer because there is every reason to script this, in case there are other features in the profile that you need, such as Message of the Day motd.
However, there is a quick and dirty alternative if you don't want to make a script and you don't want other features from the profile. Depending on your preferred shell on the remote host, you can insist that the shell bypasses the profile files. For example, if bash is available on the remote host, you can invoke it with:
ssh -t -t generic_userID#remote-host bash --noprofile
I tested the above on the macOS 10.13 version of OpenSSH. Normally the command at the end of the ssh invocation is run non-interactively, but the -t flag allows bash to start an interactive shell.
Details are in the Start-up files section of the Bash Reference Manual.

How to make SSH go directly to specific directory?

when you do an "ssh second_machine" you are able to connect to second_machine on your home directory
But usually i am working in my_machine in directory with very long path, and i want to connect to second_machine and move to my working directory right away. So everytime i have to:
ssh second_machine
cd /very/long/path/to/directory/
Is there a way to make it automatic ?? ( ssh automatically go to the desired directory )
This should work for you
ssh -t second_machine "cd /very/long/path/to/directory/; bash"
Assumes you're wanting to run bash, substitute for a different shell if required.
To make it permanent, use RemoteCommand in your ~/.ssh/config file, e.g.
Host myhost
HostName IP
User ubuntu
IdentityFile ~/.ssh/id_rsa
RemoteCommand cd /path/to/directory; $SHELL -il
Related:
SSH Config File Alias To Get To a Directory On Server
How can I automatically change directory on ssh login?
Run a remote command using ssh config file
You could do something like the one I'm using. Make an alias as the one below.
alias ssh 'ssh -t \!* "cd $PWD; csh"'
(here, csh could also be replaced by bash)
This brings you directly to the 'current' path on the other machine.
The usage would be like [$] ssh some machine
However, I find that it works slow. So, I'm looking for an alternative.

How to make ssh receive the password from stdin

How can you make SSH read the password from stdin, which it doesn't do by default?
based on this post you can do:
Create a command which open a ssh session using SSH_ASKPASS (seek SSH_ASKPASS on man ssh)
$ cat > ssh_session <<EOF
export SSH_ASKPASS="/path/to/script_returning_pass"
setsid ssh "your_user"#"your_host"
EOF
NOTE: To avoid ssh to try to ask on tty we use setsid
Create a script which returns your password (note echo "echo)
$ echo "echo your_ssh_password" > /path/to/script_returning_pass
Make them executable
$ chmod +x ssh_session
$ chmod +x /path/to/script_returning_pass
try it
$ ./ssh_session
Keep in mind that ssh stands for secure shell, and if you store your user, host and password in plain text files you are misleading the tool an creating a possible security gap
You can use sshpass which is for example in the offical debian repositories. Example:
$ apt-get install sshpass
$ sshpass -p 'password' ssh username#server
You can't with most SSH clients. You can work around it with by using SSH API's, like Paramiko for Python. Be careful not to overrule all security policies.
Distilling this answer leaves a simple and generic script:
#!/bin/bash
[[ $1 =~ password: ]] && cat || SSH_ASKPASS="$0" DISPLAY=nothing:0 exec setsid "$#"
Save it as pass, do a chmod +x pass and then use it like this:
$ echo mypass | pass ssh user#host ...
If its first argument contains password: then it passes its input to its output (cat) otherwise it launches whatver was presented after setting itself as the SSH_ASKPASS program.
When ssh encounters both SSH_ASKPASS AND DISPLAY set, it will launch the program referred to by SSH_ASKPASS, passing it the prompt user#host's password:
An old post reviving...
I found this one while looking for a solution to the exact same problem, I found something and I hope someone will one day find it useful:
Install ssh-askpass program (apt-get, yum ...)
Set the SSH_ASKPASS variable (export SSH_ASKPASS=/usr/bin/ssh-askpass)
From a terminal open a new ssh connection without an undefined TERMINAL variable (setsid ssh user#host)
This looks simple enough to be secure but did not check yet (just using in a local secure context).
Here we are.
FreeBSD mailing list recommends the expect library.
If you need a programmatic ssh login, you really ought to be using public key logins, however -- obviously there are a lot fewer security holes this way as compared to using an external library to pass a password through stdin.
a better sshpass alternative is :
https://github.com/clarkwang/passh
I got problems with sshpass, if ssh server is not added to my known_hosts sshpass will not show me any message, passh do not have this problem.
I'm not sure the reason you need this functionality but it seems you can get this behavior with ssh-keygen.
It allows you to login to a server without using a password by having a private RSA key on your computer and a public RSA key on the server.
http://www.linuxproblem.org/art_9.html