Created
January 28, 2023 01:10
-
-
Save syonfox/bf51638d0e7b28148264b326e1ca4720 to your computer and use it in GitHub Desktop.
Managing your SSH config can be a hassle, but with the new lib_ssh_config library, it's never been easier. This powerful library allows you to create, delete, and add hosts to your SSH config file with just a few simple commands. With built-in safety features like automatic backups and user prompts, you can rest easy knowing your data is safe. I…
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
######################################################################################################################## | |
# This function will check if the ssh config file located at ~/.ssh/config exists. If it does not exist, it will create | |
# it and write some default content and settings to it. It will also set the correct permissions for the ssh config file | |
# to be user readable and writable, but not writable by others (700 for the .ssh directory, and 600 for the config file). | |
# This function can be used to initialize a new ssh config file if one doesn't already exist, or to reset the config file | |
# to default settings. | |
######################################################################################################################## | |
#A function to initialize an ssh config file with basic settings and permissions | |
#Inputs: None | |
#Outputs: None, creates or modifies a file at ~/.ssh/config with basic settings and permissions | |
#Side Effects: creates or modifies a file at ~/.ssh/config, creates a directory at ~/.ssh if it doesn't exist | |
######################################################################################################################## | |
function ssh_config_init() { | |
# check if ssh config file exists | |
if [ -f ~/.ssh/config ]; then | |
read -p "Config already exists, do you want to delete it? (y/n) " choice | |
case "$choice" in | |
y|Y ) rm ~/.ssh/config;; | |
n|N ) echo "Aborting config initialization."; return;; | |
* ) echo "Invalid input. Aborting config initialization."; return;; | |
esac | |
fi | |
touch ~/.ssh/config | |
chmod 700 $HOME/.ssh | |
chmod 600 $HOME/.ssh/config | |
cat >> ~/.ssh/config << EOF | |
# SSH Config configuration details https://www.ateam-oracle.com/post/simplify-your-day-with-ssh-config-file-entries-and-self-closing-tunnels | |
# | |
# Host, an alias for the entry | |
# User, the expected and always present opc user | |
# Hostname, the address to the host you want to connect to | |
# Port, the ssh port | |
# IdentityFile, the location of your private keyfile | |
# UseKeychain, if your ssh key have a password you only need to enter it the first time and then it will be saved in the macos keychain or Gnome keyring | |
# ProxyJump, describes the chain of hosts to connect via (jump through) to get to the remote host. Multiple hosts can be specified separated by a comma. ProxyJump is a simplification of the older ProxyCommand. | |
# LocalForward, the directive on what port to forward to your local machine from the remote host. | |
# ie. LocalForward 9906 127.0.0.1:3306 # This will forward all local port 9906 traffic to port 3306 on the remote database.example.com server, | |
# letting me point my desktop GUI to localhost (127.0.0.1:9906) and have it behave exactly as if I had exposed port 3306 on the remote server | |
# and connected directly to it. | |
# $HOME/.ssh/config | |
# | |
# Permissions: User R/W, NOT Writable by others | |
# chmod 700 $HOME/.ssh | |
# chmod 600 $HOME/.ssh/config | |
# First some generic settings that applies to all specific hosts below unless specified otherwise | |
Host * | |
IdentityFile ~/.ssh/id_rsa | |
ServerAliveInterval 240 | |
ServerAliveCountMax 2 | |
TCPKeepAlive yes | |
# Examples of additional settings: | |
# Host myserver | |
# Hostname example.com | |
# Port 22 | |
# User myusername | |
# IdentityFile ~/.ssh/id_rsa_myserver | |
# ServerAliveInterval 240 | |
# ServerAliveCountMax 2 | |
# TCPKeepAlive yes | |
# UseKeychain yes | |
EOF | |
} | |
######################################################################################################################## | |
#This function is used to delete a specific "Host" block in the ssh config file, based on the provided hostname. | |
#It first creates a backup of the original config file to ensure data safety, then creates a new config file with | |
#the desired "Host" block removed, and finally overwrites the original config file with the new config file. | |
#Inputs: | |
#host_name (string): the name of the host to delete from the ssh config file | |
#Outputs: | |
#None, creates a new file at ~/.ssh/config.new with the host removed and backs up the original file to ~/.ssh/config.bak | |
#Side Effects: | |
#Modifies the original ssh config file by creating a new file with the host removed and backing up the original file | |
######################################################################################################################## | |
ssh_config_delete_host() { | |
if [ -z "$1" ]; then | |
echo "Error: hostname not provided." | |
return | |
fi | |
host_name=$1 | |
if [ -f ~/.ssh/config ]; then | |
cp ~/.ssh/config ~/.ssh/config.$(date +%FT%T).bak | |
awk ' | |
/^Host $host_name$/ { | |
while (getline && $0 !~ /^Host/) {} | |
} | |
{ print } | |
' ~/.ssh/config > ~/.ssh/config.new | |
mv ~/.ssh/config.new ~/.ssh/config | |
else | |
echo "Error: ssh config file not found" | |
fi | |
} | |
######################################################################################################################## | |
# This function is used to delete a specific "Host" block in the ssh config file. It first makes a backup of the original | |
# config file to config.data.bak, then creates a new config file with the desired "Host" block removed, and finally | |
# overwrites the original config file with the new config file. | |
#A function to delete a specific host from an ssh config file | |
#Inputs: host_name, the name of the host to delete from the ssh config file | |
#Outputs: None, creates a new file at ~/.ssh/config.new with the host removed and backs up the original file to ~/.ssh/config.bak | |
#Side Effects: modifies the original ssh config file by creating a new file with the host removed and backing up the original file | |
######################################################################################################################## | |
ssh_config_delete_host() { | |
if [ -z "$1" ]; then | |
echo "Error: host_name argument not set" | |
return | |
fi | |
host_name="$1" | |
if [ -f ~/.ssh/config ]; then | |
cp ~/.ssh/config ~/.ssh/config.$(date +%FT%T).bac | |
awk -v host_name="$host_name" ' | |
$1 == "Host" && $2 == host_name { | |
while (getline && $0 !~ /^Host/) {} | |
} | |
{ print } | |
' ~/.ssh/config > ~/.ssh/config.new | |
mv ~/.ssh/config.new ~/.ssh/config | |
else | |
echo "Error: ssh config file not found" | |
fi | |
} | |
######################################################################################################################## | |
# Append a host to the sshconfig with | |
# inputs: hostname user ip port port1 port2 ...portn with each port allowing a singler number or remote:local | |
# out`puts: appends ssh config and creates it if necessary, if there is already a config with the hostname ask user if they want overwrite rename or cancel | |
# after this is ran you should be able to run ssh hostname. | |
# @example ssh_config_host goat root 1.2.3.4 4222 5432 80:6047 3000 proxy1 proxy2 proxyn 1234:2222 | |
# | |
######################################################################################################################## | |
ssh_config_add_host() { | |
# assign input variables | |
host_name=$1 | |
user=$2 | |
ip=$3 | |
port=$4 | |
args=("${@:5}") | |
# check if ssh config file exists | |
if [ ! -f ~/.ssh/config ]; then | |
ssh_config_init | |
fi | |
# check if hostname already exists in ssh config | |
if grep -q "^Host $host_name" ~/.ssh/config; then | |
# prompt user to overwrite, rename, or cancel | |
read -p "Host $host_name already exists in ssh config. Overwrite, rename, or cancel? [o/r/c] " choice | |
case $choice in | |
o) | |
# overwrite existing hostname | |
ssh_config_delete_host $host_name | |
;; #it deletes the entire block of the ssh config for the hostname passed as an argument. It doesn't delete only the first line but the entire block of configs for that hostname. | |
r) | |
# prompt user for new hostname | |
read -p "Enter new hostname: " new_hostname | |
host_name=$new_hostname | |
;; | |
c) | |
# cancel operation | |
echo "Cancelled operation." | |
return | |
;; | |
esac | |
fi | |
echo "Host $host_name" >> ~/.ssh/config | |
echo " User $user" >> ~/.ssh/config | |
echo " HostName $ip" >> ~/.ssh/config | |
echo " Port $port" >> ~/.ssh/config | |
# append ports | |
for arg in "${args[@]}"; do | |
echo "handeling remaining arg: $arg" | |
if [[ $arg =~ ^[0-9]+([:][0-9]+)?$ ]]; then | |
local_port=$(echo $arg | cut -d: -f1) | |
remote_port=$(echo $arg | cut -d: -f2) | |
echo "Valid number or number:number format $local_port -> $remote_port" | |
echo " LocalForward $host_name:$local_port localhost:$remote_port" >> ~/.ssh/config | |
# echo "Valid number or number:number format" | |
# echo " LocalForward $host_name:$local_port localhost:$remote_port" >> ~/.ssh/config | |
else | |
echo "Invalid number or number:number format assuming this is a proxyJump definitions" | |
echo " ProxyJump $arg" >> ~/.ssh/config | |
fi | |
done | |
#todo make sure the proxyJump is valid. | |
# if [[ $1 =~ ^[a-zA-Z0-9_]+@[a-zA-Z0-9_]+([:][0-9]+)?$ ]]; then | |
# echo "Valid ProxyJump" | |
# else | |
# echo "Invalid ProxyJump" | |
# fi | |
# | |
# if ssh -q -o ConnectTimeout=5 -o BatchMode=yes -o StrictHostKeyChecking=no -o ProxyJump="$1" -o LogLevel=ERROR exit; then | |
# | |
# echo "Valid ProxyJump" | |
# | |
# else | |
# | |
# echo "Invalid ProxyJump" | |
# | |
# fi | |
} | |
function test_lib_ssh_config() { | |
mv ~/.ssh/config ~/.ssh/config.test.bac | |
# Initialize the ssh config file | |
ssh_config_init | |
cat ~/.ssh/config | |
# Add some hosts to the ssh config file | |
ssh_config_add_host "host1" "user" "host1.com" 22 | |
cat ~/.ssh/config | |
ssh_config_add_host "host2" "user" "host2.com" 4222 host1 | |
cat ~/.ssh/config | |
ssh_config_add_host "host3" "user" "host3.com" 4222 5432 88:8888 | |
cat ~/.ssh/config | |
# Delete a host from the ssh config file | |
ssh_config_delete_host "host2" | |
cat ~/.ssh/config | |
ssh_config_add_host "host3" "user" "host3.com" 4222 5432 "host2" 55:1234 host1 | |
# Confirm that the host was deleted | |
cat ~/.ssh/config | |
mv ~/.ssh/config.test.bac ~/.ssh/config | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment