File: /volume1/@appstore/VPNCenter/scripts/openvpn.sh
#!/bin/sh
#
# Startup script for openvpn server
#
PKG_USERCONF_DIR="/usr/syno/etc/packages/VPNCenter"
CONF_DIR="${PKG_USERCONF_DIR}/openvpn"
USER_CONF="openvpn.conf.user"
USER_CONF_TMP_FILE="/tmp/run.openvpn.conf.user"
OPENVPN_CONF="openvpn.conf"
PKG_TARGET="/var/packages/VPNCenter/target"
IPTABLES_MODULE_LIST="/usr/syno/etc.defaults/iptables_modules_list"
OPENVPN_MODULES="tun.ko"
SERVICE="openvpn"
BIN_IPTABLESTOOL="/usr/syno/bin/iptablestool"
BIN_SYNOMODULETOOL="/usr/syno/bin/synomoduletool"
OPENSSL="/bin/openssl-3"
PYTHON="/bin/python3"
OPENVPN_DHKEY_GENERATING_FILE="/var/packages/VPNCenter/tmp/.openvpn.dhkey.generating"
reverse_modules() {
local modules=$1
local mod
local ret=""
for mod in $modules; do
ret="$mod $ret"
done
echo $ret
}
if [ -e ${CONF_DIR}/${USER_CONF} ]; then
OPENVPN_CONF=${USER_CONF}
fi
Ovpn_Mod=""
if [ -f "${IPTABLES_MODULE_LIST}" ]; then
. ${IPTABLES_MODULE_LIST}
for mod in $OPENVPN_MODULES; do
if [ -e "/lib/modules/$mod" ]; then
Ovpn_Mod="${Ovpn_Mod} ${mod}"
fi
done
for mod in $KERNEL_MODULES_CORE; do
if [ -e "/lib/modules/$mod" ]; then
Ovpn_Mod="${Ovpn_Mod} ${mod}"
fi
done
for mod in $KERNEL_MODULES_COMMON; do
if [ -e "/lib/modules/$mod" ]; then
Ovpn_Mod="${Ovpn_Mod} ${mod}"
fi
done
for mod in $KERNEL_MODULES_NAT; do
if [ -e "/lib/modules/$mod" ]; then
Ovpn_Mod="${Ovpn_Mod} ${mod}"
fi
done
for mod in $IPV6_MODULES; do
if [ -e "/lib/modules/$mod" ]; then
Ovpn_Mod="${Ovpn_Mod} ${mod}"
fi
done
else
. ${PKG_TARGET}/scripts/vpn_modules.sh
for mod in $OVPN_MODULES; do
if [ -e "/lib/modules/$mod" ]; then
Ovpn_Mod="${Ovpn_Mod} ${mod}"
fi
done
fi
SYNOVPN_CONF="${PKG_USERCONF_DIR}/synovpn.conf"
VPNC_CURRENT="/tmp/vpnc_current"
LOCALIP=`grep "^server " ${CONF_DIR}/${OPENVPN_CONF} | cut -d' ' -f 2`
LOCALPORT=`grep "^port " ${CONF_DIR}/${OPENVPN_CONF} | cut -d' ' -f 2`
LOCALPROTO=`grep "^proto " ${CONF_DIR}/${OPENVPN_CONF} | cut -d' ' -f 2`
modify_push_route () {
local vpnifname=`/bin/get_key_value ${SYNOVPN_CONF} vpninterface`
local ServerInfo=`/bin/cat ${CONF_DIR}/${OPENVPN_CONF} | /bin/grep ^server | /usr/bin/awk '{ print $2 }'`
local OldRoute=`/bin/grep push ${CONF_DIR}/${OPENVPN_CONF} | /bin/grep -v ${ServerInfo}`
local CurIP=`/sbin/ip addr show ${vpnifname} | /bin/grep "inet" | /bin/grep -v "inet6" | head -n 1 | /usr/bin/awk '{ print $2 }'`
local NewNet=`/bin/ipcalc -n ${CurIP} | /usr/bin/cut -d= -f 2`
local NewMask=`/bin/ipcalc -m ${CurIP} | /usr/bin/cut -d= -f 2`
local NewRoute="push \"route ${NewNet} ${NewMask}\""
if [ -n "${OldRoute}" -a -n "${NewRoute}" ]; then
/bin/sed -i "s/${OldRoute}/${NewRoute}/g" ${CONF_DIR}/${OPENVPN_CONF} > /dev/null 2>&1
fi
}
add_push_route_firewall() {
local enable_push_route=`/bin/get_key_value ${SYNOVPN_CONF} openvpn_push_route`
local vpnifname=`/bin/get_key_value ${SYNOVPN_CONF} vpninterface`
local CurIP=`/sbin/ip addr show ${vpnifname} | /bin/grep "inet" | /bin/grep -v "inet6" | head -n 1 | /usr/bin/awk '{ print $2 }'`
if [ "yes" != "${enable_push_route}" ]; then
iptables -I PPPOE_FORWARD -i tun0 -d ${CurIP} -j DROP
fi
}
delete_push_route_firewall() {
local enable_push_route=`/bin/get_key_value ${SYNOVPN_CONF} openvpn_push_route`
local vpnifname=`/bin/get_key_value ${SYNOVPN_CONF} vpninterface`
local CurIP=`/sbin/ip addr show ${vpnifname} | /bin/grep "inet" | /bin/grep -v "inet6" | head -n 1 | /usr/bin/awk '{ print $2 }'`
if [ "yes" != "${enable_push_route}" ]; then
iptables -D PPPOE_FORWARD -i tun0 -d ${CurIP} -j DROP
fi
}
start() {
local Run=`/bin/get_key_value ${SYNOVPN_CONF} runopenvpn`
if [ "yes" != "$Run" ]; then
exit 0;
fi
local RunningProto=`/bin/get_key_value ${VPNC_CURRENT} proto`
if [ "openvpn" = "$RunningProto" ]; then
echo "Already running"
exit 0;
fi
if [ "${LOCALPORT}" = "443" -a "${LOCALPROTO}" = "tcp6-server" ]; then
time=1
status=`/usr/syno/bin/synow3 --get-443`
if [ "${status}" = "nginx listens on port 443" ]; then
/usr/syno/bin/synow3 --set-443-off
fi
while true; do
/bin/sleep 1;
if [ "$time" -ge "15" ]; then
exit -1;
fi
time=$(($time + 1))
status=`netstat -anp | grep ':443' | grep nginx | wc -l`
if [ "$status" = "0" ]; then
break;
fi
echo "Wait for stop nginx";
done
fi
echo 1 > /proc/sys/net/ipv4/ip_forward
# Make device if not present (not devfs)
if ( [ ! -c /dev/net/tun ] ) then
# Make /dev/net directory if needed
if ( [ ! -d /dev/net ] ) then
mkdir -m 755 /dev/net
fi
mknod /dev/net/tun c 10 200
fi
if [ -x ${BIN_SYNOMODULETOOL} ]; then
$BIN_SYNOMODULETOOL --insmod $SERVICE ${Ovpn_Mod}
elif [ -x ${BIN_IPTABLESTOOL} ]; then
$BIN_IPTABLESTOOL --insmod $SERVICE ${Ovpn_Mod}
else
for i in x_tables.ko ip_tables.ko iptable_filter.ko nf_conntrack.ko \
nf_defrag_ipv4.ko nf_conntrack_ipv4.ko nf_nat.ko \
iptable_nat.ko ipt_REDIRECT.ko xt_multiport.ko xt_tcpudp.ko \
xt_state.ko ipt_MASQUERADE.ko tun.ko
do
/sbin/modprobe /lib/modules/$i
done
fi
# copy certificate : ca.crt, ca_bundle.crt, server.crt, and server.key of ssl
/bin/rm -f ${PKG_TARGET}/etc/openvpn/keys/ca.crt
/bin/rm -f ${PKG_TARGET}/etc/openvpn/keys/ca_bundle.crt
/bin/rm -f ${PKG_TARGET}/etc/openvpn/keys/server.crt
/bin/rm -f ${PKG_TARGET}/etc/openvpn/keys/server.key
/bin/rm -f ${PKG_TARGET}/etc/openvpn/keys/common_name
if [ -f ${PKG_USERCONF_DIR}/openvpn/keys/ca.crt ]; then
/bin/cp -f ${PKG_USERCONF_DIR}/openvpn/keys/ca.crt ${PKG_TARGET}/etc/openvpn/keys/
fi
if [ -f ${PKG_USERCONF_DIR}/openvpn/keys/ca_bundle.crt ]; then
/bin/cp -f ${PKG_USERCONF_DIR}/openvpn/keys/ca_bundle.crt ${PKG_TARGET}/etc/openvpn/keys/
fi
if [ -f ${PKG_USERCONF_DIR}/openvpn/keys/server.crt ]; then
/bin/cp -f ${PKG_USERCONF_DIR}/openvpn/keys/server.crt ${PKG_TARGET}/etc/openvpn/keys/
${OPENSSL} x509 -noout -in ${PKG_USERCONF_DIR}/openvpn/keys/server.crt -subject | awk -F= '{print $NF}'| tr -d ' ' > ${PKG_TARGET}/etc/openvpn/keys/common_name
fi
if [ -f ${PKG_USERCONF_DIR}/openvpn/keys/server.key ]; then
/bin/cp -f ${PKG_USERCONF_DIR}/openvpn/keys/server.key ${PKG_TARGET}/etc/openvpn/keys/
fi
if [ -f ${PKG_USERCONF_DIR}/openvpn/keys/ta.key ]; then
/bin/cp -f ${PKG_USERCONF_DIR}/openvpn/keys/ta.key ${PKG_TARGET}/etc/openvpn/keys/
fi
if [ -f "${PKG_USERCONF_DIR}/openvpn/keys/.dh3072.pem.finish" ] && [ -f "${PKG_USERCONF_DIR}/openvpn/keys/dh3072.pem.new" ]; then
/bin/cp -f ${PKG_USERCONF_DIR}/openvpn/keys/dh3072.pem.new ${PKG_TARGET}/etc/openvpn/keys/dh3072.pem
elif [ ! -f "${OPENVPN_DHKEY_GENERATING_FILE}" ]; then
touch ${OPENVPN_DHKEY_GENERATING_FILE}
${OPENSSL} dhparam -out ${PKG_USERCONF_DIR}/openvpn/keys/dh3072.pem.new 3072 && touch ${PKG_USERCONF_DIR}/openvpn/keys/.dh3072.pem.finish && synodsmnotify @administrators openvpn_renew_dh_key_done &
fi
# start radius server
${PKG_TARGET}/scripts/radiusd.sh start
modify_push_route
echo "Starting openvpn ..."
synosystemctl start pkg-VPNCenter-openvpn-server
add_push_route_firewall
/sbin/iptables -t nat -A POSTROUTING -s ${LOCALIP}/24 -j MASQUERADE
#touch a temp file for UI check
if [ ${OPENVPN_CONF} == ${USER_CONF} ]; then
/bin/touch ${USER_CONF_TMP_FILE} 2>/dev/null
elif [ -e ${USER_CONF_TMP_FILE} ]; then
/bin/rm -rf ${USER_CONF_TMP_FILE} 2>/dev/null
fi
}
stop() {
local Run=`/bin/get_key_value ${SYNOVPN_CONF} runopenvpn`
if [ "yes" != "$Run" ]; then
exit 0;
fi
local modules=`reverse_modules "${Ovpn_Mod}"`
/sbin/iptables -t nat -D POSTROUTING -s ${LOCALIP}/24 -j MASQUERADE
echo "Stopping openvpn ..."
synosystemctl stop pkg-VPNCenter-openvpn-server
delete_push_route_firewall
time=1
while true; do
/bin/sleep 1
if [ $time -ge 10 ]; then
break
fi
time=$(($time + 1))
if [ -d /proc/${OPENVPN_PID} ]; then
echo "Wait for stoping openvpn"
else
break
fi
done
if [ -x ${BIN_SYNOMODULETOOL} ]; then
$BIN_SYNOMODULETOOL --rmmod $SERVICE $modules
elif [ -x ${BIN_IPTABLESTOOL} ]; then
$BIN_IPTABLESTOOL --rmmod $SERVICE $modules
else
/sbin/rmmod tun
/sbin/rmmod ipt_MASQUERADE xt_state xt_tcpudp xt_multiport \
ipt_REDIRECT iptable_nat nf_nat nf_conntrack_ipv4 \
nf_defrag_ipv4 nf_conntrack iptable_filter ip_tables x_tables
fi
${PKG_TARGET}/scripts/radiusd.sh stop
#delete USER_CONF_TMP_FILE
if [ -e ${USER_CONF_TMP_FILE} ]; then
/bin/rm -rf ${USER_CONF_TMP_FILE} 2>/dev/null
fi
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
sh $0 stop quiet
sleep 3
sh $0 start
;;
disconnect)
while read i; do
${PYTHON} "$PKG_TARGET/scripts/openvpn.py" "$i" > /dev/null 2>&1
done < $2
;;
status)
${PYTHON} "$PKG_TARGET/scripts/openvpn.py" "`cat /tmp/ovpn_cmd_status_2`" > "/tmp/ovpn_status_2_result"
;;
*)
echo "Usage: $0 {start|stop|restart}"
exit 1
esac
exit 0
# [EOF]