Skip to content

Commit 5604a80

Browse files
authored
Merge pull request #16 from theonemcdonald/v0.0.4_1
Merge v0.0.4_1 into main
2 parents 90a0d06 + 258d22d commit 5604a80

File tree

9 files changed

+126
-74
lines changed

9 files changed

+126
-74
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ These changes include:
1212
2. Because assigned interfaces become a system dependency, this package includes several (clever) tricks to allow the system to be upgraded and rebooted with WireGuard tunnels assigned to pfSense interfaces (e.g. LAN, OPT#, etc...). There are now two `<earlyshellcmds>` that are installed. One is a bootstrapper and one is a reloader. The bootstrapper [here](https://github.com/theonemcdonald/pfSense-pkg-WireGuard/blob/main/src/files/usr/local/pkg/wireguard/etc/rc.bootstrap_wireguard) always runs first and is written to disk by the package internals instead of by `pkg(7)`. This means that this script will remain on your system by default even if the WireGuard package is uninstalled. There will be a configuration setting to change this behavior soon. This bootstrapper protects the system from interface mismatches on startup caused by WireGuard tunnels not being built (even though they are assigned) because the package is being updated or was removed for some reason. This is accomplishd by temporarily creating loopback interfaces of the same names, thus allowing the system to boot. However, if the WireGuard package is installed, the reloader [here](https://github.com/theonemcdonald/pfSense-pkg-WireGuard/blob/main/src/files/usr/local/etc/rc.reload_wireguard) will destroy these temporary loopbacks and replace them with true `wg(8)` tunnels early on system startup.
1313
3. Assigned interfaces are now configured under the traditional pfSense `interfaces.php` page. Unassigned tunnels are still configured through the WireGuard UI.
1414
4. Gateways are no longer automatically created for tunnels assigned to pfSense interfaces. Just like any other WAN, you will now be required to create your own gateway entries for the tunnel remote side if you intended to route traffic over the tunnel itself.
15+
5. There is now a proper status page at Status > WireGuard Status. This page includes various bits from `wg(8)`, `ifconfig(8)`, `pkg(7)`, and `kldstat(8)`.
1516

1617
Note: I have now moved development to the dev branch. Moving forward main will contain code that has been tested. If you want to run dev branch code, you will need to checkout the branch and `make package` yourself.
1718

src/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
PORTNAME= pfSense-pkg-WireGuard
44
PORTVERSION= 0.0.4
5-
PORREVISION= 0
5+
PORREVISION= 1
66
CATEGORIES= net
77
MASTER_SITES= # empty
88
DISTFILES= # empty

src/files/usr/local/pkg/wireguard/etc/rc.bootstrap_wireguard

Lines changed: 9 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ function print_message($message) {
3131

3232
$message = escapeshellarg($message);
3333

34+
// printf is a shell builtin
3435
exec("printf {$message} >&2");
3536

3637
}
@@ -46,35 +47,21 @@ if (platform_booting()) {
4647

4748
}
4849

49-
// Iterate through each assigned interface looking for any wg interfaces to bootstrap
50-
$a_interfaces = $config['interfaces'];
50+
$verbose_pipe = ($run_verbose ? "" : " > /dev/null 2>&1");
5151

52-
if (is_array($a_interfaces)) {
52+
$if_list = get_configured_interface_list_by_realif($disabled);
5353

54-
foreach ($a_interfaces as $interface) {
54+
foreach ($if_list as $realif => $name) {
5555

56-
$ifname = $interface['if'];
57-
58-
// We found one, create a temporary loopback interface of the same name to allow booting if the package disappears
59-
if (substr($ifname, 0, 2) == "wg") {
56+
$ifname = escapeshellarg($realif);
6057

61-
// Create a wgX interface using lo driver, keeping track of any erroneous loifs created
62-
exec("ifconfig lo create name {$ifname}" . ($run_verbose ? "" : " > /dev/null 2>&1"), $loifs);
58+
if (substr($realif, 0, 2) == "wg") {
6359

64-
}
60+
exec("/sbin/ifconfig {$ifname}" . $verbose_pipe . " || ifconfig lo create name {$ifname}");
6561

66-
}
62+
exec("/sbin/ifconfig {$ifname} group wg");
6763

68-
}
69-
70-
// Need to clean up any erroneous loifs that might have been created
71-
if (isset($loifs) && is_array($loifs)) {
72-
73-
foreach ($loifs as $loif) {
74-
75-
exec("ifconfig {$loif} destroy" . ($run_verbose ? "" : " > /dev/null 2>&1"));
76-
77-
}
64+
}
7865

7966
}
8067

src/files/usr/local/pkg/wireguard/wg.inc

Lines changed: 75 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,14 @@ require_once('wg_validate.inc');
3939
global $wgifgroup;
4040
$wgifgroup = 'WireGuard';
4141

42-
global $wgearlyshellcmds;
42+
global $wgearlyshellcmds, $wgearlyshellcmds_pkg;
4343
$wgearlyshellcmds = array('/usr/local/etc/rc.bootstrap_wireguard', '/usr/local/etc/rc.reload_wireguard');
44+
$wgearlyshellcmds_pkg = array('/usr/local/etc/rc.reload_wireguard');
45+
46+
// Full source path of extra scripts to install
47+
global $wg_scripts_to_install;
48+
$wg_scripts_to_install = array('/usr/local/pkg/wireguard/etc/rc.bootstrap_wireguard');
49+
4450

4551
// Setup all WireGuard tunnels
4652
function wg_configure() {
@@ -88,7 +94,7 @@ function wg_configure_if($tunnel, $destroyfirst = true, $verbose = false) {
8894
exec_wg_quick_action($tunnel, "up", $verbose);
8995

9096
// Attempt to add the interface to interface group (i.e. WireGuard)
91-
exec("ifconfig {$tunnel['name']} group {$wgifgroup}");
97+
exec("/sbin/ifconfig {$tunnel['name']} group {$wgifgroup}");
9298

9399
}
94100

@@ -136,7 +142,7 @@ function deleteTunnel($tunidx) {
136142
}
137143
// Delete the tunnel configuration entry
138144
unset($config['installedpackages']['wireguard']['tunnel'][$tunidx]);
139-
write_config("WireGuard tunnel {$index} updated.");
145+
write_config("[WireGuard] tunnel {$index} updated.");
140146

141147
// Delete the wg?.conf file
142148
if (isset($conf_path) && is_file($conf_path)) {
@@ -179,69 +185,110 @@ function wg_ifgroup_install() {
179185
$a_ifgroups[] = $ifgroupentry;
180186
}
181187

182-
write_config("WireGuard interface group updated.");
188+
write_config("[WireGuard] Interface group updated.");
183189

184190
unlink_if_exists("{$g['tmp_path']}/config.cache");
185191

186192
}
187193

188-
function wg_earlyshellcmd_deinstall($clean = true) {
194+
function wg_earlyshellcmd_deinstall($cmds_to_remove) {
195+
global $config;
196+
197+
$a_earlyshellcmds = &$config['system']['earlyshellcmd'];
189198

190-
# TODO
199+
$a_earlyshellcmds = array_diff($a_earlyshellcmds, $cmds_to_remove);
191200

201+
$cmds_to_remove = implode(',', $cmds_to_remove);
202+
203+
write_config("[WireGuard] ( {$cmds_to_remove} ) earlyshellcmds deinstalled.");
204+
192205
}
193206

194-
function wg_earlyshellcmd_install() {
195-
global $config, $wgearlyshellcmds;
207+
function wg_extra_script_install($scripts_to_install, $install_dest = '/usr/local/etc', $verbose = false) {
208+
209+
foreach ($scripts_to_install as $script) {
196210

197-
// This ensures we are always starting clean
198-
wg_earlyshellcmd_deinstall();
211+
$script_name = basename($script);
199212

200-
// Need to generalize this and clean it up...
201-
unlink_if_exists('/usr/local/etc/rc.bootstrap_wireguard');
202-
copy('/usr/local/pkg/wireguard/etc/rc.bootstrap_wireguard', '/usr/local/etc/rc.bootstrap_wireguard');
203-
chmod('/usr/local/etc/rc.bootstrap_wireguard', 0755);
213+
$script_source_path = dirname($script);
204214

205-
$a_earlyshellcmd = &$config['system']['earlyshellcmd'];
215+
update_status("\nInstalling {$script_name} to {$install_dest} ...");
206216

207-
// Unlikely the user already has earlyshellcmds configured
208-
if (!is_array($a_earlyshellcmd)) {
217+
unlink_if_exists("{$install_dest}/{$script_name}");
209218

210-
$a_earlyshellcmd = array();
219+
copy("{$script}", "{$install_dest}/{$script_name}");
220+
221+
chmod("{$install_dest}/{$script_name}", 0755);
222+
223+
update_status(" done.\n");
211224

212225
}
213226

214-
// Make sure our WireGuard scripts always run first
215-
$a_earlyshellcmd = array_merge($wgearlyshellcmds, $a_earlyshellcmd);
227+
}
228+
229+
function wg_earlyshellcmd_install($cmds_to_install) {
230+
global $config;
231+
232+
// Ensures we are always starting clean
233+
wg_earlyshellcmd_deinstall($cmds_to_install);
234+
235+
$a_earlyshellcmds = &$config['system']['earlyshellcmd'];
216236

217-
write_config("WireGuard earlyshellcmds updated.");
237+
// Unlikely the user already has earlyshellcmds configured, but maybe...
238+
if (!is_array($a_earlyshellcmds)) {
239+
240+
$a_earlyshellcmds = array();
241+
242+
}
243+
244+
// Make sure our WireGuard scripts always run first, push everything else after us
245+
$a_earlyshellcmds = array_merge($cmds_to_install, $a_earlyshellcmds);
246+
247+
write_config("[WireGuard] Earlyshellcmds installed.");
218248

219249
}
220250

221251
function wg_install() {
252+
global $g, $wg_scripts_to_install, $wgearlyshellcmds;
253+
254+
$g['wireguard_install'] = true;
255+
256+
update_status("\nInstalling extra scripts... ");
222257

223-
update_status("Creating earlyshellcmds...\n");
258+
// Installs any extra scripts
259+
wg_extra_script_install($wg_scripts_to_install);
260+
261+
update_status("Finished installing extra scripts.\n");
262+
263+
update_status("Setting up earlyshellcmds... ");
224264

225265
// Installs the earlyshellcmds
226-
wg_earlyshellcmd_install();
266+
wg_earlyshellcmd_install($wgearlyshellcmds);
227267

228-
update_status(" done.\nCreating WireGuard interface group...\n");
268+
update_status(" done.\nCreating WireGuard interface group... ");
229269

230-
// Create the 'WireGuard' interface group
270+
// Installs the 'WireGuard' interface group
231271
wg_ifgroup_install();
232272

233-
update_status(" done.\nConfiguring any existing WireGuard interfaces...\n");
273+
update_status(" done.\nConfiguring existing WireGuard interfaces... ");
234274

235275
// Configure any existing interfaces
236276
wg_configure();
237277

238278
update_status(" done.\n");
239279

280+
unset($g['wireguard_install']);
281+
240282
}
241283

242284
function wg_deinstall() {
285+
global $wgearlyshellcmds_pkg;
243286

244-
# TODO
287+
update_status("Removing earlyshellcmds... ");
288+
289+
wg_earlyshellcmd_deinstall($wgearlyshellcmds_pkg);
290+
291+
update_status(" done.\n");
245292

246293
}
247294

@@ -308,7 +355,7 @@ function wg_do_post($post, $json = false) {
308355

309356
if (!$input_errors) {
310357
$config['installedpackages']['wireguard']['tunnel'][$index] = $pconfig;
311-
write_config("WireGuard tunnel {$index} updated.");
358+
write_config("[WireGuard] Tunnel {$pconfig['name']} (Index {$index}) updated.");
312359
}
313360

314361
return(array('input_errors' => $input_errors, 'pconfig' => $pconfig));

src/files/usr/local/pkg/wireguard/wg_validate.inc

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -173,12 +173,24 @@ function wg_defaultroute_check($peer) {
173173

174174
// Check if wg tunnel is assigned to an interface
175175
function is_wg_tunnel_assigned($tunnel, $disabled = true) {
176+
global $config;
177+
178+
// Assume we have an interface first
179+
$wg_ifname = $tunnel;
176180

177-
$iflist = get_configured_interface_list_by_realif($disabled);
181+
// Looks like we have a tunnel structure
182+
if (is_array($tunnel)) {
178183

179-
$ifassigned = array_key_exists($tunnel['name'], $iflist);
184+
$wg_ifname = $tunnel['name'];
185+
186+
}
180187

181-
return $ifassigned;
188+
$if_list = get_configured_interface_list_by_realif($disabled);
189+
190+
$if_assigned = array_key_exists($wg_ifname, $if_list);
191+
192+
return $if_assigned;
193+
182194
}
183195

184196
// Check if at least one tunnel is enabled

src/files/usr/local/www/shortcuts/pkg_wireguard.inc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
global $shortcuts;
2525

2626
$shortcuts['wireguard'] = array();
27-
$shortcuts['wireguard']['main'] = "/wg/vpn_wg.php";
27+
$shortcuts['wireguard']['main'] = "/wg/vpn_wg_settings.php";
2828
$shortcuts['wireguard']['status'] = "/wg/status_wireguard.php";
2929

3030
?>

src/files/usr/local/www/wg/status_wireguard.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656
</div>
5757
<div class="panel-body">
5858
<dl class="dl-horizontal">
59-
<pre><?php echo wg_status(); ?></pre>
59+
<pre><?=wg_status(); ?></pre>
6060
</dl>
6161
</div>
6262
</div>
@@ -67,7 +67,7 @@
6767
</div>
6868
<div class="panel-body">
6969
<dl class="dl-horizontal">
70-
<pre><?php echo wg_interface_status(); ?></pre>
70+
<pre><?=wg_interface_status(); ?></pre>
7171
</dl>
7272
</div>
7373
</div>
@@ -78,7 +78,7 @@
7878
</div>
7979
<div class="panel-body">
8080
<dl class="dl-horizontal">
81-
<pre><?php echo wg_version(); ?></pre>
81+
<pre><?=wg_version(); ?></pre>
8282
</dl>
8383
</div>
8484
</div>
@@ -89,7 +89,7 @@
8989
</div>
9090
<div class="panel-body">
9191
<dl class="dl-horizontal">
92-
<pre><?php echo wg_kmod_status(); ?></pre>
92+
<pre><?=wg_kmod_status(); ?></pre>
9393
</dl>
9494
</div>
9595
</div>

src/files/usr/local/www/wg/vpn_wg_edit.php

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -131,14 +131,15 @@
131131
$section->addInput(new Form_Checkbox(
132132
'enabled',
133133
'Tunnel Enabled',
134-
'',
134+
gettext('Enable'),
135135
$pconfig['enabled'] == 'yes'
136-
))->setHelp('Note: Tunnel must be enabled for interface assignment');
136+
))->setHelp('<span class="text-danger">Note: </span>'
137+
. 'Tunnel must be enabled for interface assignment');
137138

138139
$section->addInput(new Form_Input(
139140
'descr',
140141
'Description',
141-
'text',
142+
gettext('Description'),
142143
$pconfig['descr']
143144
))->setHelp('Tunnel description for administrative reference (not parsed)');
144145

@@ -183,12 +184,12 @@
183184

184185
$section->addInput(new Form_StaticText(
185186
'Assignment',
186-
"Leave these fields blank to use <a href='../../interfaces_assign.php'>Interface Assignments</a>"
187+
"<a href='../../interfaces_assign.php'>Interface Assignments</a>"
187188
));
188189

189190
$section->addInput(new Form_StaticText(
190191
'Firewall Rules',
191-
"Configure firewall rules on unassigned tunnels using the <a href='../../firewall_rules.php?if={$wgifgroup}'>WireGuard Interface Group</a>"
192+
"<a href='../../firewall_rules.php?if={$wgifgroup}'>WireGuard Interface Group</a>"
192193
));
193194

194195
$section->addInput(new Form_Input(
@@ -349,7 +350,9 @@
349350

350351
<tbody>
351352
<?php
353+
352354
$peer_num = 0;
355+
353356
if (!empty($pconfig['peers']['wgpeer'])) {
354357
foreach ($pconfig['peers']['wgpeer'] as $peer) {
355358
print('<tr id="peer_row_' . $peer_num . '" class="peer_group_' . $peer_num . '">');
@@ -366,8 +369,6 @@
366369
print("<td style=\"display:none;\">" . htmlspecialchars($peer['peerwgaddr']) . "</td>\n");
367370
?>
368371
<td style="cursor: pointer;">
369-
<a class="fa fa-download" href="https://github.com/theonemcdonald/pfSense-pkg-WireGuard/issues/7" target="_blank" title="<?=gettext("Download Peer Configuration"); ?>"></a>
370-
<a class="fa fa-qrcode" href="https://github.com/theonemcdonald/pfSense-pkg-WireGuard/issues/7" target="_blank" title="<?=gettext("View Peer Configuration QR code"); ?>"></a>
371372
<a class="fa fa-pencil" href="#" id="editpeer_<?=$peer_num?>"title="<?=gettext("Edit peer"); ?>"></a>
372373
<a class="fa fa-trash text-danger no-confirm" href="#" id="killpeer_<?=$peer_num?>" title="<?=gettext('Delete peer');?>"></a>
373374
</td>

0 commit comments

Comments
 (0)