web terminal工具gateone使用

稍微牛B的运维团队,没有运维平台是不行的,web terminal是运维平台的重要组成部分,这里吐血推荐gateone,github上5K颗星,遗憾的是作者不更新了,但瑕不掩瑜,它依然是我心目中web terminal no.1。

web上直接点击终端按钮,打开一个ssh终端,体验还是很nice的:

1.安装

1.1.环境

# cat /etc/redhat-release 
CentOS Linux release 7.4.1708 (Core) 
# python -V
Python 2.7.5

1.2.安装

# yum -y install epel-release
# yum -y install python-setuptools python-pip
# python -m pip install --upgrade pip
# pip install --upgrade setuptools

1.3.拉取master最新版本

# python setup.py install
# pip uninstall tornado
# pip install tornado==4.5.3

1.4.配置
/etc/gateone/conf.d/10server.conf

"disable_ssl": true,
"embedded": true,
"js_init": "{showToolbar: false, showTitle: false}",
"origins": ["*"],
"port": 80,
"session_timeout": 0,

此时,执行gateone即可启动。

2.免密登录

步骤1完成后,只能以http://gateone-serverip访问,需要进一步输入ip\port\username\password,以登录你想登录的服务器。

要想免密登录,需要完成以下配置,并以以下方式访问。

2.1.将gateone-server与你的目标服务器配置ssh免密登录(满大街都是方法,这里略)

2.2.在/var/lib/gateone/users/ANONYMOUS/.ssh目录下拷贝ssh秘钥,并生成.default_ids文件

#cd /var/lib/gateone/users/ANONYMOUS/.ssh
# cp /root/.ssh/id* .
# echo "id_rsa" > .default_ids

web免密登录访问方式:

http://gateone-serverip/?location=mylocation& ssh=ssh://root@target-ip

3.页面优化

3.1.不能从页面最上方输入,如下

程序中行列计算有问题,最后以固定的行列生效了,可以修改代码弥补:

gateone.js 
3911     newWorkspace: function() {
3944         sidebarWidth = go.toolbar.clientWidth || go.sideinfo.clientHeight; // clientHeight is ……
3945         v.updateDimensions();           // 增加一行
3946         // Prepare the workspace div for the grid
3947         if (go.prefs.showTitle || go.prefs.showToolbar) {

gateone_utils_extra.js 
157     getEmDimensions: function(elem, /*opt*/where) {
                // 增加开始
242             if (nodeWidth < 7.2) {
243                 nodeWidth = 7.2;
244             }
245             if (nodeHeight < 14.05) {
246                 nodeHeight = 14.05;
247             }
248             u.prevEmDimensions = {'w': nodeWidth, 'h': nodeHeight};
                // 增加结束

3.2.ssh后提示太多,精简之

精简前如3.1上图,精简后只有2行:

ssh://root@target-ip
Last login: Mon Jul ?1 19:37:47 2019 from gateone-serverip

ssh_connect.py
以下有#的都注释,同时增加2行
336     if identities:
337         #print(_(
338         #    "The following SSH identities are being used for this "
339         #    "connection:"))

345             #print(_("\t\x1b[1m%s\x1b[0m" % os.path.split(identity)[1]))

384         if not os.path.exists(socket_path):
385             args.insert(0, "-M")
386         else:
387             # print("\x1b]0;%s@%s (child)\007" % (user, host))
388             # print(_(
389             #     "\x1b]_;notice|Existing ssh session detected for ssh://%s@%s:%s;"
390             #     " utilizing existing tunnel.\007" % (user, host, port)
391             # ))
392             pass    // 新增一行
393         socket = socket.replace(r'%SHORT_SOCKET%', hashed)

805         while not validated:
806             if not url:
807                 #url = raw_input(_(
808                 #   "[Press Shift-F1 for help]\n\nHost/IP or ssh:// URL%s: " %
809                 #   default_host_str))
810                 url = raw_input(_(""))                  // 新增一行

881         if protocol == 'ssh':
882             #print(_('Connecting to ssh://%s@%s:%s' % (user, host, port)))
883             # Set title
884             # print("\x1b]0;ssh://%s@%s\007" % (user, host))
885             # Special escape handler (so the rest of the plugin knows the
886             # connect string)
887             connect_string = "{0}@{1}:{2}".format(user, host, port)
888             #print(
889             #    "\x1b]_;ssh|set;connect_string;{0}\007".format(connect_string))

890             openssh_connect(user, host, port,

3.3.关闭错误提示音(BELL)

每次一个错误输入,都会有声音,同时还会弹出以下字幕,有点烦人

关闭BELL
terminal.js

35 go.prefs.audibleBell = go.prefs.audibleBell || true; // If false, the bell sound will not be played (visual notification will still occur),
改为go.prefs.audibleBell = false

2377     bellAction: function(bellObj) {
2378         /**:GateOne.Terminal.bellAction(bellObj)
2379 
2380         Attached to the 'terminal:bell' WebSocket action; plays a bell sound and pops up a message indiciating which terminal issued a bell.
2381         */
2382         /*
2383         var term = bellObj.term;
2384         go.Terminal.playBell();
2385         v.displayMessage(gettext("Bell in: ") + term + ": " + go.Terminal.terminals[term].title);
2386         */
2387         pass
2388     },

389         // Load the bell sound from the cache.  If that fails ask the server to send us the file.
390         /* if (go.prefs.bellSound.length) {
391             logDebug("Existing bell sound found");
392             go.Terminal.loadBell({'mimetype': go.prefs.bellSoundType, 'data_uri': go.prefs.bellSound});
393         } else {
394             logDebug("Attempting to download our bell sound...");
395             go.ws.send(JSON.stringify({'terminal:get_bell': null}));
396         } */

4.与django项目集成

4.1.修改配置

20authentication.conf 
"auth": "api",

4.2.创建秘钥

# gateone --new_api_key

生成以下文件

# pwd
/etc/gateone/conf.d
# cat 30api_keys.conf 
// This file contains the key and secret pairs used by Gate One's API authentication method.
{
    "*": {
        "gateone": {
            "api_keys": {
                "YmNmZGFlMzExYzRmNDBlOGFlNDA4YjEzOGFkYzVkAAAAA": "NjBiOTRlNDM4NzRmNDQ2Y2FmNThjOGNmNDBlNDc0BBBBB"
            }
        }
    }
}

4.3.前端页面button
 

<button type="button" onclick="get_terminal(\'' + hostip + '\')">终端</button>
<script>
    function get_terminal(host_ip) {
        window.open('/assets/get_terminal?host_ip=' + host_ip)
    }
</script>

4.4.views方法

def get_terminal(request):
    host_ip = request.GET['host_ip']
    api_key = "YmNmZGFlMzExYzRmNDBlOGFlNDA4YjEzOGFkYzVkAAAAA"
    api_secret = "NjBiOTRlNDM4NzRmNDQ2Y2FmNThjOGNmNDBlNDc0BBBBB"
    gateone_owner = "meishidong"

    timestamp = str(int(time.time() * 1000))
    signature = create_signature(api_secret, api_key, gateone_owner, timestamp)

    gateone_url = "http://gateone-serverip/"
    ssh_url = "ssh://root@" + host_ip

    return render(request, "assets/terminal.html", {
        "api_key": api_key,
        "timestamp": timestamp,
        "signature": signature,
        "gateone_url": gateone_url,
        "ssh_url": ssh_url,
        "upn": gateone_owner,
        "title": host_ip.split('.')[2] + '.' + host_ip.split('.')[3],
        "location": host_ip.replace('.','-') + "_" + str(int(time.time()))
    })

4.5.与django项目集成,模板页面terminal.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{{ title }}</title>
</head>
<body>
    <script src="http://gateone-serverip/static/gateone.js"></script>
    <div id="gateone_container" style="width: 60em; height: 30em;">
        <div id="gateone"></div>
    </div>
    <script type="text/javascript">
        window.onload = function() {
            // Initialize Gate One:
            var apiauth = {
                'api_key':'{{api_key}}',
                'timestamp':'{{timestamp}}',
                'api_version':'1.0',
                'upn':'{{upn}}',
                'signature':'{{signature}}',
                'signature_method':'HMAC-SHA1',
            };
            GateOne.location = "{{ location }}";
            GateOne.init({
                auth: apiauth,
                url: '{{ gateone_url }}',
                autoConnectURL:'{{ssh_url}}',
                goDiv:'#gateone',
                showToolbar:false,
                showTitle: false,
                embedded: false,
                fillContainer: true,
                showAppChooser: false
            });
        }
    </script>
</body>
</html>

4.6.与django项目集成,upn用户key处理
gateone服务器目录/var/lib/gateone/users下会自动生成meishidong目录

# cd /var/lib/gateone/users/meishidong/.ssh
# scp id* ../../meishidong/.ssh/
# scp .default_ids ../../meishidong/.ssh/

4.7.页面调整

4.7.1集成到应用后,默认显示“Gate One - Applicaiton”页面,点击进入目标服务器;

要跳过“Gate One - Applicaiton”页面:

ssh.js
105         // Connect to the given ssh:// URL if we were given an 'ssh' query string variable (e.g. ……
106         /* if (sshQueryString) {
107             if (u.isArray(sshQueryString)) {
108                 // Assume it's all one-time only if multiple ssh:// URLs were provided
109                 sshOnce = 'true';
110                 sshQueryString.forEach(function(str) {
111                     handleQueryString(str);
112                 }); 
113             } else {
114                 handleQueryString(sshQueryString);
115             }   
116         } */
117                  //  新增以下三行
118         if (go.prefs.autoConnectURL) {
119             handleQueryString(go.prefs.autoConnectURL);
120         } 

4.7.2取消刚连接时弹出的“1:Gate One”

terminal.js
 874         var //displayText = termObj.id.split('term')[1] + ": " + go.Terminal.terminals[term].title,
 875             //termInfoDiv = u.createElement('div', {'id': 'terminfo', 'class': '?terminfo'}),
 876             marginFix = Math.round(go.Terminal.terminals[term].title.length/2),
 877             infoContainer = u.createElement('div', {'id': 'infocontainer', 'class': '?term_infocontainer ?halfsectrans'});
 878         //termInfoDiv.innerHTML = displayText;

over

发布了24 篇原创文章 · 获赞 25 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/sdmei/article/details/94405050