BASH label for IP addresses - bash

My fault: I have been so busy learning other linux stuff that I completely neglected the power of bash.
I have a number of systems to access remotely for very simple operations. The problem is that I need to remember each single IP address. And they are a lot.
Using aliases in ~./bashrc is an option:
alias ssh_customer1='ssh root#10.X.X.X'
alias ssh_customer2='ssh root#10.X.X.Y'
alias copy_customer1='scp * root#10.X.X.X:/etc/example/'
alias copy_customer2='scp * root#10.X.X.Y:/etc/example/'
alias get_customer1='scp root#10.X.X.X:/etc/example/* .'
alias get_customer2='scp root#10.X.X.Y:/etc/example/* .'
but the flexibility is minimal.
Another possibility is to define functions using the name of system as a parameter but I don't like this:
sshx('customer1')
scpx('customer2')
I would prefer to just replace a label with the corresponding IP address without the need to remember it, and use standard commands:
ssh root#ip_customer1
scp root#ip_customer2:/etc/example/* .
Is this possible?

Setup a ~/.ssh/config file:
$ cat ~/.ssh/config
Host cust1
HostName 10.X.X.X
User root
Host cust2
HostName 10.X.X.Y
User root
Now you can use:
ssh cust1
Another cool thing is that you can now attach identity files to each server:
$ cat ~/.ssh/config
Host cust1
HostName 10.X.X.X
User root
IdentityFile ~/.ssh/cust1.id_rsa
Host cust2
HostName 10.X.X.Y
User root
IdentityFile ~/.ssh/cust2.id_rsa
This will let you use ssh and scp without password, assuming the key is without password or ssh-agent is used.

Related

How to use SSH with alias

I have an alias to a server machine:
alias myserver='user#server'
however, I cannot ssh into it by using the alias:
ssh myserver
ssh: Could not resolve hostname myserver: Name or service not known
the alias is correctly set:
myserver
returns bash: user#server: command not found.
Obviously, it works when I do it extensively:
ssh user#server
what is going on? I am pretty sure it has been working until today... But not sure what I changed.
Any help?
you can either have an Alias in your bash configuration which includes the actual ssh command aswell ...
alias myserver='ssh user#myserver'
... or have an alias in your ssh config file.
Host myserver
HostName 10.10.20.20
User user
ssh myserver should work.
A more extensive answer can be found for example here.
Not sure about the alias, but I use ~/.ssh/config:
Host myserver
HostName server
User user
Port 22
Then ssh myserver is just like your alias for ssh user#server.

Secure copy over two IPs on the same network to the local machine [duplicate]

I wonder if there is a way for me to SCP the file from remote2 host directly from my local machine by going through a remote1 host.
The networks only allow connections to remote2 host from remote1 host. Also, neither remote1 host nor remote2 host can scp to my local machine.
Is there something like:
scp user1#remote1:user2#remote2:file .
First window: ssh remote1, then scp remot2:file ..
Second shell: scp remote1:file .
First window: rm file; logout
I could write a script to do all these steps, but if there is a direct way, I would rather use it.
Thanks.
EDIT: I am thinking something like opening SSH tunnels but i'm confused on what value to put where.
At the moment, to access remote1, i have the following in $HOME/.ssh/config on my local machine.
Host remote1
User user1
Hostname localhost
Port 45678
Once on remote1, to access remote2, it's the standard local DNS and port 22. What should I put on remote1 and/or change on localhost?
I don't know of any way to copy the file directly in one single command, but if you can concede to running an SSH instance in the background to just keep a port forwarding tunnel open, then you could copy the file in one command.
Like this:
# First, open the tunnel
ssh -L 1234:remote2:22 -p 45678 user1#remote1
# Then, use the tunnel to copy the file directly from remote2
scp -P 1234 user2#localhost:file .
Note that you connect as user2#localhost in the actual scp command, because it is on port 1234 on localhost that the first ssh instance is listening to forward connections to remote2. Note also that you don't need to run the first command for every subsequent file copy; you can simply leave it running.
Double ssh
Even in your complex case, you can handle file transfer using a single command line, simply with ssh ;-)
And this is useful if remote1 cannot connect to localhost:
ssh user1#remote1 'ssh user2#remote2 "cat file"' > file
tar
But you loose file properties (ownership, permissions...).
However, tar is your friend to keep these file properties:
ssh user1#remote1 'ssh user2#remote2 "cd path2; tar c file"' | tar x
You can also compress to reduce network bandwidth:
ssh user1#remote1 'ssh user2#remote2 "cd path2; tar cj file"' | tar xj
And tar also allows you transferring a recursive directory through basic ssh:
ssh user1#remote1 'ssh user2#remote2 "cd path2; tar cj ."' | tar xj
ionice
If the file is huge and you do not want to disturb other important network applications, you may miss network throughput limitation provided by scp and rsync tools (e.g. scp -l 1024 user#remote:file does not use more than 1 Mbits/second).
But, a workaround is using ionice to keep a single command line:
ionice -c2 -n7 ssh u1#remote1 'ionice -c2 -n7 ssh u2#remote2 "cat file"' > file
Note: ionice may not be available on old distributions.
This will do the trick:
scp -o 'Host remote2' -o 'ProxyCommand ssh user#remote1 nc %h %p' \
user#remote2:path/to/file .
To SCP the file from the host remote2 directly, add the two options (Host and ProxyCommand) to your ~/.ssh/config file (see also this answer on superuser). Then you can run:
scp user#remote2:path/to/file .
from your local machine without having to think about remote1.
With openssh version 7.3 and up it is easy. Use ProxyJump option in the config file.
# Add to ~/.ssh/config
Host bastion
Hostname bastion.client.com
User userForBastion
IdentityFile ~/.ssh/bastion.pem
Host appMachine
Hostname appMachine.internal.com
User bastion
ProxyJump bastion # openssh 7.3 version new feature ProxyJump
IdentityFile ~/.ssh/appMachine.pem. #no need to copy pem file to bastion host
Commands to run to login or copy
ssh appMachine # no need to specify any tunnel.
scp helloWorld.txt appMachine:. # copy without intermediate jumphost/bastion host copy.**
ofcourse you can specify bastion Jump host using option "-J" to ssh command, if not configured in config file.
Note scp does not seems to support "-J" flag as of now. (i could not find in man pages. However above scp works with config file setting)
There is a new option in scp that add recently for exactly this same job that is very convenient, it is -3.
TL;DR For the current host that has authentication already set up in ssh config files, just do:
scp -3 remote1:file remote2:file
Your scp must be from recent versions.
All other mentioned technique requires you to set up authentication from remote1 to remote2 or vice versa, which not always is a good idea.
Argument -3 means you want to move files from two remote hosts by using current host as intermediary, and this host actually does the authentication to both remote hosts, so they don't have to have access to each other.
You just have to setup authentication in ssh config files, which is fairly easy and well documented, and then just run the command in TL;DR
The source for this answer is https://superuser.com/a/686527/713762
This configuration works nice for me:
Host jump
User username
Hostname jumphost.yourorg.intranet
Host production
User username
Hostname production.yourorg.intranet
ProxyCommand ssh -q -W %h:%p jump
Then the command
scp myfile production:~
Copies myfile to production machine.
a simpler way:
scp -o 'ProxyJump your.jump.host' /local/dir/myfile.txt remote.internal.host:/remote/dir

git ssh fails to access host but succeed when direct IP is used (Windows 10)

I am using git/bash in Windows 10 and try to clone a repository.
When I use the command: git clone username#hostname, I get:
ssh: Could not resolve hostname stbcmgit: Name or service not known
However, when I use a direct IP address instead of the hostname (git clone username#x.x.x.x), the access is successful and the clone starts.
Notes:
"known_hosts" file is located at c:\Users\myname\.ssh
The file is taken from my Linux account where everything works fine there.
The .ssh folder contains also the id_rsa and id_rsa.pub keys (copied also from Linux).
When I use 'ls $HOME/.ssh', I see these files listed.
Using Windows 10.
Thanks.
You should check /etc/hosts and add such a line if it doesn't exist:
x.x.x.x hostname
If the host's IP doesn't change, you can simplify the whole command by creating $HOME/.ssh/config like this
Host YourHost
HostName x.x.x.x
User username
IdentityFile ~/.ssh/id_rsa
PubKeyAuthentication yes
Now you can run these commands:
git clone YourHost:repo
ssh YourHost
In Windows 10 and after the latest updates concerning the "Windows Subsystem for linux" aka "Bash" now you MUST assign any desired hostname with its relative IP Address by editing this file:
C:\Windows\System32\drivers\etc\hosts
P.S: on your linux please check /etc/hosts and not the 'known_hosts' file
~/.ssh/config may contain such definitions.
These definitions contain port numbers also (I think /etc/hosts can't).

ssh specify default directory to check

Instead of ssh "~/.ssh/somekey.pem" ubuntu#somehost, is there a way to make ssh auto check the ~/.ssh directory for keys so that I can simply do ssh "somekey.pem" ubuntu#somehost (i.e. omitting ~/.ssh)?
If you're using the same host then try updating your ~/.ssh/config file with the host info
Host dev
IdentityFile ~/.ssh/github.key
HostName dev.example.com
Port 22000
User fooey
then just type ssh dev to ssh in!

Make a parameter subsitution in bash aliases for ssh

Is there a way I can create a alias for this command and have it ask for the host.
ssh -i .ssh/name.pem root#
Thx
Something like the following should work (not tested)
sshfunction(){
echo "Specify your hostname:"
read host
ssh -i .ssh/name.pem root#"$host"
}
Then:
$ sshfunction
Though if it was me, I'd just provide the hostname as a variable and cut-out the middle man.
Better yet, populate your ~/.ssh/config file (if it doesn't exist you can just create it):
host MyHostName
Hostname 123.456.7.89
User username
Then:
$ ssh MyHostName

Resources