SSH (Secure Shell) 在不安全的网络上构建安全的传输通道,用于远程登录、远程执行命令、端口转发等。它的设计旨在替代telnet、rlogin等不安全的登录程序。
OpenSSH是最流行的SSH协议的实现程序,在大多数Lnux系统中默认安装,在Wndows 10中默认使用。OpenSSH提供的主要工具有
更早版本的Wndows系统一般使用PuTTY作为SSH的客户端程序,使用WinSCP作为远程文件交换程序。以下使用OpenSSH的工具进行说明。
SSH使用服务器/客户端架构,远程被访问的机器需要运行服务器端程序sshd
。sshd
默认打开端口22。
Arch Linux安装OpenSSH并启动sshd服务的指令为:
$ pacman -S openssh
$ systemctl start sshd
如果希望重启后自动运行sshd服务,使用以下指令:
$ systemctl enable sshd
sshd
的配置文件一般位于/etc/ssh/sshd_config
,用于配置SSH服务器端的操作,比如是否允许root登录,使用其他端口等。
假如服务器S已启用sshd
服务,使用以下指令从本地设备L上登录服务器S。
$ ssh user@remote_ip
其中,user
为服务器S上的一个用户名,remote_ip
为服务器S的IP地址。
如果服务器没有使用标准的SSH端口22,而是配置了自定义的端口,远程登录时需要使用-p
指定端口号,
$ ssh -p port user@remote_ip
如果不想获得远程终端,而仅仅需要在服务器上执行一条指令,使用以下命令:
$ ssh user@remote_ip command
其中,command
是需要执行的指令,比如ssh user@remote_ip ls /tmp/
列出远程服务器上/tmp/
文件夹的内容。
scp
实现本地设备与服务器间加密的文件拷贝,具体用法不赘述。
执行以上远程登录/或者远程执行指令操作时,每次都会提醒输入对应用户名的密码。如果是交互时的操作,密码输入只是多敲几下键盘的麻烦。但是,如果是编写脚本实现自动化操作,密码输入就不合适了。
SSH允许使用公钥实现免密码登录。具体地,在本地设备上生成一个私钥/公钥对,然后将公钥复制到远程服务器,就可以利用这对公私钥加密通信通道,实现免密码登录服务器了。
ssh-keygen
生成密钥$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/local_user/.ssh/id_rsa): #密钥存储文件
Enter passphrase (empty for no passphrase): #使用该密钥对的密码,可为空
Enter same passphrase again: #重输入密码,确认
Your identification has been saved in /home/local_user/.ssh/id_rsa.
Your public key has been saved in /home/local_user/.ssh/id_rsa.pub.
ssh-keygen
首先提示输入存储密钥的文件名,默认为/home/user/.ssh/id_rsa
,然后,提示输入使用该密钥的密码。使用该密钥的密码与登录服务器的密码不同,控制是否允许使用当前密钥,而非控制是否允许登录服务器。如果要实现免密码登录,需要将使用密钥的密码设为空,即在提示输入密码处直接按回车。
ssh-copy-id
复制公钥到服务器$ ssh-copy-id user@remote_ip
执行该指令时会提供输入远程服务器的登录密码。公钥复制完成后,以后再登录服务器就可以实现免密码登录了。
ssh-copy-id
效果一样)ssh-copy-id
的具体操作内容。将本地设备上/home/local_user/.ssh/id_rsa.pub
文件复制到服务器上,然后将上述文件的内容复制到服务器上/home/server_user/.ssh/authorized_keys
文件末尾。-L
$ ssh -L port0:localhost:port1 user@remote_ip
假设本地设备的IP地址为local_ip,发送到local_ip:port1
的数据将被转发到remote_ip:port0
,即local_ip:port1 --> remote_ip:port0
。
-R
$ ssh -R port0:localhost:port1 user@remote_ip
假设本地设备的IP地址为local_ip,发送到remote_ip:port1
的数据将被转发到local_ip:port0
,即local_ip:port1 <-- remote_ip:port0
。
$ ssh -f -N -T -R port0:localhost:22 user@remote_ip
-f
: ssh连接授权后进入后台运行-N
: 不运行任何的远端指令-T
: 不创建交互终端local_ip:22
,即ssh端口。所以,ssh -p port0 user@remote_ip
相当与ssh user@local_ip
。这种用法在remote_ip为公网IP,local_ip为内网IP时,非常有用。使用反向SSH隧道,内网IP地址的设备暴露到公网上,这样从任何设备都可以访问内网设备了。网络连接不稳定会导致隧道中断。这种情况下,可以使用autossh
自动重连。autossh
的参数与ssh
相同。