|
| 1 | +#!/bin/bash |
| 2 | + |
| 3 | +if [ "$(whoami)" != "$OPENWISP_USER" ]; then |
| 4 | + echo "Script should only be run by $OPENWISP_USER. Exiting!" |
| 5 | + exit 9 |
| 6 | +fi |
| 7 | + |
| 8 | +# make sure this directory is writable by the user which calls the script |
| 9 | +CONF_DIR="/opt/openwisp" |
| 10 | + |
| 11 | +# do not modify these vars |
| 12 | +_VPN_URL_PATH="$API_INTERNAL/controller/vpn" |
| 13 | +_VPN_CHECKSUM_URL="$_VPN_URL_PATH/checksum/$VPN_UUID/?key=$VPN_KEY" |
| 14 | +_VPN_DOWNLOAD_URL="$_VPN_URL_PATH/download-config/$VPN_UUID/?key=$VPN_KEY" |
| 15 | +_WORKING_DIR="$CONF_DIR/.openwisp" |
| 16 | +_CHECKSUM_FILE="$_WORKING_DIR/checksum" |
| 17 | +_TIMESTAMP_FILE="$_WORKING_DIR/timestamp" |
| 18 | +_MANAGED_INTERFACE="$_WORKING_DIR/managed-interface" |
| 19 | +_APPLIED_CONF_DIR="$_WORKING_DIR/current-conf" |
| 20 | +_CONF_TAR="$_WORKING_DIR/conf.tar.gz" |
| 21 | +_CURL="curl -s --show-error --fail" |
| 22 | +if [ "$INSECURE_CURL" == true ]; then |
| 23 | + _CURL = "$_CURL --insecure" |
| 24 | +fi |
| 25 | + |
| 26 | +mkdir -p $_WORKING_DIR |
| 27 | +mkdir -p $_APPLIED_CONF_DIR |
| 28 | + |
| 29 | +assert_exit_code() { |
| 30 | + exit_code=$? |
| 31 | + lineno=$(($1 - 1)) |
| 32 | + if [ "$exit_code" != "0" ]; then |
| 33 | + echo "Line $lineno: Command returned non zero exit code: $exit_code" |
| 34 | + exit $exit_code |
| 35 | + fi |
| 36 | +} |
| 37 | + |
| 38 | +check_config() { |
| 39 | + _latest_checksum=$($_CURL $_VPN_CHECKSUM_URL) |
| 40 | + assert_exit_code $LINENO |
| 41 | + if [ -f "$_CHECKSUM_FILE" ]; then |
| 42 | + _current_checksum=$(cat $_CHECKSUM_FILE) |
| 43 | + else |
| 44 | + _current_checksum="" |
| 45 | + fi |
| 46 | + |
| 47 | + if [ "$_current_checksum" != "$_latest_checksum" ]; then |
| 48 | + echo "Configuration changed, downloading new configuration..." |
| 49 | + update_config |
| 50 | + fi |
| 51 | +} |
| 52 | + |
| 53 | +clean_old_interface() { |
| 54 | + echo "Bringing down old wireguard interface $managed_interface_name" |
| 55 | + for old_conf_file in $_APPLIED_CONF_DIR/*.conf; do |
| 56 | + [ -e "$old_conf_file" ] || continue |
| 57 | + sudo wg-quick down $old_conf_file |
| 58 | + done |
| 59 | + rm $_APPLIED_CONF_DIR/*.conf |
| 60 | +} |
| 61 | + |
| 62 | +create_new_interface() { |
| 63 | + echo "Bringing up new wireguard interface $interface" |
| 64 | + sudo wg-quick up $file |
| 65 | +} |
| 66 | + |
| 67 | +update_config() { |
| 68 | + # Set file permissions to 0660, otherwise wg will complain |
| 69 | + # for having public configurations |
| 70 | + umask 0117 |
| 71 | + $($_CURL $_VPN_DOWNLOAD_URL >"$_CONF_TAR") |
| 72 | + assert_exit_code $LINENO |
| 73 | + echo "Configuration downloaded, extracting it..." |
| 74 | + tar -zxvf $_CONF_TAR -C $CONF_DIR >/dev/null |
| 75 | + assert_exit_code $LINENO |
| 76 | + if [ -e "$_MANAGED_INTERFACE" ]; then |
| 77 | + managed_interface_name=$(cat "$_MANAGED_INTERFACE") |
| 78 | + fi |
| 79 | + |
| 80 | + for file in $CONF_DIR/*.conf; do |
| 81 | + [ -e "$file" ] || continue |
| 82 | + filename=$(basename $file) |
| 83 | + interface="${filename%.*}" |
| 84 | + |
| 85 | + # There is no managed_interface |
| 86 | + if [ -z ${managed_interface_name+x} ]; then |
| 87 | + create_new_interface |
| 88 | + # Current managed interface is not present in new configuration |
| 89 | + elif [ "$managed_interface_name" != "$interface" ]; then |
| 90 | + clean_old_interface |
| 91 | + assert_exit_code $LINENO |
| 92 | + create_new_interface |
| 93 | + assert_exit_code $LINENO |
| 94 | + else |
| 95 | + # Update the configuration of current managed interface |
| 96 | + echo "Reloading wireguard interface $interface with config file $file..." |
| 97 | + wg_conf_filename="$filename-wg" |
| 98 | + sudo wg-quick strip "$CONF_DIR/$filename" >"$CONF_DIR/$wg_conf_filename" |
| 99 | + assert_exit_code $LINENO |
| 100 | + sudo wg syncconf $interface "$CONF_DIR/$wg_conf_filename" |
| 101 | + assert_exit_code $LINENO |
| 102 | + rm "$CONF_DIR/$wg_conf_filename" |
| 103 | + fi |
| 104 | + echo "$interface" >"$_MANAGED_INTERFACE" |
| 105 | + mv -f "$file" "$_APPLIED_CONF_DIR/$filename" |
| 106 | + assert_exit_code $LINENO |
| 107 | + done |
| 108 | + |
| 109 | + # Save checksum of applied configuration |
| 110 | + echo $_latest_checksum >$_CHECKSUM_FILE |
| 111 | + |
| 112 | + export VXLAN_IPV4_METHOD="{{ openwisp2_wireguard_vxlan_ipv4_method }}" \ |
| 113 | + VXLAN_IPV6_METHOD="{{ openwisp2_wireguard_vxlan_ipv6_method }}" |
| 114 | + if [ -e "$CONF_DIR/vxlan.json" ]; then |
| 115 | + "$CONF_DIR/update_vxlan.py" "$CONF_DIR/vxlan.json" |
| 116 | + mv -f "$CONF_DIR/vxlan.json" "$_APPLIED_CONF_DIR/vxlan.json" |
| 117 | + fi |
| 118 | +} |
| 119 | + |
| 120 | +bring_up_interface() { |
| 121 | + for conf_file in $_APPLIED_CONF_DIR/*.conf; do |
| 122 | + [ -e "$conf_file" ] || continue |
| 123 | + sudo wg-quick up $conf_file || true |
| 124 | + done |
| 125 | + exit 0 |
| 126 | +} |
| 127 | + |
| 128 | +watch_configuration_change() { |
| 129 | + _REDIS_CMD="redis-cli -h $REDIS_HOST" |
| 130 | + if [[ "$REDIS_PORT" ]]; then |
| 131 | + _REDIS_CMD="$_REDIS_CMD -p $REDIS_PORT" |
| 132 | + fi |
| 133 | + if [[ "$REDIS_PASSWORD" ]]; then |
| 134 | + _REDIS_CMD="$_REDIS_CMD -a $REDIS_PASSWORD -n 15" |
| 135 | + fi |
| 136 | + while true; do |
| 137 | + if [ -f "$_TIMESTAMP_FILE" ]; then |
| 138 | + local_timestamp=$(cat $_TIMESTAMP_FILE) |
| 139 | + else |
| 140 | + local_timestamp="" |
| 141 | + fi |
| 142 | + current_timestamp=$($_REDIS_CMD GET wg-$VPN_UUID) |
| 143 | + if [ "$current_timestamp" != "$local_timestamp" ]; then |
| 144 | + echo "Configuration reload triggered by the updater." |
| 145 | + check_config |
| 146 | + assert_exit_code $LINENO |
| 147 | + # Save timestamp of applied configuration |
| 148 | + echo $current_timestamp >$_TIMESTAMP_FILE |
| 149 | + fi |
| 150 | + sleep 3 |
| 151 | + done |
| 152 | +} |
| 153 | + |
| 154 | +"$@" |
0 commit comments