aboutsummaryrefslogtreecommitdiffstats
path: root/config
diff options
context:
space:
mode:
authorjim-p <jimp@pfsense.org>2015-03-04 15:35:54 -0500
committerjim-p <jimp@pfsense.org>2015-03-04 15:35:54 -0500
commita868b2522ef865f117c892a07ae3507686783ff3 (patch)
tree0ea5b975882bec7763184b68a10b737d1a399cd2 /config
parente7aca8a470e3ea13e018c99f7db4351c4119f082 (diff)
downloadpfsense-packages-a868b2522ef865f117c892a07ae3507686783ff3.tar.gz
pfsense-packages-a868b2522ef865f117c892a07ae3507686783ff3.tar.bz2
pfsense-packages-a868b2522ef865f117c892a07ae3507686783ff3.zip
Add a basic FTP Client Proxy using ftp-proxy(8) from FreeBSD
Diffstat (limited to 'config')
-rw-r--r--config/ftpproxy/ftpproxy.inc137
-rw-r--r--config/ftpproxy/ftpproxy.xml111
2 files changed, 248 insertions, 0 deletions
diff --git a/config/ftpproxy/ftpproxy.inc b/config/ftpproxy/ftpproxy.inc
new file mode 100644
index 00000000..7f65e646
--- /dev/null
+++ b/config/ftpproxy/ftpproxy.inc
@@ -0,0 +1,137 @@
+<?php
+function sync_package_ftpproxy() {
+ conf_mount_rw();
+ config_lock();
+ global $config;
+ $cf = $config['installedpackages']['ftpclientproxy']['config'][0];
+
+ /* Proxy is not enabled, kill the daemon and issue a filter reload. */
+ if ($cf["proxy_enable"] != "on") {
+ mwexec("/usr/bin/killall -9 ftp-proxy");
+ filter_configure();
+ return;
+ }
+ $interface_list = explode(",", $cf['localints']);
+ /* Bail if there is nothing to do */
+ if (empty($interface_list)) {
+ log_error("FTP Proxy cannot sync: No interfaces selected.");
+ return;
+ }
+
+ $start = "/usr/bin/killall -9 ftp-proxy\n";
+ $start .= "\t/usr/sbin/ftp-proxy ";
+
+ if ($cf["ipv6_enable"] == "on") {
+ $start .= " -6 ";
+ }
+ if ($cf["anononly"] == "on") {
+ $start .= " -A ";
+ }
+ if (is_ipaddr($cf["sourceaddr"])) {
+ $start .= " -a " . escapeshellarg($cf["sourceaddr"]);
+ }
+ if (is_port($cf["bindport"])) {
+ $start .= " -p " . escapeshellarg($cf["bindport"]);
+ }
+ if (is_numeric($cf["maxessions"]) && ($cf["maxessions"] >= 1) && ($cf["maxessions"] <= 500)) {
+ $start .= " -m " . escapeshellarg($cf["maxessions"]);
+ }
+ if (!empty($cf["tsq"])) {
+ $start .= " -q " . escapeshellarg($cf["tsq"]);
+ }
+ if ($cf["src20"] == "on") {
+ $start .= " -r ";
+ }
+ if (is_numeric($cf["idletimeout"]) && ($cf["idletimeout"] > 0) && ($cf["idletimeout"] <= 86400)) {
+ $start .= " -t " . escapeshellarg($cf["idletimeout"]);
+ }
+ if ($cf["log"] == "on") {
+ $start .= " -v ";
+ }
+ $start .= "\n";
+
+ write_rcfile(array(
+ "file" => "ftp-proxy.sh",
+ "start" => $start,
+ "stop" => "/usr/bin/killall -9 ftp-proxy"
+ )
+ );
+ restart_service("ftp-proxy");
+ conf_mount_ro();
+ config_unlock();
+ filter_configure();
+}
+
+function validate_form_ftpproxy($post, &$input_errors) {
+ if (empty($post["localints"])) {
+ $input_errors[] = 'One or more Local Interfaces must be selected';
+ }
+ if (!empty($post["sourceaddr"]) && !is_ipaddr($post["sourceaddr"])) {
+ $input_errors[] = 'You must specify a valid ip address in the \'Source Address\' field';
+ }
+ if (!empty($post["bindport"]) && !is_port($post["bindport"])) {
+ $input_errors[] = 'You must specify a valid port number in the \'Bind Port\' field';
+ }
+ if (!empty($post["maxessions"]) && (!is_numeric($post["maxessions"]) || ($post["maxessions"] < 1) || ($post["maxessions"] > 500))) {
+ $input_errors[] = 'You must specify a valid number in the \'Max Sessions\' field (Between 1 and 500)';
+ }
+ if (!empty($post["idletimeout"]) && (is_numeric($post["idletimeout"]) || ($post["idletimeout"] <= 0) || ($post["idletimeout"] > 86400))) {
+ $input_errors[] = 'You must specify a valid number in the \'Idle Timeout\' field (Between 1 and 86400)';
+ }
+}
+
+function ftpproxy_get_port() {
+ global $config;
+ $cf = $config['installedpackages']['ftpclientproxy']['config'][0];
+ if (!empty($cf["bindport"]) && is_port($cf["bindport"])) {
+ return $cf["bindport"];
+ } else {
+ return 8021;
+ }
+}
+
+function ftpproxy_generate_rules($type) {
+ global $config;
+ $cf = $config['installedpackages']['ftpclientproxy']['config'][0];
+ $interface_list = explode(",", $cf['localints']);
+
+ /* Proxy is not enabled, therefore, no rules/anchors. */
+ if ($cf["proxy_enable"] != "on") {
+ return;
+ }
+
+ /* Bail if there is nothing to do */
+ if (empty($interface_list)) {
+ log_error("FTP Proxy cannot sync: No interfaces selected.");
+ return;
+ }
+
+ $rules = "";
+ switch ($type) {
+ case "nat":
+ $rules .= "nat-anchor \"ftp-proxy/*\"\n";
+ $rules .= "rdr-anchor \"ftp-proxy/*\"\n";
+
+ foreach ($interface_list as $interface_friendly) {
+ if (empty($interface_friendly)) {
+ continue;
+ }
+ $interface = get_real_interface($interface_friendly);
+ if (empty($interface)) {
+ continue;
+ }
+ $rules .= "rdr pass on {$interface} inet proto tcp from any to any port 21 -> 127.0.0.1 port " . ftpproxy_get_port() . "\n";
+ if ($cf["ipv6_enable"] == "on") {
+ $rules .= "rdr pass on {$interface} inet6 proto tcp from any to any port 21 -> ::1 port " . ftpproxy_get_port() . "\n";
+ }
+ }
+ break;
+ case "filter":
+ $rules .= "anchor \"ftp-proxy/*\"\n";
+ // $rules = "pass out proto tcp from any to any port 21\n";
+ break;
+
+ }
+ return $rules;
+}
+?> \ No newline at end of file
diff --git a/config/ftpproxy/ftpproxy.xml b/config/ftpproxy/ftpproxy.xml
new file mode 100644
index 00000000..ca83f911
--- /dev/null
+++ b/config/ftpproxy/ftpproxy.xml
@@ -0,0 +1,111 @@
+<packagegui>
+ <name>FTP Client Proxy</name>
+ <version>0.1</version>
+ <title>FTP Client Proxy</title>
+ <aftersaveredirect>pkg_edit.php?xml=ftpproxy.xml</aftersaveredirect>
+ <include_file>/usr/local/pkg/ftpproxy.inc</include_file>
+ <additional_files_needed>
+ <prefix>/usr/local/pkg/</prefix>
+ <chmod>077</chmod>
+ <item>https://packages.pfsense.org/packages/config/ftpproxy/ftpproxy.inc</item>
+ </additional_files_needed>
+ <menu>
+ <name>FTP Client Proxy</name>
+ <tooltiptext>Modify FTP Client Proxy settings.</tooltiptext>
+ <section>Services</section>
+ <configfile>ftpproxy.xml</configfile>
+ <url>/pkg_edit.php?xml=ftpproxy.xml</url>
+ </menu>
+ <service>
+ <name>ftp-proxy</name>
+ <rcfile>ftp-proxy.sh</rcfile>
+ <executable>ftp-proxy</executable>
+ <description>Client FTP Proxy Daemon</description>
+ </service>
+ <fields>
+ <field>
+ <name>General Settings</name>
+ <type>listtopic</type>
+ </field>
+ <field>
+ <fielddescr>Proxy Enabled</fielddescr>
+ <fieldname>proxy_enable</fieldname>
+ <description>Enable the FTP Proxy.</description>
+ <type>checkbox</type>
+ <default_value>off</default_value>
+ </field>
+ <field>
+ <fielddescr>Local Interface</fielddescr>
+ <fieldname>localints</fieldname>
+ <type>interfaces_selection</type>
+ <description>Select the local (LAN type) interfaces which contain FTP clients.</description>
+ <required/>
+ <multiple/>
+ </field>
+ <field>
+ <fielddescr>IPv6 Support</fielddescr>
+ <fieldname>ipv6_enable</fieldname>
+ <description>Support IPv6 FTP connections, otherwise only IPv4 connections are allowed.</description>
+ <type>checkbox</type>
+ <default_value>off</default_value>
+ </field>
+ <field>
+ <fielddescr>Anonymous Only</fielddescr>
+ <fieldname>anononly</fieldname>
+ <description>Only permit anonymous FTP connections using the &quot;ftp&quot; or &quot;anonymous&quot; users.</description>
+ <type>checkbox</type>
+ <default_value>off</default_value>
+ </field>
+ <field>
+ <fielddescr>Source Address</fielddescr>
+ <fieldname>sourceaddr</fieldname>
+ <description>Enter a VIP to be the source of outgoing control traffic.</description>
+ <type>input</type>
+ </field>
+ <field>
+ <fielddescr>Bind Port (Default: 8021)</fielddescr>
+ <fieldname>bindport</fieldname>
+ <description>Port where the proxy will listen for redirected connections.</description>
+ <type>input</type>
+ </field>
+ <field>
+ <fielddescr>Maximum Sessions (Default: 100)</fielddescr>
+ <fieldname>maxessions</fieldname>
+ <description>Maximum number of concurrent FTP sessions. When the proxy reaches this limit, new connections are denied. Must be between 1 and 500.</description>
+ <type>input</type>
+ </field>
+ <field>
+ <fielddescr>Traffic Shaping Queue</fielddescr>
+ <fieldname>tsq</fieldname>
+ <description>Create rules with queue appended, so that data connections can be queued.</description>
+ <type>input</type>
+ </field>
+ <field>
+ <fielddescr>Rewrite Source to Port 20</fielddescr>
+ <fieldname>src20</fieldname>
+ <description>Rewrite source port to 20 in active mode to suit ancient clients that insist on this behavior.</description>
+ <type>checkbox</type>
+ <default_value>off</default_value>
+ </field>
+ <field>
+ <fielddescr>Idle Timeout (Default: 86400)</fielddescr>
+ <fieldname>idletimeout</fieldname>
+ <description>(Seconds) Number of seconds that the control connection can be idle, before the proxy will disconnect. The maximum is 86400 seconds. Do not set this too low, because the control connection is usually idle when large data transfers are taking place.</description>
+ <type>input</type>
+ </field>
+ <field>
+ <fielddescr>Log Connections</fielddescr>
+ <fieldname>log</fieldname>
+ <description>Set the 'log' flag on pf rules committed by ftp-proxy.</description>
+ <type>checkbox</type>
+ <default_value>off</default_value>
+ </field>
+
+ </fields>
+ <custom_php_resync_config_command>
+ sync_package_ftpproxy();
+ </custom_php_resync_config_command>
+ <custom_php_validation_command>
+ validate_form_ftpproxy($_POST, $input_errors);
+ </custom_php_validation_command>
+</packagegui>