CentOS L2TP 服务端/客户端 一键安装脚本

2018/03/20 Linux

CentOS 6/7 L2TP 服务端一键安装脚本

功能

  • 安装l2tp服务端
  • 增加l2tp用户

#!/bin/bash
#set -e
#
# Desc: 本脚本适用于 CentOS 6/7 l2tp 服务端配置安装
# CreateDate: 2018-03-05 09:41:07
# LastModify:
# Author: larryzl
# Version: 0.1
# History:
#
#
# ---------------------- Script Begin ----------------------
#



PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin

# 检查是否为root用户
isRoot(){
    if [ $UID -ne 0 ];then
        echo "错误! 请使用root运行脚本。"
        exit 1
    fi
}

# 检查 tun 是否可用
tunAvailable(){
    if [[ ! -e /dev/net/tun ]]; then
        echo "错误:TUN/TAP 不可用!" 1>&2
        exit 1
    fi
}

# 检查看是否支持系统
isOsSupport(){ 
    [ -f /etc/redhat-release ] && awk -F '[. ]' '{print ($1,$3 ~ /^[0-9]+$/?$3:$4)}' /etc/redhat-release && return
    echo "错误: 本脚本不适用于 当前操作系统"
    exit 1
}
OS=$(isOsSupport|awk '{print $NF}')
# 关闭selinux
disabledSelinux(){
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
}

# 生成随机字符串
randomStr(){
    len=$1
    : ${len:=10}
    </dev/urandom tr -dc [:alpha:] | head -c${1:-${len}}
}

#记录日志
sLog(){
    now=$(date +"[%Y-%m-%d %H:%M:%S]")
    echo "${now} $1" >> /tmp/l2tp_install.log
}

# 依赖软件包
centos6_deps=(openswan ppp xl2tpd)
centos7_deps=(libreswan xl2tpd)

# 获取IP地址
IP=$(ip a|awk -F '[/ ]' '{for(i=1;i<=NF;i++){if($(i+1) ~ /^[1-9]+$/ && $(i) ~ /^([0-9]+\.)+[0-9]+$/){ip=$i}}}END{if(ip !~ /^127.0/){print ip}}' 2>/dev/null)
[ -z ${IP} ] && IP=$(curl --connect-timeout 5 ip.cip.cc)

# 获取系统信息
getOsInfo(){
    os=$(isOsSupport)
    cpu_info=$(awk 'BEGIN{FS=":"}/model name/{name=$2} END {print name}' /proc/cpuinfo |sed 's/^[ \t]*//;s/[ \t]$//')
    cpu_cores=$(awk '/processor/{num++}END{print num}' /proc/cpuinfo)
    cpu_mhz=$(awk 'BEGIN{FS=":"}/cpu MHz/{name=$2} END {print name}' /proc/cpuinfo |sed 's/^[ \t]*//;s/[ \t]$//')
    memory=$(awk '/MemTotal/ {print $2/1024/1024}' /proc/meminfo)"g"
    swap=$(awk '/SwapTotal/ {print $2/1024/1024}' /proc/meminfo)"g"
    memory_free=$(awk '/^Cached/ {print $2/1024/1024}' /proc/meminfo)"g"
    uptime=$(awk '{a=$1/86400;b=($1%86400)/3600;c=($1%3600)/60;d=$1%60} {printf("%ddays, %d:%d:%d\n",a,b,c,d)}' /proc/uptime)
    arch=$(uname -m)
    kernel=$(uname -r)

    echo ""
    echo "########################### Script Info ###############################"
    echo "# L2TP VPN Auto Install                                               #"
    echo "# System Supported: CentOS 6                                          #"
    echo "# Author: larryzl                                                     #"
    echo "########################### System Info ###############################"
    echo "# CPU                             :   ${cpu_info}                     "
    echo "# Number of cores                 :   ${cpu_cores}                    "
    echo "# CPU MHz                         :   ${cpu_mhz}                      "
    echo "# Memory Total                    :   ${memory}                       "
    echo "# Memory Free                     :   ${memory_free}                  "
    echo "# Swap Tota                       :   ${swap}                         "
    echo "# Uptime                          :   ${uptime}                       "
    echo "# OS                              :   ${os}                           "
    echo "# Arch                            :   ${arch}                         "
    echo "# Kernel                          :   ${kernel}                       "
    echo "# Hostname                        :   $(hostname)                     "
    echo "# IPv4 address                    :   ${IP}                           "
    echo "#######################################################################"
    echo "############################### Choice  ###############################"
    echo "# 1.  Install L2TP Service                                            "
    echo "# 2.  Add VPN Client Account"
    echo ""
    
}

# 检查依赖软件是否安装
env_check(){
    uninstall_pkg=()
    for i in libreswan ppp xl2tpd;do
        rpm -ql ${i} >/dev/null 2>&1
        if [[ $? -ne 0 ]]; then
            uninstall_pkg[${#uninstall_pkg[@]}]=${i}
        fi
    done
    if [ ${#uninstall_pkg[@]} -ne 0 ];then
        echo "错误: 以下依赖软件未安装 ${uninstall_pkg[@]}"
        return 1
    else
        echo "依赖软件检查正常"
        return 0
    fi
}

# 安装l2tp
installL2tp(){
    # 初始化依赖包数组
    install_deps=()

    echo -n "是否开始安装 L2TP 服务端(n)"
    read is_install
    if [ "${is_install}0" != "y0" ];then
        exit 1
    fi
    
    echo "####################开始安装 L2TP 服务 ###############################"
    while [[ 1 == 1 ]]; do
        echo "开始安装软件包...."
        if [ "${OS}" == "6" ];then
            deps=(${centos6_deps[@]})
        elif [ "${OS}" == "7" ]; then
            deps=(${centos7_deps[@]})
        fi

        for dep in ${deps[@]};do
            read -p "是否安装 ${dep} (y):" is_install
            : ${is_install:="y"}
            if [ "${is_install}0" == "y0" ];then
                install_deps[${#install_deps[@]}]=${dep}
            fi
        done
        if [ ${#install_deps} -eq 0 ];then
            echo "没有选择任何软件安装..."
            echo -n "是否继续配置(n)"
            read is_continue
            if [ "${is_continue}0" != "y0" ];then
                continue
            fi
        else
            echo -n "确认安装软件 ${install_deps[@]} (n):"
            read is_install
            if [ "${is_install}0" == "y0" ];then
                echo "正在安装.."
                yum -y install ${install_deps[@]}
                echo "安装完成..."
            else
                continue
            fi

        fi
        env_check
        if [ $? -eq 0 ];then
            break
        fi

    done
}

alterConf(){
    while true; do
        
        echo "####################进入 VPN 配置###############################"

        read -p "请输入拨入VPN的IP地址(${IP}):" ipaddr
        : ${ipaddr:=${IP}}
        if [ "${ipaddr}0" == "0" ];then
            echo "IP地址错误,请重新输入!"
            continue
        fi

        randomSecrets=$(randomStr)
        read -p "请输入共享秘钥(${randomSecrets}):" secrets
        [ "${secrets}0" == "0" ] && secrets=$randomSecrets

        read -p "正在创建第一个用户,请输入用户名(admin):" user
        : ${user:="admin"}

        randomPwd=$(randomStr)
        read -p "请输入用户密码(${randomPwd}):" pwd
        : ${pwd:=$randomPwd}

        read -p "请输入IP Range 范围(192.168.18):" iprange
        : ${iprange:="192.168.18"}

        echo "#######################配置信息###################################"
        echo "L2TP 初始配置信息:"
        echo ""
        echo "Server IP:             ${ipaddr}"
        echo "PSK:                   ${secrets}"
        echo "UserName:              ${user}"
        echo "Password:              ${pwd}"
        echo "Server VPN IP:         ${iprange}.1"
        echo "Client IP Range:       ${iprange}.2 - ${iprange}.254"
        echo "###############################################################"
        echo -n "请确认配置信息(n):"
        read confirmInfo
        if [ "${confirmInfo}0" == "y0" ];then
            break
        fi
    done

    echo "########################开始生成配置文件############################"
    echo "创建 /etc/ipsec.d/vpn.conf "
    cat > /etc/ipsec.d/vpn.conf <<EOF
config setup
    protostack=netkey
    nhelpers=0
    uniqueids=no
    interfaces=%defaultroute
    virtual_private=%v4:10.0.0.0/8,%v4:192.168.0.0/16,%v4:172.16.0.0/12,%v4:!${iprange}.0/24

conn l2tp-psk
    rightsubnet=vhost:%priv
    also=l2tp-psk-nonat

conn l2tp-psk-nonat
    authby=secret
    pfs=no
    auto=add
    keyingtries=3
    rekey=no
    ikelifetime=8h
    keylife=1h
    type=transport
    left=%defaultroute
    leftid=${IP}
    leftprotoport=17/1701
    right=%any
    rightprotoport=17/%any
    dpddelay=40
    dpdtimeout=130
    dpdaction=clear
    sha2-truncbug=yes
    leftnexthop=%defaultroute
    rightnexthop=%defaultroute
EOF
    echo "创建 /etc/ipsec.secrets"
    cat > /etc/ipsec.secrets <<EOF
%any %any : PSK "${secrets}"
EOF
    
    echo "修改 /etc/xl2tpd/xl2tpd.conf"
    cat > /etc/xl2tpd/xl2tpd.conf <<EOF
[global]
port = 1701

[lns default]
ip range = ${iprange}.2-${iprange}.254
local ip = ${iprange}.1
require chap = yes
refuse pap = yes
require authentication = yes
name = l2tpd
ppp debug = yes
pppoptfile = /etc/ppp/options.xl2tpd
length bit = yes
EOF
    
    echo "修改 /etc/ppp/options.xl2tpd"
    cat > /etc/ppp/options.xl2tpd <<EOF
ipcp-accept-local
ipcp-accept-remote
require-mschap-v2
ms-dns 114.114.114.114
ms-dns 8.8.4.4
noccp
auth
hide-password
idle 1800
mtu 1410
mru 1410
nodefaultroute
debug
proxyarp
connect-delay 5000
lcp-echo-interval 0
lcp-echo-failure 0
EOF

    echo "正在修改 /etc/ppp/chap-secrets"
    cat > /etc/ppp/chap-secrets<<EOF
# Secrets for authentication using CHAP
# client    server    secret    IP addresses
${user}    l2tpd    ${pwd}       *
EOF

    echo "修改 /etc/sysctl.conf "
    grep net.ipv4.ip_forward /etc/sysctl.conf > /dev/null
    if [ $? -eq 0 ];then
        sed -i 's/net.ipv4.ip_forward.*/net.ipv4.ip_forward = 1/g' /etc/sysctl.conf 
    else
        echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
    fi
    for each in `ls /proc/sys/net/ipv4/conf/`; do
        echo "net.ipv4.conf.${each}.accept_source_route=0" >> /etc/sysctl.conf
        echo "net.ipv4.conf.${each}.accept_redirects=0" >> /etc/sysctl.conf
        echo "net.ipv4.conf.${each}.send_redirects=0" >> /etc/sysctl.conf
        echo "net.ipv4.conf.${each}.rp_filter=0" >> /etc/sysctl.conf
    done
    sysctl  -p > /dev/null >1

    echo "####################正在修改 iptables ###############################"
    if [ "$OS" == '6' ];then
        [ -f /etc/sysconfig/iptables ] && cp -pf /etc/sysconfig/iptables /etc/sysconfig/iptables.old.`date +%Y%m%d`
        iptables -F
        iptables -t nat -A POSTROUTING -s ${iprange}.0/24 -j SNAT --to-source ${IP}
        iptables -A INPUT -p tcp --dport 22 -j ACCEPT
        iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
        iptables -A INPUT -i lo -j ACCEPT
        iptables -A INPUT -p udp -m multiport --dports 500,4500,1701 -j ACCEPT
        iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
        iptables -A FORWARD -s ${iprange}.0/24  -j ACCEPT
        /etc/init.d/iptables save
        iptables -nvL
    elif [[ "${OS}" == '7' ]]; then
        firewall-cmd --permanent --add-service=ipsec
        firewall-cmd --permanent --add-port=22/tcp
        firewall-cmd --permanent --add-port=1701/udp
        firewall-cmd --permanent --add-port=4500/udp
        firewall-cmd --permanent --add-masquerade
        firewall-cmd --reload
    fi

    echo "####################正在启动 xl2tpd ###############################"
    if [ "$OS" == '6' ];then
        ipsec restart
        /etc/init.d/xl2tpd restart
        chkconfig xl2tpd on
        chkconfig  ipsec on
    elif [ "${OS}" == '7' ]; then
        systemctl enable ipsec
        systemctl restart ipsec
        ipsec verify 
        systemctl enable xl2tpd
        systemctl restart xl2tpd
    fi
    echo "##################################################################"
    echo "xl2tp 已经安装配置完成"
    echo "##################################################################"
    exit 0

}
    
addUser(){
    echo "####################开始添加 VPN 用户 ###############################"
    local username
    local password=$(randomStr 15)
    local ip 

    while [ 1 == 1 ]; do
        read -p "请输入用户名:" username
        if [ -z ${username} ];then
            echo "错误,用户名不能为空"
            continue
        
        elif [[ ! -z $(awk '/^[^#]/ {print $1}' /etc/ppp/chap-secrets|grep -w ${username}) ]];then
                unset ${username}
                echo "错误! 用户名已存在"
        else
            read -p "确认用户名 ${username} (n):" confirmUsername
            if [ "${confirmUsername}0" == "y0" ];then
                break
            fi
        fi     
    done

    while [[  1 == 1 ]]; do
        read -p "请输入密码(${password}):" pwd
        : ${pwd:=${password}}
        if [ ${pwd} == ${password} ];then
            break
        fi
        if [ ${#pwd} -lt 8 ] ;then
            echo "密码必须大于8个字符"
            continue
        elif [[  -z $(echo ${pwd} | awk '{if($1 ~ /[a-z]/ && length($1) > 8 && $1 ~ /[A-Z]/ && $1 ~ /[0-9]/){print $0}}') ]]; then
            echo "密码必须是大小写字母与数字组合"
            continue
        else
            break
        fi
    done
    
    read -p "是否指定客户端IP地址(n):" is_define_client_ip
    if [ "${is_define_client_ip}0" == "y0" ];then
        random_ip_index=$(awk -F '[ -]' '/ip.*range/{print $NF}' /etc/xl2tpd/xl2tpd.conf |awk 'BEGIN{FS=".";OFS="."}{print $1,$2,$3"."}')
        random_ip=${random_ip_index}$((($RANDOM+1000000)%254+1 ))
        while [[ 1 == 1 ]]; do
            read -p "请输入客户端IP地址(${random_ip}):" ip
            : ${ip:=$random_ip}
            grep $ip /etc/ppp/chap-secrets >/dev/null
            if [ $? -eq 0 ] ;then
                echo "${ip} 已经分配,请重新输入"
                continue
            else
                break
            fi
        done
    else
        ip="*"
    fi

    echo "#######################用户信息###################################"
    echo "VPN 用户信息:"
    echo ""
    echo "UserName:                     ${username}"
    echo "Password:                     ${password}"
    echo "Client IP:                    ${ip}"
    echo "###############################################################"

    echo "开始生成用户账号..."

    cat >> /etc/ppp/chap-secrets <<EOF
${username}     l2tpd   ${password}     ${ip}
EOF

   echo "用户信息生成成功,脚本结束"
   exit 0 
}

runInstall(){
    installL2tp
    alterConf
}

while [[ 1 == 1 ]]; do
    clear
    getOsInfo
    read -p "请选择操作:" choice
    if [ "${choice}0" == "10" ];then
        runInstall
    elif [[ "${choice}0" == "20" ]]; then
        addUser
    else
        continue
    fi
done

L2TP客户端安装脚本

功能

  • -i 安装客户端
  • -c 根据配置检查客户端连接情况,自动重连

#!/bin/bash
#set -e
#
# Desc: 脚本描述
# CreateDate: 2018-03-20 09:19:46
# LastModify:
# Author: larryzl
#
# History:
#
#
# ---------------------- Script Begin ----------------------
#

#- 检查地址,如果该地址ping不通证明 VPN断开
CHECK_ADDR="10.9.81.122"
#- vpn配置文件
CONF_PATH="/etc/xl2tpd/xl2tpd.conf"
# 
VPN_CONTROL="/var/run/xl2tpd/l2tp-control"
#- 日志存储目录
LOG_PATH="/Data/apps/script"
#
LOG_NAME="l2tp_client"
#- 日志保存天数
LOG_SAVE=2
#- 
VPN_GW="192.168.18.1"
#- 
REMOTE_NET="10.9.0.0/16"


save_log(){
    msg=$1
    level=$2
    : ${level:="info"}
    current_log_file=${LOG_NAME}_$(date +"%Y%m%d").log
    del_log_file=${LOG_NAME}_$(date +"%Y%m%d" --date "${LOG_SAVE} days ago").log
    if [ -f ${LOG_PATH}/${del_log_file} ];then
        rm -f ${LOG_PATH}/${del_log_file}
    fi
    now=$(date +"[%Y-%m-%d %H:%M:%S]")
    echo "${now} [${level}] ${msg}" >> ${LOG_PATH}/${current_log_file}
}

# 检查看是否支持系统
isOsSupport(){ 
    [ -f /etc/redhat-release ] && awk -F '[. ]' '{print ($1,$3 ~ /^[0-9]+$/?$3:$4)}' /etc/redhat-release && return
    echo "错误: 本脚本不适用于 当前操作系统"
    exit 1
}

# 安装client方法
install_xl2tp_client(){
    read -p "是否开始安装xl2tp客户端(n):" is_install
    if [ "${is_install}0" != "y0" ];then
        echo "退出安装"
        exit 1
    fi
    echo "开始安装xl2tp客户端...."
    echo "正在安装依赖软件...."
    yum install -y xl2tpd ppp
    while [[ 1 == 1 ]]; do
        read -p "请输入VPN地址:" VPN_ADDR
        read -p "请输入VPN连接名称:" VPN_NAME
        read -p "请输入用户名:" VPN_USER 
        read -p "请输入密码:" VPN_PWD
        echo "---------------------------------"
        echo "VPN地址: ${VPN_ADDR}"
        echo "VPN连接名称: VPN_NAME"
        echo "用户名: VPN_USER "
        echo "密码: VPN_PWD"
        read -p "确认以上信息无误(n):" c
        if [ "${c}0" != "y0" ];then
            continue
        fi
    done
    echo "开始配置..."

    cat > ${CONF_PATH} <<EOF
[lac ${VPN_NAME}]
name = ${VPN_USER} 
lns = ${VPN_ADDR}
pppoptfile = /etc/ppp/peers/${VPN_NAME}.l2tpd
ppp debug = no
EOF
    cat >  /etc/ppp/peers/${VPN_NAME}.l2tpd  <<EOF
remotename ${VPN_NAME}
user "${VPN_USER}"   
password "${VPN_PWD}"
unit 0
lock
nodeflate
nobsdcomp
noauth
persist
nopcomp
noaccomp
maxfail 5
debug
EOF
    /etc/init.d/xl2tpd start
    echo 'c ${VPN_NAME}' >/var/run/xl2tpd/l2tp-control  
    echo "VPN 客户端配置完成"
    ip addr
}

# 检查vpn状态方法
reconnect_l2tp(){
    vpn_name=$(awk 'BEGIN{FS=" |]"}{if(NR==1)print $2}' ${CONF_PATH})
    ping -c 2 -f ${CHECK_ADDR} >/dev/null 2>&1
    if [ $? == 0 ];then
        save_log "vpn连接正常"
    else
        save_log "vpn连接异常,正在重连" "error"
        /etc/init.d/xl2tpd restart
        save_log "正在重启 xl2tpd 服务" "warning"
        echo "c ${vpn_name}" > ${VPN_CONTROL}
        save_log "正在重连 xl2tpd" "warning"
        sleep 20
        dev_name=$(/sbin/ip a|grep ${VPN_GW}|awk '{print $NF}')
        if [ "${dev_name}0" == "0" ];then
            save_log "未获取到VPN网络接口名称" "error"
            exit 1
        else
            save_log "成功获取到VPN网络接口名称: ${dev_name}" "warning"
        fi
        /sbin/ip route add ${REMOTE_NET} dev ${dev_name}
        save_log "正在添加到远端路由" "warning"
    fi
}
Usage(){
   echo "Usage:`basename $0` -c | -i"
   echo "-c     auto check vpn client status" 
   echo "-i     install xl2tpd client"
}

case $1 in
    -c )
        reconnect_l2tp
        ;;
    -i )
        install_xl2tp_client
        ;;
    * )
        Usage
        ;;
esac

Search

    Table of Contents