shell脚本实现企业级简易跳板机案例

跳板机用途只做ssh中转,为严格控制跳板机数据进出、命令管理等,特对跳板机入口操作进行限制管理。该脚本包含两种界面风格,详见下面说明 。

功能说明:

* 屏蔽用户对跳板机系统进行任何未授权操作操作
* 查询用户已授权主机,具备权限用户方可连接后台服务器
* 授权命令集合(密钥生成、上传、copy,密码更改等),可根据实际需求自定义
* 此脚本依赖于LDAP用户管理,如无LDAP服务,可自行定义用户和主机组对应关系即可

界面一:用户授权登陆主机数量不超过20台

  • 通过选择左侧列表序号登陆右侧主机
  • 选择可执行命令序号,进入执行命令界面,命令作用,后面说明

界面二:用户授权登陆主机数量超过20台

  • 选择IP地址登陆序号,进入输入IP地址界面
  • 选择可执行命令序号,进入执行命令界面,命令作用,后面说明

命令作用说明

  • ssh-keygen : 生成本机ssh公钥
  • ssh-copy-id : 将跳板机公钥复制到远程服务器上
  • upload-local-key : 把本地公钥上传到跳板机上,实现跳板机免密连接
  • passwd : 更改密码
  • exit : 第一层为关闭当前会话,第二层为返回上一页
    备注:除“upload-local-key”为自定义命令外,其它参考命令本身用法

完整代码

#!/bin/bash
# Version:            v1.5
# Function:           用于跳板机入口控制
# Author:             Sly Chen
# Create Date:  Jun.13 2018

# 将脚本放在/etc/profile.d/目录下,并添加可执行权限
#set -x
# 导入系统函数
export LANG=en_US.UTF-8
. /etc/init.d/functions
SHELL_NAME=$(basename $BASH_SOURCE)
SHELL_NAME_PREFIX=$(echo $SHELL_NAME | sed ‘s/.sh$//‘)
SHELL_LOG="/tmp/${SHELL_NAME_PREFIX}.log"

# 以红色显示
red() {
    echo -e "\033[31;40m$*\033[0m"
}

# 以绿色显示
green() {
    echo -e "\033[32;40m$*\033[0m"
}

# Write Log
shell_log () {
    LOG_INFO=$1
    echo "$(date "+%Y-%m-%d") $(date "+%H:%M:%S") ${LOG_INFO}" >> ${SHELL_LOG}
}

login_banner (){
action "${LOGIN_USER} login success" /bin/true
cat << _EOF_
#######################################################################################
#        Welcome Use Jumpserver To Login                                                                                                         #
#        Please contact the system administrator or Send mail to [email protected]                                                 #
#######################################################################################
_EOF_
}

get_hosts_info () {
    LOGIN_USER=`whoami`
    [[ "$LOGIN_USER" == "root" ]] && continue
    # 屏蔽Ctrl+C
    trap ‘:‘ INT
    clear

    # 定义不同用户连接跳板机展现不同旗标
    login_banner

    # 进入ldap api封装目录,用作用户登陆主机查询
    # ldap api依赖于openldap-devel python-devel ; GET命令依赖于perl-libwww-perl
    # yum -y install openldap-devel python-devel perl-libwww-perl
    # Installing python-ldap: https://www.python-ldap.org/en/latest/installing.html#installing-from-source
    cd /data/script/ldap
    # 格式化主机名,并删除任意及禁止登陆主机权限
    array_objects=($(python ldapadmin.py user hostinfo ${LOGIN_USER} | sed "s/\[\|,\|\]\|‘//g; /*\|\!/d"))
    # 定义命令数组
    array_commands=(
    "ssh-keygen         --> authentication key generation, management and conversion"
    "ssh-copy-id        --> use locally available keys to authorise logins on a remote machine"
    "upload-local-key   --> upload the public key to the jumpserver"
    "passwd             --> update user‘s authentication tokens"
    "exit               --> return"
     )
    CMD_LIST_NAME="$(green "Execute Command") On Jumpserver."
    CLOSE_BASH="$(green "Exit Shell")"
    if [ -z "${#array_objects[@]}" ]; then
        red "No action object was found!"
        continue
    # 如果可登陆主机数超过20条,则通过自行指定IP地址登陆
    elif [ ${#array_objects[@]} -gt 20 ]; then
            IP_CUSTOM_NAME="Type $(green ‘IP ADDRESS‘) To Login."
            array_objects=("${IP_CUSTOM_NAME}" "${CMD_LIST_NAME}")
    else
        num_host=${#array_objects[@]}
        array_objects[((num_host+1))]="${CMD_LIST_NAME}"
    fi
}

network_pint_test () {
    ping -c2 $LAN_IP &> /dev/null
    [ $? -ne 0 ] && echo "$(red "$LAN_IP"): Network is unreachable" && continue
    ssh ${LAN_IP}
}

invalid_ldap_host_del () {
    # 本函数用作LDAP无效主机条目删除
    # 如果获取内网IP为空,先判断运维平台API网络状态
    ping -c 2 ${BRIDGE_URL} &> /dev/null
    [ $? -ne 0 ] && echo "$(red "$BRIDGE_URL"): Network is unreachable" && continue
    # 删除LDAP无效主机记录
    LDAP_HOST_DEL=$(python ldapadmin.py user hostdel ${LOGIN_USER} ${OBJECT} | egrep -io ‘sucessfully‘ | tr ‘A-Z‘ ‘a-z‘)
    # 记录删除主机日志
    if [ "${LDAP_HOST_DEL}" == "sucessfully" ]; then
        shell_log "${LOGIN_USER} LDAP delete $(green "$OBJECT") sucessfully"
    else
        shell_log "${LOGIN_USER} LDAP delete $(red "$OBJECT") failure "
    fi
}

main () {
    get_hosts_info

    # 获取IP数组生成菜单列表
    PS3=$(green "\nAccept Only List Numbers: ")
    # 必须加while死循环,不然无法屏蔽ctrl+d等操作
    BRIDGE_URL=‘bridge.test.com‘
    while true; do
        select VAR in "${array_objects[@]}" "${CLOSE_BASH}"; do
            [ -z "$VAR" ] && red "Invalid number" && continue
            if [[ "$VAR" == ${IP_CUSTOM_NAME} ]]; then
                 read -p "Type $(green ‘IP ADDRESS‘) To Login: " LAN_IP
                 network_pint_test
            elif [[ "$VAR" == "${CLOSE_BASH}" ]]; then
                exit
            elif [ "$VAR" != "${CMD_LIST_NAME}" ]; then
                # 判断操作对象,IP加执行SSH前缀执行,命令直接执行
                OBJECT=$(echo "${array_objects[@]}" | egrep -wo "${VAR}" | awk ‘{print $1}‘)
                # 操作对象包含数字,选择序号对应命令就等于 ssh + ip
                if [[ "$OBJECT" =~ .test.com ]]; then
                    [ x"$(which GET &> /dev/null; echo $?)" != x"0" ] &&
                    {
                        # GET依赖于perl-libwww-perl包
                        echo "-bash: $(red "GET"): command not found"
                        exit
                    }
                    LAN_IP=$(GET http://${BRIDGE_URL}/api/vm?hostname=${OBJECT} | grep -oP ‘"lan_ip[" :]+\K[^"]+‘)
                    # IP为空表示主机不存在,LDAP主机条目无效
                    if [ -z "$LAN_IP" ]; then
                        LAN_IP=$(GET http://${BRIDGE_URL}/api/phyhost?hostname=${OBJECT} | grep -oP ‘"lan_ip[" :]+\K[^"]+‘)
                        if [ -z "$LAN_IP" ]; then
                            # LDAP无效主机条目权限删除
                            invalid_ldap_host_del
                            echo "$(red "$OBJECT") not found"
                            continue
                        elif [ $(echo $LAN_IP | xargs -n 1 | wc -l) -gt 1 ]; then
                            echo "$(red "${OBJECT}") Contains multiple IP: $(echo ${LAN_IP} | xargs -n 10)"
                            continue
                        else
                            network_pint_test
                        fi
                    # 存在多个内网IP则退出执行
                    elif [ $(echo $LAN_IP | xargs -n 1 | wc -l) -gt 1 ]; then
                        echo "$(red "${OBJECT}") Contains multiple IP: $(echo ${LAN_IP} | xargs -n 10)"
                        continue
                    fi
                    network_pint_test
                else
                    echo "$(red "$VAR") Hostname does not meet the standard"
                    continue
                 fi
            # 判断变量为命令集合,则进入命令操作界面
            elif [[ "$VAR" == "${CMD_LIST_NAME}" ]]; then
                select COMMADN_SRC in "${array_commands[@]}"; do
                    [ -z "${COMMADN_SRC}" ] && red "Invalid command" && continue
                    COMMAND=$(echo "${COMMADN_SRC}" | awk ‘{print $1}‘)
                    if [ "$COMMAND" == "ssh-keygen" -o "$COMMAND" == "passwd" ]; then
                        # 执行命令
                        ${COMMAND}
                    elif [[ "$COMMAND" == "ssh-copy-id" ]]; then
                         read -p "Please specify the IP: "  IP
                        # 判断指定IP合法、网络通信
                        # 执行ssh-copy-id $IP
                        ssh-copy-id $IP
                    elif [[ "$COMMAND" == "exit" ]]; then
                        break
                    elif [[ "$COMMAND" == "upload-local-key" ]]; then
                        read -p "$(green "Please enter the public key content:") " KEY
                        if [ -z "$KEY" ]; then
                            echo "The KEY is empty."
                        elif [ -f "/home/${LOGIN_USER}/.ssh/authorized_keys" ]; then
                            [ -n "$(grep "$KEY" /home/${LOGIN_USER}/.ssh/authorized_keys)" ] &&
                            {
                                echo "The KEY already exists."
                                continue
                            }
                         fi
                         echo "$KEY" >> /home/${LOGIN_USER}/.ssh/authorized_keys
                         echo -e "\nUpload to complete."
                    fi
                done
            fi
        done
    done
}

main

原文地址:http://blog.51cto.com/wuyanc/2139429

时间: 2024-07-31 20:03:52

shell脚本实现企业级简易跳板机案例的相关文章

Linux下Dialog+Shell三层目录专业规范跳板机脚本

#Dialog+Shell介绍 Dialog+Shell结合使用,方能体现出Dialog图形化的效果,在运维的时候,使用图形化界面,能给你一个更直观的感受,相信你会喜欢上他的 #创建脚本目录  [[email protected] ~]# mkdir -p /scripts/tiaoban/{qqandroid,qqios,qqwxandroid,wxios,menu_list} #禁止普通用户登陆 [[email protected] ~]# cat /etc/profile.d/tiaoba

Linux下trap+shell三层目录专业规范跳板机脚本

跳板机安全防范规划: 跳板机-> 中心机 -> 后端服务器 跳板机:用来做跳板登陆中心机用的 中心机:一般用来做分发用的,用来登陆后端服务器 在内网:一般直接连中心机,然后直接连接后端服务器 在外网:为了安全,一般会先通过普通用户连接跳板机,然后再连接中心机,然后再在中心机连接后端服务器 注意:普通用户是不让登陆到跳板机终端的 三层目录跳板脚本实现功能: 1.通过普通用户连接跳板再直接连接后端服务器 2.ssh+key认证,CRT代理转发功能开启,自别识别用户,无需用户再输入用户名.密码和端口

shell脚本的函数介绍和使用案例

#前言:今天我们来聊聊shell脚本中的函数知识,看一下函数的优势,执行过程和相关的使用案例,我们也来看一下shell和python的函数书写方式有什么不同 #简介 1.函数也具有别名类似的功能 2.函数是把程序里多次调用相同的代码部分定义成一份,然后给这份代码定义个名字,如果出现重复的就调用就行了 #函数的优势 1.把相同的程序段定义成函数,可以减少整个程序的代码量 2.可以让程序代码结构更清晰 3.增加程序的可读.易读性.以及管理性 4.可以实现程序功能模块化,不同的程序使用函数模块化 #语

多级菜单系统安装维护shell脚本实现企业级案例

演示效果: 1.一级菜单 2.二级菜单 3.执行操作 脚本参考: #!/bin/bash #author lic(oldboy linux student) #date 1304 DISK_NO="/dev/sda1" NGINX_DIR="/usr/local/tdoa/nginx/sbin/nginx" MYSQL_DIR="/usr/local/tdoa/mysql/bin/mysqld_safe" SERVER1="WEB&qu

利用Shell开发跳板机功能脚本案例

范例17_6::开发企业级Shell跳板机案例.要求用户登录到跳板机仅能执行管理员给定的选项动作,不允许以任何形式中断脚本到跳板机服务器上执行任何系统命令. 方法1: 1)首先做好SSH密钥验证(跳板机地址192.168.33.128). 以下操作命令在所有机器上操作: [[email protected] ~]# useradd jump  #<==要在所有机器上操作. [[email protected] ~]# echo 123456|passwd --stdin jump  #<==要

Shell学习之路和我发布过的Shell脚本博文

Shell学习之路 目录 Shell学习之路[第一篇]:别名,管道,用户配置文件,变量,read Shell学习之路[第二篇]:条件测试,运算符,选择结构,for循环结构 Shell学习之路[第三篇]:While循环,C-for循环,Until循环,case分支结构,流程控制语句 Shell学习之路[第四篇]:函数,数组,变量替换 Shell学习之路[第五篇]:多线程脚本 Shell学习之路[第六篇]:Trap信号捕捉命令介绍与Shell结合实战讲解 Shell学习之路[第七篇]:Linux下d

Linux的shell脚本trap信号处理

一.trap 1.trap是一个shell内建命令,它用来在脚本中指定信号如何处理.比如,按Ctrl+C会使脚本终止执行,实际上系统发送了SIGINT信号给脚本进 程,SIGINT信号的默认处理方式就是退出程序.如果要在Ctrl+C不退出程序,那么就得使用trap命令来指定一下SIGINT的处理方式了. trap命令不仅仅处理Linux信号,还能对脚本退出(EXIT).调试(DEBUG).错误(ERR).返回(RETURN)等情况指定处理方式. 系统中的信号: 2.trap的设置和取消 3.tr

更新本地代码到服务器的shell脚本

更新本地代码到服务器的shell脚本 用Ubuntu做开发机OS遇到的第一个问题就是将更新的代码放上测试服务器运行 www.ahlinux.com 之前用windows的时候是用Winscp更新代码到服务器上去的 ubuntu下面没有类似Winscp的程序,只能自己写个简单的脚本做这种事情了 Shell代码    www.ahlinux.com #要更新的的文件数组 相对根目录的路径 file_array=("xxx/xxxxx.py" \ "xxx/xxxxx.py&quo

Shell实现跳板机,为什么用跳板机

整理自:http://blog.chinaunix.net/uid-22101889-id-3167454.html 注意:请谨慎使用,到现在为止,使用了,我还没找到改回去的方法. 1.     问题 第一.很多大公司的服务器都不允许直接登录,而是通过一个跳板机才能登录过去.在跳板机中,通常只能执行几个少数命令(如SSH),而其他命令是不允许执行的,那么怎样才能实现这个功能呢? 第二.一些小公司,由于服务器比较少,不需要什么跳板机之类的说法,公司的开发运维人员加起来也就那么十几二十人,通常大家都