不开ssh端口,怎么ssh?

今天思勇问我怎么配线上防火墙,就是只开80/443,那ssh要不要开?
一般方案都是走堡垒机,其实问题的关键不是ssh能不能开,而是按需打开,不能一直在那里listen,引火烧身。

之前我一直用linode日本的服务器,22端口时不时被墙,只能通过web访问服务器,于是使用了mosh的方案。

通常mosh需要先建立一个ssh连接,然后远程执行mosh-server命令创建一个udp-server,监听60000-61000端口

./mosh-server
#MOSH CONNECT  
MOSH CONNECT 60000 E97yTo4vcW6Wk+oiXa2TaQ

在客户端使用远程获得的port和key就可以建立一个udp的mosh连接

#MOSH_KEY= mosh-client  
MOSH_KEY=E97yTo4vcW6Wk+oiXa2TaQ mosh-client 172.104.33.236 60000

由于ssh端口被封了,不能直接通过ssh建立mosh-server,获取连接port和key
那就直接通过http来获得port/key了:
1、登陆终端启动一个mosh-daemon,监听任务队列 brpop MOSH:conn
2、浏览器访问 mosh-connect.php, 新增连接任务 lpush MOSH:conn $session_id, 并等待执行结果 BRPOP MOSH:conn:$session
3、mosh-daemon 执行命令 popen(‘/usr/bin/mosh-server 2>&1’, ‘r’) 获得连接信息并返回给客户端 lpush MOSH:conn:$session $port,$key

mosh-daemon.sh

#!/usr/bin/env php
<?php
while(1) {
    try {
        $redis = new Redis();
        $redis->connect('127.0.0.1');

        $res = $redis->blPop('MOSH:conn', 60);
        if ( !empty($res) ) {
            list(, $session_id) = $res;
            $mosh = popen('/usr/bin/mosh-server 2>&1', 'r');
            $result = fread($mosh, 1024);
            if ( preg_match('/MOSH CONNECT (\d+) (\S+)/', $result, $matches) ) {
                list(, $port, $key) = $matches;
                $redis->lPush("MOSH:conn:$session_id", "$port,$key");
            }
        }
    } catch (Exception $e) {}
}

mosh-connect.php

<?php
$redis = new Redis();
$redis->connect('127.0.0.1');

$session_id = uniqid();
$redis->lPush('MOSH:conn', $session_id);

list(, $result) = $redis->blPop('MOSH:conn:'.$session_id, 60);
list($port, $key) = explode(',', $result);

$ip = $_SERVER["SERVER_ADDR"];
echo "<pre>";
echo "$ip\n$port\n$key\n";
echo "MOSH_KEY=$key mosh-client $ip $port";

发表评论