1. ssh简介
SSH (Secure Shell) 是一个为远程登录会话和其他网络服务提供安全性的协议。通过一个安全通道,用户可以在未加密的网络中为网络服务提供强大的身份验证和安全加密,让用户可以安全地在不安全的网络环境中执行远程命令,并将本地和远程主机之间的数据进行安全传输。
SSH协议的实现包括服务端和客户端。
- SSH 服务端提供远程登录和文件传输等功能,可以被其他用户或系统通过 SSH 协议连接并访问。
- SSH 客户端是用来连接远程服务端的工具。用户可以使用命令行或图形界面工具来连接到 SSH 服务端,并通过 SSH 协议进行通信。
- SSH 客户端可以通过用户名和密码、公钥验证等方式进行身份验证,登录到服务端。登录成功后,用户就可以在远程服务器上执行命令、上传或下载文件等操作。
SSH协议有很多实现,其中最广泛使用的是OpenSSH,OpenSSH也是Linux、Unix等操作系统的SSH协议默认实现。
参考文档:
2. 安装ssh server
ubuntu/debian中:
1 | apt-get update |
centos/redhat中:
1 | yum install -y openssh-server |
3. 配置ssh server
3.1. 基础配置
ssh server的配置文件位于 /etc/ssh/sshd_config
。需要使用具有root权限的编辑器(例如:nano,vi)对其进行编辑。
在配置文件中的关键参数包括:
- Port:默认端口是22,可以根据需要改变端口。
- PermitRootLogin:这个参数决定是否允许使用root用户进行远程登录,默认是Yes,可改为No。
- PasswordAuthentication:如设置为no,则关闭了密码登录,只能通过密钥登录。
编辑完成之后,需要重启SSH服务让更改生效:
1 | /etc/init.d/ssh restart |
3.2. 白名单配置
SSH白名单配置实际上是通过TCP Wrappers实现的。TCP Wrappers为许多网络服务提供了一个基于主机的访问控制策略,包括SSH。
TCP Wrappers依赖两个配置文件:/etc/hosts.allow和/etc/hosts.deny。
在hosts.allow文件中列出的主机可以访问网络服务,而在hosts.deny文件中列出的主机则被拒绝访问。
每个文件中的条目都是一行,包含一个服务名和一列主机名或IP地址。服务名是/etc/services文件中列出的服务名或由互联网守护程序(inetd)或xinetd启动的守护进程的名称。主机名或IP地址可以是完全限定的主机名、IP地址、IPv6地址、DNS域名、网络地址或者是这些值的模式。
要为SSH配置一个白名单,需要在/etc/hosts.allow文件中指定ssh和sshd服务可以访问的主机,然后在/etc/hosts.deny文件中禁止所有其他主机访问这些服务。
假设我们希望只允许10.0.0.0/24网络中的主机和192.168.56.200通过SSH访问我们的服务器,其他所有主机都不能访问。可以按如下方式配置:
在/etc/hosts.allow文件中添加配置:
1 | sshd:10.0.0.0/24 |
在/etc/hosts.deny文件中添加配置:
1 | sshd:ALL |
参考文档:hosts.allow format and example on Linux
4. 使用ssh client
4.1. ssh登录服务器
1 | ssh voidking@192.168.56.100 |
4.2. 测试ssh连接
1 | ssh -vvv voidking@192.168.56.100 /bin/true |
4.3. ssh执行远程命令
执行远程命令很简单,直接ssh后面跟着命令就可以了。
1 | ssh voidking@192.168.56.100 "echo helloworld" |
那如果远程命令里面包含双引号怎么办?变成单引号,或者添加转义。
1 | ssh voidking@192.168.56.100 "echo 'helloworld'" |
那如果需要远程命令里使用变量怎么办?添加转义。
1 | ssh voidking@192.168.56.100 "host=\$(hostname);echo \"\${host}\"" |
4.4. ssh批量执行远程命令
已知主机列表hosts.txt内容为:
1 | 192.168.56.101 |
需求:给主机列表中的机器添加开机启动命令
脚本:
1 | for i in `cat hosts.txt`; do ssh $i "echo '/home/voidking/start.sh' | sudo tee -a /etc/rc.local";done |
5. 配置免密登录
5.1. 生成密钥对
通过ssh登录远程主机,要么使用密码,要么使用密钥对。使用密钥对的话,可以实现免密登录。
生成默认密钥对:
1 | ssh-keygen |
执行命令后,一路回车,会生成公钥~/.ssh/id_rsa.pub
和私钥 ~/.ssh/id_rsa
指定参数生成密钥对:
1 | ssh-keygen -C "voidking@qq.com" -f ~/.ssh/voidking_rsa |
执行命令后,~/.ssh/
目录下会生成 voidking_rsa
和 voidking_rsa.pub
,注释内容为 voidking@qq.com
5.2. 添加公钥到远程机器
假设远程机器为192.168.56.100。
添加默认公钥到远程机器:
1 | ssh-copy-id voidking@192.168.56.100 |
根据提示输入密码,这条命令会把 ~/.ssh/id_rsa.pub
的内容追加到远程机器的 ~/.ssh/authorized_keys
中。
注意:authorized_keys文件权限需要配置为600。如果配置好了sshd,但是无法使用密钥登录机器,请检查authorized_keys文件权限。
添加指定公钥到远程机器:
1 | ssh-copy-id -i ~/.ssh/voidking_rsa voidking@192.168.56.100 |
执行这条命令后,~/.ssh/voidking_rsa.pub
中的内容会被拷贝到远程机器的 ~/.ssh/authorized_keys
中。
对于macos系统,需要单独单装 ssh-copy-id
命令。
1 | sudo curl -L https://raw.githubusercontent.com/beautifulcode/ssh-copy-id-for-OSX/master/install.sh | sh |
5.3. 密钥添加失败问题
如果ssh-copy-id
报错cannot create .ssh/authorized_keys: Operation not permitted
或者手动编辑authorized_keys
后无法保存,chmod
也无法改变authorized_keys
文件的权限。
那么可能是因为authorized_keys
被加锁了,防止误删,需要先进行解锁。
1 | chattr -i ~/.ssh/authorized_keys |
5.4. 免密登录远程机器
使用默认私钥登录:
1 | ssh voidking@192.168.56.100 |
指定私钥登录:
1 | ssh -i ~/.ssh/id_rsa voidking@192.168.56.100 |
执行ssh
命令时,默认会先使用密钥进行验证,如果密钥配置正常,那么就不需要输入密码了。
6. 配置主机别名登录
登录远程服务器,需要执行命令
1 | ssh username@host -p port |
如果有大量的username、host、port,是很难记忆的,因此我们需要配置主机别名登录。
主机别名登录具体配置方法如下:
1、创建 ~/.ssh/config
文件,内容为
1 | Host jumpbox |
2、配置 authorized_keys
1 | ssh-copy-id -i ~/.ssh/voidking_rsa.pub jumpbox |
3、登录服务器
1 | ssh jumpbox |
7. 配置用户只能运行特定命令
7.1. 运行命令/脚本
1、authorized_keys 配置
1 | command="/usr/bin/date" ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC9... |
2、运行命令
1 | ssh voidking@192.168.56.100 |
默认会运行 date 命令。
7.2. 运行命令/脚本 + 参数
1、准备脚本 test.sh
1 | #/bin/bash |
2、authorized_keys 配置
1 | #command="/usr/bin/echo $SSH_ORIGINAL_COMMAND" ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC9... |
3、运行脚本
1 | ssh voidking@192.168.56.100 "test1 test2" |
默认会运行 test.sh 脚本,test1
和 test2
会作为两个参数传递给 test.sh。