From: Michael Tremer Date: Fri, 6 Dec 2024 18:50:33 +0000 (+0100) Subject: wireguard.cgi: Send the N2N peer configuration to the client X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a61f0c752225fd3dcde20a9929947f3fe2586781;p=people%2Fms%2Fipfire-2.x.git wireguard.cgi: Send the N2N peer configuration to the client Signed-off-by: Michael Tremer --- diff --git a/config/cfgroot/wireguard-functions.pl b/config/cfgroot/wireguard-functions.pl index 33d9032c2..bfed3f4a5 100644 --- a/config/cfgroot/wireguard-functions.pl +++ b/config/cfgroot/wireguard-functions.pl @@ -338,6 +338,58 @@ sub free_pool_addresses($$) { return @free_addresses; } +sub generate_net_configuration($$) { + my $key = shift; + my $private_key = shift; + + # Load the peer + my %peer = &load_peer($key); + + # Return if we could not find the peer + return undef unless (%peer); + + # Return if this is not a network peer + return undef unless ($peer{'TYPE'} eq 'net'); + + my @allowed_ips = (); + + # Convert all subnets into CIDR notation + foreach my $subnet ($peer{'LOCAL_SUBNETS'}) { + my $netaddress = &Network::get_netaddress($subnet); + my $prefix = &Network::get_prefix($subnet); + + # Skip invalid subnets + next if (!defined $netaddress || !defined $prefix); + + push(@allowed_ips, "${netaddress}/${prefix}"); + } + + my $endpoint = $settings{'ENDPOINT'}; + + # If no endpoint is set, we fall back to the FQDN of the firewall + if ($endpoint eq "") { + $endpoint = $General::mainsettings{'HOSTNAME'} . "." . $General::mainsettings{'DOMAINNAME'}; + } + + # Derive our own public key + my $public_key = &derive_public_key($peer{'PRIVATE_KEY'}); + + my @conf = ( + "[Interface]", + "PrivateKey = $private_key", + "Port = $peer{'ENDPOINT_PORT'}", + "", + "[Peer]", + "Endpoint = ${endpoint}:$peer{'PORT'}", + "PublicKey = $public_key", + "PresharedKey = $peer{'PSK'}", + "AllowedIPs = " . join(", ", @allowed_ips), + "PersistentKeepalive = $peer{'KEEPALIVE'}", + ); + + return join("\n", @conf); +} + sub generate_host_configuration($) { my $key = shift; diff --git a/html/cgi-bin/wireguard.cgi b/html/cgi-bin/wireguard.cgi index 82751fe1e..a98a6f680 100644 --- a/html/cgi-bin/wireguard.cgi +++ b/html/cgi-bin/wireguard.cgi @@ -171,13 +171,15 @@ if ($cgiparams{"ACTION"} eq $Lang::tr{'save'}) { # Allocate a new key my $key = &General::findhasharraykey(\%Wireguard::peers); + my $name = $cgiparams{"NAME"}; + # Check if the name is valid - unless (&Wireguard::name_is_valid($cgiparams{"NAME"})) { + unless (&Wireguard::name_is_valid($name)) { push(@errormessages, $Lang::tr{'wg invalid name'}); } # Check if the name is free - unless (&Wireguard::name_is_free($cgiparams{"NAME"}, $key)) { + unless (&Wireguard::name_is_free($name, $key)) { push(@errormessages, $Lang::tr{'wg name is already used'}); } @@ -248,7 +250,7 @@ if ($cgiparams{"ACTION"} eq $Lang::tr{'save'}) { # 1 = Type "net", # 2 = Name - $cgiparams{"NAME"}, + $name, # 3 = Remote Public Key $remote_public_key, # 4 = Local Private Key @@ -279,6 +281,45 @@ if ($cgiparams{"ACTION"} eq $Lang::tr{'save'}) { &General::system("/usr/local/bin/wireguardctrl", "start"); } + # Send HTTP Headers + &Header::showhttpheaders(); + + # Open the page + &Header::openpage($Lang::tr{'wireguard'}, 1, ''); + + # Generate the client configuration + my $config = &Wireguard::generate_net_configuration($key, $remote_private_key); + + # Encode the configuration as Base64 + $config = &MIME::Base64::encode_base64($config); + + # Open a new box + &Header::openbox('100%', '', "$Lang::tr{'wg peer configuration'}: $name"); + + # Make the filename for files + my $filename = &Header::normalize("${name}.conf"); + + print < +

+ + $Lang::tr{'wg download configuration file'} + +

+ +

+

+ +
+

+ +END + + &Header::closebox(); + &Header::closepage(); + + exit(0); + } elsif ($cgiparams{"ACTION"} eq "SAVE-PEER-NET") { my @local_subnets = (); my @remote_subnets = ();