#!/usr/bin/env bash PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin export PATH #=======================================================================# # 系统支持: Debian 10 + / Ubuntu 18.04 + # # 描述: L2TP VPN 自动安装脚本 # # 基于Teddysun版本修改 # #=======================================================================# cur_dir=`pwd` rootness(){ if [[ $EUID -ne 0 ]]; then echo "错误: 此脚本必须以root身份运行!" 1>&2 exit 1 fi } tunavailable(){ if [[ ! -e /dev/net/tun ]]; then echo "错误: TUN/TAP 不可用!" 1>&2 exit 1 fi } 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 } get_opsy(){ [ -f /etc/os-release ] && awk -F'[= "]' '/PRETTY_NAME/{print $3,$4,$5}' /etc/os-release && return [ -f /etc/lsb-release ] && awk -F'[="]+' '/DESCRIPTION/{print $2}' /etc/lsb-release && return } get_os_info(){ IP=$( ip addr | egrep -o '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | egrep -v "^192\.168|^172\.1[6-9]\.|^172\.2[0-9]\.|^172\.3[0-2]\.|^10\.|^127\.|^255\.|^0\." | head -n 1 ) [ -z ${IP} ] && IP=$( wget -qO- -t1 -T2 ipinfo.io/ip ) if [ -z ${IP} ]; then IP=$( wget -qO- -t1 -T2 ifconfig.me ) fi local cname=$( awk -F: '/model name/ {name=$2} END {print name}' /proc/cpuinfo | sed 's/^[ \t]*//;s/[ \t]*$//' ) local cores=$( awk -F: '/model name/ {core++} END {print core}' /proc/cpuinfo ) local freq=$( awk -F: '/cpu MHz/ {freq=$2} END {print freq}' /proc/cpuinfo | sed 's/^[ \t]*//;s/[ \t]*$//' ) local tram=$( free -m | awk '/Mem/ {print $2}' ) local swap=$( free -m | awk '/Swap/ {print $2}' ) local up=$( awk '{a=$1/86400;b=($1%86400)/3600;c=($1%3600)/60;d=$1%60} {printf("%d天 %d:%d:%d\n",a,b,c,d)}' /proc/uptime ) local load=$( w | head -1 | awk -F'load average:' '{print $2}' | sed 's/^[ \t]*//;s/[ \t]*$//' ) local opsy=$( get_opsy ) local arch=$( uname -m ) local lbit=$( getconf LONG_BIT ) local host=$( hostname ) local kern=$( uname -r ) echo "########## 系统信息 ##########" echo echo "CPU型号 : ${cname}" echo "CPU核心数 : ${cores}" echo "CPU频率 : ${freq} MHz" echo "总内存大小 : ${tram} MB" echo "总交换分区大小 : ${swap} MB" echo "系统运行时间 : ${up}" echo "平均负载 : ${load}" echo "操作系统 : ${opsy}" echo "系统架构 : ${arch} (${lbit} Bit)" echo "内核版本 : ${kern}" echo "主机名 : ${host}" echo "IPv4地址 : ${IP}" echo echo "##################################" } check_sys(){ local checkType=$1 local value=$2 local release='' local systemPackage='' if cat /etc/issue | grep -Eqi "debian"; then release="debian" systemPackage="apt" elif cat /etc/issue | grep -Eqi "ubuntu"; then release="ubuntu" systemPackage="apt" elif cat /proc/version | grep -Eqi "debian"; then release="debian" systemPackage="apt" elif cat /proc/version | grep -Eqi "ubuntu"; then release="ubuntu" systemPackage="apt" else echo "错误: 不支持的系统,请使用Debian或Ubuntu系统!" exit 1 fi if [[ ${checkType} == "sysRelease" ]]; then if [ "$value" == "$release" ];then return 0 else return 1 fi elif [[ ${checkType} == "packageManager" ]]; then if [ "$value" == "$systemPackage" ];then return 0 else return 1 fi fi } rand(){ index=0 str="" for i in {a..z}; do arr[index]=${i}; index=`expr ${index} + 1`; done for i in {A..Z}; do arr[index]=${i}; index=`expr ${index} + 1`; done for i in {0..9}; do arr[index]=${i}; index=`expr ${index} + 1`; done for i in {1..10}; do str="$str${arr[$RANDOM%$index]}"; done echo ${str} } is_64bit(){ if [ `getconf WORD_BIT` = '32' ] && [ `getconf LONG_BIT` = '64' ] ; then return 0 else return 1 fi } versionget(){ if [ -f /etc/os-release ];then grep -oE "[0-9.]+" /etc/os-release | head -1 else grep -oE "[0-9.]+" /etc/issue fi } debianversion(){ if check_sys sysRelease debian;then local version=$( get_opsy ) local code=${1} local main_ver=$( echo ${version} | sed 's/[^0-9]//g') if [ "${main_ver}" == "${code}" ];then return 0 else return 1 fi else return 1 fi } version_check(){ if check_sys packageManager apt; then if debianversion 5; then echo "错误: Debian 5 不支持,请重新安装OS并重试。" exit 1 fi 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 } preinstall_l2tp(){ echo if [ -d "/proc/vz" ]; then echo -e "\033[41;37m 警告: \033[0m 您的VPS基于OpenVZ,内核可能不支持IPSec。" echo "是否继续安装? (y/n)" read -p "(默认: n)" agree [ -z ${agree} ] && agree="n" if [ "${agree}" == "n" ]; then echo echo "L2TP安装已取消。" echo exit 0 fi fi echo echo "请输入IP范围:" read -p "(默认范围: 192.168.18):" iprange [ -z ${iprange} ] && iprange="192.168.18" echo "请输入PSK密钥:" read -p "(默认PSK: admin123@l2tp):" mypsk [ -z ${mypsk} ] && mypsk="admin123@l2tp" echo "请输入用户名:" read -p "(默认用户名: admin123):" username [ -z ${username} ] && username="admin123" password=`rand` echo "请输入 ${username} 的密码:" read -p "(默认密码: ${password}):" tmppassword [ ! -z ${tmppassword} ] && password=${tmppassword} echo echo "服务器IP: ${IP}" echo "服务器本地IP: ${iprange}.1" echo "客户端远程IP范围: ${iprange}.2-${iprange}.254" echo "PSK密钥: ${mypsk}" echo echo "按任意键开始安装...或按Ctrl+C取消。" char=`get_char` } # 安装依赖 install_l2tp(){ mknod /dev/random c 1 9 apt -y update apt -yq install curl wget ppp xl2tpd libreswan config_install } config_install(){ cat > /etc/ipsec.conf< /etc/ipsec.secrets< /etc/xl2tpd/xl2tpd.conf< /etc/ppp/options.xl2tpd< /etc/ppp/chap-secrets<> /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 [ -f /etc/iptables.rules ] && cp -pf /etc/iptables.rules /etc/iptables.rules.old.`date +%Y%m%d` # 确保IP变量已正确获取 if [ -z "${IP}" ]; then IP=$(wget -qO- ipinfo.io/ip) fi cat > /etc/iptables.rules < /etc/rc.local < /proc/sys/net/ipv4/ip_forward /usr/sbin/service ipsec start /usr/sbin/service xl2tpd start /sbin/iptables-restore < /etc/iptables.rules exit 0 EOF chmod +x /etc/rc.local else # 如果已存在rc.local,则追加内容 sed -i '/^exit 0/d' /etc/rc.local cat >> /etc/rc.local < /proc/sys/net/ipv4/ip_forward /usr/sbin/service ipsec start /usr/sbin/service xl2tpd start /sbin/iptables-restore < /etc/iptables.rules exit 0 EOF fi cat > /etc/network/if-up.d/iptables < /var/tmp/libreswan-nss-pwd certutil -N -f /var/tmp/libreswan-nss-pwd -d /etc/ipsec.d rm -f /var/tmp/libreswan-nss-pwd fi update-rc.d -f xl2tpd defaults # 启用并启动服务 systemctl enable ipsec systemctl enable xl2tpd echo 1 > /proc/sys/net/ipv4/ip_forward /sbin/iptables-restore < /etc/iptables.rules systemctl restart ipsec systemctl restart xl2tpd } finally(){ cp -f ${cur_dir}/l2tp.sh /usr/bin/l2tp 2>/dev/null || true echo "请稍候..." sleep 3 ipsec verify echo echo "###############################################################" echo "# L2TP 安装脚本 #" echo "###############################################################" echo echo "默认用户名和密码如下:" echo echo "服务器IP: ${IP}" echo "PSK密钥 : ${mypsk}" echo "用户名 : ${username}" echo "密码 : ${password}" echo echo "如果您想修改用户设置,请使用以下命令:" echo "-a (添加用户)" echo "-d (删除用户)" echo "-l (列出所有用户)" echo "-m (修改用户密码)" echo } l2tp(){ clear echo echo "###############################################################" echo "# L2TP 安装脚本 #" echo "###############################################################" echo rootness tunavailable disable_selinux version_check get_os_info preinstall_l2tp install_l2tp finally } list_users(){ if [ ! -f /etc/ppp/chap-secrets ];then echo "错误: /etc/ppp/chap-secrets 文件未找到." exit 1 fi local line="+-------------------------------------------+\n" local string=%20s printf "${line}|${string} |${string} |\n${line}" 用户名 密码 grep -v "^#" /etc/ppp/chap-secrets | awk '{printf "|'${string}' |'${string}' |\n", $1,$3}' printf ${line} } add_user(){ while : do read -p "请输入用户名:" user if [ -z ${user} ]; then echo "用户名不能为空" else grep -w "${user}" /etc/ppp/chap-secrets > /dev/null 2>&1 if [ $? -eq 0 ];then echo "用户名 (${user}) 已存在。请重新输入用户名。" else break fi fi done pass=`rand` echo "请输入 ${user} 的密码:" read -p "(默认密码: ${pass}):" tmppass [ ! -z ${tmppass} ] && pass=${tmppass} echo "${user} l2tpd ${pass} *" >> /etc/ppp/chap-secrets echo "用户 (${user}) 添加完成。" } del_user(){ while : do read -p "请输入要删除的用户名:" user if [ -z ${user} ]; then echo "用户名不能为空" else grep -w "${user}" /etc/ppp/chap-secrets >/dev/null 2>&1 if [ $? -eq 0 ];then break else echo "用户名 (${user}) 不存在。请重新输入用户名。" fi fi done sed -i "/^\<${user}\>/d" /etc/ppp/chap-secrets echo "用户 (${user}) 删除完成。" } mod_user(){ while : do read -p "请输入要修改密码的用户名:" user if [ -z ${user} ]; then echo "用户名不能为空" else grep -w "${user}" /etc/ppp/chap-secrets >/dev/null 2>&1 if [ $? -eq 0 ];then break else echo "用户名 (${user}) 不存在。请重新输入用户名。" fi fi done pass=`rand` echo "请输入 ${user} 的新密码:" read -p "(默认密码: ${pass}):" tmppass [ ! -z ${tmppass} ] && pass=${tmppass} sed -i "/^\<${user}\>/d" /etc/ppp/chap-secrets echo "${user} l2tpd ${pass} *" >> /etc/ppp/chap-secrets echo "用户 ${user} 的密码已更改。" } # 主程序 action=$1 if [ -z ${action} ] && [ "`basename $0`" != "l2tp" ]; then action=install fi case ${action} in install) l2tp 2>&1 | tee ${cur_dir}/l2tp.log ;; -l|--list) list_users ;; -a|--add) add_user ;; -d|--del) del_user ;; -m|--mod) mod_user ;; -h|--help) echo "用法: -l,--list 列出所有用户" echo " -a,--add 添加用户" echo " -d,--del 删除用户" echo " -m,--mod 修改用户密码" echo " -h,--help 打印此帮助信息" ;; *) echo "用法: [-l,--查看用户|-a,--添加用户|-d,--删除用户|-m,--修改密码|-h,--帮助信息]" && exit ;; esac