欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

远程登录工具----telnet、openssh

程序员文章站 2022-06-05 18:37:24
...

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. 主机认证
    客户端访问服务端,必须能够验证所访问的就是要访问的服务端。
    为此,服务端事先生成一个**对。客户端第一次登录时,把公钥给客户端1。在之后的登录,客户端只需用公钥加密一段数据发送给服务端,服务端如能解密并发给客户端,则说明是真正的服务端。
  2. 数据加密
    对于数据的加密,要使用对称加密算法,**由双方协商,周期性更换
  3. 用户认证
    服务端也需要验证用户身份,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,使用基于**认证,步骤类似,也是生成**对和传送公钥给服务端。工具栏下有主机认证、用户认证管理器:

远程登录工具----telnet、openssh

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没有要求密码。
注意,复制时有同名文件会直接覆盖,而且不会提示

(完)


  1. 不过在用户第一次登录时,只能依靠用户自己确认是否是要访问的服务端了
  2. 类似mount的挂载选项。mount除了有各命令选项外,还可用-o来指定挂载选项,使挂载方式按挂载选项指定的设置进行
  3. ftps也是使用密文的文件传输程序,只不过这个是ftp在ssl之上实现的。
    据说ftps和sftp都不好用。ftps笔者不知道,反正ftps覆盖同名文件不提示这一点,就觉得是非常不好用了。
相关标签: 远程登录