介绍
ssh(SSH 客户端)用于登录远程主机,并且在远程主机上执行命令,它的目的是替换 rlogin 和 rsh,同时在不安全的网络之上,两个互不信任的主机之间,提供加密的,安全的通信连接。X11连接和任意TCP/IP端口均可以通过此安全通道转发(forward)。
命令格式:
SSH 协议是 Linux 系统中使用较为频繁的协议之一,通常用于远程管理主机或服务器,默认使用 22 端口,可类比 Windows 系统中的
前置条件
为了理解更轻松,最大程度上简化网络拓扑,后续都只用两台机器做测试,IP 与主机名对应关系如下;更复杂的网络结构和多接口场景可举一反三延申,要用作某些特殊用途,则自行YY。
192.168.111.128 --> Kali 192.168.111.131 --> Centos
在验证 IP 地址和多级代理的场景时,会额外用到网关机器:
然后再多了解一下三个 ssh 的命令行参数,后面会用到:
-N 建立连接后不远程执行命令,也没有交互shell,通常用于端口转发的场景。 -f 建立连接后会在后台运行进程,不占用前台窗口。 -c 传输数据时对数据进行压缩,压缩算法和 gzip 的一样,但不适用于高速网络环境,会降低连接速度。 -v 打印更详细的连接过程信息。
本地转发(-L)
原理
本地转发即使用
-L [bind_address:]port:host:hostport -L [bind_address:]port:remote_socket -L local_socket:host:hostport -L local_socket:remote_socket Specifies that connections to the given TCP port or Unix socket on the local (client) host are to be forwarded to the given host and port, or Unix socket, on the remote side. This works by allocating a socket to listen to either a TCP port on the local side, optionally bound to the specified bind_address, or to a Unix socket. Whenever a connection is made to the local port or socket, the connection is for‐ warded over the secure channel, and a connection is made to either host port hostport, or the Unix socket remote_socket, from the remote machine. Port forwardings can also be specified in the configuration file. Only the superuser can forward privi‐ leged ports. IPv6 addresses can be specified by enclosing the address in square brackets. By default, the local port is bound in accordance with the GatewayPorts setting. However, an explicit bind_address may be used to bind the connection to a specific address. The bind_address of “localhost” indicates that the listening port be bound for local use only, while an empty address or ‘*’ indicates that the port should be available from all interfaces.
翻译成人话,通俗讲就是,使用该参数执行 ssh 连接后,会在本机开启一个指定监听端口1,然后绑定到远程机器的指定接口(IP)的指定端口2,用另一个程序再访问本机的指定端口1,流量就会转发到远程机器的指定端口2,相当于直接访问远程机器的端口2;可以简单的理解为 “流量从本地转发到远程机器”。
参数值(
实验
上面的转发流程有点绕,用实验来理解下实际效果,假设场景为 Kali(
试着先本地访问下(Centos 具有第二个接口:
ok 没问题,接着去另一台机器 Kali(
证明连接是通的,接下来直接在 Kali 上使用本地转发连接 Centos(为了方便已提前给两台机器配置了 ssh 公钥连接,避免输入密码),执行参数为:
ssh -NL 1080:192.168.122.1:8000 [email protected]
然后执行后会在 Kali 本地监听
Centos 这边也记录到了相应的连接日志,本地转发成功:
远程转发(-R)
原理
远程转发的执行参数是
-R [bind_address:]port:host:hostport -R [bind_address:]port:local_socket -R remote_socket:host:hostport -R remote_socket:local_socket -R [bind_address:]port Specifies that connections to the given TCP port or Unix socket on the remote (server) host are to be forwarded to the local side. This works by allocating a socket to listen to either a TCP port or to a Unix socket on the remote side. Whenever a connection is made to this port or Unix socket, the connection is forwarded over the secure channel, and a connection is made from the local machine to either an explicit destination specified by host port hostport, or local_socket, or, if no explicit destination was specified, ssh will act as a SOCKS 4/5 proxy and forward connections to the destinations requested by the remote SOCKS client. Port forwardings can also be specified in the configuration file. Privileged ports can be forwarded only when logging in as root on the remote machine. IPv6 addresses can be specified by enclosing the address in square brackets. By default, TCP listening sockets on the server will be bound to the loopback interface only. This may be overridden by specifying a bind_address. An empty bind_address, or the address ‘*’, indicates that the remote socket should listen on all interfaces. Specifying a remote bind_address will only succeed if the server's GatewayPorts option is enabled (see sshd_config(5)). If the port argument is ‘0’, the listen port will be dynamically allocated on the server and reported to the client at run time. When used together with -O forward, the allocated port will be printed to the standard output.
通俗讲就是,执行远程转发命令后,会在远程机器开启监听一个指定端口1,绑定到本地的指定端口2,所有访问远程机器端口1 的流量都会被转发到本地的端口2 上,相当于直接访问本地的端口2,也可以简单的理解为 “流量从远程转发到本地机器”;
可以注意到这里的转发流向其实是和上面的本地转发是反的,所以参数值(
这里有个值得注意的地方,可以看到参数值那块,相比于前面的本地转发多了个
实验
下面同样使用 Kali(
本地连接没问题,接下来在 Kali 上开启远程转发,参数为:
ssh -NR 1080:127.0.0.1:8000 [email protected]
这会在远程机器(Centos,
Kali 这边也有了相应的访问记录,至此远程转发成功:
反向 socks 代理
然后测试
<?php echo $_SERVER['REMOTE_ADDR'] . PHP_EOL;
访问路径是:
ok,IP 是对的,然后在 Kali(
ssh -NR 1080 [email protected]
去 Centos(
至此反向 socks 代理成功。
远程接口地址问题
在实际使用远程转发的时候,可能会遇到一个小坑,就是
然后重启
动态转发(-D)
原理
动态转发的执行参数是
-D [bind_address:]port Specifies a local “dynamic” application-level port forwarding. This works by allocating a socket to listen to port on the local side, optionally bound to the specified bind_address. Whenever a connection is made to this port, the connection is forwarded over the secure channel, and the application protocol is then used to determine where to connect to from the remote machine. Currently the SOCKS4 and SOCKS5 protocols are supported, and ssh will act as a SOCKS server. Only root can forward privileged ports. Dynamic port forwardings can also be specified in the configuration file. IPv6 addresses can be specified by enclosing the address in square brackets. Only the superuser can forward privileged ports. By default, the local port is bound in accordance with the GatewayPorts set‐ ting. However, an explicit bind_address may be used to bind the connection to a specific address. The bind_address of “localhost” indicates that the listening port be bound for local use only, while an empty address or ‘*’ indicates that the port should be available from all interfaces.
这应该是实际使用中较多的一种用途,即 socks 代理,动态转发是在本地监听一个指定端口,应用程序将 socks 代理端口设置为这个端口后,任何连接流量都会通过这个端口,经由 ssh 隧道转发到远程机器代为发送,由于不再受限于连接端和被连接端的端口与接口,所以称为动态。
参数值(
实验
还是在 Kali(
ssh -ND 1080 [email protected]
尝试用
Kali 访问 Centos 的其他接口(
多级代理(-J)
原理
实现多级代理需要用到
-J destination Connect to the target host by first making a ssh connection to the jump host described by destination and then establishing a TCP forwarding to the ultimate destination from there. Multiple jump hops may be specified separated by comma characters. This is a shortcut to specify a ProxyJump configuration di‐ rective. Note that configuration directives supplied on the command-line generally apply to the desti‐ nation host and not any specified jump hosts. Use ~/.ssh/config to specify configuration for jump hosts.
大意就是连接
实验
为了呈现多级节点的效果,这里需再次用到网关机器(
ssh [email protected] -J [email protected]
可以看到最终连接到的 Centos 机器的访问记录是跳板机 Kali 的 IP 地址:
再测试一下指定多个跳板:
ssh [email protected] -J [email protected],[email protected]
这里为了简化网络拓扑,所以把 Centos 自身也设置为一个跳板,那么经过的两个跳转节点就是
*.111.1 --> *.111.128 --> *.111.131 --> *.111.131
将