diff --git a/CHANGELOG b/CHANGELOG deleted file mode 100644 index 30f72c9..0000000 --- a/CHANGELOG +++ /dev/null @@ -1,252 +0,0 @@ - - Turtle Firewall - - 2001/11/23 13:25:00 - - Copyright (c) 2001-2024 Andrea Frigido - You may distribute under the terms of either - the GNU General Public License (GPL) - - -CHANGELOG ---------- - -05-12-2001 v.0.91 - - Modificato il nome da fwconf in Turtle Firewall (turtlefw) - -10-01-2002 v.0.92 - - Inserite le regole di accesso da/verso interfaccia lo - che precedentemente impedivano l'accesso a se stesso. - - Impostati i diritti sul file sh generato per l'esecuzione. - - Corretta la definizione delle lan nei file di configurazione - di esempio (samples). -19-03-2002 v.0.93 - - Aggiunto l'uso del modulo turtlefirewall.pm (/usr/lib) - -22-03-2002 v.0.94 - - Aggiunto supporto dell'attributo ACTIVE delle rule. -02-04-2002 v.0.95 - - Aggiunto il file setup al tarball. -17-04-2002 v.0.96 - - Add webmin module languages files for English and Italian. - - Fix Masquerade and NAT bug. -17-05-2002 v.0.97 - - Add franch webmin language file. - - Fix bugs. -23-05-2002 v.0.98 Giampaolo Tomassoni - - Do you need port-based natting? Here it is... - - Fixed the I-Wanna-Reply-To-Pings-But-It-Doesn't bug: when - the fw accepts pings on a => FIREWALL base, - don't turn the /proc/sys/net/ipv4/icmp_echo_ignore_all - kernel flag on... - - Applied few ahestetic make-ups -14-06-2002 v.0.99 - - Fix turtlefirewall privileges bug. - - Use iptables from PATH (iptables directory need to be in PATH env. var.) - - PreLoad modules for ftp connections and NAT. - - Add CVS, NNTP services. -20-06-2002 v.1.00 - - Change SystemV service start/stop order from 00/99 to 08/92. - - Change TurtleFirewall package file name. - - Check if XML::Parser perl module is installed. - - Add Telnet service. -26-06-2002 v.1.10 - - Add description field for rules and items. - - Add experimental H.323 service. - - Fix bugs. -08-07-2002 v.1.11 - - Setup procedure into webmin module, now Turtle Firewall installation is very easy. - - Removed chkconfig command for setup, it isn't availabe in all GNU/Linux distributions. - - Fix bug in "Create Nat" web interface. - - Other minor changes. -09-07-2002 v.1.12 - - Fix bug in XML::Parser module checking. -03-09-2002 v.1.13 - - Add NAT from a zone interface to a real host (etc. modem interface ip to my pc host). - - Add Redirect module (For Transparent Proxy). - - Fix security hole with INVALID packets filter code by Mark Francis. - - Enhanced Log. - - Add firewall rules for IPsec VPN service. - - Add firewall rules for Webmin service. -10-09-2002 v.1.14 - - The configurable options contains now the option to select the logfile (Karl Lovink) - - The dutch language has been added (Karl Lovink). -13-09-2002 v.1.15 - - Fix "DROP INVALID unclean" bug. -26-09-2002 v.1.16 - - Change webmin category from System to Networking. - - Fix a bug on tcp/udp Local Redirection (Soep). -16-10-2002 v.1.17 - - Fix bug with "--log-level info" iptables option. - - Enhanced log report. - - Enhanced interface. - - Add afp-over-tcp service: AFP (Apple Filing Protocol) over TCP. - (Alain Terriault) - - Add nfs (experimental) -13-11-2002 v.1.18 - - Add Firewall Configuration Options. - - Now you can change firewall rules order (more readable). - - Add fwuserdefservices.xml file for userdefined services. With this file you can write your own - services filter without changing official fwservices.xml file. - The structure of this new file is identical of fwservices.xml file structure. - If you write a service with a name used by fwservices.xml, this new service definition overwrite - the original service definition so, if you want, you can rewrite all services. - IMPORTANT: I invite all to send me your userdefined service filter definitions, so I can add them into - the predefined services list (fwservices.xml) for all Turtle Firewall users. -26-11-2002 v.1.19 - - Fix bug in Zone deletion. - - Fix a bug using aliased interfaces (signaled by Torsten) - - Add German translation (Jimmy Collins) - - Add mysql and kazaa services (Jimmy Collins) - - Add pptp (vpn) and rdp services (Joe MacDonald) - - Add PC-Anyware service (Chris Carter) - - Change setup script for Slackware Linux distribution (A.Frigido, Patrik) -15-01-2003 v.1.20 - - Add optional MAC address field in host edit form. - - Add target field (ACCEPT/DROP/REJECT) in rule edit form. - - Fix bug in Log prefix string, it must be up to 29 chars length. - - Add x11: X Window System service. - - Use numerical notation for ports in fwservices.xml. - - Add Active flag to NAT, Masquerade and Redirect rules. -16-01-2003 v.1.21 - - Fix a bug in Redirection. -12-02-2003 v.1.22 - - Firewall and NAT rules with multiple services. - - Change LOG prefix from "TFW DROP" to "TFW". - - Add --start, --stop and --status options to turtlefirewall main script. - - Add stop button in the webmin turtlefirewall index page. - - Translate error messages (english and italian). - - Add icmp_all service for all messages (request+reply). - - Add all icmp messages in the special service "all". -18-02-2003 v.1.23 - - Add proxy, ssh21, dhcp, snmptrap, socks and eDonkey services (Karl Lovink). - - Fix a bug into log viewer (Fredrik Tuomas). - - Add Configuration Backup/Restore. -31-03-2003 v.1.24 - - Change Turtle Firewall stop process, ping will be reenabled. - - Add AIM/ICQ and Soulseek std services (Frank Förster). - - Add Oracle, VNC, VNC-http services. - - Add rip, syslog, icecast, icp, irc (Karl Lovink). - - Local Redirection Improved. - - Now you can rename all firewall items. - - More options. -02-04-2003 v.1.25 - - Fix bugs. -07-05-2003 v.1.26 - - Fix "de" language file (Frank Förster). - - NAT Improved, now you can change rules order. - - NAT rules bugfix. - - Configuration backup download bugfix. -14-05-2003 v.1.27 - - Small Bug-fix. -15-07-2004 v.1.28 - - Add port 445 to netbios service. - - Add jabber and jabber-s2s (server to server) services. - - Add lpr Line Printer Protocol. - - Add rdp - Windows Remote Desktop Protocol. - - Fix bugs. -19-11-2004 v.1.29 - - Set icmp_echo_ignore_all flag to 0. Turtle Firewall use iptables - rules for drop or allow icmp echo packets. This fix a bug in tfw ping. - - Disable tcp_ecn flag. - - In masquerading configuration now you can specify source,destinatio,service, - port and action (masquerade or not masquerade). -21-11-2004 v.1.30 - - Add * option in source and destination field of a firewall rule: all zones except FIREWALL. -30-11-2004 v.1.31 - - Change rules display in turtlefirewall startup. - - Fix bugs. -17-02-2005 v.1.32 - - Use iptables-restore command to speed up firewall start up. -??-??-2005 v.1.33 - - Add source and destination option to the NAT rules. - - Bugfix on rules with target REJECT (from v.1.32). -31-11-2005 v.1.34 - - Add mangle mark rule attribute for QoS (iproute2). - - Bugfix on turtlefirewall stop procedure (signaled by Ulf Seltmann). -11-01-2006 v.1.36 - - Add multisources and multidestinations in firewall rules. - - Add service attribute in filter xml tag of services definition files. - - Eliminate drop_unclean option, doesn't work with kernel 2.6.x - - Bugfix. -02-02-2006 v.1.37 - - New service definitions were added: - igmp (Internet Group Management Protocol). - bpalogin (BPALogin). - Thanks to Rene Cunningham for this two services. - openvpn (OpenVPN protocolo, www.openvpn.net). - - Bugs were fixed. -20-05-2011 v.1.38 - - Debian 6.0 compatibility (chocolateboy). -23-04-2020 v.2.0 - - OS : Systemd support, RPM package, Ensure running via cron. - - Feature : Added Time, GeoIP and nDPI support. - - Feature : Added Optional IP Blacklist. - - Feature : Added NAT Map to Port. - - Feature : Added HostName Set and IP Set items. - - Feature : Added pptp, sip, h323 and tftp kernel module options. - - Feature : Added Flow Statistics. - - Feature : Moved Marking to Mangle Rules. ( Connmark : for use with tc ) - - Feature : Added Preroute Mangle Rules. ( Connmark Preroute : for use with iproute ) - - Logging : Added Logging per rule and Flowinfo logging for target ACCEPT. - - Services : Removed www service. ( duplicate of http service ) - - Services : Added Google QUIC, Ubiquiti Unifi, Whatsapp, Zoom, Teams, etc. - - Bug : Fixed MAC filtering. ( no ip required ) - - Bug : Fixed Mangle table flush on firewall stop. - - Bug : Migrated ip_conntrack_max to nf_conntrack_max. - - Bug : Limit zone name max characters. - - Bug : Fixed zone deletion verification. - - Connection Tracking : Replaced "-m state --state" with "-m conntrack --ctstate". - - Connection Tracking : Enabled automatic helpers. ( Todo : migrate to CT target ) - - Connection Tracking : Enabled connection marking. - - Connection Tracking : Flush conntrack table on firewall stop. - - Connection Tracking : Added conntrack tools. - - Theme : New Webmin support. ( Todo : Translate new features ) -09-10-2022 v.2.1 - - OS : Kernel 6 compatibility. - - Feature : Removed pptp, sip, h323 and tftp kernel module options. - - Feature : Added Preroute Raw Rules. ( Conntrack Preroute : for use with CT helpers ) - - Feature : Added Raw Rules. ( Conntrack : for use with CT helpers ) - - Connection Tracking : Migrated helpers to CT target. -03-06-2023 v.2.2 - - Bug : Code cleanup. - - Bug : Fixed rename and delete of multi select items used in rules. - - Bug : Fixed port or port range verification in rules. - - Bug : Fixed service display wrap in rules. - - Feature : Added Flow Risk support. - - Feature : Added Optional Domain, JA3 and SHA1 Blacklist support. - - Feature : Added Rate Limit support. - - Feature : Added "dport" Flow Statistics option. - - Feature : Removed Blacklist Flow Reports. - - Feature : Improve Blacklist view. -18-02-2024 v.2.3 - - Bug : Code cleanup. - - Bug : Fixed --mac-source masquerade. - - Bug : Removed depreciated HTML , , , and tags. - - Bug : Limit Blacklist sizes. - - Bug : Remove Domain Blacklist wildcard match. - - Bug : Fixed zone name item verification. - - Bug : Fixed Rate Limit apply when used in multiple rules. - - Feature : Rework action log format. - - Feature : Extend nDPI support. - - Logging : Replaced JA3 server with JA4 client. - - Theme : Rework group item selection. - - Theme : Split Port and nDPI service column in rule views. - - Theme : Update edit forms to use ui standard. - - Theme : Standardize Webmin images. -22-08-2024 v.2.4 - - OS : Old fw.xml format fixes in fixconfig.sh. - - OS : Restore setup.cgi for WBM install. - - OS : Support for Debian 12 syslog date format. - - OS : Standardize shebang. - - Bug : Fixed ApplyRule risk variable not initialised. - - Bug : Fixed GeoIP include for Masquerade and Redirect. - - Bug : Include reserved name check on item rename. - - Services : Removed depreciated smtps TCP port 465 service. - - Services : Added DNS over TLS TCP port 853 service. - - Feature : nDPI 4.9.11 support. - - Feature : Add ipset support. - - Feature : Add prefix support for net items. - - Feature : Add item reference lookup support. - - Todo : Translate new features - - Todo : Fix backup.cgi restore upload. diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..687568e --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,309 @@ +# ChangeLog + +## v.2.6 (30-04-2025) +- Feature : nDPI 4.15 support. +- Feature : Remove JA3 logging. +- Feature : Remove JA3 Blacklist. +- Feature : Remove TLS Version logging, already included in JA4. +- Feature : Migrate Flow Statistics query backend to q-text-as-data + and allow multiple log selection. +- Feature : Add static Blacklist include. +- Bug : Fixed translation of HTML character entities. +- Bug : Fixed Flow Statistics flow time reported incorrectly. +- Bug : Removed default variable reference in log views. +- Bug : Standardize library include and table syntax. +- Bug : Fixed missing sort in item selection. +- Bug : Fixed custom config file definition. +- Bug : Fixed connection marking. +- OS : Remove unused iptables_restore_emu. +- OS : Remove depreciated dkms feature: CLEAN +- Todo : Translate new features. +- Todo : Fix backup.cgi restore upload. + +## v.2.5 (01-01-2025) +- Services : Make user defined services permanent. +- Services : Removed depreciated kazaa and edonkey services. +- Feature : nDPI 4.13 support. +- Feature : Add clamp_mss_to_pmtu option. +- Feature : Add nDPI ACCEPT support for Hostnames. + +## v.2.4 (22-08-2024) +- OS : Old fw.xml format fixes in fixconfig.sh. +- OS : Restore setup.cgi for WBM install. +- OS : Support for Debian 12 syslog date format. +- OS : Standardize shebang. +- Bug : Fixed ApplyRule risk variable not initialised. +- Bug : Fixed GeoIP include for Masquerade and Redirect. +- Bug : Include reserved name check on item rename. +- Bug : Fixed rule highlighting on move. +- Bug : Fixed rule tcp/udp ALL ports display. +- Services : Removed depreciated smtps TCP port 465 service. +- Services : Added DNS over TLS TCP port 853 service. +- Feature : nDPI 4.11 support. +- Feature : Add ipset support. +- Feature : Add prefix support for net items. +- Feature : Add item reference lookup support. +- Feature : Make rule order configurable. + +## v.2.3 (18-02-2024) +- Bug : Code cleanup. +- Bug : Fixed --mac-source masquerade. +- Bug : Removed depreciated HTML \, \, \, \ and \ tags. +- Bug : Limit Blacklist sizes. +- Bug : Remove Domain Blacklist wildcard match. +- Bug : Fixed zone name item verification. +- Bug : Fixed Rate Limit apply when used in multiple rules. +- Feature : Rework action log format. +- Feature : Extend nDPI support. +- Logging : Replaced JA3 server with JA4 client. +- Theme : Rework group item selection. +- Theme : Split Port and nDPI service column in rule views. +- Theme : Update edit forms to use ui standard. +- Theme : Standardize Webmin images. + +## v.2.2 (03-06-2023) +- Bug : Code cleanup. +- Bug : Fixed rename and delete of multi select items used in rules. +- Bug : Fixed port or port range verification in rules. +- Bug : Fixed service display wrap in rules. +- Feature : Added Flow Risk support. +- Feature : Added Optional Domain, JA3 and SHA1 Blacklist support. +- Feature : Added Rate Limit support. +- Feature : Added "dport" Flow Statistics option. +- Feature : Removed Blacklist Flow Reports. +- Feature : Improve Blacklist view. + +## v.2.1 (09-10-2022) +- OS : Kernel 6 compatibility. +- Feature : Removed pptp, sip, h323 and tftp kernel module options. +- Feature : Added Preroute Raw Rules. ( Conntrack Preroute : for use with CT helpers ) +- Feature : Added Raw Rules. ( Conntrack : for use with CT helpers ) +- Connection Tracking : Migrated helpers to CT target. + +## v.2.0 (23-04-2020) +- OS : Systemd support, RPM package, Ensure running via cron. +- Feature : Added Time, GeoIP and nDPI support. +- Feature : Added Optional IP Blacklist. +- Feature : Added NAT Map to Port. +- Feature : Added HostName Set and IP Set items. +- Feature : Added pptp, sip, h323 and tftp kernel module options. +- Feature : Added Flow Statistics. +- Feature : Moved Marking to Mangle Rules. ( Connmark : for use with tc ) +- Feature : Added Preroute Mangle Rules. ( Connmark Preroute : for use with iproute ) +- Logging : Added Logging per rule and Flowinfo logging for target ACCEPT. +- Services : Removed www service. ( duplicate of http service ) +- Services : Added Google QUIC, Ubiquiti Unifi, Whatsapp, Zoom, Teams, etc. +- Bug : Fixed MAC filtering. ( no ip required ) +- Bug : Fixed Mangle table flush on firewall stop. +- Bug : Migrated ip_conntrack_max to nf_conntrack_max. +- Bug : Limit zone name max characters. +- Bug : Fixed zone deletion verification. +- Connection Tracking : Replaced "-m state --state" with "-m conntrack --ctstate". +- Connection Tracking : Enabled automatic helpers. ( Todo : migrate to CT target ) +- Connection Tracking : Enabled connection marking. +- Connection Tracking : Flush conntrack table on firewall stop. +- Connection Tracking : Added conntrack tools. +- Theme : New Webmin support. + +## v.1.38 (20-05-2011) +- Debian 6.0 compatibility (chocolateboy). + +## v.1.37 (02-02-2006) +- New service definitions were added: + igmp (Internet Group Management Protocol). + bpalogin (BPALogin). + Thanks to Rene Cunningham for this two services. + openvpn (OpenVPN protocolo, www.openvpn.net). +- Bugs were fixed. + +## v.1.36 (11-01-2006) +- Add multisources and multidestinations in firewall rules. +- Add service attribute in filter xml tag of services definition files. +- Eliminate drop_unclean option, doesn't work with kernel 2.6.x +- Bugfix. + +## v.1.34 (31-11-2005) +- Add mangle mark rule attribute for QoS (iproute2). +- Bugfix on turtlefirewall stop procedure (signaled by Ulf Seltmann). + +## v.1.33 (??-??-2005) +- Add source and destination option to the NAT rules. +- Bugfix on rules with target REJECT (from v.1.32). + +## v.1.32 (17-02-2005) +- Use iptables-restore command to speed up firewall start up. + +## v.1.31 (30-11-2004) +- Change rules display in turtlefirewall startup. +- Fix bugs. + +## v.1.30 (21-11-2004) +- Add * option in source and destination field of a firewall rule: all zones except FIREWALL. + +## v.1.29 (19-11-2004) +- Set icmp_echo_ignore_all flag to 0. Turtle Firewall use iptables + rules for drop or allow icmp echo packets. This fix a bug in tfw ping. +- Disable tcp_ecn flag. +- In masquerading configuration now you can specify source,destinatio,service, + port and action (masquerade or not masquerade). + +## v.1.28 (15-07-2004) +- Add port 445 to netbios service. +- Add jabber and jabber-s2s (server to server) services. +- Add lpr Line Printer Protocol. +- Add rdp - Windows Remote Desktop Protocol. +- Fix bugs. + +## v.1.27 (14-05-2003) +- Small Bug-fix. + +## v.1.26 (07-05-2003) +- Fix "de" language file (Frank Förster). +- NAT Improved, now you can change rules order. +- NAT rules bugfix. +- Configuration backup download bugfix. + +## v.1.25 (02-04-2003) +- Fix bugs. + +## v.1.24 (31-03-2003) +- Change Turtle Firewall stop process, ping will be reenabled. +- Add AIM/ICQ and Soulseek std services (Frank Förster). +- Add Oracle, VNC, VNC-http services. +- Add rip, syslog, icecast, icp, irc (Karl Lovink). +- Local Redirection Improved. +- Now you can rename all firewall items. +- More options. + +## v.1.23 (18-02-2003) +- Add proxy, ssh21, dhcp, snmptrap, socks and eDonkey services (Karl Lovink). +- Fix a bug into log viewer (Fredrik Tuomas). +- Add Configuration Backup/Restore. + +## v.1.22 (02-02-2003) +- Firewall and NAT rules with multiple services. +- Change LOG prefix from "TFW DROP" to "TFW". +- Add --start, --stop and --status options to turtlefirewall main script. +- Add stop button in the webmin turtlefirewall index page. +- Translate error messages (english and italian). +- Add icmp_all service for all messages (request+reply). +- Add all icmp messages in the special service "all". + +## v.1.21 (16-01-2003) +- Fix a bug in Redirection. + +## v.1.20 (15-01-2003) +- Add optional MAC address field in host edit form. +- Add target field (ACCEPT/DROP/REJECT) in rule edit form. +- Fix bug in Log prefix string, it must be up to 29 chars length. +- Add x11: X Window System service. +- Use numerical notation for ports in fwservices.xml. +- Add Active flag to NAT, Masquerade and Redirect rules. + +## v.1.19 (26-11-2002) +- Fix bug in Zone deletion. +- Fix a bug using aliased interfaces (signaled by Torsten) +- Add German translation (Jimmy Collins) +- Add mysql and kazaa services (Jimmy Collins) +- Add pptp (vpn) and rdp services (Joe MacDonald) +- Add PC-Anyware service (Chris Carter) +- Change setup script for Slackware Linux distribution (A.Frigido, Patrik) + +## v.1.18 (13-11-2002) +- Add Firewall Configuration Options. +- Now you can change firewall rules order (more readable). +- Add fwuserdefservices.xml file for userdefined services. With this file you can write your own + services filter without changing official fwservices.xml file. + The structure of this new file is identical of fwservices.xml file structure. + If you write a service with a name used by fwservices.xml, this new service definition overwrite + the original service definition so, if you want, you can rewrite all services. + IMPORTANT: I invite all to send me your userdefined service filter definitions, so I can add them into + the predefined services list (fwservices.xml) for all Turtle Firewall users. + +## v.1.17 (16-10-2002) +- Fix bug with "--log-level info" iptables option. +- Enhanced log report. +- Enhanced interface. +- Add afp-over-tcp service: AFP (Apple Filing Protocol) over TCP. + (Alain Terriault) +- Add nfs (experimental) + +## v.1.16 (26-09-2002) +- Change webmin category from System to Networking. +- Fix a bug on tcp/udp Local Redirection (Soep). + +## v.1.15 (13-09-2002) +- Fix "DROP INVALID unclean" bug. + +## v.1.14 (10-09-2002) +- The configurable options contains now the option to select the logfile (Karl Lovink) +- The dutch language has been added (Karl Lovink). + +## v.1.13 (03-09-2002) +- Add NAT from a zone interface to a real host (etc. modem interface ip to my pc host). +- Add Redirect module (For Transparent Proxy). +- Fix security hole with INVALID packets filter code by Mark Francis. +- Enhanced Log. +- Add firewall rules for IPsec VPN service. +- Add firewall rules for Webmin service. + +## v.1.12 (09-07-2002) +- Fix bug in XML::Parser module checking. + +## v.1.11 (08-07-2002) +- Setup procedure into webmin module, now Turtle Firewall installation is very easy. +- Removed chkconfig command for setup, it isn't availabe in all GNU/Linux distributions. +- Fix bug in "Create Nat" web interface. +- Other minor changes. + +## v.1.10 (26-06-2002) +- Add description field for rules and items. +- Add experimental H.323 service. +- Fix bugs. + +## v.1.00 (20-06-2002) +- Change SystemV service start/stop order from 00/99 to 08/92. +- Change TurtleFirewall package file name. +- Check if XML::Parser perl module is installed. +- Add Telnet service. + +## v.0.99 (14-06-2002) +- Fix turtlefirewall privileges bug. +- Use iptables from PATH (iptables directory need to be in PATH env. var.) +- PreLoad modules for ftp connections and NAT. +- Add CVS, NNTP services. + +## v.0.98 (23-05-2002) +- Do you need port-based natting? Here it is... (Giampaolo Tomassoni) +- Fixed the I-Wanna-Reply-To-Pings-But-It-Doesn't bug: when + the fw accepts pings on a => FIREWALL base, + don't turn the /proc/sys/net/ipv4/icmp_echo_ignore_all + kernel flag on... (Giampaolo Tomassoni) +- Applied few ahestetic make-ups (Giampaolo Tomassoni) + +## v.0.97 (17-05-2002) +- Add franch webmin language file. +- Fix bugs. + +## v.0.96 (17-04-2002) +- Add webmin module languages files for English and Italian. +- Fix Masquerade and NAT bug. + +## v.0.95 (02-04-2002) +- Aggiunto il file setup al tarball. + +## v.0.94 (22-03-2002) +- Aggiunto supporto dell'attributo ACTIVE delle rule. + +## v.0.93 (19-03-2002) +- Aggiunto l'uso del modulo turtlefirewall.pm (/usr/lib) + +## v.0.92 (10-01-2002) +- Inserite le regole di accesso da/verso interfaccia lo + che precedentemente impedivano l'accesso a se stesso. +- Impostati i diritti sul file sh generato per l'esecuzione. +- Corretta la definizione delle lan nei file di configurazione + di esempio (samples). + +## v.0.91 (05-12-2001) +- Modificato il nome da fwconf in Turtle Firewall (turtlefw) diff --git a/INSTALL.md b/INSTALL.md index 794401c..b90ae85 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -27,7 +27,7 @@ apt-get install webmin --install-recommends Download source. ``` cd /tmp -wget https://github.com/frisoft/turtlefirewall/archive/master.zip -O turtlefirewall-master.zip +wget https://github.com/netcons/turtlefirewall/archive/master.zip -O turtlefirewall-master.zip unzip turtlefirewall-master.zip cd turtlefirewall-master ``` @@ -39,13 +39,13 @@ Build source. Install RHEL. ``` -dnf -y install perl-XML-Parser perl-Net-CIDR-Lite perl-Text-CSV_XS iptables-nft ipset conntrack-tools rsyslog dos2unix gawk crontabs +dnf -y install perl-XML-Parser perl-Net-CIDR-Lite perl-Text-CSV_XS iptables-nft ipset conntrack-tools rsyslog dos2unix gawk crontabs q-text-as-data /usr/libexec/webmin/install-module.pl /tmp/turtlefirewall-master/build/turtlefirewall-*.wbm.gz ``` Install Debian. ``` -apt-get -y install libxml-parser-perl libnet-cidr-lite-perl libtext-csv-xs-perl iptables ipset conntrack rsyslog dos2unix gawk cron-daemon-common +apt-get -y install libxml-parser-perl libnet-cidr-lite-perl libtext-csv-xs-perl iptables ipset conntrack rsyslog dos2unix gawk cron-daemon-common python3-q-text-as-data /usr/share/webmin/install-module.pl /tmp/turtlefirewall-master/build/turtlefirewall-*.wbm.gz ``` @@ -53,11 +53,15 @@ apt-get -y install libxml-parser-perl libnet-cidr-lite-perl libtext-csv-xs-perl RHEL. ``` -dnf -y install centos-release-hyperscale-experimental -dnf -y upgrade kernel -reboot +if ! (grep -w "10" /etc/redhat-release) > /dev/null 2>&1 + then + dnf -y install centos-release-hyperscale-experimental + dnf -y upgrade kernel + reboot +fi dnf -y install kernel-devel kernel-headers +dnf -y install kernel-modules-extra dnf -y install iptables-devel libpcap-devel json-c-devel libgcrypt-devel perl-File-Path dnf -y install autoconf automake libtool dnf -y install dkms @@ -66,6 +70,7 @@ systemctl enable dkms --now Debian. ``` +apt-get -y install linux-headers-$(uname -r) apt-get -y install libxtables-dev libpcap-dev libjson-c-dev libgcrypt-dev libmodule-path-perl apt-get -y install autoconf automake libtool apt-get -y install dkms @@ -75,20 +80,22 @@ apt-get -y install dkms Download source. ``` +VERSION="0.3.3" cd /usr/src wget https://github.com/aabc/ipt-ratelimit/archive/master.zip -O ipt-ratelimit-master.zip unzip ipt-ratelimit-master.zip -mv ipt-ratelimit-master ipt-ratelimit-0.3.3 +mv ipt-ratelimit-master ipt-ratelimit-$VERSION rm -rf ipt-ratelimit-master.zip -cd ipt-ratelimit-0.3.3 +cd ipt-ratelimit-$VERSION ``` Install module. ``` cp /tmp/turtlefirewall-master/dkms/dkms-ipt-ratelimit.conf ./dkms.conf -dkms add -m ipt-ratelimit -v 0.3.3 -dkms build -m ipt-ratelimit -v 0.3.3 -dkms install -m ipt-ratelimit -v 0.3.3 +sed -i "s/^PACKAGE_VERSION=.*$/PACKAGE_VERSION=\"$VERSION\"/" dkms.conf +dkms add -m ipt-ratelimit -v $VERSION +dkms build -m ipt-ratelimit -v $VERSION +dkms install -m ipt-ratelimit -v $VERSION ``` Install library. @@ -100,19 +107,21 @@ make all install Download source. ``` +VERSION="3.30" cd /usr/src -wget https://inai.de/files/xtables-addons/xtables-addons-3.27.tar.xz -O xtables-addons-3.27.tar.xz -tar -xvf xtables-addons-3.27.tar.xz -rm -rf xtables-addons-3.27.tar.xz -cd xtables-addons-3.27 +wget https://codeberg.org/jengelh/xtables-addons/releases/download/v${VERSION}/xtables-addons-${VERSION}.tar.zst +tar --zstd -xvf xtables-addons-${VERSION}.tar.zst +rm -rf xtables-addons-${VERSION}.tar.zst +cd xtables-addons-$VERSION ``` Install module. ``` cp /tmp/turtlefirewall-master/dkms/dkms-xtables-addons.conf ./dkms.conf -dkms add -m xtables-addons -v 3.27 -dkms build -m xtables-addons -v 3.27 -dkms install -m xtables-addons -v 3.27 +sed -i "s/^PACKAGE_VERSION=.*$/PACKAGE_VERSION=\"$VERSION\"/" dkms.conf +dkms add -m xtables-addons -v $VERSION +dkms build -m xtables-addons -v $VERSION +dkms install -m xtables-addons -v $VERSION ``` Install library. @@ -126,21 +135,23 @@ make install Download source. ``` +VERSION="4.15.0" cd /usr/src wget https://github.com/vel21ripn/nDPI/archive/master.zip -O nDPI-flow_info-4.zip unzip nDPI-flow_info-4.zip -mv nDPI-flow_info-4 ndpi-netfilter-4.11.0 +mv nDPI-flow_info-4 ndpi-netfilter-$VERSION rm -rf nDPI-flow_info-4.zip -cd ndpi-netfilter-4.11.0 +cd ndpi-netfilter-$VERSION rm -rf windows ``` Install module. ``` cp /tmp/turtlefirewall-master/dkms/dkms-ndpi-netfilter.conf ./dkms.conf -dkms add -m ndpi-netfilter -v 4.11.0 -dkms build -m ndpi-netfilter -v 4.11.0 -dkms install -m ndpi-netfilter -v 4.11.0 +sed -i "s/^PACKAGE_VERSION=.*$/PACKAGE_VERSION=\"$VERSION\"/" dkms.conf +dkms add -m ndpi-netfilter -v $VERSION +dkms build -m ndpi-netfilter -v $VERSION +dkms install -m ndpi-netfilter -v $VERSION ``` Install library. @@ -155,9 +166,10 @@ make install Download source. ``` +VERSION="1.0.0" cd /usr/src -mkdir xtables-time-1.0.0 -cd xtables-time-1.0.0 +mkdir xtables-time-$VERSION +cd xtables-time-$VERSION wget https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/plain/net/netfilter/xt_time.c -O ./xt_time.c cp /tmp/turtlefirewall-master/dkms/Makefile.xt_time ./Makefile ``` @@ -165,24 +177,36 @@ cp /tmp/turtlefirewall-master/dkms/Makefile.xt_time ./Makefile Install module. ``` cp /tmp/turtlefirewall-master/dkms/dkms-xtables-time.conf ./dkms.conf -dkms add -m xtables-time -v 1.0.0 -dkms build -m xtables-time -v 1.0.0 -dkms install -m xtables-time -v 1.0.0 +sed -i "s/^PACKAGE_VERSION=.*$/PACKAGE_VERSION=\"$VERSION\"/" dkms.conf +dkms add -m xtables-time -v $VERSION +dkms build -m xtables-time -v $VERSION +dkms install -m xtables-time -v $VERSION ``` ## Turtlefirewall Setup -First finalise setup via Webmin, then enable service. - -RHEL. +Disable default firewall RHEL. ``` -/etc/cron.daily/xt_geoip_update systemctl disable firewalld --now -systemctl enable turtlefirewall --now +``` +Finalise setup via Webmin or command line RHEL. +``` +cd /usr/libexec/webmin/turtlefirewall/setup +/usr/bin/env perl setup +cd .. +rm -rf setup* ``` -Debian. +Finalise setup via Webmin or command line Debian. +``` +cd /usr/share/webmin/turtlefirewall/setup +/usr/bin/env perl setup +cd .. +rm -rf setup* +``` + +Download GeoIP database and enable service. ``` /etc/cron.daily/xt_geoip_update systemctl enable turtlefirewall --now diff --git a/README.md b/README.md index ab41dad..534950a 100644 --- a/README.md +++ b/README.md @@ -1,25 +1,23 @@ ## Turtle Firewall 2 Turtle Firewall allows you to configure a Linux firewall in a simple and fast way. -It's based on Netfilter iptables. Its operation is easy to understand: you can define the different firewall elements (zones, hosts, networks, geoip) and then set the services (port, dpi) you want to control (allow, deny, ratelimit, log) among the different elements or groups of elements. +It's based on Netfilter iptables. Its operation is easy to understand: you can define the different firewall elements (zones, hosts, networks, geoips, ipsets) and then set the services (port, dpi) you want to control (allow, deny, ratelimit, log) among the different elements or groups of elements. You can do this by simply editing a XML file or using the web interface [Webmin](http://www.webmin.com/). Turtle Firewall is an Open Source project written using the perl language and realeased under GPL version 2.0 by Andrea Frigido (Frisoft). ## New Features -- Time. -- Geo Location. -- Deep Packet Inspection. -- Risk Detection. -- Rate Limiting. -- Blacklists. -- NAT Map to Port. -- Logging per rule. -- Flow Info logging. -- Flow Statistics. -- Connection Marking. -- Connection Tracking. +- Time, GeoIP and nDPI Support. +- Blacklists and Flow Risks. +- Rate Limit Support. +- Logging per Rule. ( target ACCEPT logs flow, target DROP/REJECT logs action ) +- Flow Statistics. ( via Netflow nDPI classified historical flow data to disk ) +- Connection Marking. ( for use with tc and iproute ) +- Connection Tracking. ( for use with CT helpers ) +- NAT Map to Port. ( for port redirection ) +- Address Lists and CIDR Networks. +- Item Reference Lookup and Rule Order Configuration Support. ## Requirements @@ -31,7 +29,9 @@ Turtle Firewall is an Open Source project written using the perl language and re nf_tables,
nf_conntrack,
xt_connmark,
-xt_time.
+xt_time,
+xt_set,
+xt_tcpmss.
- Extra Netfilter kernel modules :
xt_ndpi, ( https://github.com/vel21ripn/nDPI )
xt_geoip, ( https://codeberg.org/jengelh/xtables-addons )
diff --git a/dkms/Makefile.xt_time b/dkms/Makefile.xt_time index d5a200a..6bcbbe2 100644 --- a/dkms/Makefile.xt_time +++ b/dkms/Makefile.xt_time @@ -1,7 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 # -## Makefile for the linux hfsplus filesystem routines. -# # If KERNELRELEASE is defined, the make command using this Makefile has # been invoked by the kernel build system and so can use its language. # Otherwise, if KERNELRELEASE is null, a make command was issued from diff --git a/dkms/dkms-ipt-ratelimit.conf b/dkms/dkms-ipt-ratelimit.conf index 92a5bb1..b98b53f 100644 --- a/dkms/dkms-ipt-ratelimit.conf +++ b/dkms/dkms-ipt-ratelimit.conf @@ -4,7 +4,6 @@ PACKAGE_VERSION="0.3.3" PACKAGE_NAME="ipt-ratelimit" BDIR="$dkms_tree/${PACKAGE_NAME}/${PACKAGE_VERSION}/build" -CLEAN="make clean" MAKE="make all ; find ${BDIR} -name '*.ko' -exec mv -v {} ${BDIR} \;" AUTOINSTALL="yes" diff --git a/dkms/dkms-ndpi-netfilter.conf b/dkms/dkms-ndpi-netfilter.conf index 39a23d8..5bd3bd3 100644 --- a/dkms/dkms-ndpi-netfilter.conf +++ b/dkms/dkms-ndpi-netfilter.conf @@ -1,11 +1,10 @@ -PACKAGE_VERSION="4.11.0" +PACKAGE_VERSION="4.15.0" # Items below here should not have to change with each driver version PACKAGE_NAME="ndpi-netfilter" BDIR="$dkms_tree/${PACKAGE_NAME}/${PACKAGE_VERSION}/build" PRE_BUILD="autogen.sh" -CLEAN="make clean" MAKE="make -C ndpi-netfilter; find ${BDIR} -name '*.ko' -exec mv -v {} ${BDIR} \;" AUTOINSTALL="yes" @@ -15,4 +14,4 @@ AUTOINSTALL="yes" BUILT_MODULE_LOCATION[0]="" BUILT_MODULE_NAME[0]="xt_ndpi" -DEST_MODULE_LOCATION[0]="/extra" +DEST_MODULE_LOCATION[0]="/extra" \ No newline at end of file diff --git a/dkms/dkms-xtables-addons.conf b/dkms/dkms-xtables-addons.conf index 3398dd1..823b8a6 100644 --- a/dkms/dkms-xtables-addons.conf +++ b/dkms/dkms-xtables-addons.conf @@ -1,4 +1,4 @@ -PACKAGE_VERSION="3.26" +PACKAGE_VERSION="3.30" # Items below here should not have to change with each driver version @@ -6,7 +6,6 @@ PACKAGE_NAME="xtables-addons" BDIR="$dkms_tree/${PACKAGE_NAME}/${PACKAGE_VERSION}/build" MAKEARGS=" -C $kernel_source_dir M=${BDIR}/extensions XA_ABSTOPSRCDIR=${BDIR} XA_TOPSRCDIR=${BDIR} V=1" PRE_BUILD="configure" -CLEAN="make ${MAKEARGS} clean" MAKE="make ${MAKEARGS} modules ; find ${BDIR} -name '*.ko' -exec mv -v {} ${BDIR} \;" AUTOINSTALL="yes" @@ -14,94 +13,94 @@ AUTOINSTALL="yes" # Automatically generated rules below #### -BUILT_MODULE_LOCATION[0]="" -BUILT_MODULE_NAME[0]="xt_ACCOUNT" +BUILT_MODULE_LOCATION[0]="" +BUILT_MODULE_NAME[0]="xt_ACCOUNT" DEST_MODULE_LOCATION[0]="/extra" -BUILT_MODULE_LOCATION[1]="" -BUILT_MODULE_NAME[1]="compat_xtables" +BUILT_MODULE_LOCATION[1]="" +BUILT_MODULE_NAME[1]="xt_CHAOS" DEST_MODULE_LOCATION[1]="/extra" -BUILT_MODULE_LOCATION[2]="" -BUILT_MODULE_NAME[2]="xt_pknock" +BUILT_MODULE_LOCATION[2]="" +BUILT_MODULE_NAME[2]="xt_DELUDE" DEST_MODULE_LOCATION[2]="/extra" -BUILT_MODULE_LOCATION[3]="" -BUILT_MODULE_NAME[3]="xt_CHAOS" +BUILT_MODULE_LOCATION[3]="" +BUILT_MODULE_NAME[3]="xt_DHCPMAC" DEST_MODULE_LOCATION[3]="/extra" -BUILT_MODULE_LOCATION[4]="" -BUILT_MODULE_NAME[4]="xt_DELUDE" +BUILT_MODULE_LOCATION[4]="" +BUILT_MODULE_NAME[4]="xt_DNETMAP" DEST_MODULE_LOCATION[4]="/extra" -BUILT_MODULE_LOCATION[5]="" -BUILT_MODULE_NAME[5]="xt_DHCPMAC" +BUILT_MODULE_LOCATION[5]="" +BUILT_MODULE_NAME[5]="xt_ECHO" DEST_MODULE_LOCATION[5]="/extra" -BUILT_MODULE_LOCATION[6]="" -BUILT_MODULE_NAME[6]="xt_DNETMAP" +BUILT_MODULE_LOCATION[6]="" +BUILT_MODULE_NAME[6]="xt_IPMARK" DEST_MODULE_LOCATION[6]="/extra" -BUILT_MODULE_LOCATION[7]="" -BUILT_MODULE_NAME[7]="xt_ECHO" +BUILT_MODULE_LOCATION[7]="" +BUILT_MODULE_NAME[7]="xt_LOGMARK" DEST_MODULE_LOCATION[7]="/extra" -BUILT_MODULE_LOCATION[8]="" -BUILT_MODULE_NAME[8]="xt_IPMARK" +BUILT_MODULE_LOCATION[8]="" +BUILT_MODULE_NAME[8]="xt_PROTO" DEST_MODULE_LOCATION[8]="/extra" -BUILT_MODULE_LOCATION[9]="" -BUILT_MODULE_NAME[9]="xt_LOGMARK" +BUILT_MODULE_LOCATION[9]="" +BUILT_MODULE_NAME[9]="xt_SYSRQ" DEST_MODULE_LOCATION[9]="/extra" -BUILT_MODULE_LOCATION[10]="" -BUILT_MODULE_NAME[10]="xt_PROTO" +BUILT_MODULE_LOCATION[10]="" +BUILT_MODULE_NAME[10]="xt_TARPIT" DEST_MODULE_LOCATION[10]="/extra" -BUILT_MODULE_LOCATION[11]="" -BUILT_MODULE_NAME[11]="xt_SYSRQ" +BUILT_MODULE_LOCATION[11]="" +BUILT_MODULE_NAME[11]="xt_asn" DEST_MODULE_LOCATION[11]="/extra" -BUILT_MODULE_LOCATION[12]="" -BUILT_MODULE_NAME[12]="xt_TARPIT" +BUILT_MODULE_LOCATION[12]="" +BUILT_MODULE_NAME[12]="xt_condition" DEST_MODULE_LOCATION[12]="/extra" -BUILT_MODULE_LOCATION[13]="" -BUILT_MODULE_NAME[13]="xt_condition" +BUILT_MODULE_LOCATION[13]="" +BUILT_MODULE_NAME[13]="xt_fuzzy" DEST_MODULE_LOCATION[13]="/extra" -BUILT_MODULE_LOCATION[14]="" -BUILT_MODULE_NAME[14]="xt_fuzzy" +BUILT_MODULE_LOCATION[14]="" +BUILT_MODULE_NAME[14]="xt_geoip" DEST_MODULE_LOCATION[14]="/extra" -BUILT_MODULE_LOCATION[15]="" -BUILT_MODULE_NAME[15]="xt_geoip" +BUILT_MODULE_LOCATION[15]="" +BUILT_MODULE_NAME[15]="xt_iface" DEST_MODULE_LOCATION[15]="/extra" -BUILT_MODULE_LOCATION[16]="" -BUILT_MODULE_NAME[16]="xt_iface" +BUILT_MODULE_LOCATION[16]="" +BUILT_MODULE_NAME[16]="xt_ipp2p" DEST_MODULE_LOCATION[16]="/extra" -BUILT_MODULE_LOCATION[17]="" -BUILT_MODULE_NAME[17]="xt_ipp2p" +BUILT_MODULE_LOCATION[17]="" +BUILT_MODULE_NAME[17]="xt_ipv4options" DEST_MODULE_LOCATION[17]="/extra" -BUILT_MODULE_LOCATION[18]="" -BUILT_MODULE_NAME[18]="xt_ipv4options" +BUILT_MODULE_LOCATION[18]="" +BUILT_MODULE_NAME[18]="xt_length2" DEST_MODULE_LOCATION[18]="/extra" -BUILT_MODULE_LOCATION[19]="" -BUILT_MODULE_NAME[19]="xt_length2" +BUILT_MODULE_LOCATION[19]="" +BUILT_MODULE_NAME[19]="xt_lscan" DEST_MODULE_LOCATION[19]="/extra" -BUILT_MODULE_LOCATION[20]="" -BUILT_MODULE_NAME[20]="xt_lscan" +BUILT_MODULE_LOCATION[20]="" +BUILT_MODULE_NAME[20]="xt_pknock" DEST_MODULE_LOCATION[20]="/extra" -BUILT_MODULE_LOCATION[21]="" -BUILT_MODULE_NAME[21]="xt_psd" +BUILT_MODULE_LOCATION[21]="" +BUILT_MODULE_NAME[21]="xt_psd" DEST_MODULE_LOCATION[21]="/extra" -BUILT_MODULE_LOCATION[22]="" -BUILT_MODULE_NAME[22]="xt_quota2" +BUILT_MODULE_LOCATION[22]="" +BUILT_MODULE_NAME[22]="xt_quota2" DEST_MODULE_LOCATION[22]="/extra" diff --git a/dkms/dkms-xtables-time.conf b/dkms/dkms-xtables-time.conf index cfac3b6..6465673 100644 --- a/dkms/dkms-xtables-time.conf +++ b/dkms/dkms-xtables-time.conf @@ -5,7 +5,6 @@ PACKAGE_VERSION="1.0.0" PACKAGE_NAME="xtables-time" BDIR="$dkms_tree/${PACKAGE_NAME}/${PACKAGE_VERSION}/build" MAKEARGS=" -C $kernel_source_dir M=${BDIR}" -CLEAN="make ${MAKEARGS} clean" MAKE="make ${MAKEARGS} modules; find ${BDIR} -name '*.ko' -exec mv -v {} ${BDIR} \;" AUTOINSTALL="yes" @@ -15,4 +14,4 @@ AUTOINSTALL="yes" BUILT_MODULE_LOCATION[0]="" BUILT_MODULE_NAME[0]="xt_time" -DEST_MODULE_LOCATION[0]="/extra" +DEST_MODULE_LOCATION[0]="/extra" \ No newline at end of file diff --git a/src/turtlefirewall/backup.cgi b/src/turtlefirewall/backup.cgi index 382050b..ee82f44 100644 --- a/src/turtlefirewall/backup.cgi +++ b/src/turtlefirewall/backup.cgi @@ -3,12 +3,12 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2025 Andrea Frigido # You may distribute under the terms of either the GNU General Public # License #====================================================================== -do 'turtlefirewall-lib.pl'; +require './turtlefirewall-lib.pl'; &ReadParse(); if( $in{download} ) { @@ -24,7 +24,7 @@ if( $in{upload} ) { # FIXME } else { print qq~
- +
@@ -39,7 +39,7 @@ if( $in{upload} ) {
$text{'backup_backuptitle'}
- +
@@ -94,7 +94,7 @@ sub restore_upload { syswrite(TARGZ, $backup, length($backup)); close TARGZ; - print qq~
$text{'backup_restoretitle'}
+ print qq~
diff --git a/src/turtlefirewall/edit_addresslist.cgi b/src/turtlefirewall/edit_addresslist.cgi index ff10c68..53d243f 100644 --- a/src/turtlefirewall/edit_addresslist.cgi +++ b/src/turtlefirewall/edit_addresslist.cgi @@ -3,12 +3,12 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2025 Andrea Frigido # You may distribute under the terms of either the GNU General Public # License #====================================================================== -do 'turtlefirewall-lib.pl'; +require './turtlefirewall-lib.pl'; &ReadParse(); $new = $in{'new'}; diff --git a/src/turtlefirewall/edit_connmark.cgi b/src/turtlefirewall/edit_connmark.cgi index 579b834..8c37401 100644 --- a/src/turtlefirewall/edit_connmark.cgi +++ b/src/turtlefirewall/edit_connmark.cgi @@ -3,19 +3,23 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2025 Andrea Frigido # You may distribute under the terms of either the GNU General Public # License #====================================================================== -do 'turtlefirewall-lib.pl'; +require './turtlefirewall-lib.pl'; &ReadParse(); +my $nConnmarks = $fw->GetConnmarksCount(); + $new = $in{'new'}; if( $new ) { $heading = "$icons{CREATE}{IMAGE}$text{'edit_connmark_title_create'}"; - $idx = ''; + $nConnmarks++; + $idx = $nConnmarks; + $newIdx = ''; $src = ''; $dst = ''; $service = ''; @@ -30,6 +34,7 @@ if( $new ) { } else { $heading = "$icons{EDIT}{IMAGE}$text{'edit_connmark_title_edit'}"; $idx = $in{'idx'}; + $newIdx = ''; %rule = $fw->GetConnmark($idx); $src = $rule{'SRC'}; $dst = $rule{'DST'}; @@ -45,6 +50,9 @@ if( $new ) { } &ui_print_header( $heading, $text{'title'}, "" ); +my @idxs = (); +for( my $i=1; $i<=$nConnmarks; $i++ ) { push @idxs, $i; } + my @selected_src = split(/,/, $src); my @selected_dst = split(/,/, $dst); my @items = ('*'); @@ -75,10 +83,8 @@ print &ui_hidden("idx", $idx); my @tds = ( "width=20%", "width=80%" ); print &ui_columns_start(undef, 100, 0, \@tds); my $col = ''; -if( !$new ) { - $col = "$idx"; - print &ui_columns_row([ "$icons{ID}{IMAGE}ID", $col ], \@tds); -} +$col = &ui_select("newIdx", $idx, \@idxs); +print &ui_columns_row([ "$icons{ID}{IMAGE}ID", $col ], \@tds); $col = &ui_select("src", \@selected_src, \@items, 5, 1); print &ui_columns_row([ "$icons{ZONE}{IMAGE}$text{'rule_src'}", $col ], \@tds); $col = &ui_select("dst", \@selected_dst, \@items, 5, 1); @@ -111,4 +117,4 @@ print "
$text{'backup_restoretitle'}
"; print &ui_form_end(); print "

"; -&ui_print_footer("list_manglerules.cgi?idx=$idx",'Mangle Rules list'); +&ui_print_footer("list_manglerules.cgi?table=connmark&idx=$idx",'Mangle Rules list'); diff --git a/src/turtlefirewall/edit_connmarkpreroute.cgi b/src/turtlefirewall/edit_connmarkpreroute.cgi index f17cf46..96bbeba 100644 --- a/src/turtlefirewall/edit_connmarkpreroute.cgi +++ b/src/turtlefirewall/edit_connmarkpreroute.cgi @@ -3,19 +3,23 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2025 Andrea Frigido # You may distribute under the terms of either the GNU General Public # License #====================================================================== -do 'turtlefirewall-lib.pl'; +require './turtlefirewall-lib.pl'; &ReadParse(); +my $nConnmarkPreroutes = $fw->GetConnmarkPreroutesCount(); + $new = $in{'new'}; if( $new ) { $heading = "$icons{CREATE}{IMAGE}$text{'edit_connmarkpreroute_title_create'}"; - $idx = ''; + $nConnmarkPreroutes++; + $idx = $nConnmarkPreroutes; + $newIdx = ''; $src = ''; $dst = ''; $service = ''; @@ -30,6 +34,7 @@ if( $new ) { } else { $heading = "$icons{EDIT}{IMAGE}$text{'edit_connmarkpreroute_title_edit'}"; $idx = $in{'idx'}; + $newIdx = ''; %rule = $fw->GetConnmarkPreroute($idx); $src = $rule{'SRC'}; $dst = $rule{'DST'}; @@ -45,6 +50,9 @@ if( $new ) { } &ui_print_header( $heading, $text{'title'}, "" ); +my @idxs = (); +for( my $i=1; $i<=$nConnmarkPreroutes; $i++ ) { push @idxs, $i; } + my @items_src = (); push @items_src, grep(!/FIREWALL/, $fw->GetZoneList()); push @items_src, $fw->GetGeoipList(); @@ -79,10 +87,8 @@ print &ui_hidden("idx", $idx); my @tds = ( "width=20%", "width=80%" ); print &ui_columns_start(undef, 100, 0, \@tds); my $col = ''; -if( !$new ) { - $col = "$idx"; - print &ui_columns_row([ "$icons{ID}{IMAGE}ID", $col ], \@tds); -} +$col = &ui_select("newIdx", $idx, \@idxs); +print &ui_columns_row([ "$icons{ID}{IMAGE}ID", $col ], \@tds); $col = &ui_select("src", $src, \@items_src); print &ui_columns_row([ "$icons{ZONE}{IMAGE}$text{'rule_src'}", $col ], \@tds); $col = &ui_select("dst", $dst, \@items_dst); @@ -116,4 +122,4 @@ print ""; print &ui_form_end(); print "

"; -&ui_print_footer("list_manglerules.cgi?idx=$idx",'Mangle Rules list'); +&ui_print_footer("list_manglerules.cgi?table=connmarkpreroute&idx=$idx",'Mangle Rules list'); diff --git a/src/turtlefirewall/edit_conntrack.cgi b/src/turtlefirewall/edit_conntrack.cgi index aa507c9..738044b 100644 --- a/src/turtlefirewall/edit_conntrack.cgi +++ b/src/turtlefirewall/edit_conntrack.cgi @@ -3,19 +3,23 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2025 Andrea Frigido # You may distribute under the terms of either the GNU General Public # License #====================================================================== -do 'turtlefirewall-lib.pl'; +require './turtlefirewall-lib.pl'; &ReadParse(); +my $nConntracks = $fw->GetConntracksCount(); + $new = $in{'new'}; if( $new ) { $heading = "$icons{CREATE}{IMAGE}$text{'edit_conntrack_title_create'}"; - $idx = ''; + $nConntracks++; + $idx = $nConntracks; + $newIdx = ''; $src = 'FIREWALL'; $dst = ''; $service = ''; @@ -25,6 +29,7 @@ if( $new ) { } else { $heading = "$icons{EDIT}{IMAGE}$text{'edit_conntrack_title_edit'}"; $idx = $in{'idx'}; + $newIdx = ''; %rule = $fw->GetConntrack($idx); $src = $rule{'SRC'}; $dst = $rule{'DST'}; @@ -35,6 +40,9 @@ if( $new ) { } &ui_print_header( $heading, $text{'title'}, "" ); +my @idxs = (); +for( my $i=1; $i<=$nConntracks; $i++ ) { push @idxs, $i; } + my @items_dst = ('*'); push @items_dst, grep(!/FIREWALL/, $fw->GetZoneList()); push @items_dst, $fw->GetGeoipList(); @@ -54,10 +62,8 @@ print &ui_hidden("idx", $idx); my @tds = ( "width=20%", "width=80%" ); print &ui_columns_start(undef, 100, 0, \@tds); my $col = ''; -if( !$new ) { - $col = "$idx"; - print &ui_columns_row([ "$icons{ID}{IMAGE}ID", $col ], \@tds); -} +$col = &ui_select("newIdx", $idx, \@idxs); +print &ui_columns_row([ "$icons{ID}{IMAGE}ID", $col ], \@tds); $col = "$src"; $col .= &ui_hidden("src", $src); print &ui_columns_row([ "$icons{ZONE}{IMAGE}$text{'rule_src'}", $col ], \@tds); @@ -86,4 +92,4 @@ print ""; print &ui_form_end(); print "

"; -&ui_print_footer("list_rawrules.cgi?idx=$idx",'Raw Rules list'); +&ui_print_footer("list_rawrules.cgi?table=conntrack&idx=$idx",'Raw Rules list'); diff --git a/src/turtlefirewall/edit_conntrackpreroute.cgi b/src/turtlefirewall/edit_conntrackpreroute.cgi index 9d0b94d..10c0dbb 100644 --- a/src/turtlefirewall/edit_conntrackpreroute.cgi +++ b/src/turtlefirewall/edit_conntrackpreroute.cgi @@ -3,19 +3,23 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2025 Andrea Frigido # You may distribute under the terms of either the GNU General Public # License #====================================================================== -do 'turtlefirewall-lib.pl'; +require './turtlefirewall-lib.pl'; &ReadParse(); +my $nConntrackPreroutes = $fw->GetConntrackPreroutesCount(); + $new = $in{'new'}; if( $new ) { $heading = "$icons{CREATE}{IMAGE}$text{'edit_conntrackpreroute_title_create'}"; - $idx = ''; + $nConntrackPreroutes++; + $idx = $nConntrackPreroutes; + $newIdx = ''; $src = ''; $dst = ''; $service = ''; @@ -25,6 +29,7 @@ if( $new ) { } else { $heading = "$icons{EDIT}{IMAGE}$text{'edit_conntrackpreroute_title_edit'}"; $idx = $in{'idx'}; + $newIdx = ''; %rule = $fw->GetConntrackPreroute($idx); $src = $rule{'SRC'}; $dst = $rule{'DST'}; @@ -35,6 +40,9 @@ if( $new ) { } &ui_print_header( $heading, $text{'title'}, "" ); +my @idxs = (); +for( my $i=1; $i<=$nConntrackPreroutes; $i++ ) { push @idxs, $i; } + my @items_src = ('*'); push @items_src, grep(!/FIREWALL/, $fw->GetZoneList()); push @items_src, $fw->GetGeoipList(); @@ -61,10 +69,8 @@ print &ui_hidden("idx", $idx); my @tds = ( "width=20%", "width=80%" ); print &ui_columns_start(undef, 100, 0, \@tds); my $col = ''; -if( !$new ) { - $col = "$idx"; - print &ui_columns_row([ "$icons{ID}{IMAGE}ID", $col ], \@tds); -} +$col = &ui_select("newIdx", $idx, \@idxs); +print &ui_columns_row([ "$icons{ID}{IMAGE}ID", $col ], \@tds); $col = &ui_select("src", $src, \@items_src); print &ui_columns_row([ "$icons{ZONE}{IMAGE}$text{'rule_src'}", $col ], \@tds); $col = &ui_select("dst", $dst, \@items_dst); @@ -93,4 +99,4 @@ print ""; print &ui_form_end(); print "

"; -&ui_print_footer("list_rawrules.cgi?idx=$idx",'Raw Rules list'); +&ui_print_footer("list_rawrules.cgi?table=conntrackpreroute&idx=$idx",'Raw Rules list'); diff --git a/src/turtlefirewall/edit_flowstat.cgi b/src/turtlefirewall/edit_flowstat.cgi index c8ab92c..8e0dcf3 100644 --- a/src/turtlefirewall/edit_flowstat.cgi +++ b/src/turtlefirewall/edit_flowstat.cgi @@ -3,12 +3,12 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2025 Andrea Frigido # You may distribute under the terms of either the GNU General Public # License #====================================================================== -do 'turtlefirewall-lib.pl'; +require './turtlefirewall-lib.pl'; use Tie::File; &ui_print_header( "$icons{CREATE}{IMAGE}$text{'edit_flowstat_title_create'}", $text{'title'}, "" ); @@ -22,36 +22,56 @@ print "

"; sub reportFlowStat { - my $log = $FlowLogFile; - + my @items_type = (); my @types = sort keys %flowreports; - my @maxs = ( 'all', '100', '1000', '10000', '100000' ); - my @tops = ( '5', '10', '15', '20' ); + for my $k (@types) { + my @opts = ( "$k", "$text{$flowreports{$k}{NAMEIDX}}" ); + push(@items_type, \@opts); + } + + my @items_target_op = (); + my @target_ops = sort keys %sqloperators; + for my $k (@target_ops) { + my @opts = ( "$k", "$text{$sqloperators{$k}{DESCIDX}}" ); + push(@items_target_op, \@opts); + } + + my @tops = ( '5', '10', '25', '50' ); - #my $type = $types[0]; + my $log = ''; my $type = 'protocol'; - my $max = $maxs[1]; - my $top = $tops[0]; - my $string = ''; + my $top = '5'; + my $is_target = 0; + my $target_type = 'source'; + my $target_op = '='; + my $target = ''; - my @logs = glob("${log}*"); + my @logs = ('*'); + push @logs, sort { $b cmp $a } glob("${FlowLogFile}-*"); + my $selected_log = $logs[1]; print &ui_subheading("$icons{CREATE}{IMAGE}$text{'edit_flowstat_title_create'}"); print &ui_form_start("list_flowstat.cgi", "post"); - my @tds = ( "width=20% style=white-space:nowrap ", "width=80%" ); + my @tds = ( "width=20% style=white-space:nowrap", "width=80%" ); print &ui_columns_start(undef, 100, 0, \@tds); my $col = ''; - $col = &ui_select("log", $log, \@logs); + $col = &ui_select("log", $selected_log, \@logs, 5, 1); print &ui_columns_row([ "$icons{LOG}{IMAGE}$text{'edit_flowstat_log'}", $col ], \@tds); - $col = &ui_select("type", $type, \@types); + $col = &ui_select("type", $type, \@items_type); print &ui_columns_row([ "$icons{OPTION}{IMAGE}$text{'edit_flowstat_type'}", $col ], \@tds); - $col = &ui_select("max", $max, \@maxs); - $col .= "$text{flowstat_max_help}"; - print &ui_columns_row([ "$icons{RATELIMIT}{IMAGE}$text{'edit_flowstat_max'}", $col ], \@tds); $col = &ui_select("top", $top, \@tops); print &ui_columns_row([ "$icons{FLOWSTAT}{IMAGE}$text{'edit_flowstat_top'}", $col ], \@tds); - $col = &ui_textbox("string", $string, 60, 0, 60); - print &ui_columns_row([ "$icons{TARGET}{IMAGE}$text{'edit_flowstat_string'}", $col ], \@tds); + + my @opts = ( [ 0, "$text{NO}
" ], [ 1, "$text{YES}" ] ); + $col = &ui_radio("is_target", $is_target ? 1 : 0, \@opts); + $col .= "  where  "; + $col .= &ui_select("target_type", $target_type, \@items_type); + $col .= " "; + $col .= &ui_select("target_op", $target_op, \@items_target_op); + $col .= " "; + $col .= &ui_textbox("target", $target, 60, 0, 60); + print &ui_columns_row([ "$icons{TARGET}{IMAGE}$text{'edit_flowstat_target'}", $col ], \@tds); + print &ui_columns_end(); print ""; diff --git a/src/turtlefirewall/edit_geoip.cgi b/src/turtlefirewall/edit_geoip.cgi index ad5de36..f978cc8 100644 --- a/src/turtlefirewall/edit_geoip.cgi +++ b/src/turtlefirewall/edit_geoip.cgi @@ -3,12 +3,12 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2025 Andrea Frigido # You may distribute under the terms of either the GNU General Public # License #====================================================================== -do 'turtlefirewall-lib.pl'; +require './turtlefirewall-lib.pl'; &ReadParse(); $new = $in{'new'}; diff --git a/src/turtlefirewall/edit_group.cgi b/src/turtlefirewall/edit_group.cgi index 740305c..abb71fc 100644 --- a/src/turtlefirewall/edit_group.cgi +++ b/src/turtlefirewall/edit_group.cgi @@ -3,12 +3,12 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2025 Andrea Frigido # You may distribute under the terms of either the GNU General Public # License #====================================================================== -do 'turtlefirewall-lib.pl'; +require './turtlefirewall-lib.pl'; &ReadParse(); $new = $in{'new'}; diff --git a/src/turtlefirewall/edit_host.cgi b/src/turtlefirewall/edit_host.cgi index 8b3bef9..ca5e23f 100644 --- a/src/turtlefirewall/edit_host.cgi +++ b/src/turtlefirewall/edit_host.cgi @@ -3,12 +3,12 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2025 Andrea Frigido # You may distribute under the terms of either the GNU General Public # License #====================================================================== -do 'turtlefirewall-lib.pl'; +require './turtlefirewall-lib.pl'; &ReadParse(); $new = $in{'new'}; diff --git a/src/turtlefirewall/edit_hostnameset.cgi b/src/turtlefirewall/edit_hostnameset.cgi index 33dca48..7e385e6 100644 --- a/src/turtlefirewall/edit_hostnameset.cgi +++ b/src/turtlefirewall/edit_hostnameset.cgi @@ -3,12 +3,12 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2025 Andrea Frigido # You may distribute under the terms of either the GNU General Public # License #====================================================================== -do 'turtlefirewall-lib.pl'; +require './turtlefirewall-lib.pl'; &ReadParse(); $new = $in{'new'}; diff --git a/src/turtlefirewall/edit_ipset.cgi b/src/turtlefirewall/edit_ipset.cgi index 06d97c2..73a287a 100644 --- a/src/turtlefirewall/edit_ipset.cgi +++ b/src/turtlefirewall/edit_ipset.cgi @@ -3,12 +3,12 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2025 Andrea Frigido # You may distribute under the terms of either the GNU General Public # License #====================================================================== -do 'turtlefirewall-lib.pl'; +require './turtlefirewall-lib.pl'; &ReadParse(); $new = $in{'new'}; diff --git a/src/turtlefirewall/edit_masquerade.cgi b/src/turtlefirewall/edit_masquerade.cgi index 02c255c..cdd4f6d 100644 --- a/src/turtlefirewall/edit_masquerade.cgi +++ b/src/turtlefirewall/edit_masquerade.cgi @@ -3,19 +3,23 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2025 Andrea Frigido # You may distribute under the terms of either the GNU General Public # License #====================================================================== -do 'turtlefirewall-lib.pl'; +require './turtlefirewall-lib.pl'; &ReadParse(); +my $nMasq = $fw->GetMasqueradesCount(); + $new = $in{'new'}; if( $new ) { $heading = "$icons{CREATE}{IMAGE}$text{'edit_masq_title_create'}"; - $idx = ''; + $nMasq++; + $idx = $nMasq; + $newIdx = ''; $src = ''; $dst = ''; $service = ''; @@ -25,6 +29,7 @@ if( $new ) { } else { $heading = "$icons{EDIT}{IMAGE}$text{'edit_masq_title_edit'}"; $idx = $in{'idx'}; + $newIdx = ''; %masq = $fw->GetMasquerade($idx); $src = $masq{'SRC'}; $dst = $masq{'DST'}; @@ -35,6 +40,9 @@ if( $new ) { } &ui_print_header( $heading, $text{'title'}, "" ); +my @idxs = (); +for( my $i=1; $i<=$nMasq; $i++ ) { push @idxs, $i; } + my @items_src = ('*'); push @items_src, grep(!/FIREWALL/, $fw->GetZoneList()); push @items_src, $fw->GetNetList(); @@ -59,10 +67,8 @@ print &ui_hidden("idx", $idx); my @tds = ( "width=20%", "width=80%" ); print &ui_columns_start(undef, 100, 0, \@tds); my $col = ''; -if( !$new ) { - $col = "$idx"; - print &ui_columns_row([ "$icons{ID}{IMAGE}ID", $col ], \@tds); -} +$col = &ui_select("newIdx", $idx, \@idxs); +print &ui_columns_row([ "$icons{ID}{IMAGE}ID", $col ], \@tds); $col = &ui_select("src", $src, \@items_src); print &ui_columns_row([ "$icons{ZONE}{IMAGE}$text{'masq_src'}", $col ], \@tds); $col = &ui_select("dst", $dst, \@items_dst); @@ -88,4 +94,4 @@ print "
"; print &ui_form_end(); print "

"; -&ui_print_footer('list_nat.cgi','NAT list'); +&ui_print_footer("list_nat.cgi?table=masquerade&idx=$idx",'NAT list'); diff --git a/src/turtlefirewall/edit_nat.cgi b/src/turtlefirewall/edit_nat.cgi index 83fdb3b..efec025 100644 --- a/src/turtlefirewall/edit_nat.cgi +++ b/src/turtlefirewall/edit_nat.cgi @@ -3,19 +3,23 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2025 Andrea Frigido # You may distribute under the terms of either the GNU General Public # License #====================================================================== -do 'turtlefirewall-lib.pl'; +require './turtlefirewall-lib.pl'; &ReadParse(); +$nNat = $fw->GetNatsCount(); + $new = $in{'new'}; if( $new ) { $heading = "$icons{CREATE}{IMAGE}$text{'edit_nat_title_create'}"; - $idx = ''; + $nNat++; + $idx = $nNat; + $newIdx = ''; $virtual = ''; $real = ''; $service = ''; @@ -25,6 +29,7 @@ if( $new ) { } else { $heading = "$icons{EDIT}{IMAGE}$text{'edit_nat_title_edit'}"; $idx = $in{'idx'}; + $newIdx = ''; %nat = $fw->GetNat($idx); $virtual = $nat{'VIRTUAL'}; $real = $nat{'REAL'}; @@ -35,14 +40,17 @@ if( $new ) { } &ui_print_header( $heading, $text{'title'}, "" ); +my @idxs = (); +for( my $i=1; $i<=$nNat; $i++ ) { push @idxs, $i; } + my @items_virtual = (); my @virtuals = (); push @virtuals, grep(!/FIREWALL/, $fw->GetZoneList()); push @virtuals, $fw->GetHostList(); -for my $k (@virtuals) { +for my $k (sort @virtuals) { my @opts = (); my %zone = $fw->GetZone($k); - if( $zone{IF} ne '' ) { + if( $zone{IF} ne '' ) { @opts = ( "$k", "$k ($zone{IF})" ); } else { @opts = ( "$k", "$k" ); @@ -59,10 +67,8 @@ print &ui_hidden("idx", $idx); my @tds = ( "width=20%", "width=80%" ); print &ui_columns_start(undef, 100, 0, \@tds); my $col = ''; -if( !$new ) { - $col = "$idx"; - print &ui_columns_row([ "$icons{ID}{IMAGE}ID", $col ], \@tds); -} +$col = &ui_select("newIdx", $idx, \@idxs); +print &ui_columns_row([ "$icons{ID}{IMAGE}ID", $col ], \@tds); $col = &ui_select("virtual", $virtual, \@items_virtual); print &ui_columns_row([ "$icons{ZONE}{IMAGE}$text{'virtual_host'}", $col ], \@tds); $col = &ui_select("real", $real, \@items_real); @@ -90,4 +96,4 @@ print ""; print &ui_form_end(); print "

"; -&ui_print_footer('list_nat.cgi','NAT list'); +&ui_print_footer("list_nat.cgi?table=nat&idx=$idx",'NAT list'); diff --git a/src/turtlefirewall/edit_net.cgi b/src/turtlefirewall/edit_net.cgi index ed5dd05..22b38dd 100644 --- a/src/turtlefirewall/edit_net.cgi +++ b/src/turtlefirewall/edit_net.cgi @@ -3,12 +3,12 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2025 Andrea Frigido # You may distribute under the terms of either the GNU General Public # License #====================================================================== -do 'turtlefirewall-lib.pl'; +require './turtlefirewall-lib.pl'; &ReadParse(); $new = $in{'new'}; diff --git a/src/turtlefirewall/edit_options.cgi b/src/turtlefirewall/edit_options.cgi index cfe06f0..0cf22a2 100644 --- a/src/turtlefirewall/edit_options.cgi +++ b/src/turtlefirewall/edit_options.cgi @@ -3,12 +3,12 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2025 Andrea Frigido # You may distribute under the terms of either the GNU General Public # License #====================================================================== -do 'turtlefirewall-lib.pl'; +require './turtlefirewall-lib.pl'; &ui_print_header( "$icons{EDIT}{IMAGE}$text{'edit_options_title'}", $text{'title'}, "" ); diff --git a/src/turtlefirewall/edit_ratelimit.cgi b/src/turtlefirewall/edit_ratelimit.cgi index 57f1680..db0833e 100644 --- a/src/turtlefirewall/edit_ratelimit.cgi +++ b/src/turtlefirewall/edit_ratelimit.cgi @@ -3,12 +3,12 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2025 Andrea Frigido # You may distribute under the terms of either the GNU General Public # License #====================================================================== -do 'turtlefirewall-lib.pl'; +require './turtlefirewall-lib.pl'; &ReadParse(); $new = $in{'new'}; diff --git a/src/turtlefirewall/edit_redirect.cgi b/src/turtlefirewall/edit_redirect.cgi index 4d4bbd6..1efecc8 100644 --- a/src/turtlefirewall/edit_redirect.cgi +++ b/src/turtlefirewall/edit_redirect.cgi @@ -3,19 +3,23 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2025 Andrea Frigido # You may distribute under the terms of either the GNU General Public # License #====================================================================== -do 'turtlefirewall-lib.pl'; +require './turtlefirewall-lib.pl'; &ReadParse(); +my $nRedirect = $fw->GetRedirectCount(); + $new = $in{'new'}; if( $new ) { $heading = "$icons{CREATE}{IMAGE}$text{'edit_redirect_title_create'}"; - $idx = ''; + $nRedirect++; + $idx = $nRedirect; + $newIdx = ''; $src = ''; $dst = ''; $service = ''; @@ -26,6 +30,7 @@ if( $new ) { } else { $heading = "$icons{EDIT}{IMAGE}$text{'edit_redirect_title_edit'}"; $idx = $in{'idx'}; + $newIdx = ''; %redirect = $fw->GetRedirect($idx); $src = $redirect{'SRC'}; $dst = $redirect{'DST'}; @@ -37,6 +42,9 @@ if( $new ) { } &ui_print_header( $heading, $text{'title'}, "" ); +my @idxs = (); +for( my $i=1; $i<=$nRedirect; $i++ ) { push @idxs, $i; } + my @items_src = (); push @items_src, grep(!/FIREWALL/, $fw->GetZoneList()); push @items_src, $fw->GetNetList(); @@ -62,10 +70,8 @@ print &ui_hidden("idx", $idx); my @tds = ( "width=20%", "width=80%" ); print &ui_columns_start(undef, 100, 0, \@tds); my $col = ''; -if( !$new ) { - $col = "$idx"; - print &ui_columns_row([ "$icons{ID}{IMAGE}ID", $col ], \@tds); -} +$col = &ui_select("newIdx", $idx, \@idxs); +print &ui_columns_row([ "$icons{ID}{IMAGE}ID", $col ], \@tds); $col = &ui_select("src", $src, \@items_src); print &ui_columns_row([ "$icons{ZONE}{IMAGE}$text{'redirect_src'}", $col ], \@tds); $col = &ui_select("dst", $dst, \@items_dst); @@ -94,4 +100,4 @@ print ""; print &ui_form_end(); print "

"; -&ui_print_footer('list_nat.cgi','NAT list'); +&ui_print_footer("list_nat.cgi?table=redirect&idx=$idx",'NAT list'); diff --git a/src/turtlefirewall/edit_riskset.cgi b/src/turtlefirewall/edit_riskset.cgi index 6a410e4..8de0c0b 100644 --- a/src/turtlefirewall/edit_riskset.cgi +++ b/src/turtlefirewall/edit_riskset.cgi @@ -3,12 +3,12 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2025 Andrea Frigido # You may distribute under the terms of either the GNU General Public # License #====================================================================== -do 'turtlefirewall-lib.pl'; +require './turtlefirewall-lib.pl'; &ReadParse(); $new = $in{'new'}; diff --git a/src/turtlefirewall/edit_rule.cgi b/src/turtlefirewall/edit_rule.cgi index 46f0004..c561207 100644 --- a/src/turtlefirewall/edit_rule.cgi +++ b/src/turtlefirewall/edit_rule.cgi @@ -3,19 +3,23 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2025 Andrea Frigido # You may distribute under the terms of either the GNU General Public # License #====================================================================== -do 'turtlefirewall-lib.pl'; +require './turtlefirewall-lib.pl'; &ReadParse(); +my $nRules = $fw->GetRulesCount(); + $new = $in{'new'}; if( $new ) { $heading = "$icons{CREATE}{IMAGE}$text{'edit_rule_title_create'}"; - $idx = ''; + $nRules++; + $idx = $nRules; + $newIdx = ''; $src = ''; $dst = ''; $service = ''; @@ -33,6 +37,7 @@ if( $new ) { } else { $heading = "$icons{EDIT}{IMAGE}$text{'edit_rule_title_edit'}"; $idx = $in{'idx'}; + $newIdx = ''; %rule = $fw->GetRule($idx); $src = $rule{'SRC'}; $dst = $rule{'DST'}; @@ -51,6 +56,9 @@ if( $new ) { } &ui_print_header( $heading, $text{'title'}, "" ); +my @idxs = (); +for( my $i=1; $i<=$nRules; $i++ ) { push @idxs, $i; } + my @selected_src = split(/,/, $src); my @selected_dst = split(/,/, $dst); my @items = ('*'); @@ -87,10 +95,8 @@ print &ui_hidden("idx", $idx); my @tds = ( "width=20%", "width=80%" ); print &ui_columns_start(undef, 100, 0, \@tds); my $col = ''; -if( !$new ) { - $col = "$idx"; - print &ui_columns_row([ "$icons{ID}{IMAGE}ID", $col ], \@tds); -} +$col = &ui_select("newIdx", $idx, \@idxs); +print &ui_columns_row([ "$icons{ID}{IMAGE}ID", $col ], \@tds); $col = &ui_select("src", \@selected_src, \@items, 5, 1); print &ui_columns_row([ "$icons{ZONE}{IMAGE}$text{'rule_src'}", $col ], \@tds); $col = &ui_select("dst", \@selected_dst, \@items, 5, 1); diff --git a/src/turtlefirewall/edit_time.cgi b/src/turtlefirewall/edit_time.cgi index e24aa8a..af9da72 100644 --- a/src/turtlefirewall/edit_time.cgi +++ b/src/turtlefirewall/edit_time.cgi @@ -3,12 +3,12 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2025 Andrea Frigido # You may distribute under the terms of either the GNU General Public # License #====================================================================== -do 'turtlefirewall-lib.pl'; +require './turtlefirewall-lib.pl'; &ReadParse(); $new = $in{'new'}; diff --git a/src/turtlefirewall/edit_timegroup.cgi b/src/turtlefirewall/edit_timegroup.cgi index 8f59935..790bdc2 100644 --- a/src/turtlefirewall/edit_timegroup.cgi +++ b/src/turtlefirewall/edit_timegroup.cgi @@ -3,12 +3,12 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2025 Andrea Frigido # You may distribute under the terms of either the GNU General Public # License #====================================================================== -do 'turtlefirewall-lib.pl'; +require './turtlefirewall-lib.pl'; &ReadParse(); $new = $in{'new'}; diff --git a/src/turtlefirewall/edit_zone.cgi b/src/turtlefirewall/edit_zone.cgi index 0ec1cd5..3e30c57 100644 --- a/src/turtlefirewall/edit_zone.cgi +++ b/src/turtlefirewall/edit_zone.cgi @@ -3,12 +3,12 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2025 Andrea Frigido # You may distribute under the terms of either the GNU General Public # License #====================================================================== -do 'turtlefirewall-lib.pl'; +require './turtlefirewall-lib.pl'; &ReadParse(); if( $in{'zone'} eq 'FIREWALL' ) { diff --git a/src/turtlefirewall/index.cgi b/src/turtlefirewall/index.cgi index 08cd2de..2b2edbd 100644 --- a/src/turtlefirewall/index.cgi +++ b/src/turtlefirewall/index.cgi @@ -3,12 +3,12 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2025 Andrea Frigido # You may distribute under the terms of either the GNU General Public # License #====================================================================== -do 'turtlefirewall-lib.pl'; +require './turtlefirewall-lib.pl'; &ReadParse(); &ui_print_header( "$icons{SHIELD}{IMAGE} v ".$fw->Version(), $text{'title'}, "", undef, 1, 1, 0, @@ -105,7 +105,7 @@ print ''; print &ui_form_end(); if( $in{showiptfilter} ne '' ) { - print "
+ print "
FILTER
"; print "
";
@@ -116,7 +116,7 @@ if( $in{showiptfilter} ne '' ) {
 }
 
 if( $in{showiptnat} ne '' ) {
-	print "
+ print "
NAT
"; print "
";
@@ -127,7 +127,7 @@ if( $in{showiptnat} ne '' ) {
 }
 
 if( $in{showiptmangle} ne '' ) {
-	print "
+ print "
MANGLE
"; print "
";
@@ -138,7 +138,7 @@ if( $in{showiptmangle} ne '' ) {
 }
 
 if( $in{showiptraw} ne '' ) {
-	print "
+ print "
RAW
"; print "
";
@@ -149,7 +149,7 @@ if( $in{showiptraw} ne '' ) {
 }
 
 if( $in{showconntrack} ne '' ) {
-	print "
+ print "
CONNTRACK
"; print "
";
@@ -159,7 +159,7 @@ if( $in{showconntrack} ne '' ) {
 }
 
 if( $in{flushconntrack} ne '' ) {
-	print "
+ print "
CONNTRACK
"; print "
";
diff --git a/src/turtlefirewall/install_check.pl b/src/turtlefirewall/install_check.pl
index fee82ae..03d7923 100644
--- a/src/turtlefirewall/install_check.pl
+++ b/src/turtlefirewall/install_check.pl
@@ -1,6 +1,6 @@
 # install_check.pl
 
-do 'turtlefirewall-lib.pl';
+require './turtlefirewall-lib.pl';
 
 # is_installed(mode)
 # For mode 1, returns 2 if the server is installed and configured for use by
diff --git a/src/turtlefirewall/lang/de b/src/turtlefirewall/lang/de
index 9cf538e..6ab343c 100644
--- a/src/turtlefirewall/lang/de
+++ b/src/turtlefirewall/lang/de
@@ -190,26 +190,36 @@ host_help=Note: not required for mac only host
 zone_help=Note: range eg. ppp0-ppp10 or ppp+
 port_help=Note: range eg. 6000:6010
 log_help=Note: target accept logs flow, target drop/reject logs action
-flowstat_max_help=Note: analysing all flows is resource intensive
 preroute_help=Note: zone as destination invalid during prerouting
 log_update=Aktualisieren
 log_title=Action Log
 flowlog_title=Flow Log
 report_flowstat_title=Flow Statistics Report
-flowstat_type_source=Top Sources
-flowstat_type_destination=Top Destinations
-flowstat_type_dport=Top Destination Ports
-flowstat_type_protocol=Top Protocols
-flowstat_type_hostname=Top Hostnames
-flowstat_type_risk=Top Risks
+flowstat_type_source_desc=Top Sources
+flowstat_type_destination_desc=Top Destinations
+flowstat_type_dport_desc=Top Ports
+flowstat_type_protocol_desc=Top Protocols
+flowstat_type_hostname_desc=Top Hostnames
+flowstat_type_risk_desc=Top Risks
+flowstat_type_source_name=Source
+flowstat_type_destination_name=Destination
+flowstat_type_dport_name=Port
+flowstat_type_protocol_name=Protocol
+flowstat_type_hostname_name=Hostname
+flowstat_type_risk_name=Risk
 flowstat_percent=Percentage
 flowstat_traffic=Traffic
+sql_operator_equal_desc=is equal to
+sql_operator_like_desc=contains
 edit_flowstat_title_create=Create Flow Statistics Report
 edit_flowstat_log=Log
 edit_flowstat_type=Type
 edit_flowstat_max=Max Flows
-edit_flowstat_top=Display the Top
-edit_flowstat_string=Only Flows that Contain
+edit_flowstat_top=Top
+edit_flowstat_target=Target
+item_ip_blacklist_desc=IP Address
+item_domain_blacklist_desc=DNS Domain Name
+item_sha1_blacklist_desc=SSL Certificate Fingerprint
 edit_options_title=Edit Options
 options_rp_filter_name=rp_filter
 options_rp_filter_desc=Route überprüfen: discarding packets received on an interface which does not expect to those handle traffic from the given source address. Wenn Sie VPN verwenden, müssen Sie diese Option deaktivieren.
@@ -233,12 +243,12 @@ options_drop_ip_blacklist_name=drop_ip_blacklist
 options_drop_ip_blacklist_desc=Drop IP blacklist ( globally )
 options_drop_domain_blacklist_name=drop_domain_blacklist
 options_drop_domain_blacklist_desc=Drop domain blacklist ( globally )
-options_drop_ja3_blacklist_name=drop_ja3_blacklist
-options_drop_ja3_blacklist_desc=Drop ja3 blacklist - SSL handshake fingerprint ( globally )
 options_drop_sha1_blacklist_name=drop_sha1_blacklist
 options_drop_sha1_blacklist_desc=Drop sha1 blacklist - SSL certificate fingerprint ( globally )
 options_nf_conntrack_max_name=nf_conntrack_max
 options_nf_conntrack_max_desc=Maximum number of sessions in conntrack table.
+options_clamp_mss_to_pmtu_name=clamp_mss_to_pmtu
+options_clamp_mss_to_pmtu_desc=Automatically set MSS for TCP SYN packets outgoing on any ppp interface.
 options_log_limit_name=log_limit
 options_log_limit_desc=Maximum average matching rate: number of logs per hour.
 options_log_limit_burst_name=log_limit_burst
@@ -421,9 +431,8 @@ save_rule_error1=Invalid port (1-65535) or port range (1-65535:1-65535).
 save_rule_error2=port is valid only for tcp and udp services.
 save_rule_error3=source and destination cannot both be "FIREWALL".
 save_rule_error4=source and destination are required.
-save_rule_error5=All nDPI Services, Hostname and Risk, only valid for DROP or REJECT target.
-save_rule_error6=Rate only valid for DROP target.
-save_rule_error7=Log not valid for Rate Limit.
+save_rule_error5=Rate only valid for DROP target.
+save_rule_error6=Log not valid for Rate Limit.
 
 save_connmark_error_title1=Fail to delete Connmark Rule
 save_connmark_error_title2=Fail to create new Connmark Rule
@@ -448,3 +457,5 @@ save_conntrack_error9=irc helper only supports tcp.
 save_conntrack_error10=sane helper only supports tcp.
 save_conntrack_error11=snmp helper only supports udp.
 save_conntrack_error12=netbios-ns helper only supports udp.
+
+list_flowstat_error1=target is required.
diff --git a/src/turtlefirewall/lang/en b/src/turtlefirewall/lang/en
index 732a6c7..8b6e72b 100644
--- a/src/turtlefirewall/lang/en
+++ b/src/turtlefirewall/lang/en
@@ -190,26 +190,36 @@ host_help=Note: not required for mac only host
 zone_help=Note: range eg. ppp0-ppp10 or ppp+
 port_help=Note: range eg. 6000:6010
 log_help=Note: target accept logs flow, target drop/reject logs action
-flowstat_max_help=Note: analysing all flows is resource intensive
 preroute_help=Note: zone as destination invalid during prerouting
 log_update=Refresh
 log_title=Action Log
 flowlog_title=Flow Log
 report_flowstat_title=Flow Statistics Report
-flowstat_type_source=Top Sources
-flowstat_type_destination=Top Destinations
-flowstat_type_dport=Top Destination Ports
-flowstat_type_protocol=Top Protocols
-flowstat_type_hostname=Top Hostnames
-flowstat_type_risk=Top Risks
+flowstat_type_source_desc=Top Sources
+flowstat_type_destination_desc=Top Destinations
+flowstat_type_dport_desc=Top Ports
+flowstat_type_protocol_desc=Top Protocols
+flowstat_type_hostname_desc=Top Hostnames
+flowstat_type_risk_desc=Top Risks
+flowstat_type_source_name=Source
+flowstat_type_destination_name=Destination
+flowstat_type_dport_name=Port
+flowstat_type_protocol_name=Protocol
+flowstat_type_hostname_name=Hostname
+flowstat_type_risk_name=Risk
 flowstat_percent=Percentage
 flowstat_traffic=Traffic
+sql_operator_equal_desc=is equal to
+sql_operator_like_desc=contains
 edit_flowstat_title_create=Create Flow Statistics Report
 edit_flowstat_log=Log
 edit_flowstat_type=Type
 edit_flowstat_max=Max Flows
-edit_flowstat_top=Display the Top
-edit_flowstat_string=Only Flows that Contain
+edit_flowstat_top=Top
+edit_flowstat_target=Target
+item_ip_blacklist_desc=IP Address
+item_domain_blacklist_desc=DNS Domain Name
+item_sha1_blacklist_desc=SSL Certificate Fingerprint
 edit_options_title=Edit Options
 options_rp_filter_name=rp_filter
 options_rp_filter_desc=Route verification: discarding packets received on an interface which does not expect to handle traffic from the given source address. If you are using VPN you need to disable this option.
@@ -233,12 +243,12 @@ options_drop_ip_blacklist_name=drop_ip_blacklist
 options_drop_ip_blacklist_desc=Drop IP blacklist ( globally )
 options_drop_domain_blacklist_name=drop_domain_blacklist
 options_drop_domain_blacklist_desc=Drop domain blacklist ( globally )
-options_drop_ja3_blacklist_name=drop_ja3_blacklist
-options_drop_ja3_blacklist_desc=Drop ja3 blacklist - SSL handshake fingerprint ( globally )
 options_drop_sha1_blacklist_name=drop_sha1_blacklist
 options_drop_sha1_blacklist_desc=Drop sha1 blacklist - SSL certificate fingerprint ( globally )
 options_nf_conntrack_max_name=nf_conntrack_max
 options_nf_conntrack_max_desc=Maximum number of sessions in conntrack table.
+options_clamp_mss_to_pmtu_name=clamp_mss_to_pmtu
+options_clamp_mss_to_pmtu_desc=Automatically set MSS for TCP SYN packets outgoing on any ppp interface.
 options_log_limit_name=log_limit
 options_log_limit_desc=Maximum average matching rate: number of logs per hour.
 options_log_limit_burst_name=log_limit_burst
@@ -421,9 +431,8 @@ save_rule_error1=Invalid port (1-65535) or port range (1-65535:1-65535).
 save_rule_error2=port is valid only for tcp and udp services.
 save_rule_error3=source and destination cannot both be "FIREWALL".
 save_rule_error4=source and destination are required.
-save_rule_error5=All nDPI Services, Hostname and Risk, only valid for DROP or REJECT target.
-save_rule_error6=Rate only valid for DROP target.
-save_rule_error7=Log not valid for Rate Limit.
+save_rule_error5=Rate only valid for DROP target.
+save_rule_error6=Log not valid for Rate Limit.
 
 save_connmark_error_title1=Fail to delete Connmark Rule
 save_connmark_error_title2=Fail to create new Connmark Rule
@@ -448,3 +457,5 @@ save_conntrack_error9=irc helper only supports tcp.
 save_conntrack_error10=sane helper only supports tcp.
 save_conntrack_error11=snmp helper only supports udp.
 save_conntrack_error12=netbios-ns helper only supports udp.
+
+list_flowstat_error1=target is required.
diff --git a/src/turtlefirewall/lang/fr b/src/turtlefirewall/lang/fr
index 5284e63..32783a0 100644
--- a/src/turtlefirewall/lang/fr
+++ b/src/turtlefirewall/lang/fr
@@ -190,26 +190,36 @@ host_help=Note: not required for mac only host
 zone_help=Note: range eg. ppp0-ppp10 or ppp+
 port_help=Note: range eg. 6000:6010
 log_help=Note: target accept logs flow, target drop/reject logs action
-flowstat_max_help=Note: analysing all flows is resource intensive
 preroute_help=Note: zone as destination invalid during prerouting
 log_update=Refresh
 log_title=Action Log
 flowlog_title=Flow Log
 report_flowstat_title=Flow Statistics Report
-flowstat_type_source=Top Sources
-flowstat_type_destination=Top Destinations
-flowstat_type_dport=Top Destination Ports
-flowstat_type_protocol=Top Protocols
-flowstat_type_hostname=Top Hostnames
-flowstat_type_risk=Top Risks
+flowstat_type_source_desc=Top Sources
+flowstat_type_destination_desc=Top Destinations
+flowstat_type_dport_desc=Top Ports
+flowstat_type_protocol_desc=Top Protocols
+flowstat_type_hostname_desc=Top Hostnames
+flowstat_type_risk_desc=Top Risks
+flowstat_type_source_name=Source
+flowstat_type_destination_name=Destination
+flowstat_type_dport_name=Port
+flowstat_type_protocol_name=Protocol
+flowstat_type_hostname_name=Hostname
+flowstat_type_risk_name=Risk
 flowstat_percent=Percentage
 flowstat_traffic=Traffic
+sql_operator_equal_desc=is equal to
+sql_operator_like_desc=contains
 edit_flowstat_title_create=Create Flow Statistics Report
 edit_flowstat_log=Log
 edit_flowstat_type=Type
 edit_flowstat_max=Max Flows
-edit_flowstat_top=Display the Top
-edit_flowstat_string=Only Flows that Contain
+edit_flowstat_top=Top
+edit_flowstat_target=Target
+item_ip_blacklist_desc=IP Address
+item_domain_blacklist_desc=DNS Domain Name
+item_sha1_blacklist_desc=SSL Certificate Fingerprint
 edit_options_title=Edit Options
 options_rp_filter_name=rp_filter
 options_rp_filter_desc=Route verification: discarding packets received on an interface which does not expect to handle traffic from the given source address. If you are using VPN you need to disable this option.
@@ -233,12 +243,12 @@ options_drop_ip_blacklist_name=drop_ip_blacklist
 options_drop_ip_blacklist_desc=Drop IP blacklist ( globally )
 options_drop_domain_blacklist_name=drop_domain_blacklist
 options_drop_domain_blacklist_desc=Drop domain blacklist ( globally )
-options_drop_ja3_blacklist_name=drop_ja3_blacklist
-options_drop_ja3_blacklist_desc=Drop ja3 blacklist - SSL handshake fingerprint ( globally )
 options_drop_sha1_blacklist_name=drop_sha1_blacklist
 options_drop_sha1_blacklist_desc=Drop sha1 blacklist - SSL certificate fingerprint ( globally )
 options_nf_conntrack_max_name=nf_conntrack_max
 options_nf_conntrack_max_desc=Maximum number of sessions in conntrack table.
+options_clamp_mss_to_pmtu_name=clamp_mss_to_pmtu
+options_clamp_mss_to_pmtu_desc=Automatically set MSS for TCP SYN packets outgoing on any ppp interface.
 options_log_limit_name=log_limit
 options_log_limit_desc=Maximum average matching rate: number of logs per hour.
 options_log_limit_burst_name=log_limit_burst
@@ -421,9 +431,8 @@ save_rule_error1=Invalid port (1-65535) or port range (1-65535:1-65535).
 save_rule_error2=port is valid only for tcp and udp services.
 save_rule_error3=source and destination cannot both be "FIREWALL".
 save_rule_error4=source and destination are required.
-save_rule_error5=All nDPI Services, Hostname and Risk, only valid for DROP or REJECT target.
-save_rule_error6=Rate only valid for DROP target.
-save_rule_error7=Log not valid for Rate Limit.
+save_rule_error5=Rate only valid for DROP target.
+save_rule_error6=Log not valid for Rate Limit.
 
 save_connmark_error_title1=Fail to delete Connmark Rule
 save_connmark_error_title2=Fail to create new Connmark Rule
@@ -448,3 +457,5 @@ save_conntrack_error9=irc helper only supports tcp.
 save_conntrack_error10=sane helper only supports tcp.
 save_conntrack_error11=snmp helper only supports udp.
 save_conntrack_error12=netbios-ns helper only supports udp.
+
+list_flowstat_error1=target is required.
diff --git a/src/turtlefirewall/lang/it b/src/turtlefirewall/lang/it
index 9e7c5c4..52b7cf3 100644
--- a/src/turtlefirewall/lang/it
+++ b/src/turtlefirewall/lang/it
@@ -190,26 +190,36 @@ host_help=Note: not required for mac only host
 zone_help=Note: range eg. ppp0-ppp10 or ppp+
 port_help=Note: range eg. 6000:6010
 log_help=Note: target accept logs flow, target drop/reject logs action
-flowstat_max_help=Note: analysing all flows is resource intensive
 preroute_help=Note: zone as destination invalid during prerouting
 log_update=Aggiorna
 log_title=Action Log
 flowlog_title=Flow Log
 report_flowstat_title=Flow Statistics Report
-flowstat_type_source=Top Sources
-flowstat_type_destination=Top Destinations
-flowstat_type_dport=Top Destination Ports
-flowstat_type_protocol=Top Protocols
-flowstat_type_hostname=Top Hostnames
-flowstat_type_risk=Top Risks
+flowstat_type_source_desc=Top Sources
+flowstat_type_destination_desc=Top Destinations
+flowstat_type_dport_desc=Top Ports
+flowstat_type_protocol_desc=Top Protocols
+flowstat_type_hostname_desc=Top Hostnames
+flowstat_type_risk_desc=Top Risks
+flowstat_type_source_name=Source
+flowstat_type_destination_name=Destination
+flowstat_type_dport_name=Port
+flowstat_type_protocol_name=Protocol
+flowstat_type_hostname_name=Hostname
+flowstat_type_risk_name=Risk
 flowstat_percent=Percentage
 flowstat_traffic=Traffic
+sql_operator_equal_desc=is equal to
+sql_operator_like_desc=contains
 edit_flowstat_title_create=Create Flow Statistics Report
 edit_flowstat_log=Log
 edit_flowstat_type=Type
 edit_flowstat_max=Max Flows
-edit_flowstat_top=Display the Top
-edit_flowstat_string=Only Flows that Contain
+edit_flowstat_top=Top
+edit_flowstat_target=Target
+item_ip_blacklist_desc=IP Address
+item_domain_blacklist_desc=DNS Domain Name
+item_sha1_blacklist_desc=SSL Certificate Fingerprint
 edit_options_title=Opzioni
 options_rp_filter_name=rp_filter
 options_rp_filter_desc=Blocco dei pacchetti provenienti da interfacce inaspettate, se stai implementando una VPN probabilmente hai bisogno che sia off o unchange.
@@ -233,12 +243,12 @@ options_drop_ip_blacklist_name=drop_ip_blacklist
 options_drop_ip_blacklist_desc=Drop IP blacklist ( globally )
 options_drop_domain_blacklist_name=drop_domain_blacklist
 options_drop_domain_blacklist_desc=Drop domain blacklist ( globally )
-options_drop_ja3_blacklist_name=drop_ja3_blacklist
-options_drop_ja3_blacklist_desc=Drop ja3 blacklist - SSL handshake fingerprint ( globally )
 options_drop_sha1_blacklist_name=drop_sha1_blacklist
 options_drop_sha1_blacklist_desc=Drop sha1 blacklist - SSL certificate fingerprint ( globally )
 options_nf_conntrack_max_name=nf_conntrack_max
 options_nf_conntrack_max_desc=Maximum number of sessions in conntrack table.
+options_clamp_mss_to_pmtu_name=clamp_mss_to_pmtu
+options_clamp_mss_to_pmtu_desc=Automatically set MSS for TCP SYN packets outgoing on any ppp interface.
 options_log_limit_name=log_limit
 options_log_limit_desc=Numero medio di log generati in un ora per una singola catena (zona->zona).
 options_log_limit_burst_name=log_limit_burst
@@ -421,9 +431,8 @@ save_rule_error1=numero porta errato (0-65535 o nessuno).
 save_rule_error2=il valore della porta è valido solo per i servizi tcp e udp.
 save_rule_error3=sorgente e destinazione non possono essere entrambi "FIREWALL".
 save_rule_error4=mark deve essere un numero decimale o esadecimale (es.: 10, 0x0A).
-save_rule_error5=All nDPI Services, Hostname and Risk, only valid for DROP or REJECT target.
-save_rule_error6=Rate only valid for DROP target.
-save_rule_error7=Log not valid for Rate Limit.
+save_rule_error5=Rate only valid for DROP target.
+save_rule_error6=Log not valid for Rate Limit.
 
 save_connmark_error_title1=Fail to delete Connmark Rule
 save_connmark_error_title2=Fail to create new Connmark Rule
@@ -448,3 +457,5 @@ save_conntrack_error9=irc helper only supports tcp.
 save_conntrack_error10=sane helper only supports tcp.
 save_conntrack_error11=snmp helper only supports udp.
 save_conntrack_error12=netbios-ns helper only supports udp.
+
+list_flowstat_error1=target is required.
diff --git a/src/turtlefirewall/lang/nl b/src/turtlefirewall/lang/nl
index 7fda1be..841f60e 100644
--- a/src/turtlefirewall/lang/nl
+++ b/src/turtlefirewall/lang/nl
@@ -190,26 +190,36 @@ host_help=Note: not required for mac only host
 zone_help=Note: range eg. ppp0-ppp10 or ppp+
 port_help=Note: range eg. 6000:6010
 log_help=Note: target accept logs flow, target drop/reject logs action
-flowstat_max_help=Note: analysing all flows is resource intensive
 preroute_help=Note: zone as destination invalid during prerouting
 log_update=Refresh
 log_title=Action Log
 flowlog_title=Flow Log
 report_flowstat_title=Flow Statistics Report
-flowstat_type_source=Top Sources
-flowstat_type_destination=Top Destinations
-flowstat_type_dport=Top Destination Ports
-flowstat_type_protocol=Top Protocols
-flowstat_type_hostname=Top Hostnames
-flowstat_type_risk=Top Risks
+flowstat_type_source_desc=Top Sources
+flowstat_type_destination_desc=Top Destinations
+flowstat_type_dport_desc=Top Ports
+flowstat_type_protocol_desc=Top Protocols
+flowstat_type_hostname_desc=Top Hostnames
+flowstat_type_risk_desc=Top Risks
+flowstat_type_source_name=Source
+flowstat_type_destination_name=Destination
+flowstat_type_dport_name=Port
+flowstat_type_protocol_name=Protocol
+flowstat_type_hostname_name=Hostname
+flowstat_type_risk_name=Risk
 flowstat_percent=Percentage
 flowstat_traffic=Traffic
+sql_operator_equal_desc=is equal to
+sql_operator_like_desc=contains
 edit_flowstat_title_create=Create Flow Statistics Report
 edit_flowstat_log=Log
 edit_flowstat_type=Type
 edit_flowstat_max=Max Flows
-edit_flowstat_top=Display the Top
-edit_flowstat_string=Only Flows that Contain
+edit_flowstat_top=Top
+edit_flowstat_target=Target
+item_ip_blacklist_desc=IP Address
+item_domain_blacklist_desc=DNS Domain Name
+item_sha1_blacklist_desc=SSL Certificate Fingerprint
 edit_options_title=Edit Options
 options_rp_filter_name=rp_filter
 options_rp_filter_desc=Route verification: discarding packets received on an interface which does not expect to handle traffic from the given source address. If you are using VPN you need to disable this option.
@@ -233,12 +243,12 @@ options_drop_ip_blacklist_name=drop_ip_blacklist
 options_drop_ip_blacklist_desc=Drop IP blacklist ( globally )
 options_drop_domain_blacklist_name=drop_domain_blacklist
 options_drop_domain_blacklist_desc=Drop domain blacklist ( globally )
-options_drop_ja3_blacklist_name=drop_ja3_blacklist
-options_drop_ja3_blacklist_desc=Drop ja3 blacklist - SSL handshake fingerprint ( globally )
 options_drop_sha1_blacklist_name=drop_sha1_blacklist
 options_drop_sha1_blacklist_desc=Drop sha1 blacklist - SSL certificate fingerprint ( globally )
 options_nf_conntrack_max_name=nf_conntrack_max
 options_nf_conntrack_max_desc=Maximum number of sessions in conntrack table.
+options_clamp_mss_to_pmtu_name=clamp_mss_to_pmtu
+options_clamp_mss_to_pmtu_desc=Automatically set MSS for TCP SYN packets outgoing on any ppp interface.
 options_log_limit_name=log_limit
 options_log_limit_desc=Maximum average matching rate: number of logs per hour.
 options_log_limit_burst_name=log_limit_burst
@@ -421,9 +431,8 @@ save_rule_error1=Invalid port (1-65535) or port range (1-65535:1-65535).
 save_rule_error2=port is valid only for tcp and udp services.
 save_rule_error3=source and destination cannot both be "FIREWALL".
 save_rule_error4=source and destination are required.
-save_rule_error5=All nDPI Services, Hostname and Risk, only valid for DROP or REJECT target.
-save_rule_error6=Rate only valid for DROP target.
-save_rule_error7=Log not valid for Rate Limit.
+save_rule_error5=Rate only valid for DROP target.
+save_rule_error6=Log not valid for Rate Limit.
 
 save_connmark_error_title1=Fail to delete Connmark Rule
 save_connmark_error_title2=Fail to create new Connmark Rule
@@ -448,3 +457,5 @@ save_conntrack_error9=irc helper only supports tcp.
 save_conntrack_error10=sane helper only supports tcp.
 save_conntrack_error11=snmp helper only supports udp.
 save_conntrack_error12=netbios-ns helper only supports udp.
+
+list_flowstat_error1=target is required.
diff --git a/src/turtlefirewall/list_actionlog.cgi b/src/turtlefirewall/list_actionlog.cgi
index 874592d..ac7ac4d 100644
--- a/src/turtlefirewall/list_actionlog.cgi
+++ b/src/turtlefirewall/list_actionlog.cgi
@@ -3,12 +3,12 @@
 #======================================================================
 # Turtle Firewall webmin module
 #
-# Copyright (c) Andrea Frigido
+# Copyright (c) 2001-2025 Andrea Frigido 
 # You may distribute under the terms of either the GNU General Public
 # License
 #======================================================================
 
-do 'turtlefirewall-lib.pl';
+require './turtlefirewall-lib.pl';
 &ReadParse();
 
 &ui_print_header( "$icons{LOG}{IMAGE}$text{'log_title'}", $text{'title'}, "" );
@@ -38,9 +38,8 @@ sub showLog {
 	my %dpt_list = ('*' => undef);
 
 	open( LOG, "<", $SysLogFile );
-	while(  ) {
-		if( $_ =~ /TFW=/ ) {
-			my $l = $_;
+	while (my $l = ) {
+		if( $l =~ /TFW=/ ) {
 
 			my $time = '';
 			my $action = '';
diff --git a/src/turtlefirewall/list_countrycodes.cgi b/src/turtlefirewall/list_countrycodes.cgi
index 06db042..532a17c 100644
--- a/src/turtlefirewall/list_countrycodes.cgi
+++ b/src/turtlefirewall/list_countrycodes.cgi
@@ -3,12 +3,12 @@
 #======================================================================
 # Turtle Firewall webmin module
 #
-# Copyright (c) Andrea Frigido
+# Copyright (c) 2001-2025 Andrea Frigido 
 # You may distribute under the terms of either the GNU General Public
 # License
 #======================================================================
 
-do 'turtlefirewall-lib.pl';
+require './turtlefirewall-lib.pl';
 &ReadParse();
 
 &ui_print_header( "$icons{COUNTRYCODE}{IMAGE}$text{'list_countrycodes_title'}", $text{'title'}, "" );
diff --git a/src/turtlefirewall/list_flowlog.cgi b/src/turtlefirewall/list_flowlog.cgi
index bd22829..8d13170 100644
--- a/src/turtlefirewall/list_flowlog.cgi
+++ b/src/turtlefirewall/list_flowlog.cgi
@@ -3,12 +3,12 @@
 #======================================================================
 # Turtle Firewall webmin module
 #
-# Copyright (c) Andrea Frigido
+# Copyright (c) 2001-2025 Andrea Frigido 
 # You may distribute under the terms of either the GNU General Public
 # License
 #======================================================================
 
-do 'turtlefirewall-lib.pl';
+require './turtlefirewall-lib.pl';
 &ReadParse();
 use Time::Piece;
 
@@ -29,39 +29,36 @@ sub showLog {
 	my $pagelen = 20;
 	my @buffer = ();
 
-	#my %l3proto_list = ('*'=>'x');
-	#my %l4proto_list = ('*'=>'x');
-	my %src_list = ('*' => undef);
-	#my %sport_list = ('*'=>'x');
-	#my %dst_list = ('*'=>'x');
-	#my %dport_list = ('*'=>'x');
-	#my %ubytes_list = ('*'=>'x');
-	#my %dbytes_list = ('*'=>'x');
-	#my %upackets_list = ('*'=>'x');
-	#my %dpackets_list = ('*'=>'x');
-	#my %ifindex_list = ('*'=>'x');
-	#my %connmark_list = ('*'=>'x');
-	#my %srcnat_list = ('*'=>'x');
-	#my %dstnat_list = ('*'=>'x');
-	#my %proto_list = ('*'=>'x');
-	#my %host_list = ('*'=>'x');
-	#my %ja4c_list = ('*'=>'x');
-	#my %ja3c_list = ('*'=>'x');
-	#my %tlsfp_list = ('*'=>'x');
-	#my %tlsv_list = ('*'=>'x');
-	#my %risk_list = ('*'=>'x');
+	#my %l3proto_list = ('*' => undef);
+	#my %l4proto_list = ('* '=> undef);
+	my %source_list = ('*' => undef);
+	#my %sport_list = ('*' => undef);
+	#my %destination_list = ('*' => undef);
+	#my %dport_list = ('*' => undef);
+	#my %ubytes_list = ('*' => undef);
+	#my %dbytes_list = ('*' => undef);
+	#my %upackets_list = ('*' => undef);
+	#my %dpackets_list = ('*' => undef);
+	#my %ifindex_list = ('*' => undef);
+	#my %connmark_list = ('*' => undef);
+	#my %srcnat_list = ('*' => undef);
+	#my %dstnat_list = ('*' => undef);
+	#my %protocol_list = ('*' => undef);
+	#my %hostname_list = ('*' => undef);
+	#my %ja4c_list = ('*' => undef);
+	#my %tlsfp_list = ('*' => undef);
+	#my %risk_list = ('*' => undef);
 
 	open( LOG, "<", $FlowLogFile );
-	while(  ) {
-			my $l = $_;
+	while (my $l = ) {
 
 			my $stime = '';
 			my $etime = '';
 			my $l3proto = '';
 			my $l4proto = '';
-			my $src = '';
+			my $source = '';
 			my $sport = '';
-			my $dst = '';
+			my $destination = '';
 			my $dport = '';
 			my $ubytes = '';
 			my $dbytes = '';
@@ -71,12 +68,10 @@ sub showLog {
 			my $connmark = '';
 			my $srcnat = '';
 			my $dstnat = '';
-			my $proto = '';
-			my $host = '';
+			my $protocol = '';
+			my $hostname = '';
 			my $ja4c = '';
-			my $ja3c = '';
 			my $tlsfp = '';
-			my $tlsv = '';
 			my $risk = '';
 
 			if( $l =~ /^(.*?) (.*?) (.*?) (.*?) (.*?) (.*?) (.*?) (.*?) (.*?) (.*?) (.*?) (.*?) (.*?) / ) {
@@ -84,9 +79,9 @@ sub showLog {
 				$etime = $2;
 				$l3proto = $3;
 				$l4proto = $4;
-				$src = $5;
+				$source = $5;
 				$sport = $6;
-				$dst = $7;
+				$destination = $7;
 				$dport = $8;
 				$ubytes = $9;
 				$dbytes = $10;
@@ -98,41 +93,37 @@ sub showLog {
 			if( $l =~ /CM=(.*?)( |$)/ ) { $connmark = $1; }
 			if( $l =~ /SN=(.*?)( |$)/ ) { $srcnat = $1; }
 			if( $l =~ /DN=(.*?)( |$)/ ) { $dstnat = $1; }
-			if( $l =~ /P=(.*?)( |$)/ ) { $proto = $1; }
-			if( $l =~ /H=(.*?)( |$)/ ) { $host = $1; }
+			if( $l =~ /P=(.*?)( |$)/ ) { $protocol = $1; }
+			if( $l =~ /H=(.*?)( |$)/ && $l !~ /H=\"(.*?)\"( |$)/ ) { $hostname = $1; }
 			if( $l =~ /c=(.*?)( |$)/ ) { $ja4c = $1; }
-			if( $l =~ /C=(.*?)( |$)/ ) { $ja3c = $1; }
 			if( $l =~ /F=(.*?)( |$)/ ) { $tlsfp = $1; }
-			if( $l =~ /V=(.*?)( |$)/ ) { $tlsv = $1; }
 			if( $l =~ /R=(.*?)( |$)/ ) { $risk = $1; }
 
-			#if( $l3proto ne '' ) {$l3proto_list{$l3proto} = 'x';}
-			#if( $l4proto ne '' ) {$l4proto_list{$l4proto} = 'x';}
-			if( $src ne '' ) {$src_list{$src} = undef;}
-			#if( $sport ne '' ) {$sport_list{$sport} = 'x';}
-			#if( $dst ne '' ) {$dst_list{$dst} = 'x';}
-			#if( $dport ne '' ) {$dport_list{$dport} = 'x';}
-			#if( $ubytes ne '' ) {$ubytes_list{$ubytes} = 'x';}
-			#if( $dbytes ne '' ) {$dbytes_list{$dbytes} = 'x';}
-			#if( $upackets ne '' ) {$upackets_list{$upackets} = 'x';}
-			#if( $dpackets ne '' ) {$dpackets_list{$dpackets} = 'x';}
-			#if( $ifindex ne '' ) {$ifindex_list{$ifindex} = 'x';}
-			#if( $connmark ne '' ) {$connmark_list{$connmark} = 'x';}
-			#if( $srcnat ne '' ) {$srcnat_list{$srcnat} = 'x';}
-			#if( $dstnat ne '' ) {$dstnat_list{$dstnat} = 'x';}
-			#if( $proto ne '') {$proto_list{$proto} = 'x';}
-			#if( $host ne '') {$host_list{$host} = 'x';}
-			#if( $ja4c ne '') {$ja4c_list{$ja4c} = 'x';}
-			#if( $ja3c ne '') {$ja3c_list{$ja3c} = 'x';}
-			#if( $tlsfp ne '') {$tlsfp_list{$tlsfp} = 'x';}
-			#if( $tlsv ne '') {$tlsv_list{$tlsv} = 'x';}
-			#if( $risk ne '') {$risk_list{$risk} = 'x';}
+			#if( $l3proto ne '' ) {$l3proto_list{$l3proto} = undef;}
+			#if( $l4proto ne '' ) {$l4proto_list{$l4proto} = undef;}
+			if( $source ne '' ) {$source_list{$source} = undef;}
+			#if( $sport ne '' ) {$sport_list{$sport} = undef;}
+			#if( $destination ne '' ) {$destination_list{$destination} = undef;}
+			#if( $dport ne '' ) {$dport_list{$dport} = undef;}
+			#if( $ubytes ne '' ) {$ubytes_list{$ubytes} = undef;}
+			#if( $dbytes ne '' ) {$dbytes_list{$dbytes} = undef;}
+			#if( $upackets ne '' ) {$upackets_list{$upackets} = undef;}
+			#if( $dpackets ne '' ) {$dpackets_list{$dpackets} = undef;}
+			#if( $ifindex ne '' ) {$ifindex_list{$ifindex} = undef;}
+			#if( $connmark ne '' ) {$connmark_list{$connmark} = undef;}
+			#if( $srcnat ne '' ) {$srcnat_list{$srcnat} = undef;}
+			#if( $dstnat ne '' ) {$dstnat_list{$dstnat} = undef;}
+			#if( $protocol ne '') {$protocol_list{$protocol} = undef;}
+			#if( $hostname ne '') {$hostname_list{$hostname} = undef;}
+			#if( $ja4c ne '') {$ja4c_list{$ja4c} = undef;}
+			#if( $tlsfp ne '') {$tlsfp_list{$tlsfp} = undef;}
+			#if( $risk ne '') {$risk_list{$risk} = undef;}
 
 			if( ($in{l3proto} eq '' || $in{l3proto} eq '*' || $in{l3proto} eq $l3proto) &&
 			    ($in{l4proto} eq '' || $in{l4proto} eq '*' || $in{l4proto} eq $l4proto) &&
-			    ($in{src} eq '' || $in{src} eq '*' || $in{src} eq $src) &&
+			    ($in{source} eq '' || $in{source} eq '*' || $in{source} eq $source) &&
 			    ($in{sport} eq '' || $in{sport} eq '*' || $in{sport} eq $sport) &&
-			    ($in{dst} eq '' || $in{dst} eq '*' || $in{dst} eq $dst) &&
+			    ($in{destination} eq '' || $in{destination} eq '*' || $in{destination} eq $destination) &&
 			    ($in{dport} eq '' || $in{dport} eq '*' || $in{dport} eq $dport) &&
 			    ($in{ubytes} eq '' || $in{ubytes} eq '*' || $in{ubytes} eq $ubytes) &&
 			    ($in{dbytes} eq '' || $in{dbytes} eq '*' || $in{dbytes} eq $dbytes) &&
@@ -142,20 +133,18 @@ sub showLog {
 			    ($in{connmark} eq '' || $in{connmark} eq '*' || $in{connmark} eq $connmark) &&
 			    ($in{srcnat} eq '' || $in{srcnat} eq '*' || $in{srcnat} eq $srcnat) &&
 			    ($in{dstnat} eq '' || $in{dstnat} eq '*' || $in{dstnat} eq $dstnat) &&
-			    ($in{proto} eq '' || $in{proto} eq '*' || $in{proto} eq $proto) &&
-			    ($in{host} eq '' || $in{host} eq '*' || $in{host} eq $host) &&
+			    ($in{protocol} eq '' || $in{protocol} eq '*' || $in{protocol} eq $protocol) &&
+			    ($in{hostname} eq '' || $in{hostname} eq '*' || $in{hostname} eq $hostname) &&
 			    ($in{ja4c} eq '' || $in{ja4c} eq '*' || $in{ja4c} eq $ja4c) &&
-			    ($in{ja3c} eq '' || $in{ja3c} eq '*' || $in{ja3c} eq $ja3c) &&
 			    ($in{tlsfp} eq '' || $in{tlsfp} eq '*' || $in{tlsfp} eq $tlsfp) &&
-			    ($in{tlsv} eq '' || $in{tlsv} eq '*' || $in{tlsv} eq $tlsv) &&
 			    ($in{risk} eq '' || $in{risk} eq '*' || $in{risk} eq $risk) ) {
 				$count++;
 
 				if( $count >= ($pag-1) * $pagelen && $count < $pag * $pagelen) {
-					push @buffer, [$stime, $etime, $l3proto, $l4proto, $src, $sport, $dst, $dport,
+					push @buffer, [$stime, $etime, $l3proto, $l4proto, $source, $sport, $destination, $dport,
 					      		$ubytes, $dbytes, $upackets, $dpackets, $ifindex,
-						       	$connmark, $srcnat, $dstnat, $proto, $host,
-						       	$ja4c, $ja3c, $tlsfp, $tlsv, $risk];
+						       	$connmark, $srcnat, $dstnat, $protocol, $hostname,
+						       	$ja4c, $tlsfp, $risk];
 				}
 			}
 	}
@@ -163,11 +152,11 @@ sub showLog {
 
 	# Pages index
 	my $urlparam = 'stime='.$in{stime}.'&etime='.$in{etime}.'&l3proto='.$in{l3proto}.'&l4proto='.$in{l4proto}.
-			'&src='.$in{src}.'&sport='.$in{sport}.'&dst='.$in{dst}.'&dport='.$in{dport}.'&ubytes='.$in{ubytes}.'&dbytes='.$in{dbytes}.
+			'&source='.$in{source}.'&sport='.$in{sport}.'&destination='.$in{destination}.'&dport='.$in{dport}.'&ubytes='.$in{ubytes}.'&dbytes='.$in{dbytes}.
 			'&upackets='.$in{upackets}.'&dpackets='.$in{dpackets}.'&ifindex='.$in{ifindex}.
 			'&connmark='.$in{connmark}.'&srcnat='.$in{srcnat}.'&dstnat='.$in{dstnat}.
-			'&proto='.$in{proto}.'&host='.$in{host}.'&ja4c='.$in{ja4c}.'&ja3c='.$in{ja3c}.
-			'&tlsfp='.$in{tlsfp}.'&tlsv='.$in{tlsv}.'&risk='.$in{risk};
+			'&protocol='.$in{protocol}.'&hostname='.$in{hostname}.'&ja4c='.$in{ja4c}.
+			'&tlsfp='.$in{tlsfp}.'&risk='.$in{risk};
 	my $pageindex = '';
 	if( $pag > 1 ) {
 		$pageindex .= " << ";
@@ -203,27 +192,27 @@ sub showLog {
 	$hl4proto .= "L4PROTO
"; push(@head, $hl4proto ); - local $hproto; - $hproto .= "ndpiPROTO
"; - push(@head, $hproto ); + local $hprotocol; + $hprotocol .= "L7PROTO
"; + push(@head, $hprotocol ); - local $hhost; - $hhost .= "HOSTNAME
"; - push(@head, $hhost ); + local $hhostname; + $hhostname .= "hostNAME
"; + push(@head, $hhostname ); - local $hsrc; - $hsrc .= "srcADDR
"; - push(@head, $hsrc ); + local $hsource; + $hsource .= "srcADDR
"; + push(@head, $hsource ); local $hsport; $hsport .= "srcPORT
"; push(@head, $hsport ); - local $hdst; - $hdst .= "dstADDR
"; - push(@head, $hdst ); + local $hdestination; + $hdestination .= "dstADDR
"; + push(@head, $hdestination ); local $hdport; $hdport .= "dstPORT
"; @@ -273,18 +262,10 @@ sub showLog { $hja4c .= "ja4cFINGERPRINT
"; push(@head, $hja4c ); - local $hja3c; - $hja3c .= "ja3cFINGERPRINT
"; - push(@head, $hja3c ); - local $htlsfp; $htlsfp .= "tlsFINGERPRINT
"; push(@head, $htlsfp ); - local $htlsv; - $htlsv .= "tlsVERSION
"; - push(@head, $htlsv ); - local $hrisk; $hrisk .= "RISK
"; push(@head, $hrisk ); @@ -311,24 +292,22 @@ sub showLog { "style=white-space:nowrap", "style=white-space:nowrap", "style=white-space:nowrap", - "style=white-space:nowrap", - "style=text-align:center", "style=white-space:nowrap" ); print &ui_columns_start(\@head, 100, 0, \@tds); foreach my $l (@buffer) { local @cols; - my ($stime, $etime, $l3proto, $l4proto, $src, $sport, $dst, $dport, $ubytes, $dbytes, $upackets, $dpackets, $ifindex, - $connmark, $srcnat, $dstnat, $proto, $host, $ja4c, $ja3c, $tlsfp, $tlsv, $risk) = @$l; + my ($stime, $etime, $l3proto, $l4proto, $source, $sport, $destination, $dport, $ubytes, $dbytes, $upackets, $dpackets, $ifindex, + $connmark, $srcnat, $dstnat, $protocol, $hostname, $ja4c, $tlsfp, $risk) = @$l; &showTD(localtime($stime)->strftime('%b %d %X')); &showTD(localtime($etime)->strftime('%b %d %X')); &showTD(&l3protoname($l3proto)); &showTD(&l4protoname($l4proto)); - &showTD($proto); - &showTD($host); - &showTD($src); + &showTD($protocol); + &showTD($hostname); + &showTD($source); &showTD($sport); - &showTD($dst); + &showTD($destination); &showTD($dport); &showTD(&roundbytes($ubytes + $dbytes)); &showTD(&roundbytes($ubytes)); @@ -344,9 +323,7 @@ sub showLog { &showTD($srcnat); &showTD($dstnat); &showTD($ja4c); - &showTD($ja3c); &showTD($tlsfp); - &showTD($tlsv); &showTD(&getrisknames($risk)); print &ui_columns_row(\@cols, \@tds); } diff --git a/src/turtlefirewall/list_flowstat.cgi b/src/turtlefirewall/list_flowstat.cgi index 691e3a9..aeb4acf 100644 --- a/src/turtlefirewall/list_flowstat.cgi +++ b/src/turtlefirewall/list_flowstat.cgi @@ -3,172 +3,143 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2025 Andrea Frigido # You may distribute under the terms of either the GNU General Public # License #====================================================================== -do 'turtlefirewall-lib.pl'; +require './turtlefirewall-lib.pl'; &ReadParse(); use Tie::File; use Time::Piece; -&ui_print_header( "$icons{FLOWSTAT}{IMAGE}$text{'report_flowstat_title'}", $text{'title'}, "" ); - my $log = $in{'log'}; +if( $log =~ /\*/ ) { $log = join("\0", glob("${FlowLogFile}-*")); } +$log =~ s/\0/ UNION ALL select * from /g; +$log = "(select * from $log)"; my $type = $in{'type'}; -my $max = $in{'max'}; my $top = $in{'top'}; -my $string = $in{'string'}; +my $is_target = $in{'is_target'}; +my $target_type = $in{'target_type'}; +my $target_op = $in{'target_op'}; +my $target = $in{'target'}; + +if( $target_op eq 'like' ) { $target = "%$target%"; } + +if( $is_target ) { + if( $target eq '' ) { &error( $text{list_flowstat_error1} ); } +} + +&ui_print_header( "$icons{FLOWSTAT}{IMAGE}$text{'report_flowstat_title'}", $text{'title'}, "" ); if( $type eq 'risk' ) { &LoadNdpiRisks($fw); } +my $logflowtotal = 0; my $flowtotal = 0; -my ($type_list, $flows) = &getflows($log); - -my @stats = &getstats($flowreports{$type}{LOGIDX},$type_list,$flows); +my $logflowcount = 0; +my $flowcount = 0; -&showstats($flowreports{$type}{TXTIDX},$flowreports{$type}{ICOIDX},@stats); +my $firstflowtime = ''; +my $lastflowtime = ''; -&ui_print_footer("edit_flowstat.cgi",'flow statistics'); +my $query = ''; -#============================================================================ +$query = "select count(*) from $log"; +$logflowcount = qx{q -Hp "$query" 2>/dev/null}; +$logflowcount =~ s/\n//; -sub getflows { +$query = "select sum(ubytes+dbytes) from $log"; +$logflowtotal = qx{q -Hp "$query" 2>/dev/null}; +$logflowtotal =~ s/\n//; - my $log = shift; - my %type_list = (); +if( $is_target ) { + $query = "select sum(ubytes+dbytes) from $log where $target_type $target_op '$target'"; + $flowtotal = qx{q -Hp "$query" 2>/dev/null}; + $flowtotal =~ s/\n//; - my @last_log_lines = (); + $query = "select count(*) from $log where $target_type $target_op '$target'"; + $flowcount = qx{q -Hp "$query" 2>/dev/null}; + $flowcount =~ s/\n//; - use Fcntl 'O_RDONLY'; - tie @log_lines, 'Tie::File', $log, mode => O_RDONLY; - if( $max ne 'all' ) { - @last_log_lines = ($max >= @log_lines) ? @log_lines : @log_lines[-$max..-1]; - } else { - @last_log_lines = @log_lines; - } - untie @log_lines; + $query = "select stime from $log where $target_type $target_op '$target' order by stime asc limit 1"; + $firstflowtime = qx{q -Hp "$query" 2>/dev/null}; - my @log_lines = (); + $query = "select etime from $log where $target_type $target_op '$target' order by etime desc limit 1"; + $lastflowtime = qx{q -Hp "$query" 2>/dev/null}; +} else { + $flowtotal = $logflowtotal; + $flowcount = $logflowcount; - if( $string ne '' ) { - @log_lines = grep(/$string/, @last_log_lines); - } else { - @log_lines = @last_log_lines; - } - - my @flows = (); - - foreach my $l (@log_lines) { - - my $stime = ''; - my $etime = ''; - my $l3proto = ''; - my $l4proto = ''; - my $source = ''; - my $sport = ''; - my $destination = ''; - my $dport = ''; - my $ubytes = ''; - my $dbytes = ''; - my $upackets = ''; - my $dpackets = ''; - my $ifindex = ''; - my $connmark = ''; - my $srcnat = ''; - my $dstnat = ''; - my $protocol = ''; - my $hostname = ''; - my $ja4c = ''; - my $ja3c = ''; - my $tlsfp = ''; - my $tlsv = ''; - my $risk = ''; - - if( $l =~ /^(.*?) (.*?) (.*?) (.*?) (.*?) (.*?) (.*?) (.*?) (.*?) (.*?) (.*?) (.*?) (.*?) / ) { - $stime = $1; - $etime = $2; - $l3proto = $3; - $l4proto = $4; - $source = $5; - $sport = $6; - $destination = $7; - $dport = $8; - $ubytes = $9; - $dbytes = $10; - $upackets = $11; - $dpackets = $12; - $ifindex = $13; - } + $query = "select stime from $log order by stime asc limit 1"; + $firstflowtime = qx{q -Hp "$query" 2>/dev/null}; - if( $l =~ /CM=(.*?)( |$)/ ) { $connmark = $1; } - if( $l =~ /SN=(.*?)( |$)/ ) { $srcnat = $1; } - if( $l =~ /DN=(.*?)( |$)/ ) { $dstnat = $1; } - if( $l =~ /P=(.*?)( |$)/ ) { $protocol = $1; } - if( $l =~ /H=(.*?)( |$)/ ) { $hostname = $1; } - if( $l =~ /c=(.*?)( |$)/ ) { $ja4c = $1; } - if( $l =~ /C=(.*?)( |$)/ ) { $ja3c = $1; } - if( $l =~ /F=(.*?)( |$)/ ) { $tlsfp = $1; } - if( $l =~ /V=(.*?)( |$)/ ) { $tlsv = $1; } - if( $l =~ /R=(.*?)( |$)/ ) { $risk = $1; } - - if( $type eq 'source' && $source ne '' ) {$type_list{$source} = '0';} - if( $type eq 'destination' && $destination ne '' ) {$type_list{$destination} = '0';} - if( $type eq 'dport' && $dport ne '' ) {$type_list{$dport} = '0';} - if( $type eq 'protocol' && $protocol ne '') {$type_list{$protocol} = '0';} - if( $type eq 'hostname' && $hostname ne '') {$type_list{$hostname} = '0';} - if( $type eq 'risk' && $risk ne '') {$type_list{$risk} = '0';} - - $flowtotal = ($flowtotal + $ubytes + $dbytes); - - push @flows, [$stime, $etime, $l3proto, $l4proto, $source, $sport, $destination, $dport, - $ubytes, $dbytes, $upackets, $dpackets, $ifindex, - $connmark, $srcnat, $dstnat, $protocol, $hostname, - $ja4c, $ja3c, $tlsfp, $tlsv, $risk]; - } - return (\%type_list, \@flows); + $query = "select etime from $log order by etime desc limit 1"; + $lastflowtime = qx{q -Hp "$query" 2>/dev/null}; } +$firstflowtime =~ s/\n//; +$firstflowtime = localtime($firstflowtime)->strftime('%b %d %X'); + +$lastflowtime =~ s/\n//; +$lastflowtime = localtime($lastflowtime)->strftime('%b %d %X'); + +my @stats = &getstats($log,$type,$top,$is_target,$target_type,$target_op,$target); +my $txtindex = $flowreports{$type}{DESCIDX}; +my $icoindex = $flowreports{$type}{ICOIDX}; + +&showstats($type,$is_target,$target_type,$target_op,$in{'target'},$flowcount,$flowtotal,$logflowcount,$firstflowtime,$lastflowtime,$txtindex,$icoindex,@stats); + +&ui_print_footer("edit_flowstat.cgi",'flow statistics'); + +#============================================================================ + sub getstats { - - my $logindex = shift; - my ($type_list,$flows) = @_; + + my $log = shift; + my $type = shift; + my $top = shift; + my $is_target = shift; + my $target_type = shift; + my $target_op = shift; + my $target = shift; + my $query = ''; my @stats = (); - # Sum bytes per Type - foreach my $f (@{$flows}) { - foreach $t (sort keys %{$type_list}) { - if( $f->[$logindex] eq $t ) { $type_list{$t} = ($type_list{$t} + $f->[8] + $f->[9]); } - } + if( $is_target ) { + $query = "select $type,sum(ubytes+dbytes) from $log where $type != '' and $target_type $target_op '$target' group by $type order by sum(ubytes+dbytes) desc limit $top"; + } else { + $query = "select $type,sum(ubytes+dbytes) from $log where $type != '' group by $type order by sum(ubytes+dbytes) desc limit $top"; } - # Sort Items by bytes - my $count = 0; - foreach $t (sort { $type_list{$b} <=> $type_list{$a} } keys %{$type_list}) { - push(@stats, [$t,$type_list{$t}]); - $count++; - last if($count == $top); + foreach my $l (qx{q -Hp "$query" 2>/dev/null}) { + $l =~ s/\n//; + my @t = split(/\|/, $l); + push(@stats, \@t); } + return @stats; } sub showstats { + my $type = shift; + my $is_target = shift; + my $target_type = shift; + my $target_op = shift; + my $target = shift; + my $flowcount = shift; + my $flowtotal = shift; + my $logflowcount = shift; + my $firstflowtime = shift; + my $lastflowtime = shift; my $txtindex = shift; my $icoindex = shift; my @stats = @_; my $graphwidth = 300; - my $logflowcount = qx{wc -l < $log 2>/dev/null}; - my $flowcount = @flows; - - my $firstflowtime = localtime($flows[0][0])->strftime('%b %d %X'); - my $lastflowtime = localtime($flows[$#flows][1])->strftime('%b %d %X'); - - print "Using $flowcount of $logflowcount flows from $log"; - if( $string ne '' ) { print " containing ".&ui_text_color($string, 'info').""; } + print "Using $flowcount of $logflowcount flows"; + if( $is_target ) { print " where $text{$flowreports{$target_type}{NAMEIDX}} $text{$sqloperators{$target_op}{DESCIDX}} ".&ui_text_color($target, 'info').""; } print " ( $firstflowtime --> $lastflowtime )"; @tds = ( "style=white-space:nowrap", "width=$graphwidth", "", "width=1% style=text-align:right;white-space:nowrap" ); diff --git a/src/turtlefirewall/list_itemreferences.cgi b/src/turtlefirewall/list_itemreferences.cgi index f486154..5136f4c 100644 --- a/src/turtlefirewall/list_itemreferences.cgi +++ b/src/turtlefirewall/list_itemreferences.cgi @@ -3,12 +3,12 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2025 Andrea Frigido # You may distribute under the terms of either the GNU General Public # License #====================================================================== -do 'turtlefirewall-lib.pl'; +require './turtlefirewall-lib.pl'; &ReadParse(); my $item = $in{'item'}; diff --git a/src/turtlefirewall/list_items.cgi b/src/turtlefirewall/list_items.cgi index d24a91f..78af97f 100644 --- a/src/turtlefirewall/list_items.cgi +++ b/src/turtlefirewall/list_items.cgi @@ -3,12 +3,12 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2025 Andrea Frigido # You may distribute under the terms of either the GNU General Public # License #====================================================================== -do 'turtlefirewall-lib.pl'; +require './turtlefirewall-lib.pl'; &ui_print_header( "$icons{SHIELD}{IMAGE}$text{'list_items_title'}", $text{'title'}, "" ); @@ -94,7 +94,7 @@ sub showAddressList { if( $blacklistcount eq '' ) { $blacklistcount = '0'; } push(@cols, $blacklistcount); push(@cols, "$icons{OPTION}{IMAGE}$blacklists{$b}{TYPE}" ); - push(@cols, "$icons{DESCRIPTION}{IMAGE}$blacklists{$b}{DESCRIPTION}"); + push(@cols, "$icons{DESCRIPTION}{IMAGE}$text{$blacklists{$b}{DESCIDX}}"); my $href = &ui_link("edit_options.cgi","".($fw->GetOption("drop_$b") eq 'on' ? "1" : '0').""); push(@cols, $href ); print &ui_checked_columns_row(\@cols, \@tds, "d", $k); @@ -358,7 +358,7 @@ sub showGroup { push(@cols, "$icons{GROUP}{IMAGE}$href" ); my $grouplist; my $type = ''; - for my $item (@{$group{ITEMS}}) { + for my $item (sort @{$group{ITEMS}}) { $type = $fw->GetItemType($item); $grouplist .= "$icons{$type}{IMAGE}$item
"; } @@ -563,7 +563,7 @@ sub showTimeGroup { my $href = &ui_link("edit_timegroup.cgi?timegroup=$k",$k); push(@cols, "$icons{TIMEGROUP}{IMAGE}$href" ); my $timegrouplist; - for my $item (@{$timegroup{ITEMS}}) { + for my $item (sort @{$timegroup{ITEMS}}) { $timegrouplist .= "$icons{TIME}{IMAGE}$item
"; } push(@cols, $timegrouplist ); diff --git a/src/turtlefirewall/list_manglerules.cgi b/src/turtlefirewall/list_manglerules.cgi index 740c746..68e40ea 100644 --- a/src/turtlefirewall/list_manglerules.cgi +++ b/src/turtlefirewall/list_manglerules.cgi @@ -3,12 +3,12 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2025 Andrea Frigido # You may distribute under the terms of either the GNU General Public # License #====================================================================== -do 'turtlefirewall-lib.pl'; +require './turtlefirewall-lib.pl'; &ReadParse(); &ui_print_header( "$icons{MARK}{IMAGE}$text{'list_manglerules_title'}", $text{'title'}, "" ); @@ -57,8 +57,8 @@ sub showConnmarkPreroute { my $nConnmarkPreroutes = $fw->GetConnmarkPreroutesCount(); + my $idx = $in{idx}; if( $in{table} eq 'connmarkpreroute' ) { - my $idx = $in{idx}; if( $in{down} > 0 || $in{up} > 0 ) { my $newIdx = $idx; if( $in{down} > 0 && $idx > 0 && $idx < $nConnmarkPreroutes ) { @@ -79,8 +79,8 @@ sub showConnmarkPreroute { my %attr = $fw->GetConnmarkPreroute($i); local @cols; if( $attr{'TARGET'} eq '' ) { $attr{'TARGET'} = 'ACCEPT'; } - my $bb = $idx == $i ? '' : ''; # BoldBegin - my $be = $idx == $i ? '' : ''; # BoldEnd + my $bb = $idx == $i && $in{table} eq 'connmarkpreroute' ? '' : ''; # BoldBegin + my $be = $idx == $i && $in{table} eq 'connmarkpreroute' ? '' : ''; # BoldEnd my $sb = $attr{'ACTIVE'} eq 'NO' ? '' : ''; # StrikeBegin my $se = $attr{'ACTIVE'} eq 'NO' ? '' : ''; # StrikeEnd my $href = &ui_link("edit_connmarkpreroute.cgi?idx=$i","${sb}${bb}${i}${be}${se}"); @@ -100,7 +100,7 @@ sub showConnmarkPreroute { } else { my @services = split(/,/, $attr{'SERVICE'}); foreach my $s (@services) { - $servicelist .= "$icons{SERVICE}{IMAGE}${s}
"; + $servicelist .= "$icons{SERVICE}{IMAGE}$s
"; } } push(@cols, "${sb}${bb}${servicelist}${be}${se}"); @@ -135,11 +135,6 @@ sub showConnmarkPreroute { push(@cols, "${mimage}${sb}${bb}${cb}".($attr{'MARK'} ne '' ? $attr{'MARK'} : ' ')."${ce}${be}${se}" ); local $mover; $mover .= ""; - # if( $i < $nConnmarkPreroutes-1 ) { - # $mover .= ""; - # } else { - # $mover .= ""; - # } if( $i < $nConnmarkPreroutes ) { $mover .= ""; } - # if( $i > 2 ) { - # $mover .= ""; - # } else { - # $mover .= ""; - # } $mover .= "
V     v @@ -158,11 +153,6 @@ sub showConnmarkPreroute {    A  
"; push(@cols, $mover); print &ui_checked_columns_row(\@cols, \@tds, "d", $i); @@ -208,8 +198,8 @@ sub showConnmark { my $nConnmarks = $fw->GetConnmarksCount(); + my $idx = $in{idx}; if( $in{table} eq 'connmark' ) { - my $idx = $in{idx}; if( $in{down} > 0 || $in{up} > 0 ) { my $newIdx = $idx; if( $in{down} > 0 && $idx > 0 && $idx < $nConnmarks ) { @@ -230,8 +220,8 @@ sub showConnmark { my %attr = $fw->GetConnmark($i); local @cols; if( $attr{'TARGET'} eq '' ) { $attr{'TARGET'} = 'ACCEPT'; } - my $bb = $idx == $i ? '' : ''; # BoldBegin - my $be = $idx == $i ? '' : ''; # BoldEnd + my $bb = $idx == $i && $in{table} eq 'connmark' ? '' : ''; # BoldBegin + my $be = $idx == $i && $in{table} eq 'connmark' ? '' : ''; # BoldEnd my $sb = $attr{'ACTIVE'} eq 'NO' ? '' : ''; # StrikeBegin my $se = $attr{'ACTIVE'} eq 'NO' ? '' : ''; # StrikeEnd my $href = &ui_link("edit_connmark.cgi?idx=$i","${sb}${bb}${i}${be}${se}"); @@ -261,7 +251,7 @@ sub showConnmark { } else { my @services = split(/,/, $attr{'SERVICE'}); foreach my $s (@services) { - $servicelist .= "$icons{SERVICE}{IMAGE}${s}
"; + $servicelist .= "$icons{SERVICE}{IMAGE}$s
"; } } push(@cols, "${sb}${bb}${servicelist}${be}${se}"); @@ -296,11 +286,6 @@ sub showConnmark { push(@cols, "${mimage}${sb}${bb}${cb}".($attr{'MARK'} ne '' ? $attr{'MARK'} : ' ')."${ce}${be}${se}" ); local $mover; $mover .= ""; - # if( $i < $nConnmarks-1 ) { - # $mover .= ""; - # } else { - # $mover .= ""; - # } if( $i < $nConnmarks ) { $mover .= ""; } - # if( $i > 2 ) { - # $mover .= ""; - # } else { - # $mover .= ""; - # } $mover .= "
V     v @@ -319,11 +304,6 @@ sub showConnmark {    A  
"; push(@cols, $mover); print &ui_checked_columns_row(\@cols, \@tds, "d", $i); diff --git a/src/turtlefirewall/list_nat.cgi b/src/turtlefirewall/list_nat.cgi index e79e879..a1ac3af 100644 --- a/src/turtlefirewall/list_nat.cgi +++ b/src/turtlefirewall/list_nat.cgi @@ -3,12 +3,12 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2025 Andrea Frigido # You may distribute under the terms of either the GNU General Public # License #====================================================================== -do 'turtlefirewall-lib.pl'; +require './turtlefirewall-lib.pl'; &ReadParse(); &ui_print_header( "$icons{NAT}{IMAGE}$text{'list_nat_title'}", $text{'title'}, "" ); @@ -54,55 +54,60 @@ sub showNat { $nNat = $fw->GetNatsCount(); + my $idx = $in{idx}; if( $in{table} eq 'nat' ) { - my $idx = $in{idx}; - if( $in{down} ne '' && $idx > 0 && $idx < $nNat ) { - my %appo = $fw->GetNat($idx+1); - $fw->AddNatAttr($idx+1, $fw->GetNat($idx)); - $fw->AddNatAttr($idx, %appo); - } - if( $in{up} ne '' && $idx > 1 && $idx <= $nNat ) { - my %appo = $fw->GetNat($idx-1); - $fw->AddNatAttr($idx-1, $fw->GetNat($idx)); - $fw->AddNatAttr($idx, %appo); + if( $in{down} > 0 || $in{up} > 0 ) { + my $newIdx = $idx; + if( $in{down} > 0 && $idx > 0 && $idx < $nNat ) { + $newIdx = $idx + $in{down}; + if( $newIdx > $nNat ) { $newIdx = $nNat; } + } + if( $in{up} > 0 && $idx > 1 && $idx <= $nNat ) { + $newIdx = $idx - $in{up}; + if( $newIdx < 1 ) { $newIdx = 1; } + } + $fw->MoveNat( $idx, $newIdx ); + $fw->SaveFirewall(); + $idx=$newIdx; } - $fw->SaveFirewall(); } for( my $i=1; $i<=$nNat; $i++ ) { my %attr = $fw->GetNat( $i ); local @cols; + my $bb = $idx == $i && $in{table} eq 'nat' ? '' : ''; # BoldBegin + my $be = $idx == $i && $in{table} eq 'nat'? '' : ''; # BoldEnd my $sb = $attr{'ACTIVE'} eq 'NO' ? '' : ''; # StrikeBegin my $se = $attr{'ACTIVE'} eq 'NO' ? '' : ''; # StrikeEnd - my $href = &ui_link("edit_nat.cgi?idx=$i","${sb}${i}${se}"); + my $href = &ui_link("edit_nat.cgi?idx=$i","${sb}${bb}${i}${be}${se}"); push(@cols, $href ); my %zone = $fw->GetZone($attr{'VIRTUAL'}); if( $zone{IF} ne '' ) { - push(@cols, "$icons{ZONE}{IMAGE}${sb}$attr{'VIRTUAL'} ($zone{'IF'})${se}" ); + push(@cols, "$icons{ZONE}{IMAGE}${sb}${bb}$attr{'VIRTUAL'} ($zone{'IF'})${be}${se}" ); } else { - push(@cols, "$icons{HOST}{IMAGE}${sb}$attr{'VIRTUAL'}${se}" ); + push(@cols, "$icons{HOST}{IMAGE}${sb}${bb}$attr{'VIRTUAL'}${be}${se}" ); } - push(@cols, "$icons{HOST}{IMAGE}${sb}$attr{'REAL'}${se}" ); + push(@cols, "$icons{HOST}{IMAGE}${sb}${bb}$attr{'REAL'}${be}${se}" ); my $servicelist = ''; if( $attr{'SERVICE'} eq 'tcp' || $attr{'SERVICE'} eq 'udp' ) { if( $attr{'PORT'} ne '' ) { $servicelist .= "$icons{SERVICE}{IMAGE}$attr{'SERVICE'}/$attr{'PORT'}"; } else { - $servicelist .= "$icons{SERVICE}{IMAGE}{'SERVICE'}/all"; + $servicelist .= "$icons{SERVICE}{IMAGE}$attr{'SERVICE'}/all"; } } else { my @services = split(/,/, $attr{'SERVICE'}); foreach my $s (@services) { - $servicelist .= "$icons{SERVICE}{IMAGE}${s}
"; + $servicelist .= "$icons{SERVICE}{IMAGE}$s
"; } } - push(@cols, "${sb}${servicelist}${se}"); + push(@cols, "${sb}${bb}${servicelist}${be}${se}"); my $cb = $sb eq '' ? '' : ''; # ColourBegin my $ce = $se eq '' ? '' : ''; # ColourEnd my $nimage = $attr{'ACTIVE'} eq 'NO' ? $icons{NAT}{IMAGE} : $icons{NAT_A}{IMAGE}; - push(@cols, "${nimage}${sb}${cb}$text{YES}${ce}${se}" ); + push(@cols, "${nimage}${sb}${bb}${cb}$text{YES}${ce}${be}${se}" ); my $timage = $attr{'TOPORT'} eq '' ? '' : $icons{TOPORT}{IMAGE}; - push(@cols, "${timage}${sb}$attr{'TOPORT'}${se}" ); + push(@cols, "${timage}${sb}${bb}$attr{'TOPORT'}${be}${se}" ); local $mover; $mover .= ""; @@ -160,33 +165,38 @@ sub showMasquerade { my $nMasq = $fw->GetMasqueradesCount(); + my $idx = $in{idx}; if( $in{table} eq 'masquerade' ) { - my $idx = $in{idx}; - if( $in{down} ne '' && $idx > 0 && $idx < $nMasq ) { - my %appo = $fw->GetMasquerade($idx+1); - $fw->AddMasqueradeAttr($idx+1, $fw->GetMasquerade($idx)); - $fw->AddMasqueradeAttr($idx, %appo); - } - if( $in{up} ne '' && $idx > 1 && $idx <= $nMasq ) { - my %appo = $fw->GetMasquerade($idx-1); - $fw->AddMasqueradeAttr($idx-1, $fw->GetMasquerade($idx)); - $fw->AddMasqueradeAttr($idx, %appo); + if( $in{down} > 0 || $in{up} > 0 ) { + my $newIdx = $idx; + if( $in{down} > 0 && $idx > 0 && $idx < $nMasq ) { + $newIdx = $idx + $in{down}; + if( $newIdx > $nMasq ) { $newIdx = $nMasq; } + } + if( $in{up} > 0 && $idx > 1 && $idx <= $nMasq ) { + $newIdx = $idx - $in{up}; + if( $newIdx < 1 ) { $newIdx = 1; } + } + $fw->MoveMasquerade( $idx, $newIdx ); + $fw->SaveFirewall(); + $idx=$newIdx; } - $fw->SaveFirewall(); - } - + } + for( my $i=1; $i<=$nMasq; $i++ ) { my %attr = $fw->GetMasquerade( $i ); local @cols; + my $bb = $idx == $i && $in{table} eq 'masquerade' ? '' : ''; # BoldBegin + my $be = $idx == $i && $in{table} eq 'masquerade' ? '' : ''; # BoldEnd my $sb = $attr{'ACTIVE'} eq 'NO' ? '' : ''; # StrikeBegin my $se = $attr{'ACTIVE'} eq 'NO' ? '' : ''; # StrikeEnd - my $href = &ui_link("edit_masquerade.cgi?idx=$i","${sb}${i}${se}"); + my $href = &ui_link("edit_masquerade.cgi?idx=$i","${sb}${bb}${i}${be}${se}"); push(@cols, $href ); my $type = ''; $type = $fw->GetItemType($attr{'SRC'}); - push(@cols, "$icons{$type}{IMAGE}${sb}$attr{'SRC'}${se}" ); + push(@cols, "$icons{$type}{IMAGE}${sb}${bb}$attr{'SRC'}${be}${se}" ); $type = $fw->GetItemType($attr{'DST'}); - push(@cols, "$icons{$type}{IMAGE}${sb}$attr{'DST'}${se}" ); + push(@cols, "$icons{$type}{IMAGE}${sb}${bb}$attr{'DST'}${be}${se}" ); my $servicelist = ''; if( $attr{'SERVICE'} eq 'tcp' || $attr{'SERVICE'} eq 'udp' ) { if( $attr{'PORT'} ne '' ) { @@ -197,20 +207,20 @@ sub showMasquerade { } else { my @services = split(/,/, $attr{'SERVICE'}); foreach my $s (@services) { - $servicelist .= "$icons{SERVICE}{IMAGE}${s}
"; + $servicelist .= "$icons{SERVICE}{IMAGE}$s
"; } } - push(@cols, "${sb}${servicelist}${se}"); + push(@cols, "${sb}${bb}${servicelist}${be}${se}"); if( $attr{'MASQUERADE'} eq 'NO' ) { my $cb = $sb eq '' ? '' : ''; # ColourBegin my $ce = $se eq '' ? '' : ''; # ColourEnd my $dimage = $attr{'ACTIVE'} eq 'NO' ? $icons{MASQUERADE}{IMAGE} : $icons{MASQUERADE_NO}{IMAGE}; - push(@cols, "${dimage}${sb}${cb}$text{NO}${ce}${se}" ); + push(@cols, "${dimage}${sb}${bb}${cb}$text{NO}${ce}${be}${se}" ); } else { my $cb = $sb eq '' ? '' : ''; # ColourBegin my $ce = $se eq '' ? '' : ''; # ColourEnd my $aimage = $attr{'ACTIVE'} eq 'NO' ? $icons{MASQUERADE}{IMAGE} : $icons{MASQUERADE_A}{IMAGE}; - push(@cols, "${aimage}${sb}${cb}$text{YES}${ce}${se}" ); + push(@cols, "${aimage}${sb}${bb}${cb}$text{YES}${ce}${be}${se}" ); } local $mover; $mover .= "
"; @@ -269,33 +279,39 @@ sub showRedirect { "$text{'redirect_move'}" ], 100, 0, \@tds); my $nRedirect = $fw->GetRedirectCount(); + + my $idx = $in{idx}; if( $in{table} eq 'redirect' ) { - my $idx = $in{idx}; - if( $in{down} ne '' && $idx > 0 && $idx < $nRedirect ) { - my %appo = $fw->GetRedirect($idx+1); - $fw->AddRedirectAttr($idx+1, $fw->GetRedirect($idx)); - $fw->AddRedirectAttr($idx, %appo); - } - if( $in{up} ne '' && $idx > 1 && $idx <= $nRedirect ) { - my %appo = $fw->GetRedirect($idx-1); - $fw->AddRedirectAttr($idx-1, $fw->GetRedirect($idx)); - $fw->AddRedirectAttr($idx, %appo); + if( $in{down} > 0 || $in{up} > 0 ) { + my $newIdx = $idx; + if( $in{down} > 0 && $idx > 0 && $idx < $nRedirect ) { + $newIdx = $idx + $in{down}; + if( $newIdx > $nRedirect ) { $newIdx = $nRedirect; } + } + if( $in{up} > 0 && $idx > 1 && $idx <= $nRedirect ) { + $newIdx = $idx - $in{up}; + if( $newIdx < 1 ) { $newIdx = 1; } + } + $fw->MoveRedirect( $idx, $newIdx ); + $fw->SaveFirewall(); + $idx=$newIdx; } - $fw->SaveFirewall(); } for( my $i=1; $i<=$nRedirect; $i++ ) { my %attr = $fw->GetRedirect( $i ); local @cols; + my $bb = $idx == $i && $in{table} eq 'redirect' ? '' : ''; # BoldBegin + my $be = $idx == $i && $in{table} eq 'redirect' ? '' : ''; # BoldEnd my $sb = $attr{'ACTIVE'} eq 'NO' ? '' : ''; # StrikeBegin my $se = $attr{'ACTIVE'} eq 'NO' ? '' : ''; # StrikeEnd - my $href = &ui_link("edit_redirect.cgi?idx=$i","${sb}${i}${se}"); + my $href = &ui_link("edit_redirect.cgi?idx=$i","${sb}${bb}${i}${be}${se}"); push(@cols, $href ); my $type = ''; $type = $fw->GetItemType($attr{'SRC'}); - push(@cols, "$icons{$type}{IMAGE}${sb}$attr{'SRC'}${se}" ); + push(@cols, "$icons{$type}{IMAGE}${sb}${bb}$attr{'SRC'}${be}${se}" ); $type = $fw->GetItemType($attr{'DST'}); - push(@cols, "$icons{$type}{IMAGE}${sb}$attr{'DST'}${se}" ); + push(@cols, "$icons{$type}{IMAGE}${sb}${bb}$attr{'DST'}${be}${se}" ); my $servicelist = ''; if( $attr{'SERVICE'} eq 'tcp' || $attr{'SERVICE'} eq 'udp' ) { if( $attr{'PORT'} ne '' ) { @@ -306,23 +322,23 @@ sub showRedirect { } else { my @services = split(/,/, $attr{'SERVICE'}); foreach my $s (@services) { - $servicelist .= "$icons{SERVICE}{IMAGE}${s}
"; + $servicelist .= "$icons{SERVICE}{IMAGE}$s
"; } } - push(@cols, "${sb}${servicelist}${se}"); + push(@cols, "${sb}${bb}${servicelist}${be}${se}"); if( $attr{'REDIRECT'} eq 'NO' ) { my $cb = $sb eq '' ? '' : ''; # ColourBegin my $ce = $se eq '' ? '' : ''; # ColourEnd my $dimage = $attr{'ACTIVE'} eq 'NO' ? $icons{REDIRECT}{IMAGE} : $icons{REDIRECT_NO}{IMAGE}; - push(@cols, "${dimage}${sb}${cb}$text{NO}${ce}${se}" ); + push(@cols, "${dimage}${sb}${bb}${cb}$text{NO}${ce}${be}${se}" ); push(@cols, "" ); } else { my $cb = $sb eq '' ? '' : ''; # ColourBegin my $ce = $se eq '' ? '' : ''; # ColourEnd my $aimage = $attr{'ACTIVE'} eq 'NO' ? $icons{REDIRECT}{IMAGE} : $icons{REDIRECT_A}{IMAGE}; - push(@cols, "${aimage}${sb}${cb}$text{YES}${ce}${se}" ); + push(@cols, "${aimage}${sb}${bb}${cb}$text{YES}${ce}${be}${se}" ); my $timage = $attr{'TOPORT'} eq '' ? '' : $icons{TOPORT}{IMAGE}; - push(@cols, "${timage}${sb}$attr{'TOPORT'}${se}" ); + push(@cols, "${timage}${sb}${bb}$attr{'TOPORT'}${be}${se}" ); } local $mover; $mover .= "
"; diff --git a/src/turtlefirewall/list_ndpiprotocols.cgi b/src/turtlefirewall/list_ndpiprotocols.cgi index 2959fbc..1d99b30 100644 --- a/src/turtlefirewall/list_ndpiprotocols.cgi +++ b/src/turtlefirewall/list_ndpiprotocols.cgi @@ -3,12 +3,12 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2025 Andrea Frigido # You may distribute under the terms of either the GNU General Public # License #====================================================================== -do 'turtlefirewall-lib.pl'; +require './turtlefirewall-lib.pl'; &ui_print_header( "$icons{NDPISERVICE}{IMAGE}$text{'list_ndpiprotocols_title'}", $text{'title'}, "" ); diff --git a/src/turtlefirewall/list_ndpirisks.cgi b/src/turtlefirewall/list_ndpirisks.cgi index 9b53724..c7cff53 100644 --- a/src/turtlefirewall/list_ndpirisks.cgi +++ b/src/turtlefirewall/list_ndpirisks.cgi @@ -3,12 +3,12 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2025 Andrea Frigido # You may distribute under the terms of either the GNU General Public # License #====================================================================== -do 'turtlefirewall-lib.pl'; +require './turtlefirewall-lib.pl'; &ui_print_header( "$icons{RISK}{IMAGE}$text{'list_ndpirisks_title'}", $text{'title'}, "" ); diff --git a/src/turtlefirewall/list_rawrules.cgi b/src/turtlefirewall/list_rawrules.cgi index b247a0c..4a14247 100644 --- a/src/turtlefirewall/list_rawrules.cgi +++ b/src/turtlefirewall/list_rawrules.cgi @@ -3,12 +3,12 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2025 Andrea Frigido # You may distribute under the terms of either the GNU General Public # License #====================================================================== -do 'turtlefirewall-lib.pl'; +require './turtlefirewall-lib.pl'; &ReadParse(); &ui_print_header( "$icons{HELPER}{IMAGE}$text{'list_rawrules_title'}", $text{'title'}, "" ); @@ -49,8 +49,8 @@ sub showConntrackPreroute { my $nConntrackPreroutes = $fw->GetConntrackPreroutesCount(); + my $idx = $in{idx}; if( $in{table} eq 'conntrackpreroute' ) { - my $idx = $in{idx}; if( $in{down} > 0 || $in{up} > 0 ) { my $newIdx = $idx; if( $in{down} > 0 && $idx > 0 && $idx < $nConntrackPreroutes ) { @@ -71,8 +71,8 @@ sub showConntrackPreroute { my %attr = $fw->GetConntrackPreroute($i); local @cols; if( $attr{'TARGET'} eq '' ) { $attr{'TARGET'} = 'ACCEPT'; } - my $bb = $idx == $i ? '' : ''; # BoldBegin - my $be = $idx == $i ? '' : ''; # BoldEnd + my $bb = $idx == $i && $in{table} eq 'conntrackpreroute' ? '' : ''; # BoldBegin + my $be = $idx == $i && $in{table} eq 'conntrackpreroute' ? '' : ''; # BoldEnd my $sb = $attr{'ACTIVE'} eq 'NO' ? '' : ''; # StrikeBegin my $se = $attr{'ACTIVE'} eq 'NO' ? '' : ''; # StrikeEnd my $href = &ui_link("edit_conntrackpreroute.cgi?idx=$i","${sb}${bb}${i}${be}${se}"); @@ -82,18 +82,17 @@ sub showConntrackPreroute { push(@cols, "$icons{$type}{IMAGE}${sb}${bb}$attr{'SRC'}${be}${se}" ); $type = $fw->GetItemType($attr{'DST'}); push(@cols, "$icons{$type}{IMAGE}${sb}${bb}$attr{'DST'}${be}${se}" ); - push(@cols, "$icons{SERVICE}{IMAGE}${sb}${bb}$attr{'SERVICE'}/$attr{'PORT'}${be}${se}"); + if( $attr{'PORT'} ne '' ) { + push(@cols, "$icons{SERVICE}{IMAGE}${sb}${bb}$attr{'SERVICE'}/$attr{'PORT'}${be}${se}"); + } else { + push(@cols, "$icons{SERVICE}{IMAGE}${sb}${bb}$attr{'SERVICE'}/all${be}${se}"); + } my $cb = $sb eq '' ? '' : ''; # ColourBegin my $ce = $se eq '' ? '' : ''; # ColourEnd my $himage = $attr{'ACTIVE'} eq 'NO' ? $icons{HELPER}{IMAGE} : $icons{HELPER_A}{IMAGE}; push(@cols, "${himage}${sb}${bb}${cb}".($attr{'HELPER'} ne '' ? $attr{'HELPER'} : ' ')."${ce}${be}${se}" ); local $mover; $mover .= "
"; - # if( $i < $nConntrackPreroutes-1 ) { - # $mover .= ""; - # } else { - # $mover .= ""; - # } if( $i < $nConntrackPreroutes ) { $mover .= ""; } - # if( $i > 2 ) { - # $mover .= ""; - # } else { - # $mover .= ""; - # } $mover .= "
V     v @@ -112,11 +111,6 @@ sub showConntrackPreroute {    A  
"; push(@cols, $mover); print &ui_checked_columns_row(\@cols, \@tds, "d", $i); @@ -154,8 +148,8 @@ sub showConntrack { my $nConntracks = $fw->GetConntracksCount(); + my $idx = $in{idx}; if( $in{table} eq 'conntrack' ) { - my $idx = $in{idx}; if( $in{down} > 0 || $in{up} > 0 ) { my $newIdx = $idx; if( $in{down} > 0 && $idx > 0 && $idx < $nConntracks ) { @@ -176,8 +170,8 @@ sub showConntrack { my %attr = $fw->GetConntrack($i); local @cols; if( $attr{'TARGET'} eq '' ) { $attr{'TARGET'} = 'ACCEPT'; } - my $bb = $idx == $i ? '' : ''; # BoldBegin - my $be = $idx == $i ? '' : ''; # BoldEnd + my $bb = $idx == $i && $in{table} eq 'conntrack' ? '' : ''; # BoldBegin + my $be = $idx == $i && $in{table} eq 'conntrack' ? '' : ''; # BoldEnd my $sb = $attr{'ACTIVE'} eq 'NO' ? '' : ''; # StrikeBegin my $se = $attr{'ACTIVE'} eq 'NO' ? '' : ''; # StrikeEnd my $href = &ui_link("edit_conntrack.cgi?idx=$i","${sb}${bb}${i}${be}${se}"); @@ -187,18 +181,17 @@ sub showConntrack { push(@cols, "$icons{$type}{IMAGE}${sb}${bb}$attr{'SRC'}${be}${se}" ); $type = $fw->GetItemType($attr{'DST'}); push(@cols, "$icons{$type}{IMAGE}${sb}${bb}$attr{'DST'}${be}${se}" ); - push(@cols, "$icons{SERVICE}{IMAGE}${sb}${bb}$attr{'SERVICE'}/$attr{'PORT'}${be}${se}"); + if( $attr{'PORT'} ne '' ) { + push(@cols, "$icons{SERVICE}{IMAGE}${sb}${bb}$attr{'SERVICE'}/$attr{'PORT'}${be}${se}"); + } else { + push(@cols, "$icons{SERVICE}{IMAGE}${sb}${bb}$attr{'SERVICE'}/all${be}${se}"); + } my $cb = $sb eq '' ? '' : ''; # ColourBegin my $ce = $se eq '' ? '' : ''; # ColourEnd my $himage = $attr{'ACTIVE'} eq 'NO' ? $icons{HELPER}{IMAGE} : $icons{HELPER_A}{IMAGE}; push(@cols, "${himage}${sb}${bb}${cb}".($attr{'HELPER'} ne '' ? $attr{'HELPER'} : ' ')."${ce}${be}${se}" ); local $mover; $mover .= ""; - # if( $i < $nConntracks-1 ) { - # $mover .= ""; - # } else { - # $mover .= ""; - # } if( $i < $nConntracks ) { $mover .= ""; } - # if( $i > 2 ) { - # $mover .= ""; - # } else { - # $mover .= ""; - # } $mover .= "
V     v @@ -217,11 +210,6 @@ sub showConntrack {    A  
"; push(@cols, $mover); print &ui_checked_columns_row(\@cols, \@tds, "d", $i); diff --git a/src/turtlefirewall/list_rules.cgi b/src/turtlefirewall/list_rules.cgi index 0da45ab..c1a2e34 100644 --- a/src/turtlefirewall/list_rules.cgi +++ b/src/turtlefirewall/list_rules.cgi @@ -3,12 +3,12 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2025 Andrea Frigido # You may distribute under the terms of either the GNU General Public # License #====================================================================== -do 'turtlefirewall-lib.pl'; +require './turtlefirewall-lib.pl'; &ReadParse(); &ui_print_header( "$icons{RULE}{IMAGE}$text{'list_rules_title'}", $text{'title'}, "" ); @@ -63,19 +63,10 @@ sub showRule { if( $in{down} > 0 && $idx > 0 && $idx < $nRules ) { $newIdx = $idx + $in{down}; if( $newIdx > $nRules ) { $newIdx = $nRules; } - - #my %appo = $fw->GetRule($newIdx); - #$fw->AddRuleAttr($newIdx, $fw->GetRule($idx)); - #$fw->AddRuleAttr($idx, %appo); - #$idx=$newIdx; - #$fw->SaveFirewall(); } if( $in{up} > 0 && $idx > 1 && $idx <= $nRules ) { $newIdx = $idx - $in{up}; if( $newIdx < 1 ) { $newIdx = 1; } - #my %appo = $fw->GetRule($newIdx); - #$fw->AddRuleAttr($newIdx, $fw->GetRule($idx)); - #$fw->AddRuleAttr($idx, %appo); } $fw->MoveRule( $idx, $newIdx ); $fw->SaveFirewall(); @@ -176,11 +167,6 @@ sub showRule { push(@cols, "${iimage}${sb}${bb}".($attr{'DESCRIPTION'} ne '' ? $attr{'DESCRIPTION'} : ' ')."${be}${se}" ); local $mover; $mover .= ""; - # if( $i < $nRules-1 ) { - # $mover .= ""; - # } else { - # $mover .= ""; - # } if( $i < $nRules ) { $mover .= ""; } - # if( $i > 2 ) { - # $mover .= ""; - # } else { - # $mover .= ""; - # } $mover .= "
V     v @@ -199,11 +185,6 @@ sub showRule {    A  
"; push(@cols, $mover); print &ui_checked_columns_row(\@cols, \@tds, "d", $i); diff --git a/src/turtlefirewall/list_services.cgi b/src/turtlefirewall/list_services.cgi index 22556b1..095c33d 100644 --- a/src/turtlefirewall/list_services.cgi +++ b/src/turtlefirewall/list_services.cgi @@ -3,12 +3,12 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2025 Andrea Frigido # You may distribute under the terms of either the GNU General Public # License #====================================================================== -do 'turtlefirewall-lib.pl'; +require './turtlefirewall-lib.pl'; &ui_print_header( "$icons{SERVICE}{IMAGE}$text{'list_services_title'}", $text{'title'}, "" ); diff --git a/src/turtlefirewall/module.info b/src/turtlefirewall/module.info index 832b6e2..50de2e8 100644 --- a/src/turtlefirewall/module.info +++ b/src/turtlefirewall/module.info @@ -1,5 +1,5 @@ os_support=*-linux -version=2.4 +version=2.6 longdesc=Configure a Linux firewall in a simple and fast way. name=turtlefirewall desc=Turtle Firewall diff --git a/src/turtlefirewall/save_addresslist.cgi b/src/turtlefirewall/save_addresslist.cgi index eae56c4..3dff268 100644 --- a/src/turtlefirewall/save_addresslist.cgi +++ b/src/turtlefirewall/save_addresslist.cgi @@ -3,12 +3,12 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2025 Andrea Frigido # You may distribute under the terms of either the GNU General Public # License #====================================================================== -do 'turtlefirewall-lib.pl'; +require './turtlefirewall-lib.pl'; &ReadParse(); my $addresslist = $in{'addresslist'}; diff --git a/src/turtlefirewall/save_connmark.cgi b/src/turtlefirewall/save_connmark.cgi index b72c4f7..2250dca 100644 --- a/src/turtlefirewall/save_connmark.cgi +++ b/src/turtlefirewall/save_connmark.cgi @@ -3,15 +3,16 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2025 Andrea Frigido # You may distribute under the terms of either the GNU General Public # License #====================================================================== -do 'turtlefirewall-lib.pl'; +require './turtlefirewall-lib.pl'; &ReadParse(); my $idx = $in{'idx'}; +my $newIdx = $in{'newIdx'}; my $src = $in{'src'}; $src =~ s/\0/,/g; my $dst = $in{'dst'}; @@ -71,5 +72,6 @@ if( $in{'delete'} ) { $fw->AddConnmark( $in{'new'} ? 0 : $idx, $src, $dst, $service, $ndpi, $category, $hostnameset, $riskset, $port, $time, $mark, $active ); } +if( $idx ne $newIdx ) { $fw->MoveConnmark( $idx, $newIdx ); $idx=$newIdx; } $fw->SaveFirewall(); -&redirect( 'list_manglerules.cgi'.($in{'delete'} ? "?idx=$idx" : '') ); +&redirect( 'list_manglerules.cgi'.($in{'delete'} ? '' : "?table=connmark&idx=$idx") ); diff --git a/src/turtlefirewall/save_connmarkpreroute.cgi b/src/turtlefirewall/save_connmarkpreroute.cgi index 041d649..8788101 100644 --- a/src/turtlefirewall/save_connmarkpreroute.cgi +++ b/src/turtlefirewall/save_connmarkpreroute.cgi @@ -3,15 +3,16 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2025 Andrea Frigido # You may distribute under the terms of either the GNU General Public # License #====================================================================== -do 'turtlefirewall-lib.pl'; +require './turtlefirewall-lib.pl'; &ReadParse(); my $idx = $in{'idx'}; +my $newIdx = $in{'newIdx'}; my $src = $in{'src'}; my $dst = $in{'dst'}; my ($service, $port) = &formServiceParse( $in{'servicetype'}, $in{'service2'}, $in{'service3'}, $in{'port'} ); @@ -69,5 +70,6 @@ if( $in{'delete'} ) { $fw->AddConnmarkPreroute( $in{'new'} ? 0 : $idx, $src, $dst, $service, $ndpi, $category, $hostnameset, $riskset, $port, $time, $mark, $active ); } +if( $idx ne $newIdx ) { $fw->MoveConnmarkPreroute( $idx, $newIdx ); $idx=$newIdx; } $fw->SaveFirewall(); -&redirect( 'list_manglerules.cgi'.($in{'delete'} ? "?idx=$idx" : '') ); +&redirect( 'list_manglerules.cgi'.($in{'delete'} ? '' : "?table=connmarkpreroute&idx=$idx") ); diff --git a/src/turtlefirewall/save_conntrack.cgi b/src/turtlefirewall/save_conntrack.cgi index d0fad90..e100f29 100644 --- a/src/turtlefirewall/save_conntrack.cgi +++ b/src/turtlefirewall/save_conntrack.cgi @@ -3,15 +3,16 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2025 Andrea Frigido # You may distribute under the terms of either the GNU General Public # License #====================================================================== -do 'turtlefirewall-lib.pl'; +require './turtlefirewall-lib.pl'; &ReadParse(); my $idx = $in{'idx'}; +my $newIdx = $in{'newIdx'}; my $src = $in{'src'}; my $dst = $in{'dst'}; my $service = $in{'service'}; @@ -94,5 +95,6 @@ if( $in{'delete'} ) { $fw->AddConntrack( $in{'new'} ? 0 : $idx, $src, $dst, $service, $port, $helper, $active ); } +if( $idx ne $newIdx ) { $fw->MoveConntrack( $idx, $newIdx ); $idx=$newIdx; } $fw->SaveFirewall(); -&redirect( 'list_rawrules.cgi'.($in{'delete'} ? "?idx=$idx" : '') ); +&redirect( 'list_rawrules.cgi'.($in{'delete'} ? '' : "?table=conntrack&idx=$idx") ); diff --git a/src/turtlefirewall/save_conntrackpreroute.cgi b/src/turtlefirewall/save_conntrackpreroute.cgi index 2183bda..328f78d 100644 --- a/src/turtlefirewall/save_conntrackpreroute.cgi +++ b/src/turtlefirewall/save_conntrackpreroute.cgi @@ -3,15 +3,16 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2025 Andrea Frigido # You may distribute under the terms of either the GNU General Public # License #====================================================================== -do 'turtlefirewall-lib.pl'; +require './turtlefirewall-lib.pl'; &ReadParse(); my $idx = $in{'idx'}; +my $newIdx = $in{'newIdx'}; my $src = $in{'src'}; my $dst = $in{'dst'}; my $service = $in{'service'}; @@ -94,5 +95,6 @@ if( $in{'delete'} ) { $fw->AddConntrackPreroute( $in{'new'} ? 0 : $idx, $src, $dst, $service, $port, $helper, $active ); } +if( $idx ne $newIdx ) { $fw->MoveConntrackPreroute( $idx, $newIdx ); $idx=$newIdx; } $fw->SaveFirewall(); -&redirect( 'list_rawrules.cgi'.($in{'delete'} ? "?idx=$idx" : '') ); +&redirect( 'list_rawrules.cgi'.($in{'delete'} ? '' : "?table=conntrackpreroute&idx=$idx") ); diff --git a/src/turtlefirewall/save_geoip.cgi b/src/turtlefirewall/save_geoip.cgi index b4c338b..a74e32b 100644 --- a/src/turtlefirewall/save_geoip.cgi +++ b/src/turtlefirewall/save_geoip.cgi @@ -3,12 +3,12 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2025 Andrea Frigido # You may distribute under the terms of either the GNU General Public # License #====================================================================== -do 'turtlefirewall-lib.pl'; +require './turtlefirewall-lib.pl'; &ReadParse(); my $geoip = $in{'geoip'}; diff --git a/src/turtlefirewall/save_group.cgi b/src/turtlefirewall/save_group.cgi index 1155167..8ac841f 100644 --- a/src/turtlefirewall/save_group.cgi +++ b/src/turtlefirewall/save_group.cgi @@ -3,12 +3,12 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2025 Andrea Frigido # You may distribute under the terms of either the GNU General Public # License #====================================================================== -do 'turtlefirewall-lib.pl'; +require './turtlefirewall-lib.pl'; &ReadParse(); my $group = $in{'group'}; diff --git a/src/turtlefirewall/save_host.cgi b/src/turtlefirewall/save_host.cgi index d54ee85..48a1668 100644 --- a/src/turtlefirewall/save_host.cgi +++ b/src/turtlefirewall/save_host.cgi @@ -3,12 +3,12 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2025 Andrea Frigido # You may distribute under the terms of either the GNU General Public # License #====================================================================== -do 'turtlefirewall-lib.pl'; +require './turtlefirewall-lib.pl'; &ReadParse(); my $host = $in{'host'}; diff --git a/src/turtlefirewall/save_hostnameset.cgi b/src/turtlefirewall/save_hostnameset.cgi index 4cae000..10046bf 100644 --- a/src/turtlefirewall/save_hostnameset.cgi +++ b/src/turtlefirewall/save_hostnameset.cgi @@ -3,12 +3,12 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2025 Andrea Frigido # You may distribute under the terms of either the GNU General Public # License #====================================================================== -do 'turtlefirewall-lib.pl'; +require './turtlefirewall-lib.pl'; &ReadParse(); my $hostnameset = $in{'hostnameset'}; diff --git a/src/turtlefirewall/save_ipset.cgi b/src/turtlefirewall/save_ipset.cgi index 63071d1..7ef94f7 100644 --- a/src/turtlefirewall/save_ipset.cgi +++ b/src/turtlefirewall/save_ipset.cgi @@ -3,12 +3,12 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2025 Andrea Frigido # You may distribute under the terms of either the GNU General Public # License #====================================================================== -do 'turtlefirewall-lib.pl'; +require './turtlefirewall-lib.pl'; &ReadParse(); my $ipset = $in{'ipset'}; diff --git a/src/turtlefirewall/save_masquerade.cgi b/src/turtlefirewall/save_masquerade.cgi index 60e77ef..2e396fd 100644 --- a/src/turtlefirewall/save_masquerade.cgi +++ b/src/turtlefirewall/save_masquerade.cgi @@ -3,15 +3,16 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2025 Andrea Frigido # You may distribute under the terms of either the GNU General Public # License #====================================================================== -do 'turtlefirewall-lib.pl'; +require './turtlefirewall-lib.pl'; &ReadParse(); my $idx = $in{'idx'}; +my $newIdx = $in{'newIdx'}; my $src = $in{'src'}; my $dst = $in{'dst'}; my ($service, $port) = &formServiceParse( $in{'servicetype'}, $in{'service2'}, $in{'service3'}, $in{'port'} ); @@ -57,5 +58,6 @@ if( $in{'delete'} ) { $fw->AddMasquerade( $in{'new'} ? 0 : $idx, $src, $dst, $service, $port, $is_masquerade, $active ); } +if( $idx ne $newIdx ) { $fw->MoveMasquerade( $idx, $newIdx ); $idx=$newIdx; } $fw->SaveFirewall(); -&redirect( 'list_nat.cgi' ); +&redirect( 'list_nat.cgi'.($in{'delete'} ? '' : "?table=masquerade&idx=$idx") ); diff --git a/src/turtlefirewall/save_nat.cgi b/src/turtlefirewall/save_nat.cgi index c49613f..2dede90 100644 --- a/src/turtlefirewall/save_nat.cgi +++ b/src/turtlefirewall/save_nat.cgi @@ -3,15 +3,16 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2025 Andrea Frigido # You may distribute under the terms of either the GNU General Public # License #====================================================================== -do 'turtlefirewall-lib.pl'; +require './turtlefirewall-lib.pl'; &ReadParse(); my $idx = $in{'idx'}; +my $newIdx = $in{'newIdx'}; my $virtual = $in{'virtual'}; my $real = $in{'real'}; my ($service, $port) = &formServiceParse( $in{'servicetype'}, $in{'service2'}, $in{'service3'}, $in{'port'} ); @@ -72,5 +73,6 @@ if( $in{'delete'} ) { } } +if( $idx ne $newIdx ) { $fw->MoveNat( $idx, $newIdx ); $idx=$newIdx; } $fw->SaveFirewall(); -&redirect( 'list_nat.cgi' ); +&redirect( 'list_nat.cgi'.($in{'delete'} ? '' : "?table=nat&idx=$idx") ); diff --git a/src/turtlefirewall/save_net.cgi b/src/turtlefirewall/save_net.cgi index 3650b78..d45f952 100644 --- a/src/turtlefirewall/save_net.cgi +++ b/src/turtlefirewall/save_net.cgi @@ -3,12 +3,12 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2025 Andrea Frigido # You may distribute under the terms of either the GNU General Public # License #====================================================================== -do 'turtlefirewall-lib.pl'; +require './turtlefirewall-lib.pl'; &ReadParse(); my $net = $in{'net'}; diff --git a/src/turtlefirewall/save_options.cgi b/src/turtlefirewall/save_options.cgi index 62bc445..7a3559c 100644 --- a/src/turtlefirewall/save_options.cgi +++ b/src/turtlefirewall/save_options.cgi @@ -3,12 +3,12 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2025 Andrea Frigido # You may distribute under the terms of either the GNU General Public # License #====================================================================== -do 'turtlefirewall-lib.pl'; +require './turtlefirewall-lib.pl'; &ReadParse(); if( $in{save} ne '' ) { diff --git a/src/turtlefirewall/save_ratelimit.cgi b/src/turtlefirewall/save_ratelimit.cgi index bbd8b9b..f890064 100644 --- a/src/turtlefirewall/save_ratelimit.cgi +++ b/src/turtlefirewall/save_ratelimit.cgi @@ -3,12 +3,12 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2025 Andrea Frigido # You may distribute under the terms of either the GNU General Public # License #====================================================================== -do 'turtlefirewall-lib.pl'; +require './turtlefirewall-lib.pl'; &ReadParse(); my $ratelimit = $in{'ratelimit'}; diff --git a/src/turtlefirewall/save_redirect.cgi b/src/turtlefirewall/save_redirect.cgi index 86ef283..429686b 100644 --- a/src/turtlefirewall/save_redirect.cgi +++ b/src/turtlefirewall/save_redirect.cgi @@ -3,15 +3,16 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2025 Andrea Frigido # You may distribute under the terms of either the GNU General Public # License #====================================================================== -do 'turtlefirewall-lib.pl'; +require './turtlefirewall-lib.pl'; &ReadParse(); my $idx = $in{'idx'}; +my $newIdx = $in{'newIdx'}; my $src = $in{'src'}; my $dst = $in{'dst'}; my ($service, $port) = &formServiceParse( $in{'servicetype'}, $in{'service2'}, $in{'service3'}, $in{'port'} ); @@ -66,5 +67,6 @@ if( $in{'delete'} ) { $fw->AddRedirect( $in{'new'} ? 0 : $idx, $src, $dst, $service, $port, $toport, $is_redirect, $active ); } +if( $idx ne $newIdx ) { $fw->MoveRedirect( $idx, $newIdx ); $idx=$newIdx; } $fw->SaveFirewall(); -&redirect( 'list_nat.cgi' ); +&redirect( 'list_nat.cgi'.($in{'delete'} ? '' : "?table=redirect&idx=$idx") ); diff --git a/src/turtlefirewall/save_riskset.cgi b/src/turtlefirewall/save_riskset.cgi index 630c1f5..5e00014 100644 --- a/src/turtlefirewall/save_riskset.cgi +++ b/src/turtlefirewall/save_riskset.cgi @@ -3,12 +3,12 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2025 Andrea Frigido # You may distribute under the terms of either the GNU General Public # License #====================================================================== -do 'turtlefirewall-lib.pl'; +require './turtlefirewall-lib.pl'; &ReadParse(); my $riskset = $in{'riskset'}; diff --git a/src/turtlefirewall/save_rule.cgi b/src/turtlefirewall/save_rule.cgi index 29ea535..b9d86cf 100644 --- a/src/turtlefirewall/save_rule.cgi +++ b/src/turtlefirewall/save_rule.cgi @@ -3,15 +3,16 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2025 Andrea Frigido # You may distribute under the terms of either the GNU General Public # License #====================================================================== -do 'turtlefirewall-lib.pl'; +require './turtlefirewall-lib.pl'; &ReadParse(); my $idx = $in{'idx'}; +my $newIdx = $in{'newIdx'}; my $src = $in{'src'}; $src =~ s/\0/,/g; my $dst = $in{'dst'}; @@ -72,20 +73,17 @@ if( $in{'delete'} ) { &error( $text{save_rule_error4} ); } - if( $target eq 'ACCEPT' && ($ndpi eq 'all' || $hostnameset ne '' || $riskset ne '') ) { - &error( $text{save_rule_error5} ); - } - if( $target ne 'DROP' && $ratelimit ne '' ) { - &error( $text{save_rule_error6} ); + &error( $text{save_rule_error5} ); } if( $log ne '' && $ratelimit ne '' ) { - &error( $text{save_rule_error7} ); + &error( $text{save_rule_error6} ); } $fw->AddRule( $in{'new'} ? 0 : $idx, $src, $dst, $service, $ndpi, $category, $hostnameset, $riskset, $ratelimit, $port, $time, $target, $active, $log, $description ); } +if( $idx ne $newIdx ) { $fw->MoveRule( $idx, $newIdx ); $idx=$newIdx; } $fw->SaveFirewall(); -&redirect( 'list_rules.cgi'.($in{'delete'} ? "?idx=$idx" : '') ); +&redirect( 'list_rules.cgi'.($in{'delete'} ? '' : "?idx=$idx") ); diff --git a/src/turtlefirewall/save_time.cgi b/src/turtlefirewall/save_time.cgi index 9f64970..2114a68 100644 --- a/src/turtlefirewall/save_time.cgi +++ b/src/turtlefirewall/save_time.cgi @@ -3,12 +3,12 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2025 Andrea Frigido # You may distribute under the terms of either the GNU General Public # License #====================================================================== -do 'turtlefirewall-lib.pl'; +require './turtlefirewall-lib.pl'; &ReadParse(); my $time = $in{'time'}; diff --git a/src/turtlefirewall/save_timegroup.cgi b/src/turtlefirewall/save_timegroup.cgi index fd271a4..4f1f6e2 100644 --- a/src/turtlefirewall/save_timegroup.cgi +++ b/src/turtlefirewall/save_timegroup.cgi @@ -3,12 +3,12 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2025 Andrea Frigido # You may distribute under the terms of either the GNU General Public # License #====================================================================== -do 'turtlefirewall-lib.pl'; +require './turtlefirewall-lib.pl'; &ReadParse(); my $timegroup = $in{'timegroup'}; diff --git a/src/turtlefirewall/save_zone.cgi b/src/turtlefirewall/save_zone.cgi index 3bd0253..b0f82db 100644 --- a/src/turtlefirewall/save_zone.cgi +++ b/src/turtlefirewall/save_zone.cgi @@ -3,12 +3,12 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2025 Andrea Frigido # You may distribute under the terms of either the GNU General Public # License #====================================================================== -do 'turtlefirewall-lib.pl'; +require './turtlefirewall-lib.pl'; &ReadParse(); $newzone = $in{'newzone'}; diff --git a/src/turtlefirewall/setup/TurtleFirewall.pm b/src/turtlefirewall/setup/TurtleFirewall.pm index 08e2e27..bf7daa5 100644 --- a/src/turtlefirewall/setup/TurtleFirewall.pm +++ b/src/turtlefirewall/setup/TurtleFirewall.pm @@ -1,11 +1,11 @@ -# TurtleFirewall: Turtle Firewall Library +# Turtle Firewall : Library # -# Software for configuring a Linux firewall (netfilter) +# Software for configuring a linux firewall (netfilter) # # 2001/11/23 13:25:00 # #====================================================================== -# Copyright (c) 2001-2024 Andrea Frigido +# Copyright (c) 2001-2025 Andrea Frigido # You may distribute under the terms of either the GNU General Public # License #====================================================================== @@ -16,12 +16,11 @@ use XML::Parser; # Turtle Firewall Version sub Version { - return '2.4'; + return '2.6'; } sub new { my $this ={}; - #$this->{NOME} = undef; $this->{fw} = (); $this->{fwItems} = (); $this->{fwKeys} = (); @@ -65,12 +64,12 @@ sub GetTimeList { sub GetGroupList { my $this = shift; - return @{$this->{fwKeys}{GROUP}}; + return sort @{$this->{fwKeys}{GROUP}}; } sub GetTimeGroupList { my $this = shift; - return @{$this->{fwKeys}{TIMEGROUP}}; + return sort @{$this->{fwKeys}{TIMEGROUP}}; } sub GetHostNameSetList { @@ -181,7 +180,7 @@ sub GetItemsAllowToGroup { } push @items, $g; } - return @items; + return sort @items; } sub GetItemsAllowToTimeGroup { @@ -189,7 +188,7 @@ sub GetItemsAllowToTimeGroup { my $timegroup = shift; my @items = (); push @items, @{$this->{fwKeys}{TIME}}; - return @items; + return sort @items; } sub GetServicesList { @@ -242,7 +241,6 @@ sub GetMasqueradesCount { } sub GetMasquerade { - # param n = id of masquerade rule (1 .. MasqueradeCount) my ($this,$n) = @_; return %{ $this->{fw}{MASQUERADE}[$n-1] }; } @@ -454,6 +452,13 @@ sub AddMasqueradeAttr { } } +sub MoveMasquerade { + my ($this, $idxSrc, $idxDst) = @_; + my %attr = %{$this->{fw}{MASQUERADE}[$idxSrc-1]}; + splice @{$this->{fw}{MASQUERADE}}, $idxSrc-1, 1; + splice @{$this->{fw}{MASQUERADE}}, $idxDst-1, 0, \%attr; +} + # AddNat( $idx, $virtual, $real, $service, $port, $toport, $active ) if $idx==0 then add new Masquerade sub AddNat { my ($this, $idx, $virtual, $real, $service, $port, $toport, $active) = @_; @@ -476,6 +481,13 @@ sub AddNatAttr { } } +sub MoveNat { + my ($this, $idxSrc, $idxDst) = @_; + my %attr = %{$this->{fw}{NAT}[$idxSrc-1]}; + splice @{$this->{fw}{NAT}}, $idxSrc-1, 1; + splice @{$this->{fw}{NAT}}, $idxDst-1, 0, \%attr; +} + # AddRedirect( $idx, $src, $dst, $service, $port, $toport, $active ); sub AddRedirect { my ($this, $idx, $src, $dst, $service, $port, $toport, $redirect, $active ) = @_; @@ -498,6 +510,13 @@ sub AddRedirectAttr { } } +sub MoveRedirect { + my ($this, $idxSrc, $idxDst) = @_; + my %attr = %{$this->{fw}{REDIRECT}[$idxSrc-1]}; + splice @{$this->{fw}{REDIRECT}}, $idxSrc-1, 1; + splice @{$this->{fw}{REDIRECT}}, $idxDst-1, 0, \%attr; +} + # AddRule( $idx, $src, $dst, $service, $ndpi, $category, $hostnameset, $riskset, $ratelimit, $port, $time, $target, $active, $log, $description ); sub AddRule { my ($this, $idx, $src, $dst, $service, $ndpi, $category, $hostnameset, $riskset, $ratelimit, $port, $time, $target, $active, $log, $description ) = @_; @@ -980,7 +999,7 @@ sub GetItemReferences { foreach $ruleitem ('SRC','DST','ZONE','VIRTUAL','REAL','TIME','HOSTNAMESET','RISKSET','RATELIMIT') { my @ruleitem_list = split( /,/, $this->{fw}{$ruletype}[$i]{$ruleitem} ); if( grep( /^$item$/, @ruleitem_list ) ) { - $references{"${ruleitem} ${i}"} = $ruletype; + $references{"$ruleitem $i $ruletype"} = $ruletype; } } } @@ -1136,7 +1155,7 @@ sub LoadFirewall { my @list = @{$tree[$i+1]}; my %attr = shift @list; - # Loop over second-level tags (hosts, groups, rules ecc.) + # Loop over second-level tags (hosts, groups, rules etc.) for( my $j=0; $j<=$#list; $j+=2 ) { my $name2 = uc($list[$j]); if( $name2 eq 'ZONE' ) { $this->_LoadFirewallItem( 'ZONE', @{$list[$j+1]} ); } @@ -1215,7 +1234,6 @@ sub _LoadFirewallNat { my $this = shift; my $type = shift; my @list = @_; - #my $name = $list[$i]; my %attrs = upperKeys( %{shift @list} ); ### @@ -1337,12 +1355,6 @@ sub _LoadFirewallConntrack { } # Internal method for add OPTIONS to firewall object -# -# XML: -# -# - - + + @@ -36,7 +36,7 @@ - + diff --git a/src/turtlefirewall/setup/fw.xml.sample b/src/turtlefirewall/setup/fw.xml.sample index c2feaa3..f156f0c 100644 --- a/src/turtlefirewall/setup/fw.xml.sample +++ b/src/turtlefirewall/setup/fw.xml.sample @@ -15,12 +15,12 @@