Linux 学习笔记之(十一)SSH

一、背景

     要想从本地访问远程 Linux 服务器,通常会使用一些 SSH 工具,但有时也希望程序脚本中通过 SSH 命令让远程 Linux 服务器执行一些脚本,本篇文章介绍 SSH 的基本原理,以及如何免密通过 SSH 命令 执行远程 服务器上的某些命令。

二、知识点

1、SSH 原理

 1) 基于口令认证远程

 说明:

  • “服务端的公钥指纹存放到known_hosts文件中”:客户端从服务端接受到公钥之后,直接获取了公钥指纹,先会和本地 known_hosts 文件做对比,若该公钥指纹存在文件中,则不会向用户提示确认信息,否则需要用户确认,是否连接服务端;

第一次远程服务器,控制台会显示:

 上图显示会自动把对端信息写入到 known hosts 文件中,输入密码成功远程之后退出,查看客户端 known_hosts 文件中的内容如下:

有的操作系统的客户端第一次远程会显示:

 上图显示是要用户确认是否远程到服务端。

针对上述的第一种情况,非第一次登陆就不会出现那个 warning:

 显然直接要求输入密码。

 2) 基于公钥认证远程(免密)

2、SSH 配置

  SSH 的 配置文件 在 /etc/ssh 目录下,linux 环境中 可以看到该目录下有2个配置文件:

 1) sshd_config

#    $OpenBSD: sshd_config,v 1.100 2016/08/15 12:32:04 naddy Exp $

# This is the sshd server system-wide configuration file.  See
# sshd_config(5) for more information.

# This sshd was compiled with PATH=/usr/local/bin:/usr/bin

# The strategy used for options in the default sshd_config shipped with
# OpenSSH is to specify options with their default value where
# possible, but leave them commented.  Uncommented options override the
# default value.

# If you want to change the port on a SELinux system, you have to tell
# SELinux about this change.
# semanage port -a -t ssh_port_t -p tcp #PORTNUMBER
#
Port 55555            # sshd 服务启动的时候,使用的远程端口
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::

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

# Ciphers and keying
#RekeyLimit default none

# Logging
#SyslogFacility AUTH
SyslogFacility AUTHPRIV
#LogLevel INFO

# Authentication:

#LoginGraceTime 2m
PermitRootLogin yes     # 需要设置成 yes ,客户端才能用 root 账号远程
#StrictModes yes
#MaxAuthTries 6
#MaxSessions 10

#PubkeyAuthentication yes

# 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

#AuthorizedPrincipalsFile none

#AuthorizedKeysCommand none
#AuthorizedKeysCommandUser nobody

# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
#HostbasedAuthentication no
# Change to yes if you don't trust ~/.ssh/known_hosts for
# HostbasedAuthentication
#IgnoreUserKnownHosts no
# Don't read the user's ~/.rhosts and ~/.shosts files
#IgnoreRhosts yes

# To disable tunneled clear text passwords, change to no here!
#PasswordAuthentication yes
#PermitEmptyPasswords no
PasswordAuthentication yes

# Change to no to disable s/key passwords
#ChallengeResponseAuthentication yes
ChallengeResponseAuthentication no

# Kerberos options
#KerberosAuthentication no
#KerberosOrLocalPasswd yes
#KerberosTicketCleanup yes
#KerberosGetAFSToken no
#KerberosUseKuserok yes

# GSSAPI options
GSSAPIAuthentication yes
GSSAPICleanupCredentials no
#GSSAPIStrictAcceptorCheck yes
#GSSAPIKeyExchange no
#GSSAPIEnablek5users no

# Set this to 'yes' to enable PAM authentication, account processing,
# and session processing. If this is enabled, PAM authentication will
# be allowed through the ChallengeResponseAuthentication and
# PasswordAuthentication.  Depending on your PAM configuration,
# PAM authentication via ChallengeResponseAuthentication may bypass
# the setting of "PermitRootLogin without-password".
# If you just want the PAM account and session checks to run without
# PAM authentication, then enable this but set PasswordAuthentication
# and ChallengeResponseAuthentication to 'no'.
# WARNING: 'UsePAM no' is not supported in Red Hat Enterprise Linux and may cause several
# problems.
UsePAM yes

#AllowAgentForwarding yes
#AllowTcpForwarding yes
#GatewayPorts no
X11Forwarding yes
#X11DisplayOffset 10
#X11UseLocalhost yes
#PermitTTY yes
#PrintMotd yes
#PrintLastLog yes
#TCPKeepAlive yes
#UseLogin no
#UsePrivilegeSeparation sandbox
#PermitUserEnvironment no
#Compression delayed
#ClientAliveInterval 0
#ClientAliveCountMax 3
#ShowPatchLevel no
#UseDNS no
#PidFile /var/run/sshd.pid
#MaxStartups 10:30:100
#PermitTunnel no
#ChrootDirectory none
#VersionAddendum none

# no default banner path
#Banner none    #可以指定具体文件路径,该文件中存放成功登录该服务器的提示语

# Accept locale-related environment variables
AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE
AcceptEnv XMODIFIERS

# override default of no subsystems
Subsystem    sftp    /usr/libexec/openssh/sftp-server

# Example of overriding settings on a per-user basis
#Match User anoncvs
#    X11Forwarding no
#    AllowTcpForwarding no
#    PermitTTY no
#    ForceCommand cvs server 

 上图为成功登录的提示

 2) ssh_config

#    $OpenBSD: ssh_config,v 1.30 2016/02/20 23:06:23 sobrado Exp $

# This is the ssh client system-wide configuration file.  See
# ssh_config(5) for more information.  This file provides defaults for
# users, and the values can be changed in per-user configuration files
# or on the command line.

# Configuration data is parsed as follows:
#  1. command line options
#  2. user-specific file
#  3. system-wide file
# Any configuration value is only changed the first time it is set.
# Thus, host-specific definitions should be at the beginning of the
# configuration file, and defaults at the end.

# Site-wide defaults for some commonly used options.  For a comprehensive
# list of available options, their meanings and defaults, please see the
# ssh_config(5) man page.

# Host *
#   ForwardAgent no
#   ForwardX11 no
#   RhostsRSAAuthentication no
#   RSAAuthentication yes
#   PasswordAuthentication yes
#   HostbasedAuthentication no
#   GSSAPIAuthentication no
#   GSSAPIDelegateCredentials no
#   GSSAPIKeyExchange no
#   GSSAPITrustDNS no
#   BatchMode no
#   CheckHostIP yes
#   AddressFamily any
#   ConnectTimeout 0
#   StrictHostKeyChecking ask
#   IdentityFile ~/.ssh/identity
#   IdentityFile ~/.ssh/id_rsa
#   IdentityFile ~/.ssh/id_dsa
#   IdentityFile ~/.ssh/id_ecdsa
#   IdentityFile ~/.ssh/id_ed25519
   Port 55555    # 这里默认的是22 ,若是在 sshd_config 文件中更改了端口,又想在ssh命令远程的时候不指定端口的话,这里需要更改成 和 sshd_config 中 Port 一样的端口值,否则无法不指定端口进行远程
#   Protocol 2
#   Cipher 3des
#   Ciphers aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc
#   MACs hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160
#   EscapeChar ~
#   Tunnel no
#   TunnelDevice any:any
#   PermitLocalCommand no
#   VisualHostKey no
#   ProxyCommand ssh -q -W %h:%p gateway.example.com
#   RekeyLimit 1G 1h
#
# Uncomment this if you want to use .local domain
# Host *.local
#   CheckHostIP no

Host *
    GSSAPIAuthentication yes
# If this option is set to yes then remote X11 clients will have full access
# to the original X11 display. As virtually no X11 client supports the untrusted
# mode correctly we set this to yes.
    ForwardX11Trusted yes
# Send locale-related environment variables
    SendEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
    SendEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
    SendEnv LC_IDENTIFICATION LC_ALL LANGUAGE
    SendEnv XMODIFIERS

 3、SSH远程登录

1)使用默认的端口和root 用户

ssh 用户名@服务器IP

2)指定SSH端口和用户进行登录

#在服务端添加测试用户

#创建测试用户

useradd testa

#修改测试用户登录密码,这里密码修改成了 testa

passwd testa

#在客户端使用测试用户帐号远程登录服务端

ssh -p 22 testa@10.19.214.146

服务端执行结果:

 客户端远程服务端执行结果:

  4、SSH单向免密登录

服务端信息:

A:10.19.214.146

B:10.19.214.145

1) 使用默认的端口和 root 用户进行免密登录 (A免密登录B)

前提: A 和 B 均使用了 root 账号登录,并进行下列操作

  • 在A上生成公钥/私钥
  • 将A上的公钥文件拷贝到B上
  • 在B上将从A同步过来的公钥写入到authorized_keys 文件中
  • 在A上远程B

A上执行的操作:

ssh-keygen -t rsa

scp id_rsa.pub root@10.19.214.145:~/.ssh

 B上执行的操作:

cd /root/.ssh

touch authorized_keys

cat id_rsa.pub >> authorized_keys

 在A上执行远程B的命令:

ssh root@10.19.214.145 'pwd'

 

2) 指定端口和用户进行免密登录

  这里以 两个服务器的 ssh 端口 一致为前提来进行示范。

146 服务器上创建testa用户,145 服务器上创建testb 用户,下面以在 145 上面创建  testb 为例:

#添加 testb用户

useradd testb

#修改用户 testb 的密码

passwd testb

# 在 /home 下可以看到 testb 文件夹

ll /home

146/145 两台服务器上分别为 testa estb,测试 146 在当前登录用户为 testa 的情况下,使用 testb 账号信息登录 145

  • 在A上生成公钥/私钥
  • 将A上的公钥文件拷贝到B上
  • 在B上将从A同步过来的公钥写入到authorized_keys 文件中
  • 在A上远程B

A上执行:

#在A上执行

su testa

ssh-keygen -t rsa

cd /home/testa/.ssh

#在B上执行

su testb

mkdir mkdir /home/testb/.ssh

#在A上执行

scp id_rsa.pub testb@10.19.214.145:~/.ssh

chmod 700 /home/testa/.ssh/

#在B上执行

cd /home/testa/.ssh

touch authorized_keys

cat id_rsa.pub >>authorized_keys

chmod 700 /home/testb/.ssh/

chmod 600 /home/testb/.ssh/authorized_keys

#在A上执行

ssh testb@10.19.214.145 'pwd'   #测试远程

 

 A成功免密远程登录到B

PS: 在上面的示例中仍然使用了默认SSH端口进行远程,若要指定SSH的某个端口 可以在远程的时候 使用  -p <端口> 选项。

 5、SSH 双向免密登录

服务端信息:

A:10.19.214.146

B:10.19.214.145

1) 使用默认的端口和 root 用户进行互信

前提: A 和 B 均使用了 root 账号登录,并进行下列操作

   a)  A 信任 B,免密登录B

     具体操作参考上面章节:  4、SSH单向免密登录  1) 使用默认的端口和 root 用户进行免密登录,但在 4 1) 操作中直接将A的公钥文件同步到B的.ssh/id_rsa.pub 文件中,建议重命名,否则会覆盖 B自己本身的公钥文件

 

 

 至此 A信任B,A可以远程B

   b)  B 信任A。免密登录A

    该操作流程实际上和 a) 相反

 

 

 

 上面 两张 图显示 A、B 机可以互相远程

2) 指定端口和用户进行互信

  这里以 两个服务器的 ssh 端口 一致为前提来进行互信示范。

 操作方式和上面基本雷同,只是  A、B 机的命令都要在对应用户下操作 ,同时  .ssh 下的文件是在 /home/用户 下

   a)  A 免密远程 B

 

 此时 在 A 上用 testa 可以使用 testb 账号免密远程到 B

   b)  B 免密远程 A

 

 

 

参考:

https://www.cnblogs.com/ftl1012/p/ssh.html

https://www.cnblogs.com/viplanyue/p/12700775.html

原文地址:https://www.cnblogs.com/sandyflower/p/15240317.html