ngoduykhanh / wireguard-ui

Wireguard web interface
MIT License
4.07k stars 503 forks source link

use existing wg0.conf #485

Open ragman1976 opened 11 months ago

ragman1976 commented 11 months ago

Hi,

I want to migrate my wireguard server. For the new wireguard server I use this docker image, but I`m not able to "import" my existing wg0.conf Is there a way to do that?

Greets

nebulosa2007 commented 10 months ago

I wrote converter from *.conf files to wireguard-ui db/*.json files, which Wireguard UI detects and using for work. But it not working. I suppose that all pivate keys from users should be loaded in wg directly, because wg-quick use info from something else, not only main /etc/wireguard/wg0.conf. Need to investigate futher...

Usage:

  1. Backup wg0.conf and all clients *.conf files - all in one folder.
  2. Install Wireguard UI, make sure that service is working (it creates db folder with files).
  3. Stop WGUI and wg services.
  4. Install jq and wg tools
  5. Save and execute converter in backup conf folder
  6. Copy all files in db folder and change owner (chown -R) for the files.
  7. Start WGUI and wg services and recheck all setting.
#!/bin/bash
#Require bash, jq, wireguard-tools

wg_conf_file="wg0.conf"

([ -x "$(command -v jq)" ] && [ -x "$(command -v wg)" ]) || { echo "Please install jq and wireguard-tools"; exit 1; }
[ -f $wg_conf_file ] || { echo "$wg_conf_file not found!"; exit 1; }

#Making folders
mkdir -p db/{clients,server}

updated_at=$(date --utc +%FT%T.%NZ)

interfaces(){
  addresses="$(grep -Po '(?<=^Address = )(\S+)' $wg_conf_file | sed 's/,/\",\"/g')"
  listen_port="$(grep -Po '(?<=^ListenPort = )(\S+)' $wg_conf_file)"  
  post_up="$(grep -Po '(?<=^PostUp = )(.*)' $wg_conf_file)"
  post_down="$(grep -Po '(?<=^PostDown = )(.*)' $wg_conf_file)"
  file_format='{"addresses": ["%s"], "listen_port": "%s", "updated_at": "%s", "post_up": "%s", "post_down": "%s"}'
  printf "$file_format" "$addresses" "$listen_port" "$updated_at" "$post_up" "$post_down"
}

keypair(){
  private_key="$(grep -Po '(?<=^PrivateKey = )(\S+)' $wg_conf_file)"
  public_key="$(echo $private_key | wg pubkey)"
  file_format='{"private_key": "%s", "public_key": "%s", "updated_at": "%s"}'
  printf "$file_format" "$private_key" "$public_key" "$updated_at"
}

client(){
  clid="$1"
  private_key="$2"
  public_key="$3"
  preshared_key="$4"
  name="$1"
  email=""
  allocated_ips="$(echo $5 | sed 's/,/\",\"/g')"
  allowed_ips="0.0.0.0/0\",\"::/0"
  extra_allowed_ips=''
  use_server_dns="true"
  enabled="true"
  created_at=$updated_at
  updated_at=$updated_at
  file_format='{"id": "%s", "private_key": "%s", "public_key": "%s", "preshared_key": "%s", "name": "%s", "email": "%s", "allocated_ips": ["%s"], "allowed_ips": ["%s"], "extra_allowed_ips": [], "use_server_dns": %s, "enabled": %s, "created_at": "%s", "updated_at": "%s"}'
  printf "$file_format" "$clid" "$private_key" "$public_key" "$preshared_key" "$name" "$email" "$allocated_ips" "$allowed_ips" "$use_server_dns" "$enabled" "$created_at" "$updated_at"
}

interfaces | jq > "db/server/interfaces.json"
keypair | jq > "db/server/keypair.json"

#Converting clients conf files, if any
for conf in $(/usr/bin/ls -1 *.conf | grep -v $wg_conf_file)
do
  clid="cl"$(tr -dc 'a-z0-9' < /dev/urandom | dd bs=1 count=18 2>/dev/null && echo)
  private_key="$(cat $conf | grep -Po '(?<=PrivateKey = )(\S+)')"
  public_key="$(cat $conf | grep -Po '(?<=PublicKey = )(\S+)')"
  preshared_key="$(cat $conf | grep -Po '(?<=PresharedKey = )(\S+)')"
  allowed_ips="$(cat $conf | grep -Po '(?<=Address = )(\S+)')"
  client "$clid" "$private_key" "$public_key" "$preshared_key" "$allowed_ips" | jq > "db/clients/$clid.json"
done
chaoticdude commented 9 months ago

@nebulosa2007, following these directions I don’t see it creating a json file for my three users. I’m confused at the last section for conf in /usr/bin/ls … it doesn’t look like it’s doing anything. Can you provide some guidance?

nebulosa2007 commented 9 months ago

As I wrote above:

  1. Backup wg0.conf and all clients *.conf files - all in one folder. Then save script in that folder and execute it.

For example: Backup_for_convert └─ wg0.conf └─ client1.conf └─ client2.conf └─ client3.conf └─ converter.sh

fracture-point commented 2 months ago

This generates files as I would expect, and the contents look good, however it seems that the server is not able to parse the client configs that are generated. When I log into the UI I do see tiles for all of the clients...but if I try to edit any of the "imported" clients, I get a red "please provide a valid Client ID" toast, and the edit modal contains blank values for all of the parameters.

I also compared a Client ID generated by this script vs one generated fresh using the New Client button in the UI, and they seem to follow the same pattern - random 20 characters. The only difference I see is that the imported client IDs start with cl and the UI-generated ones start with cq...but I even tried manually switching that in the .json of imported clients to no avail.

ProFiLeR4100 commented 2 months ago

@chaoticdude I've also got this problem. Looks like it is due to PublicKey duplication, because in conf file there is server's public key and not a key of a peer.

ProFiLeR4100 commented 2 months ago

yep, looks like it works now:

  1. mkdir ~/wg-ui-import
  2. find ~/wireguard-conf-backup/ -name 'peer*.conf' -exec cp "{}" ~/wg-ui-import/ \;
  3. find ~/wireguard-conf-backup/ -name 'publickey-peer*' -exec cp "{}" ~/wg-ui-import/ \;
  4. create a converter.sh using any text editor and fill it with script from this comment
  5. Change <YOUR_ENDPOINT_HERE> in script to your actual endpoint
  6. chmod +x converter.sh
  7. ./converter.sh
  8. Copy files to wireguard-ui folder
  9. apply config from UI
  10. now everything works: image
ProFiLeR4100 commented 2 months ago

Strange, only some of them opens, other one gives me the red "please provide a valid Client ID" toast. Probably id is not random, because in code dev is trying to parse it Looks like this is the library: github.com/rs/xid

ProFiLeR4100 commented 2 months ago

xid is compatible with mongodb object id, so I've found a way to generate such id in bash

Now it works as expected, every config can be downloaded.

#!/bin/bash
#Require bash, jq, wireguard-tools

wg_conf_file="wg0.conf"

([ -x "$(command -v jq)" ] && [ -x "$(command -v wg)" ]) || { echo "Please install jq and wireguard-tools"; exit 1; }
[ -f $wg_conf_file ] || { echo "$wg_conf_file not found!"; exit 1; }

#Making folders
mkdir -p db/{clients,server}

updated_at=$(date --utc +%FT%T.%NZ)

interfaces(){
  addresses="$(grep -Po '(?<=^Address = )(\S+)' $wg_conf_file | sed 's/,/\",\"/g')"
  listen_port="$(grep -Po '(?<=^ListenPort = )(\S+)' $wg_conf_file)"
  post_up="$(grep -Po '(?<=^PostUp = )(.*)' $wg_conf_file)"
  post_down="$(grep -Po '(?<=^PostDown = )(.*)' $wg_conf_file)"
  file_format='{"addresses": ["%s"], "listen_port": "%s", "updated_at": "%s", "post_up": "%s", "post_down": "%s"}'
  printf "$file_format" "$addresses" "$listen_port" "$updated_at" "$post_up" "$post_down"
}

keypair(){
  private_key="$(grep -Po '(?<=^PrivateKey = )(\S+)' $wg_conf_file)"
  public_key="$(echo $private_key | wg pubkey)"
  file_format='{"private_key": "%s", "public_key": "%s", "updated_at": "%s"}'
  printf "$file_format" "$private_key" "$public_key" "$updated_at"
}

client(){
  clid="$1"
  private_key="$2"
  public_key="$3"
  preshared_key="$4"
  name="$7"
  email=""
  allocated_ips="$(echo $5 | sed 's/,/\",\"/g')/32"
  allowed_ips="0.0.0.0/0"
  extra_allowed_ips=''
  use_server_dns="true"
  enabled="true"
  created_at=$updated_at
  updated_at=$updated_at
  file_format='{"id": "%s", "private_key": "%s", "public_key": "%s", "preshared_key": "%s", "name": "%s", "email": "%s", "allocated_ips": ["%s"], "allowed_ips": ["%s"], "extra_allowed_ips": [], "use_server_dns": %s, "enabled": %s, "created_at": "%s", "updated_at": "%s", "telegram_userid": "", "additional_notes": "", "endpoint": "<YOUR_ENDPOINT_HERE>"}'
  printf "$file_format" "$clid" "$private_key" "$public_key" "$preshared_key" "$name" "$email" "$allocated_ips" "$allowed_ips" "$use_server_dns" "$enabled" "$created_at" "$updated_at"
}

interfaces | jq --stream-errors '.' > "db/server/interfaces.json"
keypair | jq --stream-errors '.' > "db/server/keypair.json"

#Converting clients conf files, if any
for conf in $(/bin/ls -1 *.conf | grep -v $wg_conf_file)
do
  random_sec=$(tr -dc '0-9' < /dev/urandom | dd bs=1 count=6 2>/dev/null && echo)
  date=$(date --date="${random_sec} seconds ago" +%s)
#  clid="cq"$(tr -dc '0-9' < /dev/urandom | dd bs=1 count=18 2>/dev/null && echo)
  clid="$(printf "%x" ${date})000000000000"
  conf_wo_ext="$(echo $conf | cut -d'.' -f1)"
  private_key="$(cat $conf | grep -Po '(?<=PrivateKey = )(\S+)')"
  public_key="$(cat publickey-$conf_wo_ext)"
  preshared_key="$(cat $conf | grep -Po '(?<=PresharedKey = )(\S+)')"
  allowed_ips="$(cat $conf | grep -Po '(?<=Address = )(\S+)')"
  client "$clid" "$private_key" "$public_key" "$preshared_key" "$allowed_ips" "$username" "$conf_wo_ext" | jq --stream-errors '.' > "db/clients/$clid.json"
done