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 [email protected] |
服務端執行結果:
客戶端遠端服務端執行結果:
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 [email protected]:~/.ssh |
B上執行的操作:
cd /root/.ssh touch authorized_keys cat id_rsa.pub >> authorized_keys |
在A上執行遠端B的命令:
ssh [email protected] 'pwd' |
2) 指定埠和使用者進行免密登入
這裡以 兩個伺服器的 ssh 埠 一致為前提來進行示範。
146 伺服器上建立testa使用者,145 伺服器上建立testb 使用者,下面以在 145 上面建立 testb 為例:
#新增 testb使用者 useradd testb #修改使用者 testb 的密碼 passwd testb # 在 /home 下可以看到 testb 資料夾 ll /home |
146/145 兩臺伺服器上分別為 testa\testb,測試 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 mkdirmkdir /home/testb/.ssh #在A上執行 scp id_rsa.pub [email protected]:~/.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 [email protected] '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