内网穿透实战

作者:Administrator 发布时间: 2024-04-23 阅读量:17 评论数:0

一、场景

公司有两台内网服务器,192.168.0.139,192.168.0.50,假如不在公司并且需要访问公司内网,就会出现无法访问的问题。

二、方案

openvpn+frp

192.168.0.139: 

openvpn server 端口为6667

frp client 本地端口为6667 远程端口设置为7777

103.96.148.28:

frp server 绑定端口和kcp端口设置为6666 dashboard设置为8999 admin Ab.12345

token设置为k3yMVev1GAtuBN27 服务端与客户端需要一致才能连接

三、开始部署

1.部署frp

这里选择一键安装脚本进行安装:

Frps-Onekey-Install-Shell For CentOS/Debian/Ubuntu/Fedora (32bit/64bit)

Install(安装)

Aliyun

wget https://code.aliyun.com/MvsCode/frps-onekey/raw/master/install-frps.sh -O ./install-frps.sh
chmod 700 ./install-frps.sh
./install-frps.sh install

frps.init

#! /bin/bash
# chkconfig: 2345 55 25
# Description: Startup script for frps on Debian. Place in /etc/init.d and
# run 'update-rc.d -f frps defaults', or use the appropriate command on your
# distro. For CentOS/Redhat run: 'chkconfig --add frps'
#=========================================================
#   System Required:  CentOS/Debian/Ubuntu/Fedora (32bit/64bit)
#   Description:  Manager for frps, Written by Clang
#   Mender:MvsCode
#=========================================================
### BEGIN INIT INFO
# Provides:          frps
# Required-Start:    $all
# Required-Stop:     $all
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: starts the frps
# Description:       starts frps using start-stop
### END INIT INFO

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
ProgramName="Frps"
ProgramPath="/usr/local/frps"
NAME=frps
BIN=${ProgramPath}/${NAME}
CONFIGFILE=${ProgramPath}/frps.ini
SCRIPTNAME=/etc/init.d/${NAME}
version="03.20"
program_version=`${BIN} --version`
RET_VAL=0

[ -x ${BIN} ] || exit 0
strLog=""
fun_clangcn()
{
    echo ""
    echo "+---------------------------------------------------------+"
    echo "|     Manager for ${ProgramName}, Author Clang, Mender MvsCode      |"
    echo "+---------------------------------------------------------+"
    echo ""
}

fun_check_run(){
    PID=`ps -ef | grep -v grep | grep -i "${BIN}" | awk '{print $2}'`
    if [ ! -z $PID  ]; then
        return 0
    else
        return 1
    fi
}
fun_load_config(){
    if [ ! -r ${CONFIGFILE} ]; then
        echo "config file ${CONFIGFILE} not found"
        return 1
    fi
}
fun_start()
{
    if [ "${arg1}" = "start" ]; then
      fun_clangcn
    fi
    if fun_check_run; then
        echo "${ProgramName} (pid $PID) already running."
        return 0
    fi
    fun_load_config
    echo -n "Starting ${ProgramName}(${program_version})..."
    ${BIN} -c ${CONFIGFILE} >/dev/null 2>&1 &
    sleep 1
    if ! fun_check_run; then
        echo "start failed"
        return 1
    fi
    echo " done"
    echo "${ProgramName} (pid $PID)is running."
    return 0
}

fun_stop(){
    if [ "${arg1}" = "stop" ] || [ "${arg1}" = "restart" ]; then
      fun_clangcn
    fi
    if fun_check_run; then
        echo -n "Stoping ${ProgramName} (pid $PID)... "
        kill $PID
        if [ "$?" != 0 ] ; then
            echo " failed"
            return 1
        else
            echo " done"
        fi
    else
        echo "${ProgramName} is not running."
    fi
    return 0
}
fun_restart(){
    fun_stop
    fun_start
}
fun_status(){
    PID=`ps -ef | grep -v grep | grep -i "${BIN}" | awk '{print $2}'`
    if [ ! -z $PID ]; then
        echo "${ProgramName} (pid $PID) is running..."
    else
        echo "${ProgramName} is stopped"
        exit 0
    fi
}
checkos(){
    if   grep -Eqi "CentOS" /etc/issue || grep -Eq "CentOS" /etc/*-release; then
        OS=CentOS
    elif grep -Eqi "Debian" /etc/issue || grep -Eq "Debian" /etc/*-release; then
        OS=Debian
    elif grep -Eqi "Ubuntu" /etc/issue || grep -Eq "Ubuntu" /etc/*-release; then
        OS=Ubuntu
    elif grep -Eqi "Alpine" /etc/issue || grep -Eq "Alpine" /etc/*-release; then
        OS=Alpine
    elif grep -Eqi "Fedora" /etc/issue || grep -Eq "Fedora" /etc/*-release; then
        OS=Fedora
    else
        echo "Not support OS, Please reinstall OS and retry!"
        return 1
    fi
}
fun_config(){
    if [ -s ${CONFIGFILE} ]; then
        vi ${CONFIGFILE}
    else
        echo "${ProgramName} configuration file not found!"
        return 1
    fi
}
fun_version(){
    echo "${ProgramName} version ${program_version}"
    return 0
}
fun_help(){
    ${BIN} --help
    return 0
}

arg1=$1
[  -z ${arg1} ]
case "${arg1}" in
    start|stop|restart|status|config)
        fun_${arg1}
    ;;
    [vV][eE][rR][sS][iI][oO][nN]|-[vV][eE][rR][sS][iI][oO][nN]|--[vV][eE][rR][sS][iI][oO][nN]|-[vV]|--[vV])
        fun_version
    ;;
    [Cc]|[Cc][Oo][Nn][Ff]|[Cc][Oo][Nn][Ff][Ii][Gg]|-[Cc]|-[Cc][Oo][Nn][Ff]|-[Cc][Oo][Nn][Ff][Ii][Gg]|--[Cc]|--[Cc][Oo][Nn][Ff]|--[Cc][Oo][Nn][Ff][Ii][Gg])
        fun_config
    ;;
    [Hh]|[Hh][Ee][Ll][Pp]|-[Hh]|-[Hh][Ee][Ll][Pp]|--[Hh]|--[Hh][Ee][Ll][Pp])
        fun_help
    ;;
    *)
        fun_clangcn
        echo "Usage: $SCRIPTNAME {start|stop|restart|status|config|version}"
        RET_VAL=1
    ;;
esac
exit $RET_VAL

install-frps.sh

#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
###export###
export PATH
export FRPS_VER=0.37.1
export FRPS_INIT="https://raw.githubusercontent.com/MvsCode/frps-onekey/master/frps.init"
export aliyun_download_url="https://code.aliyun.com/MvsCode/frps-onekey/raw/master"
export github_download_url="https://github.com/fatedier/frp/releases/download"
#======================================================================
#   System Required:  CentOS Debian Ubuntu or Fedora(32bit/64bit)
#   Description:  A tool to auto-compile & install frps on Linux
#   Author : Clang
#   Mender : MvsCode
#======================================================================
program_name="frps"
version="210804"
str_program_dir="/usr/local/${program_name}"
program_init="/etc/init.d/${program_name}"
program_config_file="frps.ini"
ver_file="/tmp/.frp_ver.sh"
str_install_shell="https://raw.githubusercontent.com/MvsCode/frps-onekey/master/install-frps.sh"
shell_update(){
    fun_clangcn "clear"
    echo "Check updates for shell..."
    remote_shell_version=`wget  -qO- ${str_install_shell} | sed -n '/'^version'/p' | cut -d\" -f2`
    if [ ! -z ${remote_shell_version} ]; then
        if [[ "1.10.0" != "${remote_shell_version}" ]];then
            echo -e "${COLOR_GREEN}Found a new version,update now!!!${COLOR_END}"
            echo
            echo -n "Update shell ..."
            if ! wget -N  -qO $0 ${str_install_shell}; then
                echo -e " [${COLOR_RED}failed${COLOR_END}]"
                echo
                exit 1
            else
                chmod +x install-frps.sh
                echo -e " [${COLOR_GREEN}OK${COLOR_END}]"
                echo
                echo -e "${COLOR_GREEN}Please Re-run${COLOR_END} ${COLOR_PINK}$0 ${clang_action}${COLOR_END}"
                echo
            fi
            exit 1
        fi
    fi
}
fun_clangcn(){
    local clear_flag=""
    clear_flag=$1
    if [[ ${clear_flag} == "clear" ]]; then
        clear
    fi
    echo ""
    echo "+------------------------------------------------------------+"
    echo "|   frps for Linux Server, Author Clang ,Mender MvsCode     |" 
    echo "|      A tool to auto-compile & install frps on Linux        |"
    echo "+------------------------------------------------------------+"
    echo ""
}
fun_set_text_color(){
    COLOR_RED='\E[1;31m'
    COLOR_GREEN='\E[1;32m'
    COLOR_YELOW='\E[1;33m'
    COLOR_BLUE='\E[1;34m'
    COLOR_PINK='\E[1;35m'
    COLOR_PINKBACK_WHITEFONT='\033[45;37m'
    COLOR_GREEN_LIGHTNING='\033[32m \033[05m'
    COLOR_END='\E[0m'
}
# Check if user is root
rootness(){
    if [[ $EUID -ne 0 ]]; then
        fun_clangcn
        echo "Error:This script must be run as root!" 1>&2
        exit 1
    fi
}
get_char(){
    SAVEDSTTY=`stty -g`
    stty -echo
    stty cbreak
    dd if=/dev/tty bs=1 count=1 2> /dev/null
    stty -raw
    stty echo
    stty $SAVEDSTTY
}
# Check OS
checkos(){
    if   grep -Eqi "CentOS" /etc/issue || grep -Eq "CentOS" /etc/*-release; then
        OS=CentOS
    elif grep -Eqi "Debian" /etc/issue || grep -Eq "Debian" /etc/*-release; then
        OS=Debian
    elif grep -Eqi "Ubuntu" /etc/issue || grep -Eq "Ubuntu" /etc/*-release; then
        OS=Ubuntu
    elif grep -Eqi "Fedora" /etc/issue || grep -Eq "Fedora" /etc/*-release; then
        OS=Fedora
    else
        echo "Not support OS, Please reinstall OS and retry!"
        exit 1
    fi
}
# Get version
getversion(){
    if [[ -s /etc/redhat-release ]];then
        grep -oE  "[0-9.]+" /etc/redhat-release
    else
        grep -oE  "[0-9.]+" /etc/issue
    fi
}
# CentOS version
centosversion(){
    local code=$1
    local version="`getversion`"
    local main_ver=${version%%.*}
    if [ $main_ver == $code ];then
        return 0
    else
        return 1
    fi
}
# Check OS bit
check_os_bit(){
    ARCHS=""
    if [[ `getconf WORD_BIT` = '32' && `getconf LONG_BIT` = '64' ]] ; then
        Is_64bit='y'
        ARCHS="amd64"
    else
        Is_64bit='n'
        ARCHS="386"
    fi
}
check_centosversion(){
if centosversion 5; then
    echo "Not support CentOS 5.x, please change to CentOS 6,7 or Debian or Ubuntu or Fedora and try again."
    exit 1
fi
}
# Disable selinux
disable_selinux(){
    if [ -s /etc/selinux/config ] && grep 'SELINUX=enforcing' /etc/selinux/config; then
        sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
        setenforce 0
    fi
}
pre_install_packs(){
    local wget_flag=''
    local killall_flag=''
    local netstat_flag=''
    wget --version > /dev/null 2>&1
    wget_flag=$?
    killall -V >/dev/null 2>&1
    killall_flag=$?
    netstat --version >/dev/null 2>&1
    netstat_flag=$?
    if [[ ${wget_flag} -gt 1 ]] || [[ ${killall_flag} -gt 1 ]] || [[ ${netstat_flag} -gt 6 ]];then
        echo -e "${COLOR_GREEN} Install support packs...${COLOR_END}"
        if [ "${OS}" == 'CentOS' ]; then
            yum install -y wget psmisc net-tools
        else
            apt-get -y update && apt-get -y install wget psmisc net-tools
        fi
    fi
}
# Random password
fun_randstr(){
    strNum=$1
    [ -z "${strNum}" ] && strNum="16"
    strRandomPass=""
    strRandomPass=`tr -cd '[:alnum:]' < /dev/urandom | fold -w ${strNum} | head -n1`
    echo ${strRandomPass}
}
fun_getServer(){
    def_server_url="aliyun"
    echo ""
    echo -e "Please select ${program_name} download url:"
    echo -e "[1].aliyun (default)"
    echo -e "[2].github "
    read -e -p "Enter your choice (1, 2 or exit. default [${def_server_url}]): " set_server_url
    [ -z "${set_server_url}" ] && set_server_url="${def_server_url}"
    case "${set_server_url}" in
        1|[Aa][Ll][Ii][Yy][Uu][Nn])
            program_download_url=${aliyun_download_url}
            ;;
        2|[Gg][Ii][Tt][Hh][Uu][Bb])
            program_download_url=${github_download_url}
            ;;
        [eE][xX][iI][tT])
            exit 1
            ;;
        *)
            program_download_url=${aliyun_download_url}
            ;;
    esac
    echo    "-----------------------------------"
    echo -e "       Your select: ${COLOR_YELOW}${set_server_url}${COLOR_END}    "
    echo    "-----------------------------------"
}
fun_getVer(){
    echo -e "Loading network version for ${program_name}, please wait..."
    program_latest_filename="frp_${FRPS_VER}_linux_${ARCHS}.tar.gz"
    program_latest_file_url="${program_download_url}/v${FRPS_VER}/${program_latest_filename}"
    if [ -z "${program_latest_filename}" ]; then
        echo -e "${COLOR_RED}Load network version failed!!!${COLOR_END}"
    else
        echo -e "${program_name} Latest release file ${COLOR_GREEN}${program_latest_filename}${COLOR_END}"
    fi
}
fun_download_file(){
    # download
    if [ ! -s ${str_program_dir}/${program_name} ]; then
        rm -fr ${program_latest_filename} frp_${FRPS_VER}_linux_${ARCHS}
        if ! wget  -q ${program_latest_file_url} -O ${program_latest_filename}; then
            echo -e " ${COLOR_RED}failed${COLOR_END}"
            exit 1
        fi
        tar xzf ${program_latest_filename}
        mv frp_${FRPS_VER}_linux_${ARCHS}/frps ${str_program_dir}/${program_name}
        rm -fr ${program_latest_filename} frp_${FRPS_VER}_linux_${ARCHS}
    fi
    chown root:root -R ${str_program_dir}
    if [ -s ${str_program_dir}/${program_name} ]; then
        [ ! -x ${str_program_dir}/${program_name} ] && chmod 755 ${str_program_dir}/${program_name}
    else
        echo -e " ${COLOR_RED}failed${COLOR_END}"
        exit 1
    fi
}
function __readINI() {
 INIFILE=$1; SECTION=$2; ITEM=$3
 _readIni=`awk -F '=' '/\['$SECTION'\]/{a=1}a==1&&$1~/'$ITEM'/{print $2;exit}' $INIFILE`
echo ${_readIni}
}
# Check port
fun_check_port(){
    port_flag=""
    strCheckPort=""
    input_port=""
    port_flag="$1"
    strCheckPort="$2"
    if [ ${strCheckPort} -ge 1 ] && [ ${strCheckPort} -le 65535 ]; then
        checkServerPort=`netstat -ntulp | grep "\b:${strCheckPort}\b"`
        if [ -n "${checkServerPort}" ]; then
            echo ""
            echo -e "${COLOR_RED}Error:${COLOR_END} Port ${COLOR_GREEN}${strCheckPort}${COLOR_END} is ${COLOR_PINK}used${COLOR_END},view relevant port:"
            netstat -ntulp | grep "\b:${strCheckPort}\b"
            fun_input_${port_flag}_port
        else
            input_port="${strCheckPort}"
        fi
    else
        echo "Input error! Please input correct numbers."
        fun_input_${port_flag}_port
    fi
}
fun_check_number(){
    num_flag=""
    strMaxNum=""
    strCheckNum=""
    input_number=""
    num_flag="$1"
    strMaxNum="$2"
    strCheckNum="$3"
    if [ ${strCheckNum} -ge 1 ] && [ ${strCheckNum} -le ${strMaxNum} ]; then
        input_number="${strCheckNum}"
    else
        echo "Input error! Please input correct numbers."
        fun_input_${num_flag}
    fi
}
# input configuration data
fun_input_bind_port(){
    def_server_port="5443"
    echo ""
    echo -n -e "Please input ${program_name} ${COLOR_GREEN}bind_port${COLOR_END} [1-65535]"
    read -e -p "(Default Server Port: ${def_server_port}):" serverport
    [ -z "${serverport}" ] && serverport="${def_server_port}"
    fun_check_port "bind" "${serverport}"
}
fun_input_dashboard_port(){
    def_dashboard_port="6443"
    echo ""
    echo -n -e "Please input ${program_name} ${COLOR_GREEN}dashboard_port${COLOR_END} [1-65535]"
    read -e -p "(Default : ${def_dashboard_port}):" input_dashboard_port
    [ -z "${input_dashboard_port}" ] && input_dashboard_port="${def_dashboard_port}"
    fun_check_port "dashboard" "${input_dashboard_port}"
}
fun_input_vhost_http_port(){
    def_vhost_http_port="80"
    echo ""
    echo -n -e "Please input ${program_name} ${COLOR_GREEN}vhost_http_port${COLOR_END} [1-65535]"
    read -e -p "(Default : ${def_vhost_http_port}):" input_vhost_http_port
    [ -z "${input_vhost_http_port}" ] && input_vhost_http_port="${def_vhost_http_port}"
    fun_check_port "vhost_http" "${input_vhost_http_port}"
}
fun_input_vhost_https_port(){
    def_vhost_https_port="443"
    echo ""
    echo -n -e "Please input ${program_name} ${COLOR_GREEN}vhost_https_port${COLOR_END} [1-65535]"
    read -e -p "(Default : ${def_vhost_https_port}):" input_vhost_https_port
    [ -z "${input_vhost_https_port}" ] && input_vhost_https_port="${def_vhost_https_port}"
    fun_check_port "vhost_https" "${input_vhost_https_port}"
}
fun_input_log_max_days(){
    def_max_days="30" 
    def_log_max_days="3"
    echo ""
    echo -e "Please input ${program_name} ${COLOR_GREEN}log_max_days${COLOR_END} [1-${def_max_days}]"
    read -e -p "(Default : ${def_log_max_days} day):" input_log_max_days
    [ -z "${input_log_max_days}" ] && input_log_max_days="${def_log_max_days}"
    fun_check_number "log_max_days" "${def_max_days}" "${input_log_max_days}"
}
fun_input_max_pool_count(){
    def_max_pool="200"
    def_max_pool_count="50"
    echo ""
    echo -e "Please input ${program_name} ${COLOR_GREEN}max_pool_count${COLOR_END} [1-${def_max_pool}]"
    read -e -p "(Default : ${def_max_pool_count}):" input_max_pool_count
    [ -z "${input_max_pool_count}" ] && input_max_pool_count="${def_max_pool_count}"
    fun_check_number "max_pool_count" "${def_max_pool}" "${input_max_pool_count}"
}
fun_input_dashboard_user(){
    def_dashboard_user="admin"
    echo ""
    echo -n -e "Please input ${program_name} ${COLOR_GREEN}dashboard_user${COLOR_END}"
    read -e -p "(Default : ${def_dashboard_user}):" input_dashboard_user
    [ -z "${input_dashboard_user}" ] && input_dashboard_user="${def_dashboard_user}"
}
fun_input_dashboard_pwd(){
    def_dashboard_pwd=`fun_randstr 8`
    echo ""
    echo -n -e "Please input ${program_name} ${COLOR_GREEN}dashboard_pwd${COLOR_END}"
    read -e -p "(Default : ${def_dashboard_pwd}):" input_dashboard_pwd
    [ -z "${input_dashboard_pwd}" ] && input_dashboard_pwd="${def_dashboard_pwd}"
}
fun_input_token(){
    def_token=`fun_randstr 16`
    echo ""
    echo -n -e "Please input ${program_name} ${COLOR_GREEN}token${COLOR_END}"
    read -e -p "(Default : ${def_token}):" input_token
    [ -z "${input_token}" ] && input_token="${def_token}"
}
fun_input_subdomain_host(){
    def_subdomain_host=${defIP}
    echo ""
    echo -n -e "Please input ${program_name} ${COLOR_GREEN}subdomain_host${COLOR_END}"
    read -e -p "(Default : ${def_subdomain_host}):" input_subdomain_host
    [ -z "${input_subdomain_host}" ] && input_subdomain_host="${def_subdomain_host}"
}

pre_install_clang(){
    fun_clangcn
    echo -e "Check your server setting, please wait..."
    disable_selinux
    if [ -s ${str_program_dir}/${program_name} ] && [ -s ${program_init} ]; then
        echo "${program_name} is installed!"
    else
        clear
        fun_clangcn
        fun_getServer
        fun_getVer
        echo -e "Loading You Server IP, please wait..."
        defIP=$(wget -qO- ip.clang.cn | sed -r 's/\r//')
        echo -e "You Server IP:${COLOR_GREEN}${defIP}${COLOR_END}"
        echo -e "————————————————————————————————————————————"
        echo -e "     ${COLOR_RED}Please input your server setting:${COLOR_END}"
        echo -e "————————————————————————————————————————————"
        fun_input_bind_port
        [ -n "${input_port}" ] && set_bind_port="${input_port}"
        echo -e "${program_name} bind_port: ${COLOR_YELOW}${set_bind_port}${COLOR_END}"
        echo -e ""
        fun_input_vhost_http_port
        [ -n "${input_port}" ] && set_vhost_http_port="${input_port}"
        echo -e "${program_name} vhost_http_port: ${COLOR_YELOW}${set_vhost_http_port}${COLOR_END}"
        echo -e ""
        fun_input_vhost_https_port
        [ -n "${input_port}" ] && set_vhost_https_port="${input_port}"
        echo -e "${program_name} vhost_https_port: ${COLOR_YELOW}${set_vhost_https_port}${COLOR_END}"
        echo -e ""
        fun_input_dashboard_port
        [ -n "${input_port}" ] && set_dashboard_port="${input_port}"
        echo -e "${program_name} dashboard_port: ${COLOR_YELOW}${set_dashboard_port}${COLOR_END}"
        echo -e ""
        fun_input_dashboard_user
        [ -n "${input_dashboard_user}" ] && set_dashboard_user="${input_dashboard_user}"
        echo -e "${program_name} dashboard_user: ${COLOR_YELOW}${set_dashboard_user}${COLOR_END}"
        echo -e ""
        fun_input_dashboard_pwd
        [ -n "${input_dashboard_pwd}" ] && set_dashboard_pwd="${input_dashboard_pwd}"
        echo -e "${program_name} dashboard_pwd: ${COLOR_YELOW}${set_dashboard_pwd}${COLOR_END}"
        echo -e ""
        fun_input_token
        [ -n "${input_token}" ] && set_token="${input_token}"
        echo -e "${program_name} token: ${COLOR_YELOW}${set_token}${COLOR_END}"
        echo -e ""
        fun_input_subdomain_host
        [ -n "${input_subdomain_host}" ] && set_subdomain_host="${input_subdomain_host}"
        echo -e "${program_name} subdomain_host: ${COLOR_YELOW}${set_subdomain_host}${COLOR_END}"
        echo -e ""
        fun_input_max_pool_count
        [ -n "${input_number}" ] && set_max_pool_count="${input_number}"
        echo -e "${program_name} max_pool_count: ${COLOR_YELOW}${set_max_pool_count}${COLOR_END}"
        echo -e ""
        echo -e "Please select ${COLOR_GREEN}log_level${COLOR_END}"
        echo    "1: info (default)"
        echo    "2: warn"
        echo    "3: error"
        echo    "4: debug"    
        echo    "-------------------------"
        read -e -p "Enter your choice (1, 2, 3, 4 or exit. default [1]): " str_log_level
        case "${str_log_level}" in
            1|[Ii][Nn][Ff][Oo])
                str_log_level="info"
                ;;
            2|[Ww][Aa][Rr][Nn])
                str_log_level="warn"
                ;;
            3|[Ee][Rr][Rr][Oo][Rr])
                str_log_level="error"
                ;;
            4|[Dd][Ee][Bb][Uu][Gg])
                str_log_level="debug"
                ;;
            [eE][xX][iI][tT])
                exit 1
                ;;
            *)
                str_log_level="info"
                ;;
        esac
        echo -e "log_level: ${COLOR_YELOW}${str_log_level}${COLOR_END}"
        echo -e ""
        fun_input_log_max_days
        [ -n "${input_number}" ] && set_log_max_days="${input_number}"
        echo -e "${program_name} log_max_days: ${COLOR_YELOW}${set_log_max_days}${COLOR_END}"
        echo -e ""
        echo -e "Please select ${COLOR_GREEN}log_file${COLOR_END}"
        echo    "1: enable (default)"
        echo    "2: disable"
        echo "-------------------------"
        read -e -p "Enter your choice (1, 2 or exit. default [1]): " str_log_file
        case "${str_log_file}" in
            1|[yY]|[yY][eE][sS]|[oO][nN]|[tT][rR][uU][eE]|[eE][nN][aA][bB][lL][eE])
                str_log_file="./frps.log"
                str_log_file_flag="enable"
                ;;
            0|2|[nN]|[nN][oO]|[oO][fF][fF]|[fF][aA][lL][sS][eE]|[dD][iI][sS][aA][bB][lL][eE])
                str_log_file="/dev/null"
                str_log_file_flag="disable"
                ;;
            [eE][xX][iI][tT])
                exit 1
                ;;
            *)
                str_log_file="./frps.log"
                str_log_file_flag="enable"
                ;;
        esac
        echo -e "log_file: ${COLOR_YELOW}${str_log_file_flag}${COLOR_END}"
        echo -e ""
        echo -e "Please select ${COLOR_GREEN}tcp_mux${COLOR_END}"
        echo    "1: enable (default)"
        echo    "2: disable"
        echo "-------------------------"         
        read -e -p "Enter your choice (1, 2 or exit. default [1]): " str_tcp_mux
        case "${str_tcp_mux}" in
            1|[yY]|[yY][eE][sS]|[oO][nN]|[tT][rR][uU][eE]|[eE][nN][aA][bB][lL][eE])
                set_tcp_mux="true"
                ;;
            0|2|[nN]|[nN][oO]|[oO][fF][fF]|[fF][aA][lL][sS][eE]|[dD][iI][sS][aA][bB][lL][eE])
                set_tcp_mux="false"
                ;;
            [eE][xX][iI][tT])
                exit 1
                ;;
            *)
                set_tcp_mux="true"
                ;;
        esac
        echo -e "tcp_mux: ${COLOR_YELOW}${set_tcp_mux}${COLOR_END}"
        echo -e ""
        echo -e "Please select ${COLOR_GREEN}kcp support${COLOR_END}"
        echo    "1: enable (default)"
        echo    "2: disable"
        echo "-------------------------"  
        read -e -p "Enter your choice (1, 2 or exit. default [1]): " str_kcp
        case "${str_kcp}" in
            1|[yY]|[yY][eE][sS]|[oO][nN]|[tT][rR][uU][eE]|[eE][nN][aA][bB][lL][eE])
                set_kcp="true"
                ;;
            0|2|[nN]|[nN][oO]|[oO][fF][fF]|[fF][aA][lL][sS][eE]|[dD][iI][sS][aA][bB][lL][eE])
                set_kcp="false"
                ;;
            [eE][xX][iI][tT])
                exit 1
                ;;
            *)
                set_kcp="true"
                ;;
        esac
        echo -e "kcp support: ${COLOR_YELOW}${set_kcp}${COLOR_END}"
        echo -e ""

        echo "============== Check your input =============="
        echo -e "You Server IP      : ${COLOR_GREEN}${defIP}${COLOR_END}"
        echo -e "Bind port          : ${COLOR_GREEN}${set_bind_port}${COLOR_END}"
        echo -e "kcp support        : ${COLOR_GREEN}${set_kcp}${COLOR_END}"
        echo -e "vhost http port    : ${COLOR_GREEN}${set_vhost_http_port}${COLOR_END}"
        echo -e "vhost https port   : ${COLOR_GREEN}${set_vhost_https_port}${COLOR_END}"
        echo -e "Dashboard port     : ${COLOR_GREEN}${set_dashboard_port}${COLOR_END}"
        echo -e "Dashboard user     : ${COLOR_GREEN}${set_dashboard_user}${COLOR_END}"
        echo -e "Dashboard password : ${COLOR_GREEN}${set_dashboard_pwd}${COLOR_END}"
        echo -e "token              : ${COLOR_GREEN}${set_token}${COLOR_END}"
        echo -e "subdomain_host     : ${COLOR_GREEN}${set_subdomain_host}${COLOR_END}"
        echo -e "tcp_mux            : ${COLOR_GREEN}${set_tcp_mux}${COLOR_END}"
        echo -e "Max Pool count     : ${COLOR_GREEN}${set_max_pool_count}${COLOR_END}"
        echo -e "Log level          : ${COLOR_GREEN}${str_log_level}${COLOR_END}"
        echo -e "Log max days       : ${COLOR_GREEN}${set_log_max_days}${COLOR_END}"
        echo -e "Log file           : ${COLOR_GREEN}${str_log_file_flag}${COLOR_END}"
        echo "=============================================="
        echo ""
        echo "Press any key to start...or Press Ctrl+c to cancel"

        char=`get_char`
        install_program_server_clang
    fi
}
# ====== install server ======
install_program_server_clang(){
    [ ! -d ${str_program_dir} ] && mkdir -p ${str_program_dir}
    cd ${str_program_dir}
    echo "${program_name} install path:$PWD"

    echo -n "config file for ${program_name} ..."
# Config file
if [[ "${set_kcp}" == "false" ]]; then
cat > ${str_program_dir}/${program_config_file}<<-EOF
# [common] is integral section
[common]
# A literal address or host name for IPv6 must be enclosed
# in square brackets, as in "[::1]:80", "[ipv6-host]:http" or "[ipv6-host%zone]:80"
bind_addr = 0.0.0.0
bind_port = ${set_bind_port}
# udp port used for kcp protocol, it can be same with 'bind_port'
# if not set, kcp is disabled in frps
#kcp_bind_port = ${set_bind_port}
# if you want to configure or reload frps by dashboard, dashboard_port must be set
dashboard_port = ${set_dashboard_port}
# dashboard assets directory(only for debug mode)
dashboard_user = ${set_dashboard_user}
dashboard_pwd = ${set_dashboard_pwd}
# assets_dir = ./static
vhost_http_port = ${set_vhost_http_port}
vhost_https_port = ${set_vhost_https_port}
# console or real logFile path like ./frps.log
log_file = ${str_log_file}
# debug, info, warn, error
log_level = ${str_log_level}
log_max_days = ${set_log_max_days}
# auth token
token = ${set_token}
# It is convenient to use subdomain configure for http、https type when many people use one frps server together.
subdomain_host = ${set_subdomain_host}
# only allow frpc to bind ports you list, if you set nothing, there won't be any limit
#allow_ports = 1-65535
# pool_count in each proxy will change to max_pool_count if they exceed the maximum value
max_pool_count = ${set_max_pool_count}
# if tcp stream multiplexing is used, default is true
tcp_mux = ${set_tcp_mux}
EOF
else
cat > ${str_program_dir}/${program_config_file}<<-EOF
# [common] is integral section
[common]
# A literal address or host name for IPv6 must be enclosed
# in square brackets, as in "[::1]:80", "[ipv6-host]:http" or "[ipv6-host%zone]:80"
bind_addr = 0.0.0.0
bind_port = ${set_bind_port}
# udp port used for kcp protocol, it can be same with 'bind_port'
# if not set, kcp is disabled in frps
kcp_bind_port = ${set_bind_port}
# if you want to configure or reload frps by dashboard, dashboard_port must be set
dashboard_port = ${set_dashboard_port}
# dashboard assets directory(only for debug mode)
dashboard_user = ${set_dashboard_user}
dashboard_pwd = ${set_dashboard_pwd}
# assets_dir = ./static
vhost_http_port = ${set_vhost_http_port}
vhost_https_port = ${set_vhost_https_port}
# console or real logFile path like ./frps.log
log_file = ${str_log_file}
# debug, info, warn, error
log_level = ${str_log_level}
log_max_days = ${set_log_max_days}
# auth token
token = ${set_token}
# It is convenient to use subdomain configure for http、https type when many people use one frps server together.
subdomain_host = ${set_subdomain_host}
# only allow frpc to bind ports you list, if you set nothing, there won't be any limit
#allow_ports = 1-65535
# pool_count in each proxy will change to max_pool_count if they exceed the maximum value
max_pool_count = ${set_max_pool_count}
# if tcp stream multiplexing is used, default is true
tcp_mux = ${set_tcp_mux}
EOF
fi
    echo " done"

    echo -n "download ${program_name} ..."
    rm -f ${str_program_dir}/${program_name} ${program_init}
    fun_download_file
    echo " done"
    echo -n "download ${program_init}..."
    if [ ! -s ${program_init} ]; then
        if ! wget  -q ${FRPS_INIT} -O ${program_init}; then
            echo -e " ${COLOR_RED}failed${COLOR_END}"
            exit 1
        fi
    fi
    [ ! -x ${program_init} ] && chmod +x ${program_init}
    echo " done"

    echo -n "setting ${program_name} boot..."
    [ ! -x ${program_init} ] && chmod +x ${program_init}
    if [ "${OS}" == 'CentOS' ]; then
        chmod +x ${program_init}
        chkconfig --add ${program_name}
    else
        chmod +x ${program_init}
        update-rc.d -f ${program_name} defaults
    fi
    echo " done"
    [ -s ${program_init} ] && ln -s ${program_init} /usr/bin/${program_name}
    ${program_init} start
    fun_clangcn
    #install successfully
    echo ""
    echo "Congratulations, ${program_name} install completed!"
    echo "================================================"
    echo -e "You Server IP      : ${COLOR_GREEN}${defIP}${COLOR_END}"
    echo -e "Bind port          : ${COLOR_GREEN}${set_bind_port}${COLOR_END}"
    echo -e "KCP support        : ${COLOR_GREEN}${set_kcp}${COLOR_END}"
    echo -e "vhost http port    : ${COLOR_GREEN}${set_vhost_http_port}${COLOR_END}"
    echo -e "vhost https port   : ${COLOR_GREEN}${set_vhost_https_port}${COLOR_END}"
    echo -e "Dashboard port     : ${COLOR_GREEN}${set_dashboard_port}${COLOR_END}"
    echo -e "token              : ${COLOR_GREEN}${set_token}${COLOR_END}"
    echo -e "subdomain_host     : ${COLOR_GREEN}${set_subdomain_host}${COLOR_END}"
    echo -e "tcp_mux            : ${COLOR_GREEN}${set_tcp_mux}${COLOR_END}"
    echo -e "Max Pool count     : ${COLOR_GREEN}${set_max_pool_count}${COLOR_END}"
    echo -e "Log level          : ${COLOR_GREEN}${str_log_level}${COLOR_END}"
    echo -e "Log max days       : ${COLOR_GREEN}${set_log_max_days}${COLOR_END}"
    echo -e "Log file           : ${COLOR_GREEN}${str_log_file_flag}${COLOR_END}"
    echo "================================================"
    echo -e "${program_name} Dashboard     : ${COLOR_GREEN}http://${set_subdomain_host}:${set_dashboard_port}/${COLOR_END}"
    echo -e "Dashboard user     : ${COLOR_GREEN}${set_dashboard_user}${COLOR_END}"
    echo -e "Dashboard password : ${COLOR_GREEN}${set_dashboard_pwd}${COLOR_END}"
    echo "================================================"
    echo ""
    echo -e "${program_name} status manage : ${COLOR_PINKBACK_WHITEFONT}${program_name}${COLOR_END} {${COLOR_GREEN}start|stop|restart|status|config|version${COLOR_END}}"
    echo -e "Example:"
    echo -e "  start: ${COLOR_PINK}${program_name}${COLOR_END} ${COLOR_GREEN}start${COLOR_END}"
    echo -e "   stop: ${COLOR_PINK}${program_name}${COLOR_END} ${COLOR_GREEN}stop${COLOR_END}"
    echo -e "restart: ${COLOR_PINK}${program_name}${COLOR_END} ${COLOR_GREEN}restart${COLOR_END}"
    exit 0
}
############################### configure ##################################
configure_program_server_clang(){
    if [ -s ${str_program_dir}/${program_config_file} ]; then
        vi ${str_program_dir}/${program_config_file}
    else
        echo "${program_name} configuration file not found!"
        exit 1
    fi
}
############################### uninstall ##################################
uninstall_program_server_clang(){
    fun_clangcn
    if [ -s ${program_init} ] || [ -s ${str_program_dir}/${program_name} ] ; then
        echo "============== Uninstall ${program_name} =============="
        str_uninstall="n"
        echo -n -e "${COLOR_YELOW}You want to uninstall?${COLOR_END}"
        read -e -p "[Y/N]:" str_uninstall
        case "${str_uninstall}" in
        [yY]|[yY][eE][sS])
        echo ""
        echo "You select [Yes], press any key to continue."
        str_uninstall="y"
        char=`get_char`
        ;;
        *)
        echo ""
        str_uninstall="n"
        esac
        if [ "${str_uninstall}" == 'n' ]; then
            echo "You select [No],shell exit!"
        else
            checkos
            ${program_init} stop
            if [ "${OS}" == 'CentOS' ]; then
                chkconfig --del ${program_name}
            else
                update-rc.d -f ${program_name} remove
            fi
            rm -f ${program_init} /var/run/${program_name}.pid /usr/bin/${program_name}
            rm -fr ${str_program_dir}
            echo "${program_name} uninstall success!"
        fi
    else
        echo "${program_name} Not install!"
    fi
    exit 0
}
############################### update ##################################
update_config_clang(){
    if [ ! -r "${str_program_dir}/${program_config_file}" ]; then
        echo "config file ${str_program_dir}/${program_config_file} not found."
    else
        search_dashboard_user=`grep "dashboard_user" ${str_program_dir}/${program_config_file}`
        search_dashboard_pwd=`grep "dashboard_pwd" ${str_program_dir}/${program_config_file}`
        search_kcp_bind_port=`grep "kcp_bind_port" ${str_program_dir}/${program_config_file}`
        search_tcp_mux=`grep "tcp_mux" ${str_program_dir}/${program_config_file}`
        search_token=`grep "privilege_token" ${str_program_dir}/${program_config_file}`
        search_allow_ports=`grep "privilege_allow_ports" ${str_program_dir}/${program_config_file}`
        if [ -z "${search_dashboard_user}" ] || [ -z "${search_dashboard_pwd}" ] || [ -z "${search_kcp_bind_port}" ] || [ -z "${search_tcp_mux}" ] || [ ! -z "${search_token}" ] || [ ! -z "${search_allow_ports}" ];then
            echo -e "${COLOR_GREEN}Configuration files need to be updated, now setting:${COLOR_END}"
            echo ""
            if [ ! -z "${search_token}" ];then
                sed -i "s/privilege_token/token/" ${str_program_dir}/${program_config_file}
            fi
            if [ -z "${search_dashboard_user}" ] && [ -z "${search_dashboard_pwd}" ];then
                def_dashboard_user_update="admin"
                read -e -p "Please input dashboard_user (Default: ${def_dashboard_user_update}):" set_dashboard_user_update
                [ -z "${set_dashboard_user_update}" ] && set_dashboard_user_update="${def_dashboard_user_update}"
                echo "${program_name} dashboard_user: ${set_dashboard_user_update}"
                echo ""
                def_dashboard_pwd_update=`fun_randstr 8`
                read -e -p "Please input dashboard_pwd (Default: ${def_dashboard_pwd_update}):" set_dashboard_pwd_update
                [ -z "${set_dashboard_pwd_update}" ] && set_dashboard_pwd_update="${def_dashboard_pwd_update}"
                echo "${program_name} dashboard_pwd: ${set_dashboard_pwd_update}"
                echo ""
                sed -i "/dashboard_port =.*/a\dashboard_user = ${set_dashboard_user_update}\ndashboard_pwd = ${set_dashboard_pwd_update}\n" ${str_program_dir}/${program_config_file}
            fi
            if [ -z "${search_kcp_bind_port}" ];then 
                echo -e "${COLOR_GREEN}Please select kcp support${COLOR_END}"
                echo "1: enable (default)"
                echo "2: disable"
                echo "-------------------------"  
                read -e -p "Enter your choice (1, 2 or exit. default [1]): " str_kcp
                case "${str_kcp}" in
                    1|[yY]|[yY][eE][sS]|[oO][nN]|[tT][rR][uU][eE]|[eE][nN][aA][bB][lL][eE])
                        set_kcp="true"
                        ;;
                    0|2|[nN]|[nN][oO]|[oO][fF][fF]|[fF][aA][lL][sS][eE]|[dD][iI][sS][aA][bB][lL][eE])
                        set_kcp="false"
                        ;;
                    [eE][xX][iI][tT])
                        exit 1
                        ;;
                    *)
                        set_kcp="true"
                        ;;
                esac
                echo "kcp support: ${set_kcp}"
                def_kcp_bind_port=( $( __readINI ${str_program_dir}/${program_config_file} common bind_port ) )
                if [[ "${set_kcp}" == "false" ]]; then
                    sed -i "/^bind_port =.*/a\# udp port used for kcp protocol, it can be same with 'bind_port'\n# if not set, kcp is disabled in frps\n#kcp_bind_port = ${def_kcp_bind_port}\n" ${str_program_dir}/${program_config_file}
                else
                    sed -i "/^bind_port =.*/a\# udp port used for kcp protocol, it can be same with 'bind_port'\n# if not set, kcp is disabled in frps\nkcp_bind_port = ${def_kcp_bind_port}\n" ${str_program_dir}/${program_config_file}
                fi
            fi
            if [ -z "${search_tcp_mux}" ];then
                echo "# Please select tcp_mux "
                echo "1: enable (default)"
                echo "2: disable"
                echo "-------------------------"  
                read -e -p "Enter your choice (1, 2 or exit. default [1]): " str_tcp_mux
                case "${str_tcp_mux}" in
                    1|[yY]|[yY][eE][sS]|[oO][nN]|[tT][rR][uU][eE]|[eE][nN][aA][bB][lL][eE])
                        set_tcp_mux="true"
                        ;;
                    0|2|[nN]|[nN][oO]|[oO][fF][fF]|[fF][aA][lL][sS][eE]|[dD][iI][sS][aA][bB][lL][eE])
                        set_tcp_mux="false"
                        ;;
                    [eE][xX][iI][tT])
                        exit 1
                        ;;
                    *)
                        set_tcp_mux="true"
                        ;;
                esac
                echo "tcp_mux: ${set_tcp_mux}"
                sed -i "/^privilege_mode = true/d" ${str_program_dir}/${program_config_file}
                sed -i "/^token =.*/a\# if tcp stream multiplexing is used, default is true\ntcp_mux = ${set_tcp_mux}\n" ${str_program_dir}/${program_config_file}
            fi
            if [ ! -z "${search_allow_ports}" ];then
                sed -i "s/privilege_allow_ports/allow_ports/" ${str_program_dir}/${program_config_file}
            fi
        fi
        verify_dashboard_user=`grep "^dashboard_user" ${str_program_dir}/${program_config_file}`
        verify_dashboard_pwd=`grep "^dashboard_pwd" ${str_program_dir}/${program_config_file}`
        verify_kcp_bind_port=`grep "kcp_bind_port" ${str_program_dir}/${program_config_file}`
        verify_tcp_mux=`grep "^tcp_mux" ${str_program_dir}/${program_config_file}`
        verify_token=`grep "privilege_token" ${str_program_dir}/${program_config_file}`
        verify_allow_ports=`grep "privilege_allow_ports" ${str_program_dir}/${program_config_file}`
        if [ ! -z "${verify_dashboard_user}" ] && [ ! -z "${verify_dashboard_pwd}" ] && [ ! -z "${verify_kcp_bind_port}" ] && [ ! -z "${verify_tcp_mux}" ] && [ -z "${verify_token}" ] && [ -z "${verify_allow_ports}" ];then
            echo -e "${COLOR_GREEN}update configuration file successfully!!!${COLOR_END}"
        else
            echo -e "${COLOR_RED}update configuration file error!!!${COLOR_END}"
        fi
    fi
}
update_program_server_clang(){
    fun_clangcn "clear"
    if [ -s ${program_init} ] || [ -s ${str_program_dir}/${program_name} ] ; then
        echo "============== Update ${program_name} =============="
        update_config_clang
        checkos
        check_centosversion
        check_os_bit
    fun_getVer
        remote_init_version=`wget  -qO- ${FRPS_INIT} | sed -n '/'^version'/p' | cut -d\" -f2`
        local_init_version=`sed -n '/'^version'/p' ${program_init} | cut -d\" -f2`
        install_shell=${strPath}
        if [ ! -z ${remote_init_version} ];then
            if [[ "${local_init_version}" != "${remote_init_version}" ]];then
                echo "========== Update ${program_name} ${program_init} =========="
                if ! wget  ${FRPS_INIT} -O ${program_init}; then
                    echo "Failed to download ${program_name}.init file!"
                    exit 1
                else
                    echo -e "${COLOR_GREEN}${program_init} Update successfully !!!${COLOR_END}"
                fi
            fi
        fi
        [ ! -d ${str_program_dir} ] && mkdir -p ${str_program_dir}
        echo -e "Loading network version for ${program_name}, please wait..."
     fun_getServer
        fun_getVer >/dev/null 2>&1
        local_program_version=`${str_program_dir}/${program_name} --version`
        echo -e "${COLOR_GREEN}${program_name}  local version ${local_program_version}${COLOR_END}"
        echo -e "${COLOR_GREEN}${program_name} remote version ${FRPS_VER}${COLOR_END}"
        if [[ "${local_program_version}" != "${FRPS_VER}" ]];then
            echo -e "${COLOR_GREEN}Found a new version,update now!!!${COLOR_END}"
            ${program_init} stop
            sleep 1
            rm -f /usr/bin/${program_name} ${str_program_dir}/${program_name}
     fun_download_file
            if [ "${OS}" == 'CentOS' ]; then
                chmod +x ${program_init}
                chkconfig --add ${program_name}
            else
                chmod +x ${program_init}
                update-rc.d -f ${program_name} defaults
            fi
            [ -s ${program_init} ] && ln -s ${program_init} /usr/bin/${program_name}
            [ ! -x ${program_init} ] && chmod 755 ${program_init}
            ${program_init} start
            echo "${program_name} version `${str_program_dir}/${program_name} --version`"
            echo "${program_name} update success!"
        else
                echo -e "no need to update !!!${COLOR_END}"
        fi
    else
        echo "${program_name} Not install!"
    fi
    exit 0
}
clear
strPath=`pwd`
rootness
fun_set_text_color
checkos
check_centosversion
check_os_bit
pre_install_packs
shell_update
# Initialization
action=$1
[  -z $1 ]
case "$action" in
install)
    pre_install_clang 2>&1 | tee /root/${program_name}-install.log
    ;;
config)
    configure_program_server_clang
    ;;
uninstall)
    uninstall_program_server_clang 2>&1 | tee /root/${program_name}-uninstall.log
    ;;
update)
    update_program_server_clang 2>&1 | tee /root/${program_name}-update.log
    ;;
*)
    fun_clangcn
    echo "Arguments error! [${action} ]"
    echo "Usage: `basename $0` {install|uninstall|update|config}"
    RET_VAL=1
    ;;
esac

Github

wget https://raw.githubusercontent.com/MvsCode/frps-onekey/master/install-frps.sh -O ./install-frps.sh
chmod 700 ./install-frps.sh
./install-frps.sh install

Uninstall(卸载)

./install-frps.sh uninstall

Update(更新)

./install-frps.sh update

Server management(服务管理器)

Usage: /etc/init.d/frps {start|stop|restart|status|config|version}

开启服务端frps和dashboard

此部分由脚本自动安装并设置开机自启动

/usr/local/frps/frps.ini

# [common] is integral section
[common]
# A literal address or host name for IPv6 must be enclosed
# in square brackets, as in "[::1]:80", "[ipv6-host]:http" or "[ipv6-host%zone]:80"
bind_addr = 0.0.0.0
bind_port = 6666
# udp port used for kcp protocol, it can be same with 'bind_port'
# if not set, kcp is disabled in frps
kcp_bind_port = 6666
# if you want to configure or reload frps by dashboard, dashboard_port must be set
dashboard_port = 8999
# dashboard assets directory(only for debug mode)
dashboard_user = admin
dashboard_pwd = Ab.12345
# assets_dir = ./static
vhost_http_port = 6668
vhost_https_port = 6669
# console or real logFile path like ./frps.log
log_file = ./frps.log
# debug, info, warn, error
log_level = debug
log_max_days = 30
# auth token
token = k3yMVev1GAtuBN27
# It is convenient to use subdomain configure for http、https type when many people use one frps server together.
subdomain_host = 103.96.148.28
# only allow frpc to bind ports you list, if you set nothing, there won't be any limit
#allow_ports = 1-65535
# pool_count in each proxy will change to max_pool_count if they exceed the maximum value
max_pool_count = 200
# if tcp stream multiplexing is used, default is true
tcp_mux = true

frpc服务配置

cat /usr/local/src/frpc.ini
[common]
server_addr = 103.96.148.28
server_port = 6666
token = k3yMVev1GAtuBN27

[ssh]
type = tcp
local_ip = 127.0.0.1
local_port =6667
remote_port = 7777
[common]
server_addr = 47.97.81.193
server_port = 8802
token = 0r5SB6gua0f5X9j5

[ssh]
type = tcp
local_ip = 127.0.0.1
local_port =8802
remote_port = 7777

将frpc加入系统服务并设置为开机自启动

cat /lib/systemd/system/frpc.service
[Unit]
Description=The nginx HTTP and reverse proxy server
After=network.target remote-fs.target nss-lookup.target

[Service]
Type=simple
ExecStart=/usr/local/src/frp/frpc -c /usr/local/src/frp/frpc.ini
KillSignal=SIGQUIT
TimeoutStopSec=5
KillMode=process
PrivateTmp=true
StandardOutput=syslog
StandardError=inherit
Restart=on-failure
RestartSec=5s

[Install]
WantedBy=multi-user.target
systemctl enable frpc.service
Created symlink /etc/systemd/system/multi-user.target.wants/frpc.service → /lib/systemd/system/frpc.service

2.部署openvpn

根据这两篇文章写的

https://www.cnblogs.com/Devinhao/articles/15190384.html

https://www.cnblogs.com/Devinhao/articles/15191243.html

开启端口转发:

iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o enp0s31f6 -j MASQUERADE

主要贴一下配置:

root@yehee-PowerEdge-T30:/etc/openvpn# cat server.conf
#监听本机ip地址
local 0.0.0.0

#监控本机端口号
port 6667

#指定采用的传输协议,可以选择tcp或udp
proto tcp
#proto udp
#指定创建的通信隧道类型,可选tun或tap
dev tun

#指定CA证书的文件路径
ca /etc/openvpn/ca.crt

#指定服务器端的证书文件路径
cert /etc/openvpn/server/server.crt

#指定服务器端的私钥文件路径
key /etc/openvpn/server/server.key

#指定迪菲赫尔曼参数的文件路径
dh /etc/openvpn/dh.pem

#指定虚拟局域网占用的IP地址段和子网掩码,此处配置的服务器自身占用.1的ip地址
server 10.8.0.0 255.255.255.0

#推送路由到客户端
push "route 0.0.0.0 0.0.0.0"
push "route 10.8.0.0 255.255.255.0"

#服务器自动给客户端分配IP后,客户端下次连接时,仍然采用上次的IP地址(第一次分配的IP保存在ipp.txt中,下一次分配其中保存的IP)。
ifconfig-pool-persist ipp.txt

#自动推送客户端上的网关及DHCP
push "redirect-gateway def1 bypass-dhcp"

#OpenVPN的DHCP功能为客户端提供指定的 DNS、WINS 等
push "dhcp-option DNS 114.114.114.114"

#允许客户端与客户端相连接,默认情况下客户端只能与服务器相连接
client-to-client

#每10秒ping一次,连接超时时间设为120秒
keepalive 10 120

#开启TLS-auth,使用ta.key防御攻击。服务器端的第二个参数值为0,客户端的为1。
tls-auth /etc/openvpn/ta.key 0

#加密认证算法
cipher AES-256-CBC

#使用lzo压缩的通讯,服务端和客户端都必须配置
comp-lzo

#最大连接用户
max-clients 100 

#定义运行的用户和组
user openvpn
group openvpn

#重启时仍保留一些状态
;persist-key
;persist-tun

#输出短日志,每分钟刷新一次,以显示当前的客户端
status /var/log/openvpn-status.log

#日志保存路径
log         /var/log/openvpn.log
log-append  /var/log/openvpn.log

#指定日志文件的记录详细级别,可选0-9,等级越高日志内容越详细
verb 4

#相同信息的数量,如果连续出现 20 条相同的信息,将不记录到日志中
mute 20

#客户端不进行证书认证,如果不加将实现证书和用户密码双重认证,此处配置为证书和密码双重认证
#client-cert-not-required
verify-client-cert
# #用户和密码验证脚本
auth-user-pass-verify /etc/openvpn/checkpsw.sh via-env
  
#使用用户名密码登录认证
username-as-common-name
   
#脚本安全级别,验证密码时,如果script-security 2时就不能验证密码了,需要使用script-security 3
script-security 3
#禁用重协商 禁止证书自动过期,以便用户保持连接
reneg-sec 0

#sndbuf 0
#rcvbuf 0
cat /etc/openvpn/checkpsw.sh

#!/bin/bash
###########################################################

# checkpsw.sh (C) 2004 Mathias Sundman <mathias@openvpn.se>

#

# This script will authenticate OpenVPN users against

# a plain text file. The passfile should simply contain

# one row per user with the username first followed by

# one or more space(s) or tab(s) and then the password.

PASSFILE="/etc/openvpn/psw-file"
LOG_FILE="/var/log/openvpn-password.log"
TIME_STAMP=`date "+%Y-%m-%d %T"`

###########################################################

if [ ! -r "${PASSFILE}" ]; then
	    echo "${TIME_STAMP}: Could not open password file \"${PASSFILE}\" for reading." >>  ${LOG_FILE}
	        exit 1
fi 
CORRECT_PASSWORD=`awk '!/^;/&&!/^#/&&$1=="'${username}'"{print $2;exit}' ${PASSFILE}`
if [ "${CORRECT_PASSWORD}" = "" ]; then
echo "${TIME_STAMP}: User does not exist: username=\"${username}\", password=\"${password}\"." >> ${LOG_FILE}
   exit 1
fi	 
if [ "${password}" = "${CORRECT_PASSWORD}" ]; then
  echo "${TIME_STAMP}: Successful authentication: username=\"${username}\"." >> ${LOG_FILE}
exit 0
fi		 
echo "${TIME_STAMP}: Incorrect password: username=\"${username}\", password=\"${password}\"." >> ${LOG_FILE}
exit 1
root@yehee-PowerEdge-T30:/etc/openvpn/client# cat client.ovpn 
##############################################
# Sample client-side OpenVPN 2.0 config file #
# for connecting to multi-client server.     #
#                                            #
# This configuration can be used by multiple #
# clients, however each client should have   #
# its own cert and key files.                #
#                                            #
# On Windows, you might want to rename this  #
# file so it has a .ovpn extension           #
##############################################

# Specify that we are a client and that we
# will be pulling certain config file directives
# from the server.
client

# Use the same setting as you are using on
# the server.
# On most systems, the VPN will not function
# unless you partially or fully disable
# the firewall for the TUN/TAP interface.
;dev tap
dev tun

# Windows needs the TAP-Win32 adapter name
# from the Network Connections panel
# if you have more than one.  On XP SP2,
# you may need to disable the firewall
# for the TAP adapter.
;dev-node MyTap

# Are we connecting to a TCP or
# UDP server?  Use the same setting as
# on the server.
;proto udp
proto tcp

# The hostname/IP and port of the server.
# You can have multiple remote entries
# to load balance between the servers.
remote 103.96.148.28 7777
remote wangpan15.shenzhuo.vip 18302
;remote my-server-2 1194
;remote yeehe.tpddns.cn 6667
;remote free.svipss.top 23984
;remote 192.168.0.139 6667


# Choose a random host from the remote
# list for load-balancing.  Otherwise
# try hosts in the order specified.
;remote-random

# Keep trying indefinitely to resolve the
# host name of the OpenVPN server.  Very useful
# on machines which are not permanently connected
# to the internet such as laptops.
resolv-retry infinite

# Most clients don't need to bind to
# a specific local port number.
nobind
auth-user-pass
script-security 3


auth-nocache				 
# Downgrade privileges after initialization (non-Windows only)
;user nobody
;group nogroup

# Try to preserve some state across restarts.
persist-key
persist-tun
reneg-sec 0
# If you are connecting through an
# HTTP proxy to reach the actual OpenVPN
# server, put the proxy server/IP and
# port number here.  See the man page
# if your proxy server requires
# authentication.
;http-proxy-retry # retry on connection failures
;http-proxy [proxy server] [proxy port #]

# Wireless networks often produce a lot
# of duplicate packets.  Set this flag
# to silence duplicate packet warnings.
;mute-replay-warnings

# SSL/TLS parms.
# See the server config file for more
# description.  It's best to use
# a separate .crt/.key file pair
# for each client.  A single ca
# file can be used for all clients.
ca ca.crt
cert client.crt
key client.key

# Verify server certificate by checking that the
# certicate has the correct key usage set.
# This is an important precaution to protect against
# a potential attack discussed here:
#  http://openvpn.net/howto.html#mitm
#
# To use this feature, you will need to generate
# your server certificates with the keyUsage set to
#   digitalSignature, keyEncipherment
# and the extendedKeyUsage to
#   serverAuth
# EasyRSA can do this for you.
remote-cert-tls server

# If a tls-auth key is used on the server
# then every client must also have the key.
tls-auth ta.key 1

# Select a cryptographic cipher.
# If the cipher option is used on the server
# then you must also specify it here.
# Note that v2.4 client/server will automatically
# negotiate AES-256-GCM in TLS mode.
# See also the ncp-cipher option in the manpage
cipher AES-256-CBC

# Enable compression on the VPN link.
# Don't enable this unless it is also
# enabled in the server config file.
comp-lzo

# Set log file verbosity.
verb 4

# Silence repeating messages
mute 20

<ca>
-----BEGIN CERTIFICATE-----
MIIDOTCCAiGgAwIBAgIUA7hLYDsQy9i2b24wfI1KxvBY44kwDQYJKoZIhvcNAQEL
BQAwEDEOMAwGA1UEAwwFeWVoZWUwHhcNMjEwODI2MDc1ODUwWhcNMzEwODI0MDc1
ODUwWjAQMQ4wDAYDVQQDDAV5ZWhlZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
AQoCggEBALcScm176QW2QtrIv/yEk9hOXNH/sf2Edw0qvfyVwNyF8QLjw2tsQ0Vy
pwM780RyP22b4YBX8yQostWeHV3bY6pzzV7RZKeNZX76l14PMTsZjJkRXM7XKUlL
g7V0Gonvjk8LvPmUDpMTZX96yc7YsvYzGOImokoa/WZ08EvMPXVFxslMu9lUWDVi
C39YB0sskmzsL+QdaShUH3ceSt7c/uAXR7TiRnH0MdHWClXdkONljP5bhF7zdY6y
qnK8swc3l/jQFitvRi/Z5BGLJDGVdHGG2o1Joy9rPwmdX6PaE3kH4FJZTQ9o+ZKy
+JgtvpSaMMl8WiMG+znaPR+eeYVhNHECAwEAAaOBijCBhzAdBgNVHQ4EFgQUSQE4
7hNpsSfuUCBQP2EU3vtIjpYwSwYDVR0jBEQwQoAUSQE47hNpsSfuUCBQP2EU3vtI
jpahFKQSMBAxDjAMBgNVBAMMBXllaGVlghQDuEtgOxDL2LZvbjB8jUrG8FjjiTAM
BgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAGU2C
woyw9ex6UGgGu5moX+8H1SmtTDqVV7BVoLD28vWgjw5ek+Lef9t7tvcY6m8azWFv
o2ztPsyn/bEAha++3+9B7fz9Uz0HXWnBvKeREWtH3A+/5UisK0pOfKvu5h/wRnc+
OEu5lN726qcS/G5jBZlCyRTiKiJqN07DSm02yqrKN8nLodaTedcB4oDBZtKRj42H
pQOcRGHXe+QcGOT8EeXbpFeIbDP1f2rZCkJ20BBcVlsGZy+ZSotr0LEjdVcwy4Gl
ueYB2/n7tTuHEaLlxI0Z1/6DhV/DsBPctbcGMs7+Y3btznlibWc3FMYfNzxBKFYr
v7xNXWJDv5kwh3zNEg==
-----END CERTIFICATE-----
</ca>
<cert>
-----BEGIN CERTIFICATE-----
MIIDRzCCAi+gAwIBAgIQREhg5qGQCyJWcGBFcwZUTjANBgkqhkiG9w0BAQsFADAQ
MQ4wDAYDVQQDDAV5ZWhlZTAeFw0yMTA4MjYwODAxMTNaFw0yMzExMjkwODAxMTNa
MBAxDjAMBgNVBAMMBXllaGVlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
AQEAqyFWaXXCgu4ad1pIp+wUaPWWL4lB8nrXY6rTNfqD4TwdUv6LXayAEJ06uBnG
2gd/YQ6JLJKEWhdt7ZeVKzgc3RA0sfwMsN+ZDplap/FLY8iOgmdeadeaS27czKAd
HsWHdgxelaBMaip4rYJ5SD1BVU0TBmQAYXIRQadZ0objrw8Z2H8RmPwe/XFTgNJt
Hst9SUsv7hnZWJzuiYc7/6nu5a5/BaNIpEW82xT5s7q/FK//025LWy4NGi9L37Cc
L67lotpylAI/wV5PRaU4mmkAgIrt2Twg8vszF6sXYjOIZNwRQ59dJ681w+tdjoWn
qwQOHYP+lYDMBFg4TcvOGarg8QIDAQABo4GcMIGZMAkGA1UdEwQCMAAwHQYDVR0O
BBYEFCTIYGrfo03WsE3l6/8zMP/8GYnUMEsGA1UdIwREMEKAFEkBOO4TabEn7lAg
UD9hFN77SI6WoRSkEjAQMQ4wDAYDVQQDDAV5ZWhlZYIUA7hLYDsQy9i2b24wfI1K
xvBY44kwEwYDVR0lBAwwCgYIKwYBBQUHAwIwCwYDVR0PBAQDAgeAMA0GCSqGSIb3
DQEBCwUAA4IBAQBfJnsffMh78sfbKbCDKjVAhXiHABFxwYdDmhciUf5iWG9kWjP6
gtgVzVV9bt5CM18WlcXUCr/pSRM/GH7HnA4uX3ZdkojmxGap6n3g7xZDirQyldnL
ckMXfjZhx8fCkAD/G+BGuglAf3rs7yJ4Uje7Hnw8o9LfsRJuRwMRed3LdI7zf6su
tEN+Elv/6V+wYVrzXPqBAgVzr66oil8HMJHtJgHvvnvfkKHYu4M4auqx8+KNSqNi
/m6Zi/kdfM6JubdT64ZAEecTFURQxC+BxBq8Ok2lA/BBg5Tru/RjduYzbZglg8o/
spHcwlZE1xCnAlYHZ8br2viJMW7lKrbHoDtp
-----END CERTIFICATE-----
</cert>
<key>
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCrIVZpdcKC7hp3
Wkin7BRo9ZYviUHyetdjqtM1+oPhPB1S/otdrIAQnTq4GcbaB39hDokskoRaF23t
l5UrOBzdEDSx/Ayw35kOmVqn8UtjyI6CZ15p15pLbtzMoB0exYd2DF6VoExqKnit
gnlIPUFVTRMGZABhchFBp1nShuOvDxnYfxGY/B79cVOA0m0ey31JSy/uGdlYnO6J
hzv/qe7lrn8Fo0ikRbzbFPmzur8Ur//TbktbLg0aL0vfsJwvruWi2nKUAj/BXk9F
pTiaaQCAiu3ZPCDy+zMXqxdiM4hk3BFDn10nrzXD612OhaerBA4dg/6VgMwEWDhN
y84ZquDxAgMBAAECggEBAIrnyIhZucUlF/6BHjCPhBGeJoX3V7xG0cZoxoAuFBYj
AXp4ew9SEbFqrlr5MVuQcmiJr/aqBxxJoEUWoVIvfd5CZUODX5nCJS6gc+GWDqe0
B1j6Jryq8OcB2d+Op5RuqYG8kJnLP7t9Ne9A1Mk6T2m54hNx4I04VaGBAXvNWcqh
lxyj1Sw14Bus5pQAzDXQvIY8zLqOUhYF+jM1UY306kpNc/PSPZ19u6hbrXtS7bvp
KObFuLxgwgm47nJc+1VGY6rtODlBUiKM+J9nXXfw8crXki2WWdZ7hAJioFZBgcbh
9MFiLHJ0P5X2C3RVa09Z7mVHbaHgv/1HSyF5Bp7fawECgYEA266iln5QIenkHv5D
UWkEvU9clLm/UPnz87oBnToYXXaRnv47ubDIUwjXt55Vp/0HHVPaUVhJSLRkD/j8
fZx21Iwkh4UTvlZcrTHqunyoMTLF/dgc1s7YBvvF+z6WbY8i4wDi1eRKjzbUBG+H
npSrqbFKU6oln2ibk4admxyOADkCgYEAx2vkcQRnl+Snn7nJ/dxUJV5joR4CbKEl
1NNV73M+3urUvHMYZbNafTb5uMf9iqwjDs+psUa9vJbxZ7KFUMlNUFE0rkGbvD7L
X2AhTOX+q2eExheuH8nBEIPjP7VEK/IjEwaWMZSVoYQwp402Da8pYF1p37IE/CW9
kNAD6E0G9nkCgYAZH5y6h1GUv1H2dW+vdMo0+EmHPMLzeNJ8ci5TE9zLe47l1v9v
mhce3+kDt9jl8FsK8JcMLIOdC/xRk1EU8HrqjehzkzWR1ACfUhEdKLp3fe4EvN13
d4pfKhYXSK4dc3wy59wJSCV6wXN32mVxLmF/c6YjcVcCJw17zq5hmd9niQKBgQC4
UEQHIOcOQEudGP5UH3u2PhMfKrla5WYt2lYmxgFpzuloc4gtFyOfb1xHKLBxpr+Q
ROa17ogW8fuUuC73h9ZpUWS7WfAygGc/c33TsQ88JKVW4TQSNUq3lO5IR6UGaPl5
8DCJCqdxbNf7REydQTOg2TWthr+MvOUEHv49ilPRIQKBgDmemtFUEkvYbVDWyfc4
5ZL7IX8IDfaYSosS+gm1YLoKcMvL5IiPHFH9fI1T+GhxCWMOmIpCPs+YrkKxrwYm
G45zEhZEeKXVf0ujoa1jKx2HWPRfuFwHUEoWt2YU4S0jqNweHBb89oOGLXJ3Cu58
KofepIXmKFUUvkHSSNW3uFZ4
-----END PRIVATE KEY-----
</key>
key-direction 1
<tls-auth>
#
# 2048 bit OpenVPN static key
#
-----BEGIN OpenVPN Static key V1-----
5dc0a5ac144539e42237fb213089a1cd
c0b3c37071c3a3891bd3c0c5ccff3fdd
96172f25686af115775d1fb7caea61d0
cfeb2075b34a7e4d968096b8aff5edaf
1766962558c0959983293ee73da3cdca
80fc694d369c3d22b867b2991102349d
9259d4db7bd18b7d449085e08771b1a8
3bda1b149e83a47de9149d0d6e2ef879
ee86a862b7501da4c036e38d9c48140b
4a0929633f957b9d2bf7595cc19c63b7
5c37135ae58fa0880c0b2d853ae942cc
03ca0b6669d097eb79431251cd4c111a
f57a866c45d8faf91b4ddfc233437296
e8a957d4147b2366c04dc0697c163c4e
52ef0686f0693ea4ef64484ed0e3793f
893e385430a241b56df43fab01f5d9a5
-----END OpenVPN Static key V1-----
</tls-auth>
<dh>
-----BEGIN DH PARAMETERS-----
MIIBCAKCAQEA5bgDJgmVr/5nLlqxmMZjKbefQBdKMz6Xy1M2P4O806eEce4bbafr
0Ir94tSuQkXLHaBTaTdyYKjBrTC2ZrTAk/9uB+7tBI05gZvfK23RixUUVNB73Bo1
3ePIKvYFcjCixAz0WNBI5rzMG1SaW7lhwM3EtfRFVuMk+cLnC4w+76/hFNyMLhrJ
m+4ddcTVaSjTs9L4cZnDD427ozxaIRfl3HMadNliVA+Sjcu0spVW9FtXpxokNxYH
KVW4348VA8tHXvs+gR3iHOYCu8Uck464ZJI25GQHmXt/9mkHMD9dLnNZjZ6nsD9O
r6h5mCr4y2N46dqrMtTCIWpCaub2qTs18wIBAg==
-----END DH PARAMETERS-----
</dh>

3.备用配置

root@yehee:/usr/local/frp# cat frpc.ini
[common]
server_addr = 103.96.148.28
server_port = 6666
token = k3yMVev1GAtuBN27

[ssh50]
type = tcp
local_ip = 127.0.0.1
local_port =22
remote_port = 7771

评论