Advertisement
Guest User

Untitled

a guest
Jan 23rd, 2019
525
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.66 KB | None | 0 0
  1. #!/bin/sh
  2. #
  3. # Script for automatic setup of an IPsec VPN server on CentOS/RHEL 6 and 7.
  4. # Works on any dedicated server or virtual private server (VPS) except OpenVZ.
  5. #
  6. # DO NOT RUN THIS SCRIPT ON YOUR PC OR MAC!
  7. #
  8. # The latest version of this script is available at:
  9. # https://github.com/hwdsl2/setup-ipsec-vpn
  10. #
  11. # Copyright (C) 2015-2017 Lin Song <linsongui@gmail.com>
  12. # Based on the work of Thomas Sarlandie (Copyright 2012)
  13. #
  14. # This work is licensed under the Creative Commons Attribution-ShareAlike 3.0
  15. # Unported License: http://creativecommons.org/licenses/by-sa/3.0/
  16. #
  17. # Attribution required: please include my name in any derivative and let me
  18. # know how you have improved it!
  19.  
  20. # =====================================================
  21.  
  22. # Define your own values for these variables
  23. # - IPsec pre-shared key, VPN username and password
  24. # - All values MUST be placed inside 'single quotes'
  25. # - DO NOT use these special characters within values: \ " '
  26.  
  27. YOUR_IPSEC_PSK=''
  28. YOUR_USERNAME=''
  29. YOUR_PASSWORD=''
  30.  
  31. # Important notes: https://git.io/vpnnotes
  32. # Setup VPN clients: https://git.io/vpnclients
  33.  
  34. # =====================================================
  35.  
  36. export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
  37. SYS_DT="$(date +%F-%T)"
  38.  
  39. exiterr() { echo "Error: $1" >&2; exit 1; }
  40. exiterr2() { exiterr "'yum install' failed."; }
  41. conf_bk() { /bin/cp -f "$1" "$1.old-$SYS_DT" 2>/dev/null; }
  42. bigecho() { echo; echo "## $1"; echo; }
  43.  
  44. check_ip() {
  45. IP_REGEX='^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$'
  46. printf '%s' "$1" | tr -d '\n' | grep -Eq "$IP_REGEX"
  47. }
  48.  
  49. vpnsetup() {
  50.  
  51. if ! grep -qs -e "release 6" -e "release 7" /etc/redhat-release; then
  52. exiterr "This script only supports CentOS/RHEL 6 and 7."
  53. fi
  54.  
  55. if [ -f /proc/user_beancounters ]; then
  56. exiterr "OpenVZ VPS is not supported. Try OpenVPN: github.com/Nyr/openvpn-install"
  57. fi
  58.  
  59. if [ "$(id -u)" != 0 ]; then
  60. exiterr "Script must be run as root. Try 'sudo sh $0'"
  61. fi
  62.  
  63. net_iface=${VPN_NET_IFACE:-'eth0'}
  64. def_iface="$(route 2>/dev/null | grep '^default' | grep -o '[^ ]*$')"
  65. [ -z "$def_iface" ] && def_iface="$(ip -4 route list 0/0 2>/dev/null | grep -Po '(?<=dev )(\S+)')"
  66.  
  67. def_iface_state=$(cat "/sys/class/net/$def_iface/operstate" 2>/dev/null)
  68. if [ -n "$def_iface_state" ] && [ "$def_iface_state" != "down" ]; then
  69. case "$def_iface" in
  70. wl*)
  71. exiterr "Wireless interface '$def_iface' detected. DO NOT run this script on your PC or Mac!"
  72. ;;
  73. esac
  74. net_iface="$def_iface"
  75. fi
  76.  
  77. net_iface_state=$(cat "/sys/class/net/$net_iface/operstate" 2>/dev/null)
  78. if [ -z "$net_iface_state" ] || [ "$net_iface_state" = "down" ] || [ "$net_iface" = "lo" ]; then
  79. printf "Error: Network interface '%s' is not available.\n" "$net_iface" >&2
  80. if [ -z "$VPN_NET_IFACE" ]; then
  81. cat 1>&2 <<EOF
  82. Unable to detect the default network interface. Manually re-run this script with:
  83. sudo VPN_NET_IFACE="your_default_interface_name" sh "$0"
  84. EOF
  85. fi
  86. exit 1
  87. fi
  88.  
  89. [ -n "$YOUR_IPSEC_PSK" ] && VPN_IPSEC_PSK="$YOUR_IPSEC_PSK"
  90. [ -n "$YOUR_USERNAME" ] && VPN_USER="$YOUR_USERNAME"
  91. [ -n "$YOUR_PASSWORD" ] && VPN_PASSWORD="$YOUR_PASSWORD"
  92.  
  93. if [ -z "$VPN_IPSEC_PSK" ] && [ -z "$VPN_USER" ] && [ -z "$VPN_PASSWORD" ]; then
  94. bigecho "VPN credentials not set by user. Generating random PSK and password..."
  95. VPN_IPSEC_PSK="$(LC_CTYPE=C tr -dc 'A-HJ-NPR-Za-km-z2-9' < /dev/urandom | head -c 16)"
  96. VPN_USER=vpnuser
  97. VPN_PASSWORD="$(LC_CTYPE=C tr -dc 'A-HJ-NPR-Za-km-z2-9' < /dev/urandom | head -c 16)"
  98. fi
  99.  
  100. if [ -z "$VPN_IPSEC_PSK" ] || [ -z "$VPN_USER" ] || [ -z "$VPN_PASSWORD" ]; then
  101. exiterr "All VPN credentials must be specified. Edit the script and re-enter them."
  102. fi
  103.  
  104. if printf '%s' "$VPN_IPSEC_PSK $VPN_USER $VPN_PASSWORD" | LC_ALL=C grep -q '[^ -~]\+'; then
  105. exiterr "VPN credentials must not contain non-ASCII characters."
  106. fi
  107.  
  108. case "$VPN_IPSEC_PSK $VPN_USER $VPN_PASSWORD" in
  109. *[\\\"\']*)
  110. exiterr "VPN credentials must not contain these special characters: \\ \" '"
  111. ;;
  112. esac
  113.  
  114. bigecho "VPN setup in progress... Please be patient."
  115.  
  116. # Create and change to working dir
  117. mkdir -p /opt/src
  118. cd /opt/src || exiterr "Cannot enter /opt/src."
  119.  
  120. bigecho "Installing packages required for setup..."
  121.  
  122. yum -y install wget bind-utils openssl \
  123. iproute gawk grep sed net-tools || exiterr2
  124.  
  125. bigecho "Trying to auto discover IP of this server..."
  126.  
  127. cat <<'EOF'
  128. In case the script hangs here for more than a few minutes,
  129. press Ctrl-C to abort. Then edit it and manually enter IP.
  130. EOF
  131.  
  132. # In case auto IP discovery fails, enter server's public IP here.
  133. PUBLIC_IP=${VPN_PUBLIC_IP:-''}
  134.  
  135. # Try to auto discover IP of this server
  136. [ -z "$PUBLIC_IP" ] && PUBLIC_IP=$(dig @resolver1.opendns.com -t A -4 myip.opendns.com +short)
  137.  
  138. # Check IP for correct format
  139. check_ip "$PUBLIC_IP" || PUBLIC_IP=$(wget -t 3 -T 15 -qO- http://ipv4.icanhazip.com)
  140. check_ip "$PUBLIC_IP" || exiterr "Cannot detect this server's public IP. Edit the script and manually enter it."
  141.  
  142. bigecho "Adding the EPEL repository..."
  143.  
  144. epel_url="https://dl.fedoraproject.org/pub/epel/epel-release-latest-$(rpm -E '%{rhel}').noarch.rpm"
  145. yum -y install epel-release || yum -y install "$epel_url" || exiterr2
  146.  
  147. bigecho "Installing packages required for the VPN..."
  148.  
  149. yum -y install nss-devel nspr-devel pkgconfig pam-devel \
  150. libcap-ng-devel libselinux-devel curl-devel \
  151. flex bison gcc make ppp xl2tpd || exiterr2
  152.  
  153. OPT1='--enablerepo=*server-optional*'
  154. OPT2='--enablerepo=*releases-optional*'
  155. if grep -qs "release 6" /etc/redhat-release; then
  156. yum -y remove libevent-devel
  157. yum "$OPT1" "$OPT2" -y install libevent2-devel fipscheck-devel || exiterr2
  158. else
  159. yum -y install systemd-devel iptables-services || exiterr2
  160. yum "$OPT1" "$OPT2" -y install libevent-devel fipscheck-devel || exiterr2
  161. fi
  162.  
  163. bigecho "Installing Fail2Ban to protect SSH..."
  164.  
  165. yum -y install fail2ban || exiterr2
  166.  
  167. bigecho "Compiling and installing Libreswan..."
  168.  
  169. SWAN_VER=3.23
  170. swan_file="libreswan-$SWAN_VER.tar.gz"
  171. swan_url1="https://github.com/libreswan/libreswan/archive/v$SWAN_VER.tar.gz"
  172. swan_url2="https://download.libreswan.org/$swan_file"
  173. if ! { wget -t 3 -T 30 -nv -O "$swan_file" "$swan_url1" || wget -t 3 -T 30 -nv -O "$swan_file" "$swan_url2"; }; then
  174. exiterr "Cannot download Libreswan source."
  175. fi
  176. /bin/rm -rf "/opt/src/libreswan-$SWAN_VER"
  177. tar xzf "$swan_file" && /bin/rm -f "$swan_file"
  178. cd "libreswan-$SWAN_VER" || exiterr "Cannot enter Libreswan source dir."
  179. sed -i '/docker-targets\.mk/d' Makefile
  180. cat > Makefile.inc.local <<'EOF'
  181. WERROR_CFLAGS =
  182. USE_DNSSEC = false
  183. EOF
  184. NPROCS="$(grep -c ^processor /proc/cpuinfo)"
  185. [ -z "$NPROCS" ] && NPROCS=1
  186. make "-j$((NPROCS+1))" -s base && make -s install-base
  187.  
  188. # Verify the install and clean up
  189. cd /opt/src || exiterr "Cannot enter /opt/src."
  190. /bin/rm -rf "/opt/src/libreswan-$SWAN_VER"
  191. if ! /usr/local/sbin/ipsec --version 2>/dev/null | grep -qF "$SWAN_VER"; then
  192. exiterr "Libreswan $SWAN_VER failed to build."
  193. fi
  194.  
  195. bigecho "Creating VPN configuration..."
  196.  
  197. L2TP_NET=${VPN_L2TP_NET:-'192.168.42.0/24'}
  198. L2TP_LOCAL=${VPN_L2TP_LOCAL:-'192.168.42.1'}
  199. L2TP_POOL=${VPN_L2TP_POOL:-'192.168.42.10-192.168.42.250'}
  200. XAUTH_NET=${VPN_XAUTH_NET:-'192.168.43.0/24'}
  201. XAUTH_POOL=${VPN_XAUTH_POOL:-'192.168.43.10-192.168.43.250'}
  202. DNS_SRV1=${VPN_DNS_SRV1:-'8.8.8.8'}
  203. DNS_SRV2=${VPN_DNS_SRV2:-'8.8.4.4'}
  204.  
  205. # Create IPsec (Libreswan) config
  206. conf_bk "/etc/ipsec.conf"
  207. cat > /etc/ipsec.conf <<EOF
  208. version 2.0
  209.  
  210. config setup
  211. virtual-private=%v4:10.0.0.0/8,%v4:192.168.0.0/16,%v4:172.16.0.0/12,%v4:!$L2TP_NET,%v4:!$XAUTH_NET
  212. protostack=netkey
  213. interfaces=%defaultroute
  214. uniqueids=no
  215.  
  216. conn shared
  217. left=%defaultroute
  218. leftid=$PUBLIC_IP
  219. right=%any
  220. encapsulation=yes
  221. authby=secret
  222. pfs=no
  223. rekey=no
  224. keyingtries=5
  225. dpddelay=30
  226. dpdtimeout=120
  227. dpdaction=clear
  228. ike=3des-sha1,3des-sha2,aes-sha1,aes-sha1;modp1024,aes-sha2,aes-sha2;modp1024,aes256-sha2_512
  229. phase2alg=3des-sha1,3des-sha2,aes-sha1,aes-sha2,aes256-sha2_512
  230. sha2-truncbug=yes
  231.  
  232. conn l2tp-psk
  233. auto=add
  234. leftprotoport=17/1701
  235. rightprotoport=17/%any
  236. type=transport
  237. phase2=esp
  238. also=shared
  239.  
  240. conn xauth-psk
  241. auto=add
  242. leftsubnet=0.0.0.0/0
  243. rightaddresspool=$XAUTH_POOL
  244. modecfgdns="$DNS_SRV1, $DNS_SRV2"
  245. leftxauthserver=yes
  246. rightxauthclient=yes
  247. leftmodecfgserver=yes
  248. rightmodecfgclient=yes
  249. modecfgpull=yes
  250. xauthby=file
  251. ike-frag=yes
  252. ikev2=never
  253. cisco-unity=yes
  254. also=shared
  255. EOF
  256.  
  257. # Specify IPsec PSK
  258. conf_bk "/etc/ipsec.secrets"
  259. cat > /etc/ipsec.secrets <<EOF
  260. %any %any : PSK "$VPN_IPSEC_PSK"
  261. EOF
  262.  
  263. # Create xl2tpd config
  264. conf_bk "/etc/xl2tpd/xl2tpd.conf"
  265. cat > /etc/xl2tpd/xl2tpd.conf <<EOF
  266. [global]
  267. port = 1701
  268.  
  269. [lns default]
  270. ip range = $L2TP_POOL
  271. local ip = $L2TP_LOCAL
  272. require chap = yes
  273. refuse pap = yes
  274. require authentication = yes
  275. name = l2tpd
  276. pppoptfile = /etc/ppp/options.xl2tpd
  277. length bit = yes
  278. EOF
  279.  
  280. # Set xl2tpd options
  281. conf_bk "/etc/ppp/options.xl2tpd"
  282. cat > /etc/ppp/options.xl2tpd <<EOF
  283. +mschap-v2
  284. ipcp-accept-local
  285. ipcp-accept-remote
  286. ms-dns $DNS_SRV1
  287. ms-dns $DNS_SRV2
  288. noccp
  289. auth
  290. mtu 1280
  291. mru 1280
  292. proxyarp
  293. lcp-echo-failure 4
  294. lcp-echo-interval 30
  295. connect-delay 5000
  296. EOF
  297.  
  298. # Create VPN credentials
  299. conf_bk "/etc/ppp/chap-secrets"
  300. cat > /etc/ppp/chap-secrets <<EOF
  301. "$VPN_USER" l2tpd "$VPN_PASSWORD" *
  302. EOF
  303.  
  304. conf_bk "/etc/ipsec.d/passwd"
  305. VPN_PASSWORD_ENC=$(openssl passwd -1 "$VPN_PASSWORD")
  306. cat > /etc/ipsec.d/passwd <<EOF
  307. $VPN_USER:$VPN_PASSWORD_ENC:xauth-psk
  308. EOF
  309.  
  310. bigecho "Updating sysctl settings..."
  311.  
  312. if ! grep -qs "hwdsl2 VPN script" /etc/sysctl.conf; then
  313. conf_bk "/etc/sysctl.conf"
  314. if [ "$(getconf LONG_BIT)" = "64" ]; then
  315. SHM_MAX=68719476736
  316. SHM_ALL=4294967296
  317. else
  318. SHM_MAX=4294967295
  319. SHM_ALL=268435456
  320. fi
  321. cat >> /etc/sysctl.conf <<EOF
  322.  
  323. # Added by hwdsl2 VPN script
  324. kernel.msgmnb = 65536
  325. kernel.msgmax = 65536
  326. kernel.shmmax = $SHM_MAX
  327. kernel.shmall = $SHM_ALL
  328.  
  329. net.ipv4.ip_forward = 1
  330. net.ipv4.conf.all.accept_source_route = 0
  331. net.ipv4.conf.all.accept_redirects = 0
  332. net.ipv4.conf.all.send_redirects = 0
  333. net.ipv4.conf.all.rp_filter = 0
  334. net.ipv4.conf.default.accept_source_route = 0
  335. net.ipv4.conf.default.accept_redirects = 0
  336. net.ipv4.conf.default.send_redirects = 0
  337. net.ipv4.conf.default.rp_filter = 0
  338. net.ipv4.conf.$net_iface.send_redirects = 0
  339. net.ipv4.conf.$net_iface.rp_filter = 0
  340.  
  341. net.core.wmem_max = 12582912
  342. net.core.rmem_max = 12582912
  343. net.ipv4.tcp_rmem = 10240 87380 12582912
  344. net.ipv4.tcp_wmem = 10240 87380 12582912
  345. EOF
  346. fi
  347.  
  348. bigecho "Updating IPTables rules..."
  349.  
  350. # Check if IPTables rules need updating
  351. ipt_flag=0
  352. IPT_FILE="/etc/sysconfig/iptables"
  353. if ! grep -qs "hwdsl2 VPN script" "$IPT_FILE" \
  354. || ! iptables -t nat -C POSTROUTING -s "$L2TP_NET" -o "$net_iface" -j MASQUERADE 2>/dev/null \
  355. || ! iptables -t nat -C POSTROUTING -s "$XAUTH_NET" -o "$net_iface" -m policy --dir out --pol none -j MASQUERADE 2>/dev/null; then
  356. ipt_flag=1
  357. fi
  358.  
  359. # Add IPTables rules for VPN
  360. if [ "$ipt_flag" = "1" ]; then
  361. service fail2ban stop >/dev/null 2>&1
  362. iptables-save > "$IPT_FILE.old-$SYS_DT"
  363. iptables -I INPUT 1 -p udp --dport 1701 -m policy --dir in --pol none -j DROP
  364. iptables -I INPUT 2 -m conntrack --ctstate INVALID -j DROP
  365. iptables -I INPUT 3 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
  366. iptables -I INPUT 4 -p udp -m multiport --dports 500,4500 -j ACCEPT
  367. iptables -I INPUT 5 -p udp --dport 1701 -m policy --dir in --pol ipsec -j ACCEPT
  368. iptables -I INPUT 6 -p udp --dport 1701 -j DROP
  369. iptables -I FORWARD 1 -m conntrack --ctstate INVALID -j DROP
  370. iptables -I FORWARD 2 -i "$net_iface" -o ppp+ -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
  371. iptables -I FORWARD 3 -i ppp+ -o "$net_iface" -j ACCEPT
  372. iptables -I FORWARD 4 -i ppp+ -o ppp+ -s "$L2TP_NET" -d "$L2TP_NET" -j ACCEPT
  373. iptables -I FORWARD 5 -i "$net_iface" -d "$XAUTH_NET" -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
  374. iptables -I FORWARD 6 -s "$XAUTH_NET" -o "$net_iface" -j ACCEPT
  375. # Uncomment if you wish to disallow traffic between VPN clients themselves
  376. # iptables -I FORWARD 2 -i ppp+ -o ppp+ -s "$L2TP_NET" -d "$L2TP_NET" -j DROP
  377. # iptables -I FORWARD 3 -s "$XAUTH_NET" -d "$XAUTH_NET" -j DROP
  378. iptables -A FORWARD -j DROP
  379. iptables -t nat -I POSTROUTING -s "$XAUTH_NET" -o "$net_iface" -m policy --dir out --pol none -j MASQUERADE
  380. iptables -t nat -I POSTROUTING -s "$L2TP_NET" -o "$net_iface" -j MASQUERADE
  381. echo "# Modified by hwdsl2 VPN script" > "$IPT_FILE"
  382. iptables-save >> "$IPT_FILE"
  383. fi
  384.  
  385. bigecho "Creating basic Fail2Ban rules..."
  386.  
  387. if [ ! -f /etc/fail2ban/jail.local ] ; then
  388. cat > /etc/fail2ban/jail.local <<'EOF'
  389. [ssh-iptables]
  390. enabled = true
  391. filter = sshd
  392. action = iptables[name=SSH, port=ssh, protocol=tcp]
  393. logpath = /var/log/secure
  394. EOF
  395. fi
  396.  
  397. bigecho "Enabling services on boot..."
  398.  
  399. if grep -qs "release 6" /etc/redhat-release; then
  400. chkconfig iptables on
  401. chkconfig fail2ban on
  402. else
  403. systemctl --now mask firewalld 2>/dev/null
  404. systemctl enable iptables fail2ban 2>/dev/null
  405. fi
  406. if ! grep -qs "hwdsl2 VPN script" /etc/rc.local; then
  407. if [ -f /etc/rc.local ]; then
  408. conf_bk "/etc/rc.local"
  409. else
  410. echo '#!/bin/sh' > /etc/rc.local
  411. fi
  412. cat >> /etc/rc.local <<'EOF'
  413.  
  414. # Added by hwdsl2 VPN script
  415. (sleep 15
  416. modprobe -q pppol2tp
  417. service ipsec restart
  418. service xl2tpd restart
  419. echo 1 > /proc/sys/net/ipv4/ip_forward)&
  420. EOF
  421. fi
  422.  
  423. bigecho "Starting services..."
  424.  
  425. # Restore SELinux contexts
  426. restorecon /etc/ipsec.d/*db 2>/dev/null
  427. restorecon /usr/local/sbin -Rv 2>/dev/null
  428. restorecon /usr/local/libexec/ipsec -Rv 2>/dev/null
  429.  
  430. # Reload sysctl.conf
  431. sysctl -e -q -p
  432.  
  433. # Update file attributes
  434. chmod +x /etc/rc.local
  435. chmod 600 /etc/ipsec.secrets* /etc/ppp/chap-secrets* /etc/ipsec.d/passwd*
  436.  
  437. # Apply new IPTables rules
  438. iptables-restore < "$IPT_FILE"
  439.  
  440. # Fix xl2tpd on CentOS 7, if kernel module "l2tp_ppp" is unavailable
  441. if grep -qs "release 7" /etc/redhat-release; then
  442. if ! modprobe -q l2tp_ppp; then
  443. sed -i '/^ExecStartPre/s/^/#/' /usr/lib/systemd/system/xl2tpd.service
  444. systemctl daemon-reload
  445. fi
  446. fi
  447.  
  448. # Restart services
  449. modprobe -q pppol2tp
  450. service fail2ban restart 2>/dev/null
  451. service ipsec restart 2>/dev/null
  452. service xl2tpd restart 2>/dev/null
  453.  
  454. cat <<EOF
  455.  
  456. ================================================
  457.  
  458. IPsec VPN server is now ready for use!
  459.  
  460. Connect to your new VPN with these details:
  461.  
  462. Server IP: $PUBLIC_IP
  463. IPsec PSK: $VPN_IPSEC_PSK
  464. Username: $VPN_USER
  465. Password: $VPN_PASSWORD
  466.  
  467. Write these down. You'll need them to connect!
  468.  
  469. Important notes: https://git.io/vpnnotes
  470. Setup VPN clients: https://git.io/vpnclients
  471.  
  472. ================================================
  473.  
  474. EOF
  475.  
  476. }
  477.  
  478. ## Defer setup until we have the complete script
  479. vpnsetup "$@"
  480.  
  481. exit 0
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement