Spaces:
Build error
Build error
File size: 23,448 Bytes
9a0ab0f |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 |
#!/bin/bash
#
# Docker script to configure and start an IPsec VPN server
#
# DO NOT RUN THIS SCRIPT ON YOUR PC OR MAC! THIS IS ONLY MEANT TO BE RUN
# IN A CONTAINER!
#
# This file is part of IPsec VPN Docker image, available at:
# https://github.com/hwdsl2/docker-ipsec-vpn-server
#
# Copyright (C) 2016-2023 Lin Song <linsongui@gmail.com>
# Based on the work of Thomas Sarlandie (Copyright 2012)
#
# This work is licensed under the Creative Commons Attribution-ShareAlike 3.0
# Unported License: http://creativecommons.org/licenses/by-sa/3.0/
#
# Attribution required: please include my name in any derivative and let me
# know how you have improved it!
export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
exiterr() { echo "Error: $1" >&2; exit 1; }
nospaces() { printf '%s' "$1" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//'; }
onespace() { printf '%s' "$1" | tr -s ' '; }
noquotes() { printf '%s' "$1" | sed -e 's/^"\(.*\)"$/\1/' -e "s/^'\(.*\)'$/\1/"; }
noquotes2() { printf '%s' "$1" | sed -e 's/" "/ /g' -e "s/' '/ /g"; }
check_ip() {
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])$'
printf '%s' "$1" | tr -d '\n' | grep -Eq "$IP_REGEX"
}
check_dns_name() {
FQDN_REGEX='^([a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}$'
printf '%s' "$1" | tr -d '\n' | grep -Eq "$FQDN_REGEX"
}
check_client_name() {
! { [ "${#1}" -gt "64" ] || printf '%s' "$1" | LC_ALL=C grep -q '[^A-Za-z0-9_-]\+' \
|| case $1 in -*) true ;; *) false ;; esac; }
}
if [ ! -f "/.dockerenv" ] && [ ! -f "/run/.containerenv" ] \
&& [ -z "$KUBERNETES_SERVICE_HOST" ] \
&& ! head -n 1 /proc/1/sched 2>/dev/null | grep -q '^run\.sh '; then
exiterr "This script ONLY runs in a container (e.g. Docker, Podman)."
fi
if ip link add dummy0 type dummy 2>&1 | grep -q "not permitted"; then
cat 1>&2 <<'EOF'
Error: This Docker image should be run in privileged mode.
See: https://github.com/hwdsl2/docker-ipsec-vpn-server
EOF
exit 1
fi
ip link delete dummy0 >/dev/null 2>&1
os_type=debian
os_arch=$(uname -m | tr -dc 'A-Za-z0-9_-')
[ -f /etc/os-release ] && os_type=$(. /etc/os-release && printf '%s' "$ID")
if [ ! -e /dev/ppp ]; then
cat <<'EOF'
Warning: /dev/ppp is missing, and IPsec/L2TP mode may not work.
Please use IKEv2 or IPsec/XAuth mode to connect.
Debian 11/10 users, see https://vpnsetup.net/debian10
EOF
fi
NET_IFACE=$(route 2>/dev/null | grep -m 1 '^default' | grep -o '[^ ]*$')
[ -z "$NET_IFACE" ] && NET_IFACE=$(ip -4 route list 0/0 2>/dev/null | grep -m 1 -Po '(?<=dev )(\S+)')
[ -z "$NET_IFACE" ] && NET_IFACE=eth0
mkdir -p /opt/src
vpn_env="/opt/src/vpn.env"
vpn_env_dir="/opt/src/env/vpn.env"
if [ -f "$vpn_env_dir" ]; then
vpn_env="$vpn_env_dir"
fi
vpn_gen_env="/etc/ipsec.d/vpn-gen.env"
if [ -z "$VPN_IPSEC_PSK" ] && [ -z "$VPN_USER" ] && [ -z "$VPN_PASSWORD" ]; then
if [ -f "$vpn_env" ]; then
echo
echo 'Retrieving VPN credentials...'
. "$vpn_env"
elif [ -f "$vpn_gen_env" ]; then
echo
echo 'Retrieving previously generated VPN credentials...'
. "$vpn_gen_env"
else
echo
echo 'VPN credentials not set by user. Generating random PSK and password...'
VPN_IPSEC_PSK=$(LC_CTYPE=C tr -dc 'A-HJ-NPR-Za-km-z2-9' </dev/urandom 2>/dev/null | head -c 20)
VPN_USER=vpnuser
VPN_PASSWORD=$(LC_CTYPE=C tr -dc 'A-HJ-NPR-Za-km-z2-9' </dev/urandom 2>/dev/null | head -c 16)
printf '%s\n' "VPN_IPSEC_PSK='$VPN_IPSEC_PSK'" > "$vpn_gen_env"
printf '%s\n' "VPN_USER='$VPN_USER'" >> "$vpn_gen_env"
printf '%s\n' "VPN_PASSWORD='$VPN_PASSWORD'" >> "$vpn_gen_env"
chmod 600 "$vpn_gen_env"
fi
fi
# Remove whitespace and quotes around VPN variables, if any
VPN_IPSEC_PSK=$(nospaces "$VPN_IPSEC_PSK")
VPN_IPSEC_PSK=$(noquotes "$VPN_IPSEC_PSK")
VPN_USER=$(nospaces "$VPN_USER")
VPN_USER=$(noquotes "$VPN_USER")
VPN_PASSWORD=$(nospaces "$VPN_PASSWORD")
VPN_PASSWORD=$(noquotes "$VPN_PASSWORD")
if [ -n "$VPN_ADDL_USERS" ] && [ -n "$VPN_ADDL_PASSWORDS" ]; then
VPN_ADDL_USERS=$(nospaces "$VPN_ADDL_USERS")
VPN_ADDL_USERS=$(noquotes "$VPN_ADDL_USERS")
VPN_ADDL_USERS=$(onespace "$VPN_ADDL_USERS")
VPN_ADDL_USERS=$(noquotes2 "$VPN_ADDL_USERS")
VPN_ADDL_PASSWORDS=$(nospaces "$VPN_ADDL_PASSWORDS")
VPN_ADDL_PASSWORDS=$(noquotes "$VPN_ADDL_PASSWORDS")
VPN_ADDL_PASSWORDS=$(onespace "$VPN_ADDL_PASSWORDS")
VPN_ADDL_PASSWORDS=$(noquotes2 "$VPN_ADDL_PASSWORDS")
if [ -n "$VPN_ADDL_IP_ADDRS" ]; then
VPN_ADDL_IP_ADDRS=$(nospaces "$VPN_ADDL_IP_ADDRS")
VPN_ADDL_IP_ADDRS=$(noquotes "$VPN_ADDL_IP_ADDRS")
VPN_ADDL_IP_ADDRS=$(onespace "$VPN_ADDL_IP_ADDRS")
VPN_ADDL_IP_ADDRS=$(noquotes2 "$VPN_ADDL_IP_ADDRS")
fi
else
VPN_ADDL_USERS=""
VPN_ADDL_PASSWORDS=""
VPN_ADDL_IP_ADDRS=""
fi
if [ -n "$VPN_DNS_SRV1" ]; then
VPN_DNS_SRV1=$(nospaces "$VPN_DNS_SRV1")
VPN_DNS_SRV1=$(noquotes "$VPN_DNS_SRV1")
fi
if [ -n "$VPN_DNS_SRV2" ]; then
VPN_DNS_SRV2=$(nospaces "$VPN_DNS_SRV2")
VPN_DNS_SRV2=$(noquotes "$VPN_DNS_SRV2")
fi
if [ -n "$VPN_CLIENT_NAME" ]; then
VPN_CLIENT_NAME=$(nospaces "$VPN_CLIENT_NAME")
VPN_CLIENT_NAME=$(noquotes "$VPN_CLIENT_NAME")
fi
if [ -n "$VPN_DNS_NAME" ]; then
VPN_DNS_NAME=$(nospaces "$VPN_DNS_NAME")
VPN_DNS_NAME=$(noquotes "$VPN_DNS_NAME")
fi
if [ -n "$VPN_PUBLIC_IP" ]; then
VPN_PUBLIC_IP=$(nospaces "$VPN_PUBLIC_IP")
VPN_PUBLIC_IP=$(noquotes "$VPN_PUBLIC_IP")
fi
if [ -n "$VPN_ANDROID_MTU_FIX" ]; then
VPN_ANDROID_MTU_FIX=$(nospaces "$VPN_ANDROID_MTU_FIX")
VPN_ANDROID_MTU_FIX=$(noquotes "$VPN_ANDROID_MTU_FIX")
fi
if [ -n "$VPN_SHA2_TRUNCBUG" ]; then
VPN_SHA2_TRUNCBUG=$(nospaces "$VPN_SHA2_TRUNCBUG")
VPN_SHA2_TRUNCBUG=$(noquotes "$VPN_SHA2_TRUNCBUG")
fi
if [ -n "$VPN_PROTECT_CONFIG" ]; then
VPN_PROTECT_CONFIG=$(nospaces "$VPN_PROTECT_CONFIG")
VPN_PROTECT_CONFIG=$(noquotes "$VPN_PROTECT_CONFIG")
fi
if [ -n "$VPN_DISABLE_IPSEC_L2TP" ]; then
VPN_DISABLE_IPSEC_L2TP=$(nospaces "$VPN_DISABLE_IPSEC_L2TP")
VPN_DISABLE_IPSEC_L2TP=$(noquotes "$VPN_DISABLE_IPSEC_L2TP")
fi
if [ -n "$VPN_DISABLE_IPSEC_XAUTH" ]; then
VPN_DISABLE_IPSEC_XAUTH=$(nospaces "$VPN_DISABLE_IPSEC_XAUTH")
VPN_DISABLE_IPSEC_XAUTH=$(noquotes "$VPN_DISABLE_IPSEC_XAUTH")
fi
if [ -n "$VPN_IKEV2_ONLY" ]; then
VPN_IKEV2_ONLY=$(nospaces "$VPN_IKEV2_ONLY")
VPN_IKEV2_ONLY=$(noquotes "$VPN_IKEV2_ONLY")
fi
if [ -n "$VPN_ENABLE_MODP1024" ]; then
VPN_ENABLE_MODP1024=$(nospaces "$VPN_ENABLE_MODP1024")
VPN_ENABLE_MODP1024=$(noquotes "$VPN_ENABLE_MODP1024")
fi
if [ -n "$VPN_ENABLE_MODP1536" ]; then
VPN_ENABLE_MODP1536=$(nospaces "$VPN_ENABLE_MODP1536")
VPN_ENABLE_MODP1536=$(noquotes "$VPN_ENABLE_MODP1536")
fi
if [ -n "$VPN_L2TP_NET" ]; then
VPN_L2TP_NET=$(nospaces "$VPN_L2TP_NET")
VPN_L2TP_NET=$(noquotes "$VPN_L2TP_NET")
fi
if [ -n "$VPN_L2TP_LOCAL" ]; then
VPN_L2TP_LOCAL=$(nospaces "$VPN_L2TP_LOCAL")
VPN_L2TP_LOCAL=$(noquotes "$VPN_L2TP_LOCAL")
fi
if [ -n "$VPN_L2TP_POOL" ]; then
VPN_L2TP_POOL=$(nospaces "$VPN_L2TP_POOL")
VPN_L2TP_POOL=$(noquotes "$VPN_L2TP_POOL")
fi
if [ -n "$VPN_XAUTH_NET" ]; then
VPN_XAUTH_NET=$(nospaces "$VPN_XAUTH_NET")
VPN_XAUTH_NET=$(noquotes "$VPN_XAUTH_NET")
fi
if [ -n "$VPN_XAUTH_POOL" ]; then
VPN_XAUTH_POOL=$(nospaces "$VPN_XAUTH_POOL")
VPN_XAUTH_POOL=$(noquotes "$VPN_XAUTH_POOL")
fi
if [ -z "$VPN_IPSEC_PSK" ] || [ -z "$VPN_USER" ] || [ -z "$VPN_PASSWORD" ]; then
exiterr "All VPN credentials must be specified. Edit your 'env' file and re-enter them."
fi
if printf '%s' "$VPN_IPSEC_PSK $VPN_USER $VPN_PASSWORD $VPN_ADDL_USERS $VPN_ADDL_PASSWORDS" | LC_ALL=C grep -q '[^ -~]\+'; then
exiterr "VPN credentials must not contain non-ASCII characters."
fi
case "$VPN_IPSEC_PSK $VPN_USER $VPN_PASSWORD $VPN_ADDL_USERS $VPN_ADDL_PASSWORDS" in
*[\\\"\']*)
exiterr "VPN credentials must not contain these special characters: \\ \" '"
;;
esac
if printf '%s' "$VPN_USER $VPN_ADDL_USERS" | tr ' ' '\n' | sort | uniq -c | grep -qv '^ *1 '; then
exiterr "VPN usernames must not contain duplicates."
fi
# Check DNS servers and try to resolve hostnames to IPs
if [ -n "$VPN_DNS_SRV1" ]; then
check_ip "$VPN_DNS_SRV1" || VPN_DNS_SRV1=$(dig -t A -4 +short "$VPN_DNS_SRV1")
if ! check_ip "$VPN_DNS_SRV1"; then
cat <<'EOF'
Warning: Invalid DNS server. Check VPN_DNS_SRV1 in your 'env' file.
EOF
VPN_DNS_SRV1=""
fi
fi
if [ -n "$VPN_DNS_SRV2" ]; then
check_ip "$VPN_DNS_SRV2" || VPN_DNS_SRV2=$(dig -t A -4 +short "$VPN_DNS_SRV2")
if ! check_ip "$VPN_DNS_SRV2"; then
cat <<'EOF'
Warning: Invalid DNS server. Check VPN_DNS_SRV2 in your 'env' file.
EOF
VPN_DNS_SRV2=""
fi
fi
if [ -n "$VPN_CLIENT_NAME" ]; then
if ! check_client_name "$VPN_CLIENT_NAME"; then
cat <<'EOF'
Warning: Invalid client name. Use one word only, no special characters except '-' and '_'.
Falling back to default client name 'vpnclient'.
EOF
VPN_CLIENT_NAME=""
fi
fi
if [ -n "$VPN_DNS_NAME" ]; then
if ! check_dns_name "$VPN_DNS_NAME"; then
cat <<'EOF'
Warning: Invalid DNS name. 'VPN_DNS_NAME' must be a fully qualified domain name (FQDN).
Falling back to using this server's IP address.
EOF
VPN_DNS_NAME=""
fi
fi
if [ -n "$VPN_DNS_NAME" ]; then
server_addr="$VPN_DNS_NAME"
else
echo
echo 'Trying to auto discover IP of this server...'
# In case auto IP discovery fails, manually define the public IP
# of this server in your 'env' file, as variable 'VPN_PUBLIC_IP'.
public_ip=${VPN_PUBLIC_IP:-''}
check_ip "$public_ip" || public_ip=$(dig @resolver1.opendns.com -t A -4 myip.opendns.com +short)
check_ip "$public_ip" || public_ip=$(wget -t 2 -T 10 -qO- http://ipv4.icanhazip.com)
check_ip "$public_ip" || public_ip=$(wget -t 2 -T 10 -qO- http://ip1.dynupdate.no-ip.com)
check_ip "$public_ip" || exiterr "Cannot detect this server's public IP. Define it in your 'env' file as 'VPN_PUBLIC_IP'."
server_addr="$public_ip"
fi
L2TP_NET=${VPN_L2TP_NET:-'192.168.42.0/24'}
L2TP_LOCAL=${VPN_L2TP_LOCAL:-'192.168.42.1'}
L2TP_POOL=${VPN_L2TP_POOL:-'192.168.42.10-192.168.42.250'}
XAUTH_NET=${VPN_XAUTH_NET:-'192.168.43.0/24'}
XAUTH_POOL=${VPN_XAUTH_POOL:-'192.168.43.10-192.168.43.250'}
DNS_SRV1=${VPN_DNS_SRV1:-'8.8.8.8'}
DNS_SRV2=${VPN_DNS_SRV2:-'8.8.4.4'}
DNS_SRVS="\"$DNS_SRV1 $DNS_SRV2\""
[ -n "$VPN_DNS_SRV1" ] && [ -z "$VPN_DNS_SRV2" ] && DNS_SRVS="$DNS_SRV1"
if [ -n "$VPN_DNS_SRV1" ] && [ -n "$VPN_DNS_SRV2" ]; then
echo
echo "Setting DNS servers to $VPN_DNS_SRV1 and $VPN_DNS_SRV2..."
elif [ -n "$VPN_DNS_SRV1" ]; then
echo
echo "Setting DNS server to $VPN_DNS_SRV1..."
fi
sha2_truncbug=no
case $VPN_SHA2_TRUNCBUG in
[yY][eE][sS])
echo
echo "Setting sha2-truncbug to yes in ipsec.conf..."
sha2_truncbug=yes
;;
esac
disable_ipsec_l2tp=no
case $VPN_DISABLE_IPSEC_L2TP in
[yY][eE][sS])
disable_ipsec_l2tp=yes
;;
esac
disable_ipsec_xauth=no
case $VPN_DISABLE_IPSEC_XAUTH in
[yY][eE][sS])
disable_ipsec_xauth=yes
;;
esac
case $VPN_IKEV2_ONLY in
[yY][eE][sS])
disable_ipsec_l2tp=yes
disable_ipsec_xauth=yes
;;
esac
ike_algs="aes256-sha2;modp2048,aes128-sha2;modp2048,aes256-sha1;modp2048,aes128-sha1;modp2048"
ike_algs_addl_1=",aes256-sha2;modp1024,aes128-sha1;modp1024"
ike_algs_addl_2=",aes256-sha2;modp1536,aes128-sha1;modp1536"
case $VPN_ENABLE_MODP1024 in
[yY][eE][sS])
echo
echo "Enabling modp1024 in ipsec.conf..."
ike_algs="$ike_algs$ike_algs_addl_1"
;;
esac
case $VPN_ENABLE_MODP1536 in
[yY][eE][sS])
echo
echo "Enabling modp1536 in ipsec.conf..."
ike_algs="$ike_algs$ike_algs_addl_2"
;;
esac
if [ "$disable_ipsec_l2tp" = yes ] && [ "$disable_ipsec_xauth" = yes ]; then
cat <<'EOF'
Note: Running in IKEv2-only mode via env file option.
IPsec/L2TP and IPsec/XAuth ("Cisco IPsec") modes are disabled.
EOF
if ! grep -q " /etc/ipsec.d " /proc/mounts; then
cat <<'EOF'
Warning: /etc/ipsec.d not mounted. IKEv2 setup requires a Docker volume
mounted at /etc/ipsec.d.
EOF
fi
elif [ "$disable_ipsec_l2tp" = yes ]; then
cat <<'EOF'
Note: IPsec/L2TP mode is disabled via env file option.
EOF
elif [ "$disable_ipsec_xauth" = yes ]; then
cat <<'EOF'
Note: IPsec/XAuth ("Cisco IPsec") mode is disabled via env file option.
EOF
fi
# Create IPsec config
cat > /etc/ipsec.conf <<EOF
version 2.0
config setup
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
uniqueids=no
conn shared
left=%defaultroute
leftid=$server_addr
right=%any
encapsulation=yes
authby=secret
pfs=no
rekey=no
keyingtries=5
dpddelay=30
dpdtimeout=300
dpdaction=clear
ikev2=never
ike=$ike_algs
phase2alg=aes_gcm-null,aes128-sha1,aes256-sha1,aes256-sha2_512,aes128-sha2,aes256-sha2
ikelifetime=24h
salifetime=24h
sha2-truncbug=$sha2_truncbug
EOF
if [ "$disable_ipsec_l2tp" != yes ]; then
cat >> /etc/ipsec.conf <<'EOF'
conn l2tp-psk
auto=add
leftprotoport=17/1701
rightprotoport=17/%any
type=transport
also=shared
EOF
fi
if [ "$disable_ipsec_xauth" != yes ]; then
cat >> /etc/ipsec.conf <<EOF
conn xauth-psk
auto=add
leftsubnet=0.0.0.0/0
rightaddresspool=$XAUTH_POOL
modecfgdns=$DNS_SRVS
leftxauthserver=yes
rightxauthclient=yes
leftmodecfgserver=yes
rightmodecfgclient=yes
modecfgpull=yes
cisco-unity=yes
also=shared
EOF
fi
cat >> /etc/ipsec.conf <<'EOF'
include /etc/ipsec.d/*.conf
EOF
if uname -r | grep -qi 'coreos'; then
sed -i '/phase2alg/s/,aes256-sha2_512//' /etc/ipsec.conf
fi
if grep -qs ike-frag /etc/ipsec.d/ikev2.conf; then
sed -i 's/^[[:space:]]\+ike-frag=/ fragmentation=/' /etc/ipsec.d/ikev2.conf
fi
# Specify IPsec PSK
cat > /etc/ipsec.secrets <<EOF
%any %any : PSK "$VPN_IPSEC_PSK"
EOF
# Create xl2tpd config
cat > /etc/xl2tpd/xl2tpd.conf <<EOF
[global]
port = 1701
[lns default]
ip range = $L2TP_POOL
local ip = $L2TP_LOCAL
require chap = yes
refuse pap = yes
require authentication = yes
name = l2tpd
pppoptfile = /etc/ppp/options.xl2tpd
length bit = yes
EOF
# Set xl2tpd options
cat > /etc/ppp/options.xl2tpd <<EOF
+mschap-v2
ipcp-accept-local
ipcp-accept-remote
noccp
auth
mtu 1280
mru 1280
proxyarp
lcp-echo-failure 4
lcp-echo-interval 30
connect-delay 5000
ms-dns $DNS_SRV1
EOF
if [ -z "$VPN_DNS_SRV1" ] || [ -n "$VPN_DNS_SRV2" ]; then
cat >> /etc/ppp/options.xl2tpd <<EOF
ms-dns $DNS_SRV2
EOF
fi
# Create VPN credentials
cat > /etc/ppp/chap-secrets <<EOF
"$VPN_USER" l2tpd "$VPN_PASSWORD" *
EOF
VPN_PASSWORD_ENC=$(openssl passwd -1 "$VPN_PASSWORD")
cat > /etc/ipsec.d/passwd <<EOF
$VPN_USER:$VPN_PASSWORD_ENC:xauth-psk
EOF
if [ -n "$VPN_ADDL_USERS" ] && [ -n "$VPN_ADDL_PASSWORDS" ]; then
count=1
addl_user=$(printf '%s' "$VPN_ADDL_USERS" | cut -d ' ' -f 1)
addl_password=$(printf '%s' "$VPN_ADDL_PASSWORDS" | cut -d ' ' -f 1)
addl_ip=$(printf '%s' "$VPN_ADDL_IP_ADDRS" | cut -d ' ' -f 1)
while [ -n "$addl_user" ] && [ -n "$addl_password" ]; do
addl_ip_l2tp="$addl_ip"
addl_ip_xauth="$addl_ip"
if [ "$addl_ip" = "*" ] || ! check_ip "$addl_ip"; then
addl_ip_l2tp=""
addl_ip_xauth=""
elif [ "$L2TP_NET" = "192.168.42.0/24" ] && [ "$XAUTH_NET" = "192.168.43.0/24" ]; then
addl_ip_part=$(printf '%s' "$addl_ip" | cut -f 1-3 -d '.')
if [ "$addl_ip_part" = "192.168.42" ]; then
addl_ip_xauth=""
elif [ "$addl_ip_part" = "192.168.43" ]; then
addl_ip_l2tp=""
else
addl_ip_l2tp=""
addl_ip_xauth=""
fi
fi
cat >> /etc/ppp/chap-secrets <<EOF
"$addl_user" l2tpd "$addl_password" ${addl_ip_l2tp:-*}
EOF
[ -n "$addl_ip_xauth" ] && addl_ip_xauth=$(printf '%s' ":$addl_ip_xauth")
addl_password_enc=$(openssl passwd -1 "$addl_password")
cat >> /etc/ipsec.d/passwd <<EOF
$addl_user:$addl_password_enc:xauth-psk${addl_ip_xauth}
EOF
count=$((count+1))
addl_user=$(printf '%s' "$VPN_ADDL_USERS" | cut -s -d ' ' -f "$count")
addl_password=$(printf '%s' "$VPN_ADDL_PASSWORDS" | cut -s -d ' ' -f "$count")
addl_ip=$(printf '%s' "$VPN_ADDL_IP_ADDRS" | cut -s -d ' ' -f "$count")
done
fi
# Update sysctl settings
syt='/sbin/sysctl -e -q -w'
$syt kernel.msgmnb=65536 2>/dev/null
$syt kernel.msgmax=65536 2>/dev/null
$syt net.ipv4.ip_forward=1 2>/dev/null
$syt net.ipv4.conf.all.accept_redirects=0 2>/dev/null
$syt net.ipv4.conf.all.send_redirects=0 2>/dev/null
$syt net.ipv4.conf.all.rp_filter=0 2>/dev/null
$syt net.ipv4.conf.default.accept_redirects=0 2>/dev/null
$syt net.ipv4.conf.default.send_redirects=0 2>/dev/null
$syt net.ipv4.conf.default.rp_filter=0 2>/dev/null
$syt "net.ipv4.conf.$NET_IFACE.send_redirects=0" 2>/dev/null
$syt "net.ipv4.conf.$NET_IFACE.rp_filter=0" 2>/dev/null
$syt net.ipv4.tcp_rmem="4096 87380 16777216" 2>/dev/null
$syt net.ipv4.tcp_wmem="4096 87380 16777216" 2>/dev/null
if modprobe -q tcp_bbr 2>/dev/null \
&& printf '%s\n%s' "4.20" "$(uname -r)" | sort -C -V; then
$syt net.ipv4.tcp_congestion_control=bbr 2>/dev/null
fi
# Create IPTables rules
ipi='iptables -I INPUT'
ipf='iptables -I FORWARD'
ipp='iptables -t nat -I POSTROUTING'
res='RELATED,ESTABLISHED'
if ! iptables -t nat -C POSTROUTING -s "$L2TP_NET" -o "$NET_IFACE" -j MASQUERADE 2>/dev/null; then
$ipi 1 -p udp --dport 1701 -m policy --dir in --pol none -j DROP
$ipi 2 -m conntrack --ctstate INVALID -j DROP
$ipi 3 -m conntrack --ctstate "$res" -j ACCEPT
$ipi 4 -p udp -m multiport --dports 500,7860 -j ACCEPT
$ipi 5 -p udp --dport 1701 -m policy --dir in --pol ipsec -j ACCEPT
$ipi 6 -p udp --dport 1701 -j DROP
$ipf 1 -m conntrack --ctstate INVALID -j DROP
$ipf 2 -i "$NET_IFACE" -o ppp+ -m conntrack --ctstate "$res" -j ACCEPT
$ipf 3 -i ppp+ -o "$NET_IFACE" -j ACCEPT
$ipf 4 -i ppp+ -o ppp+ -j ACCEPT
$ipf 5 -i "$NET_IFACE" -d "$XAUTH_NET" -m conntrack --ctstate "$res" -j ACCEPT
$ipf 6 -s "$XAUTH_NET" -o "$NET_IFACE" -j ACCEPT
$ipf 7 -s "$XAUTH_NET" -o ppp+ -j ACCEPT
# Client-to-client traffic is allowed by default. To *disallow* such traffic,
# uncomment below and restart the Docker container.
# $ipf 2 -i ppp+ -o ppp+ -s "$L2TP_NET" -d "$L2TP_NET" -j DROP
# $ipf 3 -s "$XAUTH_NET" -d "$XAUTH_NET" -j DROP
# $ipf 4 -i ppp+ -d "$XAUTH_NET" -j DROP
# $ipf 5 -s "$XAUTH_NET" -o ppp+ -j DROP
iptables -A FORWARD -j DROP
$ipp -s "$XAUTH_NET" -o "$NET_IFACE" -m policy --dir out --pol none -j MASQUERADE
$ipp -s "$L2TP_NET" -o "$NET_IFACE" -j MASQUERADE
fi
case $VPN_ANDROID_MTU_FIX in
[yY][eE][sS])
echo
echo "Applying fix for Android MTU/MSS issues..."
iptables -t mangle -A FORWARD -m policy --pol ipsec --dir in \
-p tcp -m tcp --tcp-flags SYN,RST SYN -m tcpmss --mss 1361:1536 \
-j TCPMSS --set-mss 1360
iptables -t mangle -A FORWARD -m policy --pol ipsec --dir out \
-p tcp -m tcp --tcp-flags SYN,RST SYN -m tcpmss --mss 1361:1536 \
-j TCPMSS --set-mss 1360
echo 1 > /proc/sys/net/ipv4/ip_no_pmtu_disc
;;
esac
# Update file attributes
chmod 600 /etc/ipsec.secrets /etc/ppp/chap-secrets /etc/ipsec.d/passwd
echo
echo "Starting IPsec service..."
mkdir -p /run/pluto /var/run/pluto
rm -f /run/pluto/pluto.pid /var/run/pluto/pluto.pid
if [ "$os_type" = "alpine" ]; then
sed -i '1c\#!/sbin/openrc-run' /etc/init.d/ipsec
rc-status >/dev/null 2>&1
rc-service ipsec zap >/dev/null
rc-service -D ipsec start >/dev/null 2>&1
mkdir -p /etc/crontabs
cron_cmd="rc-service -c -D ipsec zap start"
if ! grep -qs "$cron_cmd" /etc/crontabs/root; then
cat >> /etc/crontabs/root <<EOF
* * * * * $cron_cmd
* * * * * sleep 15; $cron_cmd
* * * * * sleep 30; $cron_cmd
* * * * * sleep 45; $cron_cmd
EOF
fi
/usr/sbin/crond -L /dev/null
else
service ipsec start >/dev/null 2>&1
fi
if [ -n "$VPN_DNS_NAME" ]; then
server_text="Server"
else
server_text="Server IP"
fi
if [ "$disable_ipsec_l2tp" != yes ] || [ "$disable_ipsec_xauth" != yes ]; then
cat <<EOF
================================================
IPsec VPN server is now ready for use!
Connect to your new VPN with these details:
$server_text: $server_addr
IPsec PSK: $VPN_IPSEC_PSK
Username: $VPN_USER
Password: $VPN_PASSWORD
EOF
if [ -n "$VPN_ADDL_USERS" ] && [ -n "$VPN_ADDL_PASSWORDS" ]; then
count=1
addl_user=$(printf '%s' "$VPN_ADDL_USERS" | cut -d ' ' -f 1)
addl_password=$(printf '%s' "$VPN_ADDL_PASSWORDS" | cut -d ' ' -f 1)
cat <<'EOF'
Additional VPN users (username | password):
EOF
while [ -n "$addl_user" ] && [ -n "$addl_password" ]; do
cat <<EOF
$addl_user | $addl_password
EOF
count=$((count+1))
addl_user=$(printf '%s' "$VPN_ADDL_USERS" | cut -s -d ' ' -f "$count")
addl_password=$(printf '%s' "$VPN_ADDL_PASSWORDS" | cut -s -d ' ' -f "$count")
done
fi
cat <<'EOF'
Write these down. You'll need them to connect!
VPN client setup: https://vpnsetup.net/clients2
================================================
EOF
fi
# Set up IKEv2
status=0
ikev2_sh="/opt/src/ikev2.sh"
ikev2_conf="/etc/ipsec.d/ikev2.conf"
ikev2_log="/etc/ipsec.d/ikev2setup.log"
if grep -q " /etc/ipsec.d " /proc/mounts && [ -s "$ikev2_sh" ] && [ ! -f "$ikev2_conf" ]; then
echo
echo "Setting up IKEv2. This may take a few moments..."
if VPN_DNS_NAME="$VPN_DNS_NAME" VPN_PUBLIC_IP="$public_ip" \
VPN_CLIENT_NAME="$VPN_CLIENT_NAME" VPN_XAUTH_POOL="$VPN_XAUTH_POOL" \
VPN_DNS_SRV1="$VPN_DNS_SRV1" VPN_DNS_SRV2="$VPN_DNS_SRV2" \
VPN_PROTECT_CONFIG="$VPN_PROTECT_CONFIG" \
/bin/bash "$ikev2_sh" --auto >"$ikev2_log" 2>&1; then
status=1
status_text="IKEv2 setup successful."
else
status=4
rm -f "$ikev2_conf"
echo "IKEv2 setup failed."
fi
chmod 600 "$ikev2_log"
fi
if [ "$status" = 0 ] && [ -f "$ikev2_conf" ] && [ -s "$ikev2_log" ]; then
status=2
status_text="IKEv2 is already set up."
fi
if [ "$status" = 1 ] || [ "$status" = 2 ]; then
cat <<EOF
================================================
$status_text Details for IKEv2 mode:
EOF
sed -n '/VPN server address:/,/Next steps:/p' "$ikev2_log"
cat <<'EOF'
https://vpnsetup.net/clients2
================================================
EOF
else
echo
fi
if [ "$status" = 2 ] && [ -n "$VPN_DNS_NAME" ]; then
server_addr_cur=$(grep -s "leftcert=" /etc/ipsec.d/ikev2.conf | cut -f2 -d=)
if [ "$VPN_DNS_NAME" != "$server_addr_cur" ]; then
cat <<'EOF'
Warning: The VPN_DNS_NAME variable you specified has no effect
for IKEv2 mode, because IKEv2 is already set up in this
container. To change the IKEv2 server address, see:
https://vpnsetup.net/ikev2docker
EOF
fi
fi
# Check for new Libreswan version
ts_file="/opt/src/swanver"
if [ ! -f "$ts_file" ] || [ "$(find "$ts_file" -mmin +10080)" ]; then
touch "$ts_file"
ipsec_ver=$(ipsec --version 2>/dev/null)
swan_ver=$(printf '%s' "$ipsec_ver" | sed -e 's/.*Libreswan U\?//' -e 's/\( (\|\/K\).*//')
base_url="https://github.com/hwdsl2/vpn-extras/releases/download/v1.0.0"
swan_ver_url="$base_url/upg-docker-$os_type-$os_arch-swanver"
swan_ver_latest=$(wget -t 2 -T 10 -qO- "$swan_ver_url" | head -n 1)
if printf '%s' "$swan_ver_latest" | grep -Eq '^([3-9]|[1-9][0-9]{1,2})(\.([0-9]|[1-9][0-9]{1,2})){1,2}$' \
&& [ -n "$swan_ver" ] && [ "$swan_ver" != "$swan_ver_latest" ] \
&& printf '%s\n%s' "$swan_ver" "$swan_ver_latest" | sort -C -V; then
cat <<EOF
Note: A newer version of Libreswan ($swan_ver_latest) is available.
To update this Docker image, see: https://vpnsetup.net/dockerupdate
EOF
fi
fi
# Start xl2tpd
mkdir -p /var/run/xl2tpd
rm -f /var/run/xl2tpd.pid
exec /usr/sbin/xl2tpd -D -c /etc/xl2tpd/xl2tpd.conf
|