wg-installer: add wg-installer

This tool can be used to automatically create wireguard tunnels. Using
rpcd a new wireguard interface is created on the server where the client
can connect to.

Wiregurad server automatically installs a user and associated ACL to use
the wireguard-installer-server features. The user is called wginstaller
and so is the password.

Get Usage:
  wg-client-installer get_usage --ip 127.0.0.1 --user wginstaller
	--password wginstaller

Register Interface:
  wg-client-installer register --ip 127.0.0.1 --user wginstaller
         --password wginstaller --bandwidth 10 --mtu 1400

Signed-off-by: Nick Hainke <vincent@systemli.org>
This commit is contained in:
Nick Hainke
2021-02-04 16:34:02 +01:00
committed by Polynomdivision
parent d29ec52a58
commit 3a6949dfaf
11 changed files with 494 additions and 0 deletions
@@ -0,0 +1,8 @@
config client
option wg_key '/root/wg.key'
option wg_pub '/root/wg.pub'
option base_prefix '2000::/64'
option port_start '51820'
option port_end '52820'
option try_insecure '1'
option try_http '1'
+134
View File
@@ -0,0 +1,134 @@
. /usr/share/libubox/jshn.sh
query_gw () {
local ip=$1
local req=$2
# first try https
ret=$(curl https://$ip/ubus -d "$req") 2>/dev/null
if [ $? -eq 0 ]; then
echo $ret
return 0
fi
# try with --insecure
if [ $(uci get wgclient.@client[0].try_insecure) == '1' ]; then
ret=$(curl --insecure https://$ip/ubus -d "$req") 2>/dev/null
if [ $? -eq 0 ]; then
echo $ret
return 0
fi
fi
# try with http
if [ $(uci get wgclient.@client[0].try_http) == '1' ]; then
ret=$(curl http://$ip/ubus -d "$req") 2>/dev/null
if [ $? -eq 0 ]; then
echo $ret
return 0
fi
fi
return 1
}
request_token () {
local ip=$1
local user=$2
local password=$3
json_init
json_add_string "jsonrpc" "2.0"
json_add_int "id" "1"
json_add_string "method" "call"
json_add_array "params"
json_add_string "" "00000000000000000000000000000000"
json_add_string "" "session"
json_add_string "" "login"
json_add_object
json_add_string "username" $user
json_add_string "password" $password
json_close_object
json_close_array
req=$(json_dump)
ret=$(query_gw $ip "$req") 2>/dev/null
if [ $? != 0 ]; then
return 1
fi
json_load "$ret"
json_get_vars result result
json_select result
json_select 2
json_get_var ubus_rpc_session ubus_rpc_session
echo $ubus_rpc_session
}
wg_rpcd_get_usage () {
local token=$1
local ip=$2
local secret=$3
json_init
json_add_string "jsonrpc" "2.0"
json_add_int "id" "1"
json_add_string "method" "call"
json_add_array "params"
json_add_string "" $token
json_add_string "" "wginstaller"
json_add_string "" "get_usage"
json_add_object
json_close_object
json_close_array
req=$(json_dump)
ret=$(query_gw $ip "$req") 2>/dev/null
if [ $? != 0 ]; then
return 1
fi
# return values
json_load "$ret"
json_get_vars result result
json_select result
json_select 2
json_get_var num_interfaces num_interfaces
echo "num_interfaces: ${num_interfaces}"
}
wg_rpcd_register () {
local token=$1
local ip=$2
local uplink_bw=$3
local mtu=$4
local public_key=$5
json_init
json_add_string "jsonrpc" "2.0"
json_add_int "id" "1"
json_add_string "method" "call"
json_add_array "params"
json_add_string "" $token
json_add_string "" "wginstaller"
json_add_string "" "register"
json_add_object
json_add_int "uplink_bw" $uplink_bw
json_add_int "mtu" $mtu
json_add_string "public_key" $public_key
json_close_object
json_close_array
req=$(json_dump)
ret=$(query_gw $ip "$req") 2>/dev/null
if [ $? != 0 ]; then
return 1
fi
json_load "$ret"
json_get_vars result result
json_select result
json_select 2
json_get_var pubkey pubkey
json_get_var gw_ip gw_ip
json_get_var port port
echo "pubkey: ${pubkey}"
echo "gw_ip: ${gw_ip}"
echo "port: ${port}"
}
@@ -0,0 +1,119 @@
#!/bin/sh
. /usr/share/wginstaller/rpcd_ubus.sh
. /usr/share/wginstaller/wg.sh
CMD=$1
shift
while true; do
case "$1" in
-h | --help)
echo "help"
shift 1
;;
-i | --ip)
IP=$2
shift 2
;;
--user)
USER=$2
shift 2
;;
--password)
PASSWORD=$2
shift 2
;;
--bandwidth)
BANDWIDTH=$2
shift 2
;;
--mtu)
WG_MTU=$2
shift 2
;;
'')
break
;;
*)
break
;;
esac
done
escape_ip () {
local gw_ip=$1
# ipv4 processing
ret_ip=$(echo $gw_ip | tr '.' '_')
# ipv6 processing
ret_ip=$(echo $ret_ip | tr ':' '_')
ret_ip=$(echo $ret_ip | cut -d '[' -f 2)
ret_ip=$(echo $ret_ip | cut -d ']' -f 1)
echo $ret_ip
}
register_client_interface () {
local pubkey=$1
local gw_ip=$2
local gw_port=$3
local endpoint=$4
local mtu_client=$5
gw_key=$(uci get wgclient.@client[0].wg_key)
interface_name="gw_$(escape_ip $endpoint)"
port_start=$(uci get wgclient.@client[0].port_start)
port_end=$(uci get wgclient.@client[0].port_end)
base_prefix=$(uci get wgclient.@client[0].base_prefix)
port=$(next_port $port_start $port_end)
ifname="wg_$port"
offset=$(($port - $port_start))
client_ip=$(owipcalc $base_prefix add $offset next 128)
client_ip_assign="${client_ip}/128"
echo "Installing Interface With:"
echo "Endpoint ${endpoint}"
echo "Client IP ${client_ip}"
echo "Port ${port}"
echo "Pubkey ${pubkey}"
ip link add dev $ifname type wireguard
ip -6 a a dev $ifname $client_ip
wg set $ifname listen-port $port private-key $gw_key peer $pubkey allowed-ips ::/0 endpoint "${endpoint}:${gw_port}"
ip link set up dev $ifname
ip link set mtu $mtu_client dev $ifname # configure mtu here!
}
# rpc login
token="$(request_token $IP $USER $PASSWORD)"
if [ $? != 0 ]; then
echo "failed to register token"
exit 1
fi
# now call procedure
case $CMD in
"get_usage")
wg_rpcd_get_usage $token $IP
;;
"register")
gw_pub=$(uci get wgclient.@client[0].wg_pub)
gw_pub_string=$(cat $gw_pub)
register_output=$(wg_rpcd_register $token $IP $BANDWIDTH $WG_MTU $gw_pub_string)
if [ $? != 0 ]; then
echo "Failed to Register!"
exit 1
fi
pubkey=$(echo $register_output | awk '{print $2}')
ip_addr=$(echo $register_output | awk '{print $4}')
port=$(echo $register_output | awk '{print $6}')
client_ip=$(echo $register_output | awk '{print $8}')
register_client_interface $pubkey $ip_addr $port $IP $WG_MTU
;;
*) echo "Usage: wg-client-installer [cmd] --ip [2001::1] --user wginstaller --password wginstaller" ;;
esac