#!/bin/sh
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH

# root privilege is mandatory
if [ $(id -u) -ne 0 ]; then
  echo "Error: You must get root privilege at first."
  exit 1
fi

clear                                                                                           
echo ""
echo -e "\033[7m"
echo "+---------------------------------------------------------------------+"    
echo "+                                                                     +"    
echo "+          PPTP/L2TP/OPENVPN + Freeradius package             +"
echo "+                                                                     +"    
echo "+          Author: Palfans (palfans@gmail.com)                        +"    
echo "+          Platform: CentOS 5.5(x86_64)                               +"    
echo "+                                                                     +"    
echo "+---------------------------------------------------------------------+"
echo -e "\033[0m"
echo

# set the source url
platform=`uname -i`
if [ "$platform" = "unknown" ]; then
  platform="i386"
fi

# set server type, 1-XEN, 2-OPENVZ, 0-Init
server_type="0"
option="0"

url_epel="http://dl.fedoraproject.org/pub/epel/5/$platform/epel-release-5-4.noarch.rpm"
url_webtatic="http://repo.webtatic.com/yum/centos/5/$platform/webtatic-release-5-1.noarch.rpm"
url_pptpd="http://sourceforge.net/projects/poptop/files/pptpd/pptpd-1.3.4/pptpd-1.3.4.tar.gz"
url_openswan="http://ftp.openswan.org/openswan/openswan-2.6.24.tar.gz"
url_radiusplugin="http://www.nongnu.org/radiusplugin/radiusplugin_v2.1_beta9.tar.gz"
url_install="http://20ne.com/vpn/install.tar.gz"
url_lnmp="http://soft.vpser.net/lnmp/lnmp0.9-full.tar.gz"

# set clients ip address
# pptp, local_ip is the server ip, remote_id is the range of client
p_local_ip="192.168.77.1"
p_remote_ip="192.168.77.100-200"

#openvpn, local_ip is the client ip subnet
o_local_ip="192.168.88.0"

# l2tp, local_ip is the server ip, remote_id is the range of client
l_local_ip="192.168.99.1"
l_remote_ip="192.168.99.100-192.168.99.200"

# parameters
wd=`pwd`
wd_work=$wd/work
server_ip=`ifconfig  | grep 'inet addr:'| grep -v '127.0.0.1' | cut -d: -f2 | awk 'NR==1 { print $1}'`
mysql_root_pwd="123456"
mysql_radius_pwd="123456"

# secret key is used to replace all the secret keys
secret_key="palfans"

# dir path
#nginx_html="/usr/share/nginx/html"
radius_dir="/etc/raddb"
etc_dir="/usr/local/etc"
sbin_dir="/usr/sbin"

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
}

init()
{
  echo ""
  echo "Please input server ip:"
  read -p "(Default ip: $server_ip):" temp
  if [ "$temp" != "" ]; then
    server_ip=$temp
  fi
  echo ""
  echo "Please input the root password of Mysql:"
  read -p "(Default password: $mysql_root_pwd):" temp
  if [ "$temp" != "" ]; then
    mysql_root_pwd=$temp
  fi
  echo ""
  echo "Please input the radius password of Mysql:"
  read -p "(Default password: $mysql_radius_pwd):" temp
  if [ "$temp" != "" ]; then
    mysql_radius_pwd=$temp
  fi
  echo ""
  echo "Please input the work directory:"
  read -p "(Current directory: $wd):" temp
  if [ "$temp" != "" ]; then
    wd=$temp
  fi
  wd_work=$wd/work
  mkdir -p $wd_work
  
  echo ""
  echo -e "\033[5mPress any key to continue...\033[0m"
  get_char
  clear
}

check_source()
{
  echo "checking $1"
  httpvalue=`wget -nv --spider $1 2>&1|sed q|awk '{print $1}'`
  if [ -z $httpvalue ]; then
    echo "OK!"
  elif [ "$httpvalue" = "200" ]; then
  	echo "OK!"
  else
    echo "NOT accessible, please check"
    exit
  fi
}

install_freeradius()
{
  echo "+--------------------------------------+"
  echo "+         install freeradius           +"
  echo "+--------------------------------------+"
  ret=`rpm -qa|grep freeradius|wc -l`
  if [ "$ret" = "0" ]; then
    cd $wd_work
    yum install -y freeradius2 freeradius2-mysql freeradius2-krb5 freeradius2-utils freeradius2-python libgcrypt-devel
    
    sed -i -e "s/testing123/$secret_key/g" $radius_dir/clients.conf
    sed -i -e "s/radpass/$mysql_radius_pwd/" $radius_dir/sql/mysql/admin.sql
    sed -i -e "s/localhost/127.0.0.1/" $radius_dir/sql/mysql/admin.sql
    sed -i -e "s/radpass/$mysql_radius_pwd/" $radius_dir/sql.conf
    sed -i -e 's/server = "localhost"/server = "127.0.0.1"/' $radius_dir/sql.conf
    sed -i -e 's/^#[ \t]$INCLUDE *sql.conf$/$INCLUDE sql.conf/' $radius_dir/radiusd.conf
    sed -i -e 's/^#[ \t]*sql$/sql/' $radius_dir/sites-available/default
    echo "create database radius;" | mysql --user=root --password=$mysql_root_pwd
    mysql --user=root --password=$mysql_root_pwd < $radius_dir/sql/mysql/admin.sql
    mysql --user=root --password=$mysql_root_pwd radius < $radius_dir/sql/mysql/schema.sql
    mysql --user=root --password=$mysql_root_pwd radius < $radius_dir/sql/mysql/ippool.sql
    mysql --user=root --password=$mysql_root_pwd radius < $radius_dir/sql/mysql/nas.sql
    mysql --user=root --password=$mysql_root_pwd radius < $radius_dir/sql/mysql/cui.sql
    mysql --user=root --password=$mysql_root_pwd radius < $radius_dir/sql/mysql/wimax.sql

cat > $wd_work/w.sql <<EOF
INSERT INTO radcheck (id, username, attribute, op, value) VALUES (1, 'test', 'Cleartext-Password', ':=', '1234');
EOF

cat >> $radius_dir/dictionary <<EOF
ATTRIBUTE      Max-Monthly-Traffic     3003    integer
ATTRIBUTE      Monthly-Traffic-Limit   3004    integer
EOF

    mysql --user=root --password=$mysql_root_pwd radius < $wd_work/w.sql
    
    radiusd -X &
    sleep 30
    chkconfig radiusd on
    service radiusd restart
  fi
}

install_pptp()
{
  echo "+--------------------------------------+"
  echo "+          install pptp                +"
  echo "+--------------------------------------+"
  ret=`rpm -qa|grep pptpd|wc -l`
  if [ "$ret" = "0" ]; then
    cd $wd_work
    yum install -y ppp
    
    pptpd_name=`basename $url_pptpd`
    if [ -s $pptpd_name ]; then
      echo "$pptpd_name [Found]"
    else
      wget -c $url_pptpd
    fi
    
    rpmbuild -ta $wd_work/$pptpd_name
    rpm -ivh /usr/src/redhat/RPMS/$platform/`basename $pptpd_name .tar.gz`*.rpm
    sed -i -e 's/logwtmp/#logwtmp/' /etc/pptpd.conf
  
cat >>/etc/pptpd.conf<<EOF
localip $p_local_ip
remoteip $p_remote_ip
EOF
  
    echo "+--------------------------------------+"
    echo "+    install radiusclient for pptp     +"
    echo "+--------------------------------------+"
    
    etc_dir_t=$(echo "$etc_dir" | sed 's/\//\\\//g')
    sbin_dir_t=$(echo "$sbin_dir" | sed 's/\//\\\//g')
    cp -R $wd_work/radiusclient $etc_dir/radiusclient
    cp -f $etc_dir/radiusclient/radiusclient.conf.in $etc_dir/radiusclient/radiusclient.conf
    sed -i -e "s/@etcdir@/$etc_dir_t/" $etc_dir/radiusclient/radiusclient.conf
    sed -i -e "s/@etcdir@/$etc_dir_t/" $etc_dir/radiusclient/dictionary
    sed -i -e "s/@sbindir@/$sbin_dir_t/" $etc_dir/radiusclient/radiusclient.conf
  
cat >> $etc_dir/radiusclient/servers<<EOF
127.0.0.1 $secret_key
EOF

    sed -i -e 's/^#ms-dns 10.0.0.1$/ms-dns 8.8.8.8/' /etc/ppp/options.pptpd
    sed -i -e 's/^#ms-dns 10.0.0.2$/ms-dns 8.8.4.4/' /etc/ppp/options.pptpd
    radius_so=`find /usr -name radius.so`
  
cat >> /etc/ppp/options.pptpd <<EOF
plugin $radius_so
radius-config-file $etc_dir/radiusclient/radiusclient.conf
EOF
  
    chkconfig pptpd on
    service pptpd restart
  fi
}

install_openvpn()
{
  echo "+--------------------------------------+"
  echo "+          install openvpn             +"
  echo "+--------------------------------------+"
  ret=`rpm -qa|grep openvpn|wc -l`
  if [ "$ret" = "0" ]; then
    cd $wd_work
    yum install -y openvpn
    
    key_path=$wd/openvpn/easy-rsa/keys
    key_path=$(echo "$key_path" | sed 's/\//\\\//g')
    mkdir $wd/openvpn
    cp -R /usr/share/openvpn/easy-rsa/2.0 $wd/openvpn/easy-rsa
    cp -f $wd_work/openvpn-server.conf /etc/openvpn/server.conf
    sed -i -e "s/key_path/$key_path/g" /etc/openvpn/server.conf
    sed -i -e "s/@server_ip@/$o_local_ip/g" /etc/openvpn/server.conf
    cp -f $wd_work/vars $wd/openvpn/easy-rsa
    cd $wd/openvpn/easy-rsa
    . ./vars
    ./clean-all --batch
    ./build-ca --batch
    ./build-key-server --batch server
    ./build-dh --batch
    
    cp -f keys/*.crt /etc/openvpn/
    cp -f keys/server.key /etc/openvpn/
    cp -f keys/dh1024.pem /etc/openvpn/
    
    cd $wd/openvpn
    mkdir client
    cd $wd
    cp -f $wd_work/openvpn-client.ovpn $wd/openvpn/client/client.ovpn
    sed -i -e "s/server_ip/$server_ip/g" $wd/openvpn/client/client.ovpn
    cp -f $wd/openvpn/easy-rsa/keys/ca.crt $wd/openvpn/client/
    
    echo "+--------------------------------------+"
    echo "+   install radiusplugin for openvpn   +"
    echo "+--------------------------------------+"
    cd $wd_work
    
    radiusplugin_name=`basename $url_radiusplugin`
    if [ -s $radiusplugin_name ]; then
      echo "$radiusplugin_name [Found]"
    else
      wget -c $url_radiusplugin
    fi
    
    tar xf $radiusplugin_name
    cd radiusplugin
    make
    cp radiusplugin.so /etc/openvpn/
    sed -i -e "s/sharedsecret=testpw/sharedsecret=$secret_key/" radiusplugin.cnf
    cp radiusplugin.cnf /etc/openvpn/
    
    chkconfig openvpn on
    service openvpn restart
  fi
}

install_l2tp()
{
  echo "+--------------------------------------+"
  echo "+          install openswan            +"
  echo "+--------------------------------------+"
  ret=`rpm -qa|grep openswan|wc -l`
  if [ "$ret" = "0" ]; then
    cd $wd_work
    
    openswan_name=`basename $url_openswan`
    if [ -s $openswan_name ]; then
      echo "$openswan_name [Found]"
    else
      wget -c $url_openswan
    fi
    
    tar xzvf $openswan_name
    openswan_dir=`basename $url_openswan .tar.gz`
    cd $openswan_dir
    make programs install

cat > /etc/ipsec.conf <<EOF
version 2.0
config setup
    nat_traversal=yes
    virtual_private=%v4:10.0.0.0/8,%v4:192.168.0.0/16,%v4:172.16.0.0/12
    oe=off
    protostack=netkey
include /etc/ipsec.d/l2tp.conf
include /etc/ipsec.d/no_oe.conf
EOF

    cp -f $wd_work/l2tp.conf /etc/ipsec.d/l2tp.conf
    cp -f $wd_work/no_oe.conf /etc/ipsec.d/no_oe.conf
    sed -i -e "s/@server_ip@/$server_ip/g" /etc/ipsec.d/l2tp.conf

cat >> /etc/ipsec.secrets <<EOF
$server_ip  %any:  PSK  "$secret_key"
EOF

    chkconfig ipsec on
    service ipsec restart
    ipsec verify
    
    echo "+--------------------------------------+"
    echo "+          install xl2tp               +"
    echo "+--------------------------------------+"
    ret=`rpm -qa|grep xl2tpd|wc -l`
    if [ "$ret" = "0" ]; then
      yum install -y xl2tpd
    fi
    
    mv /etc/xl2tpd/xl2tpd.conf /etc/xl2tpd/xl2tpd.conf.ori
  
cat > /etc/xl2tpd/xl2tpd.conf <<EOF
[global]
listen-addr = $server_ip
ipsec saref = yes

[lns default]
ip range = $l_remote_ip
local ip = $l_local_ip
refuse chap = yes
refuse pap = yes
require authentication = yes
name = l2tpd
ppp debug = yes
pppoptfile = /etc/ppp/options.xl2tpd
length bit = yes
EOF

cat > /etc/ppp/options.xl2tpd <<EOF
ipcp-accept-local
ipcp-accept-remote
ms-dns 8.8.8.8
ms-dns 8.8.4.4
asyncmap 0
auth
crtscts
lock
hide-password
modem
debug
proxyarp
lcp-echo-interval 30
lcp-echo-failure 4
EOF

    radius_so=`find /usr -name radius.so`
  
cat >> /etc/ppp/options.xl2tpd <<EOF
plugin $radius_so
radius-config-file $etc_dir/radiusclient/radiusclient.conf
EOF


    chkconfig xl2tpd on
    service xl2tpd restart
  fi
}

set_iptables()
{
  echo "+--------------------------------------+"
  echo "+          iptables setting            +"
  echo "+--------------------------------------+"
  ret=`rpm -qa|grep iptables|wc -l`
  if [ "$ret" = "0" ]; then
    yum install -y iptables
  fi
  
  sed -i "s/net.ipv4.ip_forward = 0/net.ipv4.ip_forward = 1/g" /etc/sysctl.conf

cat >> /etc/sysctl.conf <<EOF
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
EOF

  sysctl -p
  
  iptables -A INPUT -i tun+ -j ACCEPT
  iptables -A FORWARD -i tun+ -j ACCEPT
  iptables -A INPUT -i tap+ -j ACCEPT
  iptables -A FORWARD -i tap+ -j ACCEPT
  iptables -A INPUT -p udp -d $server_ip --dport 500 -j ACCEPT
  iptables -A INPUT -p udp -d $server_ip --dport 4500 -j ACCEPT
  iptables -A INPUT -p udp -d $server_ip --dport 1701 -j ACCEPT
  if [ "$server_type" = "1" ]; then
    if [ "$option" = "1" ]; then
      iptables -t nat -A POSTROUTING -s 192.168.77.0/24 -j MASQUERADE -o eth0
    elif [ "$option" = "2" ]; then
      iptables -t nat -A POSTROUTING -s 192.168.88.0/24 -j MASQUERADE -o eth0
    elif [ "$option" = "3" ]; then
      iptables -t nat -A POSTROUTING -s 192.168.77.0/24 -j MASQUERADE -o eth0
      iptables -t nat -A POSTROUTING -s 192.168.88.0/24 -j MASQUERADE -o eth0
    elif [ "$option" = "4" ]; then
      iptables -t nat -A POSTROUTING -s 192.168.77.0/24 -j MASQUERADE -o eth0
      iptables -t nat -A POSTROUTING -s 192.168.99.0/24 -j MASQUERADE -o eth0
    elif [ "$option" = "5" ]; then
      iptables -t nat -A POSTROUTING -s 192.168.77.0/24 -j MASQUERADE -o eth0
      iptables -t nat -A POSTROUTING -s 192.168.88.0/24 -j MASQUERADE -o eth0
      iptables -t nat -A POSTROUTING -s 192.168.99.0/24 -j MASQUERADE -o eth0
    fi
  elif [ "$server_type" = "2" ]; then
    if [ "$option" = "1" ]; then
      iptables -t nat -A POSTROUTING -s 192.168.77.0/24 -j SNAT --to-source $server_ip
    elif [ "$option" = "2" ]; then
      iptables -t nat -A POSTROUTING -s 192.168.88.0/24 -j SNAT --to-source $server_ip
    elif [ "$option" = "3" ]; then
      iptables -t nat -A POSTROUTING -s 192.168.77.0/24 -j SNAT --to-source $server_ip
      iptables -t nat -A POSTROUTING -s 192.168.88.0/24 -j SNAT --to-source $server_ip
    fi
  fi
  iptables -t nat -A PREROUTING -p udp --dport 53 -j DNAT --to-destination 8.8.8.8
  iptables -t nat -A PREROUTING -p udp --dport 53 -j DNAT --to-destination 8.8.4.4
  
  service iptables save

  for each in /proc/sys/net/ipv4/conf/*
  do
    echo 0 > $each/accept_redirects
    echo 0 > $each/send_redirects
  done
  service iptables restart
}

check_status()
{
  if [ $# -eq 1 ]; then
    ret=`ps -ef|grep $1|grep -v grep|wc -l`
    if [ "$ret" = "0" ]; then
      echo -e "$1\t\t\t[\033[31;5;1m Failed \033[0m]"
    else
      echo -e "$1\t\t\t[\033[1m OK \033[0m]"
    fi
  fi
  
  if [ $# -eq 2 ]; then
    ret=`ps -ef|grep $1|grep $2|grep -v grep|wc -l`
    if [ "$ret" = "0" ]; then
      echo -e "$1($2)\t\t\t[\033[31;5;1m Failed \033[0m]"
    else
      echo -e "$1($2)\t\t\t[\033[1m OK \033[0m]"
    fi
  fi
}

usage()
{
	option="0"
	server_type="0"
	echo ""
	echo "Which type is your VPS? -- Please note: L2TP(IPSEC) couldn't be installed on openvz."
	echo "1. xen"
	echo "2. openvz"
	read -p "(Default type: $server_type):" temp
	if [ "$temp" != "" ]; then
    server_type=$temp
  fi
	echo ""
	echo "Now you can intall vpn software as below:"
  if [ "$server_type" = "1" ]; then
    option="5"
    echo "1.  pptp"
    echo "2.  openvpn"
    echo "3.  pptp+openvpn"
    echo "4.  pptp+l2tp"
    echo "5.  pptp+openvpn+l2tp"
  elif [ "$server_type" = "2" ]; then
  	option="3"
    echo "1.  pptp"
    echo "2.  openvpn"
    echo "3.  pptp+openvpn"
  fi
  echo ""
  echo "Please input your option:"
  read -p "(Default option: $option):" temp
  if [ "$temp" != "" ]; then
    option=$temp
  fi
}

base_setup()
{
  install_freeradius
  set_iptables
  check_status radius
}

while [ 1 ] 
do
  usage
  if [ "$server_type" = "1" -a "$option" -le "5" ]; then
    break
  elif [ "$server_type" = "2" -a "$option" -le "3" ]; then
    break
  fi
done

echo "+--------------------------------------+"
echo "+    check accessibility of source     +"
echo "+--------------------------------------+"
check_source $url_epel
check_source $url_webtatic
check_source $url_install
check_source $url_pptpd
check_source $url_openswan
check_source $url_radiusplugin
check_source $url_lnmp

rpm -Uvh $url_epel
rpm -Uvh $url_webtatic

echo "+--------------------------------------+"
echo "+    Update source list and init       +"
echo "+--------------------------------------+"
#yum update -y
yum install -y gcc gcc-c++ rpm-build vim-enhanced lsof make crypt* libgcrypt* gmp-devel bison flex
cp /usr/bin/vim /usr/bin/vi
echo "set nu" >> /etc/vimrc
init

cd $wd_work

installLNMP="y"
echo ""
echo "PHP and MySQL should be installed at first. Do you want to install LNMP package?"
read -p "(y: install(default); n: don't install; q: quit):" installLNMP

case $installLNMP in
n|N)
echo "LNMP will not be installed."
;;
q|Q)
echo "Installation is terminated."
exit 1
;;
*)
echo "Installation will be installed."
lnmp_name=`basename $url_lnmp`
if [ -s $lnmp_name ]; then
  echo "$lnmp_name [Found]"
else
  wget -c $url_lnmp
fi
tar xzvf $lnmp_name
lnmp_dir=`basename $url_lnmp .tar.gz`
cd $lnmp_dir
$wd_work/$lnmp_dir/centos.sh
esac

cd $wd_work
install_name=`basename $url_install`
if [ -s $install_name ]; then
  echo "$install_name [Found]"
else
  wget -c $url_install
fi

tar xzvf $install_name

base_setup

if [ "$option" = "1" ]; then
  install_pptp
  check_status pptpd
fi

if [ "$option" = "2" ]; then
  install_openvpn
  check_status openvpn
fi

if [ "$option" = "3" ]; then
  install_pptp
  install_openvpn
  check_status pptpd
  check_status openvpn
fi

if [ "$option" = "4" ]; then
  install_pptp
  install_l2tp
  check_status pptpd
  check_status ipsec
  check_status xl2tpd
fi

if [ "$option" = "5" ]; then
  install_openvpn
  install_pptp
  install_l2tp
  check_status pptpd
  check_status openvpn
  check_status ipsec
  check_status xl2tpd
fi
