Abner的博客

ssh常用脚本

· 664 words · 4 minutes to read
Categories: 工具

ssh登陆脚本 🔗

1.main.sh 🔗

#!/bin/bash
# 获取脚本绝对路径
SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
  DIR="$(cd -P "$(dirname "$SOURCE")" && pwd)"
  SOURCE="$(readlink "$SOURCE")"
  [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if relative, re resolve it
done
direc="$(cd -P "$(dirname "$SOURCE")" && pwd)"

# 颜色输出函数
function color(){
    blue="\033[0;36m"
    red="\033[0;31m"
    green="\033[0;32m"
    close="\033[m"
    case $1 in
        blue)
            echo -e "$blue $2 $close"
        ;;
        red)
            echo -e "$red $2 $close"
        ;;
        green)
            echo -e "$green $2 $close"
        ;;
        *)
            echo "Input color error!!"
        ;;
    esac
}

# 版权信息
function copyright(){
    echo "#####################"
    color blue "   SSH Login Platform   "
    echo "#####################"
    echo
}

# 下划线分隔符
function underline(){
    echo "-----------------------------------------"
}

# 获取服务器配置
function get_server_config() {
    local id="$1"
    awk -v server_id="server$id" -F '=' '
    BEGIN {
        current_section = ""
        ip = port = username = login_type = credential = label = ""
    }
    /^\[/ {
        current_section = substr($0, 2, length($0)-2)
        if(current_section == server_id) in_section=1
        else in_section=0
    }
    in_section && NF>0 {
        gsub(/^[ \t]+|[ \t]+$/, "", $1)
        gsub(/^[ \t]+|[ \t]+$/, "", $2)
        
        if ($1 == "ip") ip = $2
        if ($1 == "port") port = $2
        if ($1 == "username") username = $2
        if ($1 == "login_type") login_type = $2
        if ($1 == "credential") credential = $2
        if ($1 == "label") label = $2
    }
    END {
        if (ip != "") {
            printf "%s:%s:%s:%s:%s:%s", ip, port, username, login_type, credential, label
        }
    }
    ' "$direc/config.ini"
}

# 列出所有服务器
function list_servers() {
    awk -F '=' '
    BEGIN {
        print "序号 |       主机      | 登录方式 | 说明"
    }
    /^\[server/ {
        match($0, /server[0-9]+/)
        server_id = substr($0, RSTART+6, RLENGTH-6)
        ip = login_type = label = ""
    }
    !/^\[/ && $1 ~ /[[:space:]]*ip/ {
        gsub(/^[ \t]+|[ \t]+$/, "", $2)
        ip = $2
    }
    !/^\[/ && $1 ~ /[[:space:]]*login_type/ {
        gsub(/^[ \t]+|[ \t]+$/, "", $2)
        login_type = $2
    }
    !/^\[/ && $1 ~ /[[:space:]]*label/ {
        gsub(/^[ \t]+|[ \t]+$/, "", $2)
        label = $2
    }
    ip != "" && login_type != "" && label != "" {
        printf "\033[0;31m% 3s \033[m | %15s | %8s | %s\n", server_id, ip, login_type, label
        server_id = ip = login_type = label = ""
    }
    ' "$direc/config.ini"
}

# 主函数
function main(){
    while true; do
        clear
        copyright
        
        echo "序号 |       主机      | 登录方式 | 说明"
        underline
        list_servers
        underline
        
        read -p '[*] 选择主机: ' number
        
        if [[ "$number" == "q" || "$number" == "quit" ]]; then
            exit
        fi
        
        config=$(get_server_config "$number")
        
        if [ -z "$config" ]; then
            color red "[!] 无效的主机序号: $number"
            sleep 1
            continue
        fi
        
        IFS=':' read -r ipaddr port username login_type credential label <<< "$config"
        
        # 显示调试信息
        color blue "[*] 解析配置:"
        echo "路径前缀: $direc"
        echo "IP地址: $ipaddr"
        echo "端口: $port"
        echo "用户名: $username"
        echo "登录类型: $login_type"
        echo "证书文件: $credential"
        
        if [[ "$login_type" == "pem" ]]; then
            pem_path="$direc/keys/$credential"
            color green "[*] 使用证书: $credential"
            echo "证书路径: $pem_path"
            
            if [ ! -f "$pem_path" ]; then
                color red "[!] 证书文件不存在: $pem_path"
                sleep 2
                continue
            elif [ ! -r "$pem_path" ]; then
                color red "[!] 无权限读取证书文件"
                sleep 2
                continue
            fi
            
            ssh -i "$pem_path" "$username@$ipaddr" -p "$port"
            
        elif [[ "$login_type" == "pwd" ]]; then
            exp_path="$direc/login.exp"
            
            if [ ! -f "$exp_path" ]; then
                color red "[!] expect脚本不存在: $exp_path"
                sleep 2
                continue
            elif [ ! -x "$exp_path" ]; then
                color red "[!] expect脚本不可执行"
                sleep 2
                continue
            fi
            
            expect -f "$exp_path" "$ipaddr" "$username" "$credential" "$port"
        else
            color red "[!] 未知的登录类型: $login_type"
            sleep 2
        fi
    done
}

main

2.login.exp 🔗

#!/usr/bin/expect -f
proc abort {msg} {
    puts stderr $msg
    exit 1
}

if {$argc != 4} {
    abort "Usage: $argv0 host user password port"
}

set TARGET [lindex $argv 0]
set USER [lindex $argv 1]
set PASSWD [lindex $argv 2]
set PORT [lindex $argv 3]
set timeout 10

spawn ssh -o StrictHostKeyChecking=no -p $PORT $USER@$TARGET
match_max 100000

expect {
    "*yes/no" {
        send "yes\r"
        exp_continue
    }
    "*assword:" {
        send "$PASSWD\r"
        exp_continue
    }
    eof {
        puts "Connection closed."
    }
    timeout {
        abort "Connection timeout"
    }
}

interact

3.config.ini 🔗

[server1] 
ip=127.0.0.1
port=22
username=root
login_type=pwd
credential=123456
label=本地test

[server2] 
ip=127.0.0.1
port=22
username=root
login_type=pwd
credential=123456
label=本地test

4.在main.sh目录下新建keys文件夹,将证书文件放在keys文件夹下,证书权限为600 🔗

chmod 600 a.pem