ssh 转发

目录

关于ssh的一些参数

关于ssh config 一些参数

关于主机验证 

关于限制转发和登录的一些参数

ssh-agent --身份验证代理连接的转发

使用场景

ssh 代理

正向代理 - 本地端口代理转发  LocalForward(-L) 

使用场景  (外部访问内部服务)

关于VPN --多个LocalForward 转发的集合

反向代理 -远端启动端口代理转发  RemoteForward(-R)

使用场景  (外部访问内部服务)

本地 socks5 代理-动态端口转发 DynamicForward(-D)

使用场景  (使用网络代理请求)

autossh

自动跳转多个中间机器   - ProxyJump (-J) 与 ProxyCommand   用于通过中间机器 来跳 转目的主机

使用场景(目的主机需要多次登录调整,或者本机到目的主机网络限制,不能直接连接)

在配置文件中配置

关于ssh的一些其他安全配置 

参阅:


OpenSSH_7.4p1, OpenSSL 1.0.2k-fips  26 Jan 2017
CentOS Linux release 7.4.1708 (Core) 

关于ssh的一些参数

#https://man7.org/linux/man-pages/man1/ssh.1.html
ssh [-D [bind_address:]port]  [-L address]  [-R address]  ······

-A        启用代理验证转发,可以在配置文件中配置,登录会生成保留登录信息的文件 类似于ssh-agent
-a      禁用代理验证转发
-D         用于在 SSH 连接上创建动态端口转发(Dynamic Port Forwarding)
-F        系统默认配置文件/etc/ssh/ssh_config,用户默认配置文件~/.ssh/config.
-f        转到后台,转发后可以放后台执行
-G        命令用于显示Host和Match配置信息,但不会连接到远程主机
-g        允许远程主机连接到本地转发端口。
-J         命令用于指定跳板主机(jump host)
-t        检查配置文件的语法是否正确 等同于ProxyJump配置指令
-L        本地监听一个端口,转发数据到远程主机 ,默认使用GatewayPorts 启用远程访问
-M        ControlMaster通路复用共享会话 no(默认值),其他的参数还有(-S ControlPath) ControlPersist
-N        不执行远程命令。这仅适用于转发端口。不加-N则直接登录进去
-n        阻止从stdin读取,拒绝交互操作批量执行远程命令时非常有用,ssh -n  hosta "telnet hostb 80"
-O        控制-M 命令,有check、forward、cancel、exit 等
-o        配置文件参数以命令行格式体现,临时使用非常有用
-q        安静模式
-R        与-L 相反,远程主机上给定TCP端口或Unix socket转发到本地,可以是本地动态端口,与-O forward 连用会打印到标准输出
-T        禁用伪终端分配。
-v        调试消息详细模式 -vv -vvv,
-W         本地和远程主机之间的网络流量转发到另一个地址和端口。ssh -W <destination_address>:<destination_port> user@example.com
-w         创建一个 IP 层隧道,允许将网络流量通过 SSH 连接从一个主机转发到另一个主机。类似vpn通道ssh -f -w 0:1 192.168.1.15 true

关于ssh config 一些参数

(存在可能因版本问题造成的参数不可用)

#https://man7.org/linux/man-pages/man5/ssh_config.5.html
读取文件顺序
    1.   command-line options
    2.   user''s configuration file (~/.ssh/config)
    3.   system-wide configuration file (/etc/ssh/ssh_config)
    
Host                #配置主机之后添加特定的配置
Match                #匹配自定义条件后(如canonical, exec, host, originalhost, user, and localuser)    添加特定的配置
AddKeysToAgent      #密钥自动添加ssh-agent中,no (the default) 
AddressFamily        #允许是使用的ip地址,  IPv4 or IPv6 or any
BatchMode            #yes:不会打印密码短语/密码查询,方便无交互模式下,no (the default).
CanonicalDomains    #类似别名功能
CanonicalizeHostname             #别名开关
CanonicalizePermittedCNAMEs        #类似域名的泛解析
CertificateFile     #密钥路径
CheckHostIP            #yes(the default).一般会检查~/.ssh/known_hosts 并添加,不受StrictHostKeyChecking影响
ClearAllForwardings #no (the default).是否清除所有已存在的端口转发设置
Compression            #是否压缩 no (the default)
ConnectionAttempts    #连接重试
ConnectTimeout        #连接超时
ControlMaster        #ssh复用 no (the default)
ControlPath            #会话信息存储路径
ControlPersist        #ssh复用时间,no不会放后台,yes永久,时间:复用有效期时间
DynamicForward        #-D 用于在 SSH 连接上创建动态端口转发[bind_address:]port,默认可以GatewayPorts 启用远程访问 
ExitOnForwardFailure            #遇到错误或无法成功建立端口转发,则会立即退出 SSH 连接
ForwardAgent        #启用 SSH 代理的转发功能,无需将密钥直接传输到远程服务器
GatewayPorts        #no (the default). 默认不允许远程访问
GSSAPIAuthentication            #可以理解为基于api验证
HostbasedAuthentication            #no (the default).   基于主机的验证,通常情况公钥验证或其他更安全的身份验证方法会更可取。
HostKeyAlias        #除了hosts中定义别名,也可以使用他来定义别名
HostName            #-h 真实主机名
IdentityAgent         #缓存登录信息,类似ControlPath
Include                #nclude the specified configuration file(s)
KbdInteractiveAuthentication     #键盘交互式身份验证进行用户身份验证:yes (the default)
LocalCommand        #~/.ssh/config 执行本地命令(非交互) 还支持ssh转义命令
LocalForward        # -L 本地监听一个端口,转发数据到远程主机
NoHostAuthenticationForLocalhost# no(the default). 是否对本地回环地址(localhost)进行主机身份验证
PasswordAuthentication             #yes (the default) 是否允许使用密码进行 SSH 认证
PermitLocalCommand    #no (the default)  控制LocalCommand 生效
PreferredAuthentications        #验证顺序  默认顺序:gssapi-with-mic,hostbased,publickey,keyboard-interactive,password
ProxyCommand        # ProxyJump是ProxyCommand升级版  ssh -o ProxyCommand="ssh -W %h:%p <jump server>" <remote server>
                    #https://www.cyberciti.biz/faq/linux-unix-ssh-proxycommand-passing-through-one-host-gateway-server/
                    #~/.ssh/config
                    ## sample for ProxyJump
                    ProxyJump user@<jumpserver>
                    ## sample for ProxyCommand
                    ProxyCommand ssh -W %h:%p <jumpserver>
ProxyJump            #-J 命令用于指定一个或者多个跳板主机(jump host)
                    #ssh -J <jump server1>,<jump server2>,<jump server3> <remote server>
PubkeyAuthentication            #是否尝试公钥身份验,yes (the default)
RekeyLimit 1G 1h    #当数据传输量达到 1GB 或连接时间超过 1小时时,SSH 会触发rekeying限制重新生成密钥后恢复连接
RemoteForward        #-R    ,远程主机上给定TCP端口或Unix socket转发到本地,可以是本地动态端口
RequestTTY            # -T -t 
RevokedHostKeys        #吊销的主机密钥 慎用
RhostsRSAAuthentication            #no (the default) 是否尝试使用RSA主机身份验证进行基于 .rhosts 文件的身份验证
RSAAuthentication                #yes (the default) 是否尝试RSA身份验证
SendEnv                #指定应将本地环境中变量发送到服务器
ServerAliveCountMax             #最大重连尝试次数,默认3次
ServerAliveInterval                #重试时间间隔
StrictHostKeyChecking            # ask (the default),在第一次连接远程主机时询问用户是否信任该主机的公钥。
TCPKeepAlive                    #default is yes 启用TCP层级的保持活动状态功能。
Tunnel                #隧道,客户端和服务器之间的设备转发
TunnelDevice        #打开tun的设备,it defaults to any.  The default is any:any
UpdateHostKeys         #no (the default)主机密钥发生变化,客户端将显示警告并拒绝连接
VerifyHostKeyDNS     #额外通过 DNS 来验证主机密钥(Host Key).生产环境中谨慎使用

关于主机验证 

ssh验证过程包含:主机验证和用户身份验证(这里不讨论针对主机和用户的登录限制策略)
[root@tserver121 ~]# ssh 10.3.246.110
The authenticity of host '10.3.246.110 (10.3.246.110)' cant be established.
ECDSA key fingerprint is SHA256:OU+wRDPwaCOrKSEKKrwvlA/sQbjZWCttViD9VEjCtBI.
ECDSA key fingerprint is MD5:6c:94:2b:6f:70:fc:3d:5c:19:9b:8e:f8:0a:ac:d4:a6.

StrictHostKeyChecking        #ask (the default),在第一次连接远程主机时询问用户是否信任该主机的公钥。
CheckHostIP                    #yes(the default).一般会检查~/.ssh/known_hosts 并添加,不受StrictHostKeyChecking影响
HostbasedAuthentication        #no (the default).   基于主机的验证

上述一般情况下主机验证 是没有开启的,所以一般不用太关注~/.ssh/known_hosts的内容,可以看出来上面是采用ECDSA签名算法。在 CentOS 7 上,默认情况下并不支持 Ed25519 密钥算法, ECDSA 优先级大于RSA。

系统默认有密钥对/etc/ssh/ssh_host_*可以直接使用,/etc/ssh/sshd_config 也有对应的配置
[root@tserver121 ~]#  cat /etc/ssh/sshd_config |grep HostKey
HostKey /etc/ssh/ssh_host_rsa_key
#HostKey /etc/ssh/ssh_host_dsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key
所以fingerprint就使用是/etc/ssh/ssh_host_ecdsa_key文件

使用场景
1.除了网络上arping之外, 某种情况下,ssh也能验证是否是同一台机器
[root@tserver120 ~]# hostname -I
10.3.246.110 
[root@tserver120 ~]# ssh-keygen -l -E md5 -f /etc/ssh/ssh_host_ecdsa_key  #和上登录时的指纹是一致的
256 MD5:6c:94:2b:6f:70:fc:3d:5c:19:9b:8e:f8:0a:ac:d4:a6 /etc/ssh/ssh_host_ecdsa_key.pub (ECDSA)

2.验证密钥对是否一致或者 远端机是否添加正确
[root@tserver121 ~]#  ssh-keygen -l -E md5 -f  /root/.ssh/id_rsa
2048 MD5:70:67:73:5a:33:e4:51:c6:fd:0e:b1:72:73:fb:57:bf root@tserver121 (RSA)
[root@tserver121 ~]#  ssh-keygen -l -E md5 -f  /root/.ssh/id_rsa.pub 
2048 MD5:70:67:73:5a:33:e4:51:c6:fd:0e:b1:72:73:fb:57:bf root@tserver121 (RSA)
[root@tserver121 ~]# ssh 10.3.246.110
Last login: Mon Dec 18 19:53:22 2023 from 10.3.246.108
[root@tserver120 ~]# ssh-keygen -l -E md5 -f /root/.ssh/authorized_keys 
2048 MD5:70:67:73:5a:33:e4:51:c6:fd:0e:b1:72:73:fb:57:bf root@tserver121 (RSA)
 

关于限制转发和登录的一些参数

AllowTcpForwarding、AllowAgentForwarding与ForwardAgent、PermitOpen、Match、ForceCommand

#AllowTcpForwarding  #禁用TCP转发并不能提高安全性 #/etc/ssh/sshd_config
    在OpenSSH服务器的配置文件中,可以设置为以下几种值之一:
        yes:允许TCP连接转发。(默认)
        no:禁止TCP连接转发。
        local:仅允许本地TCP连接转发。
        remote:仅允许远程TCP连接转发。

#AllowAgentForwarding   #/etc/ssh/sshd_config
        yes:允许ssh-agent转发。(默认)
        no:禁止TCP连接转发。
        
#ForwardAgent            #一般在客户端配置中/etc/ssh/ssh_confi  
        yes:启用ssh-agent转发。
        no: 关闭ssh-agent转发。(默认)

#DenyUsers, AllowUsers, DenyGroups, AllowGroup 控制用户、用户组登录
    DenyGroups  hellogroup testgroup  # 表示即拒绝这些组用户连接
    DenyUsers   hello test            # 表示即拒绝这些用户连接
     ~/.rhosts or ~/.shosts 不是必需,最好不要使用这两个文件来控制远程主机访问本地主机

#PermitOpen host:port    #默认情况下,允许所有端口转发请求
#PermitRootLogin         #控制是否允许 root 用户通过 SSH 登录到服务器
        yes:允许root登录。(默认)
        prohibit-password:拒绝密码行验证。
        without-password:拒绝密码行验证。
        forced-commands-only:不允许交互式登录
        no:禁止root登录。
         
GatewayPorts no        #禁止远程访问

#Match                   #添加自定义的匹配配置 偏向系统配置  #/etc/ssh/sshd_config
Match Address 192.168.1.0/24     #ip匹配
   PermitRootLogin yes             #特殊条件

#Host                    #添加自定义主机配置    偏向用户级别 #~/.ssh/config    
        Host t109
          User root
          Port 22
          HostName 10.3.246.109
          
ForceCommand 属于登录后的限制
ForceCommand /bin/bash  或在~/.ssh/authorized_keys对应的rsa public key 前面加上command="/bin/bash"(参考gitlab的/var/opt/gitlab/.ssh/authorized_keys) 效果是等效的。这样就可以实现允许用户远程登录系统,但是scp和rsync命令失效,同时由于限定死了command参数,导致你的非交互式ssh命令也无法使用了,比如ssh user@ip ls /这一类非交互式ssh不起作用了。
ForceCommand internal-sftp  则表示只允许使用sftp,不允许shell登录。如果配置中去掉Subsystem sftp /usr/lib/openssh/sftp-server这一行就可以关闭sftp服务

[root@tserver121 ~]# cat /var/opt/gitlab/.ssh/authorized_keys
command="/opt/gitlab/embedded/service/gitlab-shell/bin/gitlab-shell key-4",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-rsa ·····
 

ssh-agent --身份验证代理连接的转发

 -A        启用代理验证转发,也可以在ssh_config 或者 ~/.ssh/config 中配置ForwardAgent开启 
         登录其他机器后 /tmp/ssh-QJPzmXUEhK  会生成随机文件一般包含一些加密算法、密钥信息、会话ID等。 可以用于使用同样的信息再次登录其他机器不需要再次输入登录信息 类似于ssh代理工具ssh-agent
        ssh-agent 保存用于公钥身份验证的私钥的程序 https://www.man7.org/linux/man-pages/man1/ssh-agent.1.html

使用场景
跳板机 --登录--> 管理多个管理机 --登录--> 管理多个应用服务器
使用密钥登录服务器,但不想把自己的私钥放到管理机(也可以称之为中转机器),提高安全性。
这就可以使用ssh-agent功能了,与-A一样都是启用身份验证代理连接的转发。在远端机器的时候,将本机的登录验证信息抓发给远端机器。

#前提是转发机器都需要开启用SSH代理的转发功能,所有机器都添加了登录用户的公钥
ForwardAgent    yes     #此配置不必要写入到全局配置 可以使用Host或者Match参数去匹配指定服务器
AddKeysToAgent  no      #自动添加到ssh-agent,no (the default) 此参数不用开启

[user@DevOps4JP ~]$ ssh-agent bash                           启动                  
[user@DevOps4JP ~]$ ssh-add ~/.ssh/id_rsa                    添加私钥,输入密钥密码
[user@DevOps4JP ~]$ ssh-add ~/.ssh/id_rsa2                   添加私钥2,输入密钥密码
[user@DevOps4JP ~]$ ssh-add  -l                              查看
[user@DevOps4JP ~]$ ll /tmp/                                 会看到生成个带ssh的缓存目录
[user@DevOps4JP ~]$ ssh 10.3.246.112 -A     连接(管理机)
[root@tserver-mgmt ~]# ssh 10.3.246.108 -A  再连接(管理机1)
[root@tserver121 ~]#  ssh 10.3.246.109 -A   再连接(管理机2) 
[root@tserver118 ~]#   ssh 10.3.246.110     再连接(应用服务器)
当使用 ssh -vvv 参数是 可以看到如下agent中读取登录信息
    key: /home/user/.ssh/id_rsa (0x557675912180), agent
 
优化 
	针对ssh-agent 登录登出,多用户 多终端等匹配不对造成无法登录问题

使用:
    可以将认证程序放置至后台程序,重新登录后自动重新读取会话信息。
    
    
[user@DevOps4JP ~]$ ps -ef |grep agen
user1   731     1  0 Dec14 ?        00:00:00 ssh-agent -s -a /home/user1/.ssh/agent.sock
user2  8862     1  0 May26 ?        00:00:14 ssh-agent -s -a /home/user2/.ssh/agent.sock

优点:可以ssh-agent和密钥自动加载到工作中的每个终端会话中的shell脚本
缺点:用户再次重新登录可以复用,安全性有问题,如果可以接受,也不用添加下面配置(退出关闭ssh-agent,再次登录只需要输一次密码)
# cat ~/.bash_logout
NUM=$(who -u | grep -c "$USER")
if [[ "$SSH_AGENT_PID" != "" ]]; then
   [[ "$NUM" == "1" ]] && eval `/usr/bin/ssh-agent -k`
fi

ssh 代理

10.3.246.108  hostA  (tserver121)
10.3.246.109  hostB  (tserver118)
10.3.246.110  hostC  (tserver120)

正向代理 - 本地端口代理转发  LocalForward(-L) 
命令:-L localport:remotehost:remotehostport sshserver #相当于 iptable 的 port forwarding
说明:localport       本机开启的端口号
      remotehost      最终连接机器的IP地址
      remotehostport       最终连接机器的端口号
      sshserver       转发机器的IP地址
      remotehost 和 sshserver  可以是同一个
选项:-f 后台启用
      -N 不打开远程shell,处于等待状态(不加-N则直接登录进去)
      -g 启用网关功能,允许远程主机连接到本地转发端口。
      -C 为压缩数据
      -q 安静模式
      -T 禁止远程分配终端
      -n 关闭标准输入
使用场景  (外部访问内部服务)

外部hostA想访问内部服务器hostC,但网络不通,但能访问到内部服务器hostB,这时在hostB 上做一个转发(本地启动端口,把本地端口数据转发到远端) 到hostC,这样hostA可以访问到 hostC了

hostB上做转发
[root@hostB ~]# ssh -L 0.0.0.0:22022:hostC:22  -fN root@hostC    #hostB:22022-->hostC:22
[root@hostB ~]# netstat -nlpt  
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:22022           0.0.0.0:*               LISTEN      1450/ssh   
[root@hostA ~]# ssh hostB -p 22022 "hostname"    #请求hostB:22022实际被转发到了hostC:22
hostC

hostA上做转发
[root@hostA ~]# ssh -L 0.0.0.0:22080:hostC:80  -fN root@hostB     #hostA:22080-->hostB:22-->hostC:80
[root@hostA ~]# sudo -u nobody curl http://hostA:22080 -v  
[root@hostC nginx]# cat nginx.log  #在hostC可以看出来 请求是从10.3.246.109(hostB)上发起的
{"host":"10.3.246.110","clientip":"10.3.246.109","size":162,"responsetime":0.000,"upstreamtime":"-","upstreamhost":"-","http_host":"hosta","url":"GET / HTTP/1.1","xff":"-","referer":"-","agent":"curl/7.29.0","status":"403"}


两种用法的区别是
第一种用法hostA 到hostB的数据可以明文的,但不需要ssh到hostB权限,客户端不需要额外配置。
第二种用法hostA ssh加密传输给 hostB 又转发给 hostC:PortC。 但需要ssh到hostB权限
关于VPN --多个LocalForward 转发的集合

sshuttle -r user@remote_ip 10.0.0.0/8
代表将10.0.0.0/8这个网段的请求走SSH代理,是不是很容易使用?
    此外,还支持--dns,--auto-hosts, --auto-nets等十分有用的参数,根据实际情况去选用即可。

sshuttle实际体验上非常类似于VPN,但是比VPN更轻量,而且无需管理。值得注意的是,本质上这个工具是利用了端口转发的原理,并不是真正的VPN,所以对于ICMP这类的协议是没用的,也就是说,对于ping命令是无效的。

反向代理 -远端启动端口代理转发  RemoteForward(-R)
命令:-R [bind_address:]sshserverport:remotehost:remotehostport sshserver  #相当于 frp 或者 ngrok
说明:sshserverport         被转发机器开启的端口号
      remotehost          最终连接机器的IP地址
      remotehostport        最终连接机器的端口号
      sshserver             被转发机器的IP地址
      remotehost 和 sshserver  可以是同一个
选项:-f 后台启用
      -N 不打开远程shell,处于等待状态(不加-N则直接登录进去)
      -g 启用网关功能,允许远程主机连接到本地转发端口。
      -C 为压缩数据
      -q 安静模式
      -T 禁止远程分配终端
      -n 关闭标准输入
使用场景  (外部访问内部服务)

外部hostA 也访问不了内部的hostB 和hostC,但hostB能访问到外部hostA,,这时在hostB 上做一个转发(远端hostA启动端口,把远端端口数据转发到本地。在转发到hostC) ,这样hostC可以访问到 hostA了

[root@hostB ~] ssh -R hostA:11080:hostC:80  -fN  hostA   #hostA:11080-->hostB:22-->hostC:80
[root@hostA ~]# netstat -nlpta|grep ssh               #hostB <-->hostA有一个长连接,并且hostA 有监11080
#GatewayPorts 设置成为yes ,bind_address 就配置成了0.0.0.0:11080  
tcp        0      0 127.0.0.1:11080         0.0.0.0:*               LISTEN      44647/sshd: root      
tcp        0      0 10.3.246.108:22         10.3.246.109:57315      ESTABLISHED 44647/sshd: root   
[root@hostA ~]# sudo -u nobody curl http://127.0.0.1:11080  -v   
[root@hostC nginx]# cat nginx.log  #在hostC可以看出来 请求是从10.3.246.109(hostB)上发起的
{"host":"10.3.246.110","clientip":"10.3.246.109","size":162,"responsetime":0.000,"upstreamtime":"-","upstreamhost":"-","http_host":"127.0.0.1","url":"GET / HTTP/1.1","xff":"-","referer":"-","agent":"curl/7.29.0","status":"403"}
本地 socks5 代理-动态端口转发 DynamicForward(-D)
命令:-D [bind_address:]port  sshserver  #相当于 ss/ssr 
说明:sshserver             被转发机器的IP地址

选项:-f 后台启用
      -N 不打开远程shell,处于等待状态(不加-N则直接登录进去)
      -g 启用网关功能,允许远程主机连接到本地转发端口。
      -C 为压缩数据
      -q 安静模式
      -T 禁止远程分配终端
      -n 关闭标准输入
使用场景  (使用网络代理请求)

外部hostA想访问内部服务器hostC,但网络不通,但能访问到内部服务器hostB,这时在hostB 上做一个转发(创建一个 SOCKS 代理将所有流量通过代理hostB) 到hostC,这样hostA可以通过网络代理的方式访问到 hostC了

[root@hostB ~] ssh -D 0.0.0.0:31080 -fN  hostC       #hostB:31080-->hostC:80
[root@hostB ~]# netstat -nlpta|grep 20860
tcp        0      0 0.0.0.0:31080           0.0.0.0:*               LISTEN      20860/ssh           
tcp        0      0 10.3.246.109:8416       10.3.246.110:22         ESTABLISHED 20860/ssh  
[root@hostA ~]# curl --socks5 hostB:31080  http://hostC:80 -v  #可以多个端口
[root@hostA ~]# curl --socks5 hostB:31080  http://hostC:8888 -v 
[root@hostC nginx]# cat nginx.log  #在hostC可以看出来 请求是从10.3.246.110(hostC)上发起的
{"host":"10.3.246.110","clientip":"10.3.246.110","size":162,"responsetime":0.000,"upstreamtime":"-","upstreamhost":"-","http_host":"hostc","url":"GET / HTTP/1.1","xff":"-","referer":"-","agent":"curl/7.29.0","status":"403"}

autossh

ssh直接做可能会因为网络闪断导致代理失效,如果希望ssh自动重连,可以使用autossh这个小工具,帮我们在ssh断掉之后自动重连,维持代理隧道的稳定。
autossh的使用也十分简单,基本兼容绝大多数ssh参数,像ssh一样用就行,比如:

    autossh -M 0 -R 9999:192.168.1.10:9999 -C -N

自动跳转多个中间机器   - ProxyJump (-J) 与 ProxyCommand   用于通过中间机器 来跳 转目的主机

OpenSSH 版本 7.3 开始支持中间机器可以为多个

10.3.246.108  thostA  
10.3.246.109  thostB  thostE
10.3.246.110  thostC 
10.3.246.112  thostD

ProxyCommand        # ProxyJump是ProxyCommand升级版 
                    # ssh -o ProxyCommand="ssh -W %h:%p <jump server>" <remote server>  SSH 连接时使用的自定义命令
                    # 连接多个中间机器没有ProxyJump方便
                    # ssh -o ProxyCommand="ssh -W %h:%p user1@jump1.example.com 'ssh -W %h:%p user2@jump2.example.com'" user3@target.example.com
                    #https://www.cyberciti.biz/faq/linux-unix-ssh-proxycommand-passing-through-one-host-gateway-server/

ProxyJump            #-J 命令用于指定一个或者多个跳板主机(jump host)
                    #ssh -J <jump server1>,<jump server2>,<jump server3> <remote server>

使用场景(目的主机需要多次登录调整,或者本机到目的主机网络限制,不能直接连接)

虽然ssh-agent能解决ssh复用问题,但不能解决多次跳转登录

在配置文件中配置
#~/.ssh/config
#    # sample for ProxyJump
#    ProxyJump user@<jumpserver>
#    # sample for ProxyCommand
#    ProxyCommand ssh -W %h:%p <jumpserver>
  
Host 10.3.246.108
  Hostname 10.3.246.108
  User root
  ForwardAgent yes
  
Host thostB
  Hostname 10.3.246.109
  User root
  ProxyCommand ssh -W %h:%p 10.3.246.108
  ForwardAgent yes
  
Host thostC
  Hostname 10.3.246.110 
  User root
  ProxyJump 10.3.246.108
  ForwardAgent yes

Host thostE
  Hostname 10.3.246.109 
  User root
  ProxyJump 10.3.246.110,10.3.246.108
  ForwardAgent yes

# 登录测试
[root@thostD ~]# ssh thostC -v                 #ProxyJump 在thostD 登录thostC
OpenSSH_7.4p1, OpenSSL 1.0.2k-fips  26 Jan 2017
debug1: Reading configuration data /root/.ssh/config
debug1: Setting implicit ProxyCommand from ProxyJump: ssh -v -W %h:%p 10.3.246.108
debug1: Executing proxy command: exec ssh -v -W 10.3.246.110:22 10.3.246.108
[root@thostD ~]# ssh thostB -v				   #ProxyCommand 在thostD 登录thostB
OpenSSH_7.4p1, OpenSSL 1.0.2k-fips  26 Jan 2017
debug1: Reading configuration data /root/.ssh/config
debug1: Executing proxy command: exec ssh -W 10.3.246.109:22 10.3.246.108

[root@thostD ~]# ssh thostE -v				   #在thostD 登录thostE(10.3.246.109) 中间多个跳转
debug1: Setting implicit ProxyCommand from ProxyJump: ssh -J 10.3.246.110 -v -W %h:%p 10.3.246.108
debug1: Executing proxy command: exec ssh -J 10.3.246.110 -v -W 10.3.246.109:22 10.3.246.108
debug1: Setting implicit ProxyCommand from ProxyJump: ssh -v -W %h:%p 10.3.246.110
debug1: Executing proxy command: exec ssh -v -W 10.3.246.108:22 10.3.246.110
Authenticated to 10.3.246.110 ([10.3.246.110]:22).
debug1: channel_connect_stdio_fwd 10.3.246.108:22
Authenticated to 10.3.246.108 (via proxy).
debug1: channel_connect_stdio_fwd 10.3.246.109:22
[root@thostE ~]# w
 19:53:18 up 218 days,  1:39,  1 user,  load average: 0.02, 0.02, 0.05
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
root     pts/2    10.3.246.108     19:51    6.00s  0.00s  0.00s w

ssh命令行

 #10.3.246.110 和 10.3.246.108 为中转机。
ssh -J 10.3.246.110,10.3.246.108  10.3.246.109 
ssh -o ProxyCommand="ssh -W %h:%p 10.3.246.110 'ssh -W %h:%p 10.3.246.108'" 10.3.246.109

关于ssh的一些其他安全配置 

https://www.junmajinlong.com/linux/ssh/
ssh 登录一般采用密钥对验证是比较安全的一种验证方式
    默认监听在22端口,不过可以修改或者增加不常见的端口监听
    ssh服务端配置文件为/etc/ssh/sshd_config
    ssh客户端的全局配置文件/etc/ssh/ssh_config

一些安全配置
    #PermitRootLogin no 或者  without-password            # 是否允许root用户登录
    重要的ssh-key生成最好在创建的时候设置一个复杂密码

登录直接执行某个命令
    命令放在~/.ssh/rc或/etc/ssh/rc .bash_profile  甚至可以写入在/etc/passwd
    
登录显示信息/etc/motd、/run/motd.dynamic,登错机器是经常碰到的,显示机器的备注信息可以一定程度避免次情况发生

部分控制登录配置
    #DenyUsers, AllowUsers, DenyGroups, AllowGroup
    DenyGroups  hellogroup testgroup  # 表示即拒绝这些组用户连接
    DenyUsers   hello test            # 表示即拒绝这些用户连接
    禁用用户登录: /etc/passwd
    禁用用户组登录:/etc/group
     ~/.rhosts or ~/.shosts 不是必需,最好不要使用这两个文件来控制远程主机访问本地主机
     
提高登录速度 
    可以通过PreferredAuthentications调整验证顺序,或者关闭不必要的验证方式
    UseDNS no

ssh传文件,从标准输入中读取数据然后传输到远程
    cat 86_64.rpm | ssh 172.16.10.6  "cat - > /tmp/86_64.rpm"
    [root@xuexi ~]# cat ~/.ssh/id_rsa.pub | ssh 172.16.10.6 "umask 077; test -d ~/.ssh || mkdir ~/.ssh ; cat >> ~/.ssh/authorized_keys"
 

参阅:

SSH权限详解: SSH权限详解 - DTeam 技术日志

如何通过 PyCharm 连接服务器 JumpServer 如何通过 PyCharm 连接 - FIT2CLOUD 知识库

ssh系列文章:https://www.junmajinlong.com/linux/ssh_port_forward/

SSH 命令的三种代理功能(-L/-R/-D):https://zhuanlan.zhihu.com/p/57630633

SSH ProxyCommand example: https://www.cyberciti.biz/faq/linux-unix-ssh-proxycommand-passing-through-one-host-gateway-server/

  • 14
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值