diff --git a/.env.example b/.env.example index 85374c5..8bb08e7 100644 --- a/.env.example +++ b/.env.example @@ -11,14 +11,15 @@ DB_PASS=openvpn_pass # OpenVPN settings VPN_CONF=/etc/openvpn -VPN_LOCAL=192.168.1.2 +VPN_DEV=tun0 +VPN_PROTO=tcp +VPN_LISTEN=192.168.1.2 +VPN_LISTEN_PORT=1194 VPN_REMOTE=172.10.12.15 +VPN_REMOTE_PORT=443 VPN_USER=nobody VPN_GROUP=nogroup -VPN_PORT=1194 -VPN_PROTO=tcp -VPN_INIF=tun0 -VPN_OUTIF=eth0 +VPN_IF=eth0 # TODO: Rewrite this part to ipcalc VPN_SERVER="10.8.0.0 255.255.255.0" VPN_NET=10.8.0.0/24 diff --git a/app/ovpn.php b/app/ovpn.php index 1a5ffdd..d19f590 100644 --- a/app/ovpn.php +++ b/app/ovpn.php @@ -2,38 +2,39 @@ $_ovpn = new EvilFreelancer\OpenVPN(); -$_ovpn->dev = getenv('VPN_INIF'); -$_ovpn->proto = getenv('VPN_PROTO'); -$_ovpn->port = getenv('VPN_PORT'); -$_ovpn->remote = getenv('VPN_REMOTE'); -$_ovpn->resolvRetry = 'infinite'; -$_ovpn->cipher = 'AES-256-CBC'; -$_ovpn->redirectGateway = true; - -$_ovpn->addCert('ca', getenv('VPN_CONF') . '/ca.crt', true) -->addCert('tls-auth', getenv('VPN_CONF') . '/ta.key', true); - -$_ovpn->keyDirection = 1; -$_ovpn->remoteCertTls = 'server'; -$_ovpn->authUserPass = true; -$_ovpn->authNocache = true; - -$_ovpn->nobind = true; -$_ovpn->persistKey = true; -$_ovpn->persistTun = true; -$_ovpn->compLzo = true; -$_ovpn->verb = 3; - -$config = $_ovpn->getClientConfig(); +$_ovpn + ->addParam('client') + ->addParam('dev', getenv('VPN_INIF')) + ->addParam('proto', getenv('VPN_PROTO')) + ->addParam('remote', getenv('VPN_REMOTE')) + ->addParam('port', getenv('VPN_REMOTE_PORT')) + ->addParam('resolv-retry', 'infinite') + ->addParam('cipher', 'AES-256-CBC') + ->addParam('redirect-gateway', true) + ->addParam('key-direction', 1) + ->addParam('remote-cert-tls', 'server') + ->addParam('auth-user-pass', true) + ->addParam('auth-nocache', true) + ->addParam('nobind', true) + ->addParam('persist-key', true) + ->addParam('persist-tun', true) + ->addParam('comp-lzo', true) + ->addParam('verb', 3); + +$_ovpn + ->addCert('ca', getenv('VPN_CONF') . '/ca.crt', true) + ->addCert('tls-auth', getenv('VPN_CONF') . '/ta.key', true); + +$config = $_ovpn->generateConfig(); switch ($_POST['configuration_os']) { -case 'gnu_linux': -case 'configuration_os': -$filename = 'client.conf'; -break; -default: -$filename = 'client.ovpn'; -break; + case 'gnu_linux': + case 'configuration_os': + $filename = 'client.conf'; + break; + default: + $filename = 'client.ovpn'; + break; } header('Content-Type:text/plain'); @@ -41,4 +42,4 @@ header("Content-Disposition: attachment; filename=$filename"); header("Pragma: no-cache"); header("Expires: 0"); -die("$config"); \ No newline at end of file +die("$config"); diff --git a/composer.json b/composer.json index fc856c5..223764a 100644 --- a/composer.json +++ b/composer.json @@ -12,6 +12,6 @@ ], "require": { "vlucas/phpdotenv": "^2.4", - "evilfreelancer/openvpn-php": "^0.1.1" + "evilfreelancer/openvpn-php": "^0.2.0" } } diff --git a/configs/server.conf b/configs/server.conf deleted file mode 100644 index c0372b0..0000000 --- a/configs/server.conf +++ /dev/null @@ -1,91 +0,0 @@ -## GENERAL ## - -# TCP or UDP, port 443, tunneling -mode server -proto VPN_PROTO -port VPN_PORT -dev VPN_INIF - -## KEY, CERTS AND NETWORK CONFIGURATION ## -# Identity -ca ca.crt -# Public key -cert server.crt -# Private key -key server.key -# Symmetric encryption -dh dh.pem -# Improve security (DDOS, port flooding...) -# 0 for the server, 1 for the client -tls-auth ta.key 0 -# Encryption protocol -cipher AES-256-CBC - -# Network -# Subnetwork, the server will be the 10.8.0.1 and clients will take the other ips -server VPN_SERVER - -# Redirect all IP network traffic originating on client machines to pass through the OpenVPN server -push "redirect-gateway def1" - -# Alternatives DNS (FDN) -push "dhcp-option DNS 80.67.169.12" -push "dhcp-option DNS 80.67.169.40" - -# (OpenDNS) -# push "dhcp-option DNS 208.67.222.222" -# push "dhcp-option DNS 208.67.220.220" - -# (Google) -# push "dhcp-option DNS 8.8.8.8" -# push "dhcp-option DNS 8.8.4.4" - -# Ping every 10 seconds and if after 120 seconds the client doesn't respond we disconnect -keepalive 10 120 -# Regenerate key each 5 hours (disconnect the client) -reneg-sec 18000 - -## SECURITY ## - -# Downgrade privileges of the daemon -user VPN_USER -group VPN_GROUP - -# Persist keys (because we are nobody, so we couldn't read them again) -persist-key -# Don't close and re open TUN/TAP device -persist-tun -# Enable compression -comp-lzo - -## LOG ## - -# Verbosity -# 3/4 for a normal utilisation -verb 3 -# Max 20 messages of the same category -mute 20 -# Log gile where we put the clients status -status /var/log/openvpn/status.log -# Log file -log-append /var/log/openvpn/openvpn.log -# Configuration directory of the clients -client-config-dir ccd - -## PASS ## - -# Allow running external scripts with password in ENV variables -script-security 3 - -# Use the authenticated username as the common name, rather than the common name from the client cert -username-as-common-name -# Client certificate is not required -verify-client-cert none -# Maximum of clients -max-clients 50 - -# Use the connection script when a user wants to login -auth-user-pass-verify SCRIPTS_LOGIN via-env -# Run this scripts when the client connects/disconnects -client-connect SCRIPTS_CONNECT -client-disconnect SCRIPTS_DISCONNECT diff --git a/scripts/install/00_env.sh b/scripts/install/00_env.sh index 0673edd..f8af1b9 100644 --- a/scripts/install/00_env.sh +++ b/scripts/install/00_env.sh @@ -2,22 +2,26 @@ printf "\n################## Server informations ##################\n" -[ ! -z "$VPN_LOCAL" ] && echo "VPN_LOCAL=$VPN_LOCAL" -[ -z "$VPN_LOCAL" ] && read -p "Server local Hostname/IP: " VPN_LOCAL -[ -z "$VPN_LOCAL" ] && print_error "Server local address is required!" +[ ! -z "$VPN_LISTEN" ] && echo "VPN_LISTEN=$VPN_LISTEN" +[ -z "$VPN_LISTEN" ] && read -p "Server local Hostname/IP: " VPN_LISTEN +[ -z "$VPN_LISTEN" ] && print_error "Server local address is required!" -[ ! -z "$VPN_REMOTE" ] && echo "VPN_LOCAL=$VPN_REMOTE" +[ ! -z "$VPN_LISTEN_PORT" ] && echo "VPN_LISTEN_PORT=$VPN_LISTEN_PORT" +[ -z "$VPN_LISTEN_PORT" ] && read -p "OpenVPN listen port [1194]: " VPN_LISTEN_PORT +[ -z "$VPN_LISTEN_PORT" ] && VPN_LISTEN_PORT="1194" + +[ ! -z "$VPN_REMOTE" ] && echo "VPN_REMOTE=$VPN_REMOTE" [ -z "$VPN_REMOTE" ] && read -p "Server remote Hostname/IP: " VPN_REMOTE [ -z "$VPN_REMOTE" ] && print_error "Server remote address is required!" +[ ! -z "$VPN_REMOTE_PORT" ] && echo "VPN_REMOTE_PORT=$VPN_REMOTE_PORT" +[ -z "$VPN_REMOTE_PORT" ] && read -p "OpenVPN remote port [443]: " VPN_REMOTE_PORT +[ -z "$VPN_REMOTE_PORT" ] && VPN_REMOTE_PORT="443" + [ ! -z "$VPN_PROTO" ] && echo "VPN_PROTO=$VPN_PROTO" [ -z "$VPN_PROTO" ] && read -p "OpenVPN protocol (tcp or udp) [tcp]: " VPN_PROTO [ -z "$VPN_PROTO" ] && VPN_PROTO="tcp" -[ ! -z "$VPN_PORT" ] && echo "VPN_PORT=$VPN_PORT" -[ -z "$VPN_PORT" ] && read -p "OpenVPN port [443]: " VPN_PORT -[ -z "$VPN_PORT" ] && VPN_PORT="443" - [ ! -z "$VPN_USER" ] && echo "VPN_USER=$VPN_USER" [ -z "$VPN_USER" ] && read -p "OpenVPN user [nobody]: " VPN_USER [ -z "$VPN_USER" ] && VPN_USER="nobody" @@ -26,13 +30,13 @@ printf "\n################## Server informations ##################\n" [ -z "$VPN_GROUP" ] && read -p "OpenVPN group [nogroup]: " VPN_GROUP [ -z "$VPN_GROUP" ] && VPN_GROUP="nogroup" -[ ! -z "$VPN_INIF" ] && echo "VPN_INIF=$VPN_INIF" -[ -z "$VPN_INIF" ] && read -p "OpenVPN tunnel interface [tun0]: " VPN_INIF -[ -z "$VPN_INIF" ] && VPN_INIF="tun0" +[ ! -z "$VPN_DEV" ] && echo "VPN_DEV=$VPN_DEV" +[ -z "$VPN_DEV" ] && read -p "OpenVPN tunnel interface [tun0]: " VPN_DEV +[ -z "$VPN_DEV" ] && VPN_DEV="tun0" -[ ! -z "$VPN_OUTIF" ] && echo "VPN_OUTIF=$VPN_OUTIF" -[ -z "$VPN_OUTIF" ] && read -p "OpenVPN physical interface [eth0]: " VPN_OUTIF -[ -z "$VPN_OUTIF" ] && VPN_OUTIF="eth0" +[ ! -z "$VPN_IF" ] && echo "VPN_IF=$VPN_IF" +[ -z "$VPN_IF" ] && read -p "OpenVPN physical interface [eth0]: " VPN_IF +[ -z "$VPN_IF" ] && VPN_IF="eth0" [ ! -z "$VPN_NET" ] && echo "VPN_NET=$VPN_NET" [ -z "$VPN_NET" ] && read -p "OpenVPN clients subnet [10.8.0.0/24]: " VPN_NET diff --git a/scripts/install/04_openvpn.sh b/scripts/install/04_openvpn.sh index 4be36a0..7346e92 100644 --- a/scripts/install/04_openvpn.sh +++ b/scripts/install/04_openvpn.sh @@ -4,18 +4,12 @@ printf "\n################## Setup OpenVPN ##################\n" # Copy certificates and the server configuration in the openvpn directory cp "$VPN_CONF/easy-rsa/pki/"{ca.crt,ta.key,issued/server.crt,private/server.key,dh.pem} "$VPN_CONF/" + +# Certs must be readable via web interface chmod +r $VPN_CONF/{ca.crt,ta.key} -cp "$base_path/../configs/server.conf" "$VPN_CONF/" + +# Configuration directory of the clients mkdir -p "$VPN_CONF/ccd" -sed " -s/VPN_SERVER/$VPN_SERVER/; -s/VPN_PORT/$VPN_PORT/ -s/VPN_INIF/$VPN_INIF/ -s/VPN_PROTO/$VPN_PROTO/ -s/VPN_GROUP/$VPN_GROUP/ -s/VPN_USER/$VPN_USER/ -s|SCRIPTS_LOGIN|$SCRIPTS_LOGIN| -s|SCRIPTS_CONNECT|$SCRIPTS_CONNECT| -s|SCRIPTS_DISCONNECT|$SCRIPTS_DISCONNECT| -" -i "$VPN_CONF/server.conf" +# Generate server config +php -f "$base_path/server-conf.php" > "$VPN_CONF/server.conf" diff --git a/scripts/install/05_firewall.sh b/scripts/install/05_firewall.sh index 6198d4b..2127e92 100644 --- a/scripts/install/05_firewall.sh +++ b/scripts/install/05_firewall.sh @@ -7,10 +7,10 @@ echo 1 > "/proc/sys/net/ipv4/ip_forward" echo "net.ipv4.ip_forward = 1" >> "/etc/sysctl.conf" # Iptable rules -iptables -I FORWARD -i $VPN_INIF -j ACCEPT -iptables -I FORWARD -o $VPN_INIF -j ACCEPT -iptables -I OUTPUT -o $VPN_INIF -j ACCEPT +iptables -I FORWARD -i $VPN_DEV -j ACCEPT +iptables -I FORWARD -o $VPN_DEV -j ACCEPT +iptables -I OUTPUT -o $VPN_DEV -j ACCEPT -iptables -A FORWARD -i $VPN_INIF -o $VPN_OUTIF -j ACCEPT -iptables -t nat -A POSTROUTING -o $VPN_OUTIF -j MASQUERADE -iptables -t nat -A POSTROUTING -s $VPN_NET -o $VPN_OUTIF -j MASQUERADE +iptables -A FORWARD -i $VPN_DEV -o $VPN_IF -j ACCEPT +iptables -t nat -A POSTROUTING -o $VPN_IF -j MASQUERADE +iptables -t nat -A POSTROUTING -s $VPN_NET -o $VPN_IF -j MASQUERADE diff --git a/scripts/server-conf.php b/scripts/server-conf.php new file mode 100644 index 0000000..264114f --- /dev/null +++ b/scripts/server-conf.php @@ -0,0 +1,63 @@ +load(); + +$_ovpn = new EvilFreelancer\OpenVPN(); + +// TCP or UDP, port 443, tunneling +$_ovpn + ->addParam('server') + ->addParam('dev', getenv('VPN_DEV')) + ->addParam('proto', getenv('VPN_PROTO')) + ->addParam('port', getenv('VPN_LISTEN_PORT')); + +// If listening address is set +if (!empty(getenv('VPN_LISTEN'))) + $_ovpn->addParam('listen', getenv('VPN_LISTEN')); + +// KEY, CERTS AND NETWORK CONFIGURATION +$_ovpn + ->addCert('ca', getenv('VPN_CONF') . '/ca.crt') + ->addCert('cert', getenv('VPN_CONF') . '/server.crt') + ->addCert('key', getenv('VPN_CONF') . '/server.key') + ->addCert('dh', getenv('VPN_CONF') . '/dh.pem') + ->addCert('tls-auth', getenv('VPN_CONF') . '/ta.key', false, '0') + ->addParam('cipher', 'AES-256-CBC') + ->addParam('server', getenv('VPN_SERVER')) + ->addPush('redirect-gateway def1') + ->addPush('dhcp-option DNS 8.8.8.8') + ->addPush('dhcp-option DNS 8.8.4.4') + ->addParam('keepalive', '10 120') + ->addParam('reneg-sec', '18000'); + +// SECURITY +$_ovpn + ->addParam('user', getenv('VPN_USER')) + ->addParam('group', getenv('VPN_GROUP')) + ->addParam('persist-key') + ->addParam('persist-tun') + ->addParam('comp-lzo'); + +// LOG +$_ovpn + ->addParam('verb', 3) + ->addParam('mute', 20) + ->addParam('status', '/var/log/openvpn/status.log') + ->addParam('log-append', '/var/log/openvpn/openvpn.log') + ->addParam('client-config-dir', 'ccd'); + +// PASS +$_ovpn + ->addParam('script-security', 3) + ->addParam('username-as-common-name') + ->addParam('verify-client-cert', 'none') + ->addParam('max-clients', '50') + ->addParam('auth-user-pass-verify', getenv('SCRIPTS_LOGIN') . ' via-env') + ->addParam('client-connect', getenv('SCRIPTS_CONNECT')) + ->addParam('client-disconnect', getenv('SCRIPTS_DISCONNECT')); + +$config = $_ovpn->generateConfig(); + +die("$config");