应用SSH增强产品竞争力

来源:互联网 发布:淘宝鞋子关键词 编辑:程序博客网 时间:2024/05/17 03:30

1         前言

SSH其实是一个功能非常强大的武器,我们以前只是使用了其加密登陆的最基础的功能,SSH其实可以在如下方面增强我们产品的竞争力:

1. 免密码却更为安全的SSH登陆;

2. 应用SSH隧道技术实现的无线组网方案;

3. 应用SSH压缩功能的无线省流量方案;

4. 应用SSH SOCKS5代理的降成本方案;

5. 应用SSH X11的远程桌面方案。

 

2         免密码却更为安全的SSH登陆

2.1  以往的安全漏洞

我们以往产品的安全性其实是很低的,体现在:

1.      允许root账号的ssh登陆;

2.      Root密码被列为密码字典的一部分,可轻易破解;

3.      默认监听的22端口没有改变;

4.      没有禁止密码登陆。

这意味着,不怀好意的人通过网络扫描工具发现单板IP22端口是打开的,然后用户设置为最易猜测的root账号,导入密码字典,一会功夫,就可以轻易入侵到我们的单板内部。

2.2  更安全的策略

2.2.1             策略

因此,建议以后的产品做如下改动:

1.      将默认的22端口禁止掉,ssh服务改为另一个端口进行监听

2.      禁止密码,采用密钥

3.      禁止root用户的ssh登陆,改用另一个不易猜测的用户名,并使该用户具有管理员的权限

采用以上方式,正常的破解方式已经接近于不可能!

正常情况下,仅采用方法12,已经具有足够高的安全,保留root用户的ssh登陆,具有一定的方便性。

2.2.2             实施方法

实施方法:

打开/etc/ssh/sshd_config

PasswordAuthentication 改为no,可以禁止密码登陆;

Port 22 取消注释并改为另一个端口xx

ssh user@ip –p xx,即可实现采用xx端口登陆)

(如果需要禁止root用户的ssh登陆,将PermitRootLogin 改为 no

linux上,执行ssh-keygen,默认生成rsa加密的密钥对,可以将其命名为和项目有关的名字,以方便管理,举例pmsc_v10(密钥自动为pmsc_v10,公钥自动为pmsc_v10.pub)。

执行ssh-keygen

第一步,输入pmsc_v10

后面两步直接回车即可(空密码)。

然后,将公钥导入到目标单板中。

ssh-copy-id –i ~/.ssh/pmsc_v10.pub root@target_ip

那么,以后pc采用私钥pmsc_v10,即可ssh访问单板。

2.2.3             注意

如果为了防止密钥被人窃取使用,在ssh-keygen时,加入密码即可,这样,获取密钥的人,也需要通过密码才能使用,这和我们平时的数字证书加密码的原理是一致的。

为了防止内部人员离职带走密钥,防止一把钥匙打开所有的单板,每个项目可以拥有自己的密钥,这样密钥丢失的影响也会降到最小。

2.3  非密钥的免密码登陆

如果你非常顽固,就是不采用密钥的方式,我还是有一个免密码的方式推荐给你,sshpass

安装sshpass

sshpass –p your_password ssh user@ip

即可登陆

如果不想输入密码,可以将密码设置为全局有效。

export SSHPASS=your_password

sshpass –e ssh user@ip

即可免密码登陆。

3         应用SSH隧道的无线组网方案

3.1  背景

这里的无线组网,准确地说,是移动网络组网,通过SIM卡获取的网络IP,属于局域网IP。然而,单板更多时候是作为服务端存在,客户端无法主动访问,单板服务。这里就是要通过SSH隧道的方式来解决客户端无法主动访问单板服务的问题。

3.2  必要条件

使用该方案的前提是,至少具备一个公网IP的电脑

3.3  如何实施

假设公网IP电脑的IP10.9.81.145

公网电脑已经安装了ssh服务(sshd);

假设公网电脑的系统为linux,且在/etc/ssh/sshd_config中将GatewayPorts设置为yes

3.3.1             访问单板的WEB

客户需要访问处于移动内网中的单板的WEB界面,如何做?

第一步,在单板执行如下命令:

ssh -fNR *:8000:localhost:80 mania@10.9.81.145

    然后……然后就完成了。

    客户在自己的电脑浏览器输入:10.9.81.145:8000

就可以访问单板的WEB了。

    (如果客户就在公网电脑上操作,输入localhost:8000127.0.0.1:8000即可)

3.3.2             访问单板的SNMP

这个要麻烦些。

因为SSH隧道是基于TCP的,所以只支持TCP协议,web使用的http协议就是基于tcp的,所以可以直接使用。

SNMP是基于UDP的,所以需要多一个工序。

公网IP电脑和单板需要新增一个socat指令。

执行步骤:

第一步,单板执行:

ssh -fNR *:6666:localhost:6666 mania@10.9.81.145

socat -v tcp4-listen:6666reuseaddrfork udp4-sendto:localhost:161

第二步,公网电脑执行:

socat udp4-listen:1610reuseaddrfork tcp:localhost:6666

然后……然后就完成了。

客户在自己的电脑上对10.9.81.1451610端口进行snmp轮询,就能获取单板的snmp信息了。

3.3.3             实施注意

可以看到单板IP和端口被映射为一个远程端口

3.3.3.1  单板实施

开局时,每个站点的单板,必须设置一个唯一的远程端口。

1.需要增加一个参数,供开局时设置,单板的远程端口不能重复。

2.为了稳定,可以采用autossh,当网络断开(含IP改变),会自动重建ssh反向隧道。

3.由于建立ssh隧道时,需要输入公网电脑的账号密码(否则无法在公网电脑打开它的端口),因此,需要加入ssh密钥方式或sshpass自动输入密码的方式解决人工输入密码的过程。

3.3.3.2  网管实施

网管访问单板,不需要再关注IP(或会改变的IP),只需要注册哪个站点的单板对应的是哪个远程端口即可,轮询这个远程端口,不管单板IP怎么变化,都能访问到。

单板主动上送改变的IP,已经没有意义。

网管可以直接部署在公网电脑上,也可以处于内网,通过访问公网电脑的方式,间接访问另一个内网的单板。

ssh隧道的性能测试,接近等价于公网电脑的端口转发性能测试。

 

3.4  原理

3.4.1             访问web的原理

单板处于内网,只能是单板主动发起连接,因此,单板主动发起的ssh隧道叫ssh反向隧道,原理和ssh隧道一样,只是发起方向不一样而已。

Ssh隧道本质还是通过长连接实现一个通道,但是,它的长连接可以被其他进程所用。

如下图,建立了单板80端口映射远程电脑8000端口的隧道。

远程电脑的ssh服务监听8000端口,如果有数据,会通过socket将数据通过22端口发给单板的ssh端口;单板xx端口收到数据后,立刻转发给80端口。

这样,就等价于如下的公式:

远程电脑的8000端口 == 单板的80端口

由于远程电脑IP是公网IP,因此,内网单板web就可以直接访问了。



 

3.4.2             访问SNMP的原理

本质就是解决ssh隧道传输udp的问题。

在远程电脑和单板增加TCPUDP互转的工具即可,可以采用netcatsocat实现(测试中,发现socat具有更好的稳定性)。

Snmpmib浏览器访问远程电脑的udp1610端口,socat监听它,发现有数据,转发给tcp:6666端口。

远程的6666端口通过ssh隧道到达单板的6666端口(原理和web一样)。

单板的socat监听本地的tcp6666端口,发现有数据,转发给udp161端口。

Snmpd监听着udp161端口,数据就到达snmpd内部了。

因此,上述过程等价于:

远程电脑的udp1610端口 == 单板的udp161端口

  

3.5  SSH隧道和VPN比较

具体比较见下表,加黑的为优势方:

 

SSH隧道

VPN

实施难度

前后台实施都非常简单。第5代监控,全部默认具有ssh功能,无需移植。

前后台实施的工作量很大。复杂。

网络灵活性

针对的是进程级。意味着,A进程可以和网管通信的同时,B进程可以将数据发给家里的服务器。这是大数据分析的基础。

单板全局有效。单板的任何一个进程,只能处于客户的网络当中,无法发送数据到其他网络中。

开局难度

必须为每个站点设置唯一的远程端口,并在网管中注册

每个站点的开局工序一样。

网管轮询单板

不变的端口

会改变的IP

组网适用性

网管和单板,均可处于内网。

建议用于组网规模不大的场合(规模大小的界定,应与实测结果结合)

网管和单板,均可处于内网。

建议用于组网规模大的场合

 

总的说,ssh隧道的方案相比VPN实施起来更简单,建议用于监控规模的不大的市场。

3.6  免密码的进一步说明

前一节提到的免密码登陆,是PC具有私钥主动登陆单板。

而这里的场景为,单板具有私钥,需要主动登陆客户的PC,是相反的过程。

详细实施如下:

开发阶段:用ssh-keygen -t rsa生成密匙对,建议改掉默认名,举例这里私钥为id_rsa_esmu,公钥为id_rsa_esmu.pub。将私钥放入单板文件系统的/root/.ssh中,公钥给客户。

在客户服务器:建立一个我们单板将要登陆的用户A,将公钥放入(假设为linux系统)Ahome目录下的.ssh文件夹下,将公钥导入认证钥匙中,cat ~/.ssh/id_rsa_esmu.pub >> ~/.ssh/authorized_keys

在我们的单板:加入sshssh-keyscan指令,ssh-keyscan -H 客户IP >> ~/.ssh/known_hosts, 然后ssh -i ~/.ssh/id_rsa_esmu A@客户IP 就可以自动登陆了。(免人工干预最关键的就是使用了ssh-keyscan,它可以免人工确认的生成known_hosts文件。)

3.7  Autossh

3.7.1             Autossh原理与实现

ssh处于移动网络时,容易出现断开的问题,这时可以采用autossh。它会间接调用ssh,但是加入了链路检测。

编译:将Makefile中的gcc改为交叉编译gccssh的路径改为单板的ssh实际路径即可。

用法:原来ssh的语句,将开头的ssh改为autossh -M port即可。

(—M后的端口是autossh用来检测链路用,要确保portport+1可用即可)

检测的原理:autossh会额外加入如下命令(假设-M后是6000):

ssh -L 6000:127.0.0.1:6000-R 6000:127.0.0.1:6001

很明显,对本地6000端口发检测包,最终又会回到本地的6000+1端口,这样就能知道链路是否断开,如果断开,它会自动重连。

3.7.2             实践中发现的问题

实践中,发现偶尔会出现如下告警:

Warning: remote port forwarding failed for listen port xx

3.7.2.1  SSH长连接缺失导致的告警

3.7.2.1.1            引入ssh长连接的必要

ssh默认不会发送心跳包维持长连接。 ssh需要加了一个ServerAliveInterval的参数,告诉ssh多久发送一次心跳包。

在外网环境中,中间各级的路由器维持链路的记忆一般只有几分钟,假设按5分钟计算。

另外一方面,autossh检测链路通断会由快到慢,最后慢下来后,基本维持10分钟检测一次链路通断。(也就是说,开始时,这个问题不会暴露,当autossh的检测慢下来后,这个问题才会出现。)

这时,在autossh发送下一次检测包之前,链路已经断开,这样,autossh的检测包,就得不到回复,autossh认为链路断了,就会重启ssh客户端。

注意,由于网络断,ssh服务端那块不知道ssh客户端挂了,一直还在运行。

autossh重启ssh客户端时,会要求服务器那重启一个ssh服务,但是,以前那个还在,所以就会存在无法监听端口的问题。

3.7.2.1.2            引入长连接后的效果

当加入 ServerAliveInterval=10 后, 10秒, sshsshd会产生3个包

ssh --> sshd 的加密包

ssh <-- sshd 的加密包

ssh --> sshd 的普通TCP

这意味着,加入ServerAliveInterval这个参数,是可以保证长连接状态

再次验证,发现出现告警的概率大幅下降,但是仍然完全杜绝掉告警的产生。

3.7.2.2  异常关闭导致的告警

3.7.2.2.1            复现告警

1.

建立隧道后, 杀死ssh wireshark显示,存在网络结束的正常交互包;

这时,再次按相同端口,与sshd建立隧道,不会报任何告警。

2.

建立隧道后, 关掉ssh电脑的网络, 然后杀死ssh

恢复网络后,再次按相同端口,与sshd建立隧道,产生和开头描述一样的告警信息;

告警信息产生后,通过wireshark检查,sshsshd的通信一切正常。

这证明了告警信息的产生,是不会影响实际效果的

3.7.2.2.2            异常网络下告警信息产生的理论分析

1. 存在一段时间的网络无法互通,可能是外网服务器的问题,也可能是csu的无线网络问题;

2. autossh发现网络断后 ,重启ssh(这时,由于网络断,ssh死亡的信息,无法被sshd知道,sshd仍然傻傻地在坚守着);

3. autossh周期重启ssh,过了一段时间,网络恢复,ssh建隧道的信息到达 sshd,这时,会新建一个sshd进程,监听的端口和原来那个不知情的老sshd进程一样。

由于老sshd霸占着端口,所以显示端口被占用的告警信息,然后新sshd进程退出。

4. ssh继续与老的sshd进程进行通信。

4         应用SSH压缩功能的无线省流量方案

4.1  通过SSH实现WEB的压缩

在无线组网方案中,省流量是非常有优势的:

1.      更少的流量,意味着可以节省更多的流量费用;

2.      更少的流量,意味着通信更快,在网络差的环境中,通信成功率更为明显。

在内容不变的情况下,采用压缩算法,是省流量的最佳办法。

由于单板使用的web服务boa不支持压缩功能,因此,需要借助其他方式来实现。

这里,采用SSH通道的方式来访问web网页,在SSH传输时,对内容加入gzip的压缩。

如果需要SSH在传输内容时支持内容的压缩,只需要加入-C参数,就可以实现。

4.2  流量对比

在上面的ssh隧道中,加入压缩功能,针对web访问的情况进行了测试对比:

 

直接访问(KB)

SSH隧道下的访问(KB)

SSH隧道加压缩的访问(KB)

测试网页

隧道压缩对比直接访问节省

备注

41

39.79

12.25

PLC

70.12%

单包

156

156.78

22.18

站点配置

85.78%

单包

20.5

23.99

12.17

活动告警(1个)

40.63%

单包

34.3

56

24

活动告警(18个)

30.03%

多包

89

111

47

开关电源实时量

47.19%

多包

30.5

32.78

4.01

历史告警(100条)

86.85%

单包

 

可以发现,由于web是基于html,而html又是文本类型,因此,压缩效果非常明显!!

对于SNMP,由于都是一条条命令交互,内容越少,SSH隧道附加的内容就会相对显得越多,压缩效果也没这么明显。实测,walk获取324条数据,普通轮询需要55KSSH隧道用了95KSSH隧道加上压缩用了58K,反而多了5%的流量消耗。

因此,SSH隧道压缩特别适合在htmlxml等文本传输的协议中使用。

5         应用SSH SOCKS5代理的降成本方案

5.1  SOCKS5代理的实现

这项技术是在服务器维护的实践中发现的。

由于作者需要同时维护多台服务器,而公司的上网账号只能在一处登陆,因此,会出现多台服务器上网更新的网络问题。

作者采用的方式是:

在一台服务器A上登陆上网账号,由于sshd默认支持SOCKS5代理,其他服务器只需要通过如下方法,即可通过服务器A进行上网更新软件:

执行 ssh –fND localhost:xx_port server_A_user_name@server_A_ip

那么服务器通过访问本机xx_port,即可通过服务器Asshd进行上网。

举例,firefox的高级-网络-设置中,选择手动代理,将除socks5以外的全部清空,socks5填入127.0.0.1 xx_port,那么,firefox上网时,就会通过服务器A来上网。

对于很多不支持SOCKS5的软件而言,这种方法是不可操作的,这里,可以引入polipo软件。

polipo可以强制流量全部通过SOCKS5走掉。

下载polipo压缩包,解压,make,复制polipo/usr/bin即可使用。

创建/etc/polipo/config文件,加入三行

daemonise = true

socksParentProxy = 127.0.0.1:xx_port

socksProxyType = socks5

最后,export http_proxy=http://localhost:8123.这样,普通的程序也可以上网下载了其中,8123polipo默认创建的端口.

5.2  可能的应用

正确情况下,单板如果需要无线网络通信,需要配置无线网卡等,每个单板都需要一套,成本较高。

如果,这些单板可以通过有线网络进行通信,如通过交换机等,那么,其中一套单板配置一个无线网卡,其他单板通过SSHSOCKS5代理方式连接到这套具有无线网卡的单板中,则可能具有降成本的可能。

 

6         应用SSH X11的远程桌面方案

6.1  背景

这项技术是在服务器的维护实践中发现。

以往维护远程电脑,都必须远程桌面,对应统一开发环境的服务器,对每一个用户开启远程桌面是非常麻烦的事情。

使用SSH默认支持的X11协议,开发人员可以非常非常简单的打开服务器上的应用软件显示窗口。

6.2  X11的实现

X11就是X windows system 版本11的意思,用于窗口的位图显示,是一个现代操作系统都基本支持的通用显示协议。

linux默认都支持X11 ssh服务也默认支持X11转发.

那么当需要打开远程电脑的图形界面时,就不需要VNCrdp等远程桌面, 只需要在ssh登录中加入-Y ssh -Y user_name@ip

登录后, 举例,执行firefox,那么就会弹出firefox的图形界面了这种方式,不需要全局桌面,只显示你需要的软件GUI,非常方便.

这其中的原理就是利用了ssh的转发功能, X11的客户端和服务端数据都通过ssh转发实现交互.

6.3  可能的应用

单板的液晶采用的就是基于位图的窗口,如果加以改造,使其满足X11的要求,那么我们将不再需要自己定制的远程桌面,通过ssh即可获取单板的液晶窗口,非常方便和通用。

 

7         总结

每一个软件开发同学,每天都要使用SSH,用了这么多年SSH,是不是第一次发现SSH居然有这么强大的功能。

生活在于发现,有趣的事情总会出现。