wireguard.sh (4830B)
1 #!/bin/sh 2 # Copyright 2016-2017 Dan Luedtke <mail@danrl.com> 3 # Licensed to the public under the Apache License 2.0. 4 5 6 WG=/usr/bin/wg 7 if [ ! -x $WG ]; then 8 logger -t "wireguard" "error: missing wireguard-tools (${WG})" 9 exit 0 10 fi 11 12 13 [ -n "$INCLUDE_ONLY" ] || { 14 . /lib/functions.sh 15 . ../netifd-proto.sh 16 init_proto "$@" 17 } 18 19 20 proto_wireguard_init_config() { 21 proto_config_add_string "private_key" 22 proto_config_add_int "listen_port" 23 proto_config_add_int "mtu" 24 proto_config_add_string "preshared_key" 25 proto_config_add_string "fwmark" 26 available=1 27 no_proto_task=1 28 } 29 30 31 proto_wireguard_setup_peer() { 32 local peer_config="$1" 33 34 local public_key 35 local allowed_ips 36 local route_allowed_ips 37 local endpoint_host 38 local endpoint_port 39 local persistent_keepalive 40 41 config_get public_key "${peer_config}" "public_key" 42 config_get allowed_ips "${peer_config}" "allowed_ips" 43 config_get_bool route_allowed_ips "${peer_config}" "route_allowed_ips" 0 44 config_get endpoint_host "${peer_config}" "endpoint_host" 45 config_get endpoint_port "${peer_config}" "endpoint_port" 46 config_get persistent_keepalive "${peer_config}" "persistent_keepalive" 47 48 # peer configuration 49 echo "[Peer]" >> "${wg_cfg}" 50 echo "PublicKey=${public_key}" >> "${wg_cfg}" 51 for allowed_ip in $allowed_ips; do 52 echo "AllowedIPs=${allowed_ip}" >> "${wg_cfg}" 53 done 54 if [ "${endpoint_host}" ]; then 55 case "${endpoint_host}" in 56 *:*) 57 endpoint="[${endpoint_host}]" 58 ;; 59 *) 60 endpoint="${endpoint_host}" 61 ;; 62 esac 63 if [ "${endpoint_port}" ]; then 64 endpoint="${endpoint}:${endpoint_port}" 65 else 66 endpoint="${endpoint}:51820" 67 fi 68 echo "Endpoint=${endpoint}" >> "${wg_cfg}" 69 fi 70 if [ "${persistent_keepalive}" ]; then 71 echo "PersistentKeepalive=${persistent_keepalive}" >> "${wg_cfg}" 72 fi 73 74 # add routes for allowed ips 75 if [ ${route_allowed_ips} -ne 0 ]; then 76 for allowed_ip in ${allowed_ips}; do 77 case "${allowed_ip}" in 78 *:*/*) 79 proto_add_ipv6_route "${allowed_ip%%/*}" "${allowed_ip##*/}" 80 ;; 81 */*) 82 proto_add_ipv4_route "${allowed_ip%%/*}" "${allowed_ip##*/}" 83 ;; 84 esac 85 done 86 fi 87 } 88 89 90 proto_wireguard_setup() { 91 local config="$1" 92 local wg_dir="/tmp/wireguard" 93 local wg_cfg="${wg_dir}/${config}" 94 95 local private_key 96 local listen_port 97 local mtu 98 local preshared_key 99 100 # load configuration 101 config_load network 102 config_get private_key "${config}" "private_key" 103 config_get listen_port "${config}" "listen_port" 104 config_get addresses "${config}" "addresses" 105 config_get mtu "${config}" "mtu" 106 config_get preshared_key "${config}" "preshared_key" 107 config_get fwmark "${config}" "fwmark" 108 109 # create interface 110 ip link del dev "${config}" 2>/dev/null 111 ip link add dev "${config}" type wireguard 112 113 if [ "${mtu}" ]; then 114 ip link set mtu "${mtu}" dev "${config}" 115 fi 116 117 proto_init_update "${config}" 1 118 119 # generate configuration file 120 umask 077 121 mkdir -p "${wg_dir}" 122 echo "[Interface]" > "${wg_cfg}" 123 echo "PrivateKey=${private_key}" >> "${wg_cfg}" 124 if [ "${listen_port}" ]; then 125 echo "ListenPort=${listen_port}" >> "${wg_cfg}" 126 fi 127 if [ "${preshared_key}" ]; then 128 echo "PresharedKey=${preshared_key}" >> "${wg_cfg}" 129 fi 130 if [ "${fwmark}" ]; then 131 echo "FwMark=${fwmark}" >> "${wg_cfg}" 132 fi 133 config_foreach proto_wireguard_setup_peer "wireguard_${config}" 134 135 # apply configuration file 136 ${WG} setconf ${config} "${wg_cfg}" 137 WG_RETURN=$? 138 139 # delete configuration file 140 rm -f "${wg_cfg}" 141 142 # check status 143 if [ ${WG_RETURN} -ne 0 ]; then 144 sleep 5 145 proto_setup_failed "${config}" 146 exit 1 147 fi 148 149 # add ip addresses 150 for address in ${addresses}; do 151 case "${address}" in 152 *:*/*) 153 proto_add_ipv6_address "${address%%/*}" "${address##*/}" 154 ;; 155 *.*/*) 156 proto_add_ipv4_address "${address%%/*}" "${address##*/}" 157 ;; 158 *:*) 159 proto_add_ipv6_address "${address%%/*}" "128" 160 ;; 161 *.*) 162 proto_add_ipv4_address "${address%%/*}" "32" 163 ;; 164 esac 165 done 166 167 # endpoint dependency 168 wg show "${config}" endpoints | \ 169 sed -E 's/\[?([0-9.:a-f]+)\]?:([0-9]+)/\1 \2/' | \ 170 while IFS=$'\t ' read -r key address port; do 171 [ -n "${port}" ] || continue 172 echo "adding host depedency for ${address} at ${config}" 173 proto_add_host_dependency "${config}" "${address}" 174 done 175 176 proto_send_update "${config}" 177 } 178 179 180 proto_wireguard_teardown() { 181 local config="$1" 182 ip link del dev "${config}" >/dev/null 2>&1 183 } 184 185 186 [ -n "$INCLUDE_ONLY" ] || { 187 add_protocol wireguard 188 }