基于web的ssh客户端很多,但是基于python开发的貌似就一款:webssh,当然,我说的是开源的。

还是先看看效果:



项目地址:

https://github.com/huashengdun/webssh​github.com/huashengdun/webssh

项目主页上,关于如何使用等,说明的非常清楚,例如:

pip install webssh
wssh

然后浏览器访问 http://127.0.0.1:8888 即可。

如果在实际生产环境下,关于如何部署,或许可以展开说几句:

我目前的环境 有一个在Apache环境下部署的Django项目,我需要复用现有环境,使这个webssh以最简单靠谱的方式被访问,我选择的是,通过Apache反向代理,来间接访问webssh服务。

通过官网知晓,webssh正常工作流如图,ssh server主动给browser推送信息时需要websocket的支持。

没有反向代理的工作流

如果部署在Apache之后,Apache会接管browser的流量,代为访问webssh服务

通过反向代理的工作流

当在webssh正常工作流中间引入了proxy之后,有两个问题需要额外关注下:

  • http head重写
  • URL重写

当正常的web流量被这种http server代理之后,http proxy server默认会改写http request报文的头部,改写为proxy自身的信息。

http头部被重写后,又会导致两个问题:websocket协商不成功,不允许CSRF跨域访问。

websocket协商

client-server之间的会话由http升级到websocket,client的http 报文头部必须携带

Connection: Upgrade ,Upgrade: websocket 这些字段,当被proxy改写为普通的http请求,必然协商不成功。

CSRF跨域访问

为了防止跨域伪造攻击,对于表单类似的 提交信息的网页元素,web框架默认都会为web应用添加CSRF token,只有当用户实际访问该页面,并且把CSRF token附在表单提交的http request头部回传到server,server才会认为是一个正常的请求,对于经过proxy代理的流量,被拆分为两段,CSRF token会不匹配,导致不能正常访问webssh。

来实际部署试试:

克隆或者下载项目到本地目录并解压:

https://github.com/huashengdun/webssh.git

在webssh根目录,启动webssh:

python run.py --address="127.0.0.1" --port=8888 --encoding='utf-8' --log-file-prefix=C:\Users\AA340261\Downloads\Dj_cmdb\webssh\main.log 

此时webssh应该可以正常访问,http://127.0.0.1:8888, 确切说是让部署在本地的Apache来访问。

Apache添加reverse proxy相关的配置:

httpd.conf 编辑此文件,加载下面模块(去掉注释)
mod_rewrite.so
mod_proxy.so
mod_proxy_http.so
mod_proxy_wstunnel.so

在定义VirtualHost的子配置文件中添加如下配置,例如我的Django项目启用了https,相关virtualhost的配置在httpd-ssl.conf子文件中

<VirtualHost _default_:${SSL_PORT}>
.
.
.
ProxyPreserveHost On
RewriteEngine On
RewriteCond %{HTTP:Upgrade} =websocket [NC]
RewriteRule /ssh/(.) ws://localhost:8888/$1 [P,L]
RewriteCond %{HTTP:Upgrade} !=websocket [NC]
RewriteRule /ssh/(.) http://localhost:8888/$1 [P,L]

ProxyPass /ssh/ http://localhost:8888/
ProxyPassReverse /ssh/ http://localhost:8888/
.
.
.
</VirtualHost>

其中ProxyPreserveHost On 表示保留http request header作为proxy http request的header,即保留原始http 头部。

RewriteEngine 下面的配置表示,如果 http头部字段Upgrade =websocket, 转换http请求为正确的ws的请求

完成以上后,应该就可以通过访问https://my_django_site/ssh/ 来间接访问http://localhost:8888/

one more thing:

可以把

python run.py --address="127.0.0.1" --port=8888 --encoding='utf-8' --log-file-prefix=C:\Users\AA340261\Downloads\Dj_cmdb\webssh\main.log

这个启动webssh的命令封装为一个系统服务,Linux系统比较容易,Windows系统可以使用NSSM来封装,没有sc命令需要exe文件的限制

添加图片注释,不超过 140 字(可选)

以上。

最后修改:2022 年 08 月 13 日
如果觉得我的文章对你有用,请随意赞赏