SSH服務連接


SSH基本概述

SSH是一個安全協議,在進行數據傳輸時,會對數據包進行加密處理,加密后在進行數據傳輸。確保了數據傳輸安全。

SSH服務

ssh: secure shell, protocol, 22/tcp, 安全的遠程登錄

具體的軟件實現:

OpenSSH: ssh協議的開源實現,CentOS默認安裝

SSH協議版本

v1: 基於CRC-32做MAC,不安全;man-in-middle

v2:雙方主機協議選擇安全的MAC方式

基於DH算法做密鑰交換,基於RSA或DSA實現身份認證

兩種方式的用戶登錄認證:

基於password

基於key

ssh選項:

-A:開啟認證代理連接轉發功能;
-a:關閉認證代理連接轉發功能;
-b:使用本機指定地址作為對應連接的源ip地址;
-C:請求壓縮所有數據;
-F:指定ssh指令的配置文件;
-f:后台執行ssh指令;
-g:允許遠程主機連接主機的轉發端口;
-i:指定身份文件;
-l:指定連接遠程服務器登錄用戶名;
-N:不執行遠程指令;
-o:指定配置選項;
-p:指定遠程服務器上的端口;
-q:靜默模式;
-X:開啟X11轉發功能;
-x:關閉X11轉發功能;
-y:開啟信任X11轉發功能。

SSH服務主要功能:

  1. 提供遠程連接服務器的服務

  2. 對傳輸的數據進行加密

SSHTelnet的區別:

  • ssh服務對傳輸數據進行加密,監聽在本地22/tcp端口, ssh服務默認支持root用戶登錄

  • telnet服務不對數據進行加密,監聽在本地23/tcp端口,,Telnet默認不支持root用戶登錄

  • 服務連接方式 服務數據傳輸 服務監聽端口 服務登陸用戶
    ssh 加密 22/tcp 默認支持root用戶登陸
    telnet 明文 23/tcp 不支持root用戶登陸
  • 企業面試題

    下列服務,分別使用的那個端口?

     ftp     21/tcp
     dns     53/udp
     ssh     22/tcp
     telnet  23/tcp
     mysql   3306/tcp
     http    80/tcp
     https   443/tcp 443/udp

    使用wireshark驗證telnet明文傳輸與ssh加密傳輸

    1. 安裝telnet服務並運行

     [root@m01 ~]# yum -y install telnet-server
     [root@m01 ~]# systemctl start telnet.socket
    1. 使用wireshark檢測vmnet8網卡上telnet的流量

    2.  

      3. telnet無法使用root用戶登錄Linux系統,需要創建普通用戶       

    3. [root@nfs ~]# useradd admin
      [root@nfs ~]# echo "123"| passwd --stdin admin
      

        使用普通用戶進行telnet登錄

    4.  

       搜索wireshark包含telnet相關的流量

    5.  

       

      6.使用wireshark分析ssh流量

    6.  

       

       

      SSH相關命令

      SSH有客戶端與服務端,我們將這種模式稱為C/S架構,ssh客戶端支持Windows、Linux、Mac等平台。 在ssh客戶端中包含 ssh|slogin遠程登陸、scp遠程拷貝、sftp遠程數據傳輸、ssh-copy-id秘鑰分發等應用程序。 

    7. SSH有客戶端與服務端,我們將這種模式稱為C/S架構,ssh客戶端支持Windows、Linux、Mac等平台。 在ssh客戶端中包含 ssh|slogin遠程登陸、scp遠程拷貝、sftp遠程數據傳輸、ssh-copy-id秘鑰分發等應用程序。
    8. ssh遠程登錄服務器命令示例

       ssh [-p port] [user@]hostname [command]
       # -p指定連接遠程主機端口,默認22端口可省略
       # "@"前面為用戶名,如果用當前用戶連接,可以不指定用戶
       # "@"后面為要連接的服務器的IP
       [root@m01 ~]# ssh -p22 root@10.0.0.41  # 遠程登錄服務器
       [root@m01 ~]# ssh root@172.16.1.41 "hostname -i" # 遠程在指定服務器執行命令
       172.16.1.41

      scp遠程拷貝(全量復制)至遠程主機命令示例

    9. scp [-pr] [-P port] [-l limit] [[user@]host1:]file1 ... [[user@]host2:]file2
      # -P 指定端口,默認22端口可不寫
      # -r 表示遞歸拷貝目錄
      # -p 表示在拷貝文件前后保持文件或目錄屬性不變
      # -l 限制傳輸使用帶寬(默認kb)

    10. # 推:將本地/tmp/oldboy推送至遠端服務器10.0.0.61的/tmp目錄,使用對端的root用戶

      [root@m01 ~]# scp -P22 -rp /tmp/oldboy oldboy@10.0.0.61:/tmp
    11. # 拉:將遠程10.0.0.61服務器/tmp/oldboy文件拉取到本地/opt/目錄下

      [root@m01 ~]# scp -P22 -rp root@10.0.0.61:/tmp/oldboy /opt/
    12. # 限速

      [root@m01 ~]# scp /opt/1.txt root@172.16.1.31:/tmp
      root@172.16.1.31 password: 
      test 100% 656MB '83.9MB/s' 00:07 
      # 限速為8096kb,換算為MB,要除以 8096/8=1024KB=1MB
      [root@m01 ~]# scp -rp -l 8096 /opt/1.txt root@172.16.1.31:/tmp
      root@172.16.1.31s password: 
      test 7% 48MB '1.0MB/s' 09:45
    13. 結論:

      1. scp通過ssh協議加密方式進行文件或目錄拷貝。

      2. scp使用連接時指定的用戶作為為拷貝文件或目錄的權限。

      3. scp支持數據推送和拉取,每次都是全量拷貝,效率較低。

    14. sftp遠程數據傳輸命令

       # 默認可以通過sftp命令連接sftp服務
       sftp root@10.0.0.61
       sftp -oPort=22222 root@10.0.0.61  # -o 使用ssh的選項
       # sftp使用get下載文件至於本地服務器
       sftp> get conf.txt /tmp/
       # sftp使用put上傳本地服務器文件~至遠程服務器
       sftp> put /root/t1.txt /root/

      ssh加密通訊

    15. 基於用戶和口令登錄驗證 1 客戶端發起ssh請求,服務器會把自己的公鑰發送給用戶 2 用戶會根據服務器發來的公鑰對密碼進行加密 3 加密后的信息回傳給服務器,服務器用自己的私鑰解密,如果密碼正確,則 用戶登錄成功

      示例:ssh 192.168.34.100 默認以root身份連接對方的主機

      當我們第一次連接對方的時候,會出現是否想去連接對方的提示信息,如果選擇yes,並輸入對方的口令后,就會將對方的公鑰文件存到自己/root/.ssh 目錄下,此目錄下有一個文件名叫konwn_hosts

    16. SSH驗證方式

      基於賬戶密碼遠程登錄

      知道服務器的IP端口,賬號密碼,即可通過ssh客戶端命令登陸遠程主機。

      ~ ssh -p22 root@10.0.0.61
       root@10.0.0.61 password:
       [root@m01 ~]#

      基於秘鑰遠程登錄

      默認情況下,通過ssh客戶端命令登陸遠程服務器,需要提供遠程系統上的帳號與密碼,但為了降低密碼泄露的機率和提高登陸的方便性,建議使用密鑰驗證方式。

       

       

       

      1. 在服務器上生成非對稱密鑰,使用-t指定要創建的密鑰類型, 使用-C提供新注釋

       [root@m01 ~]# ssh-keygen -t rsa -C 593528156@qq.com
       # 默認一路回車即可
      1. 將A服務器上的公鑰推送至B服務器

       ssh-copy-id [-i [identity_file]] [user@]hostname
       -i        # 指定下發的公鑰文件的路徑
       [user@]   # 指定分發公鑰的用戶身份,默認以當前系統用戶身份
       hostname  # 下發公鑰至那台服務器, 填寫遠程主機IP地址
       # 分發公鑰,[將A服務器的公鑰寫入B服務器的~/.ssh/authorized_keys文件中]
       [root@m01 ~]# ssh-copy-id -i ~/.ssh/id_rsa.pub root@172.16.1.41
      1. 如果A服務器連接B服務器無需密碼則表示秘鑰已配置成功

       [root@m01 ~]# ssh root@172.16.1.41
       [root@nfs ~]#

      SSH應用場景

      用戶通過Windows/MAC/Linux客戶端連接跳板機免密碼登錄,跳板機連接后端無外網的Linux主機實現免密登錄,架構圖如下。 實踐多用戶登陸一台服務器無密碼 實踐單用戶登陸多台服務器免密碼

    17.  

      1. windows客戶端使用Xshell生成秘鑰對,並下發公鑰至跳板機

                   1) Xshell-->選擇工具-->新建用戶密鑰生成向導

    18.  

       

       

       2) 選擇創建密鑰類型和密鑰長度,默認即可,選擇下一步

    19.  

      3) 生成公鑰對,選擇下一步 

    20.  

       4) 填寫秘鑰名稱。秘鑰加密密碼不建議配置

    21.  

       5) Windows會提示密碼為空,選是即可

    22.  

      6) 生成秘鑰后,點擊Xshell-->工具-->用戶秘鑰管理者 

    23.  

      7) 選擇對應秘鑰的屬性 

    24.  

       8) 選擇對應秘鑰的公鑰,將其復制或者保存為文件

    25. 9) 將從WIndows下復制好的公鑰粘貼至跳板機~/.ssh/authorized_keys中,然后測試

       [root@m01 ~]# cd ; umask 077; mkdir -p .ssh ;cd .ssh
       [root@m01 .ssh]# vim authorized_keys  # 添加windows公鑰
      1. 跳板機下發公鑰至后端主機

      1) 在跳板機上生成秘鑰對

       [root@m01 ~]# ssh-keygen -t rsa -C manager@qq.com

      2) 拷貝跳板機上的密鑰至后端主機,如果SSH不是使用默認22端口, 使用-p指定對應端口

       [root@m01 ~]# ssh-copy-id  -i /root/.ssh/id_rsa.pub -p22 root@172.16.1.31
       [root@m01 ~]# ssh-copy-id  -i /root/.ssh/id_rsa.pub -p22 root@172.16.1.41

      3) 在m01管理機上測試是否成功登陸兩台服務器

    26. [root@m01 ~]# ssh root@172.16.1.41
      [root@nfs01 ~]# exit
      [root@m01 ~]# ssh root@1172.16.1.31
      [root@backup ~]# exit
    27. 通過跳板機能實現scp拷貝文件免密碼
    28. [root@m01 ~]# scp zls.txt root@172.16.1.31:/tmp
      zls.txt 100% 0 0.0KB/s 00:00 
      [root@m01 ~]# scp zls.txt root@172.16.1.41:/tmp
      zls.txt 100% 0 0.0KB/s 00:00
    29. 通過跳板機獲取所有機器的load,CPU,Memory等信息(思考:如果服務器數量多,如何並發查看和分發數據)
    30. [root@m01 ~]# cat all.sh 
      #!/usr/bin/bash
      [ $# -ne 1 ] && echo "請輸入執行的命令" && exit 1
      
      for i in 31 41
      do
      echo "172.16.1.$i"
      ssh root@172.16.1.$i "$1"
      done
    31. #!/bin/bash
      #jumpserver
      lb01=10.0.0.5
      lb02=10.0.0.6
      web01=10.0.0.7
      web02=10.0.0.8
      web03=10.0.0.9
      nfs=10.0.0.31
      backup=10.0.0.41
      db01=10.0.0.51
      m01=10.0.0.61
      zabbix=10.0.0.71
      
      menu(){
      cat <<-EOF
      +-------------------------+
      | 1) lb01 |
      | 2) lb02 |
      | 3) web01 |
      | 4) web02 |
      | 5) web03 |
      | 6) nfs |
      | 7) backup |
      | 8) db01 |
      | 9) m01 |
      | 10) zabbix |
      | h) help |
      +-------------------------+
      EOF
      }
      #菜單函數
      menu
      
      #連接函數
      connect(){
      ping -c 1 -w 1 $1 &>/dev/null
      if [ $? -eq 0 ];then
      ssh root@$1
      else
      echo -e "\033[5;4;40;31m 別連了,我的哥,$2:$1機器都沒開!!!\033[0m"
      fi
      }
      
      #控制不讓輸入ctrl+c,z
      trap "" HUP INT TSTP
      while true
      do
      read -p "請輸入要連接的主機編號:" num
      case $num in
      1|lb01)
      connect $lb01 lb01
      ;;
      2|lb02)
      connect $lb02 lb02
      ;;
      3|web01)
      connect $web01 web01
      ;;
      4|web02)
      connect $web02 web02
      ;;
      5|web03)
      connect $web03 web03
      ;;
      6|nfs)
      connect $nfs nfs
      ;;
      7|backup)
      connect $backup backup
      ;;
      8|db01)
      connect $db01 db01
      ;;
      9|m01)
      connect $m01 m01
      ;;
      10|zabbix)
      connect $zabbix zabbix
      ;;
      h|help)
      clear
      menu
      ;;
      close)
      break
      ;;
      esac
      done
    32. 腳本實現(圖形化跳板機)
    33. #!/bin/bash
      
      lb01=10.0.0.5
      lb02=10.0.0.6
      web01=10.0.0.7
      web02=10.0.0.8
      web03=10.0.0.9
      nfs=10.0.0.31
      backup=10.0.0.41
      db01=10.0.0.51
      db02=10.0.0.52
      m01=10.0.0.61
      zabbix=10.0.0.71
      
      title="歡迎進入lnb跳板機-$m01"
      
      #跳板機函數
      JUMP(){
      OPTION=$(whiptail --title "$title" --menu "請選擇你要連接的服務器:" 25 60 11 \
      "1" "連接 lb01" \
      "2" "連接 lb02" \
      "3" "連接 web01" \
      "4" "連接 web02" \
      "5" "連接 web03" \
      "6" "連接 nfs" \
      "7" "連接 backup" \
      "8" "連接 db01" \
      "9" "連接 db02" \
      "10" "連接 m01" \
      "11" "連接 zabbix" 3>&1 1>&2 2>&3)
      
      exitstatus=$?
      if [ $exitstatus = 0 ]; then
      case $OPTION in
      1)
      connect $lb01
      ;;
      2)
      connect $lb02
      ;;
      3)
      connect $web01
      ;;
      4)
      connect $web02
      ;;
      5)
      connect $web03
      ;;
      6)
      connect $nfs
      ;;
      7)
      connect $backup
      ;;
      8)
      connect $db01
      ;;
      9)
      connect $db02
      ;;
      10)
      connect $m01
      ;;
      11)
      connect $zabbix
      ;;
      12)
      connect $te
      ;;
      13)
      connect $te_web
      ;;
      esac
      fi
      }
      
      #主機函數
      HOST_INFO (){
      HOST=$(whiptail --title "$title" --checklist \
      "請選擇要發送的主機名:" 25 60 11 \
      "$lb01" "發送給lb01" OFF \
      "$lb02" "發送給lb01" OFF \
      "$web01" "發送給web01" OFF \
      "$web02" "發送給web02" OFF \
      "$web03" "發送給web03" OFF \
      "$nfs" "發送給nfs" OFF \
      "$backup" "發送給backup" OFF \
      "$db01" "發送給db01" OFF \
      "$db02" "發送給db02" OFF \
      "$m01" "發送給m01" OFF \
      "$zabbix" "發送給zabbix" OFF 3>&1 1>&2 2>&3)
      }
      
      SER_INFO(){
      SER=$(whiptail --title "$title" --checklist \
      "請選擇要檢查的服務:" 25 60 10 \
      "nginx" "檢查nginx" OFF \
      "mysqld" "檢查mysqld" OFF \
      "php" "檢查php" OFF \
      "tomcat" "檢查tomcat" OFF \
      "sshd" "檢查sshd" OFF \
      "httpd" "檢查httpd" OFF \
      "vsftpd" "檢查vsftpd" OFF \
      "docker" "檢查docker" OFF \
      "saltstack" "檢查saltstack" OFF \
      "rsyncd" "檢查rsyncd" OFF 3>&1 1>&2 2>&3)
      }
      
      #連接函數
      connect(){
      whiptail --title "$title" --yesno "你確定要連接這台機器么?想好了啊!!!" 10 60
      if [ $? -eq 0 ];then
      {
      ping -c 1 -w 1 $1 >/tmp/ping.txt 2>/dev/null
      if [ $? -ne 0 ];then
      for ((i = 0 ; i <= 100 ; i+=30)); do
      sleep 1
      echo $i
      done
      fi
      } | whiptail --gauge "emmmm...我正在連接$1,檢測網絡中,等我一哈子..." 6 60 0
      grep 'ttl' /tmp/ping.txt &>/dev/null
      if [ $? -eq 0 ];then
      ssh root@$1
      else
      whiptail --title "$title" --msgbox "網絡檢測失敗,別連了,我的哥,$1機器都沒開" 10 60
      fi
      
      fi
      }
      
      #推送文件函數
      SCP (){
      HOST_INFO
      
      PA=$(whiptail --title "$title" --inputbox "請輸入需要推送的文件本地路徑:" 10 60 /etc/passwd 3>&1 1>&2 2>&3)
      DEST=$(whiptail --title "$title" --inputbox "請輸入需要分發到主機的哪個目錄:" 10 60 /tmp 3>&1 1>&2 2>&3)
      {
      for H in ${HOST};do
      echo "scp $PA ${H}:${DEST}"|bash &>/dev/null
      for ((i = 0 ; i <= 100 ; i+=50));do
      sleep 1
      echo $i
      done
      done
      } | whiptail --gauge "別着急,正在傳送中..." 6 60 0
      }
      
      #檢查磁盤函數
      CHECK_DISK (){
      HOST_INFO
      
      for H in ${HOST};do
      echo "ssh $H 'df -h' "|bash > /tmp/disk
      whiptail --title "$(date +%F-%T) | $H 磁盤信息" --msgbox "$(cat /tmp/disk)" 10 60
      done
      }
      
      #檢查內存函數
      CHECK_MEM (){
      HOST_INFO
      
      for H in ${HOST};do
      echo "ssh $H 'free -m' "|bash > /tmp/meminfo
      whiptail --title "$(date +%F-%T) | $H 內存信息" --msgbox "$(cat /tmp/meminfo)" 30 80
      done
      }
      
      #查看服務狀態
      CHECK_SER (){
      HOST_INFO
      SER_INFO
      
      for H in ${HOST};do
      for S in ${SER};do
      HO=`echo "$H"|awk -F \" '{print $2}'`
      PROC=`ssh $HO "ps -ef|grep $S|wc -l"`
      NUM=$( expr $PROC - 3 )
      if [[ $PROC > 3 ]];then
      whiptail --title "$(date +%F-%T) | $H 服務信息" --msgbox "${S} 存活 | 進程數:$NUM" 10 60
      else
      whiptail --title "$(date +%F-%T) | $H 服務信息" --msgbox "${S} 沒有存活| 進程數:$NUM" 10 60
      fi
      done
      done
      }
      
      #批量之心命令函數
      EXEC_CMD(){
      HOST_INFO
      
      CMD=$(whiptail --title "$title" --inputbox "請輸入要執行的命令:" 10 60 ifconfig 3>&1 1>&2 2>&3)
      for H in ${HOST};do
      HO=`echo "$H"|awk -F \" '{print $2}'`
      RES=`ssh $HO "$CMD"`
      whiptail --title "$(date +%F-%T) | $H 命令執行結果" --msgbox "$RES" 40 80
      done
      
      
      }
      
      
      #退出函數
      EXIT(){
      pass=$(whiptail --title "$title" --passwordbox "請輸入你的退出密碼" 10 60 3>&1 1>&2 2>&3)
      if [ $pass == '123456' ];then
      exit
      else
      whiptail --title "$title" --msgbox "密碼錯誤,你不是運維,小樣的~~~" 10 60
      continue
      fi
      }
      
      whiptail --title "$title" --msgbox "lnb跳板機,給你全新不一樣的feel,進去了,就不想出來" 10 60
      
      #抓取鍵盤信號
      trap "" HUP INT TSTP
      while true;do
      OPTION=$(whiptail --title "$title" --menu "請選擇你的動作(輕點...)" 15 60 8 \
      "1" "SSH遠程連接" \
      "2" "推送文件" \
      "3" "查看磁盤空間" \
      "4" "查看內存空間" \
      "5" "查看服務狀態" \
      "6" "批量執行命令" \
      "7" "輕松一下(game)" \
      "8" "退出" 3>&1 1>&2 2>&3)
      
      exitstatus=$?
      if [ $exitstatus = 0 ]; then
      case $OPTION in
      1)
      JUMP
      ;;
      2)
      SCP
      ;;
      3)
      CHECK_DISK
      ;;
      4)
      CHECK_MEM
      ;;
      5)
      CHECK_SER
      ;;
      6)
      EXEC_CMD
      ;;
      7)
      sh /root/eluosi.sh
      ;;
      8)
      EXIT
      ;;
      esac
      fi
      done
    34. vim ip.sh 書寫腳本文件
      #!/bin/bash
      user=wang
      password=centos
      ssh-keygen -t rsa -P "" -f /root/.ssh/id_rsa
      
      while read ip ;do
      expect <<EOF
      set timeout 10
      spawn ssh-copy-id -i /root/.ssh/id_rsa.pub $user@$ip
      expect {
      "yes/no" { send "yes\n";exp_continue }
      "password" { send "$password\n" }
      }
      expect eof
      EOF
      done < ip list.txt
      
      SSH安全優化
      SSH作為遠程連接服務,通常我們需要考慮到該服務的安全,所以需要對該服務進行安全方面的配置。
      
      更改遠程連接登陸的端口
      
      禁止ROOT管理員直接登錄
      
      密碼認證方式改為密鑰認證
      
      重要服務不使用公網IP地址
      
      使用防火牆限制來源IP地址
      
      SSH服務登錄防護需進行如下配置調整,先對如下參數進行了解
      Port 6666 # 變更SSH服務遠程連接端口
      PermitRootLogin no # 禁止root用戶直接遠程登錄
      PasswordAuthentication no # 禁止使用密碼直接遠程登錄
      UseDNS no # 禁止ssh進行dns反向解析,影響ssh連接效率參數
      GSSAPIAuthentication no # 禁止GSS認證,減少連接時產生的延遲
      
      #END#
      免交互expect[擴展]
      安裝expect
      
       [root@m01 ~]# yum install  expect  -y
      編寫expect腳本
      
       #!/usr/bin/expect
       set ip 10.0.0.51
       set pass 123456
       set timeout 30
       spawn ssh root@$ip
       expect {
               "(yes/no)" {send "yes\r"; exp_continue}
               "password:" {send "$pass\r"}
       }
       expect "root@"  {send "df -h\r"}
       expect "root@"  {send "exit\r"}
       expect eof
      免交互sshpass[擴展]
      安裝sshpass
      
       [root@m01 ~]# yum install sshpass  -y
      使用sshpass命令
      
       [root@m01 ~]# sshpass -p 123456 ssh root@10.0.0.51
       ​
       [option]
       -p:指定密碼
       -f:從文件中取密碼
       -e:從環境變量中取密碼
       -P:設置密碼提示
      使用用戶名密碼驗證方式
      
      ssh遠程連接的方式:
      
      172.16.1.41連接172.16.1.31
      
       1 直接連接
       ssh  10.0.0.31
       2 指定用戶連接
       ssh root@10.0.0.31    linux
       ssh root@10.0.0.31     windows
       3 指定用戶加端口方式
       ssh  -p22   root@10.0.0.31   linux
       ssh root@10.0.0.31   22
      1. 實驗一:

        安裝telnet軟件:進行跳板機實驗(SSH端口本地轉發功能)

        centos6 打開telnet功能:

        yum install telnet-server 安裝telnet
        
        chkconfig telnet on 打開telnet功能
        
        service xinetd start 打開xinetd功能

        centos7:打開telnet功能

        yum instlal telnet-server
        
        systemctl start telnet.socket

        模擬情況:

        C:模擬telnet服務端

        B:模擬ssh服務端

        A:模擬客戶端

        telnet服務端拒絕客戶端的訪問:C拒絕A訪問

        流程解釋:

        數據一旦被telnet打開以后,數據會發送到本機9527端口,再在本機開一個隨機端口,充當ssh客戶端,再把數據流量發送到22端口的ssh服務端,收到數據以后,解密數據,臨時開一個隨機端口充當客戶端,再把流量發送到23端口telnet服務端

      2.  

         

        1)在telnet服務端執行防火牆阻擋功能,阻擋客戶端訪問:C拒絕A

        iptables -A INPUT -s 192.168.34.101 -j REJECT

        2)我們要查看自己和服務端哪些端口未被占用,在A主機找一個未用的端口進行綁定,此時,9527端口未被使用:

      3. 第一種連接方式:

        [root@centos7~]#ssh -L 9527:192.168.34.100:23 -Nf 192.168.34.200 在A執行此命令,打開B主機上未被占用的端口9527,然后A通過此9527端口連接B服務器最后再到telnet端。-f 是后台執行,不加-f就會前台執行。
        
        [root@centos7~]#telnet 127.0.0.1 9527 在A上執行telnet連接操作,並輸入指定的9527端口號
        Trying 127.0.0.1...
        Connected to 127.0.0.1.
        Escape character is '^]'.
        CentOS release 6.10 (Final)
        Kernel 2.6.32-754.el6.x86_64 on an x86_64
        centos6.10.localdomain login: 用戶名
        Password: 密碼
        Last login: Thu Oct 24 20:56:12 from 192.168.34.200 #以顯示連接到C服務器的機器是B,但實際是從A主機將9527端口轉發連接到C服務器
        [liu@centos6~]$
      4.  第二種連接方式:

      5.  ssh -L 9527:192.168.34.100:23 -fNg 192.168.34.200 在A機器上打開B機器的9527端口,在B機器搭上隧道。
        telnet 192.168.34.101 9527 在A機器上通過端口9527,連接C機器
      6. 在C機器上查看當前連接的信息:
      7. [root@centos6~]#ss -nt
        State Recv-Q Send-Q Local Address:Port Peer Address:Port
        ESTAB 0 52 192.168.34.100:22 192.168.34.1:49369
        ESTAB 0 0 192.168.34.100:23 192.168.34.200:53668 (其中100:23位telnet服務器端IP和23端口,200:53668為ssh服務端的IP和隨機端口)
      8. 結論:當客戶端打開9527端口,請求到ssh協議封裝將數據報文發送給ssh服務器端,然后在ssh服務器端上解封裝,開啟隨機端口將數據報文傳給telnet服務器,telnet服務器最終得到數據,實現客戶端連接telnet服務器端。

        注意:雖然能通過跳板機連接到telnet服務器,但是外部機器連接內部機器時,一般防火牆不會打開22端口,客戶端無法到達服務端,最終無法連接telnet端的服務。

         遠程轉發: -R sshserverport:remotehost:remotehostport sshserver

      9. 示例: ssh -R 9527:telnetsrv:23 -Nf sshsrv 讓sshsrv偵聽9527端口的訪問,如有訪問,就加密后通過ssh服務轉發請求到本 機ssh客戶端,再由本機解密后轉發到telnetsrv:23

      10. Data<--> sshsrv:9527 <--> sshsrv:22 <--> localhost:XXXXX <--> localhost:YYYYY<-->telnetsrv:23

        一般防火牆從外部到內部會阻止訪問,但從內部到外部不會阻止訪問:

        遠程轉發實驗:

        三台機器:C:服務器,B:跳板機(ssh服務器),A:客戶端

        C服務器只允許telnet連接(23端口)訪問,不允許外部客戶端直接訪問,B跳板機是一個ssh服務器;有一個用戶需要從外部連接到企業內部的C服務器。

        模擬:C 不允許A訪問:

        當前模擬telnet服務端阻擋服務端訪問:

        在C執行防火牆阻擋A:

        iptables -A INPUT -s 192.168.34.101 -j REJECT
        [root@b~]#ssh -R 9527:192.168.34.100:23 -Nf 192.168.34.101 #在B機器上后台打開A主機的9527端口
        root@192.168.34.101's password: #輸入本機密碼驗證
        [root@b~]#
        [root@centos7~]#telnet 127.0.0.1 9527 #在A機器上用telnet連接本地IP地址和9527端口,可以遠程訪問到內部C服務器
        Trying 127.0.0.1...
        Connected to 127.0.0.1.
        Escape character is '^]'.
        CentOS release 6.10 (Final)
        Kernel 2.6.32-754.el6.x86_64 on an x86_64
        centos6.10.localdomain login: wang
        Password:
        Last login: Sun Oct 27 11:42:33 from 192.168.34.200 #此時已經連接到C主機,並顯示連接C主機是從跳板機B連接的。
        [wang@centos6~]$
      11. 總結:客戶端打開9527端口走ssh協議將數據報文封裝,發送到跳板機,跳板機解封裝報文得到數據,跳板機開啟一個隨機端口,發送數據報文到telnet服務端,實現外部的客戶機通過內部跳板機連接到telnet服務器。

        注意:防火牆只會阻擋從外部到內部的端口連接,不會阻擋從內部到外部的端口,現實生產中比較實用,省去了重新設置防火牆的時間。

      12. 另一種遠程端口轉發情況:外部有一個客戶端(A)連接外部的服務端(B),然后再通過服務端連接內部的跳板機(ssh服務器C),最后到達telnet服務端(D),此處可以將外部客戶端和服務端作為

        一個堡壘機,內部的ssh服務器和telnet服務器可以看做是一個堡壘機,具體連接情況如下:

        1)需要將外部客戶端(A)的ssh配置文件打開:

        vim /etc/ssh/sshd_config
        修改里邊的文件gateway no 改為yes,然后重啟ssh服務,systemctl restart sshd
        2)ssh -R 9527:192.168.34.100:23 -fNg 192.168.34.101 ssh服務器端(C)輸入當前的命令,將A客戶端的9527端口打開,開啟后台隧道。
        3)telnet 192.168.34.101 9527 在外部客戶端(A)輸入自己的本地IP也可以連接到telnet服務端(D)。

        SSH動態端口轉發:(合理上國外網站)

        客戶端---->代理服務器----->國外網站

        模擬:

        A: 本地機器

        B: 代理客戶端

        C: 外國網絡

        當用firefox訪問internet時,本機的9527端口做為代理服務器,firefox的訪問請求被轉發到sshserver上,由sshserver替之訪問internet

      13.  

         

        以下為搭建A訪問C的過程:

        實現Linux主機通過代理進行訪問國外網站:

         iptables -A  INPUT -s 192.168.34.101 -j REJECT   設置C阻擋A模擬。
          echo www.google.com > /var/www/html/index.html  在C建立google網站,訪問此google網站實驗
          service httpd start  啟動C的httpd服務
          ssh -D 9528 192.168.34.200 -fN   在A機器搭建代理客戶端的后台隧道
         curl --socks5 127.0.0.1:9528 192.168.34.100   在A上輸入此命令,訪問外國網站即可  www.google.com

        通過代理可以訪問windows版國外網站搭建:

      14. [root@b.ssh]#iptables -A INPUT -s 192.168.34.1 -j REJECT C主機進行防火牆控制windows窗口連接
        [root@centos7~]#ssh -D 9528 192.168.34.200 -fNg -g選項自己能通過網關訪問windows網站,別人也可以訪問自己
        [root@centos7~]#curl --socks5 127.0.0.1:9528 192.168.34.100 也可以通過輸入命令訪問windows國外網站
        www.google.com
      15. 在windows網頁上高級設置也可以在客戶端上訪問外國網絡:
      16.  

         

         

         

         服務器端:sshd, 配置文件: /etc/ssh/sshd_config 常用參數:

      17. Port 端口號
        ListenAddress ip 監聽IP地址
        LoginGraceTime 2m 等待時間是2分鍾
        PermitRootLogin yes 禁止ROOT用戶模式進行ssh連接
        StrictModes yes 檢查.ssh/文件的所有者,權限等
        MaxAuthTries 6 錯誤的連接最大次數,默認是3次
        MaxSessions 10 同一個連接最大會話
        PubkeyAuthentication yes 支持公鑰驗證
        PermitEmptyPasswords no 禁止空口令登陸
        PasswordAuthentication yes 支持口令驗證
        GSSAPIAuthentication yes 默認是yes,建議改為no影響連接速度。
        UsePAM yes # 使用PAM模塊
        ClientAliveInterval 2 檢查客戶端是否活躍,每兩秒檢查一次,客戶端10s時間不動就會斷開
        ClientAliveCountMax 3 連續檢查3次客戶端活躍情況。
        GatewayPorts no 網關接口默認值是no
        ClientAliveInterval 單位:秒
        ClientAliveCountMax 默認3
        UseDNS yes # 反向解析SSH,需要將此改為no,SSH連接與數據傳輸就會變快。
        GSSAPIAuthentication yes 提高速度可改為no
        MaxStartups 未認證連接最大值,默認值10, 連接並發連接數,當到達20,開始拒絕部分人。
        Banner /path/file 登陸提示文件
      18. 限制可登錄用戶的辦法: AllowUsers user1 user2 user3 白名單用戶 DenyUsers 黑名單用戶 加入名單的用戶名就無法通過ssh連接 AllowGroups DenyGroups

        結論:白名單優先級比黑名單優先級高,如果黑白名單同時有一個IP地址被禁止ssh連接,默認可以連接。

        /etc/ssh/sshd_config配置文件部分內容詳解:

        服務器端修改配置文件中以下兩項進行修改,可以加速ssh的連接

      19. vim /etc/ssh/sshd_conf
        UseDNS no 
        GSSAPIAuthentication no
        • 在/etc/ssh/sshd_config配置中,我們默認的port(端口號)是22,可以通過此配置文件將自己的端口號改掉,以防黑客暴力破解當前的用戶賬號和密碼,修改完之后service sshd restart。

        修改完之后的端口號,我們再連接時需要指定端口號:ssh 192.168.34.100 -p 44(修改后的端口號)

        • 我們可以在指定的配置文件中輸入要監聽的IP地址:listenadress 192.168.34.10 直接綁定自己的IP地址和端口號,默認只能自己通過ssh連接。

      20.  

         還可以在最后一行限制普通用戶登錄情況,例如:allowusers wang 只能wang用戶進行ssh登錄。

      21.  

        ssh服務的最佳實踐

        • 建議使用非默認端口

        • 禁止使用protocol version 1

        • 限制可登錄用戶

        • 設定空閑會話超時時長

        • 利用防火牆設置ssh訪問策略

        • 僅監聽特定的IP地址

        • 基於口令認證時,使用強密碼策略

        • 使用基於密鑰的認證

        • 禁止使用空密碼

        • 禁止root用戶直接登錄

        • 限制ssh的訪問頻度和並發在線數

        • 經常分析日志

        SSH服務配置文件
        /etc/ssh/sshd_config

        Port 22 --- 修改服務端口信息
        ListenAddress 0.0.0.0 --- 監聽地址 指定一塊網卡能夠接受遠程訪問請求 *****
        PS: 指定監聽地址只能是本地網卡上有的地址
        PermitEmptyPasswords no --- 是否允許遠程用戶使用空密碼登錄,默認不允許
        PermitRootLogin yes --- 是否禁止root用戶遠程連接主機 建議改為no
        GSSAPIAuthentication no --- 是否開啟GSSAPI認證功能 不用的時候關閉 
        UseDNS no --- 是否開啟反向DNS解析功能 建議進行關閉

        ssh故障告警

        ssh WARNING:REMOTE HOST IDENTIFICATION HAS CHANGED(警告:遠程主機標識已更改)

        ssh 192.168.1.88 出現以下警告:
        
        @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
        @ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
        @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
        IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
        Someone could be eavesdropping on you right now (man-in-the-middle attack)!
        It is also possible that a host key has just been changed.
        The fingerprint for the ECDSA key sent by the remote host is
        SHA256:Rf81ie6kn6C04O3fJKR3YyJ1ApVmIxwTo8zhZ+sbsjY.
        Please contact your system administrator.
        Add correct host key in /root/.ssh/known_hosts to get rid of this message.
        Offending ECDSA key in /root/.ssh/known_hosts:4
        ECDSA host key for 192.168.1.88 has changed and you have requested strict checking.
        Host key verification failed.
        
        解決方案: 刪除 /root/.ssh/known_hosts 文件中對應IP的那一行即可
        不用交互輸入密碼信息,進行遠程連接分發公鑰:
        第一步驟: 下載安裝軟件
        yum install -y sshpass
        
        第二步驟: 執行免交互方式分發公鑰命令
        sshpass -p123456 ssh-copy-id -i /root/.ssh/id_dsa.pub root@172.16.1.41
        
        如何不要輸入連接yes或no的確認信息
        ssh-copy-id -i /root/.ssh/id_dsa.pub root@172.16.1.41 "-o StrictHostKeyChecking=no"
        
        服務端口號發生變化,如何進行批量分發公鑰
        sshpass -p123456 ssh-copy-id -i /root/.ssh/id_dsa.pub root@172.16.1.41 -p 52113 "-o StrictHostKeyChecking=no"
        

          


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM