Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

协议小册 #82

Open
FrankKai opened this issue Jul 4, 2018 · 3 comments
Open

协议小册 #82

FrankKai opened this issue Jul 4, 2018 · 3 comments

Comments

@FrankKai
Copy link
Owner

FrankKai commented Jul 4, 2018

  • SSH
  • MQTT
  • Websocket
@FrankKai
Copy link
Owner Author

FrankKai commented Jul 4, 2018

SSH 协议

Linux SSH COMMAND

这一页主要是Unix/Linux或者Mac终端的OpenSSH ssh命令。
几乎所有的Unix和Linux系统包括ssh命令。这个命令可以用来开启SSH 客户端程序,从而建立SSH 服务器与远程机器之间的安全连接。
ssh命令有以下用途:

  • 登录远程机器
  • 在两台机器间传输文件
  • 在远程机器上执行命令
Linux的SSH 命令

ssh命令可以在不安全的网络中对两个主机建立安全的加密连接。这个连接可用于终端验证,文件传输,以及与其他应用建立通道。Graphical X11应用可以通过SSH命令在远程安全运行。

其他的 SSH 命令

除了SSH客户端命令,这里有一些其他的SSH命令。每一个都有自己的page。

  • ssh-keygen - 为公钥验证创建钥匙对。
  • ssh-copy-id - 在服务器上配置公钥的授权。
  • ssh-agent - 用于保存单点登录私钥的代理程序
  • ssh-add - 添加秘钥到代理的工具
  • scp - 基于RCP-like命令接口的文件传输客户端
  • sftp - 基于FTP-like命令接口的文件传输客户端
  • sshd - OpenSSH 服务器
使用Linux SSH 客户端

Linux默认使用OpenSSH客户端。ssh命令可以登录到一个远程机器非常好用。为了登录到名为sample.ssh.com的远程计算机,在shell命令行输入下面的命令:

ssh sample.ssh.com

如果这是你第一次使用ssh连接远端的机器,你将看到下面的信息:

The authenticity of host 'sample.ssh.com' cannot be established.
DSA key fingerprint is 04:48:30:31:b0:f3:5a:9b:01:9d:b3:a7:38:e2:b1:0c.(或者是RSA key fingerprint is SHA256:foo0a1b /bar0a1b )
Are you sure you want to continue connecting (yes/no)?

输入yes继续。这将添加服务到你的已知host文件中。(~/.ssh/known_hosts),会给出下面的提示信息:

Warning: Permanently added 'sample.ssh.com' (DSA) to the list of known hosts.
(或者Warning: Permanently added 'fe.crm.test.weidiango.com' (RSA) to the list of known hosts.
)

known_hosts文件的格式如下,以github为例:

github.com,13.229.188.59 ssh-rsa AAAAB3NzaC1yc2EA...

格式为 域名, ip地址 ssh-rsa/ssh-dsa public key,在使用ssh登录远程主机时,远程主机会为你返回public key。

每一个服务器都有一个host key,通过上面的与验证相关的问题可以验证并且保存host key,所以下次你连接服务器时,host key可以识别出这是相同的服务器。

一旦连接建立,用户就完成了认证。通常来说,它会提醒你输入密码。对于一些服务器,你将输入硬编码的密码。

一旦验证通过,你将可以通过本地的终端,键入命令去控制远程的机器。

指定不同的用户名

可以通过命令指定不同的用户登录:

ssh alternative-username@sample.ssh.com

也可以用下面的语法表示:

ssh -l alternative-username sample.ssh.com
在服务器上执行远程命令

ssh命令可以在不登录的情况下执行远程机器的命令。语法如下:

ssh hostname command

例如,执行下面的命令

ls /tmp/doc

在主机sample.ssh.com,键入下面的命令

ssh sample.ssh.com ls /tmp/doc

或者是

ssh root@192.169.33.32 ls /etc

注意:
1.在不登录的情况下,没次都需要输入root用户的密码。
2.若不指定用户名,则会登录到你本地的当前用户名账号。
例如:frankdeiMac:~ frank$ ssh 192.169.33.32
会提示输入:frank@192.169.33.32's password:

在远程服务器验证完后,远程目录中的内容将会被展示出来,而且你将返回自己的本地shell 终端。-x 禁用Disables X11转发。

退出ssh登录
exit
SSH客户端配置文件

ssh的配置文件位于~/.ssh/config。可查阅SSH client configuration file

SSH公钥认证

ssh-keygen以及ssh-copy-id,macOS的公钥位于 ~/.ssh/id_rsa.pub,windows的位于C:\Users\username.ssh\id_rsa.pub。

配置端口转发

可以本地转发(本地端口转发到服务器的Ip地址和端口)。可以远程转发(远程端口转发到客户端的Ip地址和端口)。
OpenSSH支持通过通道设备转发Unix 域名socket和IP 包,从而建立VPN(Virtual Private Network)。

#####SSH 命令行参数
下面是一些非常重要的OpenSSH客户端命令行参数。

  • 1 使用第1版本的协议
  • 2 使用第2版本的协议
  • 4 仅使用IPv4地址
  • 6 仅使用IPv6地址
  • A 开启代理认证转发
  • a 禁用代理认证转发
  • C 使用数据压缩
  • c cipher_spec 选择密码格式去加密session。
  • D [bind_address:]port 动态应用级端口转发。这会分配一个套接字来侦听本地端口。当与此端口建立连接时,将通过安全通道转发连接,然后使用应用程序协议确定从远程计算机连接的位置。
  • E log_file 添加一个debug日志到log_file而不是标准错误。
  • F configfile 指定用户的ssh配置文件,默认的位于~/.ssh/config。
  • g 允许远程主机链接到本地的转发端口。
  • i identity_file 认证文件,公钥文件。
  • J [user@]host[:port] 连接创建ssh连接到pjump主机(/iam/jump-host),然后建立一个TCP 转发到远程的机器。
  • l login_name 指定登录到远程机器的用户名
  • p 指定连接到远程机器的端口
  • q 安静模式
  • V 显示版本号
  • v冗余模式
  • X 执行X11转发
一个小历史

SSH在1990s取到了众多老旧的Unix和Linux命令行和协议。包括telnet,rlogin和rsh。
SSH运行在TCP/IP 22号端口。SSH诞生于1995年春天,这是一个telnet和FTP被大肆使用的年代。关于SSH如果得到22号端口,有一个很有趣的故事。how SSH got port 22

而关于SSH安全协议的由来,这里有一个作者本人的Youtube视频:https://youtu.be/OHBdKM7s5V4

参考:https://www.ssh.com/ssh/command/

@FrankKai
Copy link
Owner Author

FrankKai commented Aug 4, 2018

MQTT协议

以mqtt.js以及阿里云LMQ为例进行说明。

基础

  • MQTT解决了什么痛点?
    • MQTT全名为Message Queuing Telemetry Transport,中文名为消息队列遥测传输。
    • 是一种"发布-订阅"模式的消息协议,它工作在TCP/IP协议栈顶。
    • 为硬件性能低下的远程设备以及网络状况糟糕的情况下设计的发布/订阅型消息协议,因此,它需要一个消息中间件。
  • 什么是QoS?
    • Quality of Service ,指代消息传输的服务质量。
    • QoS0 最多分发一次 ,<=1。
    • QoS1 至少达到一次, >=1。
    • QoS2 仅分发一次,=1。
QoS 级别 cleanSession=true cleanSession=false
QoS0 无离线消息,在线消息只尝试推一次 无离线消息,在线消息只尝试推一次
QoS1 无离线消息,在线消息保证可达 有离线消息,所有消息保证可达
QoS2 无离线消息,在线消息保证只推一次
  • subscribe方法与message事件区别是什么?
    client.subscribe(topic(s))只是告诉服务端订阅哪些topic。
    message事件是对特定的topic做监听,function(topic,message,packet){},其中message是主要的用来增量更新当前聊天界面的数据,packet是基于mqtt-packet库的一个完整的packet。

参数说明:

{
  url,
  {
      username: accessKey,
      password: crypto.createHmac('sha1',secretKey).digest().toString('base64'),
      clientId: GroupID@@@DeviceID,
      clean: true, 
      reconnectPeriod: 3000,
      resubscribe: false,
  }
}

url: 又名broker,经纪人的意思。支持多种协议:mqtt,mqtts,tcp,tls,ws,wss。阿里云MQ接入地址,只要将Domain作为broker即可。
username:broker需要的用户名。阿里云控制台的AK,即accessKey。
password:broker需要的密码。阿里云控制台的SK,即secretKey,需要crypto加密,若使用nodejs,可以使用以下传入SK以及groupId,并调用标准库crypto进行加密:

const crypto = require('crypto');
const encrypto = (data) => {
  const { secret, groupId } = data;
  const HmacInstance = crypto.createHmac('sha1', secret);
  return HmacInstance.update(groupId).digest().toString('base64');
}
  • 为什么没有用node官方demo的sha256和'hex'输出?
    因为阿里云的LMQ消息中间件加密算法为sha1,Hmac码值为base64格式。
    传入secretKey和groupId,加密算法为sha1,最终生成的Hmac码为base64格式。
return crypto.createHmac('sha1',secretKey).update(groupId).digest().toString('base64');

clientID: 每个客户端的唯一标识。GroupID代表一类相同功能的设备。DeviceID代表独一无二的设备,例如传感器的序列号。
clean: 默认为true,设置为false,在离线时接收QoS 1(>=1条)或者QoS2(=1条) 级的消息。
reconnectPeriod: 1000毫秒,两次重新连接之间的间隔。
resubscribe: 如果连接断掉并且重连成功,自动再次订阅所有的topic。

参考:
https://github.com/mqttjs/MQTT.js
https://help.aliyun.com/document_detail/44879.html?spm=a2c4g.11186623.6.729.ma9gWc

@FrankKai
Copy link
Owner Author

FrankKai commented Aug 4, 2018

WebSocket协议

  • mqtt消息中的Opcode2是什么意思?
    Opcode标明了WebSocket帧的帧类型,值为0到15之间整型值。
Opcode Meaning
0 Continuation Frame
1 Text Frame
2 Binary Frame
8 Connection Close Frame
9 Ping Frame
10 Pong Frame
  • Ping Frame和Pong Frame是什么?
    控制帧。包括0x8(Close),0x9(Ping),0xA(Pong)。0xB-0xF是为未来预留的还未定义的控制帧。
    控制帧用于描述WebSocket的状态。它可以被插入在消息片段的间隔。
    所有控制帧都必须有一个小于等于125字节的payload,并且这125个字节的payload必须是连续的,不能是离散的。

    • Ping
      • 它可以包含应用数据。收到一个Ping 帧后,端点必须在响应中发送一个Pong帧,除非它已经接收到一个Close帧。实际操作中,应该尽快使用Pong帧回应它。
      • 端点在建立连接之后连接断开之前,在任何时间它都可能发送一个Ping帧。
      • Ping帧可以作为keepalive或作为一种手端,验证远程端点是否仍然响应。
    • Pong
      • Pong帧的opcode是0xA。
      • 发送给Ping帧作为响应的Pong帧,必须拥有独立的应用数据,它用来回复Ping帧的message body。
      • 如果一个端点接收到一个Ping帧,但是还没有发送Pong帧给之前的Ping帧,端点将选择最近接收到的Ping帧进行处理并且返回Pong帧。
      • Pong帧也可能是主动发送的。这是一个单向心跳。主动发出的Pong帧的响应式不可预期的。
  • Pings和Pongs:WebSockets心跳
    握手后的任何端点,无论是客户端还是服务端都可以选择给对方发一个ping帧。当接收到ping的时候,需要立即发送一个pong帧。你可以使用这个确保client处于连接状态。
    ping帧和pong帧只是普通的帧,但是它们是控制帧。Ping帧的opcode是0x9,Pong帧的opcode是0xA。当你得到一个ping帧时,返回一个与ping帧拥有相同负载的pong帧。(这2种帧的payload长度都是125。)也许你会在没发送ping帧时收到pong帧,当这种事情发生时忽略即可。
    如果在返回一个pong帧之前,收到很多很多ping帧,你只返回一个pong帧。
    参考:
    https://tools.ietf.org/html/rfc6455#section-6.1
    https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_servers-=

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant