diff options
| author | Jan Tuomi <jans.tuomi@gmail.com> | 2022-09-29 10:14:18 +0300 |
|---|---|---|
| committer | Jan Tuomi <jans.tuomi@gmail.com> | 2022-09-29 10:14:18 +0300 |
| commit | 418fa96576517390f1e6c36cf0b5b54b7f6fb0dc (patch) | |
| tree | 08d7ce9a453886a57d1d8075194184d6052ac825 /server.sh | |
Diffstat (limited to 'server.sh')
| -rwxr-xr-x | server.sh | 204 |
1 files changed, 204 insertions, 0 deletions
diff --git a/server.sh b/server.sh new file mode 100755 index 0000000..2c4d435 --- /dev/null +++ b/server.sh @@ -0,0 +1,204 @@ +#!/bin/bash + +DIR=/config/vpn-management-site +LOGFILE=/var/log/vpn-management-site.log + +set -eE + +err_report() { + error="HTTP/1.1 500 Internal server error\n\nserver.sh: Error on line ${1}" + echo -e error >> ${LOGFILE} + echo -e error +} + +trap 'err_report $LINENO' ERR + +# Read first line of HTTP request, set operation var +OP="" +IFS= read -r LINE_NL +LINE=${LINE_NL::-1} +if [[ "${LINE}" == "POST "* ]]; then + OP="modify_vpn" +elif [[ "${LINE}" == "GET /servers.json"* ]]; then + OP="get_server_list" +elif [[ "${LINE}" == "GET /"* ]]; then + OP="get_html" +else + RESPONSE="HTTP/1.1 400 Bad Request\n\nInvalid HTTP prelude\n${LINE}" + echo -e $RESPONSE >> ${LOGFILE} + echo -e $RESPONSE +fi + +# Find the content length (nc doesn't send an EOL) +CONTENT_LENGTH=-1 +while IFS= read -r LINE_NL; do + LINE=${LINE_NL::-1} + if [[ "${LINE}" == "Content-Length:"* ]]; then + CONTENT_LENGTH=${LINE:16} + elif [[ "${LINE}" == "" ]]; then + break + fi +done + +# If the request is about a static resource, just send that +if [[ "${OP}" == "get_html" ]]; then + HTML=$(cat ${DIR}/index.html) + RESPONSE="HTTP/1.1 200 OK\nContent-Type: text/html\n\n${HTML}" + echo -e RESPONSE >> ${LOGFILE} + echo -e RESPONSE + exit 0 +fi + +if [[ "${OP}" == "get_server_list" ]]; then + JSON=$(cat ${DIR}/servers.json) + RESPONSE="HTTP/1.1 200 OK\nContent-Type: application/json\n\n${JSON}" + echo -e RESPONSE >> ${LOGFILE} + echo -e RESPONSE + exit 0 +fi + +# Otherwise the request must be about setting the VPN state +if [[ "${OP}" != "modify_vpn" ]]; then + echo "Invalid operation ${OP}" >> ${LOGFILE} + RESPONSE="HTTP/1.1 400 Bad Request\n\n" + echo -e RESPONSE >> ${LOGFILE} + echo -e RESPONSE +fi + +# Read CONTENT_LENGTH worth of content +IFS= read -n${CONTENT_LENGTH} -d$'\0' -r CONTENT + +# Read the action field from the content JSON (either enable or disable) +ACTION=$(echo ${CONTENT} | jq -r .action) + +# Make router configuration commands available +source /opt/vyatta/etc/functions/script-template > /dev/null + +# If action is disable, disable the openvpn interface +if [[ "${ACTION}" == "disable" ]]; then + echo "Disabling VPN..." >> ${LOGFILE} + configure 2>&1 >> ${LOGFILE} + set interfaces openvpn vtun0 disable 2>&1 >> ${LOGFILE} + commit 2>&1 >> ${LOGFILE} + save 2>&1 >> ${LOGFILE} + + RESPONSE="HTTP/1.1 200 OK\n\nVPN disabled" + echo -e RESPONSE >> ${LOGFILE} + echo -e RESPONSE + exit 0 +fi + +# Otherwise the action must be enable +if [[ "${ACTION}" != "enable" ]]; then + echo "Invalid action ${ACTION}" >> ${LOGFILE} + + RESPONSE="HTTP/1.1 400 Bad Request\n\nInvalid action ${ACTION}" + echo -e RESPONSE >> ${LOGFILE} + echo -e RESPONSE + exit 1 +fi + +echo "Enabling VPN..." >> ${LOGFILE} + +# Read the VPN server domain and IP from the request content JSON +DOMAIN=$(echo ${CONTENT} | jq -r .domain) +IP=$(echo ${CONTENT} | jq -r .ip) + +# Produce an openvpn config +cat > /config/openvpn/vpn.ovpn <<- ENDOUT +client +dev tun +proto udp +remote ${IP} 1194 +resolv-retry infinite +remote-random +nobind +tun-mtu 1500 +tun-mtu-extra 32 +mssfix 1450 +persist-key +persist-tun +ping 15 +ping-restart 0 +ping-timer-rem +reneg-sec 0 +comp-lzo no +verify-x509-name CN=${DOMAIN} +remote-cert-tls server +auth-user-pass /config/openvpn/nordvpnauth.txt +route-nopull +verb 3 +pull +fast-io +cipher AES-256-CBC +auth SHA512 +<ca> +-----BEGIN CERTIFICATE----- +MIIFCjCCAvKgAwIBAgIBATANBgkqhkiG9w0BAQ0FADA5MQswCQYDVQQGEwJQQTEQ +MA4GA1UEChMHTm9yZFZQTjEYMBYGA1UEAxMPTm9yZFZQTiBSb290IENBMB4XDTE2 +MDEwMTAwMDAwMFoXDTM1MTIzMTIzNTk1OVowOTELMAkGA1UEBhMCUEExEDAOBgNV +BAoTB05vcmRWUE4xGDAWBgNVBAMTD05vcmRWUE4gUm9vdCBDQTCCAiIwDQYJKoZI +hvcNAQEBBQADggIPADCCAgoCggIBAMkr/BYhyo0F2upsIMXwC6QvkZps3NN2/eQF +kfQIS1gql0aejsKsEnmY0Kaon8uZCTXPsRH1gQNgg5D2gixdd1mJUvV3dE3y9FJr +XMoDkXdCGBodvKJyU6lcfEVF6/UxHcbBguZK9UtRHS9eJYm3rpL/5huQMCppX7kU +eQ8dpCwd3iKITqwd1ZudDqsWaU0vqzC2H55IyaZ/5/TnCk31Q1UP6BksbbuRcwOV +skEDsm6YoWDnn/IIzGOYnFJRzQH5jTz3j1QBvRIuQuBuvUkfhx1FEwhwZigrcxXu +MP+QgM54kezgziJUaZcOM2zF3lvrwMvXDMfNeIoJABv9ljw969xQ8czQCU5lMVmA +37ltv5Ec9U5hZuwk/9QO1Z+d/r6Jx0mlurS8gnCAKJgwa3kyZw6e4FZ8mYL4vpRR +hPdvRTWCMJkeB4yBHyhxUmTRgJHm6YR3D6hcFAc9cQcTEl/I60tMdz33G6m0O42s +Qt/+AR3YCY/RusWVBJB/qNS94EtNtj8iaebCQW1jHAhvGmFILVR9lzD0EzWKHkvy +WEjmUVRgCDd6Ne3eFRNS73gdv/C3l5boYySeu4exkEYVxVRn8DhCxs0MnkMHWFK6 +MyzXCCn+JnWFDYPfDKHvpff/kLDobtPBf+Lbch5wQy9quY27xaj0XwLyjOltpiST +LWae/Q4vAgMBAAGjHTAbMAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQDAgEGMA0GCSqG +SIb3DQEBDQUAA4ICAQC9fUL2sZPxIN2mD32VeNySTgZlCEdVmlq471o/bDMP4B8g +nQesFRtXY2ZCjs50Jm73B2LViL9qlREmI6vE5IC8IsRBJSV4ce1WYxyXro5rmVg/ +k6a10rlsbK/eg//GHoJxDdXDOokLUSnxt7gk3QKpX6eCdh67p0PuWm/7WUJQxH2S +DxsT9vB/iZriTIEe/ILoOQF0Aqp7AgNCcLcLAmbxXQkXYCCSB35Vp06u+eTWjG0/ +pyS5V14stGtw+fA0DJp5ZJV4eqJ5LqxMlYvEZ/qKTEdoCeaXv2QEmN6dVqjDoTAo +k0t5u4YRXzEVCfXAC3ocplNdtCA72wjFJcSbfif4BSC8bDACTXtnPC7nD0VndZLp ++RiNLeiENhk0oTC+UVdSc+n2nJOzkCK0vYu0Ads4JGIB7g8IB3z2t9ICmsWrgnhd +NdcOe15BincrGA8avQ1cWXsfIKEjbrnEuEk9b5jel6NfHtPKoHc9mDpRdNPISeVa +wDBM1mJChneHt59Nh8Gah74+TM1jBsw4fhJPvoc7Atcg740JErb904mZfkIEmojC +VPhBHVQ9LHBAdM8qFI2kRK0IynOmAZhexlP/aT/kpEsEPyaZQlnBn3An1CRz8h0S +PApL8PytggYKeQmRhl499+6jLxcZ2IegLfqq41dzIjwHwTMplg+1pKIOVojpWA== +-----END CERTIFICATE----- +</ca> +key-direction 1 +<tls-auth> +# +# 2048 bit OpenVPN static key +# +-----BEGIN OpenVPN Static key V1----- +e685bdaf659a25a200e2b9e39e51ff03 +0fc72cf1ce07232bd8b2be5e6c670143 +f51e937e670eee09d4f2ea5a6e4e6996 +5db852c275351b86fc4ca892d78ae002 +d6f70d029bd79c4d1c26cf14e9588033 +cf639f8a74809f29f72b9d58f9b8f5fe +fc7938eade40e9fed6cb92184abb2cc1 +0eb1a296df243b251df0643d53724cdb +5a92a1d6cb817804c4a9319b57d53be5 +80815bcfcb2df55018cc83fc43bc7ff8 +2d51f9b88364776ee9d12fc85cc7ea5b +9741c4f598c485316db066d52db4540e +212e1518a9bd4828219e24b20d88f598 +a196c9de96012090e333519ae18d3509 +9427e7b372d348d352dc4c85e18cd4b9 +3f8a56ddb2e64eb67adfc9b337157ff4 +-----END OpenVPN Static key V1----- +</tls-auth> +ENDOUT + +# Cycle the openvpn interface off and on to force config reload +configure 2>&1 >> ${LOGFILE} +set interfaces openvpn vtun0 disable 2>&1 >> ${LOGFILE} +commit 2>&1 >> ${LOGFILE} +delete interfaces openvpn vtun0 disable 2>&1 >> ${LOGFILE} +commit 2>&1 >> ${LOGFILE} +save 2>&1 >> ${LOGFILE} + +# Send OK response +RESPONSE="HTTP/1.1 200 OK\n\nVPN enabled, IP: ${IP}, domain: ${DOMAIN}" +echo -e RESPONSE >> ${LOGFILE} +echo -e RESPONSE +exit 0 |
