From: Michael Tremer Date: Fri, 6 Dec 2024 17:35:42 +0000 (+0100) Subject: wireguard.cgi: Create a new simplified dialogue to create a new N2N connection X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4e4b6033294509f6a9301cf7d7700263adc69172;p=people%2Fms%2Fipfire-2.x.git wireguard.cgi: Create a new simplified dialogue to create a new N2N connection The former process was very complicated and required that many settings were copied across both sides. It seems to be much more elegant to generate a new connection in one place and import it on the other side. Signed-off-by: Michael Tremer --- diff --git a/html/cgi-bin/wireguard.cgi b/html/cgi-bin/wireguard.cgi index 9635be126..da88e1639 100644 --- a/html/cgi-bin/wireguard.cgi +++ b/html/cgi-bin/wireguard.cgi @@ -164,12 +164,130 @@ if ($cgiparams{"ACTION"} eq $Lang::tr{'save'}) { die "Unsupported type: $type"; } +} elsif ($cgiparams{"ACTION"} eq "CREATE-PEER-NET") { + my @local_subnets = (); + my @remote_subnets = (); + + # Allocate a new key + my $key = &General::findhasharraykey(\%Wireguard::peers); + + # Check if the name is valid + unless (&Wireguard::name_is_valid($cgiparams{"NAME"})) { + push(@errormessages, $Lang::tr{'wg invalid name'}); + } + + # Check if the name is free + unless (&Wireguard::name_is_free($cgiparams{"NAME"}, $key)) { + push(@errormessages, $Lang::tr{'wg name is already used'}); + } + + # Check the endpoint address + if ($cgiparams{'ENDPOINT_ADDRESS'} eq '') { + # The endpoint address may be empty + } elsif (&General::validfqdn($cgiparams{'ENDPOINT_ADDRESS'})) { + # The endpoint is a valid FQDN + } elsif (&Network::check_ip_address($cgiparams{'ENDPOINT_ADDRESS'})) { + # The endpoint is a valid IP address + } else { + push(@errormessages, $Lang::tr{'wg invalid endpoint address'}); + } + + # Check local subnets + if (defined $cgiparams{'LOCAL_SUBNETS'}) { + @local_subnets = split(/,/, $cgiparams{'LOCAL_SUBNETS'}); + + foreach my $subnet (@local_subnets) { + $subnet =~ s/^\s+//g; + $subnet =~ s/\s+$//g; + + unless (&Network::check_subnet($subnet)) { + push(@errormessages, $Lang::tr{'wg invalid local subnet'} . ": ${subnet}"); + } + } + } else { + push(@errormessages, $Lang::tr{'wg no local subnets'}); + } + + # Check remote subnets + if (defined $cgiparams{'REMOTE_SUBNETS'}) { + @remote_subnets = split(/,/, $cgiparams{'REMOTE_SUBNETS'}); + + foreach my $subnet (@remote_subnets) { + $subnet =~ s/^\s+//g; + $subnet =~ s/\s+$//g; + + unless (&Network::check_subnet($subnet)) { + push(@errormessages, $Lang::tr{'wg invalid remote subnet'} . ": ${subnet}"); + } + } + } else { + push(@errormessages, $Lang::tr{'wg no remote subnets'}); + } + + # If there are any errors, we go back to the editor + goto EDITNET if (scalar @errormessages); + + # Generate a new key pair + my $local_private_key = &Wireguard::generate_private_key(); + my $remote_private_key = &Wireguard::generate_private_key(); + + # Derive the public key + my $remote_public_key = &Wireguard::derive_public_key($remote_private_key); + + # Generate a new PSK + my $psk = &Wireguard::generate_private_key(); + + # Generate two new ports + my $local_port = &Wireguard::get_free_port(); + my $remote_port = &Wireguard::get_free_port(); + + # Save the connection + $Wireguard::peers{$key} = [ + # 0 = Enabled + "on", + # 1 = Type + "net", + # 2 = Name + $cgiparams{"NAME"}, + # 3 = Remote Public Key + $remote_public_key, + # 4 = Local Private Key + $local_private_key, + # 5 = Port + $local_port, + # 6 = Endpoint Address + $cgiparams{"ENDPOINT_ADDRESS"}, + # 7 = Endpoint Port + $remote_port, + # 8 = Remote Subnets + &Wireguard::encode_subnets(@remote_subnets), + # 9 = Remark + &Wireguard::encode_remarks($cgiparams{"REMARKS"}), + # 10 = Local Subnets + &Wireguard::encode_subnets(@local_subnets), + # 11 = PSK + $psk, + # 12 = Keepalive + $Wireguard::DEFAULT_KEEPALIVE, + ]; + + # Store the configuration + &General::writehasharray("/var/ipfire/wireguard/peers", \%Wireguard::peers); + + # Reload if enabled + if ($Wireguard::settings{'ENABLED'} eq "on") { + &General::system("/usr/local/bin/wireguardctrl", "start"); + } + } elsif ($cgiparams{"ACTION"} eq "SAVE-PEER-NET") { my @local_subnets = (); my @remote_subnets = (); # Fetch or allocate a new key - my $key = $cgiparams{'KEY'} || &General::findhasharraykey(\%Wireguard::peers); + my $key = $cgiparams{'KEY'}; + + # Load the existing peer + my %peer = &Wireguard::load_peer($key); # Check if the name is valid unless (&Wireguard::name_is_valid($cgiparams{"NAME"})) { @@ -186,13 +304,6 @@ if ($cgiparams{"ACTION"} eq $Lang::tr{'save'}) { push(@errormessages, $Lang::tr{'wg invalid public key'}); } - # Check private key - #if ($cgiparams{'PRIVATE_KEY'} eq '') { - # # The private key may be empty - #} elsif (!&Wireguard::key_is_valid($cgiparams{'PRIVATE_KEY'})) { - # push(@errormessages, $Lang::tr{'wg invalid private key'}); - #} - # Check PSK if ($cgiparams{'PSK'} eq '') { # The PSK may be empty @@ -276,7 +387,7 @@ if ($cgiparams{"ACTION"} eq $Lang::tr{'save'}) { # 3 = Public Key $cgiparams{"PUBLIC_KEY"}, # 4 = Private Key - $cgiparams{"PRIVATE_KEY"}, + $peer{"PRIVATE_KEY"}, # 5 = Port $cgiparams{"PORT"}, # 6 = Endpoint Address @@ -421,16 +532,10 @@ if ($cgiparams{"ACTION"} eq $Lang::tr{'save'}) { } elsif ($cgiparams{"ACTION"} eq $Lang::tr{'add'}) { if ($cgiparams{"TYPE"} eq "net") { - # Generate a new private key - $cgiparams{'PRIVATE_KEY'} = &Wireguard::generate_private_key(); - - # Generate a new PSK - $cgiparams{"PSK"} = &Wireguard::generate_private_key(); - - goto EDITNET; + goto CREATENET; } elsif ($cgiparams{"TYPE"} eq "host") { - goto EDITHOST; + goto CREATEHOST; } elsif ($cgiparams{"TYPE"} eq "import") { # Parse the configuration file @@ -845,6 +950,108 @@ END exit(0); +CREATENET: + # Send HTTP Headers + &Header::showhttpheaders(); + + # Open the page + &Header::openpage($Lang::tr{'wireguard'}, 1, ''); + + # Show any error messages + &Header::errorbox(@errormessages); + + # Open a new box + &Header::openbox('100%', '', $Lang::tr{'wg create net-to-net peer'}); + + # Set defaults + &General::set_defaults(\%cgiparams, { + "LOCAL_SUBNETS" => + $Network::ethernet{"GREEN_NETADDRESS"} + . "/" . $Network::ethernet{"GREEN_NETMASK"}, + }); + + print < + + + + + + + + + + + + + + +
+ $Lang::tr{'name'} + + +
+ $Lang::tr{'remarks'} + + +
+ +
$Lang::tr{'endpoint'}
+ + + + + + + +
+ $Lang::tr{'endpoint address'} + + +
+ +
$Lang::tr{'routing'}
+ + + + + + + + + + + + + + + + + +
+ $Lang::tr{'local subnets'} + + +
+ $Lang::tr{'remote subnets'} + + +
+ +
+ +END + + &Header::closebox(); + &Header::closepage(); + + exit(0); + EDITNET: # Send HTTP Headers &Header::showhttpheaders(); @@ -858,31 +1065,17 @@ EDITNET: # Fetch the key my $key = $cgiparams{'KEY'}; - # Derive our own public key - my $public_key = &Wireguard::derive_public_key($cgiparams{'PRIVATE_KEY'}); - # Open a new box - &Header::openbox('100%', '', - (defined $key) ? $Lang::tr{'wg edit net-to-net peer'} : $Lang::tr{'wg create net-to-net peer'}); + &Header::openbox('100%', '', $Lang::tr{'wg edit net-to-net peer'}); - # Set defaults - unless (defined $key) { - &General::set_defaults(\%cgiparams, { - "ENDPOINT_PORT" => $Wireguard::DEFAULT_PORT, - "LOCAL_SUBNETS" => - $Network::ethernet{"GREEN_NETADDRESS"} - . "/" . $Network::ethernet{"GREEN_NETMASK"}, - "KEEPALIVE" => $Wireguard::DEFAULT_KEEPALIVE, - }); - } + # Derive our own public key + my $public_key = &Wireguard::derive_public_key($cgiparams{'PRIVATE_KEY'}); print < - -
@@ -1023,6 +1216,7 @@ END exit(0); +CREATEHOST: EDITHOST: # Send HTTP Headers &Header::showhttpheaders();