目录
1. SSH 笔记
1.1. 查看 SSH 状态
查看是否安装:
rpm -qa | grep ssh
查看服务状态:
ps -e |grep ssh
ps -ef | grep ssh
或:
/etc/init.d/ssh status
重启 SSH 服务:
service sshd restart
# 或:
/etc/init.d/ssh restart
1.2. SSH 软件安装
安装服务端:
# Debian
$ sudo apt-get install openssh-server -y
# RedHat
$ sudo yum install openssh-server -y
安装客户端:
# Debian
$ sudo apt-get install openssh-clients -y
# RedHat
$ sudo yum install openssh-clients -y
1.3. 开启多个 SSH 端口
# verify settings.
$ sshd -t
# apply changes.
$ systemctl restart ssh.service
$ /etc/init.d/sshd restart
# sshd also offers the -f flag to supply an alternative options file.
$ /usr/sbin/sshd -f /etc/ssh/sshd_config_custom
1.3.1. Same Daemon on Different Ports
$ echo -e 'Port 666\nPort 667' >> /etc/ssh/sshd_config && sshd -t && systemctl restart ssh.service
1.3.2. Two Daemons on Two Ports
$ /usr/sbin/sshd -f /etc/ssh/sshd_config_internal
Autostart:
cp /lib/systemd/system/ssh.service /lib/systemd/system/ssh_internal.service
# configure the Exec* lines of /lib/systemd/system/ssh_internal.service to the appropriate values by adding the -f switch with the proper file path where necessary
# ...
$ systemctl enable ssh_internal
$ systemctl start ssh_internal
2. SSH 软件配置
2.1. SSH 配置文件选项
SSH 配置文件: /etc/ssh/sshd_config
- 当使用 RSA Key 进行授权登录时要打开下面两个选项:
RSAAuthentication yes
PubkeyAuthentication yes
- 为了安全, 禁用 root 用户登录 (前提是已有其它用户) 和密码登录:
PermitRootLogin no
PasswordAuthentication no
2.2. SSH 相关的防火墙设置
查看本博客防火墙相关文章。
2.3. ssh 登陆进去后, .bashrc
也没有被执行
查了一下, ssh login 之后, 会执行 .bash_profile
于是新建一个 .bash_profile
, 内容如下
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
3. SSH 软件使用实例
3.1. 生成 RSA 公钥和私钥
3.1.1. 方法 1: 生成时自动复制进系统目录下
ssh-keygen -t rsa -b 4096 -C "1@qq.com"
3.1.2. 方法 2: 生成时指定了公钥与私钥的文件名
ssh-keygen -t rsa -b 4096 -f server_rsa -C "1@qq.com"
-t rsa
表示使用 RSA 加密得法, 你也可以使用 dsa 代替;-b 2048
表示使用 2048 位加密, 如果你对安全性要求更高, 可以使用 4096 位加密;-f server_rsa
表示要生成的文件名为server_rsa
(私钥) 和server_rsa.pub
(公钥)。- 最后的
-C "1@qq.com"
是注释, 会追加在造成的 Key 文件尾部, 通常会写上用户或机器的身份信息备查。
生成完成后:
之后输入 RSA Key 的使用密码并确认, ssh-keygen 命令就会造成一对密钥对。把生成的密钥对拷贝到 ~/.ssh/
下, root 用户是文件夹 /root/.ssh
。
3.1.3. 方法 3: 一步到位生成, 在 Docker 创建镜像时用到的较多
ssh-keygen -q -t rsa -b 4096 -f /root/.ssh/id_rsa -P ''-N'123456'
mv id_rsa.pub authorized_keys
chmod 600 authorized_keys
在文件夹 .ssh/
下的 id_rsa
是私钥, id_rsa.pub
是公钥。
将 /root/.ssh/id_rsa.pub
改名为 /root/.ssh/authorized_keys
:
mv /root/.ssh/id_rsa.pub /root/.ssh/authorized_keys
即 authorized_keys
是公钥。另外, 记得把私钥下下来:
sz id_rsa
** 附: ssh-keygen(选项)**
`-b`: 指定密钥长度;
`-e`: 读取 openssh 的私钥或者公钥文件;
`-C`: 添加注释;
`-f`: 指定用来保存密钥的文件名;
`-i`: 读取未加密的 ssh-v2 兼容的私钥 / 公钥文件, 然后在标准输出设备上显示 openssh 兼容的私钥 / 公钥;
`-l`: 显示公钥文件的指纹数据;
`-N`: 提供一个新密语;
`-P`: 提供 (旧) 密语;
`-q`: 静默模式;
`-t`: 指定要创建的密钥类型。
3.1.4. 注意: 对于公钥和私钥一定要保证是当前用户的
可以使用以下命令:
$ chown user:user authorized_keys
$ chmod 600 authorized_keys
$ chown user:user id_rsa
$ chmod 600 id_rsa
3.2. 刷新 SSH key, 使其无密码
3.2.1. 方法 1
$ openssl *** -in xxx -out yyy
重新生成一个 key, 在设置 passphrase 的时候直接 回车 跳过就好了。…
3.2.2. 方法 2
在 ~/.ssh/config
中添加
UseKeychain yes
AddKeysToAgent yes
3.2.3. 方法 3
使用命令 ssh-add -A
时, 竟然不需要输入密码。
3.3. 执行 ssh-add 时出现 Could not open a connection to your authentication agent
若执行 ssh-add /path/to/xxx.pem
是出现这个错误: Could not open a connection to your authentication agent
, 则先执行如下命令即可:
ssh-agent bash
更多关于 ssh-agent
的细节, 可以用 man ssh-agent
来查看
4. SSH 与远程机器交互
4.1. 使用 SSH 命令行登录
4.1.1. 直接连接到对方的主机, 这样登录服务器的默认用户
$ ssh 192.168.142.84
[admin@localhost ~]$ ssh 192.168.142.84
4.1.2. 使用账号登录对方主机 nii
用户
$ ssh nii@192.168.142.84
4.1.3. 登出
$ exit
如果你注册过 RSA Key 后仍需要输入服务器用户密码, 应该是服务器端用户文件权限问题: 需要:
- 服务器用户
$HOME
目录权限不能有用户组写权限 - 服务器用户
$HOME/.ssh
目录权限必须是 700 - 服务器用户
$HOME/.ssh/authorized_keys
文件权限必须是 600
4.2. 把生成的公钥发送到对方的主机上去
使用 ssh-copy-id
命令, 自动保存在对方主机的 /root/.ssh/authorized_keys
文件中去:
$ ssh-copy-id -i /root/.ssh/id_rsa.pub root@192.168.142.84
登录不需要密码了:
$ ssh 192.168.142.84
4.3. 指定密钥路径, 登录
ssh -i /root/.ssh/ido_sch_pro ido@192.168.1.111 -p 7744
如上,
/root/.ssh/ido_sch_pro
: 密钥文件路径ido@192.168.1.111
: 需要连接的服务器用户名 & IP-p 7744
: 端口7744
(如果修改了默认端口号)
4.4. SSH 调试
$ ssh -v git@github.com
4.5. git 调试
ssh -T git@github.com
ssh -T -v git@github.com
ssh -T -vvv git@github.com
4.6. 对于不用网站使用不同的 key
cat ~/.ssh/config
# gitlab
Host gitee.com
HostName gitee.com
PreferredAuthentications publickey
IdentityFile ~/.ssh/id_rsa
User git
# gitcode
Host gitcode.net
HostName gitcode.net
PreferredAuthentications publickey
IdentityFile ~/.ssh/id_rsa2
User git
4.7. 检查 RSA 公钥 / 私钥对是否匹配
- 用私钥文件生成对应的公钥
ssh-keygen -y -e -f /root/.ssh/id_rsa
- 查看公钥与第 1 步中的输出公钥是否相同
cat /etc/.ssh/id_rsa.pub
4.7.1. ssh 连接 debug
连接测试 debug 命令:
ssh -vvv -i id_rsa [youruser]@[yourLinode]
出现错误:
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: UNPROTECTED PRIVATE KEY FILE! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0644 for '/root/.ssh/ido_sch_pro' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
Load key "/root/.ssh/ido_sch_pro": bad permissions
ido@192.168.1.111: Permission denied (publickey).
问题原因: 文件权限错误。
修改方案, 修改指定文件夹的权限:
- 如果是需要 “只读” 权限:
chmod 400 ~/.ssh/id_rsa
- If Keys need to be read-writable by you:
chmod 600 ~/.ssh/id_rsa
4.7.2. 调试 openssh-client
ssh -l root -p 2222 192.168.99.100 -v -T (-l 是 login 的意思)
4.7.3. 调试 openssh-server
If you can try the failing connection again easily, one way easy way is to run:
/usr/sbin/sshd -d -p 2222
and then retry the connection with:
ssh -p 2222 user@host
Using -p 2222
so that we don’t have to stop the main SSH server, which could lock you out.
4.8. SSH 远程传输文件
使用 scp
命令。
scp
命令用于在 Linux 下进行远程拷贝文件的命令, 和它类似的命令有 cp
, 不过 cp
只是在本机进行拷贝不能跨服务器, 而且 scp
传输是加密的。可能会稍微影响一下速度。当你服务器硬盘变为只读 read only system
时, 用 scp
可以帮你把文件移出来。另外, scp
还非常不占资源, 不会提高多少系统负荷, 在这一点上, rsync
就远远不及它了。虽然 rsync
比 scp
会快一点, 但当小文件众多的情况下, rsync
会导致硬盘 I/O 非常高, 而 scp
基本不影响系统正常使用。
scp
即 SSH Copy.
4.8.1. 语法
scp(选项)(参数)
4.8.2. 选项
-1
: 使用 ssh 协议版本 1;
-2
: 使用 ssh 协议版本 2;
-4
: 使用 ipv4;
-6
: 使用 ipv6;
-B
: 以批处理模式运行;
-C
: 使用压缩;
-F
: 指定 ssh 配置文件;
-l
: 指定宽带限制;
-o
: 指定使用的 ssh 选项;
-P
: 指定远程主机的端口号;
-p
: 保留文件的最后修改时间, 最后访问时间和权限模式;
-q
: 不显示复制进度;
-r
: 以递归方式复制。
4.8.3. 参数
- 源文件: 指定要复制的源文件。
- 目标文件: 目标文件。格式为
user@host: filename
(文件名为目标文件的名称)。
4.8.4. 实例
从远程复制到本地的 scp
命令与上面的命令雷同, 只要将从本地复制到远程的命令后面 2 个参数互换顺序就行了。
4.8.4.1. 从远处复制文件到本地目录
scp root@10.10.10.10:/opt/soft/nginx-0.5.38.tar.gz /opt/soft/
从 10.10.10.10 机器上的 /opt/soft/
的目录中下载 nginx-0.5.38.tar.gz
文件到本地 /opt/soft/
目录中。
4.8.4.2. 从远处复制到本地
scp -r root@10.10.10.10:/opt/soft/mongodb /opt/soft/
从 10.10.10.10
机器上的 /opt/soft/
中下载 mongodb
目录到本地的 /opt/soft/
目录来。
4.8.4.3. 上传本地文件到远程机器指定目录
scp /opt/soft/nginx-0.5.38.tar.gz root@10.10.10.10:/opt/soft/scptest
复制本地 /opt/soft/
目录下的文件 nginx-0.5.38.tar.gz
到远程机器 10.10.10.10
的 opt/soft/scptest
目录。
4.8.4.4. 上传本地目录到远程机器指定目录
scp -r /opt/soft/mongodb root@10.10.10.10:/opt/soft/scptest
上传本地目录 /opt/soft/mongodb
到远程机器 10.10.10.10 上 /opt/soft/scptest
的目录中去。
4.9. SSH 远程执行任务
4.9.1. 远程执行命令
如果我们要查看一下某台主机的磁盘使用情况, 是不是必须要登录到目标主机上才能执行 df
命令呢? 当然不是的, 我们可以使用 ssh
命令在远程的主机上执行 df
命令, 然后直接把结果显示出来。整个过程就像是在本地执行了一条命令一样:
$ ssh nick@xxx.xxx.xxx.xxx "df -h"
那么如何一次执行多条命令呢? 其实也很简单, 使用分号把不同的命令隔起来就 OK 了:
$ ssh nick@xxx.xxx.xxx.xxx "pwd; cat hello.txt"
注意, 当命令多于一个时最好用引号括起来, 否则在有的系统中除了第一个命令, 其它都是在本地执行的。
4.9.2. 执行需要交互的命令
需要与用户交互 (需要 TTY)。
默认情况下, 当你执行不带命令的 ssh 连接时, 会为你分配一个 TTY。因为此时你应该是想要运行一个 shell 会话。
但是当你通过 ssh 在远程主机上执行命令时, 并不会为这个远程会话分配 TTY。此时 ssh 会立即退出远程主机, 所以需要交互的命令也随之结束。
好在我们可以通过 -t
参数显式的告诉 ssh, 我们需要一个 TTY 远程 shell 进行交互!
添加 -t
参数后, ssh 会保持登录状态, 直到你退出需要交互的命令。
$ ssh -t nick@192.168.1.2 "top"
作为总结, 我们看看 -t
参数的官方解释:
"Force pseudo-terminal allocation. 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."
好吧, 更强悍的是我们居然可以指定多个 -t
参数!
4.9.3. 执行多行的命令
有时候我们可能需要随手写几行简单的逻辑, 这也没有问题, ssh 能轻松搞定!
nick@u16os:~$ ssh nick@192.168.1.2 "
> ls
> pwd
> "
hello.txt
test1
test2
/home/nick
你可以用单引号或双引号开头, 然后写上几行命令, 最后再用相同的引号来结束。
那么如果需要在命令中使用引号该怎么办? 其实针对类似的情况有一条比较通用的规则, 就是混合使用单双引号。这条规则在这里也是适用的:
nick@u16os:~$ ssh nick@192.168.1.2 '
> ls
> pwd
> echo "haha"
hello.txt
test1
test2
/home/nick
haha
当我们在命令中引用了变量时会怎么样呢?
nick@u16os:~$ name=nick
nick@u16os:~$ ssh nick@192.168.1.2 "
> echo $name
> "
nick
nick@u16os:~$ ssh nick@192.168.1.2 '
> echo $name
> '
请注意上图中的最后一行, 并没有输出我们期望的 nick
。这里多少有些诡异, 因为如果变量没有被解释的话, 输出的应该是 $name
才对。但是这里却什么都没有输出。
对于引用变量的写法, 可以通过下面的方式保证变量被正确解释:
nick@u16os:~$ ssh nick@192.168.1.2 bash -c "'echo $name'"
nick
注意, 我们在上图的命令中为 bash 指定了 -c
参数。
4.9.4. 远程执行脚本
4.9.4.1. 执行本地的脚本
我们在本地创建一个脚本文件 test.sh, 然后运行下面的命令:
$ ssh nick@xxx.xxx.xxx.xxx < test.sh
通过重定向 stdin, 本地的脚本 test.sh
在远程服务器上被执行。
远程执行带有参数的脚本, 需要为 bash 指定 -s
参数:
$ ssh nick@xxx.xxx.xxx.xxx 'bash -s' < test.sh helloworld
附: test.sh
:
ls
pwd
echo $0
echo $1
4.9.4.2. 执行远程服务器上的脚本
在远程服务器上用户 nick 的家目录中有一个脚本 test.sh
。
注意, 此时需要指定脚本的绝对路径!
$ ssh nick@xxx.xxx.xxx.xxx /home/nick/test.sh helloworld
5. SSH 加密算法
5.1. SSH 选择哪种加密算法
5.1.1. 原理与安全性
RSA 与 DSA 都是非对称加密算法。其中 RSA 的安全性是基于极其困难的大整数的分解 (两个素数的乘积); DSA 的安全性是基于整数有限域离散对数难题。基本上可以认为相同密钥长度的 RSA 算法与 DSA 算法安全性相当。
有点要注意, RSA 的安全性依赖于大数分解, 但是否等同于大数分解一直未能得到理论上的证明, 因为没有证明破解 RSA 就一定需要作大数分解。不过也不必太过担心, RSA 从诞生以来, 经历了各种攻击, 至今未被完全攻破 (依靠暴力破解, 小于 1024 位密钥长度的 RSA 有被攻破的记录, 但未从算法上被攻破)。
5.1.2. 用途:
DSA 只能用于数字签名, 而无法用于加密 (某些扩展可以支持加密); RSA 即可作为数字签名, 也可以作为加密算法。不过作为加密使用的 RSA 有着随密钥长度增加, 性能急剧下降的问题。
5.1.3. 性能:
相同密钥长度下, DSA 做签名时速度更快, 但做签名验证时速度较慢, 一般情况验证签名的次数多于签名的次数。
相同密钥长度下, DSA (在扩展支持下) 解密密文更快, 而加密更慢; RSA 正好反过来, 一般来说解密次数多于加密次数。不过由于非对称加密算法的先天性能问题, 两者都不是加密的好选择。
5.1.4. 业界支持:
在业界支持方面, RSA 显然是赢家。RSA 具有更为广泛的部署与支持。
5.1.5. 使用 ssh-keygen 时的选择:
上面说了那么多, 可以看到 RSA 与 DSA 各有优缺点。回到开头的问题, 在使用 ssh-keygen 时, RSA 与 DSA 到底选哪个? 比较有意思的是, 这个问题最终答案与上面那些优缺点无关。虽然理论上可以生成更长长度的 DSA 密钥 (NIST FIPS 186-3), 但 ssh-keygen 在生成 DSA 密钥时, 其长度只能为 1024 位 (基于 NIST FIPS 186-2); 而 ssh-keygen 在 RSA 的密钥长度上没有限制。
由于小于 1024 位密钥长度的 RSA 已经有被攻破的记录, 所以说现在: RSA 2048 位密钥是更好的选择。
5.1.6. 其它选择:
RSA 与 DSA 各有优缺点, 那有没一个更好的选择呢? 答案是肯定的, ECC(Elliptic Curves Cryptography): 椭圆曲线算法。
ECC 与 RSA 相比, 有以下的优点:
- (1) 相同密钥长度下, 安全性能更高, 如 160 位 ECC 已经与 1024 位 RSA、DSA 有相同的安全强度。
- (2) 计算量小, 处理速度快, 在私钥的处理速度上 (解密和签名), ECC 远比 RSA、DSA 快得多。
- (3) 存储空间占用小 ECC 的密钥尺寸和系统参数与 RSA、DSA 相比要小得多, 所以占用的存储空间小得多。
- (4) 带宽要求低使得 ECC 具有广泛得应用前景。
在 ssh-keygen 中, ECC 算法的相应参数是 -t ecdsa
。可惜的是由于椭圆曲线算法只有在较新版本的 openssl 与 ssh-keygen 中才被支持, 而无法得到普遍使用而去完全替代 RSA/DSA。不过由于椭圆曲线算法的优点, 使其取代 RSA/DSA 而成为新一代通用的非对称加密算法成为可能, 至少 SET 协议的制定者们已经把它作为下一代 SET 协议中缺省的公钥密码算法了。