很多时候服务器并没有显示器,我们也不可能每次都通过控制台去管理服务器,这时就需要远程登录。远程登录到服务器可以通过Telnet或ssh的方式。但是用Telnet登录,整个过程都是以明文的方式传输的,不安全。所以,建议使用ssh的方式来登录,因为ssh在整个连接过程中,数据都是加密的。
本章的实验拓扑图如图12-1所示。
图12-1 实验拓扑图
其中server.rhce.cc中有lduan用户和tom用户,server2.rhce.cc中只有tom用户。如果没有server2.rhce.cc这台机器,请按照第一章内容自行安装。
ssh的基本用法1:
ssh 主机名/IP
这里如果没有指明用什么用户连接,则是以当前用户连接。
当第一次远程连接到服务器,要记录服务器的公钥指纹信息。
[lduan@server ~]$ ssh 192.168.26.102
The authenticity of host '192.168.26.102 (192.168.26.102)' can't be established.
ECDSA key fingerprint is SHA256:6Dcs1+DaxottLBGknNLdSnK3OllTRgbayLg0QZAWor8.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '192.168.26.102' (ECDSA) to the list of known hosts.
lduan@192.168.26.102's password:
上面如果输入的是no,则连接终止。输入yes,则保存在了当前用户家目录下的.ssh/known_hosts文件中。
上面的命令中,我们并没有指定使用哪个用户连接到192.168.26.102,但是他是以lduan用户登录到192.168.26.102的。
但在server2上是没有lduan用户的,如下所示。
[root@server2 ~]# id lduan
id: “lduan”:无此用户
[root@server2 ~]#
所以,输入的密码都是错误的。连续输入3次密码不正确就退出来,因为192.168.26.102上根本没有lduan用户,但是有tom用户,如下所示。
[root@server2 ~]# id tom
uid=1000(tom) gid=1000(tom) 组=1000(tom)
[root@server2 ~]#
我们可以指定使用哪个用户名连接过去。
ssh的基本用法2:
ssh -l 用户名 主机名/IP
ssh 用户名@主机名/IP
建议用第2个。现在以tom的身份连接,命令如下。
[lduan@server ~]$ ssh tom@192.168.26.102
tom@192.168.26.102's password: 此处输入tom的密码
...输出...
[tom@server2 ~]$
可以看到,此时已经正常连接过去了,要退出来时只要输入exit即可。
[tom@server2 ~]$ exit
注销
Connection to 192.168.26.102 closed.
[lduan@server ~]$
如果连接时出现了图12-2所示的错误。
图12-2 密钥变更导致报错
只要把家目录下.ssh/known_hosts删除,或者此文件中192.168.26.120对应的条目删除即可,命令如下。
[lduan@server ~]$ ssh tom@192.168.26.102
The authenticity of host '192.168.26.102 (192.168.26.102)' can't be established.
ECDSA key fingerprint is SHA256:0XZjkM0qUACpJbUhD024+mqbwcVA6XXg7e7MQpk41EM.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '192.168.26.102' (ECDSA) to the list of known hosts.
tom@192.168.26.102's password:
...输出...
[tom@server2 ~]$
然后会重新记录192.168.26.102的公钥指纹信息。
当远程连接到远端机器,例如,从server上通过tom用户连接到server2上,命令如下。
[lduan@server ~]$ ssh tom@192.168.26.102
tom@192.168.26.102's password:
...输出...
[tom@server2 ~]$ firefox
Error: no DISPLAY environment variable specified
[tom@server2 ~]$
然后执行firefox &命令,出现了“Error: no DISPLAY environment variable specified”的错误提示。这是为什么呢?首先我们了解Xserver和Xclient的一些信息。
每个打开的图形化界面的工具,例如,终端、Firefox浏览器、gedit记事本等,这些都叫作Xclient,这些Xclient必须要在Xserver上运行。Xserver是一个平台环境,装系统时如果选择了图形化界面,那么Xserver就已经安装上去了,如图12-3所示。
图12-3 了解Xserver和Xclient
要是想在本机打开远端服务器的Xclient即图形化客户端,需要满足3个条件。
(1)ssh登录到服务器的时候,要加上X(大写的X)选项。
因为ssh建立的连接默认只允许字符传输,不允许Xclient进行传输,加上X选项之后就可以让Xclient通过ssh建立的连接传输。
(2)本地要运行Xserver。
(3)远端服务器要安装了xorg-x11-xauth,默认为已经安装上去了的。
现在退出来,重新ssh过去,加上-X选项,命令如下。
[lduan@server ~]$ ssh tom@192.168.26.102 -X
tom@192.168.26.102's password:
...输出...
/usr/bin/xauth: file /home/tom/.Xauthority does not exist
[tom@server2 ~]$
然后再次执行firefox命令,此时是可以正常打开的了,如图12-4所示。
图12-4 通过ssh打开远端的浏览器
Windows下常见的Xserver有Xming和Xmanager,其中Xming是开源的。
ssh远程登录到远程服务器时有两种认证方式。
前面在server上ssh到server1时,命令如下。
[lduan@server ~]$ ssh tom@192.168.26.102
tom@192.168.26.102's password:
这里需要输入密码才能正常登录,这种就是密码认证。
如果做了密钥认证,远程登录时是不需要密码就可以直接登录。这里server上的lduan准备以tom身份无密码连接到server2上,如图12-5所示。
图12-5 配置ssh无密码登录
为了好描述,server上的lduan用户称呼为lduan@server,server2上的tom用户称呼为tom@server2。
lduan@server需要生成一个密钥对,命令如下。
[lduan@server ~]$ ssh-keygen -f ~/.ssh/id_rsa -N ""
...输出...
+---[RSA 3072]----+
|*=+ . . . |
|.Bo+ o + o . |
|..* O o + . |
|oE + = o. |
|o . ooS. |
| o . . += |
|. = *o o |
| . = =.+o |
| ..= o... |
+----[SHA256]-----+
[lduan@server ~]$
这条命令会生成一个密钥对(私钥和公钥),这里-f指定了生成私钥的路径和名称,如果不指定默认也是这个路径。 -N 后面双引号中是没有空格,意思是不对生成的私钥加密。
这样lduan生成了自己的密钥对,存放在自己家目录的.ssh目录下,命令如下。
[lduan@server ~]$ ls .ssh/
id_rsa id_rsa.pub known_hosts
[lduan@server ~]$
其中id_rsa是私钥,id_rsa.pub是公钥。
然后通过ssh-copy-id把公钥的内容存储在tom@server2家目录下.ssh/authorized_keys这个文件中,如果没有此文件,拷贝过去之后会自动创建,命令如下。
[tom@server2 ~]$ ls .ssh
ls: 无法访问'.ssh': 没有那个文件或目录
[tom@server2 ~]$
下面执行ssh-copy-id命令,命令如下。
[lduan@server ~]$ ssh-copy-id tom@192.168.26.102
...输出...
tom@192.168.26.102's password: 此处输入tom的密码
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'tom@192.168.26.102'"
and check to make sure that only the key(s) you wanted were added.
[lduan@server ~]$
这样lduan的公钥就存放在tom@server2家目录下的文件.ssh/authorized_keys中了。
[tom@server2 ~]$ cat .ssh/authorized_keys
ssh-rsa AAAAB3NzaC1yc2EAAAADAQoxpqZqPhQlK/Wy8WDxl9apZJEKFTUjFE/uWtffTTz5
...输出
O+JNaicYEnxGfhmRayqQEFrx26uOkyzurkaCMk8h3U2W2f981TRkaziv3asegezNn0muoE52r8268aU= lduan@server.rhce.cc
[tom@server2 ~]$
通过对比,发现这个文件的内容就是lduan@server的公钥的内容。
下面远程登录测试,命令如下。
[lduan@server ~]$ ssh tom@192.168.26.102
Activate the web console with: systemctl enable --now cockpit.socket
...输出...
[tom@server2 ~]$
可以看到,已经无密码的登录过去了。
前面已经讲了,ssh有两种认证方式密码认证和密钥认证,lduan@server到tom@server2是用的密钥认证,其他用户登录方式仍然是密码登录,现在想设置只能用其中一种认证是否可以?答案是可以的。
在server2上,以root用户编辑/etc/ssh/sshd_config,找到PubkeyAuthentication,修改内容如下。
将“#PubkeyAuthentication yes”修改为“PubkeyAuthentication no”(需要注意的是,这里前面的注释#被删除了)。
这样就禁用了密钥登录,保存退出,并重启sshd,命令如下。
[root@server2 ~]# systemctl restart sshd
[root@server2 ~]#
此时已经禁用了密钥登录只能密码登录,到server上进行测试,命令如下。
[lduan@server ~]$ ssh tom@192.168.26.102
tom@192.168.26.102's password: 此处输入tom的密码
...输出...
[tom@server2 ~]$ exit
注销
Connection to 192.168.26.102 closed.
[lduan@server ~]$
这里只能使用密码登录,原来配置的密钥认证不再生效。
再次设置允许密钥登录(PubkeyAuthentication yes),修改如下。
将 PubkeyAuthentication no
修改为 PubkeyAuthentication yes
并重启sshd,命令如下。
[root@server2 ~]# systemctl restart sshd
[root@server2 ~]#
在server2上,以root用户编辑/etc/ssh/sshd_config,找到PasswordAuthentication,修改内容如下。
将 PasswordAuthentication yes
修改为 PasswordAuthentication no
这样就禁用了密码认证,保存退出之后,然后重启sshd,命令如下。
[root@server2 ~]# systemctl restart sshd
[root@server2 ~]#
此时只允许密钥登录不允许密码登录。
为了测试方便,在server2上创建用户bob,密码设置为haha001。
[root@server2 ~]# useradd bob
[root@server2 ~]# echo haha001 | passwd --stdin bob
更改用户 bob 的密码 。
passwd:所有的身份验证令牌已经成功更新。
[root@server2 ~]#
在server上进行验证,首先以tom身份连接过去。
[lduan@server ~]$ ssh tom@192.168.26.102
...输出...
[tom@server2 ~]$ exit
注销
Connection to 192.168.26.102 closed.
[lduan@server ~]$
可以看到,使用tom登录192.168.26.102时是可以无密码登录的。
然后以bob身份连接过去。
[lduan@server ~]$ ssh bob@192.168.26.102
bob@192.168.26.102: Permission denied (publickey,gssapi-keyex,gssapi-with-mic).
[lduan@server ~]$
因为我们并没有做bob用户无密码登录到server2,只能使用密码认证,而密码认证被禁用,所以bob登录失败。
请自行设置允许密码登录,修改/etc/ssh/sshd_config,如下所示。
将 PasswordAuthentication no
修改为 PasswordAuthentication yes
并重启sshd服务,命令如下。
[root@server2 ~]# systemctl restart sshd
[root@server2 ~]#
再次使用bob用户登录。
[lduan@server ~]$ ssh bob@192.168.26.102
bob@192.168.26.102's password:
...输出...
[bob@server2 ~]$
[bob@server2 ~]$ exit
注销
Connection to 192.168.26.102 closed.
[lduan@server ~]$
已经可以正常登录了。
对于服务器上的有效用户,基本上都是可以远程ssh过去的,但是有时为了安全性要禁用某些用户登录,如禁用root等。
在RHEL9里默认情况下,是不允许使用root 以密码的方式ssh到远端服务器的。
[lduan@server ~]$ ssh root@192.168.26.102
root@192.168.26.102's password:
Permission denied, please try again.
root@192.168.26.102's password:
【ctrl+c】终止
[lduan@server ~]$
这里可以看到root并没有登录成功。如果要设置root用户能否ssh登录,在server2上用vim编辑打开/etc/ssh/sshd_config,找到PermitRootLogin选项,这个参数有三个值:
prohibit-password,这个在RHEL9里是默认值,意思是当root以密码的方式ssh过来时是不允许的,如果root以密钥的方式登录则是允许的。
yes,不管是密码还是密钥都允许root ssh登录系统
no,不管是密码还是密钥,都不允许root ssh登录系统
这里将 PermitRootLogin prohibit-password
修改为 PermitRootLogin yes
保存退出之后,然后重启sshd,在server上进行验证。
[lduan@server ~]$ ssh root@192.168.26.102
root@192.168.26.102's password:
[root@server2 ~]$ exit
[lduan@server ~]$
这里就可以登录了,如果不允许root用户登录,按如下内容修改。
将 PermitRootLogin yes
修改为 PermitRootLogin no
然后重启sshd即可,这里仍然设置为yes,即允许root ssh登录。
如果想禁用某普通用户,可以用DenyUsers选项实现,用法是打开/etc/ssh/sshd_config,在任意一行位置添加DenyUsers userX,就可以限制userX ssh登录了。如果需要在server2上禁用bob用户用ssh登录,可以用vim编辑打开/etc/ssh/sshd_config,在任意一行位置添加DenyUsers bob,命令如下。
DenyUsers bob
这里就是禁用bob用户ssh登录,退出保存并重启sshd,然后到server上进行测试,命令如下。
[lduan@server ~]$ ssh bob@192.168.26.102
bob@192.168.26.102's password:
Permission denied, please try again.
bob@192.168.26.102's password:
这里提示被拒绝,是因为bob用户被限制登录了,按【Ctrl+C】组合键终止。
这里只是禁用了bob用户,并不影响其他用户登录。
类似的选项还有AllowUsers和DenyGroups。
其中AllowUsers userX的意思是,只允许userX用户登录,不允许其他用户登录。
如果写成AllowUsers userX userY,意思是只允许userX和userY登录,不允许其他用户登录。
如果以下两个条目同时出现
AllowUsers bob
DenyUsers bob
则DenyUsers生效,bob仍然是不能登录的。
Ssh的其他设置保留设置ssh的默认用户及解决ssh慢的问题。
前面讲了在使用ssh登录时,如果没有指明用户则使用当前用户登录。其实我们也是可以指定默认用户的,即ssh登录时如果没有指定用户,则使用默认用户登录。
下面进行一个练习,在lduan@server家目录下的.ssh目录中创建config文件,内容如下。
[lduan@server ~]$ cat .ssh/config
Host 192.168.26.102
User tom
[lduan@server ~]$
这个设置的意思就是,当连接到192.168.26.102时,如果没指定用户,则默认为用的是tom用户。
[lduan@server ~]$ chmod 644 .ssh/config
[lduan@server ~]$
需要注意的是,这里要把.ssh/config的权限改为644。在server上验证。
[lduan@server ~]$ ssh 192.168.26.102
...输出...
[tom@server2 ~]$ exit
注销
Connection to 192.168.26.102 closed.
[lduan@server ~]$
这里虽然没有指定用户名,但是可以看到是以tom身份连接。
首次连接某台机器时,都会提示我们是否保存那台机器的公钥指纹信息,让我们输入yes/no,且必须要输入yes。如果想默认输入yes,即自动输入yes,可以修改.ssh/config,内容如下。
[lduan@server ~]$ cat .ssh/config
Host 192.168.26.102
User tom
Host *
StrictHostKeyChecking no
[lduan@server ~]$
上述黑体字是新增加的,Host 后面的*是通配符,表示所有主机。整体意思就是不管连接到哪台主机都不会再提示yes/no了,下面验证,命令如下。
[lduan@server ~]$ rm -rf .ssh/known_hosts
[lduan@server ~]$ ssh 192.168.26.102
Warning: Permanently added '192.168.26.102' (ECDSA) to the list of known hosts.
...输出...
[tom@server2 ~]$
这里先清除已经保存的记录,即删除.ssh/knowner_hsots,然后重新登录,可以看到现在已经不提示我们输入yes/no了。
有时我们在通过ssh登录到一台服务器时,连接的过程会比较慢,要等几十秒才能看到输入密码的提示。很多时候这是因为系统自动去做反向解析,即把 ssh 192.168.26.102中的192.168.26.102反向解析成主机名,才会导致ssh速度慢。
为了防止这个问题可以修改服务器上配置。用vim编辑打开/etc/ssh/sshd_config,找到UseDNS,进行如下修改。
将#UseDNS yes变成UseDNS no,这里同时把#注释去掉了,然后重启sshd即可。
注意:RHEL8中默认已经是UseDNS no了。
很多时候服务器上安装的是Linux系统,但我们平时用的笔记本用的是Windows系统,如果要使用Windows远程登录,只要在Windows安装ssh客户端,就可以ssh到远端的Linux服务器了。Windows下常见的ssh客户端包括Putty、XShell、SecureCRT等。
Windows下的这些客户端,大家根据自己的喜好自行下载使用即可。
有时我们需要远程拷贝一些文件,例如,把文件或目录从A机器拷贝到B机器上,这种情况下我们一般用scp或rsync。
scp或rsync利用的是ssh建立的通道,然后把文件传输过去,scp的用法如下。
scp /path1/file1 remoteIP:/path2/
意思是把本地的/path1/file1拷贝到remoteIP这台机器的/path2路径下。需要注意的是,表示远程主机上目录的表示方式是“IP:目录”,冒号两边没有空格。如果拷贝目录需要加r选项。
先查看server2上/opt目录中的内容。
[root@server2 ~]# ls /opt/
[root@server2 ~]#
然后到server上拷贝/etc/hosts到server2的/opt目录中。
[root@server ~]# scp /etc/hosts 192.168.26.102:/opt
root@192.168.26.102's password:
hosts 100% 158 47.7KB/s 00:00
[root@server ~]#
这样就把文件拷贝过去了,scp利用的是ssh建立的通道,那这里如果没有指明使用哪个用户连接到192.168.26.102,则使用的是当前用户root。
下面使用以tom身份登录192.168.26.102并拷贝文件,命令如下。
[root@server ~]# scp /etc/hosts tom@192.168.26.102:/opt
tom@192.168.26.102's password:
scp: /opt/hosts: Permission denied
[root@server ~]#
因为192.168.26.102上的tom用户对/opt没有写权限,所以拷贝过去时出现了"Permission denied"这样的报错信息。
把目录/boot/grub2拷贝到server2上的/opt目录中,命令如下。
[root@server ~]# scp /boot/grub2/ 192.168.26.102:/opt
root@192.168.26.102's password:
/boot/grub2: not a regular file
[root@server ~]#
结果是没有拷贝过去,因为/boot/grub2是一个目录,拷贝目录需要加上-r选项,命令如下。
[root@server ~]# scp -r /boot/grub2/ 192.168.26.102:/opt
root@192.168.26.102's password:
...大量输出...
[root@server ~]#
这样就把该目录拷贝过去了,到server2上查看,命令如下。
[root@server2 ~]# ls /opt/
grub2 hosts
[root@server2 ~]#
清空server2上/opt中的内容,命令如下。
[root@server2 ~]# rm -rf /opt/*
[root@server2 ~]# ls /opt/
[root@server2 ~]#
另外一个远程拷贝的工具是rsync,rsync的语法如下。
rsync /path1/file1 remoteIP:/path2/
rsync的用法跟scp的用法一致,rsync有更多的选项可用,可以通过rsync --help进行查看。
但需要注意的是,使用rsync拷贝目录时的一点区别,下面练习将server上的目录/boot/grub2拷贝到server2上的/opt目录中,命令如下。
[root@server ~]# rsync -r /boot/grub2 192.168.26.102:/opt
root@192.168.26.102's password:
[root@server ~]#
需要注意的是,这里“/boot/grub2”最后是没有/的,即写的不是“/boot/grub2/”,切换到server2上查看,命令如下。
[root@server2 ~]# ls /opt/
grub2
[root@server2 ~]#
可以看到,这里是将目录grub2及里面的东西一起拷贝过来了。
删除server2上/opt中的内容,命令如下。
[root@server2 ~]# rm -rf /opt/*
[root@server2 ~]# ls /opt/
[root@server2 ~]#
再次把server上的目录/boot/grub2拷贝到server2上的/opt目录中,命令如下。
[root@server ~]# rsync -r /boot/grub2/ 192.168.26.102:/opt
root@192.168.26.102's password:
[root@server ~]#
这次拷贝的目录写成了“/boot/grub2/”,也就是grub2后面带了一个“/”,切换到server2上查看,命令如下。
[root@server2 ~]# ls /opt/
device.map fonts grub.cfg grubenv i386-pc
[root@server2 ~]#
可以看到,这里是把grub2这个目录中的内容拷贝过来了,并不包括grub2目录本身。
一般情况下我们访问一个目录时,有没有最后表示分隔符的“/”是无所谓的,但需要注意的是,在使用rsync拷贝目录时有没有这个"/"结果还是又区别的。
清空server2上/opt中的内容,命令如下。
[root@server2 ~]# rm -rf /opt/*
[root@server2 ~]#
sftp也是远程传输工具,默认情况下,SFTP也是使用SSH 协议进行身份验证并建立安全连接。用法是
sftp 用户名@IP 或者
sftp 用户名@IP:目录
这样就可以登录到远端机器指定的目录里了,如果没有指定用户名的话,则使用的是当前用户登录。
步骤1:以root身份登录到192.168.26.102。
[lduan@server ~]$ sftp root@192.168.26.102
root@192.168.26.102's password:
Connected to 192.168.26.102.
sftp> pwd
Remote working directory: /root
sftp>
这里输入pwd之后,可以看到登录到远端的哪个目录,通过exit退出sftp。
sftp> exit
[lduan@server ~]$
步骤2:以root身份登录到192.168.26.102的/opt目录里。
[lduan@server1 ~]$ sftp root@192.168.26.102:/opt
root@192.168.26.102's password:
Connected to 192.168.26.102.
Changing to: /opt
sftp> pwd
Remote working directory: /opt
sftp>
这里通过pwd可以看到现在是在/opt目录里的,然后执行ls命令。
sftp> ls
sftp>
现在看不到任何东西,说明192.168.26.102的/opt目录下没有任何的文件或者目录,可以通过put上传文件。
步骤3:通过put命令把本机的/etc/hosts上传到192.168.26.102的/opt目录里。
sftp> put /etc/hosts
Uploading /etc/hosts to /opt/hosts
hosts 100% 241 145.7KB/s 00:00
sftp> ls
hosts
这里通过ls命令可以看到已经有了hosts文件了,然后通过ls -l hosts查看hosts文件的属性。
sftp> ls -l hosts
hosts
sftp> chmod 666 hosts
Changing mode on /opt/hosts.
sftp>
这里发现看不到文件的详细信息,和系统里不一样,使用chmod修改权限最终其实也没修改成功。如果想通过系统命令修改的话,在命令前面加上叹号。
sftp> !ls -l hosts
-rw-r--r--. 1 lduan lduan 241 12月 20 18:46 hosts
sftp>
这里查看文件的属性,显示的还是644,然后通过!chmod修改之后。
sftp> !chmod 666 hosts
Changing mode on /opt/hosts
sftp>
sftp> !ls -l hosts
-rw-rw-rw-. 1 lduan lduan 241 12月 20 18:46 hosts
sftp>
这里可以看到权限已经变为了666了。
如果要下载文件到本地的话,则用get命令,比如把hosts下载到当前目录里:
sftp> get hosts
Fetching /opt/hosts to hosts
hosts 100% 241 276.1KB/s 00:00
sftp>
删除此文件
sftp> rm hosts
Removing /opt/hosts
sftp> ls
sftp>
这里文件已经被删除了。
sftp> quit
[lduan@server ~]$
1在jerry@workstation上通过ssh登录到server,且希望能打开server上的Firefox,应该使用如下哪个命令?
a. ssh server
b. ssh server -x
c. ssh server -X11
d. ssh server -X
3在测试环境中,通过ssh登录到服务器时会花很长时间才能登录过去,下面哪个选项能解决此问题?
a. UseLogin
b. GSSAPIAuthentication
c. UseDNS
d. TCPKeepAlive
要求server2上的tom用户,在ssh到192.168.26.0/X的任何主机时,默认的用户名为root,请问如何设置?
tom从server2在通过ssh命令以root身份登录server之后,执行firefox命令,却出现了如图12-7所示的报错。
图12-7 报错信息
请问如何解决?
不希望用root用户ssh到server2,那么请在server2上如何设置?
不希望tom组的用户ssh到 server2上,请问该如何设置?