Project

General

Profile

Feature #12522 » openvpn_csc_patch-pfsense-v2.7.2.patch

Phil Wardt, 07/19/2024 07:28 PM

View differences:

src/etc/inc/openvpn.inc
757 757

  
758 758
	if ($settings['netbios_enable']) {
759 759

  
760
		if (!empty($settings['dhcp_nbttype']) && ($settings['dhcp_nbttype'] != 0)) {
761
			$conf .= "push \"dhcp-option NBT {$settings['dhcp_nbttype']}\"\n";
760
		if (!empty($settings['netbios_ntype']) && ($settings['netbios_ntype'] != 0)) {
761
			$conf .= "push \"dhcp-option NBT {$settings['netbios_ntype']}\"\n";
762 762
		}
763
		if (!empty($settings['dhcp_nbtscope'])) {
764
			$conf .= "push \"dhcp-option NBS {$settings['dhcp_nbtscope']}\"\n";
763
		if (!empty($settings['netbios_scope'])) {
764
			$conf .= "push \"dhcp-option NBS {$settings['netbios_scope']}\"\n";
765 765
		}
766 766

  
767 767
		if (!empty($settings['wins_server1'])) {
......
774 774
		if (!empty($settings['nbdd_server1'])) {
775 775
			$conf .= "push \"dhcp-option NBDD {$settings['nbdd_server1']}\"\n";
776 776
		}
777
		if (!empty($settings['nbdd_server2'])) {
778
			$conf .= "push \"dhcp-option NBDD {$settings['nbdd_server2']}\"\n";
777 779
		}
780
	}
778 781

  
779 782
	if ($settings['gwredir']) {
780 783
		$conf .= "push \"redirect-gateway def1\"\n";
......
1695 1698
	}
1696 1699
	openvpn_create_dirs();
1697 1700

  
1701
	/* Some options remove the gateway or topology which are required;
1702
	 * in such cases, these can be automatically determined. */
1703
	$auto_config_gateway4 = false;
1704
	$auto_config_gateway6 = false;
1705
	$auto_config_topology = false;
1706

  
1698 1707
	if (empty($settings['server_list'])) {
1699 1708
		$csc_server_list = array();
1700 1709
	} else {
......
1706 1715
		$conf .= "disable\n";
1707 1716
	}
1708 1717

  
1709
	if ($settings['push_reset']) {
1718
	// Reset options
1719
	if (isset($settings['override_options'])) {
1720
		if ($settings['override_options'] == 'push_reset') {
1721
			if ($settings['keep_minimal']) {
1722
				$auto_config_gateway4 = true;
1723
				$auto_config_gateway6 = true;
1724
				$auto_config_topology = true;
1725
			}
1710 1726
			$conf .= "push-reset\n";
1727
		} elseif (($settings['override_options'] == 'remove_specified') && !empty($settings['remove_options'])) {
1728
			foreach (explode(',', $settings['remove_options']) as $option) {
1729
				if ($settings['keep_minimal'] && ($option == 'remove_route')) {
1730
					$auto_config_gateway4 = true;
1731
					$auto_config_gateway6 = true;
1711 1732
	}
1712

  
1713
	if ($settings['remove_route']) {
1714
		$conf .= "push-remove route\n";
1733
				$options = match ($option) {
1734
					'remove_route' => 'route',
1735
					'remove_iroute' => 'iroute',
1736
					'remove_redirect_gateway' => 'redirect-gateway',
1737
					'remove_inactive' => 'inactive',
1738
					'remove_ping' => 'ping',
1739
					'remove_ping_action' => ['ping-restart', 'ping-exit'],
1740
					'remove_blockoutsidedns' => 'block-outside-dns',
1741
					'remove_dnsdomain' => '"dhcp-option DOMAIN"',
1742
					'remove_dnsservers' => '"dhcp-option DNS"',
1743
					'remove_ntpservers' => '"dhcp-option NTP"',
1744
					'remove_netbios_ntype' => '"dhcp-option NBT"',
1745
					'remove_netbios_scope' => '"dhcp-option NBS"',
1746
					'remove_wins' => '"dhcp-option WINS"'
1747
				};
1748
				if (is_array($options)) {
1749
					foreach ($options as $option_name) {
1750
						$conf .= "push-remove {$option_name}\n";
1715 1751
					}
1752
				} else {
1753
					$conf .= "push-remove {$options}\n";
1754
				}
1755
			}
1756
		}
1757
	}
1716 1758

  
1759
	// Local network route options
1717 1760
	if ($settings['local_network']) {
1718 1761
		$conf .= openvpn_gen_routes($settings['local_network'], "ipv4", true);
1719 1762
	}
......
1721 1764
		$conf .= openvpn_gen_routes($settings['local_networkv6'], "ipv6", true);
1722 1765
	}
1723 1766

  
1724
	// Add a remote network iroute if set
1767
	// Remote network iroute options
1725 1768
	if (openvpn_validate_cidr($settings['remote_network'], "", true, "ipv4", true) === FALSE) {
1726 1769
		$conf .= openvpn_gen_routes($settings['remote_network'], "ipv4", false, true);
1727 1770
	}
1728
	// Add a remote network iroute if set
1729 1771
	if (openvpn_validate_cidr($settings['remote_networkv6'], "", true, "ipv6", true) === FALSE) {
1730 1772
		$conf .= openvpn_gen_routes($settings['remote_networkv6'], "ipv6", false, true);
1731 1773
	}
1732 1774

  
1775
	// Gatewy override options
1776
	if (!empty($settings['gateway'])) {
1777
		$auto_config_gateway4 = false;
1778
		$conf .= "push \"route-gateway {$settings['gateway']}\"\n";
1779
	}
1780
	if (!empty($settings['gateway6'])) {
1781
		$auto_config_gateway6 = false;
1782
		$conf .= "push \"route-ipv6-gateway {$settings['gateway6']}\"\n";
1783
	}
1784

  
1785
	// Inactivity override options
1786
	if (isset($settings['inactive_seconds'])) {
1787
		$conf .= "push \"inactive {$settings['inactive_seconds']}\"\n";
1788
	}
1789

  
1790
	// Ping override options
1791
	if (isset($settings['ping_seconds'])) {
1792
		$conf .= "push \"ping {$settings['ping_seconds']}\"\n";
1793
	}
1794
	if (isset($settings['ping_action'])) {
1795
		$action = str_replace("_", "-", $settings['ping_action']);
1796
		$conf .= "push \"{$action} {$settings['ping_action_seconds']}\"\n";
1797
	}
1798

  
1799
	// DHCP and gateway redirect options
1733 1800
	openvpn_add_dhcpopts($settings, $conf);
1734 1801

  
1802
	// Custom options
1735 1803
	openvpn_add_custom($settings, $conf);
1804

  
1736 1805
	/* Loop through servers, find which ones can use this CSC */
1737 1806
	foreach (config_get_path('openvpn/openvpn-server', []) as $serversettings) {
1738 1807
		if (isset($serversettings['disable'])) {
......
1742 1811
			if ($serversettings['vpnid'] && (empty($csc_server_list) || in_array($serversettings['vpnid'], $csc_server_list))) {
1743 1812
				$csc_path = "{$g['openvpn_base']}/server{$serversettings['vpnid']}/csc/" . basename($settings['common_name']);
1744 1813
				$csc_conf = $conf;
1814

  
1815
				/* Topology is depends on the server configuration.
1816
				 * TAP mode always uses a subnet topology */
1817
				$topology = ($serversettings['dev_mode'] == 'tap') ? 'subnet' : $serversettings['topology'];
1818
				if ($auto_config_topology) {
1819
					$csc_conf .= "push \"topology {$topology}\"\n";
1820
				}
1821

  
1822
				/* The gateway is the first usable address in the tunnel network.
1823
				 * If the tunnel network is not set, the gateway must be manually
1824
				 * defined. This can happen when using a net30 topology and
1825
				 * resetting options. */
1826
				if ($auto_config_gateway6) {
1827
					// IPv6 always uses a subnet topology
1828
					$tunnel_network = null;
1829
					if (!empty($settings['tunnel_networkv6'])) {
1830
						$tunnel_network = $settings['tunnel_networkv6'];
1831
					} elseif (!empty($serversettings['tunnel_networkv6'])) {
1832
						$tunnel_network = $serversettings['tunnel_networkv6'];
1833
					}
1834
					if (!empty($tunnel_network)) {
1835
						$tunnel_network_parts = openvpn_gen_tunnel_network($tunnel_network);
1836
						$gateway = ip6_after(gen_subnetv6($tunnel_network_parts[0], $tunnel_network_parts[1]));
1837
						$csc_conf .= "push \"route-ipv6-gateway {$gateway}\"\n";
1838
					}
1839
				}
1840
				if ($auto_config_gateway4) {
1841
					$tunnel_network = null;
1842
					if ($topology == "subnet") {
1843
						// The client tunnel network is assumed to be the same as the server's
1844
						$tunnel_network = $serversettings['tunnel_network'];
1845
					} elseif (!empty($settings['tunnel_network'])) {
1846
						$tunnel_network = $settings['tunnel_network'];
1847
					}
1848
					if (!empty($tunnel_network)) {
1849
						$tunnel_network_parts = openvpn_gen_tunnel_network($tunnel_network);
1850
						$gateway = ip_after(gen_subnetv4($tunnel_network_parts[0], $tunnel_network_parts[1]), 1);
1851
						$csc_conf .= "push \"route-gateway {$gateway}\"\n";
1852
					}
1853
				}
1745 1854

  
1746 1855
				if (!empty($serversettings['tunnel_network']) && !empty($settings['tunnel_network'])) {
1747 1856
					list($ip, $mask) = openvpn_gen_tunnel_network($settings['tunnel_network']);
1748
-- a/src/usr/local/www/vpn_openvpn_csc.php
1857
++ b/src/usr/local/www/vpn_openvpn_csc.php
......
34 34
require_once("pfsense-utils.inc");
35 35
require_once("pkg-utils.inc");
36 36

  
37
global $openvpn_tls_server_modes;
37
global $openvpn_tls_server_modes, $openvpn_ping_action;
38 38

  
39 39
init_config_arr(array('openvpn', 'openvpn-csc'));
40 40
$a_csc = &$config['openvpn']['openvpn-csc'];
......
78 78

  
79 79
if (($act == "edit") || ($act == "dup")) {
80 80
	if (isset($id) && $a_csc[$id]) {
81
		$pconfig['keep_minimal'] = $a_csc[$id]['keep_minimal'];
82
		// Handle the "Reset Options" list
83
		if (!empty($a_csc[$id]['remove_options'])) {
84
			$pconfig['override_options'] = 'remove_specified';
85
			$pconfig['remove_options'] = explode(',', $a_csc[$id]['remove_options']);
86
		} elseif ($a_csc[$id]['override_options'] == 'push_reset') {
87
			$pconfig['override_options'] = 'push_reset';
88
		}
89

  
81 90
		$pconfig['server_list'] = explode(",", $a_csc[$id]['server_list']);
82 91
		$pconfig['custom_options'] = $a_csc[$id]['custom_options'];
83 92
		$pconfig['disable'] = isset($a_csc[$id]['disable']);
......
89 98
		$pconfig['tunnel_networkv6'] = $a_csc[$id]['tunnel_networkv6'];
90 99
		$pconfig['local_network'] = $a_csc[$id]['local_network'];
91 100
		$pconfig['local_networkv6'] = $a_csc[$id]['local_networkv6'];
101
		$pconfig['gateway'] = $a_csc[$id]['gateway'];
102
		$pconfig['gateway6'] = $a_csc[$id]['gateway6'];
92 103
		$pconfig['remote_network'] = $a_csc[$id]['remote_network'];
93 104
		$pconfig['remote_networkv6'] = $a_csc[$id]['remote_networkv6'];
94 105
		$pconfig['gwredir'] = $a_csc[$id]['gwredir'];
106
		$pconfig['gwredir6'] = $a_csc[$id]['gwredir6'];
95 107

  
96
		$pconfig['push_reset'] = $a_csc[$id]['push_reset'];
97
		$pconfig['remove_route'] = $a_csc[$id]['remove_route'];
108
		$pconfig['inactive_seconds'] = $a_csc[$id]['inactive_seconds'];
109
		$pconfig['ping_seconds'] = $a_csc[$id]['ping_seconds'];
110
		$pconfig['ping_action'] = $a_csc[$id]['ping_action'];
111
		$pconfig['ping_action_seconds'] = $a_csc[$id]['ping_action_seconds'];
98 112

  
99 113
		$pconfig['dns_domain'] = $a_csc[$id]['dns_domain'];
100 114
		if ($pconfig['dns_domain']) {
......
113 127
			$pconfig['dns_server_enable'] = true;
114 128
		}
115 129

  
130
		$pconfig['push_blockoutsidedns'] = $a_csc[$id]['push_blockoutsidedns'];
131
		$pconfig['push_register_dns'] = $a_csc[$id]['push_register_dns'];
132

  
116 133
		$pconfig['ntp_server1'] = $a_csc[$id]['ntp_server1'];
117 134
		$pconfig['ntp_server2'] = $a_csc[$id]['ntp_server2'];
118 135

  
......
134 151
		}
135 152

  
136 153
		$pconfig['nbdd_server1'] = $a_csc[$id]['nbdd_server1'];
137
		if ($pconfig['nbdd_server1']) {
154
		$pconfig['nbdd_server2'] = $a_csc[$id]['nbdd_server2'];
155

  
156
		if ($pconfig['nbdd_server1'] || $pconfig['nbdd_server2']) {
138 157
			$pconfig['nbdd_server_enable'] = true;
139 158
		}
140 159
	}
......
157 176
		$input_errors[] = gettext("This user does not have sufficient privileges to edit Advanced options on this instance.");
158 177
	}
159 178
	if (!$user_can_edit_advanced && !empty($a_csc[$id]['custom_options'])) {
179
		// Restore the "custom options" field
160 180
		$pconfig['custom_options'] = $a_csc[$id]['custom_options'];
161 181
	}
162 182

  
......
180 200
		$input_errors[] = gettext("The field 'IPv6 Tunnel Network' must contain a valid IPv6 prefix or an alias with a single IPv6 prefix.");
181 201
	}
182 202

  
183
	if ($result = openvpn_validate_cidr($pconfig['local_network'], 'IPv4 Local Network', true, "ipv4", true)) {
203
	if (empty($pconfig['gwredir']) && ($result = openvpn_validate_cidr($pconfig['local_network'], 'IPv4 Local Network', true, "ipv4", true))) {
184 204
		$input_errors[] = $result;
185 205
	}
186 206

  
187
	if ($result = openvpn_validate_cidr($pconfig['local_networkv6'], 'IPv6 Local Network', true, "ipv6", true)) {
207
	if (empty($pconfig['gwredir6']) && ($result = openvpn_validate_cidr($pconfig['local_networkv6'], 'IPv6 Local Network', true, "ipv6", true))) {
188 208
		$input_errors[] = $result;
189 209
	}
190 210

  
211
	if (!empty($pconfig['gateway']) && !is_ipaddrv4($pconfig['gateway'])) {
212
		$input_errors[] = gettext("The specified IPv4 gateway address is invalid.");
213
	}
214

  
215
	if (!empty($pconfig['gateway6']) && !is_ipaddrv6($pconfig['gateway6'])) {
216
		$input_errors[] = gettext("The specified IPv6 gateway address is invalid.");
217
	}
218

  
191 219
	if ($result = openvpn_validate_cidr($pconfig['remote_network'], 'IPv4 Remote Network', true, "ipv4", true)) {
192 220
		$input_errors[] = $result;
193 221
	}
......
196 224
		$input_errors[] = $result;
197 225
	}
198 226

  
227
	if (!empty($pconfig['inactive_seconds']) && !is_numericint($pconfig['inactive_seconds'])) {
228
		$input_errors[] = gettext('The supplied "Inactivity Timeout" value is invalid.');
229
	}
230

  
231
	if (!empty($pconfig['ping_seconds']) && !is_numericint($pconfig['ping_seconds'])) {
232
		$input_errors[] = gettext('The supplied "Ping Interval" value is invalid.');
233
	}
234
	if (!empty($pconfig['ping_action']) && ($pconfig['ping_action'] != 'default')) {
235
		if (!isset($openvpn_ping_action[$pconfig['ping_action']])) {
236
			$input_errors[] = gettext('The field "Ping Action" contains an invalid selection.');
237
		}
238
		if (!is_numericint($pconfig['ping_action_seconds'])) {
239
			$input_errors[] = gettext('The supplied "Ping Action" timeout value is invalid.');
240
		}
241
	}
242

  
199 243
	if ($pconfig['dns_server_enable']) {
200 244
		if (!empty($pconfig['dns_server1']) && !is_ipaddr(trim($pconfig['dns_server1']))) {
201 245
			$input_errors[] = gettext("The field 'DNS Server #1' must contain a valid IP address");
......
239 283
			if (!empty($pconfig['nbdd_server1']) && !is_ipaddr(trim($pconfig['nbdd_server1']))) {
240 284
				$input_errors[] = gettext("The field 'NetBIOS Data Distribution Server #1' must contain a valid IP address");
241 285
			}
286
			if (!empty($pconfig['nbdd_server2']) && !is_ipaddr(trim($pconfig['nbdd_server2']))) {
287
				$input_errors[] = gettext("The field 'NetBIOS Data Distribution Server #2' must contain a valid IP address");
242 288
			}
289
		}
243 290

  
244 291
		if (!empty($pconfig['netbios_ntype']) &&
245 292
		    !array_key_exists($pconfig['netbios_ntype'], $netbios_nodetypes)) {
......
255 302
	if (!$input_errors) {
256 303
		$csc = array();
257 304

  
305
		// Handle "Reset Server Options" and "Reset Options"
306
		$csc['override_options'] = $pconfig['override_options'];
307
		if ($pconfig['override_options'] == 'remove_specified') {
308
			// If no options are specified, keep the default behavior.
309
			if (!empty($pconfig['remove_options'])) {
310
				$csc['remove_options'] = implode(',', $pconfig['remove_options']);
311
			}
312
		}
313
		if (!empty($pconfig['keep_minimal']) && ($pconfig['override_options'] != 'default')) {
314
			//Do not set keep_minimal if override_options is on "default"
315
			$csc['keep_minimal'] = $pconfig['keep_minimal'];
316
		}
317

  
258 318
		if (is_array($pconfig['server_list'])) {
259 319
			$csc['server_list'] = implode(",", $pconfig['server_list']);
260 320
		} else {
......
269 329
		$csc['description'] = $pconfig['description'];
270 330
		$csc['tunnel_network'] = $pconfig['tunnel_network'];
271 331
		$csc['tunnel_networkv6'] = $pconfig['tunnel_networkv6'];
332

  
333
		$csc['gateway'] = $pconfig['gateway'];
334
		$csc['gateway6'] = $pconfig['gateway6'];
335
		// Don't push routes if redirecting all traffic.
336
		if (!empty($pconfig['gwredir'])) {
337
			$csc['gwredir'] = $pconfig['gwredir'];
338
		} else {
272 339
			$csc['local_network'] = $pconfig['local_network'];
340
		}
341
		if (!empty($pconfig['gwredir6'])) {
342
			$csc['gwredir6'] = $pconfig['gwredir6'];
343
		} else {
273 344
			$csc['local_networkv6'] = $pconfig['local_networkv6'];
345
		}
346

  
274 347
		$csc['remote_network'] = $pconfig['remote_network'];
275 348
		$csc['remote_networkv6'] = $pconfig['remote_networkv6'];
276
		$csc['gwredir'] = $pconfig['gwredir'];
277
		$csc['push_reset'] = $pconfig['push_reset'];
278
		$csc['remove_route'] = $pconfig['remove_route'];
279 349

  
350
		if (is_numericint($pconfig['inactive_seconds'])) {
351
			$csc['inactive_seconds'] = $pconfig['inactive_seconds'];
352
		}
353
		if (is_numericint($pconfig['ping_seconds'])) {
354
			$csc['ping_seconds'] = $pconfig['ping_seconds'];
355
		}
356
		if (!empty($pconfig['ping_action']) && ($pconfig['ping_action'] != 'default')) {
357
			$csc['ping_action'] = $pconfig['ping_action'];
358
			$csc['ping_action_seconds'] = $pconfig['ping_action_seconds'];
359
		}
360

  
280 361
		if ($pconfig['dns_domain_enable']) {
281 362
			$csc['dns_domain'] = $pconfig['dns_domain'];
282 363
		}
......
288 369
			$csc['dns_server4'] = $pconfig['dns_server4'];
289 370
		}
290 371

  
372
		$csc['push_blockoutsidedns'] = $pconfig['push_blockoutsidedns'];
373
		$csc['push_register_dns'] = $pconfig['push_register_dns'];
374

  
291 375
		if ($pconfig['ntp_server_enable']) {
292 376
			$csc['ntp_server1'] = $pconfig['ntp_server1'];
293 377
			$csc['ntp_server2'] = $pconfig['ntp_server2'];
294 378
		}
295 379

  
296 380
		$csc['netbios_enable'] = $pconfig['netbios_enable'];
381

  
382
		if ($pconfig['netbios_enable']) {
297 383
		$csc['netbios_ntype'] = $pconfig['netbios_ntype'];
298 384
		$csc['netbios_scope'] = $pconfig['netbios_scope'];
299 385

  
300
		if ($pconfig['netbios_enable']) {
301 386
			if ($pconfig['wins_server_enable']) {
302 387
				$csc['wins_server1'] = $pconfig['wins_server1'];
303 388
				$csc['wins_server2'] = $pconfig['wins_server2'];
304 389
			}
305 390

  
306
			if ($pconfig['dns_server_enable']) {
391
			if ($pconfig['nbdd_server_enable']) {
307 392
				$csc['nbdd_server1'] = $pconfig['nbdd_server1'];
393
				$csc['nbdd_server2'] = $pconfig['nbdd_server2'];
308 394
			}
309 395
		}
310 396

  
......
407 493
		true
408 494
		))->setHelp('Select the servers that will utilize this override. When no servers are selected, the override will apply to all servers.');
409 495

  
496

  
497
	$section->addInput(new Form_Select(
498
		'override_options',
499
		'Reset Server Options',
500
		($pconfig['override_options'] ?? 'default'),
501
		[
502
			'default' => 'Keep all server options (default)',
503
			'push_reset' => 'Reset all options',
504
			'remove_specified' => 'Remove specified options'
505
		]
506
	))->setHelp('Prevent this client from receiving server-defined client settings. Other client-specific options on this page will supersede these options.');
507

  
508
	$group = new Form_Group('Remove Options');
509
	$group->addClass('remove_options');
510
	$group->add(new Form_Select(
511
		'remove_options',
512
		null,
513
		$pconfig['remove_options'],
514
		[
515
			'remove_route' => 'Local Routes and Gateways',
516
			'remove_iroute' => 'Remote Routes',
517
			'remove_redirect_gateway' => 'Redirect Gateways',
518
			'remove_inactive' => 'Inactivity Timeout',
519
			'remove_ping' => 'Client Ping',
520
			'remove_ping_action' => 'Ping Action',
521
			'remove_blockoutsidedns' => 'Block Outside DNS',
522
			'remove_dnsdomain' => 'DNS Domains',
523
			'remove_dnsservers' => 'DNS Servers',
524
			'remove_ntpservers' => 'NTP Options',
525
			'remove_netbios_ntype' => 'NetBIOS Type',
526
			'remove_netbios_scope' => 'NetBIOS Scope',
527
			'remove_wins' => 'WINS Options'
528
		],
529
		true
530
	))->setHelp('A "push-remove" option will be sent to the client for the selected options, removing the respective server-defined option.');
531
	$section->add($group);
532

  
533
	$section->addInput(new Form_Checkbox(
534
		'keep_minimal',
535
		'Keep minimal options',
536
		'Automatically determine the client topology and gateway',
537
		$pconfig['keep_minimal']
538
	))->setHelp('If checked, generate the required client configuration when server options are reset or removed.');
539

  
410 540
	$form->add($section);
411 541

  
412 542
	$section = new Form_Section('Tunnel Settings');
......
431 561
			'<br />');
432 562

  
433 563
	$section->addInput(new Form_Input(
564
		'gateway',
565
		'IPv4 Gateway',
566
		'text',
567
		$pconfig['gateway']
568
	))->setHelp('This is the IPv4 Gateway to push to the client. Normally it is left blank and determined automatically.');
569

  
570
	$section->addInput(new Form_Input(
571
		'gateway6',
572
		'IPv6 Gateway',
573
		'text',
574
		$pconfig['gateway6']
575
	))->setHelp('This is the IPv6 Gateway to push to the client. Normally it is left blank and determined automatically.');
576

  
577
	$section->addInput(new Form_Checkbox(
578
		'gwredir',
579
		'Redirect IPv4 Gateway',
580
		'Force all client generated IPv4 traffic through the tunnel.',
581
		$pconfig['gwredir']
582
	));
583

  
584
	$section->addInput(new Form_Checkbox(
585
		'gwredir6',
586
		'Redirect IPv6 Gateway',
587
		'Force all client-generated IPv6 traffic through the tunnel.',
588
		$pconfig['gwredir6']
589
	));
590

  
591
	$section->addInput(new Form_Input(
434 592
		'local_network',
435 593
		'IPv4 Local Network/s',
436 594
		'text',
......
468 626
		    'NOTE: Remember to add these subnets to the IPv6 Remote Networks list on the corresponding OpenVPN server settings.',
469 627
			'<br />');
470 628

  
471
	$section->addInput(new Form_Checkbox(
472
		'gwredir',
473
		'Redirect Gateway',
474
		'Force all client generated traffic through the tunnel.',
475
		$pconfig['gwredir']
476
	));
477

  
478 629
	$form->add($section);
479 630

  
480
	$section = new Form_Section('Client Settings');
631
	$section = new Form_Section('Other Client Settings');
481 632

  
482
	$section->addInput(new Form_Checkbox(
483
		'push_reset',
484
		'Server Definitions',
485
		'Prevent this client from receiving any server-defined client settings. ',
486
		$pconfig['push_reset']
487
	));
633
	$section->addInput(new Form_Input(
634
		'inactive_seconds',
635
		'Inactivity Timeout',
636
		'number',
637
		$pconfig['inactive_seconds'],
638
		['min' => '0']
639
	))->setHelp('Set connection inactivity timeout')->setWidth(3);
488 640

  
489
	/* as "push-reset" can break subnet topology, 
490
	 * "push-remove route" removes only IPv4/IPv6 routes, see #9702 */
491
	$section->addInput(new Form_Checkbox(
492
		'remove_route',
493
		'Remove Server Routes',
494
		'Prevent this client from receiving any server-defined routes without removing any other options. ',
495
		$pconfig['remove_route']
496
	));
641
	$section->addInput(new Form_Input(
642
		'ping_seconds',
643
		'Ping Interval',
644
		'number',
645
		$pconfig['ping_seconds'],
646
		['min' => '0']
647
	))->setHelp('Set peer ping interval')->setWidth(3);
497 648

  
649
	$group = new Form_Group('Ping Action');
650
	$group->add(new Form_Select(
651
		'ping_action',
652
		null,
653
		$pconfig['ping_action'] ?? 'default',
654
		array_merge([
655
			'default' => 'Don\'t override option (default)'
656
		], $openvpn_ping_action)
657
	))->setHelp('Exit or restart OpenVPN client after server timeout')->setWidth(4);
658
	$group->add(new Form_Input(
659
		'ping_action_seconds',
660
		'timeout seconds',
661
		'number',
662
		$pconfig['ping_action_seconds'],
663
		['min' => '0']
664
	))->setWidth(2)->addClass('ping_action_seconds');
665
	$section->add($group);
666

  
498 667
	$section->addInput(new Form_Checkbox(
499 668
		'dns_domain_enable',
500 669
		'DNS Default Domain',
......
555 724

  
556 725
	$section->add($group);
557 726

  
727
	$section->addInput(new Form_Checkbox(
728
		'push_blockoutsidedns',
729
		'Block Outside DNS',
730
		'Make Windows 10 Clients Block access to DNS servers except across OpenVPN while connected, forcing clients to use only VPN DNS servers.',
731
		$pconfig['push_blockoutsidedns']
732
	))->setHelp('Requires Windows 10 and OpenVPN 2.3.9 or later. Only Windows 10 is prone to DNS leakage in this way, other clients will ignore the option as they are not affected.');
733

  
734
	$section->addInput(new Form_Checkbox(
735
		'push_register_dns',
736
		'Force DNS cache update',
737
		'Run "net stop dnscache", "net start dnscache", "ipconfig /flushdns" and "ipconfig /registerdns" on connection initiation.',
738
		$pconfig['push_register_dns']
739
	))->setHelp('This is known to kick Windows into recognizing pushed DNS servers.');
740

  
558 741
	// NTP servers
559 742
	$section->addInput(new Form_Checkbox(
560 743
		'ntp_server_enable',
......
634 817

  
635 818
	$section->add($group);
636 819

  
820
	$section->addInput(new Form_Checkbox(
821
		'nbdd_server_enable',
822
		'NBDD servers',
823
		'Provide a NetBIOS over TCP/IP Datagram Distribution Servers list to clients',
824
		$pconfig['nbdd_server_enable']
825
	));
826

  
827
	$group = new Form_Group(null);
828

  
829
	$group->add(new Form_Input(
830
		'nbdd_server1',
831
		null,
832
		'text',
833
		$pconfig['nbdd_server1']
834
	))->setHelp('Server 1');
835

  
836
	$group->add(new Form_Input(
837
		'nbdd_server2',
838
		null,
839
		'text',
840
		$pconfig['nbdd_server2']
841
	))->setHelp('Server 2');
842

  
843
	$group->addClass('nbddservers');
844

  
845
	$section->add($group);
846

  
637 847
	$custops = new Form_Textarea(
638 848
		'custom_options',
639 849
		'Advanced',
......
671 881
<script type="text/javascript">
672 882
//<![CDATA[
673 883
events.push(function() {
884
	function gwredir_change() {
885
		hideInput('local_network', ($('#gwredir').prop('checked')));
886
	}
887

  
888
	function gwredir6_change() {
889
		hideInput('local_networkv6', ($('#gwredir6').prop('checked')));
890
	}
891

  
892
	function ping_action_change() {
893
		hideClass('ping_action_seconds', ($('#ping_action').find('option:selected').val() == 'default'));
894
	}
895

  
674 896
	function dnsdomain_change() {
675 897
		if ($('#dns_domain_enable').prop('checked')) {
676 898
			hideClass('dnsdomain', false);
......
702 924
			hideInput('netbios_scope', false);
703 925
			hideCheckbox('wins_server_enable', false);
704 926
			setWins();
927
			hideCheckbox('nbdd_server_enable', false);
928
			setNbdds();
705 929
		} else {
706 930
			hideInput('netbios_ntype', true);
707 931
			hideInput('netbios_scope', true);
708 932
			hideCheckbox('wins_server_enable', true);
709 933
			hideClass('winsservers', true);
934
			hideCheckbox('nbdd_server_enable', true);
935
			hideClass('nbddservers', true);
710 936
		}
711 937
	}
712 938

  
......
714 940
		hideClass('winsservers', ! $('#wins_server_enable').prop('checked'));
715 941
	}
716 942

  
943
	function setNbdds() {
944
		hideClass('nbddservers', ! $('#nbdd_server_enable').prop('checked'));
945
	}
946

  
947
	function remove_options_change() {
948
		hideCheckbox('keep_minimal', ($('#override_options').find('option:selected').val() == 'default'));
949
		hideClass('remove_options', ($('#override_options').find('option:selected').val() != 'remove_specified'));
950
	}
951

  
717 952
	// ---------- Click checkbox handlers ---------------------------------------------------------
718 953

  
954
	 // On clicking Gateway redirect
955
	$('#gwredir').click(function () {
956
		gwredir_change();
957
	});
958

  
959
	 // On clicking Gateway redirect IPv6
960
	$('#gwredir6').click(function () {
961
		gwredir6_change();
962
	});
963

  
964
	 // On clicking Ping Action
965
	$('#ping_action').click(function () {
966
		ping_action_change();
967
	});
968

  
719 969
	 // On clicking DNS Default Domain
720 970
	$('#dns_domain_enable').click(function () {
721 971
		dnsdomain_change();
......
741 991
		setWins();
742 992
	});
743 993

  
994
	// On clicking the nbdd_server_enable checkbox
995
	$('#nbdd_server_enable').click(function () {
996
		setNbdds();
997
	});
998

  
999
	$('#override_options').on('change', function() {
1000
		remove_options_change();
1001
	});
744 1002
	// ---------- On initial page load ------------------------------------------------------------
745 1003

  
1004
	remove_options_change();
1005
	gwredir_change();
1006
	gwredir6_change();
1007
	ping_action_change();
746 1008
	setNetbios();
747 1009
	dnsdomain_change();
748 1010
	dnsservers_change();
749
-- a/src/etc/inc/upgrade_config.inc
1011
++ b/src/etc/inc/upgrade_config.inc
......
7026 7026
	}
7027 7027
}
7028 7028

  
7029
/* OpenVPN Client-Specific Override options have changed.
7030
 * https://redmine.pfsense.org/issues/12522 */
7031
 function upgrade_233_to_234() {
7032
	$openvpn_csc_config = config_get_path('openvpn/openvpn-csc', []);
7033
	if (empty($openvpn_csc_config)) {
7034
		return;
7035
	}
7036
	foreach ($openvpn_csc_config as &$settings) {
7037
		if (!is_array($settings)) {
7038
			continue;
7039
		}
7040

  
7041
		// Migrate "remove_route"
7042
		if (isset($settings['remove_route'])) {
7043
			$settings['remove_options'] = 'remove_route';
7044
			unset($settings['remove_route']);
7045
		}
7046
	}
7047
	config_set_path('openvpn/openvpn-csc', $openvpn_csc_config);
7048
}
7049

  
7029 7050
/*
7030 7051
 * Special function that is called independent of current config version. It's
7031 7052
 * a workaround to have config_upgrade running on older versions after next
7032
-- a/src/etc/inc/util.inc
7053
++ b/src/etc/inc/util.inc
......
533 533
	return long2ip32(ip2long($ip) + $offset);
534 534
}
535 535

  
536
/**
537
 * Return the next IPv6 address after the given address
538
 * 
539
 * @param string $ip IPv6 address
540
 * 
541
 * @return string|false IPv6 address; false if it cannot be incremented
542
 */
543
function ip6_after(string $ip): string|false {
544
	/* Convert the IPv6 string to its in_addr representation,
545
	 * increment it by one, then convert it back to a string. */
546
	return inet_ntop(str_pad(gmp_export(
547
		str_increment((string) gmp_import(inet_pton($ip)))
548
	), 16, "\0", STR_PAD_LEFT));
549
}
550

  
536 551
/* Return true if the first IP is 'before' the second */
537 552
function ip_less_than($ip1, $ip2) {
538 553
	// Compare as unsigned long because otherwise it wouldn't work when
(11-11/14)