近来,在为公司客户部署相关DNS系统服务,用于资源调度服务,但是客户出口缺少公网ip地址,不能方便的去管理这台服务器,开始想到使用teamviewer做中转,穿透内网,但是在Centos环境下,照teamviewer官方给出的手册尝试安装多次,未果,始终未能获取ID号,甚至最后都安装了图形gnome环境,尝试在图形环境下安装teamviewer,网络始终是notReady,最后,只能放弃使用teamviewer,在公司找了台有公网ip的机器,用ssh反向主动连接,也就是常说的端口转发。
这种方式跟最早网上流行的反弹式远程控制工具原理类似,像灰鸽子,任我行,Pcshare等等,包括现在很多***使用的远程控制***程序都是这种主动连接反弹式***,“堡垒总是从内部突破容易的多”。
回归正题,先来实操,最后上原理。
系统环境:
公司主机:extrahost(代指主机名和ip,具有公网ip),用户名:root ssh端口:2200
客户服务器:Intrahost(代指主机名和ip,私网ip做了NAT),用户名:root ssh端口:2211
ssh用到的参数:
-N:不执行何指令
-f:后台执行
-R:建立反向 tunnel
在客户的系统中输入如下命令:
----------------------------------------------------------------------------------------------------------
[root@Intrahost ]# ssh -NfR 2233:localhost:2211 root@extrahost -p 2200
输入密码即可
//port2233指绑定远程主机extrahost端口2233
-------------------------------------------------------------------
在公司管理设备查看端口2233是否在监听状态,netstat -ant,
如果未成功监听,请检查管理设备防火墙 和sshd是否有相关访问控制
在公司管理主机extrahost输入如下命令和密码,登陆到客户系统intrahost
--------------------------------------------------------------------
[root@extrahost]#ssh [email protected] -p 2233
//即可连接到客户的服务器上
------------------------------------------------------------------
问题
一.连接稳定问题
由于是反向主动连接,在会话异常中断,无法由控制端发起连接,我们可以借助几个工具来帮我们保持会话。
1.使用autossh工具
安装方法 autossh工具不在linux源中,需要从第三方源下载
地址:http://pkgs.repoforge.org/autossh/ 安装包有32位和64位,下载根据操作系统去选择。
使用方法 跟ssh类似,区别autossh需要不断去检测ssh连接状态,需要我们使用 -M参数,来指定autossh监听端口:
---------------------------------------------------------------------------------------
[root@Intrahost]autossh -M 1100 -NfR 2233:localhost:2211 root@extrahost -p 2200
----------------------------------------------------------------------------------------
2.使用nohup命令,截断挂起信号
用法:Usage: nohup COMMAND [ARG]...
or: nohup OPTION
示例:
------------------------------------------------------------------------------------
[root@Intrahost]nohup ssh -NfR 2233:localhost:2211 root@extrahost -p 2200
来中断对ssh的挂起信号。
---------------------------------------------------------------------------
3.建议大家使用nohup命令,这种方法可靠性很高,原因稍后阐述,现在我们来编写脚本使用crond定时任何计划来保持ssh会话,脚本内容如下。
#!/bin/bash createTunnel() { /usr/bin/ssh -NfR 2233:localhost:2211 root@extrahost -p 2200 if [[ $? -eq 0 ]]; then echo Tunnel to jumpbox created successfully else echo An error occurred creating a tunnel to jumpbox. RC was $? fi } /bin/pidof ssh if [[ $? -ne 0 ]]; then echo Creating new tunnel connection createTunnel fi
添加定时任务计划,重复执行脚本来判断通信隧道的建立
-----------------------------------------------------
命令:crontab -e
*/1 * * * * /root/ReverseSsh.sh > tunnel.log 2>&1
别忘了将脚本赋予执行权限
----------------------------------------------------
chmod u+x /root/ReverseSsh.sh
-----------------------------------------------------
鄙人能看到和想到的维持会话的方法,就在这了,欢迎大家分享自己的创新方法。
二、安全性问题
虽然我们坦然的建立了这条tunnel,可是大家忽略了一个东西,就是建立反向连接的tunnel时,我们需要输入对方设备的密码,假设我们的设备因为我们人品的关系,导致了重启,这时,无论再好的保持会话的工具和命令,都没办法替你输入密码,除非,公司的客户是你的好朋友或者至少是你信任的人,让他帮你输入密码,很不幸,事情往往超乎我们的想象。
所以,我们需要建立一个脚本,来替我们输入密码,并且对脚本进行加密,来防止客户肆意窥探我们管理设备的密码。也有,拿密钥做认证来免密码登陆,不建议大家这么做,这样虽然方便管理,但同样意味着客户可以使用该设备随意进入我们的管理设备,这是我们不愿意发生的事情,虽然我们的客户很可爱而且善良和蔼可亲。
脚本内容如下,我们需要借助自动化工具expect,至于expect是怎样的套件和工具,具体使用方法,大家可以去查资料学习,这个是我们自动化运维较常用的交互工具,建议大家掌握。
except安装方法,建议使用yum安装:
----------------------------------------------
yum -y install expect*
----------------------------------------------
#!/bin/sh # description:The script file for keepalive ssh session # Founder broadband interconnection.DE created by John.zhang # update 20151104 passwd=******** expect -c " /usr/bin/ssh -NfR 2233:localhost:2211 root@extrahost -p 2200 set timeout 5 expect \"password:\" send \"${passwd}\r\" expect eof "
脚本内容功能实现简单,大家可以尽情发挥,然后我们对该脚本文件进行加密,较常用的有三四种,我们这里推荐大家使用SHC工具,方便安全容易。
详细的安装方法大家去网上检索,这里简单飘过,我们只说使用方法。
下载地址:wget http://www.datsi.fi.upm.es/~frosal/sources/shc-3.8.9b.tgz
下载后,我们进行解包,
tar -xvf shc-3.8.9b.tgz
这个包下到的不是源代码,是预编译好的文件,直接安装即可make install
使用示例:[root@Intrahost]#shc -r -f ~/ReverseSsh_pass.sh
运行后会生成两个文件,ReverseSsh_pass.x 和 ReverseSsh_pass.x.c. 其中sReverseSsh_pass.x是加密后的可执行的二进制程序;用./ReverseSsh_pass.x即可运行,ReverseSsh_pass.x.c是生成ReverseSsh_pass.x的原文件,建议大家拷贝到自己电脑,从服务器上删除。并且对该程序添加执行权限,添加到开机启动。
[root@Intrahost]# vi /etc/rc3.d/S99local
在该文件下边写入我们加密脚本后的程序 /root/ReverseSsh_pass.x,用于开机自启动。注意这里是命令行方式,注意启动级别。
三、原理阐述,大神可忽略。
1.SSH reverse tunnel
如图,为ssh服务的正向和反向两种会话连接示意图,正常情况下(正向),我们由客户端发起会话请求到服务端,使用ssh协议为我们建立起一条连接通讯,我们可以将这条连接看做是条隧道(tunnel),这样我就可以使用终端工具来远程管理我们的服务器,注意,这里我们并不是真正意思上打开了终端,而是我们在网络层上,通过建立起来的隧道来连接到终端,所以我们把像使用putty,Securecrt这类工具,建立起连接呈现的终端也叫仿真终端。
既然我们建立起这样一条隧道,那必然每条隧道都有相同的端点,起始端和结束端,而这两端的端点正是我们的客户端和服务端,不同的是,正向连接是声明要连接的对端ip和端口,而反向连接则是由服务端声明可以连接到本机的对端ip和通讯端口。
这里提醒大家的是,正向连接和反向连接,建立起隧道的方向是一致的,都是由客户端作为起始端创建的通讯隧道,所谓的正向连接和反向连接取决于服务端在建立隧道的行为,正向连接,是被动接受来自客户端的请求,建立连接;而反向连接则是由服务端主动请求连接,但创建会话连接的起始端始终是客户端。
同样,弄懂原理后,那么像Telnet,FTP,甚至是我们用来连接windows桌面的RDP,也可以实现反向连接,大家可以在网上搜搜具体方法。
2.nohup
刚才我们提到了nohup这个命令,这个理解其实很容易,从字面不难理解禁止挂断,官方手册解释也很简单,ignoring hangup signals,忽略挂断信号,个人认为把它解释为截断挂断信号,更好点,nohup实现原理像一个守护进程,但它工作的机制是信号量级的,当我们所运行的进程在异常中断,或者超时的时候,会产生中断信号,来结束该进程,节约资源开销,nohup原理就是当收到来自针对该进程的中断信号时,会阻止该信号的发送,从而保持进程的运行不会因为异常情况而中断。
使用这个命令的优势很明显,autossh保持会话的工作原理基本和我们编写的脚本类似,而nohup工作机制直接是信号量级的,不需要通过执行另外的程序产生信号结果反馈,linux的信号机制起源于Unix系统,信号量由软件产生,进程之间的通讯均由信号完成,所以nohup执行效率和稳定性相比autossh很高,或者说两个没有可比性,因为它们实现的方式不一样。
就写到这吧,路漫漫上下而求索,希望大家能提出更好的方法,最后附上相关组件和工具。