Pages

Showing posts with label SSH. Show all posts
Showing posts with label SSH. Show all posts

Wednesday, 20 February 2019

Easily SCP/Rsync through bastion host or SCP/Rsync through multiple hops

Often we work in environment where we need to copy files or directories from a local system to another server that can be accessed only through a Bastion host. In such cases, typically we transfer from local machine to Bastion and from Bastion to the intended server. This is time consuming, repetitive and unreliable too. There are many ways you can make this automated. I found a way to get this done through SSH tunneling. Here's how it works:

There are 3 machines involved here:
  1. localhost
  2. Bastion host
  3. Intended server

1. Create an SSH tunnel from localhost to the intended host through bastion. The tunnel will be created from port 1234 at localhost. You may choose any other port.
ssh -L 1234:<intended_server>:22 <user>@<bastion-host> cat -
2. In a new tab initiate the file/directory transfer using the tunnel port
scp -P 1234 <file_to_transfer> <user_of_intended_server>@127.0.0.1:~/

As I did this, I realized SCP is very slow in getting the transfer done due to its linear and sequential file transfer behavior. Hence, I used Rsync which made it pretty fast due to its delta based transfer algorithm

rsync -avz -e "ssh -p 1234" <file_to_transfer> <user_of_intended_server>@127.0.0.1:~/

Saturday, 9 February 2019

Copying ssh keys easily

I use VMs/Vagrant a lot in my day work for all sysadmin/devops automation. One of the problems that I always face with the systems is to authorize my server for the 1st time with my master host. If I am using 10 VMs I need to authorize them 10 times? I wrote a small script to automate this process:

  1. Create a "list" file and add all IPs and hostnames for the VMs in it.
  2. Create a "password" file to write your SSH password in it, you may choose to write the password in the bash, however I feel this gives me the flexibility to add the bash to my source code if need by putting password file in a.gitignore
  3. Next create a shell script that will read the IP addresses and the hostnames from the "list" file and password/s from the password file(I generally keep the same password for all VMs for simplicity)
  4. Remember 2 commands are useful here ssh-copy-ip and ssh-keyscan. Here's how you use them:
 
    ssh-keyscan -H <IP> >> ~/.ssh/known_hosts                                                                                                                                
    sshpass -f <password> ssh-copy-id -i ~/.ssh/id_rsa.pub <USER>@<IP>                                                                                                      
The ssh-keyscan command command is for gathering the public ssh host key of a VM host specified. After collecting the publich ssh-key it adds it to your localhost. You can verify this by checking the contents of "~/.ssh/known_hosts"

The ssh-copy-id command copies the public key of your default identity (otherwise use -i identity_file for other identities) to the remote host. You can verify this by checking the content on ~/.ssh/authorized_keys in the VM host.

The final script looks like this with a loop:

#!/bin/bash                                                                                                                                                                 
user="vagrant"                                                                                                                                                              
for ip in `cat ./list`; do                                                                                                                                                  
    ssh-keyscan -H $ip >> ~/.ssh/known_hosts                                                                                                                                
    sshpass -f password.txt ssh-copy-id -i ~/.ssh/id_rsa.pub $user@$ip                                                                                                      
done 


That's how my "list" file looks like:



consul-server1                                                                                                                                                              
consul-server2                                                                                                                                                              
bootstrap-server1                                                                                                                                                           
client1                                                                                                                                                                     
client2                                                                                                                                                                     
client3                                                                                                                                                                     
client4                                                                                                                                                                     
client5                                                                                                                                                                     
192.168.3.111                                                                                                                                                               
192.168.3.112                                                                                                                                                               
192.168.3.121                                                                                                                                                               
192.168.3.151                                                                                                                                                               
192.168.3.152                                                                                                                                                               
192.168.3.153                                                                                                                                                               
192.168.3.154                                                                                                                                                               
192.168.3.155                                                                                                                                                               

I purposely add IP as well as hostname as I keep using them interchangeably. I also came to know about ansible authorized_keys module that does the ssh-copy-id task:
- name: Set authorized key for user ubuntu copying it from current user
  authorized_key:
    user: ubuntu
    state: present
    key: "{{ lookup('file', lookup('env','HOME') + '/.ssh/id_rsa.pub') }}"
However, you will still need the the ssh-keyscan here. This script goes handy for ops who keep destroying their local environment and use a new one.This is available on Github: https://github.com/iamrawtion/ansible-autossh