当前位置 : 首页 » 文章分类 :  开发  »  SSH笔记

SSH笔记

SSH 笔记


ssh 命令

远程登录

常用格式:
ssh [-l login_name] [-p port] [user@]hostname
若不指定用户直接 ssh hostname,默认是用当前机器的用户登录,例如本机用户为user1,则 ssh hostname 等于 ssh user1@hostname

-p 指定远程服务器上的端口;
-i 指定身份文件;
-l 指定连接远程服务器登录用户名,可以用 user@ip 代替
-o 指定配置选项, 比如在命令行指定代理服务器
-1:强制使用ssh协议版本1;
-2:强制使用ssh协议版本2;
-4:强制使用IPv4地址;
-6:强制使用IPv6地址;
-A:开启认证代理连接转发功能;
-a:关闭认证代理连接转发功能;
-b:使用本机指定地址作为对应连接的源ip地址;
-C:请求压缩所有数据;
-F:指定ssh指令的配置文件;
-f:后台执行ssh指令;
-g:允许远程主机连接主机的转发端口;
-N:不执行远程指令;
-q:静默模式;
-X:开启X11转发功能;
-x:关闭X11转发功能;
-y:开启信任X11转发功能。

例如:
1、指定root用户登录,
ssh root@192.168.25.169ssh -l root 192.168.25.169
回车后再输入169上root用户的密码。

2、指定端口登录
ssh -p 10022 user@hostname
在某些 Windows 上,不能使用 -p 参数指定端口,需要使用 ip后空格加端口号的方式指定端口号,例如 ssh admin@127.0.0.1 222

3、指定密钥文件登录
ssh -p 10022 user@hostname -i ~/.ssh/id_rsa

登录到指定目录

ssh user@hostname -t 'cd /apps/app1/logs; bash --login'
或者
ssh user@hostname -t 'cd /apps/app1/logs; sh -i'

登陆后立即执行命令

ssh user@hostname -t 'ls -l; bash --login'
或者
ssh user@hostname -t 'ls -l; sh -i'

登出/退出 logout/exit

ssh登录远程服务器后,输入命令 logoutexit 即可退出,回到本地bash。
两者的区别如下:

[xxxx@t-awsbj-xxxxxx ~]$ exit
登出
Connection to 10.125.1.1 closed.

[xxxx@t-awsbj-xxxxxx ~]$ logout

Connection to 10.125.1.1 closed.

ssh -V 查看ssh版本

$ ssh -V
OpenSSH_7.1p2, OpenSSL 1.0.2g  1 Mar 2016

设置ssh超时时间

基于安全的理由,如果用户连线到 SSH Server 后闲置,SSH Server 会在超过特定时间后自动终止 SSH 连线。
为了避免总是被强行退出,可设置ssh超时时间。

编辑 sshd_config 配置文件
sudo vi /etc/ssh/sshd_config

默认配置如下

#ClientAliveInterval 0
#ClientAliveCountMax 3

ClientAliveInterval 指定了服务器端向客户端请求 no-op 包的时间间隔, 默认是0, 不发送。设置60表示每60秒发送一次, 然后客户端响应, 这样就保持长连接了。
ClientAliveCountMax 表示服务器发出请求后客户端没有响应的次数达到一定值, 就自动断开。正常情况下, 客户端不会不响应,使用默认值3即可。

改为:

ServerAliveInterval 60
ServerAliveCountMax 3

修改后重新启动 sshd 服务
service sshd restart

另一种方式:
不修改配置文件,设置单词会话的超时时间:
在命令参数里 ssh -o ServerAliveInterval=60 这样子只会在需要的连接中保持持久连接, 毕竟不是所有连接都要保持持久的


代理环境下使用ssh

ProxyCommand命令

命令格式:
ProxyCommand connect 代理服务器地址 端口 %h %p
ProxyCommand corkscrew 代理服务器地址 端口 %h %p
ProxyCommand 其他代理软件 代理服务器地址 端口 %h %p
其中 %h 表示目标地址, %p 是目标端口。这句可以用在命令行里。

其中connect和corkscrew是用于连接的程序。Windows用户下载安装了msysgit,里面就有connect程序。或者使用corkscrew这个软件。
如果使用corkscrew,那么下载后解压缩,把corkscrew.exe和cygwin1.dll拷贝到msysgit的bin目录中。

ssh配置文件形式

1、使用 connect 代理工具

Host github.com *.github.com
    ProxyCommand connect -H 172.17.18.80:8080 %h %p   #设置代理

2、使用 ncat 代理工具
MacOSX 的默认 nc 和 Linux 的 nc 不不同. 因此 MacOSX 需要安装 nmap 软件包. 通过 brew install nmap 可以安装. 或者⾃自⾏行行使⽤用其他⽀支持http协议的工具亦可.

# vim ~/.ssh/config
# mac osx
Host github.com
  ProxyCommand /usr/local/bin/ncat --proxy proxy.nioint.com:8080 --proxy-type http %h %p

# linux
Host github.com
    ProxyCommand nc -x proxy.int.com:8080 %h %p

命令行指定代理服务器

使用 ncat 代理工具

# mac
ssh -o 'ProxyCommand=/usr/local/bin/ncat --proxy proxy.int.com:8080 --proxy-type http %h %p' 10.110.0.8

# linux
ssh -o 'ProxyCommand=nc -x proxy.int.com:8080 %h %p' 10.110.0.8

需要密码认证的代理

如果HTTP代理需要用户名/密码验证,则需要写上代理验证文件。假设代理服务器是192.168.0.1:808。用户名密码是name:pass,打算存放在/.ssh/proxyauth。则有
ProxyCommand corkscrew 192.168.0.1 808 %h %p ~/.ssh/proxyauth
新建
/.ssh/proxyauth文件,写上
name:pass


ssh配置

配置文件~/.ssh/config和/etc/ssh/ssh_config

一般不需要修改 OpenSSH 客户端配置文件。对于给定用户,共有两个配置文件:

  • ~/.ssh/config:用户配置
  • /etc/ssh/ssh_config:全局配置

编写好 config 文件之后,需要把 config 文件的权限改为 rw-r–r–。如果权限过大,ssh 会禁止登录。c

要按照该顺序读取这些文件,对于给定的某个参数,它使用的是读取过程中发现的第一个配置。用户可以通过以下方式将全局参数设置覆盖掉:在自己的用户配置文件中设置同样的参数即可。在ssh或scp命令行上给出的参数的优先级要高于这两个文件中所设置的参数的优先级。
用户的/.ssh/config文件必须由该用户所有(他是目录”/“的所有者),并且除了所有者之外任何人都不能写入该文件。否则客户端就会给出一条错误消息然后退出。这个文件的模式通常被设为600,这是因为除了它的所有者之外任何人没有理由能够读取它。
这些配置文件中的配置行包含着声明,这些声明均以某个关键字(例如Host,Port,User不区分大小写)开头,后面跟着空格,最后是参数(区分大小写)。可以使用关键字Host,让声明只作用于特定的主机。Host声明作用于它与下一条Host声明之间的所有配置行

config配置示例

Host example                       # 关键词
    HostName example.com           # 主机地址
    User root                      # 用户名
    # IdentityFile ~/.ssh/id_ecdsa # 认证文件
    # Port 22                      # 指定端口

Host配置

Host 用于我们执行 SSH 命令的时候如何匹配到该配置。
Host 可以使用通配符,当ssh的时候如果server的URL能match上这里Host指定的值,则Host下面指定的HostName将被作为最终URL使用。同时该Host下配置的User, Port都将被使用。
*代表0~n个非空白字符,?代表一个非空白字符,!表示例外通配。

例如:
*,匹配所有主机名。
*.example.com,匹配以 .example.com 结尾。
!*.dialup.example.com,*.example.com,以!开头是排除的意思。
192.168.0.?,?代表单个字符,匹配 192.168.0.[0-9] 的 IP。

例如:
1、使用指定别名登录到 www.hi-linux.com 这台主机:

Host www
    HostName www.hi-linux.com
    Port 22
    User root
    IdentityFile  ~/.ssh/id_rsa
    IdentitiesOnly yes

直接ssh www即可登录

2、不同主机使用同一私钥进行登陆:

Host github.com git.coding.net
    HostName %h
    Port 22
    User git
    IdentityFile  ~/.ssh/id_rsa_blog
    IdentitiesOnly yes

3、连接 114.80.119.* 时自动使用jackie用户名:

Host 114.80.119.*
  User jackie
  Port 22

4、连接10.125.开头的所有服务器时都使用id_rsa私钥,都自动使用xiaoy用户名,并且都用2222端口

Host 10.125.*
    IdentityFile ~/.ssh/id_rsa
    User xiaoy
    Port 2222

其中id_rsa是私钥,公钥已放在对应的服务器上,此后就可以将之前的登录命令
ssh -i ~/.ssh/id_rsa -p 2222 xiaoy@10.125.1.1
简化为
ssh 10.125.1.1

5、不同域名使用不同私钥,并且都走代理

Host github.com *.github.com
    ProxyCommand connect -H 172.17.18.80:8080 %h %p   #设置代理
    IdentityFile ~/.ssh/id_rsa

Host git.oschina.net
    ProxyCommand connect -H 172.17.18.80:8080 %h %p   #设置代理
    IdentityFile ~/.ssh/oschina_rsa

配置文件~/.ssh/config和/etc/ssh/ssh_config
http://book.51cto.com/art/200906/126284.htm

SSH Config 那些你所知道和不知道的事
https://deepzz.com/post/how-to-setup-ssh-config.html


ControlMaster 多连接共享

如果你需要在多个窗口中打开到同一个服务器的连接,而不想每次都输入用户名,密码,或是等待连接建立,那么你可以配置 SSH 的连接共享选项。
SSH 支持 ControlMaster 模式,可以复用之前已经建立的连接。所以开启这个功能之后,如果已经有一条到某个 host 的连接,那么再连接的时候,就不需要再输入密码了。
ControlMaster 配合 ControlPath 一起使用。

编辑 ~/.ssh/config 配置文件

Host *
    ControlMaster auto
    ControlPath ~/.ssh/master-%r@%h:%p

%r 表示远程登录的用户,%h 表示目标地址,%p 是目标端口

ControlPersist 连接保持

ControlPersist 参数的含义就是在最后一个连接关闭之后也不真正的关掉连接,这样后面再连接的时候就还是不用输入密码。
SSH 版本必须是 5.6 或以上版本才可使用 ControlPersist 特性。

ControlPersist yes 打开之后即使关闭了所有的已连接ssh连接,一段时间内也能无需密码重新连接。
ControlPersist 4h 每次通过 SSH 与服务器建立连接之后,这条连接将被保持4个小时,即使在你退出服务器之后这条连接依然可以重用,因此,在你下一次(4小时之内)登录服务器时,你会发现连接以闪电般的速度建立完成,这个选项对于通过scp拷贝多个文件提速尤其明显,因为你不在需要为每个文件做单独的认证了。

编辑 ~/.ssh/config 配置文件

Host *
    ControlPersist 4h
    ControlMaster auto
    ControlPath ~/.ssh/master-%r@%h:%p

root账户无密码登录

为了安全起见,FreeBSD默认情况下是不允许root用户进行SSH远程登录的

PermitLocalCommand和LocalCommand

PermitLocalCommand
是否允许指定 LocalCommand,值可以为 no(default)/yes。

LocalCommand
指定在连接成功后,本地主机执行的命令(单纯的本地命令)。可使用 %d,%h,%l,%n,%p,%r,%u,%C 替换部分参数。只在 PermitLocalCommand 开启的情况下有效。

但如果我如下配置,登录能成功但会提示 zsh:1: no such file or directory: cd /data/log/uds_relation/ ,这个目录确实存在但就是提示找不到
因为 LocalCommand 中配置的命令是作为一个参数传递给 /bin/sh -c <localcommand>

Host relation-test
    HostName 10.125.22.13
    IdentityFile ~/.ssh/si.ma.private_key
    User si.ma
    Port 2222
    PermitLocalCommand yes
    LocalCommand "cd /data/log/uds_relation/"

How can I automatically change directory on ssh login?
https://serverfault.com/questions/167416/how-can-i-automatically-change-directory-on-ssh-login


ssh公钥私钥免密登录

ssh 公钥认证是 ssh 认证的方式之一。通过公钥认证可实现 ssh 免密码登陆,git 的 ssh 方式也是通过公钥进行认证的。

ssh-keygen 生成密钥对

在客户端使用 ssh-keygen 命令生成密钥对。
使用 ssh-keygen 时,请先进入到 ~/.ssh 目录,不存在的话,请先创建。并且保证 ~/.ssh 以及所有父目录的权限不能大于 711

ssh 无密码登录要使用公钥与私钥,linux 下可以用用 ssh-keygen 命令生成公钥/私钥对
命令格式:
ssh-keygen -t type [-C comment] [-P ''] [-f output_keyfile]
参数说明:
-t type,指定要创建的密钥类型,type可取值为”rsa1”(SSH-1) “rsa”(SSH-2) “dsa”(SSH-2),默认为为rsa
-C comment,提供一个新注释,一般用邮箱做注释
-f output_keyfile,指定密钥文件名,如果不指定执行命令时会提示输入文件名,使用rsa密码的话默认为 ~/.ssh/id_rsa 和 id_rsa.pub
-P passphrase,表示密码passphrase,-P '' 就表示空密码,也可以不用-P参数,这样就要三个回车,用 -P 就一次回车。

例如:
ssh-keygen -P ''
生成密钥对, 使用默认加密算法rsa,空密码,默认文件名,得到私钥文件 id_rsa,公钥文件 id_rsa.pub

ssh-keygen -t rsa -P ''
加密类型为rsa,密码为空,回车后输入文件名(直接回车就是默认文件名id_rsa和id_rsa.pub),该命令将在~/.ssh目录下面产生一对密钥id_rsa和id_rsa.pub,分别为私钥和公钥。

ssh-keygen -P '' -f ~/.ssh/bwg_rsa
加密类型为默认的rsa,密码为空,指定输出文件名为bwg_rsa,会在~/.ssh目录下生成bwg_rsa私钥文件和bwg_rsa.pub公钥文件

ssh-keygen 查看私钥对应的公钥

使用 ssh-keygen 命令可以查看私钥对应的公钥

ssh-keygen -y -f /path_to_key_pair/my-key-pair.pem

ssh-add

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

ssh-keyscan

ssh-keyscan 是一个用于收集大量主机的 ssh 主机公钥的实用程序。该实用程序用于帮助生成和验证 ssh_known_hosts 文件。
例如
ssh-keyscan -t rsa github.com >> ~/.ssh/known_hosts

服务端配置公钥

把公钥 id_rsa.pub 上传到要访问的机器上
一、图形界面方式,比如上传到 Github 网站指定位置上
二、终端访问方式,在要访问的机器上创建 ~/.ssh 目录,把公钥内容复制到 ~/.ssh/authorized_keys 文件里(没有则新建此文件)。如果有修改配置 /etc/ssh/sshd_config,需要重启ssh服务器 /etc/init.d/ssh restart

方式二的具体步骤
1、创建 .ssh 目录 和 authorized_keys 文件
mkdir -p ~/.ssh && touch ~/.ssh/authorized_keys

2、修改权限
chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys

3、拷贝公钥到 authorized_keys 中

注意:如果是用 root 账号 创建的 .ssh 目录 和 authorized_keys 文件,还需要把 .ssh 的 owner 改为实际登录的账户
chown -R your_username:your_username /home/your_username/.ssh

Use Public Key Authentication with SSH
https://www.linode.com/docs/security/authentication/use-public-key-authentication-with-ssh/

配置/etc/ssh/sshd_config

使用终端方式时,还需要对服务器做如下配置,打开 ssh 的密钥对登录,指定公钥文件为 ~/.ssh/authorized_keys

vim /etc/ssh/sshd_config
#禁用root账户登录,非必要,但为了安全性,请配置
PermitRootLogin no

# 是否让 sshd 去检查用户家目录或相关档案的权限数据,
# 这是为了担心使用者将某些重要档案的权限设错,可能会导致一些问题所致。
# 例如使用者的 ~.ssh/ 权限设错时,某些特殊情况下会不许用户登入
StrictModes no

# 是否允许用户自行使用成对的密钥系统进行登入行为,仅针对 version 2。
# 至于自制的公钥数据就放置于用户家目录下的 .ssh/authorized_keys 内
RSAAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysFile      %h/.ssh/authorized_keys

#有了证书登录了,就禁用密码登录吧,安全要紧
PasswordAuthentication no

配置多个公钥

假如想从多台客户端连接此服务器,可以分别生成各自的密钥,然后把公钥文件中的内容追加到 ~/.ssh/authorized_keys 文件的末尾。
注意追加前authorized_keys文件的末尾需要有个换行符。


ssh-copy-id

ssh-copy-id [-i [identity_file]] [user@]machine

ssh-copy-id 命令可以把本地公钥文件安装到远程主机对应的账户下。
也就是将 ssh-keygen 命令生成的公钥填充到一个远程机器上的 ~/.ssh/authorized_keys 文件中。
其实就是自动进行了:
1 登录远程主机
2 编辑 authorized_keys 文件
3 把本地的公钥贴进去
这几个动作。


SecureCRT/XShell 客户端配置私钥

客户端通过私钥id_rsa登录ssh服务器:
1、SecureCRT设置方法:properties->Connection->SSH2->Authentication->PublicKey->选择私钥id_rsa

2、XShell设置方法:属性-连接-用户身份验证-用户密钥

3、或者不在终端软件中设置,每次指定私钥:
ssh登录命令:
ssh -i ~/.ssh/id_rsa -p 22 username@<ssh_server_ip>
scp命令:
scp -i ~/.ssh/id_rsa filename username@<ssh_server_ip>:~/

为了避免每次都手动指定密钥,可以在ssh的配置文件中指定:
编辑~/.ssh/config配置文件,针对不同host指定不同的私钥文件

ssh证书登录(实例详解)
https://www.cnblogs.com/ggjucheng/archive/2012/08/19/2646346.html


问题

设置公钥后仍需密码登录

网上给出的最多的解释是:不能让所有者之外的用户对authorized_keys文件有写权限,否则,sshd将不允许使用该文件,因为它可能会被其他用户篡改。
如果authorized_keys文件、/.ssh目录 或 ~目录让本用户之外的用户有写权限,那么sshd都会拒绝使用 ~/.ssh/authorized_keys 文件中的key来进行认证的。
所以需要将group或others的w权限去掉,比如chmod g-w ~/.ssh/authorized_keys

chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
但我这样试了,还是不行,还是需要密码。
最后google了一下,http://serverfault.com/questions/396935/ssh-keys-authentication-keeps-asking-for-password
里提供的方法解决了,使用命令
ssh-copy-id user@remote_server
会自动将id_rsa.pub公钥文件拷贝到远程主机remote_server上,自动生成
/.ssh/authorized_keys文件,然后免密登录成功。
之后若还有其他主机想免密登录到remote_server,将其id_rsa.pub公钥scp拷贝到remote_server上,cat id_rsa.pub >> authorized_keys 追加到授权文件中即可。
所以我感觉可能还是authorized_keys文件内容出错了,手动拷贝出了问题。

私钥权限过大无法登陆

确保 ssh私钥 文件具有权限 0400 而不是 0777。
否则登录时提示:
错误:未保护的私钥文件

在mac使用时,0644的权限都不行:

xxxxx  ~/.ssh  ssh aws
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0644 for '/Users/xxx/.ssh/xxx.pem' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
Load key "/Users/xxxx/.ssh/xxxx.pem": bad permissions
ec2-user@ec2-xxxxxx.us-west-2.compute.amazonaws.com: Permission denied (publickey,gssapi-keyex,gssapi-with-mic).

必须保护您的私钥文件,防止其他任何用户对其进行读写操作。如果除您外其他任何人都能够读取或写入您的私钥,则 SSH 会忽略您的密钥
获取您在启动实例时指定的密钥对的 .pem 文件在您电脑上位置的完全限定路径。确保 .pem 文件具有权限 0400 而不是 0777。
chmod 0400 .ssh/my_private_key 改小私钥文件的权限

Bad owner or permissions on .ssh/config

自己新建的 config 文件,全年过大,改小权限即可。
sudo chmod 600 config


私钥文件所有者非当前用户导致Permission denied (publickey)

生产密钥并添加到 GitHub 后还是提示
Permission denied (publickey)

ssh -vT git@github.com 显示 ssh 找不到 私钥文件

> ...
> debug1: identity file /Users/you/.ssh/id_rsa type -1
> debug1: identity file /Users/you/.ssh/id_rsa-cert type -1
> debug1: identity file /Users/you/.ssh/id_dsa type -1
> debug1: identity file /Users/you/.ssh/id_dsa-cert type -1
> ...
> debug1: Authentications that can continue: publickey
> debug1: Next authentication method: publickey
> debug1: Trying private key: /Users/you/.ssh/id_rsa
> debug1: Trying private key: /Users/you/.ssh/id_dsa
> debug1: No more authentication methods to try.
> Permission denied (publickey).

最后发现是使用 ssh-keygen 命令生成密钥对时加了 sudo 导致文件拥有者是 root ,当前用户无权限读取密钥文件
修改密钥拥有者为当前用户即可

sudo chown -R ec2-user github github.pub
sudo chgrp -R ec2-user github github.pub

Error: Permission denied (publickey)
https://help.github.com/en/articles/error-permission-denied-publickey


上一篇 Hexo博客(03)源码备份及不同电脑上的同步问题

下一篇 Hexo博客(02)安装Hexo生成博客并部署到GitHub

阅读
评论
5k
阅读预计20分钟
创建日期 2016-03-25
修改日期 2023-03-28
类别
标签

页面信息

location:
protocol:
host:
hostname:
origin:
pathname:
href:
document:
referrer:
navigator:
platform:
userAgent:

评论