通常会有通过外网访问内网服务器的需求,比如在寝室搬砖,新冠隔离在家搬砖等。frp是一个十分方便的内网穿透工具,它可以实现对外网环境提供ssh,http或https服务。

暂时只用到ssh连接,所以本文只有介绍如何用frp工具实现内网穿透ssh连接。

用到的东西

  1. 具有外网访问权的云服务器
  2. 内网服务器
  3. frp工具: https://github.com/fatedier/frp

内网穿透实现ssh连接

  1. 下载frp工具,注意云服务器与内网服务器的frp版本要相同。

  2. 配置内网服务器

    内网服务器需要配置的是frpc.ini文件:

    cat frpc.ini
    > [common]
    > server_addr = <云服务器的公网ip>
    > server_port = <云服务器的监听端口>
    > 
    > [ssh01] # 多个连接需要使用不同名字和端口
    > type = <配置类型,ssh为tcp> # tcp
    > local_ip = <内网服务器的ip,可以填127.0.0.1> # 127.0.0.1
    > local_port = <内网服务器需要监听的端口,ssh为22> # 22
    > remote_port = <需要映射到公网服务器上的端口,之后的ssh连接需要这个端口> # 6001

    运行frpc

    nohup ./frpc -c ./frpc.ini &>elog.txt &

    需要注意的是,内网服务器需要开放配置文件里的端口。

  3. 配置云服务器

    云服务器需要配置的是frps.ini文件:

    cat frps.ini
    > [common]
    > bind_port = <监听端口,对应frpc.ini中的server_port>

    运行frps

    nohup ./frps -c frps.ini &>elog.txt &

    需要注意的是,云服务器需要开放配置文件里的端口(例如阿里云服务器需要手动开启端口)。

  4. 通过云服务器公网ip和内网服务器的remote_port端口来连接内网服务器:

    ssh -p remote_port username@server_addr
  5. 为了方便,可以在~/.zshrc中进行alias配置:

    # frp
    alias sshtoserver='frp <server_addr> <client_addr> <remote_port> <username>'
    function frp(){
        if [ $# -ne 4 ]; then
            echo "Usage: frp SERVER_IP CLIENT_IP PORT USR"
            # plog ERROR red "Usage: frp SERVER_IP CLIENT_IP PORT USR"
            return 1
        fi
        server_ip=$1
        client_ip=$2
        port=$3
        usr=$4
        # 检查是否可以在内网直接连接
        gtimeout 1 nc -z -n ${client_ip} 22 &>/dev/null
        if [ $? -ne 0 ]; then
            echo "SSH by FRP"
            # plog INFO green "SSH by FRP"
            ssh -p ${port} ${usr}@${server_ip}
        else
            ssh ${usr}@${client_ip}
        fi
    }

参考

[1] 一稚杨.Frp实现内网穿透[EB/OL].https://zhuanlan.zhihu.com/p/45445979,2018-09-27.