远程登录工具----telnet、openssh
0 目录
1 telnet
1.1 telnet是什么
telnet是一种远程登录协议,可以使用户远程操作主机。
telnet协议的实现程序就叫telnet。服务端安装程序包telnet-server,客户端安装程序包telnet。
服务端监听在tcp端口23。
由于telnet使用的是明文传输,所以最好用ssh。各linux发行版默认也是没安装的。
1.2 telnet如何启动
1.2.1 瞬时守护进程、独立守护进程
服务进程分为独立守护进程、瞬时守护进程。
独立守护进程:通常是被访问比较频繁的进程。服务进程一直运行,监听在指定端口,随时响应。比如httpd。
瞬时守护进程:被访问频率较低,若服务进程一直运行则会浪费系统资源。如telnet。
1.2.1 对于CentOS 6
对CentOS 6 来说,linux提供了超级守护进程xinetd来统一管理瞬时守护进程。
机制:由xinetd来代替各瞬时守护进程的服务监听在对应端口,各服务进程没有真正启动。当有对指定服务的请求时,xinetd再启动对应的服务,响应完成后,服务进程又终止。从而减少对系统资源的浪费。
xinetd的配置文件为/etc/xinetd.conf和/etc/xinetd.d目录下,被xinetd管理的服务在/etc/xinetd目录下都有对应的文件:
[[email protected] ~]% ls /etc/xinetd.d/
chargen-dgram daytime-dgram discard-dgram echo-dgram rsync telnet time-stream
chargen-stream daytime-stream discard-stream echo-stream tcpmux-server time-dgram
比如telnet对应的内容(本机已安装telnet-server):
# default: on
# description: The telnet server serves telnet sessions; it uses \
# unencrypted username/password pairs for authentication.
service telnet
{
flags = REUSE
socket_type = stream
wait = no
user = root
server = /usr/sbin/in.telnetd
log_on_failure += USERID
disable = yes
}
默认disable字段的设置为yes,表示禁用。改为“no”,并重启xinetd,telnet就会自动启动了:
[[email protected] ~]% service xinetd restart
Stopping xinetd: [ OK ]
Starting xinetd: [ OK ]
[[email protected] ~]% ss -tnlp | grep 23 | grep -v grep
LISTEN 0 64 :::23 :::* users:(("xinetd",1756,5))
可以看到监听23号端口的进程是xinetd,而不是telnet。
也可使用chkconfig来控制telnet是否自动启动:
[[email protected] ~]% chkconfig telnet on # 瞬时守护进程不考虑级别,要令其开机自动启动,直接on就行
chkconfig控制等价于在xinetd的telnet配置文件中修改disable项,两种是一致的。
1.2.2 对于CentOS 7
由于CentOS 7使用systemd来管理所有服务,所以不再使用xinetd来管理瞬时守护进程而改用systemd。
systemd管理的各服务在/usr/lib/sysetmd/system下有对应的.service文件,不过在CentOS 7上安装的telnet-server还生成了.socket文件:
[[email protected] etc]% rpm -ql telnet-server
/usr/lib/systemd/system/telnet.socket
/usr/lib/systemd/system/[email protected]
/usr/sbin/in.telnetd
/usr/share/man/man5/issue.net.5.gz
/usr/share/man/man8/in.telnetd.8.gz
/usr/share/man/man8/telnetd.8.gz
启动telnet.socket就是令systemd代为监听23端口,而不真正启动telnet服务,待有请求来时再启动:
[[email protected] ~]% systemctl start telnet.socket
[[email protected] ~]% ss -tnlp | grep 23 | grep -v grep
LISTEN 0 128 :::23 :::* users:(("systemd",pid=1,fd=41))
可以看到监听23号端口的是systemd。
1.3 效果
telnet客户端使用格式:telnet [host[:port]]
,如果监听的不是默认端口则需要指明端口号。
默认不允许使用root直接登录,如需要,可使用普通用户登录,然后su到root。
在主机192.168.0.171(CentOS 7)启动telnet-server,在主机192.168.0.175(CentOS 7)作为客户端访问,验证效果:
1、在171创建普通用户user1:
[[email protected] ~]% useradd user1
[[email protected] ~]% echo user1 | passwd --stdin user1
Changing password for user user1.
passwd: all authentication tokens updated successfully.
2、在175,使用用户user1远程连接:
[[email protected] ~]% telnet 192.168.0.171
Trying 192.168.0.171...
Connected to 192.168.0.171.
Escape character is '^]'.
Kernel 3.10.0-514.el7.x86_64 on an x86_64
node171 login: user1
Password:
[[email protected] ~]% ip addr show | grep 192\.168 # 执行结果是171主机的
inet 192.168.0.171/24 brd 192.168.0.255 scope global ens33
2 ssh
ssh,Secure SHell,安全的远程登录协议。服务端默认监听于22号端口。
ssh分为1、2两版,由于1版有漏洞,所以使用2。
ssh协议规定了远程登录时一系列的加密、解密方式。对于使用和配置来说,主要有下述3方面:
- 主机认证
客户端访问服务端,必须能够验证所访问的就是要访问的服务端。
为此,服务端事先生成一个**对。客户端第一次登录时,把公钥给客户端1。在之后的登录,客户端只需用公钥加密一段数据发送给服务端,服务端如能解密并发给客户端,则说明是真正的服务端。 - 数据加密
对于数据的加密,要使用对称加密算法,**由双方协商,周期性更换 - 用户认证
服务端也需要验证用户身份,ssh有两种认证方式- 基于口令认证
就是用户使用密码认证。密码传送是加密的。 - 基于**认证
虽然用户密码加密了,但仍不希望其在网络上传输。
用户可在客户端生成**对,保存私钥,发送公钥给服务端(注意这个虽然是公钥,但也不能公开,只能给服务端,因为是用来验证用户的)。用户登录时,只需使用私钥加密一段数据,服务端如能解密,则认证成功,不再需要密码。
- 基于口令认证
3 openssh
openssh是ssh协议的开源实现。linux各发行版都在使用,且默认是启动的。
3.1 openssh客户端
对于linux,openssh的客户端命令就是ssh(windows的客户端有多种如Xshell、securecrt等)。
客户端配置文件/etc/ssh/ssh_config。
3.1.1 格式、常用选项和登录效果
格式:ssh [options] [[email protected]] [COMMAND]
表示使用用户user登录主机host,如果不指定user,则默认使用当前用户名;
如最后跟上指令COMMAND,则表示登录后运行指令COMMAND就退出远程登录。
常用选项:
选项 | 意义 |
---|---|
-l | 以指定用户身份登录。不使用上述格式中的”user”来指定用户 |
-p | 指定远程服务器的端口。虽然ssh服务端默认端口是22,但为安全起见,监听的往往是其他端口。所以登录时要用”-p”专门指定 |
-X | 支持X11界面转发,默认不支持。就是使远程主机上的图形界面也会传至客户端 |
-i | 用户基于**认证进行登录时,要使用私钥加密一段数据。这个私钥在哪个路径,由-i选项指定。默认路径有:~/.ssh/id_dsa, ~/.ssh/id_ecdsa, ~/.ssh/id_ed25519 ,~/.ssh/id_rsa,它们是使用不同非对称加密算法生成的私钥的默认存放位置。所以默认也无需指定 |
-b | 指定客户端以哪个IP作为源地址访问远程主机。因为有时服务端会限制某些IP的访问,所以源地址需要指定为服务端允许的 |
-o | 除了上述各命令选项,还可使用-o指定连接选项2 |
比如,使用175主机登录171主机:
[[email protected] ~]% ssh 192.168.0.171
The authenticity of host '192.168.0.171 (192.168.0.171)' can't be established.
ECDSA key fingerprint is SHA256:qub+piqPQn9dlXav7JGZ3gelFAZLNBIXWr48qb0tQGM.
ECDSA key fingerprint is MD5:cc:86:c1:18:f5:df:fe:f0:08:5d:a2:52:06:d3:e8:66.
Are you sure you want to continue connecting (yes/no)? yes # 注意,由于是第一次连接,会提示确认是否确认连接。确认连接则表示认为对方确实是要访问的主机,接受对方的公钥,该公钥就是用来在以后的连接时,进行主机认证的
Warning: Permanently added '192.168.0.171' (ECDSA) to the list of known hosts.
[email protected]'s password:
Last login: Sat Nov 25 22:16:22 2017 from 192.168.0.105
[[email protected] ~]%
接上,再次连接时,则不会再出现上述关于主机认证的提示,因为已经有服务端的公钥了:
[[email protected] ~]% ssh 192.168.0.171 ifconfig | grep 192.168 | grep -v grep
[email protected]192.168.0.171's password:
inet 192.168.0.171 netmask 255.255.255.0 broadcast 192.168.0.255
上面两次登录都没有指定用户名,所以以当前使用的用户名(root)连接了(当然前提是被连接的主机也有该用户名,并且要输入被连接主机上的该用户的密码才可登录)。
3.1.2 使用基于**的用户认证
由上述ssh协议的介绍,使用基于**的用户认证,首先要在客户端生成一个**对,而后把公钥传给服务端。之后就可不再使用密码登录。
ssh提供了专门的指令ssh-******,它会直接生成**对,无需用户生成私钥再提取公钥。
比如,在175主机生成**对:
[[email protected] ~]% ssh-****** -b 1024 -t rsa # -b指定**长度;-t指定使用的算法,默认使用的就是rsa,不指也行
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): # 指定把**存放在哪个文件,默认是用户家目录下的.ssh/id_rsa,直接回车表示就存放在默认路径,否则指定一个路径
Enter passphrase (empty for no passphrase): # 为**文件设置一个密码。这样在使用基于**登录时,仍要输入密码。不过这个密码不是用户的密码,而是在此处设置的、为这个**设置的密码
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:MPkZmbCt9JL+T3vxLDXMbtaSVmQka7e+wM59hDi36x0 [email protected]
The key's randomart image is:
+---[RSA 1024]----+
| . |
| = o . .|
| * = + |
| . B o o +|
| + S = =.|
| . . = B.o|
| . . @.E |
| . . .= &o+|
| ..o. Oo=+|
+----[SHA256]-----+
而后可看到在对应路径下,有了**对,私钥id_rsa和公钥id_rsa.pub:
[[email protected] ~]% ls .ssh/
id_rsa id_rsa.pub known_hosts y y.pub
如果在生成**对时,不想和系统交互(即无需提示存放位置和是否为私钥提供密码),可直接使用ssh-******的选项”-f:”指定**存放路径;-N指定为私钥提供的密码(可以为空)。
而后要做的是把公钥发给服务端。
ssh把用户公钥发给服务端也有专门的命令ssh-copy-id。
格式:ssh-copy-id [email protected] -i PUB_FILE
,表示以哪个用户身份user,把公钥文件PUB_FILE复制到哪个主机host。注意用户身份很重要,因为复制到的目标主机的路径,就是指定用户家目录下的authorized_keys文件。
接上,把175主机上的公钥文件复制到171主机:
[[email protected] ~]% ssh-copy-id -i .ssh/id_rsa.pub [email protected]192.168.0.171
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: ".ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
[email protected]192.168.0.171's password: # 当然第一次复制时还是需要密码认证的
Number of key(s) added: 1
Now try logging into the machine, with: "ssh '[email protected]192.168.0.171'"
and check to make sure that only the key(s) you wanted were added.
在171主机,可看到175主机root用户对应的公钥:
[[email protected] ~]% cat .ssh/authorized_keys
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQCYoFjj7KagYWuHSW4k/C9SSRDsEuiFvcAExUXlvrt3mbJRzkG50l+bYqD37Jats/KEcdCEE71Q2Tk9UToNmDcdds7A4z9HyLLbsu5i9Jt0rV+p18LmPL2p+LuaLY6/zlVNUH8QgvuKxw911mTTzJSfM57m4uKRlErQivlc40uTJQ== [email protected]
在175主机再登录时,即可直接登录,无需密码认证:
[[email protected] ~]% ssh 192.168.0.171
Last login: Sat Nov 25 23:32:09 2017 from node171
[[email protected] ~]% ip addr show | grep 192.168 | grep -v grep
inet 192.168.0.171/24 brd 192.168.0.255 scope global ens33
对于windows的Xshell,使用基于**认证,步骤类似,也是生成**对和传送公钥给服务端。工具栏下有主机认证、用户认证管理器:
Xshell的具体步骤不赘述了。
3.1.3 客户端配置文件
可以看到客户端配置文件/etc/ssh/ssh_config对有一个对所有主机的配置:
Host * # 该文件使用*表示所有主机
……
也可根据指定主机做不同的配置。配置内容主要是连接选项(就是命令ssh的-o选项所能设置的那些)。
不过一般使用默认即可。
3.2 openssh服务端
服务端程序是sshd。
服务端配置文件/etc/ssh/sshd_config。
sshd默认是独立守护进程,也可运行为瞬时守护进程。以CentOS 7来说,取决于启动的是service还是socket:
[[email protected] ~]% rpm -ql openssh-server
/etc/pam.d/sshd
/etc/ssh/sshd_config
/etc/sysconfig/sshd
/usr/lib/systemd/system/sshd-******.service
/usr/lib/systemd/system/sshd.service # sshd作为独立守护进程启动,也是默认启动
/usr/lib/systemd/system/sshd.socket # sshd作为瞬时守护进程启动
……
对sshd的管理主要通过其配置文件/etc/ssh/sshd_config,配置文件中”#”后不跟空格的表示处于注释状态的可配置内容;跟空格的表示纯注释信息。
配置格式类似于httpd的,Directive Value
其中常需设置的字段有:
-
关于监听地址和端口:
#Port 22 # 监听的端口。实际使用时为安全起见,不要使用默认的22号端口 #AddressFamily any # 使用的IP族。v4和v6两种,any表示都使用 #ListenAddress 0.0.0.0 # 监听在本机的所有地址(v4)。实际使用时,监听的地址应该是个私网地址,客户端通过VPN连如该私网,通过私网地址访问ssh服务端。并且最好通过**认证而非口令认证 #ListenAddress :: # 监听在本机的所有地址(v6)
-
指定使用的ssh协议版本,默认是2:
# The default requires explicit activation of protocol 1 #Protocol 2
-
指定进行主机认证时,服务端根据哪个**文件发给客户端公钥。不同算法对应不同文件:
# HostKeys for protocol version 2 HostKey /etc/ssh/ssh_host_rsa_key #HostKey /etc/ssh/ssh_host_dsa_key HostKey /etc/ssh/ssh_host_ecdsa_key HostKey /etc/ssh/ssh_host_ed25519_key
这些文件都有对应的公钥文件,就是用来进行主机认证的:
[[email protected] ~]% ls /etc/ssh/ssh ssh_config ssh_host_ecdsa_key ssh_host_ed25519_key ssh_host_rsa_key sshd_config ssh_host_ecdsa_key.pub ssh_host_ed25519_key.pub ssh_host_rsa_key.pub
-
关于登录认证的限制:
#LoginGraceTime 2m # 指定用户登录时间。防止用户登录时间过长浪费服务端资源 #PermitRootLogin yes # 是否允许root登录。默认是yes最好改为no #StrictModes yes #MaxAuthTries 6 # 最大尝试次数。输入多少次密码错误后自动断开 #MaxSessions 10 # 最多连接会话数。sshd还是比较消耗资源,不能开启过多ssh会话
-
指定基于**认证用户时,用户公钥在服务端的默认存放位置:
# The default is to check both .ssh/authorized_keys and .ssh/authorized_keys2 # but this is overridden so installations will only check .ssh/authorized_keys AuthorizedKeysFile .ssh/authorized_keys
这正是为什么标题3.1.2使用基于**认证时,用户公钥会存放在authorized_keys。
-
指定是否基于密码认证
# To disable tunneled clear text passwords, change to no here! #PasswordAuthentication yes #PermitEmptyPasswords no PasswordAuthentication yes
-
是否反解IP为主机名:
#UseDNS yes # 最好改为no,否则登录时会试图反解为主机名
-
访问控制
在配置文件中,默认没有使用、也没有注释出来的访问控制指令:
指令 意义 AllowUser 允许指定用户登录 AllowGroup 允许指定组登录 DenyUser 拒绝指定用户登录 DenyGroup 拒绝指定组登录 前者是做白名单、后者是做黑名单,不可同时使用。
3.3 ssh使用最佳实践
所谓最佳实践,就是前人使用过程中的经验总结,大概有以下:
1、不要使用默认端口。在配置文件中修改Port
2、不要使用ssh第一版协议。在配置文件中修改Protocol为2(默认就是2)
3、最好能限制可登录的用户。就是在服务端配置文件中做白名单(显然比黑名单更安全)
4、设定空闲会话超时时长
5、利用iptables设置安全登录策略。比如仅允许来自指定IP的主机访问等
6、服务端仅监听于指定的IP地址,服务端配置文件ListenAddress设置
7、基于口令认证时,使用强密码
8、最好使用基于**的认证,而不是口令
9、禁用空密码
10、禁止管理员直接登录
11、限制访问频度(iptables设置)、ssh会话最大并发数(服务端配置文件设定)
12、做好日志分析
4 scp与sftp
scp和sftp也是由openssh客户端提供的。
[[email protected] ~]% rpm -qf /usr/bin/scp
openssh-clients-6.6.1p1-31.el7.x86_64
[[email protected] ~]% rpm -qf /usr/bin/sftp
openssh-clients-6.6.1p1-31.el7.x86_64
它们也都基于ssh协议。
4.1 scp
scp,secure cp,用于安全、跨主机复制文件。
可把本地主机的文件复制到远程主机的指定路径;也可把远程主机的文件复制到本地主机指定路径。
格式:
scp 本地文件路径 user@host:/远程主机文件路径
scp 远程主机文件路径 user@host:/本地文件路径
常用选项:
选项 | 意义 |
---|---|
-r | 同cp的-r选项,递归地复制目录下的内容 |
-p | 保存原文件的元数据信息(主要是权限) |
-p PORT | 指定远程主机端口。因为服务端很可能不使用默认的22号端口 |
容易理解,不再赘述演示。
4.2 sftp
使用类似ftp,不过更加安全,ftp是明文传输的3。
sftp是openssh的一个子系统,所以默认是启动的,直接使用sftp使用即可。复制文件比scp更灵活。
比如在175主机,复制171主机的文件:
[[email protected] ~]% sftp 192.168.0.171
Connected to 192.168.0.171.
sftp> ls
anaconda-ks.cfg repo.sh
sftp> get repo.sh
Fetching /root/repo.sh to repo.sh
sftp> exit
由于上述已使用175做**认证,所以此处使用sftp没有要求密码。
注意,复制时有同名文件会直接覆盖,而且不会提示!
(完)