mirror of
https://github.com/anatolykopyl/sshukh.git
synced 2026-06-14 22:44:11 +00:00
Fixed behaviour when using ssh config alias
This commit is contained in:
12
README.md
12
README.md
@@ -1,4 +1,5 @@
|
|||||||
# sshukh zsh plugin
|
# sshukh zsh plugin
|
||||||
|
|
||||||
*SSH Update Known Hosts*
|
*SSH Update Known Hosts*
|
||||||
|
|
||||||
Prompts to update `known_hosts` file for you if needed.
|
Prompts to update `known_hosts` file for you if needed.
|
||||||
@@ -6,25 +7,33 @@ Prompts to update `known_hosts` file for you if needed.
|
|||||||
## Installation:
|
## Installation:
|
||||||
|
|
||||||
**With Oh-my-zsh:** run the following command:
|
**With Oh-my-zsh:** run the following command:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ git clone https://github.com/anatolykopyl/sshukh.git $HOME/.oh-my-zsh/custom/plugins/sshukh
|
$ git clone https://github.com/anatolykopyl/sshukh.git $HOME/.oh-my-zsh/custom/plugins/sshukh
|
||||||
```
|
```
|
||||||
|
|
||||||
**With Antigen:** add the following to your `.zshrc`:
|
**With Antigen:** add the following to your `.zshrc`:
|
||||||
|
|
||||||
```
|
```
|
||||||
antigen bundle anatolykopyl/sshukh
|
antigen bundle anatolykopyl/sshukh
|
||||||
```
|
```
|
||||||
|
|
||||||
To always use with ssh (recommended) add this alias to your `.zshrc`:
|
To always use with ssh (recommended) add this alias to your `.zshrc`:
|
||||||
|
|
||||||
```
|
```
|
||||||
alias ssh='sshukh'
|
alias ssh='sshukh'
|
||||||
```
|
```
|
||||||
|
|
||||||
Zsh may tell you that the plugin is disabled until permissions are fixed. Just run the command it suggests.
|
Zsh may tell you that the plugin is disabled until permissions are fixed. Just run the command it suggests.
|
||||||
|
|
||||||
```
|
```
|
||||||
$ compaudit | xargs chmod g-w,o-w
|
$ compaudit | xargs chmod g-w,o-w
|
||||||
```
|
```
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
Let's connect to an ip that changed hosts:
|
Let's connect to an ip that changed hosts:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ sshukh pi@192.168.1.54
|
$ sshukh pi@192.168.1.54
|
||||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
@@ -45,4 +54,5 @@ Update known_hosts? [y/n] y
|
|||||||
/Users/akopyl/.ssh/known_hosts updated.
|
/Users/akopyl/.ssh/known_hosts updated.
|
||||||
Original contents retained as /Users/akopyl/.ssh/known_hosts.old
|
Original contents retained as /Users/akopyl/.ssh/known_hosts.old
|
||||||
```
|
```
|
||||||
There is a prompt asking if you want to remove the conflicting host from `known_hosts` and upon answering `y` ssh reruns automatically successfully.
|
|
||||||
|
There is a prompt asking if you want to remove the conflicting host from `known_hosts` and upon answering `y` ssh reruns automatically successfully.
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
# Description
|
# Description
|
||||||
# -----------
|
# -----------
|
||||||
#
|
#
|
||||||
# User will be prompted if they want to update known_hosts if ssh errors out
|
# User will be prompted if they want to update known_hosts if ssh errors out
|
||||||
# with "Host key verification failed."
|
# with "Host key verification failed."
|
||||||
#
|
#
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
@@ -13,18 +13,130 @@
|
|||||||
#
|
#
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
sshukh () {
|
# OpenSSH prints "<keytype> host key for <host> has changed." — use that host
|
||||||
output=$(\ssh "$@" 2>&1 | tee /dev/tty)
|
# for ssh-keygen -R (correct for SSH config Host aliases that resolve to IPs).
|
||||||
error=$(echo $output | tail -1)
|
_sshukh_offending_host_from_output() {
|
||||||
if [[ "$error" == "Host key verification failed."* ]]; then
|
print -r -- "$1" | command grep -E -m1 ' host key for .+ has changed' | command sed -E 's/.* host key for ([^ ]+) has changed.*/\1/'
|
||||||
host=$(cut -d'@' -f2 <<< $1)
|
}
|
||||||
while true; do
|
|
||||||
read yn"?Update known_hosts? [y/n] "
|
# Walk ssh argv like ssh(1): options first, then destination [command ...].
|
||||||
case $yn in
|
# Sets _sshukh_prefix (options only) and _sshukh_dest (user@host or alias).
|
||||||
[Yy]* ) ssh-keygen -R $host && \ssh "$@"; break;;
|
_sshukh_split_ssh_args() {
|
||||||
[Nn]* ) break;;
|
local i a
|
||||||
* ) echo "Please answer y or n.";;
|
local -a args
|
||||||
esac
|
args=("$@")
|
||||||
done
|
_sshukh_prefix=()
|
||||||
fi
|
_sshukh_dest=""
|
||||||
|
|
||||||
|
i=1
|
||||||
|
while (( i <= $#args )); do
|
||||||
|
a="${args[i]}"
|
||||||
|
case $a in
|
||||||
|
--)
|
||||||
|
_sshukh_prefix+=("$a")
|
||||||
|
(( i++ ))
|
||||||
|
(( i <= $#args )) || return 1
|
||||||
|
_sshukh_dest="${args[i]}"
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
-[46AaCfGgKkMNnqsTtVvXxYy])
|
||||||
|
_sshukh_prefix+=("$a")
|
||||||
|
;;
|
||||||
|
-v*)
|
||||||
|
_sshukh_prefix+=("$a")
|
||||||
|
;;
|
||||||
|
-B|-b|-c|-E|-e|-F|-I|-i|-J|-L|-l|-m|-O|-P|-p|-Q|-R|-S|-W|-w)
|
||||||
|
_sshukh_prefix+=("$a")
|
||||||
|
(( i++ ))
|
||||||
|
(( i <= $#args )) || return 1
|
||||||
|
_sshukh_prefix+=("${args[i]}")
|
||||||
|
;;
|
||||||
|
-D)
|
||||||
|
_sshukh_prefix+=("$a")
|
||||||
|
(( i++ ))
|
||||||
|
(( i <= $#args )) || return 1
|
||||||
|
_sshukh_prefix+=("${args[i]}")
|
||||||
|
;;
|
||||||
|
-D*|-B*|-b*|-c*|-E*|-e*|-F*|-I*|-i*|-J*|-L*|-l*|-m*|-O*|-P*|-p*|-Q*|-R*|-S*|-W*|-w*)
|
||||||
|
_sshukh_prefix+=("$a")
|
||||||
|
;;
|
||||||
|
-o)
|
||||||
|
_sshukh_prefix+=("$a")
|
||||||
|
(( i++ ))
|
||||||
|
(( i <= $#args )) || return 1
|
||||||
|
_sshukh_prefix+=("${args[i]}")
|
||||||
|
;;
|
||||||
|
-o*)
|
||||||
|
_sshukh_prefix+=("$a")
|
||||||
|
;;
|
||||||
|
-*)
|
||||||
|
_sshukh_prefix+=("$a")
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
_sshukh_dest="$a"
|
||||||
|
return 0
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
(( i++ ))
|
||||||
|
done
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Hostnames to try with ssh-keygen -R: offending line from ssh, then config
|
||||||
|
# alias / canonical names from ssh -G (covers known_hosts under IP vs name).
|
||||||
|
_sshukh_hosts_for_keygen() {
|
||||||
|
local output h stripped dest canon hostpat gout
|
||||||
|
output="$1"
|
||||||
|
shift
|
||||||
|
|
||||||
|
typeset -U hosts
|
||||||
|
hosts=()
|
||||||
|
|
||||||
|
h=$(_sshukh_offending_host_from_output "$output")
|
||||||
|
[[ -n "$h" ]] && hosts+=("$h")
|
||||||
|
|
||||||
|
if _sshukh_split_ssh_args "$@"; then
|
||||||
|
dest="$_sshukh_dest"
|
||||||
|
stripped="${dest#*@}"
|
||||||
|
[[ "$stripped" == "$dest" ]] && stripped="$dest"
|
||||||
|
[[ -n "$stripped" ]] && hosts+=("$stripped")
|
||||||
|
|
||||||
|
gout=$(\ssh -G "${_sshukh_prefix[@]}" "$dest" 2>/dev/null) || gout=""
|
||||||
|
if [[ -n "$gout" ]]; then
|
||||||
|
canon=$(print -r -- "$gout" | command awk '/^hostname / { print $2; exit }')
|
||||||
|
hostpat=$(print -r -- "$gout" | command awk '/^host / { print $2; exit }')
|
||||||
|
[[ -n "$canon" ]] && hosts+=("$canon")
|
||||||
|
[[ -n "$hostpat" ]] && hosts+=("$hostpat")
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
print -rl -- "${hosts[@]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
sshukh () {
|
||||||
|
local output error host
|
||||||
|
|
||||||
|
output=$(\ssh "$@" 2>&1 | tee /dev/tty)
|
||||||
|
error=$(print -r -- "$output" | tail -n1)
|
||||||
|
|
||||||
|
if [[ "$error" != *"Host key verification failed"* ]]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
read yn"?Update known_hosts? [y/n] "
|
||||||
|
case $yn in
|
||||||
|
[Yy]* )
|
||||||
|
while IFS= read -r host; do
|
||||||
|
[[ -z "$host" ]] && continue
|
||||||
|
\ssh-keygen -R "$host" 2>/dev/null
|
||||||
|
done < <(_sshukh_hosts_for_keygen "$output" "$@")
|
||||||
|
|
||||||
|
\ssh "$@"
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
[Nn]* ) break;;
|
||||||
|
* ) echo "Please answer y or n.";;
|
||||||
|
esac
|
||||||
|
done
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user