ssh端口转发远程调试elixir服务端程序

observer 远程调试服务器应用

elixir 应用跑在服务器上想监测程序状态?observer 无法直接运行在ssh登录的无图形界面环境中

iex([email protected])1> :observer.start
04:08:11: Error: Unable to initialize GTK+, is DISPLAY set properly?
                                                                    {:error,
 {{:einval, 'Could not initiate graphics'},
  [
    {:wxe_server, :start, 1, [file: 'wxe_server.erl', line: 65]},
    {:wx, :new, 1, [file: 'wx.erl', line: 115]},
    {:observer_wx, :init, 1, [file: 'observer_wx.erl', line: 98]},
    {:wx_object, :init_it, 6, [file: 'wx_object.erl', line: 372]},
    {:proc_lib, :init_p_do_apply, 3, [file: 'proc_lib.erl', line: 247]}
  ]}}

此时可以利用ssh建立通道让本地端口重定向(转发)到远程服务器

服务器端:

1. iex --name [email protected] --cookie any
Erlang/OTP 20 [erts-9.0] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]
Interactive Elixir (1.4.5) - press Ctrl+C to exit (type h() ENTER for help)
iex(serv@127.0.0.1)1>

2. epmd -names
    epmd: up and running on port 4369 with data:
    name serv at port 51097


本地端:

1. ssh -L 4369:localhost:4369 -L 51097:localhost:51097 root@server

这里有个问题为什么使用localhost?man ssh 查看了下-L的参数
-L [bind_address:]port:host:hostport
-L [bind_address:]port:remote_socket
-L local_socket:host:hostport
-L local_socket:remote_socket
应该是服务端的ip才对啊,文章末尾将进一步解释。

2. iex --name client@127.0.0.1 --cookie any
iex(client@127.0.0.1)1> :observer.start
:ok
iex(client@127.0.0.1)2>

在本地端iex中开启observer后即可在node中找到[email protected]

这里写图片描述

这里写图片描述

这里写图片描述

这个做法其实就是利用ssh的-L在本地绑定一个端口,使得所有本地访问此端口的数据全部转发至服务器,从而架起了一个本地和服务器的数据通信桥梁。其实epmd是Erlang Port Mapper Daemon, 在分布式erlang应用中充当类似dns的名称到端口的映射4369即是该服务监听的端口,此例中51097是我们开启的节点serv所对应的端口。通过ssh -L 我们就可以轻松实现非局域网内的节点访问监测相当实用, 当然也用Wobserver这样的专用项目可供使用Wobserver

其实这里端口转发时localhost表示本地主机也即是远程服务器的本地主机。如果远程主机端口不允许外回路访问只允许本地访问的话这里只能是localhost或是127.0.0.1,代表访问来自远程主机的本地回路。 相当于我们假设局域网中你的主机ip是192.168.0.40,你有一个端口有对内环的http监听服务假设端口8080返回hello world。 在你的浏览其中输入127.0.0.1:8080, 和192.168.0.40:8080结果是不同的。192.168.0.40:8080将会是拒绝访问, 127.0.0.1:8080会正确显示hello world。写个简单的python小脚本测试一下

import socket   #socket模块
import commands   #执行系统命令模块
HOST='127.0.0.1' #内环访问
PORT=8080
s= socket.socket(socket.AF_INET,socket.SOCK_STREAM)   #定义socket类型,网络通信,TCP
s.bind((HOST,PORT))   #套接字绑定的IP与端口
s.listen(1)         #开始TCP监听,监听1个请求
while 1:
    conn,addr=s.accept()
    conn.send("HTTP/1.0 200 OK\r\nContent-Length: 11\r\n\r\nhello world")

这里写图片描述

这里写图片描述
这里如果将HOST改为’0.0.0.0’再运行的话,你会发现浏览器地址栏中不管输入192.168.0.40:8080还是127.0.0.1:8080都会是一样的结果(经典的hello world)
这里写图片描述
所以对本例中localhost的理解就是ssh端口转发你的本地访问到服务器上时会采用内环访问的方式也即127.0.0.1:4369去获取该端口上的服务,这样即便是该端口不对外开放也能通过内环的方式访问(其实大部分服务器为了防止黑客攻击都不会随意开放端口,所以只能回环访问),那有人会问ssh的22端口呢, 当然这个是对外开放的,不过一般这个端口的服务是需要密码的(强烈建议用RSA非对称加密的方式对外提供服务, 应该关闭密码验证采用公钥验证方式, 网络上有很多ssh端口扫描机器人bot, 一旦密码被攻破,被获取服务器权限将是多么可怕的一件事。 删库跑路, 植入黑客程序啥的敢想后果吗)

ssh的端口转发是非常有用的,因为ssh是加密通道, 所以所有经过ssh通道的数据是无法通过中间人截取明文的,试想一下如果使用ssh端口转发443/80、53端口到远程服务器,再在远程服务器上架设客户端监听这些端口转发数据,是否可以避免污染(用途不言而喻)。ssh的转发有本地转发(-L)远程转发(-R)和动态转发(-D),本例使用的是本地转发。使用动态转发也可轻易造梯,github上有很多相关的开源代码。关于ssh隧道有一片文章描述的非常详尽这里不再赘述实战 ssh 端口转发

猜你喜欢

转载自blog.csdn.net/u011031257/article/details/80655663
今日推荐