php script to add NAT rule is taking forever to apply
-
hi !
for a school project, i have a pfsense instance running on a proxmox server.
pfsense have a dedicated dual ethernet card with the wan connected to my network and the lan connected to the motherboard ethernet port used by proxmox.i need for this project to create new LXC in proxmox and add new NAT rules for these into pfsense.
i'me using ssh to connect into pfsense and then launch a php script to create the new NAT rules (ssh, http and https).
i can see in the webgui that the rules are added and in the " Status/Filter Reload" that the update is (i think) done.but when trying to ssh into the newly created LXC, i get an connection timed out because the NAT rule is not yet usable, i can wait up to 20 min for the LXC to be reachable.
i don't have this problem when creating a NAT rule with the webgui and i can ssh into the new LXC from another VM in the pfsense lan.
any help will be apreciated, thx !
here is the php script called with pfSsh.php playback:
require_once("config.inc"); require_once("functions.inc"); require_once("filter.inc"); global $argv, $command_split; $args = array_slice($argv, 2); // Assigning parameters $interface = $args[1]; $external_port = $args[2]; $internal_ip = $args[3]; $internal_port = $args[4]; $description = $args[5]; // Create the NAT rule array $natent = array(); $natent['interface'] = $interface; // WAN/LAN interface $natent['ipprotocol'] = 'inet'; $natent['protocol'] = 'tcp/udp'; // Protocol (TCP/UDP) $natent['target'] = $internal_ip; // Internal IP address $natent['local-port'] = $internal_port; // Internal port $natent['descr'] = $description; // Description for the rule $natent['natreflection'] = 'default'; // Enable NAT reflection if required $natent['associated-rule-id'] ='pass'; // Set pass rule (need the firewall to have a pass rule) $natent['disabled'] = false; // Enabled rule // Add source and destination $natent['source'] = array( 'any' => '' ); $natent['destination'] = array( 'network' => 'wanip', // Use the WAN IP for the destination 'port' => $external_port // Matches the external port provided as input ); // Add the rule to the NAT configuration $config['nat']['rule'][] = $natent; //print_r($config); // Save the configuration and apply the changes write_config("added new NAT rule for " . $description); mark_subsystem_dirty('nat'); filter_configure(); echo "Port forwarding rule added successfully.\n"; exit(0);
-
@arndel90 said in php script to add NAT rule is taking forever to apply:
i don't have this problem when creating a NAT rule with the webgui
Then why not creating a NAT rule, the one you want, using the GUI.
First, get a copy of the config.xml,
Go to the GUI, and add your NAT rule.
Then have look that the config again, and do a diff, check what changed.Now you have the exact content needed when you want to do the same thing using a script.
Are you sure about <natreflection> ?
And 'network' => 'wanip' but no firewall rule to let the traffic in ?I'm not sure if you can get away with it by not inserting things like :
<created> <time>1656698727</time> <username><![CDATA[admin@2001:470:ccea:3::1000 (Local Database)]]></username> </created> <updated> <time>1730826919</time> <username><![CDATA[admin@192.168.1.6 (Local Database)]]></username> </updated>
-
Hi !
thx for the answer.i'm creating a web portal to handle LXC that will be available for students so it must be done programmatically.
i've based the script from what i can see in the request send by the web page when creating a nat, the default natreflection was in the request
i haven't been able to find the options to create a related firewall rule that's why i use "pass" so i don't need any (if i understand it right) and the person in charge of the infrastructure was is good with it
for the xml config, here what i have with the nat created with the webgui :
<rule> <source> <any></any> </source> <destination> <network>wanip</network> <port>2200</port> </destination> <ipprotocol>inet</ipprotocol> <protocol>tcp/udp</protocol> <target>10.1.0.20</target> <local-port>22</local-port> <interface>wan</interface> <descr><![CDATA[NAt created with webgui]]></descr> <associated-rule-id>pass</associated-rule-id> <updated> <time>1735841291</time> <username><![CDATA[admin@192.168.1.153 (Local Database)]]></username> </updated> <created> <time>1735841291</time> <username><![CDATA[admin@192.168.1.153 (Local Database)]]></username> </created> </rule>
and what i have with the script :
<rule> <interface>wan</interface> <ipprotocol>inet</ipprotocol> <protocol>tcp/udp</protocol> <target>10.1.0.15</target> <local-port>22</local-port> <descr><![CDATA[NAT created with php script]]></descr> <natreflection>default</natreflection> <associated-rule-id>pass</associated-rule-id> <source> <any></any> </source> <destination> <network>wanip</network> <port>2000</port> </destination> </rule>
so i don't have the <created> and <updated> tags.
are they that important for the nat to be apply ? (not a pfsense expert here :p )if they really are needed, how can i give the proper time and username in the php script ?
-
Update :
Ok, just tried in System>Advances>Miscellaneous>PHP Setting and set "Memory Limit" to the max i could so 5569 and reboot the physical computer.
And now it works 8/10 times...don't understand what the php memory have to do with the rules application ?
is it because i call "filter_configure()" in a script with the "pfSsh.php playback" ? -
@arndel90 said in php script to add NAT rule is taking forever to apply:
don't understand what the php memory have to do with the rules application ?
is it because i call "filter_configure()" in a script with the "pfSsh.php playback" ?Because your script is 'eventuated' as a PHP as it is PHP, so the PHP interpreter is used.
PHP is pretty huge, and uses it own fixed size memory pool, as you've seen and won't fall back using all available system memory.@arndel90 said in php script to add NAT rule is taking forever to apply:
i haven't been able to find the options to create a related firewall rule that's why i use "pass" so i don't need any
I'm using 3 NAT rules myself, and every NAT rules has an associated firewall rule with it.
Create one manually yourself, and then come back to edit it, go down and you'll see it here :The auto generated firewall rule has several options grayed out, as you should not edit it directly, but edit the NAT rule itself.
The rules is indicated with a reminder :What I try to explain : a NAT rules, normally, needs an associated firewall rule.
A NAT (PAT actually) rule is an "address and port" translation instruction for the router, like :
Traffic coming into interface X using port Y with protocol Z, send it to interface A, using protocol Y (doesn't change) to port C (can be Z also, or something else, hence the PAT where the P stands for Port translation).
But, for traffic to enter an interface, like the WAN, you need a firewall rule to so traffic, using our example , X, Y and Z, can actually reach the firewall / router. Only when it has enetred, the NAT rule itself will apply. -
@Gertjan thx for the explanation.
As the problem seems to be related to the php interpreter memory pool and the computer i'm testing on (2sockets - 2 cores of a i7-6700 with 6G of ram) seems pretty weak for the use case i'm trying to to implement.
I'm gonna try to see if a can do some test on the server the app will be deploy on.For the firewall related rule, i meant an option in the php script as the goal is to aumotate all the LXC handling process.
It works in "pass" mode but i guess it would be better with a firewall rule ?I will give a feedback after some tesing (if they let me play with the big toys :p )