Revision 2ca58ffd
Added by Reid Linnemann almost 3 years ago
src/etc/inc/filter.inc | ||
---|---|---|
103 | 103 |
global $filter_interface_remove; |
104 | 104 |
$filter_interface_remove = array(); |
105 | 105 |
|
106 |
if ($config['ipsec']['filtermode'] == 'if_ipsec') {
|
|
106 |
if (config_get_path('ipsec/filtermode') == 'if_ipsec') {
|
|
107 | 107 |
$filter_interface_remove[] = 'enc'; |
108 | 108 |
} else { |
109 | 109 |
$filter_interface_remove[] = 'ipsec'; |
... | ... | |
1137 | 1137 |
|
1138 | 1138 |
/* returns space separated list of vpn subnets */ |
1139 | 1139 |
function filter_get_vpns_list() { |
1140 |
global $config; |
|
1141 |
|
|
1142 | 1140 |
$vpns = ""; |
1143 | 1141 |
$vpns_arr = array(); |
1144 | 1142 |
|
... | ... | |
1149 | 1147 |
if (ipsec_enabled()) { |
1150 | 1148 |
/* Include mobile IPsec client subnet in the VPN network list. |
1151 | 1149 |
See https://redmine.pfsense.org/issues/7005 */ |
1152 |
if (is_array($config['ipsec']['client']) |
|
1153 |
&& isset($config['ipsec']['client']['enable']) |
|
1154 |
&& isset($config['ipsec']['client']['pool_address']) |
|
1155 |
&& isset($config['ipsec']['client']['pool_netbits'])) { |
|
1156 |
$client_subnet = "{$config['ipsec']['client']['pool_address']}/{$config['ipsec']['client']['pool_netbits']}"; |
|
1150 |
$pool_address = config_get_path('ipsec/client/pool_address'); |
|
1151 |
$pool_netbits = config_get_path('ipsec/client/pool_netbits'); |
|
1152 |
if (config_path_enabled('ipsec/client') |
|
1153 |
&& isset($pool_address) |
|
1154 |
&& isset($pool_netbits)) { |
|
1155 |
$client_subnet = "{$pool_address}/{$pool_netbits}"; |
|
1157 | 1156 |
if (is_subnet($client_subnet)) { |
1158 | 1157 |
$vpns_arr[] = $client_subnet; |
1159 | 1158 |
} |
1160 | 1159 |
} |
1161 |
if (is_array($config['ipsec']['phase2'])) { |
|
1162 |
foreach ($config['ipsec']['phase2'] as $ph2ent) { |
|
1163 |
if ((!$ph2ent['mobile']) && ($ph2ent['mode'] != 'transport') && |
|
1164 |
!isset($ph2ent['disabled'])) { |
|
1165 |
if (!is_array($ph2ent['remoteid'])) { |
|
1166 |
continue; |
|
1167 |
} |
|
1168 |
$ph2ent['remoteid']['mode'] = $ph2ent['mode']; |
|
1169 |
$vpns_subnet = ipsec_idinfo_to_cidr($ph2ent['remoteid'], true); |
|
1170 |
if (!is_subnet($vpns_subnet) || $vpns_subnet == "0.0.0.0/0" || $vpns_subnet == "::/0") { |
|
1171 |
continue; |
|
1172 |
} |
|
1173 |
$vpns_arr[] = $vpns_subnet; |
|
1160 |
foreach (config_get_path('ipsec/phase2', []) as $ph2ent) { |
|
1161 |
if ((!$ph2ent['mobile']) && ($ph2ent['mode'] != 'transport') && |
|
1162 |
!isset($ph2ent['disabled'])) { |
|
1163 |
if (!is_array($ph2ent['remoteid'])) { |
|
1164 |
continue; |
|
1165 |
} |
|
1166 |
$ph2ent['remoteid']['mode'] = $ph2ent['mode']; |
|
1167 |
$vpns_subnet = ipsec_idinfo_to_cidr($ph2ent['remoteid'], true); |
|
1168 |
if (!is_subnet($vpns_subnet) |
|
1169 |
|| $vpns_subnet == "0.0.0.0/0" |
|
1170 |
|| $vpns_subnet == "::/0") { |
|
1171 |
continue; |
|
1174 | 1172 |
} |
1173 |
$vpns_arr[] = $vpns_subnet; |
|
1175 | 1174 |
} |
1176 | 1175 |
} |
1177 | 1176 |
} |
... | ... | |
1379 | 1378 |
$FilterIflist[$if] = $oic; |
1380 | 1379 |
} |
1381 | 1380 |
|
1382 |
if ($config['l2tp']['mode'] == "server") {
|
|
1381 |
if (config_get_path('l2tp/mode') == "server") {
|
|
1383 | 1382 |
$oic = array(); |
1384 | 1383 |
$oic['if'] = 'l2tp'; |
1385 | 1384 |
$oic['descr'] = 'L2TP'; |
... | ... | |
1394 | 1393 |
$oic['virtual'] = true; |
1395 | 1394 |
$FilterIflist['l2tp'] = $oic; |
1396 | 1395 |
} |
1397 |
if (is_array($config['pppoes']['pppoe']) && (count($config['pppoes']['pppoe']) > 0)) { |
|
1398 |
$pppoeifs = array(); |
|
1399 |
foreach ($config['pppoes']['pppoe'] as $pppoe) { |
|
1400 |
if ($pppoe['mode'] == "server") { |
|
1401 |
$oic = array(); |
|
1402 |
$oic['if'] = 'pppoe'; |
|
1403 |
$oic['descr'] = 'pppoe'; |
|
1404 |
$oic['ip'] = $pppoe['localip']; |
|
1405 |
$oic['sa'] = $pppoe['remoteip']; |
|
1406 |
$oic['mode'] = $pppoe['mode']; |
|
1407 |
$oic['virtual'] = true; |
|
1408 |
if ($pppoe['pppoe_subnet'] <> "") { |
|
1409 |
$oic['sn'] = $pppoe['pppoe_subnet']; |
|
1410 |
} else { |
|
1411 |
$oic['sn'] = "32"; |
|
1412 |
} |
|
1413 |
$pppoeifs[] = $oic; |
|
1396 |
$pppoeifs = array(); |
|
1397 |
foreach (config_get_path('pppoes/pppoe', []) as $pppoe) { |
|
1398 |
if ($pppoe['mode'] == "server") { |
|
1399 |
$oic = array(); |
|
1400 |
$oic['if'] = 'pppoe'; |
|
1401 |
$oic['descr'] = 'pppoe'; |
|
1402 |
$oic['ip'] = $pppoe['localip']; |
|
1403 |
$oic['sa'] = $pppoe['remoteip']; |
|
1404 |
$oic['mode'] = $pppoe['mode']; |
|
1405 |
$oic['virtual'] = true; |
|
1406 |
if ($pppoe['pppoe_subnet'] <> "") { |
|
1407 |
$oic['sn'] = $pppoe['pppoe_subnet']; |
|
1408 |
} else { |
|
1409 |
$oic['sn'] = "32"; |
|
1414 | 1410 |
} |
1415 |
} |
|
1416 |
if (count($pppoeifs)) { |
|
1417 |
$FilterIflist['pppoe'] = $pppoeifs; |
|
1411 |
$pppoeifs[] = $oic; |
|
1418 | 1412 |
} |
1419 | 1413 |
} |
1414 |
if (count($pppoeifs)) { |
|
1415 |
$FilterIflist['pppoe'] = $pppoeifs; |
|
1416 |
} |
|
1420 | 1417 |
/* add ipsec interfaces */ |
1421 | 1418 |
if (!function_exists('ipsec_enabled')) { |
1422 | 1419 |
require_once("ipsec.inc"); |
... | ... | |
1824 | 1821 |
} |
1825 | 1822 |
|
1826 | 1823 |
function filter_nat_rules_automatic_tonathosts($with_descr = false) { |
1827 |
global $config, $FilterIflist, $GatewaysList;
|
|
1824 |
global $FilterIflist, $GatewaysList; |
|
1828 | 1825 |
|
1829 | 1826 |
$tonathosts = array("127.0.0.0/8", "::1/128"); |
1830 | 1827 |
$descriptions = array(gettext("localhost"), gettext("localhost")); |
... | ... | |
1910 | 1907 |
|
1911 | 1908 |
// OpenVPN CSO |
1912 | 1909 |
init_config_arr(array('openvpn', 'openvpn-csc')); |
1913 |
foreach ($config['openvpn']['openvpn-csc'] as $ovpnent) {
|
|
1910 |
foreach (config_get_path('openvpn/openvpn-csc') as $ovpnent) {
|
|
1914 | 1911 |
if (is_array($ovpnent) && !isset($ovpnent['disable']) && !empty($ovpnent['tunnel_network'])) { |
1915 | 1912 |
$tonathosts[] = implode('/', openvpn_gen_tunnel_network($ovpnent['tunnel_network'])); |
1916 | 1913 |
$descriptions[] = gettext("OpenVPN CSO"); |
... | ... | |
1918 | 1915 |
} |
1919 | 1916 |
|
1920 | 1917 |
/* IPsec mode_cfg subnet */ |
1918 |
$ipsc_pool_addr = config_get_path('ipsec/client/pool_address'); |
|
1919 |
$ipsc_pool_netbits = config_get_path('ipsec/client/pool_netbits'); |
|
1921 | 1920 |
if (config_path_enabled('ipsec/client') && |
1922 |
(!empty($config['ipsec']['client']['pool_address'])) &&
|
|
1923 |
(!empty($config['ipsec']['client']['pool_netbits']))) {
|
|
1924 |
$tonathosts[] = "{$config['ipsec']['client']['pool_address']}/{$config['ipsec']['client']['pool_netbits']}";
|
|
1921 |
(!empty($ipsc_pool_addr)) &&
|
|
1922 |
(!empty($ipsc_pool_netbits))) {
|
|
1923 |
$tonathosts[] = "{$ipsc_pool_addr}/{$ipsc_pool_netbits}";
|
|
1925 | 1924 |
$descriptions[] = gettext("IPsec client"); |
1926 | 1925 |
} |
1927 |
if (config_path_enabled('ipsec/client') && |
|
1928 |
isset($config['ipsec']['mobilekey'])) { |
|
1929 |
foreach ($config['ipsec']['mobilekey'] as $key) { |
|
1926 |
if (config_path_enabled('ipsec/client')) { |
|
1927 |
foreach (config_get_path('ipsec/mobilekey', []) as $key) { |
|
1930 | 1928 |
if (in_array("{$key['pool_address']}/{$key['pool_netbits']}", $tonathosts)) { |
1931 | 1929 |
continue; |
1932 | 1930 |
} |
... | ... | |
1937 | 1935 |
} |
1938 | 1936 |
} |
1939 | 1937 |
} |
1940 |
if (is_array($config['ipsec']) && is_array($config['ipsec']['phase1']) && is_array($config['ipsec']['phase2'])) { |
|
1941 |
foreach ($config['ipsec']['phase1'] as $ph1ent) { |
|
1942 |
$vti_addrs = ipsec_vti($ph1ent, true); |
|
1943 |
// Skip non-VTI tunnels |
|
1944 |
if (!$vti_addrs || !is_array($vti_addrs)) { |
|
1945 |
continue; |
|
1946 |
} |
|
1947 |
// If any of the VTI remotes is v4, then we can make a v4 gw |
|
1948 |
foreach ($vti_addrs as $vtia) { |
|
1949 |
if (is_ipaddrv4($vtia['right'])) { |
|
1950 |
$tonathosts[] = $vtia['right']; |
|
1951 |
$descriptions[] = gettext("IPsec VTI: {$ph1ent['descr']}"); |
|
1952 |
} |
|
1938 |
foreach (config_get_path('ipsec/phase1', []) as $ph1ent) { |
|
1939 |
$vti_addrs = ipsec_vti($ph1ent, true); |
|
1940 |
// Skip non-VTI tunnels |
|
1941 |
if (!$vti_addrs || !is_array($vti_addrs)) { |
|
1942 |
continue; |
|
1943 |
} |
|
1944 |
// If any of the VTI remotes is v4, then we can make a v4 gw |
|
1945 |
foreach ($vti_addrs as $vtia) { |
|
1946 |
if (is_ipaddrv4($vtia['right'])) { |
|
1947 |
$tonathosts[] = $vtia['right']; |
|
1948 |
$descriptions[] = gettext("IPsec VTI: {$ph1ent['descr']}"); |
|
1953 | 1949 |
} |
1954 | 1950 |
} |
1955 | 1951 |
} |
... | ... | |
2180 | 2176 |
} |
2181 | 2177 |
|
2182 | 2178 |
function filter_nat_rules_generate() { |
2183 |
global $config, $g, $FilterIflist;
|
|
2179 |
global $g, $FilterIflist; |
|
2184 | 2180 |
|
2185 | 2181 |
init_config_arr(array('ipsec', 'client')); |
2186 |
$ipsec_client = $config['ipsec']['client'];
|
|
2182 |
$ipsec_client = config_get_path('ipsec/client');
|
|
2187 | 2183 |
|
2188 | 2184 |
$natrules = "no nat proto carp\n"; |
2189 | 2185 |
$natrules .= "no rdr proto carp\n"; |
... | ... | |
2198 | 2194 |
$route_table = ""; |
2199 | 2195 |
|
2200 | 2196 |
/* any 1:1 mappings? */ |
2201 |
if (is_array($config['nat']['onetoone'])) { |
|
2202 |
foreach ($config['nat']['onetoone'] as $rule) { |
|
2203 |
if (isset($rule['disabled'])) { |
|
2204 |
continue; |
|
2205 |
} |
|
2197 |
foreach (config_get_path('nat/onetoone', []) as $rule) { |
|
2198 |
if (isset($rule['disabled'])) { |
|
2199 |
continue; |
|
2200 |
} |
|
2206 | 2201 |
|
2207 |
$sn = "";
|
|
2208 |
$sn1 = "";
|
|
2202 |
$sn = ""; |
|
2203 |
$sn1 = ""; |
|
2209 | 2204 |
|
2210 |
if (($rule['ipprotocol'] == 'inet6') || is_ipaddrv6($rule['external'])) {
|
|
2211 |
$ipproto = 'inet6';
|
|
2212 |
} else {
|
|
2213 |
$ipproto = 'inet';
|
|
2214 |
}
|
|
2205 |
if (($rule['ipprotocol'] == 'inet6') || is_ipaddrv6($rule['external'])) { |
|
2206 |
$ipproto = 'inet6'; |
|
2207 |
} else { |
|
2208 |
$ipproto = 'inet'; |
|
2209 |
} |
|
2215 | 2210 |
|
2216 |
if (is_ipaddr($rule['external'])) {
|
|
2217 |
$target = $rule['external'];
|
|
2218 |
} else {
|
|
2219 |
$tmprule = array();
|
|
2220 |
$tmprule['external']['network'] = $rule['external'];
|
|
2221 |
$tmprule['ipprotocol'] = $ipproto;
|
|
2222 |
$target = filter_generate_address($tmprule, 'external');
|
|
2223 |
}
|
|
2224 |
if (!$target) {
|
|
2225 |
$natrules .= "# Unresolvable alias {$rule['target']}\n";
|
|
2226 |
continue; /* unresolvable alias */
|
|
2227 |
}
|
|
2211 |
if (is_ipaddr($rule['external'])) { |
|
2212 |
$target = $rule['external']; |
|
2213 |
} else { |
|
2214 |
$tmprule = array(); |
|
2215 |
$tmprule['external']['network'] = $rule['external']; |
|
2216 |
$tmprule['ipprotocol'] = $ipproto; |
|
2217 |
$target = filter_generate_address($tmprule, 'external'); |
|
2218 |
} |
|
2219 |
if (!$target) { |
|
2220 |
$natrules .= "# Unresolvable alias {$rule['target']}\n"; |
|
2221 |
continue; /* unresolvable alias */ |
|
2222 |
} |
|
2228 | 2223 |
|
2229 |
if (!$rule['interface']) {
|
|
2230 |
$natif = "wan";
|
|
2231 |
} else {
|
|
2232 |
$natif = $rule['interface'];
|
|
2233 |
}
|
|
2234 |
if (!isset($FilterIflist[$natif])) {
|
|
2235 |
continue;
|
|
2236 |
}
|
|
2224 |
if (!$rule['interface']) { |
|
2225 |
$natif = "wan"; |
|
2226 |
} else { |
|
2227 |
$natif = $rule['interface']; |
|
2228 |
} |
|
2229 |
if (!isset($FilterIflist[$natif])) { |
|
2230 |
continue; |
|
2231 |
} |
|
2237 | 2232 |
|
2238 |
$srcaddr = filter_generate_address($rule, 'source');
|
|
2239 |
$dstaddr = filter_generate_address($rule, 'destination');
|
|
2240 |
$srcaddr = trim($srcaddr);
|
|
2241 |
$dstaddr = trim($dstaddr);
|
|
2233 |
$srcaddr = filter_generate_address($rule, 'source'); |
|
2234 |
$dstaddr = filter_generate_address($rule, 'destination'); |
|
2235 |
$srcaddr = trim($srcaddr); |
|
2236 |
$dstaddr = trim($dstaddr); |
|
2242 | 2237 |
|
2243 |
if (empty($srcaddr) || empty($dstaddr)) {
|
|
2244 |
continue;
|
|
2245 |
}
|
|
2238 |
if (empty($srcaddr) || empty($dstaddr)) { |
|
2239 |
continue; |
|
2240 |
} |
|
2246 | 2241 |
|
2247 |
if (($srcaddr != 'any') && !is_ipaddr($srcaddr) && !is_subnet($srcaddr)) {
|
|
2248 |
$srcaddr = explode(' ', $srcaddr)[1];
|
|
2249 |
}
|
|
2250 |
$tmp = explode('/', $srcaddr);
|
|
2251 |
$srcip = $tmp[0];
|
|
2252 |
if (!empty($tmp[1]) && is_numeric($tmp[1])) {
|
|
2253 |
$sn = $tmp[1];
|
|
2254 |
$sn1 = "/{$sn}";
|
|
2255 |
}
|
|
2242 |
if (($srcaddr != 'any') && !is_ipaddr($srcaddr) && !is_subnet($srcaddr)) { |
|
2243 |
$srcaddr = explode(' ', $srcaddr)[1]; |
|
2244 |
} |
|
2245 |
$tmp = explode('/', $srcaddr); |
|
2246 |
$srcip = $tmp[0]; |
|
2247 |
if (!empty($tmp[1]) && is_numeric($tmp[1])) { |
|
2248 |
$sn = $tmp[1]; |
|
2249 |
$sn1 = "/{$sn}"; |
|
2250 |
} |
|
2256 | 2251 |
|
2257 |
$natifname = $FilterIflist[$natif]['if'];
|
|
2258 |
if ((($srcaddr == 'any') || is_ipaddrv6($tmp[0])) &&
|
|
2259 |
($ipproto == 'inet6') &&
|
|
2260 |
(($FilterIflist[$natif]['type6'] == '6rd') ||
|
|
2261 |
($FilterIflist[$natif]['type6'] == '6to4'))) {
|
|
2262 |
$natif = strtolower($FilterIflist[$natif]['descr']) . "_stf";
|
|
2263 |
} else {
|
|
2264 |
$natif = $natifname;
|
|
2265 |
}
|
|
2252 |
$natifname = $FilterIflist[$natif]['if']; |
|
2253 |
if ((($srcaddr == 'any') || is_ipaddrv6($tmp[0])) && |
|
2254 |
($ipproto == 'inet6') && |
|
2255 |
(($FilterIflist[$natif]['type6'] == '6rd') || |
|
2256 |
($FilterIflist[$natif]['type6'] == '6to4'))) { |
|
2257 |
$natif = strtolower($FilterIflist[$natif]['descr']) . "_stf"; |
|
2258 |
} else { |
|
2259 |
$natif = $natifname; |
|
2260 |
} |
|
2266 | 2261 |
|
2267 |
$nat_if_list = array(); |
|
2268 |
if (isset($rule['nobinat'])) { |
|
2269 |
$natrules .= "no binat on {$natif} {$ipproto} from {$srcaddr} to {$dstaddr}\n"; |
|
2270 |
} else { |
|
2271 |
/* |
|
2272 |
* If reflection is enabled, turn on extra redirections |
|
2273 |
* for this rule by adding other interfaces to an rdr rule. |
|
2274 |
*/ |
|
2275 |
if ((isset($config['system']['enablebinatreflection']) || $rule['natreflection'] == "enable") && |
|
2276 |
($rule['natreflection'] != "disable")) { |
|
2277 |
$nat_if_list = filter_get_reflection_interfaces($natifname); |
|
2278 |
} |
|
2262 |
$nat_if_list = array(); |
|
2263 |
if (isset($rule['nobinat'])) { |
|
2264 |
$natrules .= "no binat on {$natif} {$ipproto} from {$srcaddr} to {$dstaddr}\n"; |
|
2265 |
} else { |
|
2266 |
/* |
|
2267 |
* If reflection is enabled, turn on extra redirections |
|
2268 |
* for this rule by adding other interfaces to an rdr rule. |
|
2269 |
*/ |
|
2270 |
if ((config_path_enabled('system','enablebinatreflection') || |
|
2271 |
$rule['natreflection'] == "enable") && |
|
2272 |
($rule['natreflection'] != "disable")) { |
|
2273 |
$nat_if_list = filter_get_reflection_interfaces($natifname); |
|
2274 |
} |
|
2279 | 2275 |
|
2280 |
$natrules .= "binat on {$natif} {$ipproto} from {$srcaddr} to {$dstaddr} -> {$target}{$sn1}\n";
|
|
2276 |
$natrules .= "binat on {$natif} {$ipproto} from {$srcaddr} to {$dstaddr} -> {$target}{$sn1}\n"; |
|
2281 | 2277 |
|
2282 |
if (!empty($nat_if_list)) { |
|
2283 |
$binat_if_list = implode(" ", $nat_if_list); |
|
2284 |
$binat_if_list = "{ {$binat_if_list} }"; |
|
2285 |
$reflection_txt .= "rdr on {$binat_if_list} {$ipproto} from {$dstaddr} to {$target}{$sn1} -> {$srcaddr} bitmask\n"; |
|
2286 |
} |
|
2278 |
if (!empty($nat_if_list)) { |
|
2279 |
$binat_if_list = implode(" ", $nat_if_list); |
|
2280 |
$binat_if_list = "{ {$binat_if_list} }"; |
|
2281 |
$reflection_txt .= "rdr on {$binat_if_list} {$ipproto} from {$dstaddr} to {$target}{$sn1} -> {$srcaddr} bitmask\n"; |
|
2287 | 2282 |
} |
2288 |
|
|
2289 |
$nat_if_list = array_merge(array($natif), $nat_if_list); |
|
2290 |
$reflection_txt .= filter_generate_reflection_nat($rule, $route_table, $nat_if_list, "", $srcaddr, $srcip, $sn); |
|
2291 | 2283 |
} |
2284 |
|
|
2285 |
$nat_if_list = array_merge(array($natif), $nat_if_list); |
|
2286 |
$reflection_txt .= filter_generate_reflection_nat($rule, $route_table, $nat_if_list, "", $srcaddr, $srcip, $sn); |
|
2292 | 2287 |
} |
2293 | 2288 |
|
2294 | 2289 |
/* Add binat rules for Network Prefix translation */ |
2295 |
if (is_array($config['nat']['npt'])) { |
|
2296 |
foreach ($config['nat']['npt'] as $rule) { |
|
2297 |
if (isset($rule['disabled'])) { |
|
2298 |
continue; |
|
2299 |
} |
|
2300 |
$rule['ipprotocol'] = 'inet6'; |
|
2290 |
foreach (config_get_path('nat/npt', []) as $rule) { |
|
2291 |
if (isset($rule['disabled'])) { |
|
2292 |
continue; |
|
2293 |
} |
|
2294 |
$rule['ipprotocol'] = 'inet6'; |
|
2301 | 2295 |
|
2302 |
if (!$rule['interface']) {
|
|
2303 |
$natif = "wan";
|
|
2304 |
} else {
|
|
2305 |
$natif = $rule['interface'];
|
|
2306 |
}
|
|
2307 |
if (!isset($FilterIflist[$natif])) {
|
|
2308 |
continue;
|
|
2309 |
}
|
|
2296 |
if (!$rule['interface']) { |
|
2297 |
$natif = "wan"; |
|
2298 |
} else { |
|
2299 |
$natif = $rule['interface']; |
|
2300 |
} |
|
2301 |
if (!isset($FilterIflist[$natif])) { |
|
2302 |
continue; |
|
2303 |
} |
|
2310 | 2304 |
|
2311 |
$srcaddr = filter_generate_address($rule, 'source'); |
|
2312 |
if (isset($rule['destination']['network']) && !is_subnetv6($rule['destination']['network'])) { |
|
2313 |
$dst_arr = explode("/", $rule['destination']['network']); |
|
2314 |
if (count($dst_arr) > 1) { |
|
2315 |
$track6ip = get_interface_track6ip($dst_arr[0]); |
|
2316 |
$pdsubnet = gen_subnetv6($track6ip[0], $dst_arr[1]); |
|
2317 |
$rule['destination']['address'] = $pdsubnet . "/" . $dst_arr[1]; |
|
2318 |
unset($rule['destination']['network']); |
|
2319 |
} |
|
2305 |
$srcaddr = filter_generate_address($rule, 'source'); |
|
2306 |
if (isset($rule['destination']['network']) && !is_subnetv6($rule['destination']['network'])) { |
|
2307 |
$dst_arr = explode("/", $rule['destination']['network']); |
|
2308 |
if (count($dst_arr) > 1) { |
|
2309 |
$track6ip = get_interface_track6ip($dst_arr[0]); |
|
2310 |
$pdsubnet = gen_subnetv6($track6ip[0], $dst_arr[1]); |
|
2311 |
$rule['destination']['address'] = $pdsubnet . "/" . $dst_arr[1]; |
|
2312 |
unset($rule['destination']['network']); |
|
2320 | 2313 |
} |
2321 |
$dstaddr = filter_generate_address($rule, 'destination'); |
|
2314 |
} |
|
2315 |
$dstaddr = filter_generate_address($rule, 'destination'); |
|
2322 | 2316 |
|
2323 |
$srcaddr = trim($srcaddr);
|
|
2324 |
$dstaddr = trim($dstaddr);
|
|
2317 |
$srcaddr = trim($srcaddr); |
|
2318 |
$dstaddr = trim($dstaddr); |
|
2325 | 2319 |
|
2326 |
if (($FilterIflist[$natif]['type6'] == '6rd') || ($FilterIflist[$natif]['type6'] == '6to4')) {
|
|
2320 |
if (($FilterIflist[$natif]['type6'] == '6rd') || ($FilterIflist[$natif]['type6'] == '6to4')) { |
|
2327 | 2321 |
$natif = $FilterIflist[$natif]['descr'] . "_STF"; |
2328 |
} else { |
|
2329 |
$natif = $FilterIflist[$natif]['descr']; |
|
2330 |
} |
|
2331 |
|
|
2332 |
/* Do not form an invalid NPt rule. |
|
2333 |
* See https://redmine.pfsense.org/issues/8575 */ |
|
2334 |
if (!(is_subnetv6($srcaddr) || is_ipaddrv6($srcaddr)) || |
|
2335 |
!(is_subnetv6($dstaddr) || is_ipaddrv6($dstaddr))) { |
|
2336 |
continue; |
|
2337 |
} |
|
2338 |
|
|
2339 |
$natrules .= "binat on \${$natif} inet6 from {$srcaddr} to any -> {$dstaddr}\n"; |
|
2340 |
$natrules .= "binat on \${$natif} inet6 from any to {$dstaddr} -> {$srcaddr}\n"; |
|
2322 |
} else { |
|
2323 |
$natif = $FilterIflist[$natif]['descr']; |
|
2324 |
} |
|
2341 | 2325 |
|
2326 |
/* Do not form an invalid NPt rule. |
|
2327 |
* See https://redmine.pfsense.org/issues/8575 */ |
|
2328 |
if (!(is_subnetv6($srcaddr) || is_ipaddrv6($srcaddr)) || |
|
2329 |
!(is_subnetv6($dstaddr) || is_ipaddrv6($dstaddr))) { |
|
2330 |
continue; |
|
2342 | 2331 |
} |
2332 |
|
|
2333 |
$natrules .= "binat on \${$natif} inet6 from {$srcaddr} to any -> {$dstaddr}\n"; |
|
2334 |
$natrules .= "binat on \${$natif} inet6 from any to {$dstaddr} -> {$srcaddr}\n"; |
|
2343 | 2335 |
} |
2344 | 2336 |
|
2345 | 2337 |
/* ipsec nat */ |
... | ... | |
2347 | 2339 |
require_once("ipsec.inc"); |
2348 | 2340 |
} |
2349 | 2341 |
if (ipsec_enabled()) { |
2350 |
if (is_array($config['ipsec']['phase2'])) { |
|
2351 |
foreach ($config['ipsec']['phase2'] as $ph2ent) { |
|
2352 |
if ($ph2ent['mode'] != 'transport' && !empty($ph2ent['natlocalid']) && !isset($ph2ent['disabled'])) { |
|
2353 |
if (!ipsec_lookup_phase1($ph2ent, $ph1ent)) { |
|
2354 |
continue; |
|
2355 |
} |
|
2356 |
if (isset($ph1ent['disabled'])) { |
|
2357 |
continue; |
|
2358 |
} |
|
2359 |
if (!is_array($ph2ent['localid'])) { |
|
2360 |
$ph2ent['localid'] = array(); |
|
2361 |
} |
|
2362 |
$ph2ent['localid']['mode'] = $ph2ent['mode']; |
|
2363 |
$local_subnet = ipsec_idinfo_to_cidr($ph2ent['localid']); |
|
2364 |
if (empty($local_subnet) || $local_subnet == "0.0.0.0/0") { |
|
2365 |
continue; |
|
2366 |
} |
|
2367 |
if (!is_subnet($local_subnet) && !is_ipaddr($local_subnet)) { |
|
2368 |
continue; |
|
2369 |
} |
|
2370 |
if (!is_array($ph2ent['natlocalid'])) { |
|
2371 |
$ph2ent['natlocalid'] = array(); |
|
2372 |
} |
|
2373 |
$ph2ent['natlocalid']['mode'] = $ph2ent['mode']; |
|
2374 |
$natlocal_subnet = ipsec_idinfo_to_cidr($ph2ent['natlocalid']); |
|
2375 |
if (empty($natlocal_subnet) || $natlocal_subnet == "0.0.0.0/0") { |
|
2376 |
continue; |
|
2377 |
} |
|
2378 |
if (!is_subnet($natlocal_subnet) && !is_ipaddr($natlocal_subnet)) { |
|
2379 |
continue; |
|
2380 |
} |
|
2381 |
if (!is_array($ph2ent['remoteid'])) { |
|
2382 |
$ph2ent['remoteid'] = array(); |
|
2383 |
} |
|
2384 |
$ph2ent['remoteid']['mode'] = $ph2ent['mode']; |
|
2385 |
if (!isset($ph2ent['mobile'])) { |
|
2386 |
$remote_subnet = ipsec_idinfo_to_cidr($ph2ent['remoteid']); |
|
2387 |
} elseif (!empty($ipsec_client['pool_address'])) { |
|
2388 |
$remote_subnet = "{$ipsec_client['pool_address']}/{$ipsec_client['pool_netbits']}"; |
|
2389 |
} |
|
2390 |
if (empty($remote_subnet)) { |
|
2391 |
continue; |
|
2392 |
} |
|
2393 |
if (!is_subnet($remote_subnet) && !is_ipaddr($remote_subnet)) { |
|
2394 |
continue; |
|
2395 |
} |
|
2396 |
if ($remote_subnet == "0.0.0.0/0") { |
|
2397 |
$remote_subnet = "any"; |
|
2398 |
} |
|
2399 |
if (is_ipaddr($natlocal_subnet) && !is_ipaddr($local_subnet)) { |
|
2342 |
foreach (config_get_path('ipsec/phase2', []) as $ph2ent) { |
|
2343 |
if ($ph2ent['mode'] != 'transport' && !empty($ph2ent['natlocalid']) && !isset($ph2ent['disabled'])) { |
|
2344 |
if (!ipsec_lookup_phase1($ph2ent, $ph1ent)) { |
|
2345 |
continue; |
|
2346 |
} |
|
2347 |
if (isset($ph1ent['disabled'])) { |
|
2348 |
continue; |
|
2349 |
} |
|
2350 |
if (!is_array($ph2ent['localid'])) { |
|
2351 |
$ph2ent['localid'] = array(); |
|
2352 |
} |
|
2353 |
$ph2ent['localid']['mode'] = $ph2ent['mode']; |
|
2354 |
$local_subnet = ipsec_idinfo_to_cidr($ph2ent['localid']); |
|
2355 |
if (empty($local_subnet) || $local_subnet == "0.0.0.0/0") { |
|
2356 |
continue; |
|
2357 |
} |
|
2358 |
if (!is_subnet($local_subnet) && !is_ipaddr($local_subnet)) { |
|
2359 |
continue; |
|
2360 |
} |
|
2361 |
if (!is_array($ph2ent['natlocalid'])) { |
|
2362 |
$ph2ent['natlocalid'] = array(); |
|
2363 |
} |
|
2364 |
$ph2ent['natlocalid']['mode'] = $ph2ent['mode']; |
|
2365 |
$natlocal_subnet = ipsec_idinfo_to_cidr($ph2ent['natlocalid']); |
|
2366 |
if (empty($natlocal_subnet) || $natlocal_subnet == "0.0.0.0/0") { |
|
2367 |
continue; |
|
2368 |
} |
|
2369 |
if (!is_subnet($natlocal_subnet) && !is_ipaddr($natlocal_subnet)) { |
|
2370 |
continue; |
|
2371 |
} |
|
2372 |
if (!is_array($ph2ent['remoteid'])) { |
|
2373 |
$ph2ent['remoteid'] = array(); |
|
2374 |
} |
|
2375 |
$ph2ent['remoteid']['mode'] = $ph2ent['mode']; |
|
2376 |
if (!isset($ph2ent['mobile'])) { |
|
2377 |
$remote_subnet = ipsec_idinfo_to_cidr($ph2ent['remoteid']); |
|
2378 |
} elseif (!empty($ipsec_client['pool_address'])) { |
|
2379 |
$remote_subnet = "{$ipsec_client['pool_address']}/{$ipsec_client['pool_netbits']}"; |
|
2380 |
} |
|
2381 |
if (empty($remote_subnet)) { |
|
2382 |
continue; |
|
2383 |
} |
|
2384 |
if (!is_subnet($remote_subnet) && !is_ipaddr($remote_subnet)) { |
|
2385 |
continue; |
|
2386 |
} |
|
2387 |
if ($remote_subnet == "0.0.0.0/0") { |
|
2388 |
$remote_subnet = "any"; |
|
2389 |
} |
|
2390 |
if (is_ipaddr($natlocal_subnet) && !is_ipaddr($local_subnet)) { |
|
2391 |
$nattype = "nat"; |
|
2392 |
} else { |
|
2393 |
list($natnet, $natmask) = explode('/', $natlocal_subnet); |
|
2394 |
list($locnet, $locmask) = explode('/', $local_subnet); |
|
2395 |
if (intval($natmask) != intval($locmask)) { |
|
2400 | 2396 |
$nattype = "nat"; |
2401 | 2397 |
} else { |
2402 |
list($natnet, $natmask) = explode('/', $natlocal_subnet); |
|
2403 |
list($locnet, $locmask) = explode('/', $local_subnet); |
|
2404 |
if (intval($natmask) != intval($locmask)) { |
|
2405 |
$nattype = "nat"; |
|
2406 |
} else { |
|
2407 |
$nattype = "binat"; |
|
2408 |
} |
|
2409 |
unset($natnet, $natmask, $locnet, $locmask); |
|
2398 |
$nattype = "binat"; |
|
2410 | 2399 |
} |
2411 |
$natrules .= "{$nattype} on enc0 from {$local_subnet} to {$remote_subnet} -> {$natlocal_subnet}\n";
|
|
2400 |
unset($natnet, $natmask, $locnet, $locmask);
|
|
2412 | 2401 |
} |
2402 |
$natrules .= "{$nattype} on enc0 from {$local_subnet} to {$remote_subnet} -> {$natlocal_subnet}\n"; |
|
2413 | 2403 |
} |
2414 | 2404 |
} |
2415 | 2405 |
} |
2416 | 2406 |
|
2417 |
if ($config['nat']['outbound']['mode'] == "disabled") { |
|
2407 |
$natomode = config_get_path('nat/outbound/mode'); |
|
2408 |
switch ($natomode) { |
|
2409 |
case "disabled": |
|
2418 | 2410 |
$natrules .= "\n# Outbound NAT rules are disabled\n"; |
2419 |
}
|
|
2420 |
|
|
2421 |
if ($config['nat']['outbound']['mode'] == "advanced" || $config['nat']['outbound']['mode'] == "hybrid") {
|
|
2411 |
break;
|
|
2412 |
case "advanced": /* fallthrough */ |
|
2413 |
case "hybrid":
|
|
2422 | 2414 |
$natrules .= "\n# Outbound NAT rules (manual)\n"; |
2423 | 2415 |
/* advanced outbound rules */ |
2424 |
if (is_array($config['nat']['outbound']['rule'])) { |
|
2425 |
foreach ($config['nat']['outbound']['rule'] as $obent) { |
|
2426 |
if (isset($obent['disabled'])) { |
|
2427 |
continue; |
|
2428 |
} |
|
2429 |
update_filter_reload_status(sprintf(gettext("Creating advanced outbound rule %s"), $obent['descr'])); |
|
2430 |
$src = alias_expand($obent['source']['network']); |
|
2431 |
if (!$src) { |
|
2432 |
$src = $obent['source']['network']; |
|
2433 |
} |
|
2434 |
$dst = alias_expand($obent['destination']['address']); |
|
2435 |
if (!$dst) { |
|
2436 |
$dst = $obent['destination']['address']; |
|
2437 |
} |
|
2438 |
if (isset($obent['destination']['not']) && !isset($obent['destination']['any'])) { |
|
2439 |
$dst = "!" . $dst; |
|
2440 |
} |
|
2441 |
|
|
2442 |
if (!$obent['interface'] || !isset($FilterIflist[$obent['interface']])) { |
|
2443 |
continue; |
|
2444 |
} |
|
2445 |
|
|
2446 |
$obtarget = ($obent['target'] == "other-subnet") ? $obent['targetip'] . '/' . $obent['targetip_subnet']: $obent['target']; |
|
2447 |
$poolopts = (is_subnet($obtarget) || is_alias($obtarget)) ? $obent['poolopts'] : ""; |
|
2416 |
foreach (config_get_path('nat/outbound/rule') as $obent) { |
|
2417 |
if (isset($obent['disabled'])) { |
|
2418 |
continue; |
|
2419 |
} |
|
2420 |
update_filter_reload_status(sprintf(gettext("Creating advanced outbound rule %s"), $obent['descr'])); |
|
2421 |
$src = alias_expand($obent['source']['network']); |
|
2422 |
if (!$src) { |
|
2423 |
$src = $obent['source']['network']; |
|
2424 |
} |
|
2425 |
$dst = alias_expand($obent['destination']['address']); |
|
2426 |
if (!$dst) { |
|
2427 |
$dst = $obent['destination']['address']; |
|
2428 |
} |
|
2429 |
if (isset($obent['destination']['not']) && !isset($obent['destination']['any'])) { |
|
2430 |
$dst = "!" . $dst; |
|
2431 |
} |
|
2448 | 2432 |
|
2449 |
/* pool option source-hash allows specification of an optional source-hash key */ |
|
2450 |
if ($poolopts == "source-hash" && !empty($obent['source_hash_key'])) { |
|
2451 |
$poolopts = "source-hash ".$obent['source_hash_key']; |
|
2452 |
} |
|
2433 |
if (!$obent['interface'] || !isset($FilterIflist[$obent['interface']])) { |
|
2434 |
continue; |
|
2435 |
} |
|
2453 | 2436 |
|
2454 |
$natrules .= filter_nat_rules_generate_if($obent['interface'], |
|
2455 |
$obent['descr'], |
|
2456 |
$obent['ipprotocol'], |
|
2457 |
$src, |
|
2458 |
$obent['sourceport'], |
|
2459 |
$dst, |
|
2460 |
$obent['dstport'], |
|
2461 |
$obtarget, |
|
2462 |
$obent['natport'], |
|
2463 |
isset($obent['nonat']), |
|
2464 |
isset($obent['staticnatport']), |
|
2465 |
$obent['protocol'], |
|
2466 |
$poolopts |
|
2437 |
$obtarget = ($obent['target'] == "other-subnet") ? $obent['targetip'] . '/' . $obent['targetip_subnet']: $obent['target']; |
|
2438 |
$poolopts = (is_subnet($obtarget) || is_alias($obtarget)) ? $obent['poolopts'] : ""; |
|
2439 |
|
|
2440 |
/* pool option source-hash allows specification of an optional source-hash key */ |
|
2441 |
if ($poolopts == "source-hash" && !empty($obent['source_hash_key'])) { |
|
2442 |
$poolopts = "source-hash ".$obent['source_hash_key']; |
|
2443 |
} |
|
2444 |
|
|
2445 |
$natrules .= filter_nat_rules_generate_if( |
|
2446 |
$obent['interface'], |
|
2447 |
$obent['descr'], |
|
2448 |
$obent['ipprotocol'], |
|
2449 |
$src, |
|
2450 |
$obent['sourceport'], |
|
2451 |
$dst, |
|
2452 |
$obent['dstport'], |
|
2453 |
$obtarget, |
|
2454 |
$obent['natport'], |
|
2455 |
isset($obent['nonat']), |
|
2456 |
isset($obent['staticnatport']), |
|
2457 |
$obent['protocol'], |
|
2458 |
$poolopts |
|
2467 | 2459 |
); |
2468 |
} |
|
2469 | 2460 |
} |
2461 |
break; |
|
2462 |
default: |
|
2463 |
;//noop |
|
2470 | 2464 |
} |
2471 | 2465 |
|
2472 | 2466 |
/* outbound rules */ |
2473 |
if ((!isset($config['nat']['outbound']['mode'])) ||
|
|
2474 |
($config['nat']['outbound']['mode'] == "automatic") ||
|
|
2475 |
($config['nat']['outbound']['mode'] == "hybrid")) {
|
|
2467 |
if ((!isset($natomode)) ||
|
|
2468 |
($natomode == "automatic") ||
|
|
2469 |
($natomode == "hybrid")) {
|
|
2476 | 2470 |
$natrules .= "\n# Outbound NAT rules (automatic)\n"; |
2477 | 2471 |
/* standard outbound rules (one for each interface) */ |
2478 | 2472 |
update_filter_reload_status(gettext("Creating outbound NAT rules")); |
... | ... | |
2514 | 2508 |
$natrules .= "# TFTP proxy\n"; |
2515 | 2509 |
$natrules .= "rdr-anchor \"tftp-proxy/*\"\n"; |
2516 | 2510 |
|
2517 |
if (!empty($config['system']['tftpinterface'])) { |
|
2518 |
$tftpifs = explode(",", $config['system']['tftpinterface']); |
|
2511 |
$tftpinterface = config_get_path('system/tftpinterface'); |
|
2512 |
if (!empty($tftpinterface)) { |
|
2513 |
$tftpifs = explode(",", $tftpinterface); |
|
2519 | 2514 |
foreach ($tftpifs as $tftpif) { |
2520 | 2515 |
if ($FilterIflist[$tftpif]) { |
2521 | 2516 |
$natrules .= "rdr pass on {$FilterIflist[$tftpif]['if']} proto udp from any to any port tftp -> 127.0.0.1 port 6969\n"; |
... | ... | |
2527 | 2522 |
$natrules .= filter_captiveportal_rdr(); |
2528 | 2523 |
|
2529 | 2524 |
/* DIAG: add ipv6 NAT, if requested */ |
2530 |
if ((isset($config['diag']['ipv6nat']['enable'])) && |
|
2531 |
(is_ipaddr($config['diag']['ipv6nat']['ipaddr'])) && |
|
2525 |
$ipv6nataddr = config_get_path('diag/ipv6nat/ipaddr'); |
|
2526 |
if (config_path_enabled('diag/ipv6nat') && |
|
2527 |
(is_ipaddr($ipv6nataddr)) && |
|
2532 | 2528 |
(is_array($FilterIflist['wan']))) { |
2533 | 2529 |
/* XXX: FIX ME! IPV6 */ |
2534 |
$natrules .= "rdr on \${$FilterIflist['wan']['descr']} proto ipv6 from any to any -> {$config['diag']['ipv6nat']['ipaddr']}\n";
|
|
2530 |
$natrules .= "rdr on \${$FilterIflist['wan']['descr']} proto ipv6 from any to any -> {$pv6nataddr}\n";
|
|
2535 | 2531 |
} |
2536 | 2532 |
|
2537 | 2533 |
unlink_if_exists("{$g['varetc_path']}/xinetd.conf"); |
2538 | 2534 |
// Open xinetd.conf write handle |
2539 | 2535 |
$xinetd_fd = fopen("{$g['varetc_path']}/xinetd.conf", "w"); |
2540 | 2536 |
|
2541 |
if (!empty($config['system']['tftpinterface'])) {
|
|
2537 |
if (!empty(config_get_path('system/tftpinterface'))) {
|
|
2542 | 2538 |
/* add tftp helper */ |
2543 | 2539 |
$ftp_proxy_entry = array( |
2544 | 2540 |
'port' => 6969, |
... | ... | |
2552 | 2548 |
fwrite($xinetd_fd, xinetd_service_entry($ftp_proxy_entry)); |
2553 | 2549 |
} |
2554 | 2550 |
|
2555 |
if (isset($config['nat']['rule'])) { |
|
2556 |
/* start reflection redirects on port 19000 of localhost */ |
|
2557 |
$starting_localhost_port = 19000; |
|
2558 |
$natrules .= "# NAT Inbound Redirects\n"; |
|
2559 |
$nonatrule = array(); |
|
2560 |
foreach ($config['nat']['rule'] as $rule) { |
|
2561 |
update_filter_reload_status(sprintf(gettext("Creating NAT rule %s"), $rule['descr'])); |
|
2551 |
/* start reflection redirects on port 19000 of localhost */ |
|
2552 |
$starting_localhost_port = 19000; |
|
2553 |
$natrules .= "# NAT Inbound Redirects\n"; |
|
2554 |
$nonatrule = array(); |
|
2555 |
foreach (config_get_path('nat/rule', []) as $rule) { |
|
2556 |
update_filter_reload_status(sprintf(gettext("Creating NAT rule %s"), $rule['descr'])); |
|
2562 | 2557 |
|
2563 |
if (isset($rule['disabled'])) {
|
|
2564 |
continue;
|
|
2565 |
}
|
|
2558 |
if (isset($rule['disabled'])) { |
|
2559 |
continue; |
|
2560 |
} |
|
2566 | 2561 |
|
2567 |
/* if item is an alias, expand */
|
|
2568 |
$dstport = array();
|
|
2569 |
$dstport[0] = alias_expand($rule['destination']['port']);
|
|
2570 |
if (!$dstport[0]) {
|
|
2571 |
$dstport = explode("-", $rule['destination']['port']);
|
|
2562 |
/* if item is an alias, expand */ |
|
2563 |
$dstport = array(); |
|
2564 |
$dstport[0] = alias_expand($rule['destination']['port']); |
|
2565 |
if (!$dstport[0]) { |
|
2566 |
$dstport = explode("-", $rule['destination']['port']); |
|
2572 | 2567 |
} |
2573 | 2568 |
|
2574 |
/* if item is an alias, expand */ |
|
2575 |
$localport = alias_expand($rule['local-port']); |
|
2576 |
if (!$localport || $dstport[0] == $localport) { |
|
2577 |
$localport = ""; |
|
2578 |
} else if (is_alias($rule['local-port'])) { |
|
2579 |
$localport = filter_expand_alias($rule['local-port']); |
|
2580 |
if ($localport) { |
|
2581 |
$localport = explode(" ", trim($localport)); |
|
2582 |
$localport = $localport[0]; |
|
2583 |
$localport = " port {$localport}"; |
|
2584 |
} |
|
2585 |
} else if (is_alias($rule['destination']['port'])) { |
|
2569 |
/* if item is an alias, expand */ |
|
2570 |
$localport = alias_expand($rule['local-port']); |
|
2571 |
if (!$localport || $dstport[0] == $localport) { |
|
2572 |
$localport = ""; |
|
2573 |
} else if (is_alias($rule['local-port'])) { |
|
2574 |
$localport = filter_expand_alias($rule['local-port']); |
|
2575 |
if ($localport) { |
|
2576 |
$localport = explode(" ", trim($localport)); |
|
2577 |
$localport = $localport[0]; |
|
2586 | 2578 |
$localport = " port {$localport}"; |
2587 |
} else { |
|
2588 |
if (($dstport[1]) && ($dstport[0] != $dstport[1])) { |
|
2589 |
$localendport = $localport + ($dstport[1] - $dstport[0]); |
|
2579 |
} |
|
2580 |
} else if (is_alias($rule['destination']['port'])) { |
|
2581 |
$localport = " port {$localport}"; |
|
2582 |
} else { |
|
2583 |
if (($dstport[1]) && ($dstport[0] != $dstport[1])) { |
|
2584 |
$localendport = $localport + ($dstport[1] - $dstport[0]); |
|
2585 |
|
|
2586 |
$localport .= ":$localendport"; |
|
2587 |
} |
|
2590 | 2588 |
|
2591 |
$localport .= ":$localendport";
|
|
2592 |
}
|
|
2589 |
$localport = " port {$localport}";
|
|
2590 |
} |
|
2593 | 2591 |
|
2594 |
$localport = " port {$localport}"; |
|
2595 |
} |
|
2592 |
if ($rule['ipprotocol'] == 'inet6') { |
|
2593 |
$ipproto = 'inet6'; |
|
2594 |
} else { |
|
2595 |
$ipproto = 'inet'; |
|
2596 |
} |
|
2596 | 2597 |
|
2597 |
if ($rule['ipprotocol'] == 'inet6') { |
|
2598 |
$ipproto = 'inet6'; |
|
2599 |
} else { |
|
2600 |
$ipproto = 'inet'; |
|
2601 |
} |
|
2598 |
switch (strtolower($rule['protocol'])) { |
|
2599 |
case "tcp/udp": |
|
2600 |
$protocol = "{ tcp udp }"; |
|
2601 |
break; |
|
2602 |
case "tcp": |
|
2603 |
case "udp": |
|
2604 |
$protocol = strtolower($rule['protocol']); |
|
2605 |
break; |
|
2606 |
default: |
|
2607 |
$protocol = strtolower($rule['protocol']); |
|
2608 |
$localport = ""; |
|
2609 |
break; |
|
2610 |
} |
|
2602 | 2611 |
|
2603 |
switch (strtolower($rule['protocol'])) { |
|
2604 |
case "tcp/udp": |
|
2605 |
$protocol = "{ tcp udp }"; |
|
2606 |
break; |
|
2607 |
case "tcp": |
|
2608 |
case "udp": |
|
2609 |
$protocol = strtolower($rule['protocol']); |
|
2610 |
break; |
|
2611 |
default: |
|
2612 |
$protocol = strtolower($rule['protocol']); |
|
2613 |
$localport = ""; |
|
2614 |
break; |
|
2615 |
} |
|
2612 |
if (is_ipaddr($rule['target'])) { |
|
2613 |
$target = $rule['target']; |
|
2614 |
} elseif (is_alias($rule['target'])) { |
|
2615 |
$target = alias_expand($rule['target']); |
|
2616 |
} else { |
|
2617 |
$tmprule = array(); |
|
2618 |
$tmprule['localip']['network'] = $rule['target']; |
|
2619 |
$tmprule['ipprotocol'] = $ipproto; |
|
2620 |
$target = filter_generate_address($tmprule, 'localip'); |
|
2621 |
} |
|
2622 |
if (!$target && !isset($rule['nordr'])) { |
|
2623 |
$natrules .= "# Unresolvable alias {$rule['target']}\n"; |
|
2624 |
continue; /* unresolvable alias */ |
|
2625 |
} |
|
2616 | 2626 |
|
2617 |
if (is_ipaddr($rule['target'])) { |
|
2618 |
$target = $rule['target']; |
|
2619 |
} elseif (is_alias($rule['target'])) { |
|
2620 |
$target = alias_expand($rule['target']); |
|
2621 |
} else { |
|
2622 |
$tmprule = array(); |
|
2623 |
$tmprule['localip']['network'] = $rule['target']; |
|
2624 |
$tmprule['ipprotocol'] = $ipproto; |
|
2625 |
$target = filter_generate_address($tmprule, 'localip'); |
|
2626 |
} |
|
2627 |
if (!$target && !isset($rule['nordr'])) { |
|
2628 |
$natrules .= "# Unresolvable alias {$rule['target']}\n"; |
|
2629 |
continue; /* unresolvable alias */ |
|
2630 |
} |
|
2631 |
|
|
2632 |
if (is_alias($rule['target'])) { |
|
2633 |
$target_ip = filter_expand_alias($rule['target']); |
|
2634 |
} else if (is_ipaddr($rule['target'])) { |
|
2635 |
$target_ip = $rule['target']; |
|
2636 |
} else if (is_ipaddr($FilterIflist[$rule['target']]['ip'])) { |
|
2637 |
$target_ip = $FilterIflist[$rule['target']]['ip']; |
|
2638 |
} else { |
|
2639 |
$target_ip = $rule['target']; |
|
2640 |
} |
|
2641 |
$target_ip = trim($target_ip); |
|
2627 |
if (is_alias($rule['target'])) { |
|
2628 |
$target_ip = filter_expand_alias($rule['target']); |
|
2629 |
} else if (is_ipaddr($rule['target'])) { |
|
2630 |
$target_ip = $rule['target']; |
|
2631 |
} else if (is_ipaddr($FilterIflist[$rule['target']]['ip'])) { |
|
2632 |
$target_ip = $FilterIflist[$rule['target']]['ip']; |
|
2633 |
} else { |
|
2634 |
$target_ip = $rule['target']; |
|
2635 |
} |
|
2636 |
$target_ip = trim($target_ip); |
|
2642 | 2637 |
|
2643 |
if ($rule['associated-rule-id'] == "pass") {
|
|
2644 |
$rdrpass = "pass ";
|
|
2645 |
} else {
|
|
2646 |
$rdrpass = "";
|
|
2647 |
}
|
|
2638 |
if ($rule['associated-rule-id'] == "pass") { |
|
2639 |
$rdrpass = "pass "; |
|
2640 |
} else { |
|
2641 |
$rdrpass = ""; |
|
2642 |
} |
|
2648 | 2643 |
|
2649 |
if (isset($rule['nordr'])) {
|
|
2650 |
$nordr = "no ";
|
|
2651 |
$rdrpass = "";
|
|
2652 |
} else {
|
|
2653 |
$nordr = "";
|
|
2654 |
}
|
|
2644 |
if (isset($rule['nordr'])) { |
|
2645 |
$nordr = "no "; |
|
2646 |
$rdrpass = ""; |
|
2647 |
} else { |
|
2648 |
$nordr = ""; |
|
2649 |
} |
|
2655 | 2650 |
|
2656 |
if (!$rule['interface']) {
|
|
2657 |
$natif = "wan";
|
|
2658 |
} else {
|
|
2659 |
$natif = $rule['interface'];
|
|
2660 |
}
|
|
2651 |
if (!$rule['interface']) { |
|
2652 |
$natif = "wan"; |
|
2653 |
} else { |
|
2654 |
$natif = $rule['interface']; |
|
2655 |
} |
|
2661 | 2656 |
|
2662 |
if (!isset($FilterIflist[$natif])) {
|
|
2663 |
continue;
|
|
2664 |
}
|
|
2657 |
if (!isset($FilterIflist[$natif])) { |
|
2658 |
continue; |
|
2659 |
} |
|
2665 | 2660 |
|
2666 |
if (($ipproto == 'inet6') && is_stf_interface($natif)) { |
|
2667 |
$rdrif = $natif . "_stf"; |
|
2668 |
} elseif ($natif == 'pppoe') { |
|
2669 |
$rdrif = 'pppoe'; |
|
2661 |
if (($ipproto == 'inet6') && is_stf_interface($natif)) { |
|
2662 |
$rdrif = $natif . "_stf"; |
|
2663 |
} elseif ($natif == 'pppoe') { |
|
2664 |
$rdrif = 'pppoe'; |
|
2665 |
} else { |
|
2666 |
$rdrif = $FilterIflist[$natif]['if']; |
|
2667 |
} |
|
2668 |
|
|
2669 |
$srcaddr = filter_generate_address($rule, 'source', true); |
|
2670 |
$dstaddr = filter_generate_address($rule, 'destination', true); |
|
2671 |
$srcaddr = trim($srcaddr); |
|
2672 |
$dstaddr = trim($dstaddr); |
|
2673 |
|
|
2674 |
$dstaddr_port = explode(" ", $dstaddr); |
|
2675 |
if (empty($dstaddr_port[0]) || strtolower(trim($dstaddr_port[0])) == "port") { |
|
2676 |
continue; // Skip port forward if no destination address found |
|
2677 |
} |
|
2678 |
$dstaddr_reflect = $dstaddr; |
|
2679 |
$natref_disabled = config_path_enabled('system','disablenatreflection'); |
|
2680 |
if (isset($rule['destination']['any']) && |
|
2681 |
((!isset($rule['natreflection']) && !$natref_disabled) || |
|
2682 |
($rule['natreflection'] == "purenat") || ($rule['natreflection'] == "enable"))) { |
|
2683 |
/* With reflection enabled, destination of 'any' has side effects |
|
2684 |
* that most people would not expect, so change it on reflection rules. */ |
|
2685 |
|
|
2686 |
if (!empty($FilterIflist[$natif]['ip'])) { |
|
2687 |
$dstaddr_reflect = $FilterIflist[$natif]['ip']; |
|
2670 | 2688 |
} else { |
2671 |
$rdrif = $FilterIflist[$natif]['if']; |
|
2689 |
// no IP, bail |
|
2690 |
continue; |
|
2672 | 2691 |
} |
2673 | 2692 |
|
2674 |
$srcaddr = filter_generate_address($rule, 'source', true); |
|
2675 |
$dstaddr = filter_generate_address($rule, 'destination', true); |
|
2676 |
$srcaddr = trim($srcaddr); |
|
2677 |
$dstaddr = trim($dstaddr); |
|
2678 |
|
|
2679 |
$dstaddr_port = explode(" ", $dstaddr); |
|
2680 |
if (empty($dstaddr_port[0]) || strtolower(trim($dstaddr_port[0])) == "port") { |
|
2681 |
continue; // Skip port forward if no destination address found |
|
2693 |
if (!empty($FilterIflist[$natif]['sn'])) { |
|
2694 |
$dstaddr_reflect = gen_subnet($dstaddr_reflect, $FilterIflist[$natif]['sn']) . '/' . $FilterIflist[$natif]['sn']; |
|
2682 | 2695 |
} |
2683 |
$dstaddr_reflect = $dstaddr; |
|
2684 |
if (isset($rule['destination']['any']) && |
|
2685 |
((!isset($rule['natreflection']) && !isset($config['system']['disablenatreflection'])) || |
|
2686 |
($rule['natreflection'] == "purenat") || ($rule['natreflection'] == "enable"))) { |
|
2687 |
/* With reflection enabled, destination of 'any' has side effects |
|
2688 |
* that most people would not expect, so change it on reflection rules. */ |
|
2689 | 2696 |
|
2690 |
if (!empty($FilterIflist[$natif]['ip'])) { |
|
2691 |
$dstaddr_reflect = $FilterIflist[$natif]['ip']; |
|
2692 |
} else { |
|
2693 |
// no IP, bail |
|
2694 |
continue; |
|
2695 |
} |
|
2696 |
|
|
2697 |
if (!empty($FilterIflist[$natif]['sn'])) { |
|
2698 |
$dstaddr_reflect = gen_subnet($dstaddr_reflect, $FilterIflist[$natif]['sn']) . '/' . $FilterIflist[$natif]['sn']; |
|
2699 |
} |
|
2700 |
|
|
2701 |
if ($dstaddr_port[count($dstaddr_port)-1]) { |
|
2702 |
$dstaddr_reflect .= " port " . $dstaddr_port[count($dstaddr_port)-1]; |
|
2703 |
} |
|
2697 |
if ($dstaddr_port[count($dstaddr_port)-1]) { |
|
2698 |
$dstaddr_reflect .= " port " . $dstaddr_port[count($dstaddr_port)-1]; |
|
2704 | 2699 |
} |
2700 |
} |
|
2705 | 2701 |
|
2706 |
if ($natif != 'pppoe') {
|
|
2707 |
$natif = $FilterIflist[$natif]['if'];
|
|
2708 |
}
|
|
2702 |
if ($natif != 'pppoe') { |
|
2703 |
$natif = $FilterIflist[$natif]['if']; |
|
2704 |
} |
|
2709 | 2705 |
|
2710 |
$reflection_type = "none"; |
|
2711 |
if (($rule['natreflection'] != "disable") && ($dstaddr_port[0] != "0.0.0.0") && |
|
2712 |
($dstaddr_port[0] != "::")) { |
|
2713 |
if ($rule['natreflection'] == "enable") { |
|
2714 |
$reflection_type = "proxy"; |
|
2715 |
} else if ($rule['natreflection'] == "purenat") { |
|
2706 |
$reflection_type = "none"; |
|
2707 |
if (($rule['natreflection'] != "disable") && ($dstaddr_port[0] != "0.0.0.0") && |
|
2708 |
($dstaddr_port[0] != "::")) { |
|
2709 |
if ($rule['natreflection'] == "enable") { |
|
2710 |
$reflection_type = "proxy"; |
|
2711 |
} else if ($rule['natreflection'] == "purenat") { |
|
2712 |
$reflection_type = "purenat"; |
|
2713 |
} else if (!$natref_disabled) { |
|
2714 |
if (config_path_enabled('system','enablenatreflectionpurenat')) { |
|
2716 | 2715 |
$reflection_type = "purenat"; |
2717 |
} else if (!isset($config['system']['disablenatreflection'])) { |
|
2718 |
if (isset($config['system']['enablenatreflectionpurenat'])) { |
|
2719 |
$reflection_type = "purenat"; |
|
2720 |
} else { |
|
2721 |
$reflection_type = "proxy"; |
|
2722 |
} |
|
2716 |
} else { |
|
2717 |
$reflection_type = "proxy"; |
|
2723 | 2718 |
} |
2724 | 2719 |
} |
2720 |
} |
|
2725 | 2721 |
|
2726 |
if ($reflection_type != "none") {
|
|
2727 |
$nat_if_list = filter_get_reflection_interfaces($natif);
|
|
2728 |
} else {
|
|
2729 |
$nat_if_list = array();
|
|
2730 |
}
|
|
2722 |
if ($reflection_type != "none") { |
|
2723 |
$nat_if_list = filter_get_reflection_interfaces($natif); |
|
2724 |
} else { |
|
2725 |
$nat_if_list = array(); |
|
2726 |
} |
|
2731 | 2727 |
|
2732 |
if (empty($nat_if_list)) {
|
|
2733 |
$reflection_type = "none";
|
|
2734 |
}
|
|
2728 |
if (empty($nat_if_list)) { |
|
2729 |
$reflection_type = "none"; |
|
2730 |
} |
|
2735 | 2731 |
|
2736 |
$localport_nat = $localport;
|
|
2737 |
if (empty($localport_nat) && is_port($dstaddr_port[count($dstaddr_port)-1])) {
|
|
2738 |
$localport_nat = " port " . $dstaddr_port[count($dstaddr_port)-1];
|
|
2739 |
}
|
|
2732 |
$localport_nat = $localport; |
|
2733 |
if (empty($localport_nat) && is_port($dstaddr_port[count($dstaddr_port)-1])) { |
|
2734 |
$localport_nat = " port " . $dstaddr_port[count($dstaddr_port)-1]; |
|
2735 |
} |
|
2740 | 2736 |
|
2741 |
if ($srcaddr <> "" && $dstaddr <> "" && $natif) { |
|
2742 |
if ($protocol == 'any') { |
|
2743 |
$proto = ''; |
|
2737 |
if ($srcaddr <> "" && $dstaddr <> "" && $natif) { |
|
2738 |
if ($protocol == 'any') { |
|
2739 |
$proto = ''; |
|
2740 |
} else { |
|
2741 |
$proto = "proto {$protocol}"; |
|
2742 |
} |
|
2743 |
$natrules .= "{$nordr}rdr {$rdrpass}on {$rdrif} {$ipproto} {$proto} from {$srcaddr} to {$dstaddr}" . ($nordr == "" ? " -> {$target}{$localport}" : ""); |
|
2744 |
|
|
2745 |
/* Does this rule redirect back to a internal host? */ |
|
2746 |
if (isset($rule['destination']['any']) |
|
2747 |
&& !isset($rule['nordr']) |
|
2748 |
&& !config_path_enabled('system','enablenatreflectionhelper') |
|
2749 |
&& !interface_has_gateway($rule['interface'])) { |
|
2750 |
if ($ipproto == 'inet') { |
|
2751 |
$rule_interface_ip = find_interface_ip($natif); |
|
2752 |
$rule_interface_subnet = find_interface_subnet($natif); |
|
2744 | 2753 |
} else { |
2745 |
$proto = "proto {$protocol}"; |
|
2754 |
$rule_interface_ip = find_interface_ipv6($natif); |
|
2755 |
$rule_interface_subnet = find_interface_subnetv6($natif); |
|
2746 | 2756 |
} |
2747 |
$natrules .= "{$nordr}rdr {$rdrpass}on {$rdrif} {$ipproto} {$proto} from {$srcaddr} to {$dstaddr}" . ($nordr == "" ? " -> {$target}{$localport}" : ""); |
|
2748 |
|
|
2749 |
/* Does this rule redirect back to a internal host? */ |
|
2750 |
if (isset($rule['destination']['any']) && !isset($rule['nordr']) && !isset($config['system']['enablenatreflectionhelper']) && !interface_has_gateway($rule['interface'])) { |
|
2751 |
if ($ipproto == 'inet') { |
|
2752 |
$rule_interface_ip = find_interface_ip($natif); |
|
2753 |
$rule_interface_subnet = find_interface_subnet($natif); |
|
2754 |
} else { |
|
2755 |
$rule_interface_ip = find_interface_ipv6($natif); |
|
2756 |
$rule_interface_subnet = find_interface_subnetv6($natif); |
|
2757 |
} |
|
2758 |
if (!empty($rule_interface_ip) && !empty($rule_interface_subnet)) { |
|
2759 |
$rule_subnet = gen_subnet($rule_interface_ip, $rule_interface_subnet); |
|
2760 |
$nonatnet = $rule_subnet . '/' . $rule_interface_subnet; |
|
2761 |
$natrules .= "\n"; |
|
2762 |
/* Do not generate a rule with an interface source if that interface has no IP address. |
|
2763 |
* See https://redmine.pfsense.org/issues/8604 */ |
|
2764 |
if (((($ipproto == 'inet') && !empty(get_interface_ip($natif))) || |
|
2765 |
(($ipproto == 'inet6') && !empty(get_interface_ipv6($natif)))) && |
|
2766 |
(!$nonatrule[$natif])) { |
|
2767 |
$natrules .= "no nat on {$rdrif} {$ipproto} proto tcp from ({$natif}) to {$nonatnet}\n"; |
|
2768 |
$nonatrule[$natif] = true; |
|
2769 |
} |
|
2770 |
$natrules .= "nat on {$rdrif} {$ipproto} proto tcp from {$rule_subnet}/{$rule_interface_subnet} to {$target} port {$dstport[0]} -> ({$natif})\n"; |
|
2757 |
if (!empty($rule_interface_ip) && !empty($rule_interface_subnet)) { |
|
2758 |
$rule_subnet = gen_subnet($rule_interface_ip, $rule_interface_subnet); |
|
2759 |
$nonatnet = $rule_subnet . '/' . $rule_interface_subnet; |
|
2760 |
$natrules .= "\n"; |
|
2761 |
/* Do not generate a rule with an interface source if that interface has no IP address. |
|
2762 |
* See https://redmine.pfsense.org/issues/8604 */ |
|
2763 |
if (((($ipproto == 'inet') && !empty(get_interface_ip($natif))) || |
|
2764 |
(($ipproto == 'inet6') && !empty(get_interface_ipv6($natif)))) && |
|
2765 |
(!$nonatrule[$natif])) { |
|
2766 |
$natrules .= "no nat on {$rdrif} {$ipproto} proto tcp from ({$natif}) to {$nonatnet}\n"; |
|
2767 |
$nonatrule[$natif] = true; |
|
2771 | 2768 |
} |
2769 |
$natrules .= "nat on {$rdrif} {$ipproto} proto tcp from {$rule_subnet}/{$rule_interface_subnet} to {$target} port {$dstport[0]} -> ({$natif})\n"; |
|
2772 | 2770 |
} |
2771 |
} |
|
2773 | 2772 |
|
2774 |
if ($reflection_type != "none") { |
|
2775 |
if ($reflection_type == "proxy" && !isset($rule['nordr'])) { |
|
2776 |
$natrules .= filter_generate_reflection_proxy($rule, $nordr, $nat_if_list, $srcaddr, $dstaddr, $starting_localhost_port, $reflection_rules); |
|
2777 |
$nat_if_list = array($natif); |
|
2778 |
foreach ($reflection_rules as $reflection_rule) { |
|
2779 |
fwrite($xinetd_fd, xinetd_service_entry($reflection_rule)); |
|
2780 |
} |
|
2781 |
} else if ($reflection_type == "purenat" || isset($rule['nordr'])) { |
|
2782 |
$rdr_if_list = implode(" ", $nat_if_list); |
|
2783 |
if (count($nat_if_list) > 1) { |
|
2784 |
$rdr_if_list = "{ {$rdr_if_list} }"; |
|
2785 |
} |
|
2786 |
$natrules .= "\n# Reflection redirect\n"; |
|
2787 |
$natrules .= "{$nordr}rdr {$rdrpass}on {$rdr_if_list} {$ipproto} {$proto} from {$srcaddr} to {$dstaddr_reflect}" . ($nordr == "" ? " -> {$target}{$localport}" : ""); |
|
2788 |
$nat_if_list = array_merge(array($natif), $nat_if_list); |
|
2773 |
if ($reflection_type != "none") { |
|
2774 |
if ($reflection_type == "proxy" && !isset($rule['nordr'])) { |
|
2775 |
$natrules .= filter_generate_reflection_proxy($rule, $nordr, $nat_if_list, $srcaddr, $dstaddr, $starting_localhost_port, $reflection_rules); |
|
2776 |
$nat_if_list = array($natif); |
|
2777 |
foreach ($reflection_rules as $reflection_rule) { |
|
2778 |
fwrite($xinetd_fd, xinetd_service_entry($reflection_rule)); |
|
2779 |
} |
|
2780 |
} else if ($reflection_type == "purenat" || isset($rule['nordr'])) { |
|
2781 |
$rdr_if_list = implode(" ", $nat_if_list); |
|
2782 |
if (count($nat_if_list) > 1) { |
|
2783 |
$rdr_if_list = "{ {$rdr_if_list} }"; |
|
2789 | 2784 |
} |
2785 |
$natrules .= "\n# Reflection redirect\n"; |
|
2786 |
$natrules .= "{$nordr}rdr {$rdrpass}on {$rdr_if_list} {$ipproto} {$proto} from {$srcaddr} to {$dstaddr_reflect}" . ($nordr == "" ? " -> {$target}{$localport}" : ""); |
|
2787 |
$nat_if_list = array_merge(array($natif), $nat_if_list); |
|
2790 | 2788 |
} |
2789 |
} |
|
2791 | 2790 |
|
2792 |
if (empty($nat_if_list)) {
|
|
2793 |
$nat_if_list = array($natif);
|
|
2794 |
}
|
|
2791 |
if (empty($nat_if_list)) { |
|
2792 |
$nat_if_list = array($natif); |
|
2793 |
} |
|
2795 | 2794 |
|
2796 |
$natrules .= "\n"; |
|
2797 |
if (!isset($rule['nordr'])) { |
|
2798 |
$natrules .= filter_generate_reflection_nat($rule, $route_table, $nat_if_list, $protocol, "{$target}{$localport_nat}", $target_ip); |
|
2799 |
} |
|
2795 |
$natrules .= "\n"; |
|
2796 |
if (!isset($rule['nordr'])) { |
|
2797 |
$natrules .= filter_generate_reflection_nat($rule, $route_table, $nat_if_list, $protocol, "{$target}{$localport_nat}", $target_ip); |
|
2800 | 2798 |
} |
2801 | 2799 |
} |
2802 | 2800 |
} |
Also available in: Unified diff
Replace several direct config accesses in filter.inc
Major overhauls done in: * filter_generate_gateways(0 * filter_get_vpns_list() * filter_generate_optcfg_arry() * filter_generate_reflection_proxy() * filter_nat_rules_automatic_tonathosts() * filter_nat_rules_generate()