我有一台防火墙后面的机器。 我用一个端口通过ssh进行VPN隧道远程连接。 要连接到本机,我使用VPN的外部IP以及我的个人和临时指定的端口。 我使用的命令是:
ssh USER@VPN_IP -p PORT
由于VPN_IP和PORT频繁更改,我无法获得将主机密钥保存在known_host优势,以摆脱人为中间人攻击,但同时主机密钥对我来说是众所周知的,我可以将其提供给ssh,以便将其用于当前的VPN_IP和PORT组合。 那可能吗? 怎么样?
known_hosts文件是用来提供这些密钥的,没有直接的命令行select(反正它也不会那么方便)。 但是,您的目标完全可能与known_hosts文件!
通读man sshd的ssh_known_hosts文件格式 。
当进行主机authentication时,如果任何匹配的线路具有正确的密钥,则接受authentication; 要么是完全匹配的,要么是,如果服务器已经提交了用于authentication的证书,则为签名证书的证书颁发机构的密钥。
可以在~/.ssh/known_hosts (和/etc/ssh/ssh_known_hosts )中使用通配符:
这些文件中的每行都包含以下字段:标记(可选),主机名,密钥types,base64编码密钥,注释。 这些字段由空格分隔。
主机名是逗号分隔的模式列表(
*和?充当通配符); 每个模式依次与规范主机名(在对客户端进行身份validation时)或用户提供的名称(在对服务器进行身份validation时)进行匹配。 一个模式也可能在之前!以表示否定:如果主机名称与否定模式相匹配,即使与线路上的其他模式匹配,也不会被该线路接受。 主机名或地址可以select性地包含在[和]括号内,然后是“:”和一个非标准的端口号。
有可能做出一个值得信赖的关键
networking范围,如果已知,例如对于TEST-NET-2 :
198.51.100.* ssh-rsa AAAAB3Nza...2iQ==
多个范围(例如所有TEST-NET )使用逗号分隔列表:
192.0.2.*,198.51.100.*,203.0.113.* ssh-rsa AAAAB3Nza...2iQ==
甚至连接任何地方时:
* ssh-rsa AAAAB3Nza...2iQ==
如果此键不存在,如果您回答yes ,它仍然会提醒您其他键的真实性,显示指纹并自动添加。 比较是逐行完成的。
使用Esa Jokinen的有用答案和自动化过程在这里我的解决scheme:
#!/bin/sh previous_IP_OR_known_host_key_line=$1 current_IP=$2 user=$3 port=$4 #random extension to avoid collision by multiple script execution temp_file="/tmp/temp_host_file.$(hexdump -n 2 -e '/2 "%u"' /dev/urandom)" if [ "$(echo "$previous_IP_OR_known_host_key_line"|wc -w)" -gt 1 ]; then echo "$previous_IP_OR_known_host_key_line"|sed "s/^[^ ]*/$current_IP/">"$temp_file" else ssh-keygen -F "$previous_IP_OR_known_host_key_line"|grep -v "^#"|sed "s/^[^ ]*/$current_IP/">"$temp_file" fi ssh "$user"@"$current_IP" -p "$port" -o UserKnownHostsFile="$temp_file" rm "$temp_file"
该脚本生成一个临时的known_host文件提供给ssh。 脚本需要以下参数(按照顺序):
– 机器在之前接受的连接中具有的目标IP,或相应的RAW行与来自known_host文件的密钥。
– 当前的IP(在VPN /防火墙之后)。
-用户。
-港口。