主页

索引

模块索引

搜索页面

ssh命令

各参数含义:

-C 传输时压缩数据
-f 输入密码登陆后,ssh进入后台运行
-n 关闭标准输入
-N 不执行远程命令,只提供端口转发。仅用于ssh2协议
-g 允许远程主机连接ssh转发端口
-D 设置socks代理地址和监听端口,如果是只允许本地访问则指定IP为127.0.0.1
-l ssh登陆用户名
-i 指定ssh登陆用的私钥,如果是用公钥、私钥对登陆则需要指定
-q 安静模式
-o 指定options
-T Disable pseudo-terminal allocation.(禁止远程分配终端)
-t Force pseudo-terminal allocation.

选项

-vvvvv选项

打印5级debug日志:

ssh -vvvvv user@ip

-L选项(正向代理)

  • 相当于 iptable 的 port forwarding

命令:

-L [bind_address:]port:host:hostport
-L [bind_address:]port:remote_socket
-L local_socket:host:hostport
-L local_socket:remote_socket

用法1:把远程端口(C)映射到其他机器(B):

// HostB 上启动一个 PortB 端口,把 HostC:PortC 映射到 PortB 上
// 在 HostB 上运行:
$ ssh -L 0.0.0.0:PortB:HostC:PortC user@HostC

// 访问 HostB:PortB 相当于访问 HostC:PortC
// (和 iptable 的 port-forwarding 类似)

用法2:通过跳板(B)把远程端口(C)映射到本地端口(A):

// 说明
// HostA不能直接访问HostC,HostB可以访问HostC
// HostA 上启动一个 PortA 端口,通过 HostB 转发到 HostC:PortC上
// 在 HostA 上运行
$ ssh -L 0.0.0.0:PortA:HostC:PortC  user@HostB
// 这时访问 HostA:PortA 相当于直接访问 HostC:PortC(使用HostB为中介)


示例: 把远端的端口3306影射到本地的3308(把远端的mysql通过本地访问):
$ ssh -L 3308:<ip>:3306 <user>@<host>
// 因为本机不能访问mysql,但host机能访问mysql

备注

两种用法的区别是,第一种用法本地到跳板机 HostB 的数据是明文的,而第二种用法一般本地就是 HostA, 访问本地的 PortA,数据被 ssh 加密传输给 HostB 又转发给 HostC:PortC。

用法3:把远程机器端口(C)映射到本地端口(A):

$ ssh -L PortA:localhost:PortC user@HostC
// 注意: 这儿的 localhost 其实是在HostC上的localhost
// 本质是用法2的变种: HostB 和 HostC 是同一机器的情况

-R选项(反向代理)

  • 相当于 frp 或者 ngrok

命令:

-R [bind_address:]port:host:hostport
-R [bind_address:]port:local_socket
-R remote_socket:host:hostport
-R remote_socket:local_socket
-R [bind_address:]port

“反向代理”就是让远端启动端口,把远端端口数据转发到本地:

// HostA 将自己可以访问的 HostB:PortB 暴露给外网服务器 HostC:PortC,在 HostA 上运行
$ ssh -R HostC:PortC:HostB:PortB  user@HostC
// 链接 HostC:PortC 就相当于链接 HostB:PortB

使用时需修改 HostC 的 /etc/ssh/sshd_config 添加:

GatewayPorts yes

备注

相当于内网穿透,比如 HostA 和 HostB 是同一个内网下的两台可以互相访问的机器,HostC是外网跳板机,HostC不能访问 HostA,但是 HostA 可以访问 HostC。那么通过在内网 HostA 上运行 ssh -R 告诉 HostC,创建 PortC 端口监听,把该端口所有数据转发给我(HostA),我会再转发给同一个内网下的 HostB:PortB。同内网下的 HostA/HostB 也可以是同一台机器,换句话说就是内网 HostA 把自己可以访问的端口暴露给了外网 HostC。

备注

相当于再 HostA 上启动了 frpc,而再 HostC 上启动了 frps。

-D选项(socket5代理)

  • 相当于 ss/ssr

命令:

-D [bind_address:]port
  • 指定一个动态应用级端口做转发,然后可以在浏览器做代理,通过指定服务器进行访问(如翻墙):

    ssh -D 7070 username@yourserver.com
    

实例:

ssh -CfNg -D 0.0.0.0:1080 -l username xxx.xxx.xxx.xxx

-o选项(指定options)

命令:

-o option

常用options:

-oPort=6000: 指定连接时使用的端口号为 6000
-o 'ProxyCommand ...': 通过代理(proxy)连接到远程主机

ProxyCommand详解:

1. 通过 netcat 进行代理:
    ssh -o 'ProxyCommand nc -X 5 -x proxy-server:1080 %h %p' user@remote-host

2. 通过 socat 进行代理:
    ssh -o 'ProxyCommand socat - PROXY:proxy-server:%h:%p,proxyport=1080' user@remote-host

3. 通过 sshuttle 进行代理:
    ssh -o 'ProxyCommand sshuttle -r user@proxy-server %h:%p' user@remote-host

4. 通过 corkscrew 进行代理:
    ssh -o 'ProxyCommand corkscrew proxy-server 8080 %h %p' user@remote-host

-t选项

  • 在 SSH 连接中分配一个伪终端(pseudo-terminal)

  • This can be used to execute arbitrary screen-based programs on a remote machine, which can be very useful, e.g. when implementing menu services.

  • Multiple -t options force tty allocation, even if ssh has no local tty.

  • 通常用于在远程服务器上执行交互式命令或程序。

  • 它会告诉 SSH 客户端在远程服务器上打开一个伪终端,以便用户可以与远程服务器进行交互,就像直接在本地终端中执行命令一样。

  • 使用 -t 选项可以确保在 SSH 连接中正确处理输入和输出,使得用户可以正确地与远程服务器进行交互。

sshd命令

安装:

sudo apt install openssh-server

周边ssh命令

ssh-keygen命令

// 删除known_hosts中对应host/ip的记录
ssh-keygen -R <hostname>
ssh-keygen -R <ip_address>

// 显示key and ascii art representation
ssh-keygen -l -f <filePath>
ssh-keygen -lv -f ~/.ssh/known_hosts  //以图形化的方式展示

// 生成pem格式的密钥
ssh-keygen -t rsa -m pem
// 生成到指定文件
ssh-keygen -t rsa -m pem -f <file>.pem

ssh-add命令相关

// ssh-add命令是把专用密钥添加到ssh-agent的高速缓存中
// 语法
ssh-add [-cDdLlXx] [-t life] [file ...]
ssh-add -s pkcs11
ssh-add -e pkcs11

选项:

-D: 删除ssh-agent中的所有密钥.
-d: 从ssh-agent中的删除密钥
-e: pkcs11:删除PKCS#11共享库pkcs1提供的钥匙。
-s: pkcs11:添加PKCS#11共享库pkcs1提供的钥匙。
-L: 显示ssh-agent中的公钥
-l: 显示ssh-agent中的密钥
-t: life:对加载的密钥设置超时时间,超时ssh-agent将自动卸载密钥
-X: 对ssh-agent进行解锁
-x: 对ssh-agent进行加锁

实例:

把专用密钥添加到 ssh-agent 的高速缓存中:
ssh-add ~/.ssh/id_dsa
2、从ssh-agent中删除密钥:
ssh-add -d ~/.ssh/id_xxx.pub
3、查看ssh-agent中的密钥:
ssh-add -l

mac专用 [1]:

-K: When adding identities, each passphrase will also be stored in the user's keychain.
  When removing identities with -d, each passphrase will be removed from it.
$ ssh-add -K [path/to/your/ssh-key]

ssh-copy-id

ssh-copy-id 将本机的公钥复制到远程机器的authorized_keys文件中,ssh-copy-id也能让你有到远程机器的home, ~./ssh , 和 ~/.ssh/authorized_keys的权利

用ssh-copy-id将公钥复制到远程机器中:

$  ssh-copy-id -i .ssh/id_rsa.pub  username@192.168.x.xxx

sshpass

安装:

# yum install sshpass
$ sudo apt-get install sshpass

Usage:

 sshpass [-f|-d|-p|-e] [-hV] command parameters
-f filename   Take password to use from file
-d number     Use number as file descriptor for getting password
-p password   Provide password as argument (security unwise)
-e            Password is passed as env-var "SSHPASS"
With no parameters - password will be taken from stdin

示例:

$ export SSHPASS='my_pass_here'
$ sshpass -e ssh aaronkilik@10.42.0.1

如何使 SSH 会话保持活动状态

client配置 emacs ~/.ssh/config

Host *
ServerAliveInterval 120
ServerAliveCountMax 30
  • Host: The configurations specified only apply to the hosts listed following the “Host” keyword. Because we used a wildcard character (*), they apply to all hosts.

  • ServerAliveInterval: Sets a timeout interval in seconds, after which, if no data has been received from the server, SSH will send a message through the encrypted channel to request a response from the server. The default is 0, indicating that these messages will not be sent to the server.

  • ServerAliveCountMax: Sets the number of server alive messages which may be sent without SSH receiving any messages back from the server. If this threshold is reached while server-alive messages are being sent, SSH will disconnect from the server, terminating the session. The default value is 3.

server配置 emacs /etc/ssh/sshd_config

TCPKeepAlive yes
ClientAliveInterval 120
ClientAliveCountMax 30
  • TCPKeepAlive: Specifies whether the system should send TCP keepalive messages to the client.

  • ClientAliveInterval: Sets a timeout interval in seconds, after which, if no data has been received from the client, the SSH server will send a message through the encrypted channel to request a response from the client. The default is 0, indicating that these messages will not be sent to the client.

  • ClientAliveCountMax: Sets the number of client alive messages which may be sent without the SSH server receiving any messages back from the client. If this threshold is reached while client-alive messages are being sent, the SSH server will disconnect the client, terminating the session. The default value is 3.

【问题解决】避免SSH连接因超时闲置断开:

用SSH过程连接电脑时,经常遇到长时间不操作而被服务器踢出的情况,常见的提示如:
  Write failed: Broken pipe

这是因为如果有一段时间在SSH连接上无数据传输,连接就会断开。解决此问题有以下几种方法:

1. 修改 ``/etc/ssh/ssh_config`` 文件(可分在服务器端还是客户端)(需要root权限):
  * 在客户端设置, 添加如下一行(此后该系统里的用户连接SSH时,每60秒会发一个KeepAlive请求,避免被踢):

       ServerAliveInterval 60

  * 在服务器端设置, 添加如下设置(应注意启用该功能后,安全性会有一定下降[比如忘记登出时……]):

      ClientAliveInterval 60


  * 注意,执行完上面修改后,需要重启sshd服务::

      service sshd reload


2. 修改 ``~/.ssh/config`` 文件,在此文件中增加如下一句::

  ServerAliveInterval 60

  保存退出,重新开启用户的shell,则再ssh远程服务器的时候,不会因为长时间操作断开。应该是加入这句之后,ssh客户端会每隔一段时间自动与ssh服务器通信一次,所以长时间操作不会断开。

3. 修改 ``/etc/profile`` 配置文件,增加::

  TMOUT=1800
  这样30分钟没操作就自动LOGOUT

4. 利用expect 模拟键盘动作,在闲置时间之内模拟地给个键盘响应,将下列代码保存为xxx,然后用expect执行::

  #!/usr/bin/expect
  set timeout 60
  spawn ssh user@host
        interact {
          timeout 300 {send "\x20"}
        }
  expect xxx

  接着按提示输入密码就可以了,这样每隔300秒就会自动打一个空格(\x20),具体的时间间隔可以根据具体情况设置。

5. 如果你在windows下通过工具连接,可以设置为
  secureCRT:选项---终端---反空闲 中设置每隔多少秒发送一个字符串,或者是NO-OP协议包
  putty:putty -> Connection -> Seconds between keepalives ( 0 to turn off ), 默认为0, 改为300.

常见问题

* Agent admitted failure to sign using the key.
* Permission denied (publickey,gssapi-with-mic).
* Permission denied (publickey,keyboard-interactive).
* Permission denied (publickey,password).    // 3次密码输入错误
* ssh_exchange_identification: read: Connection reset by peer(1.运营商2.尝试次数太多ip被防火墙干掉了)

常见问题 => Too many authentication failures:

  >> ssh root@58.56.108.133
  Received disconnect from 58.56.108.133: 2: Too many authentication failures for root

//原因: .ssh/文件夹下面的东西太多了

ssh中“Host key verification failed.“的解决方案:

这个问题的原理和比较长久的解决方案:

用OpenSSH的人都知ssh会把你每个你访问过计算机的公钥(public key)都记录在~/.ssh/known_hosts
当下次访问相同计算机时,OpenSSH会核对公钥。如果公钥不同,OpenSSH会发出警告,避免你受到DNS Hijack之类的攻击
SSH对主机的public_key的检查等级是根据StrictHostKeyChecking变量来配置的
默认情况下,StrictHostKeyChecking=ask
简单所下它的三种配置值:

    1.StrictHostKeyChecking=no
    # 最不安全的级别,当然也没有那么多烦人的提示了,相对安全的内网测试时建议使用
    # 如果连接server的key在本地不存在,那么就自动添加到文件中(默认是known_hosts),并且给出一个警告

    2.StrictHostKeyChecking=ask
    # 默认的级别,就是出现刚才的提示了
    如果连接和key不匹配,给出提示,并拒绝登录

    3.StrictHostKeyChecking=yes  #最安全的级别,如果连接与key不匹配,就拒绝连接,不会提示详细信息

对于我来说,在内网的进行的一些测试,为了方便,选择最低的安全级别
在.ssh/config(或/etc/ssh/ssh_config)中配置:

StrictHostKeyChecking no
UserKnownHostsFile /dev/null

Unable to negotiate with xxxxx no matching host key type found. Their offer: ssh-rsa:

// : Mac发现的此问题
HostKeyAlgorithms +ssh-rsa
PubkeyAcceptedKeyTypes +ssh-rsa

示例:
Host ssh.zhaoweiguo.com
HostName ssh.zhaoweiguo.com
User zwg
Port 22
HostKeyAlgorithms +ssh-rsa
PubkeyAcceptedKeyTypes +ssh-rsa

原因:
    8.8p1 版的 openssh  ssh 客户端默认禁用了 ssh-rsa 算法, 但是对方服务器只支持 ssh-rsa

    # OpenSSH7.0 以后的版本不再支持 ssh-dss (DSA) 算法,官方的说法是这个算法太弱了
    # MACOS 升到 10.12 附带的 openssh版本是 7.4
    # 方法 1 终端命令添加 -oHostKeyAlgorithms=+ssh-rsa 如: ssh -oHostKeyAlgorithms=+ssh-rsa user@xxx
    # 方法 2 追加以下内容

有了openssh密钥,如何生成putty ssh密钥:

假设openssh的私钥名为Identity则,在linux上,使用puttygen命令如下:
  puttygen Identity -o Identity.ppk -O private

这样可以使用生成的.ppk文件登陆openssh服务器了

如何实现只能通过ssh私钥登录:

修改/etc/ssh/sshd_config文件:
  PermitRootLogin no          //修改为no(禁止root登陆)
  PubkeyAuthentication yes    //允许ssh登陆
  AuthorizedKeysFile     .ssh/authorized_keys         //設定ssh登陆
  PasswordAuthentication no              //禁止密码登陆

  //可以让你在远程机器上执行gui程序然后在"本地"显示图形
  AllowTcpForwarding yes
  X11Forwarding yes

ssh服务相关文件:

> cat /etc/ssh/sshd_config
AuthorizedKeysFile      %h/.ssh/authorized_keys
PasswordAuthentication   no: 指定不允许密码登录
PermitRootLogin          no: 不允许root用户登陆
Port                     22: 指定登录端口,默认TCP 22端口
AllowUsers happy test kaixin   指定允许登录用户

ChallengeResponseAuthentication yes: @todo 未知是做啥的(估计是用于expect脚本登录)

.ssh/config文件内容格式:

host eqitonghub
user git
hostname 60.216.116.245
port 22
identityfile ~/.ssh/gordon.git

mac使用跳板机时, 每次重启机器都要执行一次ssh-add命令输入密码 [1]:

原因:
ssh-add 这个命令不是用来永久性的记住你所使用的私钥的
实际上,它的作用只是把你指定的私钥添加到 ssh-agent 所管理的一个 session 当中
而 ssh-agent 是一个用于存储私钥的临时性的 session 服务
也就是说当你重启之后,ssh-agent 服务也就重置了。

解决:
Mac 系统内置了一个 Keychain 的服务及其管理程序,可以方便的帮你管理各种秘钥,其中包括 ssh 秘钥
ssh-add 默认将制定的秘钥添加在当前运行的 ssh-agent 服务中
  但是你可以改变这个默认行为让它添加到 keychain 服务中,让 Mac 来帮你记住、管理并保障这些秘钥的安全性

主页

索引

模块索引

搜索页面