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..960703e --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,335 @@ +# ChangeLog + +## v.2.8 (Not Yet Released) +- Cleanup : Variable Declarations. +- Cleanup : Formatting Order. +- Cleanup : Remove custom roundbytes function. +- Cleanup : Standardize mover function. +- Feature : Add Risk Severity Info. +- Bug : Fixed backup.cgi restore upload. +- Theme : Add item reference image. +- Todo : Translate new features. + +## v.2.7 (11-12-2025) +- OS : DEB package, remove EOL OS instructions. +- Feature : nDPI 5.1 support. +- Bug : Fix variable declarations. +- Bug : Add invalid port service check. +- Bug : Don't check group membership for * zone during apply of Masquerade and Redirect. +- Bug : Improve expand_item. +- Bug : Rework LoadServices. +- Bug : Enable strict mode. +- Bug : Add invalid use of MAC address check. +- Bug : Add invalid nDPI service check. +- Bug : Add invalid nDPI category check. +- Services : Add Wireguard on port 51820 service. +- Services : Add udp port 5514 to Unifi service. +- Theme : Rework Webmin images. + +## 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 +- Theme : Webmin 2.600 support. +- Theme : Update lib to use ui standard. + +## 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.deb12.md b/INSTALL.deb12.md new file mode 100644 index 0000000..e500abc --- /dev/null +++ b/INSTALL.deb12.md @@ -0,0 +1,38 @@ +## Debian 12 + +Activate Repos. +``` +cp /usr/share/doc/apt/examples/sources.list /etc/apt/sources.list.d +sed -i "s/^deb cdrom:/#deb cdrom:/" /etc/apt/sources.list +apt-get update +apt-get -y install curl wget dpkg-dev + +wget https://raw.githubusercontent.com/webmin/webmin/master/setup-repos.sh +sh setup-repos.sh -f + +mkdir -p /var/tmp/tfw +cd /var/tmp/tfw +curl -s https://api.github.com/repos/netcons/turtlefirewall/releases \ +| grep "browser_download_url.*deb12_*" \ +| cut -d : -f 2,3 \ +| tr -d \" \ +| wget -qi - +dpkg-scanpackages . /dev/null | gzip -9c > Packages.gz + +echo "deb [trusted=yes] file:/var/tmp/tfw ./" > /etc/apt/sources.list.d/tfw.list + +apt-get update +``` + +Install Turtle Firewall. +``` +apt-get -y upgrade linux-image-amd64 linux-headers-amd64 +reboot + +apt-get -y install turtlefirewall +``` + +Configure */etc/turtlefirewall/fw.xml* or via Webmin and enable Turtle Firewall. +``` +systemctl enable turtlefirewall --now +``` \ No newline at end of file diff --git a/INSTALL.deb13.md b/INSTALL.deb13.md new file mode 100644 index 0000000..bceb59e --- /dev/null +++ b/INSTALL.deb13.md @@ -0,0 +1,38 @@ +## Debian 13 + +Activate Repos. +``` +cp /usr/share/doc/apt/examples/debian.sources /etc/apt/sources.list.d +sed -i "s/^deb cdrom:/#deb cdrom:/" /etc/apt/sources.list +apt-get update +apt-get -y install curl wget dpkg-dev + +wget https://raw.githubusercontent.com/webmin/webmin/master/setup-repos.sh +sh setup-repos.sh -f + +mkdir -p /var/tmp/tfw +cd /var/tmp/tfw +curl -s https://api.github.com/repos/netcons/turtlefirewall/releases \ +| grep "browser_download_url.*deb13_*" \ +| cut -d : -f 2,3 \ +| tr -d \" \ +| wget -qi - +dpkg-scanpackages . /dev/null | gzip -9c > Packages.gz + +echo "deb [trusted=yes] file:/var/tmp/tfw ./" > /etc/apt/sources.list.d/tfw.list + +apt-get update +``` + +Install Turtle Firewall. +``` +apt-get -y upgrade linux-image-amd64 linux-headers-amd64 +reboot + +apt-get -y install turtlefirewall +``` + +Configure */etc/turtlefirewall/fw.xml* or via Webmin and enable Turtle Firewall. +``` +systemctl enable turtlefirewall --now +``` \ No newline at end of file diff --git a/INSTALL.el10.md b/INSTALL.el10.md new file mode 100644 index 0000000..4b80240 --- /dev/null +++ b/INSTALL.el10.md @@ -0,0 +1,59 @@ +## RHEL 10 + +Activate Repos. +``` +dnf config-manager --set-enabled extras-common +dnf config-manager --set-enabled crb +dnf config-manager --save --setopt=optional_metadata_types=filelists +dnf -y install epel-release +dnf -y install centos-release-kmods-kernel +dnf -y install createrepo wget + +wget https://raw.githubusercontent.com/webmin/webmin/master/setup-repos.sh +sh setup-repos.sh -f + +mkdir -p /var/tmp/tfw +cd /var/tmp/tfw +curl -s https://api.github.com/repos/netcons/turtlefirewall/releases \ +| grep "browser_download_url.*.el10.*rpm" \ +| cut -d : -f 2,3 \ +| tr -d \" \ +| wget -qi - +createrepo ./ + +cd /etc/pki/rpm-gpg +curl -s https://api.github.com/repos/netcons/turtlefirewall/releases \ +| grep "browser_download_url.*RPM-GPG-KEY-tfw" \ +| cut -d : -f 2,3 \ +| tr -d \" \ +| wget -qi - + +echo '[tfw] +name=CentOS Stream $releasever - Turtlefirewall +baseurl=file:/var/tmp/tfw/ +gpgckeck=1 +gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-tfw +enabled=1' > /etc/yum.repos.d/tfw.repo +``` + +Install Turtle Firewall. +``` +dnf -y upgrade kernel +dnf -y install kernel-devel kernel-headers +reboot + +dnf -y install https://github.com/harelba/q/releases/download/v3.1.6/q-text-as-data-3.1.6.x86_64.rpm + +dnf -y install turtlefirewall +systemctl enable dkms --now +``` + +Disable Firewalld. +``` +systemctl disable firewalld --now +``` + +Configure */etc/turtlefirewall/fw.xml* or via Webmin and enable Turtle Firewall. +``` +systemctl enable turtlefirewall --now +``` \ No newline at end of file diff --git a/INSTALL.el9.md b/INSTALL.el9.md new file mode 100644 index 0000000..ea6951c --- /dev/null +++ b/INSTALL.el9.md @@ -0,0 +1,50 @@ +## RHEL 9 + +Activate Repos. +``` +dnf config-manager --set-enabled extras-common +dnf config-manager --set-enabled crb +dnf -y install epel-release +dnf -y install centos-release-kmods-kernel +dnf -y install createrepo wget + +wget https://raw.githubusercontent.com/webmin/webmin/master/setup-repos.sh +sh setup-repos.sh -f + +mkdir -p /var/tmp/tfw +cd /var/tmp/tfw +curl -s https://api.github.com/repos/netcons/turtlefirewall/releases \ +| grep "browser_download_url.*.el9.*rpm" \ +| cut -d : -f 2,3 \ +| tr -d \" \ +| wget -qi - +createrepo ./ + +echo '[tfw] +name=CentOS Stream $releasever - Turtlefirewall +baseurl=file:/var/tmp/tfw/ +gpgckeck=0 +enabled=1' > /etc/yum.repos.d/tfw.repo +``` + +Install Turtle Firewall. +``` +dnf -y upgrade kernel +dnf -y install kernel-devel kernel-headers +reboot + +dnf -y install https://github.com/harelba/q/releases/download/v3.1.6/q-text-as-data-3.1.6.x86_64.rpm + +dnf -y install turtlefirewall +systemctl enable dkms --now +``` + +Disable Firewalld. +``` +systemctl disable firewalld --now +``` + +Configure */etc/turtlefirewall/fw.xml* or via Webmin and enable Turtle Firewall. +``` +systemctl enable turtlefirewall --now +``` \ No newline at end of file diff --git a/INSTALL.md b/INSTALL.md index 794401c..c3c39b1 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -19,7 +19,7 @@ apt-get -y install wget wget https://raw.githubusercontent.com/webmin/webmin/master/setup-repos.sh sh setup-repos.sh -f -apt-get install webmin --install-recommends +apt-get -y install webmin --install-recommends ``` ## Turtlefirewall Webmin Module @@ -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,15 @@ Build source. Install RHEL. ``` +dnf -y install https://github.com/harelba/q/releases/download/v3.1.6/q-text-as-data-3.1.6.x86_64.rpm + dnf -y install perl-XML-Parser perl-Net-CIDR-Lite perl-Text-CSV_XS iptables-nft ipset conntrack-tools rsyslog dos2unix gawk crontabs /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,7 +55,7 @@ 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 install centos-release-kmods-kernel dnf -y upgrade kernel reboot @@ -66,6 +68,10 @@ systemctl enable dkms --now Debian. ``` +apt-get -y upgrade linux-image-amd64 +reboot + +apt-get -y install linux-headers-amd64 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 +81,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 +108,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,26 +136,29 @@ make install Download source. ``` +VERSION="5.1.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. ``` ./autogen.sh +./configure cd ndpi-netfilter make make install @@ -155,9 +168,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 +179,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..aa67111 100644 --- a/README.md +++ b/README.md @@ -1,41 +1,40 @@ ## 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. -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. +You can define the different firewall elements (zones, hosts, networks, geoips and ipsets) and then set the services (port or dpi) you want to control (allow, deny, ratelimit, mark or 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](https://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](https://github.com/frisoft)). + +## Features + +- Time, GeoIP and nDPI based rules. +- 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 ) ## Requirements +- Linux Kernel 6.x or newer - expat library installed. - XML::Parser perl module installed. -- Webmin installed. ( https://github.com/webmin/webmin ) +- Webmin installed. ([webmin](https://github.com/webmin/webmin)) - iptables command in PATH. - Standard Netfilter kernel modules :
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 )
-xt_ratelimit. ( https://github.com/aabc/ipt-ratelimit )
+xt_ndpi, ([vel21ripn](https://github.com/vel21ripn/nDPI))
+xt_geoip, ([jengelh](https://codeberg.org/jengelh/xtables-addons))
+xt_ratelimit. ([aabc](https://github.com/aabc/ipt-ratelimit))
## Contributors 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..d3f4e6b 100644 --- a/dkms/dkms-ndpi-netfilter.conf +++ b/dkms/dkms-ndpi-netfilter.conf @@ -1,12 +1,11 @@ -PACKAGE_VERSION="4.11.0" +PACKAGE_VERSION="5.1.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} \;" +MAKE="./configure; 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..1dcbaf6 100644 --- a/src/turtlefirewall/backup.cgi +++ b/src/turtlefirewall/backup.cgi @@ -3,106 +3,22 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2026 Andrea Frigido # You may distribute under the terms of either the GNU General Public # License #====================================================================== -do 'turtlefirewall-lib.pl'; -&ReadParse(); +require './turtlefirewall-lib.pl'; -if( $in{download} ) { - &backup_download(); -} +my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); +my $d = sprintf("%04d%02d%02d-%02d%02d", $year+1900, $mday+1, $mday, $hour, $min); +my $confdir = &confdir(); -&ui_print_header( "$icons{SHIELD}{IMAGE}$text{'backup_title'}", $text{'title'}, "" ); - -if( $in{upload} ) { - # FIXME - &restore_upload( $in{backup} ); - &ui_print_footer('backup.cgi',$text{'backup_title'}); - # FIXME -} else { - print qq~
- - - - - - - -
$text{'backup_backuptitle'}
-
~; - print &ui_form_start("backup.cgi?download=1", "post"); - print &ui_submit($text{'backup_index_download'}); - print &ui_form_end(); - print qq~

-
- - - - - - - - -
$text{'backup_restoretitle'}
-
~; - print &ui_form_start("backup.cgi", "form-data"); - print &ui_upload("backup", 40); - print &ui_submit($text{'backup_index_restore'}); - print &ui_form_end(); - print qq~

-
-

~; - - &ui_print_footer('index.cgi',$text{'index'}); -} - -sub backup_download { - my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); - my $d = sprintf("%04d%02d%02d-%02d%02d", $year+1900, $mday+1, $mday, $hour, $min); - my $confdir = &confdir(); - - open TARGZ, "tar cz --directory $confdir fw.xml fwuserdefservices.xml |" - or &error( "Error during backup" ); - print "Content-type: application/x-gzip\n"; - print "Expires: Mon, 26 Jul 1997 05:00:00 GMT\n"; # Date in the past - print "Cache-Control: no-store, no-cache, must-revalidate\n"; # HTTP/1.1 - print "Cache-Control: post-check=0, pre-check=0\n"; - #print "Pragma: no-cache\n"; - print "Content-Disposition: inline; filename=turtlefirewall-backup-$d.tar.gz\n"; - print "\n"; - my $buffer = ''; - while( read( TARGZ, $buffer, 1024) ) { - print $buffer; - } - close TARGZ; - exit 0; -} - -sub restore_upload { - my $backup = shift; - my $output = &tempname(); - my $confdir = &confdir(); - - $whatfailed = $text{backup_error_title1}; - - #chdir '/etc/turtlefirewall'; - #chdir '/tmp'; - open TARGZ, "| tar xvz --directory $confdir fw.xml fwuserdefservices.xml >$output 2>&1" or &error( $text{backup_error1} ); - syswrite(TARGZ, $backup, length($backup)); - close TARGZ; - - print qq~ - - - - -
$text{'backup_restoretitle'}
~;
-	open FILE, "<$output";
-	while(  ) { print; }
-	close FILE;
-	unlink $output;
-	print qq~	
~; -} +print "Content-Disposition: Attachment; filename=turtlefirewall-backup-$d.tar.gz\n"; +print "X-Content-Type-Options: nosniff\n"; +print "Content-type: application/x-gzip\n\n"; +my $buffer = ''; +open TARGZ, "tar cz --directory $confdir fw.xml fwuserdefservices.xml |" + or &error( $text{configuration_error2} ); +while(read( TARGZ, $buffer, &get_buffer_size_binary())) { print $buffer; } +close TARGZ; diff --git a/src/turtlefirewall/configuration.cgi b/src/turtlefirewall/configuration.cgi new file mode 100644 index 0000000..5b30606 --- /dev/null +++ b/src/turtlefirewall/configuration.cgi @@ -0,0 +1,31 @@ +#!/usr/bin/perl + +#====================================================================== +# Turtle Firewall webmin module +# +# Copyright (c) 2001-2026 Andrea Frigido +# You may distribute under the terms of either the GNU General Public +# License +#====================================================================== + +require './turtlefirewall-lib.pl'; + +&ui_print_header( "$icons{ICON}{IMAGE}$text{'index_icon_configuration'}", $text{'title'}, "" ); + +print ''; +print ''; +print ''; +print '
'; +print &ui_form_start("backup.cgi", "post"); +print &ui_submit($text{'configuration_index_download'}); +print &ui_form_end(); +print ''; +print &ui_form_start("restore.cgi", "form-data"); +print &ui_upload("backup", 40); +print &ui_submit($text{'configuration_index_restore'}); +print &ui_form_end(); +print '
'; + +print "
\n"; + +&ui_print_footer('index.cgi',$text{'index'}); diff --git a/src/turtlefirewall/edit_addresslist.cgi b/src/turtlefirewall/edit_addresslist.cgi index ff10c68..1307a0f 100644 --- a/src/turtlefirewall/edit_addresslist.cgi +++ b/src/turtlefirewall/edit_addresslist.cgi @@ -3,15 +3,15 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2026 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'}; +my $new = $in{'new'}; my $heading = ''; if( $new ) { @@ -19,7 +19,7 @@ if( $new ) { } else { $heading = "$icons{EDIT}{IMAGE}$text{'edit_addresslist_title_edit'}"; } -&ui_print_header( $heading, $text{'title'}, "" ); +&ui_print_header( "$icons{ICON}{IMAGE}$text{'index_icon_items'}", $text{'title'}, "" ); my $addresslist = $in{'addresslist'}; my $newaddresslist = $in{'newaddresslist'}; @@ -62,4 +62,4 @@ print ""; print &ui_form_end(); print "

"; -&ui_print_footer('list_items.cgi','items list'); +&ui_print_footer('list_items.cgi',$text{'index_items'}); diff --git a/src/turtlefirewall/edit_connmark.cgi b/src/turtlefirewall/edit_connmark.cgi index 579b834..63ebd7b 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-2026 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'}; +my $nConnmarks = $fw->GetConnmarksCount(); + +my $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'}; @@ -43,7 +48,10 @@ if( $new ) { $mark = $rule{'MARK'}; $active = $rule{'ACTIVE'} ne 'NO'; } -&ui_print_header( $heading, $text{'title'}, "" ); +&ui_print_header( "$icons{ICON}{IMAGE}$text{'index_icon_manglerules'}", $text{'title'}, "" ); + +my @idxs = (); +for( my $i=1; $i<=$nConnmarks; $i++ ) { push @idxs, $i; } my @selected_src = split(/,/, $src); my @selected_dst = split(/,/, $dst); @@ -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 ""; 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",$text{'index_manglerules'}); diff --git a/src/turtlefirewall/edit_connmarkpreroute.cgi b/src/turtlefirewall/edit_connmarkpreroute.cgi index f17cf46..0cc46ba 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-2026 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'}; +my $nConnmarkPreroutes = $fw->GetConnmarkPreroutesCount(); + +my $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'}; @@ -43,7 +48,10 @@ if( $new ) { $mark = $rule{'MARK'}; $active = $rule{'ACTIVE'} ne 'NO'; } -&ui_print_header( $heading, $text{'title'}, "" ); +&ui_print_header( "$icons{ICON}{IMAGE}$text{'index_icon_manglerules'}", $text{'title'}, "" ); + +my @idxs = (); +for( my $i=1; $i<=$nConnmarkPreroutes; $i++ ) { push @idxs, $i; } my @items_src = (); push @items_src, grep(!/FIREWALL/, $fw->GetZoneList()); @@ -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",$text{'index_manglerules'}); diff --git a/src/turtlefirewall/edit_conntrack.cgi b/src/turtlefirewall/edit_conntrack.cgi index aa507c9..6ff49e6 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-2026 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'}; +my $nConntracks = $fw->GetConntracksCount(); + +my $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'}; @@ -33,7 +38,10 @@ if( $new ) { $helper = $rule{'HELPER'}; $active = $rule{'ACTIVE'} ne 'NO'; } -&ui_print_header( $heading, $text{'title'}, "" ); +&ui_print_header( "$icons{ICON}{IMAGE}$text{'index_icon_rawrules'}", $text{'title'}, "" ); + +my @idxs = (); +for( my $i=1; $i<=$nConntracks; $i++ ) { push @idxs, $i; } my @items_dst = ('*'); push @items_dst, grep(!/FIREWALL/, $fw->GetZoneList()); @@ -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); @@ -69,7 +75,7 @@ $col .= &ui_textbox("port", $port, 11, 0, 11); $col .= "$text{port_help}"; print &ui_columns_row([ "$icons{SERVICE}{IMAGE}$text{'rule_service'}", $col ], \@tds); $col = &ui_select("helper", $helper, \@helpers); -print &ui_columns_row([ "$icons{NDPISERVICE}{IMAGE}$text{'rule_helper'}", $col ], \@tds); +print &ui_columns_row([ "$icons{HELPER}{IMAGE}$text{'rule_helper'}", $col ], \@tds); $col = &ui_checkbox("active", 1, undef, $active ? 1 : 0); print &ui_columns_row([ "$icons{ACTIVE}{IMAGE}$text{'rule_active'}", $col ], \@tds); print &ui_columns_end(); @@ -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",$text{'index_rawrules'}); diff --git a/src/turtlefirewall/edit_conntrackpreroute.cgi b/src/turtlefirewall/edit_conntrackpreroute.cgi index 9d0b94d..7cd1eda 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-2026 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'}; +my $nConntrackPreroutes = $fw->GetConntrackPreroutesCount(); + +my $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'}; @@ -33,7 +38,10 @@ if( $new ) { $helper = $rule{'HELPER'}; $active = $rule{'ACTIVE'} ne 'NO'; } -&ui_print_header( $heading, $text{'title'}, "" ); +&ui_print_header( "$icons{ICON}{IMAGE}$text{'index_icon_rawrules'}", $text{'title'}, "" ); + +my @idxs = (); +for( my $i=1; $i<=$nConntrackPreroutes; $i++ ) { push @idxs, $i; } my @items_src = ('*'); push @items_src, grep(!/FIREWALL/, $fw->GetZoneList()); @@ -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); @@ -76,7 +82,7 @@ $col .= &ui_textbox("port", $port, 11, 0, 11); $col .= "$text{port_help}"; print &ui_columns_row([ "$icons{SERVICE}{IMAGE}$text{'rule_service'}", $col ], \@tds); $col = &ui_select("helper", $helper, \@helpers); -print &ui_columns_row([ "$icons{NDPISERVICE}{IMAGE}$text{'rule_helper'}", $col ], \@tds); +print &ui_columns_row([ "$icons{HELPER}{IMAGE}$text{'rule_helper'}", $col ], \@tds); $col = &ui_checkbox("active", 1, undef, $active ? 1 : 0); print &ui_columns_row([ "$icons{ACTIVE}{IMAGE}$text{'rule_active'}", $col ], \@tds); print &ui_columns_end(); @@ -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",$text{'index_rawrules'}); diff --git a/src/turtlefirewall/edit_flowstat.cgi b/src/turtlefirewall/edit_flowstat.cgi index c8ab92c..6ea7b21 100644 --- a/src/turtlefirewall/edit_flowstat.cgi +++ b/src/turtlefirewall/edit_flowstat.cgi @@ -3,15 +3,15 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2026 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'}, "" ); +&ui_print_header( "$icons{ICON}{IMAGE}$text{'index_icon_flowstat'}", $text{'title'}, "" ); &reportFlowStat(); print "

"; @@ -22,36 +22,58 @@ 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 $is_log = '1'; + 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[0]; 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); + my @opts = ( [ 0, "$text{'flowlog_all'}
" ], [ 1, "".&ui_select("log", $selected_log, \@logs, 5, 1)."
" ], [ 2, "$text{'flowlog_current'}" ] ); + $col = &ui_radio("is_log", $is_log, \@opts); 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..4b68332 100644 --- a/src/turtlefirewall/edit_geoip.cgi +++ b/src/turtlefirewall/edit_geoip.cgi @@ -3,15 +3,15 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2026 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'}; +my $new = $in{'new'}; my $heading = ''; if( $new ) { @@ -19,7 +19,7 @@ if( $new ) { } else { $heading = "$icons{EDIT}{IMAGE}$text{'edit_geoip_title_edit'}"; } -&ui_print_header( $heading, $text{'title'}, "" ); +&ui_print_header( "$icons{ICON}{IMAGE}$text{'index_icon_items'}", $text{'title'}, "" ); my $geoip = $in{'geoip'}; my $newgeoip = $in{'newgeoip'}; @@ -32,8 +32,7 @@ my @zones = grep(!/FIREWALL/, $fw->GetZoneList()); &LoadCountryCodes($fw); my @items_countrycode = (); -my @countrycodes = $fw->GetCountryCodesList(); -for my $k (@countrycodes) { +for my $k ($fw->GetCountryCodesList()) { my %country = $fw->GetCountryCode($k); my @opts = ( "$k", "$k - $country{DESCRIPTION}" ); push(@items_countrycode, \@opts); @@ -71,4 +70,4 @@ print "
"; print &ui_form_end(); print "

"; -&ui_print_footer('list_items.cgi','items list'); +&ui_print_footer('list_items.cgi',$text{'index_items'}); diff --git a/src/turtlefirewall/edit_group.cgi b/src/turtlefirewall/edit_group.cgi index 740305c..4a43796 100644 --- a/src/turtlefirewall/edit_group.cgi +++ b/src/turtlefirewall/edit_group.cgi @@ -3,17 +3,17 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2026 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'}; -$group = $in{'group'}; -$newgroup = $in{'newgroup'}; +my $new = $in{'new'}; +my $group = $in{'group'}; +my $newgroup = $in{'newgroup'}; my $heading = ''; if( $new ) { @@ -21,7 +21,7 @@ if( $new ) { } else { $heading = "$icons{EDIT}{IMAGE}$text{'edit_group_title_edit'}"; } -&ui_print_header( $heading, $text{'title'}, "" ); +&ui_print_header( "$icons{ICON}{IMAGE}$text{'index_icon_items'}", $text{'title'}, "" ); my %g = $fw->GetGroup($group); my @selected_items = @{$g{ITEMS}}; @@ -59,4 +59,4 @@ print ""; print &ui_form_end(); print "

"; -&ui_print_footer('list_items.cgi','items list'); +&ui_print_footer('list_items.cgi',$text{'index_items'}); diff --git a/src/turtlefirewall/edit_host.cgi b/src/turtlefirewall/edit_host.cgi index 8b3bef9..eb35952 100644 --- a/src/turtlefirewall/edit_host.cgi +++ b/src/turtlefirewall/edit_host.cgi @@ -3,15 +3,15 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2026 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'}; +my $new = $in{'new'}; my $heading = ''; if( $new ) { @@ -19,7 +19,7 @@ if( $new ) { } else { $heading = "$icons{EDIT}{IMAGE}$text{'edit_host_title_edit'}"; } -&ui_print_header( $heading, $text{'title'}, "" ); +&ui_print_header( "$icons{ICON}{IMAGE}$text{'index_icon_items'}", $text{'title'}, "" ); my $host = $in{'host'}; my %h = $fw->GetHost($host); @@ -66,4 +66,4 @@ print ""; print &ui_form_end(); print "

"; -&ui_print_footer('list_items.cgi','items list'); +&ui_print_footer('list_items.cgi',$text{'index_items'}); diff --git a/src/turtlefirewall/edit_hostnameset.cgi b/src/turtlefirewall/edit_hostnameset.cgi index 33dca48..68b72c1 100644 --- a/src/turtlefirewall/edit_hostnameset.cgi +++ b/src/turtlefirewall/edit_hostnameset.cgi @@ -3,17 +3,17 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2026 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'}; -$hostnameset = $in{'hostnameset'}; -$newhostnameset = $in{'newhostnameset'}; +my $new = $in{'new'}; +my $hostnameset = $in{'hostnameset'}; +my $newhostnameset = $in{'newhostnameset'}; my $heading = ''; if( $new ) { @@ -21,7 +21,7 @@ if( $new ) { } else { $heading = "$icons{EDIT}{IMAGE}$text{'edit_hostnameset_title_edit'}"; } -&ui_print_header( $heading, $text{'title'}, "" ); +&ui_print_header( "$icons{ICON}{IMAGE}$text{'index_icon_items'}", $text{'title'}, "" ); my %h = $fw->GetHostNameSet($hostnameset); my $hostnames = $h{'HOSTNAMES'}; @@ -59,4 +59,4 @@ print ""; print &ui_form_end(); print "

"; -&ui_print_footer('list_items.cgi','items list'); +&ui_print_footer('list_items.cgi',$text{'index_items'}); diff --git a/src/turtlefirewall/edit_ipset.cgi b/src/turtlefirewall/edit_ipset.cgi index 06d97c2..7cf34eb 100644 --- a/src/turtlefirewall/edit_ipset.cgi +++ b/src/turtlefirewall/edit_ipset.cgi @@ -3,15 +3,15 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2026 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'}; +my $new = $in{'new'}; my $heading = ''; if( $new ) { @@ -19,7 +19,7 @@ if( $new ) { } else { $heading = "$icons{EDIT}{IMAGE}$text{'edit_ipset_title_edit'}"; } -&ui_print_header( $heading, $text{'title'}, "" ); +&ui_print_header( "$icons{ICON}{IMAGE}$text{'index_icon_items'}", $text{'title'}, "" ); my $ipset = $in{'ipset'}; my $newipset = $in{'newipset'}; @@ -64,4 +64,4 @@ print ""; print &ui_form_end(); print "

"; -&ui_print_footer('list_items.cgi','items list'); +&ui_print_footer('list_items.cgi',$text{'index_items'}); diff --git a/src/turtlefirewall/edit_masquerade.cgi b/src/turtlefirewall/edit_masquerade.cgi index 02c255c..5cffdc6 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-2026 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'}; +my $nMasq = $fw->GetMasqueradesCount(); + +my $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'}; @@ -33,7 +38,10 @@ if( $new ) { $is_masquerade = $masq{'MASQUERADE'} ne 'NO'; $active = $masq{'ACTIVE'} ne 'NO'; } -&ui_print_header( $heading, $text{'title'}, "" ); +&ui_print_header( "$icons{ICON}{IMAGE}$text{'index_icon_nat'}", $text{'title'}, "" ); + +my @idxs = (); +for( my $i=1; $i<=$nMasq; $i++ ) { push @idxs, $i; } my @items_src = ('*'); push @items_src, grep(!/FIREWALL/, $fw->GetZoneList()); @@ -59,17 +67,15 @@ 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); print &ui_columns_row([ "$icons{ZONE}{IMAGE}$text{'masq_dst'}", $col ], \@tds); $col = &formService($service, $port, 1); print &ui_columns_row([ "$icons{SERVICE}{IMAGE}$text{'rule_service'}", $col ], \@tds); -my @opts = ( [ 0, "$text{NO}
" ], [ 1, $text{YES} ] ); +my @opts = ( [ 0, "$text{NO}
" ], [ 1, "$text{YES}" ] ); $col = &ui_radio("masquerade", $is_masquerade ? 1 : 0, \@opts); print &ui_columns_row([ "$icons{MASQUERADE}{IMAGE}$text{'masq_masquerade'}", $col ], \@tds); $col = &ui_checkbox("active", 1, undef, $active ? 1 : 0); @@ -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",$text{'index_nat'}); diff --git a/src/turtlefirewall/edit_nat.cgi b/src/turtlefirewall/edit_nat.cgi index 83fdb3b..66ff5ab 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-2026 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'}; +my $nNat = $fw->GetNatsCount(); + +my $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'}; @@ -33,16 +38,19 @@ if( $new ) { $toport = $nat{'TOPORT'}; $active = $nat{'ACTIVE'} ne 'NO'; } -&ui_print_header( $heading, $text{'title'}, "" ); +&ui_print_header( "$icons{ICON}{IMAGE}$text{'index_icon_nat'}", $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",$text{'index_nat'}); diff --git a/src/turtlefirewall/edit_net.cgi b/src/turtlefirewall/edit_net.cgi index ed5dd05..a4b8a95 100644 --- a/src/turtlefirewall/edit_net.cgi +++ b/src/turtlefirewall/edit_net.cgi @@ -3,15 +3,15 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2026 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'}; +my $new = $in{'new'}; my $heading = ''; if( $new ) { @@ -19,7 +19,7 @@ if( $new ) { } else { $heading = "$icons{EDIT}{IMAGE}$text{'edit_net_title_edit'}"; } -&ui_print_header( $heading, $text{'title'}, "" ); +&ui_print_header( "$icons{ICON}{IMAGE}$text{'index_icon_items'}", $text{'title'}, "" ); my $net = $in{'net'}; my $newnet = $in{'newnet'}; @@ -65,4 +65,4 @@ print ""; print &ui_form_end(); print "

"; -&ui_print_footer('list_items.cgi','items list'); +&ui_print_footer('list_items.cgi',$text{'index_items'}); diff --git a/src/turtlefirewall/edit_options.cgi b/src/turtlefirewall/edit_options.cgi index cfe06f0..e5f7b09 100644 --- a/src/turtlefirewall/edit_options.cgi +++ b/src/turtlefirewall/edit_options.cgi @@ -3,14 +3,14 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2026 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'}, "" ); +&ui_print_header( "$icons{ICON}{IMAGE}$text{'index_icon_options'}", $text{'title'}, "" ); &getOptionsList(); diff --git a/src/turtlefirewall/edit_ratelimit.cgi b/src/turtlefirewall/edit_ratelimit.cgi index 57f1680..343388f 100644 --- a/src/turtlefirewall/edit_ratelimit.cgi +++ b/src/turtlefirewall/edit_ratelimit.cgi @@ -3,17 +3,17 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2026 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'}; -$ratelimit = $in{'ratelimit'}; -$newratelimit = $in{'newratelimit'}; +my $new = $in{'new'}; +my $ratelimit = $in{'ratelimit'}; +my $newratelimit = $in{'newratelimit'}; my $heading = ''; if( $new ) { @@ -21,7 +21,7 @@ if( $new ) { } else { $heading = "$icons{EDIT}{IMAGE}$text{'edit_ratelimit_title_edit'}"; } -&ui_print_header( $heading, $text{'title'}, "" ); +&ui_print_header( "$icons{ICON}{IMAGE}$text{'index_icon_items'}", $text{'title'}, "" ); my %r = $fw->GetRateLimit($ratelimit); my $rate = $r{'RATE'}; @@ -58,4 +58,4 @@ print ""; print &ui_form_end(); print "

"; -&ui_print_footer('list_items.cgi','items list'); +&ui_print_footer('list_items.cgi',$text{'index_items'}); diff --git a/src/turtlefirewall/edit_redirect.cgi b/src/turtlefirewall/edit_redirect.cgi index 4d4bbd6..845bcba 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-2026 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'}; +my $nRedirect = $fw->GetRedirectCount(); + +my $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'}; @@ -35,7 +40,10 @@ if( $new ) { $is_redirect = $redirect{'REDIRECT'} ne 'NO'; $active = $redirect{'ACTIVE'} ne 'NO'; } -&ui_print_header( $heading, $text{'title'}, "" ); +&ui_print_header( "$icons{ICON}{IMAGE}$text{'index_icon_nat'}", $text{'title'}, "" ); + +my @idxs = (); +for( my $i=1; $i<=$nRedirect; $i++ ) { push @idxs, $i; } my @items_src = (); push @items_src, grep(!/FIREWALL/, $fw->GetZoneList()); @@ -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",$text{'index_nat'}); diff --git a/src/turtlefirewall/edit_riskset.cgi b/src/turtlefirewall/edit_riskset.cgi index 6a410e4..095ee05 100644 --- a/src/turtlefirewall/edit_riskset.cgi +++ b/src/turtlefirewall/edit_riskset.cgi @@ -3,17 +3,17 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2026 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'}; -$riskset = $in{'riskset'}; -$newriskset = $in{'newriskset'}; +my $new = $in{'new'}; +my $riskset = $in{'riskset'}; +my $newriskset = $in{'newriskset'}; my $heading = ''; if( $new ) { @@ -21,7 +21,7 @@ if( $new ) { } else { $heading = "$icons{EDIT}{IMAGE}$text{'edit_riskset_title_edit'}"; } -&ui_print_header( $heading, $text{'title'}, "" ); +&ui_print_header( "$icons{ICON}{IMAGE}$text{'index_icon_items'}", $text{'title'}, "" ); my %r = $fw->GetRiskSet($riskset); my $risks = $r{'RISKS'}; @@ -44,7 +44,7 @@ for my $k (@risks) { } } my %risk = $fw->GetNdpiRisk($k); - my @opts = ( "$k", "$k - $risk{DESCRIPTION}" ); + my @opts = ( "$k", "$k - $risk{DESCRIPTION} - $risk{SEVERITY}" ); push(@items_risk, \@opts); } @@ -78,4 +78,4 @@ print ""; print &ui_form_end(); print "

"; -&ui_print_footer('list_items.cgi','items list'); +&ui_print_footer('list_items.cgi',$text{'index_items'}); diff --git a/src/turtlefirewall/edit_rule.cgi b/src/turtlefirewall/edit_rule.cgi index 46f0004..2ffe387 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-2026 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'}; +my $nRules = $fw->GetRulesCount(); + +my $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'}; @@ -49,7 +54,10 @@ if( $new ) { $log = $rule{'LOG'} eq 'YES'; $description = $rule{'DESCRIPTION'}; } -&ui_print_header( $heading, $text{'title'}, "" ); +&ui_print_header( "$icons{ICON}{IMAGE}$text{'index_icon_rules'}", $text{'title'}, "" ); + +my @idxs = (); +for( my $i=1; $i<=$nRules; $i++ ) { push @idxs, $i; } my @selected_src = split(/,/, $src); my @selected_dst = split(/,/, $dst); @@ -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); @@ -130,4 +136,4 @@ print ""; print &ui_form_end(); print "

"; -&ui_print_footer("list_rules.cgi?idx=$idx",'Rules list'); +&ui_print_footer("list_rules.cgi?idx=$idx",$text{'index_rules'}); diff --git a/src/turtlefirewall/edit_time.cgi b/src/turtlefirewall/edit_time.cgi index e24aa8a..a41e003 100644 --- a/src/turtlefirewall/edit_time.cgi +++ b/src/turtlefirewall/edit_time.cgi @@ -3,17 +3,17 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2026 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'}; -$time = $in{'time'}; -$newtime = $in{'newtime'}; +my $new = $in{'new'}; +my $time = $in{'time'}; +my $newtime = $in{'newtime'}; my $heading = ''; if( $new ) { @@ -21,7 +21,7 @@ if( $new ) { } else { $heading = "$icons{EDIT}{IMAGE}$text{'edit_time_title_edit'}"; } -&ui_print_header( $heading, $text{'title'}, "" ); +&ui_print_header( "$icons{ICON}{IMAGE}$text{'index_icon_items'}", $text{'title'}, "" ); my @aWeekdays = ('Mon','Tue','Wed','Thu','Fri','Sat','Sun'); @@ -77,4 +77,4 @@ print ""; print &ui_form_end(); print "

"; -&ui_print_footer('list_items.cgi','items list'); +&ui_print_footer('list_items.cgi',$text{'index_items'}); diff --git a/src/turtlefirewall/edit_timegroup.cgi b/src/turtlefirewall/edit_timegroup.cgi index 8f59935..2ab333a 100644 --- a/src/turtlefirewall/edit_timegroup.cgi +++ b/src/turtlefirewall/edit_timegroup.cgi @@ -3,17 +3,17 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2026 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'}; -$timegroup = $in{'timegroup'}; -$newtimegroup = $in{'newtimegroup'}; +my $new = $in{'new'}; +my $timegroup = $in{'timegroup'}; +my $newtimegroup = $in{'newtimegroup'}; my $heading = ''; if( $new ) { @@ -21,7 +21,7 @@ if( $new ) { } else { $heading = "$icons{EDIT}{IMAGE}$text{'edit_timegroup_title_edit'}"; } -&ui_print_header( $heading, $text{'title'}, "" ); +&ui_print_header( "$icons{ICON}{IMAGE}$text{'index_icon_items'}", $text{'title'}, "" ); my %g = $fw->GetTimeGroup($timegroup); my @selected_items = @{$g{ITEMS}}; @@ -59,4 +59,4 @@ print ""; print &ui_form_end(); print "

"; -&ui_print_footer('list_items.cgi','items list'); +&ui_print_footer('list_items.cgi',$text{'index_items'}); diff --git a/src/turtlefirewall/edit_zone.cgi b/src/turtlefirewall/edit_zone.cgi index 0ec1cd5..162c5b6 100644 --- a/src/turtlefirewall/edit_zone.cgi +++ b/src/turtlefirewall/edit_zone.cgi @@ -3,19 +3,19 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2026 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' ) { - redirect('list_items.cgi'); + &redirect('list_items.cgi'); } -$new = $in{'new'}; +my $new = $in{'new'}; my $heading = ''; if( $new ) { @@ -23,7 +23,7 @@ if( $new ) { } else { $heading = "$icons{EDIT}{IMAGE}$text{'edit_zone_title_edit'}"; } -&ui_print_header( $heading, $text{'title'}, "" ); +&ui_print_header( "$icons{ICON}{IMAGE}$text{'index_icon_items'}", $text{'title'}, "" ); my %z = $fw->GetZone($in{'zone'}); my $if = $z{'IF'}; @@ -60,4 +60,4 @@ print ""; print &ui_form_end(); print "

"; -&ui_print_footer('list_items.cgi','items list'); +&ui_print_footer('list_items.cgi',$text{'index_items'}); diff --git a/src/turtlefirewall/images/after.gif b/src/turtlefirewall/images/after.gif deleted file mode 100644 index f4c0eb1..0000000 Binary files a/src/turtlefirewall/images/after.gif and /dev/null differ diff --git a/src/turtlefirewall/images/before.gif b/src/turtlefirewall/images/before.gif deleted file mode 100644 index 5c1010e..0000000 Binary files a/src/turtlefirewall/images/before.gif and /dev/null differ diff --git a/src/turtlefirewall/images/backup.png b/src/turtlefirewall/images/configuration.png similarity index 100% rename from src/turtlefirewall/images/backup.png rename to src/turtlefirewall/images/configuration.png diff --git a/src/turtlefirewall/images/down5.gif b/src/turtlefirewall/images/down5.gif deleted file mode 100644 index e312839..0000000 Binary files a/src/turtlefirewall/images/down5.gif and /dev/null differ diff --git a/src/turtlefirewall/images/gap.gif b/src/turtlefirewall/images/gap.gif deleted file mode 100644 index 1a77764..0000000 Binary files a/src/turtlefirewall/images/gap.gif and /dev/null differ diff --git a/src/turtlefirewall/images/grey-helper.png b/src/turtlefirewall/images/grey-helper.png index b4778fc..3979a3c 100644 Binary files a/src/turtlefirewall/images/grey-helper.png and b/src/turtlefirewall/images/grey-helper.png differ diff --git a/src/turtlefirewall/images/grey-mark.png b/src/turtlefirewall/images/grey-mark.png index 9bd718b..0606d69 100644 Binary files a/src/turtlefirewall/images/grey-mark.png and b/src/turtlefirewall/images/grey-mark.png differ diff --git a/src/turtlefirewall/images/grey-nat.png b/src/turtlefirewall/images/grey-nat.png index 376ce9f..efb333f 100644 Binary files a/src/turtlefirewall/images/grey-nat.png and b/src/turtlefirewall/images/grey-nat.png differ diff --git a/src/turtlefirewall/images/grey-no.png b/src/turtlefirewall/images/grey-no.png index c985aef..298fea7 100644 Binary files a/src/turtlefirewall/images/grey-no.png and b/src/turtlefirewall/images/grey-no.png differ diff --git a/src/turtlefirewall/images/grey-reject.png b/src/turtlefirewall/images/grey-reject.png index 747cffe..1d15c4b 100644 Binary files a/src/turtlefirewall/images/grey-reject.png and b/src/turtlefirewall/images/grey-reject.png differ diff --git a/src/turtlefirewall/images/grey-yes.png b/src/turtlefirewall/images/grey-yes.png index 7c4470f..59bcd5e 100644 Binary files a/src/turtlefirewall/images/grey-yes.png and b/src/turtlefirewall/images/grey-yes.png differ diff --git a/src/turtlefirewall/images/helper.png b/src/turtlefirewall/images/helper.png index 2b77e44..a70ca91 100644 Binary files a/src/turtlefirewall/images/helper.png and b/src/turtlefirewall/images/helper.png differ diff --git a/src/turtlefirewall/images/hostnameset.png b/src/turtlefirewall/images/hostnameset.png index ed53304..c644686 100644 Binary files a/src/turtlefirewall/images/hostnameset.png and b/src/turtlefirewall/images/hostnameset.png differ diff --git a/src/turtlefirewall/images/icon.gif b/src/turtlefirewall/images/icon.gif index b7d7d49..9ff2a64 100644 Binary files a/src/turtlefirewall/images/icon.gif and b/src/turtlefirewall/images/icon.gif differ diff --git a/src/turtlefirewall/images/mark.png b/src/turtlefirewall/images/mark.png index 321002a..e835528 100644 Binary files a/src/turtlefirewall/images/mark.png and b/src/turtlefirewall/images/mark.png differ diff --git a/src/turtlefirewall/images/nat.png b/src/turtlefirewall/images/nat.png index f092b13..03ab93a 100644 Binary files a/src/turtlefirewall/images/nat.png and b/src/turtlefirewall/images/nat.png differ diff --git a/src/turtlefirewall/images/no.png b/src/turtlefirewall/images/no.png index f568315..102a6cb 100644 Binary files a/src/turtlefirewall/images/no.png and b/src/turtlefirewall/images/no.png differ diff --git a/src/turtlefirewall/images/red-nat.png b/src/turtlefirewall/images/red-nat.png index 2739d3f..8877df4 100644 Binary files a/src/turtlefirewall/images/red-nat.png and b/src/turtlefirewall/images/red-nat.png differ diff --git a/src/turtlefirewall/images/ref.png b/src/turtlefirewall/images/ref.png new file mode 100644 index 0000000..b4d7a0c Binary files /dev/null and b/src/turtlefirewall/images/ref.png differ diff --git a/src/turtlefirewall/images/reject.png b/src/turtlefirewall/images/reject.png index 00f1fba..39e68aa 100644 Binary files a/src/turtlefirewall/images/reject.png and b/src/turtlefirewall/images/reject.png differ diff --git a/src/turtlefirewall/images/shield.png b/src/turtlefirewall/images/shield.png deleted file mode 100644 index 8260d4e..0000000 Binary files a/src/turtlefirewall/images/shield.png and /dev/null differ diff --git a/src/turtlefirewall/images/up5.gif b/src/turtlefirewall/images/up5.gif deleted file mode 100644 index b4163bd..0000000 Binary files a/src/turtlefirewall/images/up5.gif and /dev/null differ diff --git a/src/turtlefirewall/images/yes.png b/src/turtlefirewall/images/yes.png index 3586249..abc6cc5 100644 Binary files a/src/turtlefirewall/images/yes.png and b/src/turtlefirewall/images/yes.png differ diff --git a/src/turtlefirewall/index.cgi b/src/turtlefirewall/index.cgi index 08cd2de..0df96d2 100644 --- a/src/turtlefirewall/index.cgi +++ b/src/turtlefirewall/index.cgi @@ -3,16 +3,16 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2026 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, - &help_search_link("iptables", "man", "doc")); +&ui_print_header( "$icons{ICON}{IMAGE} v ".$fw->Version(), $text{'title'}, "", undef, 1, 1, 0, + &help_search_link("iptables", "man", "doc")); my @olinks = ('list_items.cgi', 'list_services.cgi', @@ -20,21 +20,21 @@ my @olinks = ('list_items.cgi', 'list_ndpirisks.cgi', 'list_countrycodes.cgi', 'edit_options.cgi', - 'backup.cgi'); -my @otitles = ($text{'index_icon_firewall_items'}, - $text{'index_icon_firewall_services'}, - $text{'index_icon_firewall_ndpiprotocols'}, - $text{'index_icon_firewall_ndpirisks'}, - $text{'index_icon_firewall_countrycodes'}, - $text{'index_icon_edit_options'}, - $text{'index_icon_backup'}); + 'configuration.cgi'); +my @otitles = ($text{'index_icon_items'}, + $text{'index_icon_services'}, + $text{'index_icon_ndpiprotocols'}, + $text{'index_icon_ndpirisks'}, + $text{'index_icon_countrycodes'}, + $text{'index_icon_options'}, + $text{'index_icon_configuration'}); my @oicons = ('images/items.png', 'images/services.png', 'images/ndpiprotocols.png', 'images/ndpirisks.png', 'images/countrycodes.png', 'images/options.png', - 'images/backup.png'); + 'images/configuration.png'); &icons_table(\@olinks, \@otitles, \@oicons, 10); print &ui_hr(); @@ -42,10 +42,10 @@ my @rlinks = ('list_rules.cgi', 'list_nat.cgi', 'list_manglerules.cgi', 'list_rawrules.cgi'); -my @rtitles = ($text{'index_icon_firewall_rules'}, - $text{'index_icon_firewall_nat'}, - $text{'index_icon_firewall_manglerules'}, - $text{'index_icon_firewall_rawrules'}); +my @rtitles = ($text{'index_icon_rules'}, + $text{'index_icon_nat'}, + $text{'index_icon_manglerules'}, + $text{'index_icon_rawrules'}); my @ricons = ('images/rules.png', 'images/nats.png', 'images/manglerules.png', @@ -105,9 +105,9 @@ print ''; print &ui_form_end(); if( $in{showiptfilter} ne '' ) { - print "
- -
FILTER
"; + print "
+ +
FILTER
"; print "
";
 	print qx{iptables -L -n -v -x 2>&1};
 	#print qx{nft list table ip filter 2>&1};
@@ -116,9 +116,9 @@ if( $in{showiptfilter} ne '' ) {
 }
 
 if( $in{showiptnat} ne '' ) {
-	print "
- -
NAT
"; + print "
+ +
NAT
"; print "
";
 	print qx{iptables -t nat -L -n -v -x 2>&1};
 	#print qx{nft list table ip nat 2>&1};
@@ -127,9 +127,9 @@ if( $in{showiptnat} ne '' ) {
 }
 
 if( $in{showiptmangle} ne '' ) {
-	print "
- -
MANGLE
"; + print "
+ +
MANGLE
"; print "
";
 	print qx{iptables -t mangle -L -n -v -x 2>&1};
 	#print qx{nft list table ip mangle 2>&1};
@@ -138,9 +138,9 @@ if( $in{showiptmangle} ne '' ) {
 }
 
 if( $in{showiptraw} ne '' ) {
-	print "
- -
RAW
"; + print "
+ +
RAW
"; print "
";
 	print qx{iptables -t raw -L -n -v -x 2>&1};
 	#print qx{nft list table ip raw 2>&1};
@@ -149,9 +149,9 @@ if( $in{showiptraw} ne '' ) {
 }
 
 if( $in{showconntrack} ne '' ) {
-	print "
- -
CONNTRACK
"; + print "
+ +
CONNTRACK
"; print "
";
 	print qx{/usr/sbin/conntrack -L -o extended};
 	print "
"; @@ -159,9 +159,9 @@ if( $in{showconntrack} ne '' ) { } if( $in{flushconntrack} ne '' ) { - print "
- -
CONNTRACK
"; + print "
+ +
CONNTRACK
"; print "
";
 	print qx{/usr/sbin/conntrack -F 2>&1};
 	print "
"; diff --git a/src/turtlefirewall/install_check.pl b/src/turtlefirewall/install_check.pl index fee82ae..b7e9cd6 100644 --- a/src/turtlefirewall/install_check.pl +++ b/src/turtlefirewall/install_check.pl @@ -1,6 +1,14 @@ -# install_check.pl +#!/usr/bin/perl -do 'turtlefirewall-lib.pl'; +#====================================================================== +# Turtle Firewall webmin module +# +# Copyright (c) 2001-2026 Andrea Frigido +# You may distribute under the terms of either the GNU General Public +# License +#====================================================================== + +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..9b75bb2 100644 --- a/src/turtlefirewall/lang/de +++ b/src/turtlefirewall/lang/de @@ -32,6 +32,7 @@ time=Time timeitems=Weekdays name=Name id=ID +rule=Filter nat=NAT masquerade=Masquerade connmark_preroute=Connmark Preroute @@ -82,8 +83,17 @@ items=Items reference=Ref references=References file=File +flag=DPI +severity=Severity category=Category index=Turtle Firewall index +index_configuration=Configuration index +index_items=Items index +index_flowstat=Flow Statistics index +index_manglerules=Mangle Rules index +index_rawrules=Raw Rules index +index_nat=NAT index +index_rules=Filter Rules index index_start=Start index_stop=Stop index_restart=Änderungen übernehmen @@ -93,22 +103,21 @@ index_showiptmangle=Show MANGLE Table index_showiptraw=Show RAW Table index_showconntrack=Show CONNTRACK Table index_flushconntrack=Flush CONNTRACK Table -index_icon_firewall_items=Objekte -index_icon_firewall_rules=Regeln -index_icon_firewall_nat=NAT und Masquerading -index_icon_firewall_manglerules=Mangle Rules -index_icon_firewall_rawrules=Raw Rules -index_icon_firewall_services=Dienste -index_icon_firewall_countrycodes=Country Codes -index_icon_firewall_ndpiprotocols=nDPI Services -index_icon_firewall_ndpirisks=nDPI Risks -index_icon_edit_options=Optionen -index_icon_log=Log +index_icon_items=Objekte +index_icon_rules=Regeln +index_icon_nat=NAT und Masquerading +index_icon_manglerules=Mangle Rules +index_icon_rawrules=Raw Rules +index_icon_services=Dienste +index_icon_countrycodes=Country Codes +index_icon_ndpiprotocols=nDPI Services +index_icon_ndpirisks=nDPI Risks +index_icon_options=Optionen +index_icon_log=Action Log index_icon_flowlog=Flow Log index_icon_flowstat=Flow Statistics -index_icon_backup=Backup +index_icon_configuration=Configuration list_itemreferences_title=Item References -list_items_title=Firewall Objekte list_items_create_zone=neue Zone erstellen list_items_create_geoip=create new geoip list_items_create_net=neues Netz erstellen @@ -145,14 +154,12 @@ edit_addresslist_title_create=Create new AddressList edit_addresslist_title_edit=Edit AddressList edit_ipset_title_create=Create new IPSet edit_ipset_title_edit=Edit IPSet -list_nat_title=NAT und Masquerading list_nat_create_nat=neues NAT erstellen list_nat_create_masq=neues Masquerading erstellen edit_nat_title_create=NAT erstellen edit_nat_title_edit=NAT bearbeiten edit_masq_title_create=Masquerading erstellen edit_masq_title_edit=Masquerading bearbeiten -list_rules_title=Firewall-Regeln list_rules_create_rule=neue Regel erstellen list_connmarkpreroutes_create_rule=create new Connmark Preroute list_connmarks_create_rule=create new Connmark @@ -160,7 +167,6 @@ list_conntrackpreroutes_create_rule=create new Conntrack Preroute list_conntracks_create_rule=create new Conntrack edit_rule_title_create=Regel erstellen edit_rule_title_edit=Regel bearbeiten -list_manglerules_title=Mangle Rules edit_conntrackpreroute_title_create=Create new Conntrack Preroute edit_conntrack_title_create=Create new Conntrack edit_connmarkpreroute_title_create=Create new Connmark Preroute @@ -169,11 +175,7 @@ edit_conntrackpreroute_title_edit=Edit Conntrack Preroute edit_conntrack_title_edit=Edit Conntrack edit_connmarkpreroute_title_edit=Edit Connmark Preroute edit_connmark_title_edit=Edit Connmark -list_rawrules_title=Raw Rules -list_services_title=Dienste list_countrycodes_title=Country Codes -list_ndpiprotocols_title=nDPI Services -list_ndpirisks_title=nDPI Risks redirect_src=Quelle redirect_dst=Ziel redirect_service=Dienst @@ -190,26 +192,38 @@ 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 +flowlog_current=Current Flow Log +flowlog_all=All Historical Flow Logs 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,25 +247,22 @@ 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 options_log_limit_burst_desc=Maximum initial number of packets to log: this number gets recharged by one every time the limit specified above is not reached, up to this number. - -backup_title=Backup -backup_backuptitle=Backup -backup_restoretitle=Restore -backup_index_download=Download Config -backup_index_restore=Upload Config -backup_error_title1=Restore failed -backup_error1=Fail to execute tar/gzip commands +configuration_index_download=Backup +configuration_index_restore=Restore +configuration_error_title1=Restore failed +configuration_error1=Fail to execute tar/gzip commands +configuration_error2=Error during backup save_zone_error_title1=Fail to delete zone save_zone_error_title2=Fail to create new zone @@ -421,9 +432,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 +458,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..44445b0 100644 --- a/src/turtlefirewall/lang/en +++ b/src/turtlefirewall/lang/en @@ -32,6 +32,7 @@ time=Time timeitems=Weekdays name=Name id=ID +rule=Filter nat=NAT masquerade=Masquerade connmark_preroute=Connmark Preroute @@ -82,8 +83,17 @@ items=Items reference=Ref references=References file=File +flag=DPI +severity=Severity category=Category index=Turtle Firewall index +index_configuration=Configuration index +index_items=Items index +index_flowstat=Flow Statistics index +index_manglerules=Mangle Rules index +index_rawrules=Raw Rules index +index_nat=NAT index +index_rules=Filter Rules index index_start=Start index_stop=Stop index_restart=Apply Configuration @@ -93,22 +103,21 @@ index_showiptmangle=Show MANGLE Table index_showiptraw=Show RAW Table index_showconntrack=Show CONNTRACK Table index_flushconntrack=Flush CONNTRACK Table -index_icon_firewall_items=Items -index_icon_firewall_rules=Filter Rules -index_icon_firewall_nat=NAT Rules -index_icon_firewall_manglerules=Mangle Rules -index_icon_firewall_rawrules=Raw Rules -index_icon_firewall_services=Port Services -index_icon_firewall_countrycodes=Country Codes -index_icon_firewall_ndpiprotocols=nDPI Services -index_icon_firewall_ndpirisks=nDPI Risks -index_icon_edit_options=Options +index_icon_items=Items +index_icon_rules=Filter Rules +index_icon_nat=NAT Rules +index_icon_manglerules=Mangle Rules +index_icon_rawrules=Raw Rules +index_icon_services=Port Services +index_icon_countrycodes=Country Codes +index_icon_ndpiprotocols=nDPI Services +index_icon_ndpirisks=nDPI Risks +index_icon_options=Options index_icon_log=Action Log index_icon_flowlog=Flow Log index_icon_flowstat=Flow Statistics -index_icon_backup=Backup +index_icon_configuration=Configuration list_itemreferences_title=Item References -list_items_title=Items list_items_create_zone=create new zone list_items_create_geoip=create new geoip list_items_create_net=create new net @@ -145,14 +154,12 @@ edit_addresslist_title_create=Create new AddressList edit_addresslist_title_edit=Edit AddressList edit_ipset_title_create=Create new IPSet edit_ipset_title_edit=Edit IPSet -list_nat_title=NAT Rules list_nat_create_nat=create new NAT list_nat_create_masq=create new Masquerade edit_nat_title_create=Create new NAT edit_nat_title_edit=Edit NAT edit_masq_title_create=Create new Masquerade edit_masq_title_edit=Edit Masquerade -list_rules_title=Filter Rules list_rules_create_rule=create new Rule list_connmarkpreroutes_create_rule=create new Connmark Preroute list_connmarks_create_rule=create new Connmark @@ -160,7 +167,6 @@ list_conntrackpreroutes_create_rule=create new Conntrack Preroute list_conntracks_create_rule=create new Conntrack edit_rule_title_create=Create new Rule edit_rule_title_edit=Edit Rule -list_manglerules_title=Mangle Rules edit_conntrackpreroute_title_create=Create new Conntrack Preroute edit_conntrack_title_create=Create new Conntrack edit_connmarkpreroute_title_create=Create new Connmark Preroute @@ -169,11 +175,6 @@ edit_conntrackpreroute_title_edit=Edit Conntrack Preroute edit_conntrack_title_edit=Edit Conntrack edit_connmarkpreroute_title_edit=Edit Connmark Preroute edit_connmark_title_edit=Edit Connmark -list_rawrules_title=Raw Rules -list_services_title=Port Services -list_countrycodes_title=Country Codes -list_ndpiprotocols_title=nDPI Services -list_ndpirisks_title=nDPI Risks redirect_src=Source redirect_dst=Destination redirect_service=Port Service @@ -190,26 +191,38 @@ 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 +flowlog_current=Current Flow Log +flowlog_all=All Historical Flow Logs 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,25 +246,22 @@ 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 options_log_limit_burst_desc=Maximum initial number of packets to log: this number gets recharged by one every time the limit specified above is not reached, up to this number. - -backup_title=Backup -backup_backuptitle=Backup -backup_restoretitle=Restore -backup_index_download=Download Config -backup_index_restore=Upload Config -backup_error_title1=Restore failed -backup_error1=Fail to execute tar/gzip commands +configuration_index_download=Backup +configuration_index_restore=Restore +configuration_error_title1=Restore failed +configuration_error1=Fail to execute tar/gzip commands +configuration_error2=Error during backup save_zone_error_title1=Fail to delete zone save_zone_error_title2=Fail to create new zone @@ -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..9a34c51 100644 --- a/src/turtlefirewall/lang/fr +++ b/src/turtlefirewall/lang/fr @@ -32,6 +32,7 @@ time=Time timeitems=Weekdays name=Nom id=ID +rule=Filter nat=NAT masquerade=Masquerade connmark_preroute=Connmark Preroute @@ -82,8 +83,17 @@ items=Items reference=Ref references=References file=File +flag=DPI +severity=Severity category=Category index=Turtle Firewall index +index_configuration=Configuration index +index_items=Items index +index_flowstat=Flow Statistics index +index_manglerules=Mangle Rules index +index_rawrules=Raw Rules index +index_nat=NAT index +index_rules=Filter Rules index index_start=Start index_stop=Stop index_restart=Appliquer les changements @@ -93,22 +103,21 @@ index_showiptmangle=Show MANGLE Table index_showiptraw=Show RAW Table index_showconntrack=Show CONNTRACK Table index_flushconntrack=Flush CONNTRACK Table -index_icon_firewall_items=Eléments -index_icon_firewall_rules=Règles -index_icon_firewall_nat=NAT et Masquerade -index_icon_firewall_manglerules=Mangle Rules -index_icon_firewall_rawrules=Raw Rules -index_icon_firewall_services=Services -index_icon_firewall_countrycodes=Country Codes -index_icon_firewall_ndpiprotocols=nDPI Services -index_icon_firewall_ndpirisks=nDPI Risks -index_icon_edit_options=Options -index_icon_log=Log +index_icon_items=Eléments +index_icon_rules=Règles +index_icon_nat=NAT et Masquerade +index_icon_manglerules=Mangle Rules +index_icon_rawrules=Raw Rules +index_icon_services=Services +index_icon_countrycodes=Country Codes +index_icon_ndpiprotocols=nDPI Services +index_icon_ndpirisks=nDPI Risks +index_icon_options=Options +index_icon_log=Action Log index_icon_flowlog=Flow Log index_icon_flowstat=Flow Statistics -index_icon_backup=Backup +index_icon_configuration=Configuration list_itemreferences_title=Item References -list_items_title=Eléments du Firewall list_items_create_zone=créer une nouvelle zone list_items_create_geoip=create new geoip list_items_create_net=créer un nouveau réseau @@ -145,14 +154,12 @@ edit_addresslist_title_create=Create new AddressList edit_addresslist_title_edit=Edit AddressList edit_ipset_title_create=Create new IPSet edit_ipset_title_edit=Edit IPSet -list_nat_title=NAT et Masquerade list_nat_create_nat=créer un nouveau NAT list_nat_create_masq=créer un nouveau Masquerade edit_nat_title_create=Créer NAT edit_nat_title_edit=Editer NAT edit_masq_title_create=Créer Masquerade edit_masq_title_edit=Editer Masquerade -list_rules_title=Règles du Firewall list_rules_create_rule=créer une nouvelle règle list_connmarkpreroutes_create_rule=create new Connmark Preroute list_connmarks_create_rule=create new Connmark @@ -160,7 +167,6 @@ list_conntrackpreroutes_create_rule=create new Conntrack Preroute list_conntracks_create_rule=create new Conntrack edit_rule_title_create=Créer la règle edit_rule_title_edit=Editer la règle -list_manglerules_title=Mangle Rules edit_conntrackpreroute_title_create=Create new Conntrack Preroute edit_conntrack_title_create=Create new Conntrack edit_connmarkpreroute_title_create=Create new Connmark Preroute @@ -169,11 +175,7 @@ edit_conntrackpreroute_title_edit=Edit Conntrack Preroute edit_conntrack_title_edit=Edit Conntrack edit_connmarkpreroute_title_edit=Edit Connmark Preroute edit_connmark_title_edit=Edit Connmark -list_rawrules_title=Raw Rules -list_services_title=Services list_countrycodes_title=Country Codes -list_ndpiprotocols_title=nDPI Services -list_ndpirisks_title=nDPI Risks redirect_src=Source redirect_dst=Destination redirect_service=Port Service @@ -190,26 +192,38 @@ 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 +flowlog_current=Current Flow Log +flowlog_all=All Historical Flow Logs 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,25 +247,22 @@ 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 options_log_limit_burst_desc=Maximum initial number of packets to log: this number gets recharged by one every time the limit specified above is not reached, up to this number. - -backup_title=Backup -backup_backuptitle=Backup -backup_restoretitle=Restore -backup_index_download=Download Config -backup_index_restore=Upload Config -backup_error_title1=Restore failed -backup_error1=Fail to execute tar/gzip commands +configuration_index_download=Backup +configuration_index_restore=Restore +configuration_error_title1=Restore failed +configuration_error1=Fail to execute tar/gzip commands +configuration_error2=Error during backup save_zone_error_title1=Fail to delete zone save_zone_error_title2=Fail to create new zone @@ -421,9 +432,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 +458,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..7c9dbf8 100644 --- a/src/turtlefirewall/lang/it +++ b/src/turtlefirewall/lang/it @@ -32,6 +32,7 @@ time=Time timeitems=Weekdays name=Nome id=ID +rule=Filter nat=NAT masquerade=Mascheramento connmark_preroute=Connmark Preroute @@ -82,8 +83,17 @@ items=Items reference=Ref references=References file=File +flag=DPI +severity=Severity category=Category index=Turtle Firewall index +index_configuration=Configuration index +index_items=Items index +index_flowstat=Flow Statistics index +index_manglerules=Mangle Rules index +index_rawrules=Raw Rules index +index_nat=NAT index +index_rules=Filter Rules index index_start=Attiva Firewall index_stop=Disattiva Firewall index_restart=Applica le modifiche @@ -93,22 +103,21 @@ index_showiptmangle=Show MANGLE Table index_showiptraw=Show RAW Table index_showconntrack=Show CONNTRACK Table index_flushconntrack=Flush CONNTRACK Table -index_icon_firewall_items=Elementi -index_icon_firewall_rules=Regole -index_icon_firewall_nat=NAT, Mascheramento e Redirezione -index_icon_firewall_manglerules=Mangle Rules -index_icon_firewall_rawrules=Raw Rules -index_icon_firewall_services=Servizi -index_icon_firewall_countrycodes=Country Codes -index_icon_firewall_ndpiprotocols=nDPI Services -index_icon_firewall_ndpirisks=nDPI Risks -index_icon_edit_options=Opzioni -index_icon_log=Log +index_icon_items=Elementi +index_icon_rules=Regole +index_icon_nat=NAT, Mascheramento e Redirezione +index_icon_manglerules=Mangle Rules +index_icon_rawrules=Raw Rules +index_icon_services=Servizi +index_icon_countrycodes=Country Codes +index_icon_ndpiprotocols=nDPI Services +index_icon_ndpirisks=nDPI Risks +index_icon_options=Opzioni +index_icon_log=Action Log index_icon_flowlog=Flow Log index_icon_flowstat=Flow Statistics -index_icon_backup=Backup Configurazione +index_icon_configuration=Configurazione list_itemreferences_title=Item References -list_items_title=Elementi del firewall list_items_create_zone=crea una nuova zona list_items_create_geoip=create new geoip list_items_create_net=crea una nuova rete @@ -145,14 +154,12 @@ edit_addresslist_title_create=Create new AddressList edit_addresslist_title_edit=Edit AddressList edit_ipset_title_create=Create new IPSet edit_ipset_title_edit=Edit IPSet -list_nat_title=NAT, Mascheramento e Redirezione list_nat_create_nat=crea una nuova regola NAT list_nat_create_masq=crea un nuovo mascheramento edit_nat_title_create=Crea NAT edit_nat_title_edit=Modifica NAT edit_masq_title_create=Crea nuovo Mascheramento edit_masq_title_edit=Modifica Mascheramento -list_rules_title=Regole del Firewall list_rules_create_rule=crea una nuova regola list_connmarkpreroutes_create_rule=create new Connmark Preroute list_connmarks_create_rule=create new Connmark @@ -160,7 +167,6 @@ list_conntrackpreroutes_create_rule=create new Conntrack Preroute list_conntracks_create_rule=create new Conntrack edit_rule_title_create=Crea una regola edit_rule_title_edit=Modifica una regola -list_manglerules_title=Mangle Rules edit_conntrackpreroute_title_create=Create new Conntrack Preroute edit_conntrack_title_create=Create new Conntrack edit_connmarkpreroute_title_create=Create new Connmark Preroute @@ -169,11 +175,7 @@ edit_conntrackpreroute_title_edit=Edit Conntrack Preroute edit_conntrack_title_edit=Edit Conntrack edit_connmarkpreroute_title_edit=Edit Connmark Preroute edit_connmark_title_edit=Edit Connmark -list_rawrules_title=Raw Rules -list_services_title=Servizi list_countrycodes_title=Country Codes -list_ndpiprotocols_title=nDPI Services -list_ndpirisks_title=nDPI Risks redirect_src=Sorgente redirect_dst=Destinazione redirect_service=Servizio @@ -190,26 +192,38 @@ 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 +flowlog_current=Current Flow Log +flowlog_all=All Historical Flow Logs 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,25 +247,22 @@ 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 options_log_limit_burst_desc=Numero di log generati inizialmente. Ogni volta che viene raggiunto il tempo "limit" senza la generazione di log, questo valore viene incrementato di una unità. - -backup_title=Backup Configurazione -backup_backuptitle=Backup -backup_restoretitle=Restore -backup_index_download=Download Config -backup_index_restore=Upload Config -backup_error_title1=Restore fallito -backup_error1=Errore eseguendo i comandi tar/gzip. +configuration_index_download=Backup +configuration_index_restore=Restore +configuration_error_title1=Restore fallito +configuration_error1=Errore eseguendo i comandi tar/gzip. +configuration_error2=Error during backup save_zone_error_title1=Errore eliminando la zona save_zone_error_title2=Errore creando la zona @@ -421,9 +432,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 +458,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..22c019c 100644 --- a/src/turtlefirewall/lang/nl +++ b/src/turtlefirewall/lang/nl @@ -32,6 +32,7 @@ time=Time timeitems=Weekdays name=Naam id=ID +rule=Filter nat=NAT masquerade=Verbergen connmark_preroute=Connmark Preroute @@ -82,8 +83,17 @@ items=Items reference=Ref references=References file=File +flag=DPI +severity=Severity category=Category index=Turtle Firewall index +index_configuration=Configuration index +index_items=Items index +index_flowstat=Flow Statistics index +index_manglerules=Mangle Rules index +index_rawrules=Raw Rules index +index_nat=NAT index +index_rules=Filter Rules index index_start=Start index_stop=Stop index_restart=Verwerken wijzigingen @@ -93,22 +103,21 @@ index_showiptmangle=Show MANGLE Table index_showiptraw=Show RAW Table index_showconntrack=Show CONNTRACK Table index_flushconntrack=Flush CONNTRACK Table -index_icon_firewall_items=Objecten -index_icon_firewall_rules=Regels -index_icon_firewall_nat=NAT en Masquerading -index_icon_firewall_manglerules=Mangle Rules -index_icon_firewall_rawrules=Raw Rules -index_icon_firewall_services=Diensten -index_icon_firewall_countrycodes=Country Codes -index_icon_firewall_ndpiprotocols=nDPI Services -index_icon_firewall_ndpirisks=nDPI Risks -index_icon_edit_options=Options -index_icon_log=Log +index_icon_items=Objecten +index_icon_rules=Regels +index_icon_nat=NAT en Masquerading +index_icon_manglerules=Mangle Rules +index_icon_rawrules=Raw Rules +index_icon_services=Diensten +index_icon_countrycodes=Country Codes +index_icon_ndpiprotocols=nDPI Services +index_icon_ndpirisks=nDPI Risks +index_icon_options=Options +index_icon_log=Action Log index_icon_flowlog=Flow Log index_icon_flowstat=Flow Statistics -index_icon_backup=Backup +index_icon_configuration=Configuration list_itemreferences_title=Item References -list_items_title=Firewall Objecten list_items_create_zone=Toevoegen nieuwe zone list_items_create_geoip=create new geoip list_items_create_net=Toevoegen nieuw netwerk @@ -145,14 +154,12 @@ edit_addresslist_title_create=Create new AddressList edit_addresslist_title_edit=Edit AddressList edit_ipset_title_create=Create new IPSet edit_ipset_title_edit=Edit IPSet -list_nat_title=NAT en Masquerading list_nat_create_nat=Toevoegen NAT regel list_nat_create_masq=Toevoegen Masquerade regel edit_nat_title_create=NAT toevoegen edit_nat_title_edit=NAT wijzigen edit_masq_title_create=Masquerade toevoegen edit_masq_title_edit=Masquerade wijzigen -list_rules_title=Firewall regels list_rules_create_rule=Regel toevoegen list_connmarkpreroutes_create_rule=create new Connmark Preroute list_connmarks_create_rule=create new Connmark @@ -160,7 +167,6 @@ list_conntrackpreroutes_create_rule=create new Conntrack Preroute list_conntracks_create_rule=create new Conntrack edit_rule_title_create=Regel toevoegen edit_rule_title_edit=Regel wijzigen -list_manglerules_title=Mangle Rules edit_conntrackpreroute_title_create=Create new Conntrack Preroute edit_conntrack_title_create=Create new Conntrack edit_connmarkpreroute_title_create=Create new Connmark Preroute @@ -169,11 +175,7 @@ edit_conntrackpreroute_title_edit=Edit Conntrack Preroute edit_conntrack_title_edit=Edit Conntrack edit_connmarkpreroute_title_edit=Edit Connmark Preroute edit_connmark_title_edit=Edit Connmark -list_rawrules_title=Raw Rules -list_services_title=Diensten list_countrycodes_title=Country Codes -list_ndpiprotocols_title=nDPI Services -list_ndpirisks_title=nDPI Risks redirect_src=Bron redirect_dst=Doel redirect_service=Dienst @@ -190,26 +192,38 @@ 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 +flowlog_current=Current Flow Log +flowlog_all=All Historical Flow Logs 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,25 +247,22 @@ 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 options_log_limit_burst_desc=Maximum initial number of packets to log: this number gets recharged by one every time the limit specified above is not reached, up to this number. - -backup_title=Backup -backup_backuptitle=Backup -backup_restoretitle=Restore -backup_index_download=Download Config -backup_index_restore=Upload Config -backup_error_title1=Restore failed -backup_error1=Fail to execute tar/gzip commands +configuration_index_download=Backup +configuration_index_restore=Restore +configuration_error_title1=Restore failed +configuration_error1=Fail to execute tar/gzip commands +configuration_error2=Error during backup save_zone_error_title1=Fail to delete zone save_zone_error_title2=Fail to create new zone @@ -421,9 +432,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 +458,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..09baf3a 100644 --- a/src/turtlefirewall/list_actionlog.cgi +++ b/src/turtlefirewall/list_actionlog.cgi @@ -3,15 +3,15 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2026 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'}, "" ); +&ui_print_header( "$icons{ICON}{IMAGE}$text{'index_icon_log'}", $text{'title'}, "" ); &showLog(); @@ -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 = ''; @@ -108,90 +107,80 @@ sub showLog { $lastpag = int(($count-1) / $pagelen) + 1; if( $pag < $lastpag ) { $pageindex .= " > "; - $pageindex .= qq~ >> ~; + $pageindex .= " >> "; } print &ui_form_start("list_actionlog.cgi", "post"); - print "
$pageindex
\n"; + print "
$pageindex
\n"; my $opz; - local @head; + my @head = (); - local $hdate; - $hdate .= "DATE
"; - push(@head, $hdate ); + my $hdate = "DATE
"; + push(@head, $hdate ); - local $haction; - $haction .= "ACTION
"; + foreach $opz (sort keys %action_list) {$haction .= "$opz";} $haction .= "
"; push(@head, $haction ); - local $hin; - $hin .= "IN
"; + foreach $opz (sort keys %in_list) {$hin .= "$opz";} $hin .= "
"; push(@head, $hin ); - local $hout; - $hout .= "OUT
"; + foreach $opz (sort keys %out_list) {$hout .= "$opz";} $hout .= "
"; push(@head, $hout ); - local $hsrc; - $hsrc .= "SRC
"; + foreach $opz (sort keys %src_list) {$hsrc .= "$opz";} $hsrc .= "
"; push(@head, $hsrc ); - local $hdst; - $hdst .= "DST
"; + foreach $opz (sort keys %dst_list) {$hdst .= "$opz";} $hdst .= "
"; push(@head, $hdst ); - local $hproto; - $hproto .= "PROTO
"; + foreach $opz (sort keys %proto_list) {$hproto .= "$opz";} $hproto .= "
"; push(@head, $hproto ); - local $hspt; - $hspt .= "SPORT
"; + foreach $opz (sort keys %spt_list) {$hspt .= "$opz";} $hspt .= "
"; push(@head, $hspt ); - local $hdpt; - $hdpt .= "DPORT
"; + foreach $opz (sort keys %dpt_list) {$hdpt .= "$opz";} $hdpt .= "
"; push(@head, $hdpt ); - local $hmac; - $hmac .= "MAC
"; + foreach $opz (sort keys %mac_list) {$hmac .= "$opz";} $hmac .= "
"; push(@head, $hmac ); - @tds = ( "style=white-space:nowrap", "style=text-align:center", "style=text-align:center", "", "", "", "style=text-align:center", "", "", "" ); + my @tds = ( "style=white-space:nowrap", "style=text-align:center", "style=text-align:center", "", "", "", "style=text-align:center", "", "", "" ); print &ui_columns_start(\@head, 100, 0, \@tds); foreach my $l (@buffer) { - local @cols; + my @cols = (); my ($time, $action, $in, $out, $mac, $src, $dst, $proto, $spt, $dpt) = @$l; - &showTD($time); - &showTD($action); - &showTD($in); - &showTD($out); - &showTD($src); - &showTD($dst); - &showTD($proto); - &showTD($spt); - &showTD($dpt); - &showTD($mac); + push(@cols, "".($time eq '' ? " " : "$time").""); + push(@cols, "".($action eq '' ? " " : "$action").""); + push(@cols, "".($in eq '' ? " " : "$in").""); + push(@cols, "".($out eq '' ? " " : "$out").""); + push(@cols, "".($mac eq '' ? " " : "$mac").""); + push(@cols, "".($src eq '' ? " " : "$src").""); + push(@cols, "".($dst eq '' ? " " : "$dst").""); + push(@cols, "".($proto eq '' ? " " : "$proto").""); + push(@cols, "".($spt eq '' ? " " : "$spt").""); + push(@cols, "".($dpt eq '' ? " " : "$dpt").""); print &ui_columns_row(\@cols, \@tds); } print &ui_columns_end(); @@ -202,11 +191,5 @@ sub showLog { print &ui_form_end(); - print "
$pageindex
\n"; -} - -sub showTD { - my $text = shift; - if( $text eq '' ) { $text = ' '; } - push(@cols, "$text"); + print "
$pageindex
\n"; } diff --git a/src/turtlefirewall/list_countrycodes.cgi b/src/turtlefirewall/list_countrycodes.cgi index 06db042..2cd6ec7 100644 --- a/src/turtlefirewall/list_countrycodes.cgi +++ b/src/turtlefirewall/list_countrycodes.cgi @@ -3,15 +3,15 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2026 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'}, "" ); +&ui_print_header( "$icons{ICON}{IMAGE}$text{'index_icon_countrycodes'}", $text{'title'}, "" ); &LoadCountryCodes($fw); &showCountryCodes(); @@ -22,7 +22,7 @@ print "

"; #============================================================================ sub showCountryCodes { - @tds = ( "width=5%", "width=95%" ); + my @tds = ( "width=5%", "width=95%" ); print &ui_columns_start([ "$text{'name'}", "$text{'description'}" ], 100, 0, \@tds); my @countrycodes = $fw->GetCountryCodesList(); foreach my $name (@countrycodes) { diff --git a/src/turtlefirewall/list_flowlog.cgi b/src/turtlefirewall/list_flowlog.cgi index bd22829..d25af5a 100644 --- a/src/turtlefirewall/list_flowlog.cgi +++ b/src/turtlefirewall/list_flowlog.cgi @@ -3,16 +3,16 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2026 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; -&ui_print_header( "$icons{LOG}{IMAGE}$text{'flowlog_title'}", $text{'title'}, "" ); +&ui_print_header( "$icons{ICON}{IMAGE}$text{'index_icon_flowlog'}", $text{'title'}, "" ); &LoadNdpiRisks($fw); &showLog(); @@ -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 .= " << "; @@ -177,119 +166,88 @@ sub showLog { $lastpag = int(($count-1) / $pagelen) + 1; if( $pag < $lastpag ) { $pageindex .= " > "; - $pageindex .= qq~ >> ~; + $pageindex .= " >> "; } print &ui_form_start("list_flowlog.cgi", "post"); - print "
$pageindex
\n"; + print "
$pageindex
\n"; my $opz; - local @head; + my @head = (); - local $hstime; - $hstime .= "startTIME
"; + my $hstime = "startTIME
"; push(@head, $hstime ); - local $hetime; - $hetime .= "endTIME
"; + my $hetime = "endTIME
"; push(@head, $hetime ); - local $hl3proto; - $hl3proto .= "L3PROTO
"; + my $hl3proto = "L3PROTO
"; push(@head, $hl3proto ); - local $hl4proto; - $hl4proto .= "L4PROTO
"; + my $hl4proto = "L4PROTO
"; push(@head, $hl4proto ); - local $hproto; - $hproto .= "ndpiPROTO
"; - push(@head, $hproto ); + my $hprotocol = "L7PROTO
"; + push(@head, $hprotocol ); - local $hhost; - $hhost .= "HOSTNAME
"; - push(@head, $hhost ); + my $hhostname = "hostNAME
"; + push(@head, $hhostname ); - local $hsrc; - $hsrc .= "srcADDR
"; - push(@head, $hsrc ); + my $hsource = "srcADDR
"; + push(@head, $hsource ); - local $hsport; - $hsport .= "srcPORT
"; + my $hsport = "srcPORT
"; push(@head, $hsport ); - local $hdst; - $hdst .= "dstADDR
"; - push(@head, $hdst ); + my $hdestination = "dstADDR
"; + push(@head, $hdestination ); - local $hdport; - $hdport .= "dstPORT
"; + my $hdport = "dstPORT
"; push(@head, $hdport ); - local $htbytes; - $htbytes .= "totalBYTES
"; + my $htbytes = "totalBYTES
"; push(@head, $htbytes ); - local $hubytes; - $hubytes .= "upBYTES
"; + my $hubytes = "upBYTES
"; push(@head, $hubytes ); - local $hdbytes; - $hdbytes .= "downBYTES
"; + my $hdbytes = "downBYTES
"; push(@head, $hdbytes ); - local $hupackets; - $hupackets .= "upPACKETS
"; + my $hupackets = "upPACKETS
"; push(@head, $hupackets ); - local $hdpackets; - $hdpackets .= "downPACKETS
"; + my $hdpackets = "downPACKETS
"; push(@head, $hdpackets ); - local $hinif; - $hinif .= "inIF
"; + my $hinif = "inIF
"; push(@head, $hinif ); - local $houtif; - $houtif .= "outIF
"; + my $houtif = "outIF
"; push(@head, $houtif ); - local $hconnmark; - $hconnmark .= "connMARK
"; + my $hconnmark = "connMARK
"; push(@head, $hconnmark ); - local $hsrcnat; - $hsrcnat .= "srcNAT
"; + my $hsrcnat = "srcNAT
"; push(@head, $hsrcnat ); - local $hdstnat; - $hdstnat .= "dstNAT
"; + my $hdstnat = "dstNAT
"; push(@head, $hdstnat ); - local $hja4c; - $hja4c .= "ja4cFINGERPRINT
"; + my $hja4c = "ja4cFINGERPRINT
"; push(@head, $hja4c ); - local $hja3c; - $hja3c .= "ja3cFINGERPRINT
"; - push(@head, $hja3c ); - - local $htlsfp; - $htlsfp .= "tlsFINGERPRINT
"; + my $htlsfp = "tlsFINGERPRINT
"; push(@head, $htlsfp ); - local $htlsv; - $htlsv .= "tlsVERSION
"; - push(@head, $htlsv ); - - local $hrisk; - $hrisk .= "RISK
"; + my $hrisk = "RISK
"; push(@head, $hrisk ); - @tds = ( "style=white-space:nowrap", + my @tds = ( "style=white-space:nowrap", "style=white-space:nowrap", "style=text-align:center", "style=text-align:center", @@ -311,43 +269,48 @@ 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; - &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($sport); - &showTD($dst); - &showTD($dport); - &showTD(&roundbytes($ubytes + $dbytes)); - &showTD(&roundbytes($ubytes)); - &showTD(&roundbytes($dbytes)); - &showTD($upackets); - &showTD($dpackets); + my @cols = (); + my ($stime, $etime, $l3proto, $l4proto, $source, $sport, $destination, $dport, $ubytes, $dbytes, $upackets, $dpackets, $ifindex, + $connmark, $srcnat, $dstnat, $protocol, $hostname, $ja4c, $tlsfp, $risk) = @$l; + $stime = localtime($stime)->strftime('%b %d %X'); + push(@cols, "".($stime eq '' ? " " : "$stime  ").""); + $etime = localtime($etime)->strftime('%b %d %X'); + push(@cols, "".($etime eq '' ? " " : "$etime  ").""); + $l3proto = &l3protoname($l3proto); + push(@cols, "".($l3proto eq '' ? " " : "$l3proto  ").""); + $l4proto = &l4protoname($l4proto); + push(@cols, "".($l4proto eq '' ? " " : "$l4proto  ").""); + push(@cols, "".($protocol eq '' ? " " : "$protocol  ").""); + push(@cols, "".($hostname eq '' ? " " : "$hostname  ").""); + push(@cols, "".($source eq '' ? " " : "$source  ").""); + push(@cols, "".($sport eq '' ? " " : "$sport  ").""); + push(@cols, "".($destination eq '' ? " " : "$destination  ").""); + push(@cols, "".($dport eq '' ? " " : "$dport  ").""); + my $tbytes = &nice_size($ubytes + $dbytes); + push(@cols, "".($tbytes eq '' ? " " : "$tbytes  ").""); + $ubytes = &nice_size($ubytes); + push(@cols, "".($ubytes eq '' ? " " : "$ubytes  ").""); + $dbytes = &nice_size($dbytes); + push(@cols, "".($dbytes eq '' ? " " : "$dbytes  ").""); + push(@cols, "".($upackets eq '' ? " " : "$upackets  ").""); + push(@cols, "".($dpackets eq '' ? " " : "$dpackets  ").""); $t = $ifindex; if( $t =~ /I=(.*?)(,|$)/ ) { $inifindex = $1; }; - &showTD(&getifname($inifindex)); + my $inifname = &getifname($inifindex); + push(@cols, "".($inifname eq '' ? " " : "$inifname  ").""); if( $t =~ /,(.*?)$/ ) { $outifindex = $1; }; - &showTD(&getifname($outifindex)); - &showTD($connmark); - &showTD($srcnat); - &showTD($dstnat); - &showTD($ja4c); - &showTD($ja3c); - &showTD($tlsfp); - &showTD($tlsv); - &showTD(&getrisknames($risk)); + my $outifname = &getifname($outifindex); + push(@cols, "".($outifname eq '' ? " " : "$outifname  ").""); + push(@cols, "".($connmark eq '' ? " " : "$connmark  ").""); + push(@cols, "".($srcnat eq '' ? " " : "$srcnat  ").""); + push(@cols, "".($dstnat eq '' ? " " : "$dstnat  ").""); + push(@cols, "".($ja4c eq '' ? " " : "$ja4c  ").""); + push(@cols, "".($tlsfp eq '' ? " " : "$tlsfp  ").""); + push(@cols, "".($risk eq '' ? " " : "$risk  ").""); print &ui_columns_row(\@cols, \@tds); } print &ui_columns_end(); @@ -358,14 +321,7 @@ sub showLog { print &ui_form_end(); - print "
$pageindex
\n"; -} - -sub showTD { - my $text = shift; - - if( $text eq '' ) { $text = ' '; } - push(@cols, "$text  "); + print "
$pageindex
\n"; } sub l3protoname { diff --git a/src/turtlefirewall/list_flowstat.cgi b/src/turtlefirewall/list_flowstat.cgi index 691e3a9..fa329fd 100644 --- a/src/turtlefirewall/list_flowstat.cgi +++ b/src/turtlefirewall/list_flowstat.cgi @@ -3,181 +3,164 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2026 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'}; + +my $is_log = $in{'is_log'}; +if( $is_log eq '0' ) { + $log = join("\0", glob("${FlowLogFile}-*")); +} elsif( $is_log eq '2' ) { + $log = "/var/log/flowinfo.tmp"; + system("cp -f $FlowLogFile $log > /dev/null 2>&1"); + system("convertflowinfo.pl --log=$log > /dev/null 2>&1"); +} +$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{ICON}{IMAGE}$text{'index_icon_flowstat'}", $text{'title'}, "" ); if( $type eq 'risk' ) { &LoadNdpiRisks($fw); } +my $logflowtotal = 0; my $flowtotal = 0; -my ($type_list, $flows) = &getflows($log); +my $logflowcount = 0; +my $flowcount = 0; -my @stats = &getstats($flowreports{$type}{LOGIDX},$type_list,$flows); +my $firstflowtime = ''; +my $lastflowtime = ''; -&showstats($flowreports{$type}{TXTIDX},$flowreports{$type}{ICOIDX},@stats); +my $query = ''; -&ui_print_footer("edit_flowstat.cgi",'flow statistics'); +$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}; + +print &ui_subheading($icons{FLOWSTAT}{IMAGE},$text{'report_flowstat_title'}); +&showstats($type,$is_target,$target_type,$target_op,$in{'target'},$flowcount,$flowtotal,$logflowcount,$firstflowtime,$lastflowtime,$txtindex,$icoindex,@stats); + +unlink "/var/log/flowinfo.tmp"; + +&ui_print_footer("edit_flowstat.cgi",$text{'index_flowstat'}); + +#============================================================================ + 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" ); + my @tds = ( "style=white-space:nowrap", "width=$graphwidth", "", "width=1% style=text-align:right;white-space:nowrap" ); print &ui_columns_start([ "$text{$txtindex}", "$text{'flowstat_percent'}", "", "$text{'flowstat_traffic'}" ], 100, 0, \@tds); foreach my $l (@stats) { - local @cols; - my ( $item, $bytes) = @$l; + my @cols = (); + my ($item, $bytes) = @$l; # Compared to overall traffic my $width = ($bytes/$flowtotal) * $graphwidth; @@ -205,11 +188,11 @@ sub showstats { push(@cols, "  $percent %"); - push(@cols, "".&roundbytes($bytes).""); + push(@cols, "".&nice_size($bytes).""); print &ui_columns_row(\@cols, \@tds); } - print &ui_columns_row([undef, undef, undef, "Total : ".&roundbytes($flowtotal).""], \@tds); + print &ui_columns_row([undef, undef, undef, "Total : ".&nice_size($flowtotal).""], \@tds); print &ui_columns_end(); } diff --git a/src/turtlefirewall/list_itemreferences.cgi b/src/turtlefirewall/list_itemreferences.cgi index f486154..2fbab07 100644 --- a/src/turtlefirewall/list_itemreferences.cgi +++ b/src/turtlefirewall/list_itemreferences.cgi @@ -3,21 +3,21 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2026 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'}; -&ui_print_header( "$icons{SHIELD}{IMAGE}$text{'list_itemreferences_title'}", $text{'title'}, "" ); +&ui_print_header( "$icons{ICON}{IMAGE}$text{'list_itemreferences_title'}", $text{'title'}, "" ); &showItemReferences(); -&ui_print_footer('list_items.cgi','items list'); +&ui_print_footer('list_items.cgi',$text{'index_items'}); #============================================================================ @@ -26,7 +26,7 @@ sub showItemReferences { my $image = $icons{$type}{IMAGE}; print &ui_subheading($image,$item); - @tds = (); + my @tds = ( "style=text-align:left" ); print &ui_columns_start([ "$text{'references'}" ], 100, 0, \@tds); my %itemreferences = $fw->GetItemReferences($item); foreach my $k (sort keys %itemreferences) { @@ -41,10 +41,10 @@ sub showItemReferences { if( $idx ne '' ) { $idx++; my $refnamelc = lc($refname); - $href = &ui_link("edit_$reftypelc.cgi?idx=$idx","$prefix rule id $idx $refnamelc"); + $href = &ui_link("edit_$reftypelc.cgi?idx=$idx","$prefix rule id $idx ${refnamelc}$icons{REF}{IMAGE}"); } else { # Item in Item - $href = &ui_link("edit_$reftypelc.cgi?$reftypelc=$refname","$prefix item $refname"); + $href = &ui_link("edit_$reftypelc.cgi?$reftypelc=$refname","$prefix item ${refname}$icons{REF}{IMAGE}"); } print &ui_columns_row([ "$icons{$reftype}{IMAGE}$href" ], \@tds); } diff --git a/src/turtlefirewall/list_items.cgi b/src/turtlefirewall/list_items.cgi index d24a91f..36e60d2 100644 --- a/src/turtlefirewall/list_items.cgi +++ b/src/turtlefirewall/list_items.cgi @@ -3,14 +3,14 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2026 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'}, "" ); +&ui_print_header( "$icons{ICON}{IMAGE}$text{'index_icon_items'}", $text{'title'}, "" ); $form = 0; &showAddressList(); @@ -68,10 +68,10 @@ print "

"; sub showAddressList { print &ui_subheading($icons{ADDRESSLIST}{IMAGE},$text{'addresslist'}); print &ui_form_start("save_addresslist.cgi", "post"); - @links = ( &select_all_link("d", $form), + my @links = ( &select_all_link("d", $form), &select_invert_link("d", $form), - "$text{'list_items_create_addresslist'}" ); - @tds = ( "width=1% style=vertical-align:top", + &ui_link("edit_addresslist.cgi?new=1", "$text{'list_items_create_addresslist'}") ); + my @tds = ( "width=1% style=vertical-align:top", "style=vertical-align:top", "style=vertical-align:top", "style=vertical-align:top", @@ -87,15 +87,15 @@ sub showAddressList { "$text{'description'}", "$text{'reference'}" ], 100, 0, \@tds); foreach my $b (sort keys %blacklists) { - local @cols; + my @cols = (); push(@cols, "$icons{BLACKLIST}{IMAGE}$b"); push(@cols, "$icons{FILE}{IMAGE}$blacklists{$b}{FILE}"); my $blacklistcount = qx{wc -l < $blacklists{$b}{FILE} 2>/dev/null}; if( $blacklistcount eq '' ) { $blacklistcount = '0'; } push(@cols, $blacklistcount); push(@cols, "$icons{OPTION}{IMAGE}$blacklists{$b}{TYPE}" ); - push(@cols, "$icons{DESCRIPTION}{IMAGE}$blacklists{$b}{DESCRIPTION}"); - my $href = &ui_link("edit_options.cgi","".($fw->GetOption("drop_$b") eq 'on' ? "1" : '0').""); + push(@cols, "$icons{DESCRIPTION}{IMAGE}$text{$blacklists{$b}{DESCIDX}}"); + my $href = &ui_link("edit_options.cgi", "".($fw->GetOption("drop_$b") eq 'on' ? "1$icons{REF}{IMAGE}" : ' ').""); push(@cols, $href ); print &ui_checked_columns_row(\@cols, \@tds, "d", $k); } @@ -103,7 +103,7 @@ sub showAddressList { my %addresslist = $fw->GetAddressList($k); my %itemreferences = $fw->GetItemReferences($k); my $count = keys %itemreferences; - local @cols; + my @cols = (); my $href = &ui_link("edit_addresslist.cgi?addresslist=$k",$k); push(@cols, "$icons{ADDRESSLIST}{IMAGE}$href" ); push(@cols, "$icons{FILE}{IMAGE}$addresslist{'FILE'}" ); @@ -112,7 +112,7 @@ sub showAddressList { push(@cols, $listcount); push(@cols, "$icons{OPTION}{IMAGE}$addresslist{'TYPE'}" ); push(@cols, "".($addresslist{'DESCRIPTION'} ne '' ? "$icons{DESCRIPTION}{IMAGE}$addresslist{'DESCRIPTION'}" : ' ')."" ); - $href = &ui_link("list_itemreferences.cgi?item=$k",$count); + $href = $count > 0 ? &ui_link("list_itemreferences.cgi?item=$k", "${count}$icons{REF}{IMAGE}") : ' '; push(@cols, $href); print &ui_checked_columns_row(\@cols, \@tds, "d", $k); } @@ -126,10 +126,10 @@ sub showAddressList { sub showZone { print &ui_subheading($icons{ZONE}{IMAGE},"$text{'zone'}"); print &ui_form_start("save_zone.cgi", "post"); - @links = ( &select_all_link("d", $form), + my @links = ( &select_all_link("d", $form), &select_invert_link("d", $form), - "$text{'list_items_create_zone'}" ); - @tds = ( "width=1% style=vertical-align:top", + &ui_link("edit_zone.cgi?new=1", "$text{'list_items_create_zone'}") ); + my @tds = ( "width=1% style=vertical-align:top", "style=vertical-align:top", "style=vertical-align:top", "style=vertical-align:top", @@ -144,7 +144,7 @@ sub showZone { my %zone = $fw->GetZone($k); my %itemreferences = $fw->GetItemReferences($k); my $count = keys %itemreferences; - local @cols; + my @cols = (); my $href = &ui_link("edit_zone.cgi?zone=$k",$k); if( $k eq 'FIREWALL' ) { push(@cols, "$icons{FIREWALL}{IMAGE}$k" ); @@ -153,7 +153,7 @@ sub showZone { } push(@cols, "".($zone{'IF'} ne '' ? "$icons{INTERFACE}{IMAGE}$zone{'IF'}" : ' ')."" ); push(@cols, "".($zone{'DESCRIPTION'} ne '' ? "$icons{DESCRIPTION}{IMAGE}$zone{'DESCRIPTION'}" : ' ')."" ); - $href = &ui_link("list_itemreferences.cgi?item=$k",$count); + $href = $count > 0 ? &ui_link("list_itemreferences.cgi?item=$k", "${count}$icons{REF}{IMAGE}") : ' '; push(@cols, $href); print &ui_checked_columns_row(\@cols, \@tds, "d", $k); } @@ -167,10 +167,10 @@ sub showZone { sub showHost { print &ui_subheading($icons{HOST}{IMAGE},$text{'host'}); print &ui_form_start("save_host.cgi", "post"); - @links = ( &select_all_link("d", $form), + my @links = ( &select_all_link("d", $form), &select_invert_link("d", $form), - "$text{'list_items_create_host'}" ); - @tds = ( "width=1% style=vertical-align:top", + &ui_link("edit_host.cgi?new=1", "$text{'list_items_create_host'}") ); + my @tds = ( "width=1% style=vertical-align:top", "style=vertical-align:top", "style=vertical-align:top", "style=vertical-align:top", @@ -189,14 +189,14 @@ sub showHost { my %host = $fw->GetHost($k); my %itemreferences = $fw->GetItemReferences($k); my $count = keys %itemreferences; - local @cols; + my @cols = (); my $href = &ui_link("edit_host.cgi?host=$k",$k); push(@cols, "$icons{HOST}{IMAGE}$href" ); push(@cols, "".($host{'IP'} ne '' ? "$icons{ADDRESS}{IMAGE}$host{'IP'}" : ' ')."" ); push(@cols, "".($host{'MAC'} ne '' ? "$icons{ADDRESS}{IMAGE}$host{'MAC'}" : ' ')."" ); push(@cols, "$icons{ZONE}{IMAGE}$host{'ZONE'}" ); push(@cols, "".($host{'DESCRIPTION'} ne '' ? "$icons{DESCRIPTION}{IMAGE}$host{'DESCRIPTION'}" : ' ')."" ); - $href = &ui_link("list_itemreferences.cgi?item=$k",$count); + $href = $count > 0 ? &ui_link("list_itemreferences.cgi?item=$k", "${count}$icons{REF}{IMAGE}") : ' '; push(@cols, $href); print &ui_checked_columns_row(\@cols, \@tds, "d", $k); } @@ -210,10 +210,10 @@ sub showHost { sub showNet { print &ui_subheading($icons{NET}{IMAGE},$text{'net'}); print &ui_form_start("save_net.cgi", "post"); - @links = ( &select_all_link("d", $form), + my @links = ( &select_all_link("d", $form), &select_invert_link("d", $form), - "$text{'list_items_create_net'}" ); - @tds = ( "width=1% style=vertical-align:top", + &ui_link("edit_net.cgi?new=1", "$text{'list_items_create_net'}") ); + my @tds = ( "width=1% style=vertical-align:top", "style=vertical-align:top", "style=vertical-align:top", "style=vertical-align:top", @@ -233,14 +233,14 @@ sub showNet { my %itemreferences = $fw->GetItemReferences($k); my $count = keys %itemreferences; push(@cols, $count); - local @cols; + my @cols = (); my $href = &ui_link("edit_net.cgi?net=$k",$k); push(@cols, "$icons{NET}{IMAGE}$href" ); push(@cols, "$icons{ADDRESS}{IMAGE}$net{'IP'}" ); push(@cols, "$icons{NETMASK}{IMAGE}$net{'NETMASK'}" ); push(@cols, "$icons{ZONE}{IMAGE}$net{'ZONE'}" ); push(@cols, "".($net{'DESCRIPTION'} ne '' ? "$icons{DESCRIPTION}{IMAGE}$net{'DESCRIPTION'}" : ' ')."" ); - $href = &ui_link("list_itemreferences.cgi?item=$k",$count); + $href = $count > 0 ? &ui_link("list_itemreferences.cgi?item=$k", "${count}$icons{REF}{IMAGE}") : ' '; push(@cols, $href); print &ui_checked_columns_row(\@cols, \@tds, "d", $k); } @@ -254,10 +254,10 @@ sub showNet { sub showGeoip { print &ui_subheading($icons{GEOIP}{IMAGE},$text{'geoip'}); print &ui_form_start("save_geoip.cgi", "post"); - @links = ( &select_all_link("d", $form), + my @links = ( &select_all_link("d", $form), &select_invert_link("d", $form), - "$text{'list_items_create_geoip'}" ); - @tds = ( "width=1% style=vertical-align:top", + &ui_link("edit_geoip.cgi?new=1", "$text{'list_items_create_geoip'}") ); + my @tds = ( "width=1% style=vertical-align:top", "style=vertical-align:top", "style=vertical-align:top", "style=vertical-align:top", @@ -274,14 +274,14 @@ sub showGeoip { my %geoip = $fw->GetGeoip($k); my %itemreferences = $fw->GetItemReferences($k); my $count = keys %itemreferences; - local @cols; + my @cols = (); my $href = &ui_link("edit_geoip.cgi?geoip=$k",$k); push(@cols, "$icons{GEOIP}{IMAGE}$href" ); my %g = $fw->GetCountryCode($geoip{'IP'}); push(@cols, "$icons{COUNTRYCODE}{IMAGE}$geoip{'IP'} - $g{'DESCRIPTION'}" ); push(@cols, "$icons{ZONE}{IMAGE}$geoip{'ZONE'}" ); push(@cols, "".($geoip{'DESCRIPTION'} ne '' ? "$icons{DESCRIPTION}{IMAGE}$geoip{'DESCRIPTION'}" : ' ')."" ); - $href = &ui_link("list_itemreferences.cgi?item=$k",$count); + $href = $count > 0 ? &ui_link("list_itemreferences.cgi?item=$k", "${count}$icons{REF}{IMAGE}") : ' '; push(@cols, $href); print &ui_checked_columns_row(\@cols, \@tds, "d", $k); } @@ -295,10 +295,10 @@ sub showGeoip { sub showIPSet { print &ui_subheading($icons{IPSET}{IMAGE},$text{'ipset'}); print &ui_form_start("save_ipset.cgi", "post"); - @links = ( &select_all_link("d", $form), + my @links = ( &select_all_link("d", $form), &select_invert_link("d", $form), - "$text{'list_items_create_ipset'}" ); - @tds = ( "width=1% style=vertical-align:top", + &ui_link("edit_ipset.cgi?new=1", "$text{'list_items_create_ipset'}") ); + my @tds = ( "width=1% style=vertical-align:top", "style=vertical-align:top", "style=vertical-align:top", "style=vertical-align:top", @@ -315,13 +315,13 @@ sub showIPSet { my %ipset = $fw->GetIPSet($k); my %itemreferences = $fw->GetItemReferences($k); my $count = keys %itemreferences; - local @cols; + my @cols = (); my $href = &ui_link("edit_ipset.cgi?ipset=$k",$k); push(@cols, "$icons{IPSET}{IMAGE}$href" ); push(@cols, "$icons{ADDRESS}{IMAGE}$ipset{'IP'}" ); push(@cols, "$icons{ZONE}{IMAGE}$ipset{'ZONE'}" ); push(@cols, "".($ipset{'DESCRIPTION'} ne '' ? "$icons{DESCRIPTION}{IMAGE}$ipset{'DESCRIPTION'}" : ' ')."" ); - $href = &ui_link("list_itemreferences.cgi?item=$k",$count); + $href = $count > 0 ? &ui_link("list_itemreferences.cgi?item=$k", "${count}$icons{REF}{IMAGE}") : ' '; push(@cols, $href); print &ui_checked_columns_row(\@cols, \@tds, "d", $k); } @@ -335,10 +335,10 @@ sub showIPSet { sub showGroup { print &ui_subheading($icons{GROUP}{IMAGE},$text{'group'}); print &ui_form_start("save_group.cgi", "post" ); - @links = ( &select_all_link("d", $form), + my @links = ( &select_all_link("d", $form), &select_invert_link("d", $form), - "$text{'list_items_create_group'}" ); - @tds = ( "width=1% style=vertical-align:top", + &ui_link("edit_group.cgi?new=1", "$text{'list_items_create_group'}") ); + my @tds = ( "width=1% style=vertical-align:top", "style=vertical-align:top", "style=vertical-align:top", "style=vertical-align:top", @@ -353,18 +353,18 @@ sub showGroup { my %group = $fw->GetGroup($k); my %itemreferences = $fw->GetItemReferences($k); my $count = keys %itemreferences; - local @cols; + my @cols = (); my $href = &ui_link("edit_group.cgi?group=$k",$k); 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
"; } push(@cols, $grouplist ); push(@cols, "".($group{'DESCRIPTION'} ne '' ? "$icons{DESCRIPTION}{IMAGE}$group{'DESCRIPTION'}" : ' ')."" ); - $href = &ui_link("list_itemreferences.cgi?item=$k",$count); + $href = $count > 0 ? &ui_link("list_itemreferences.cgi?item=$k", "${count}$icons{REF}{IMAGE}") : ' '; push(@cols, $href); print &ui_checked_columns_row(\@cols, \@tds, "d", $k); } @@ -378,10 +378,10 @@ sub showGroup { sub showHostNameSet { print &ui_subheading($icons{HOSTNAMESET}{IMAGE},$text{'hostnameset'}); print &ui_form_start("save_hostnameset.cgi", "post"); - @links = ( &select_all_link("d", $form), + my @links = ( &select_all_link("d", $form), &select_invert_link("d", $form), - "$text{'list_items_create_hostnameset'}" ); - @tds = ( "width=1% style=vertical-align:top", + &ui_link("edit_hostnameset.cgi?new=1", "$text{'list_items_create_hostnameset'}") ); + my @tds = ( "width=1% style=vertical-align:top", "style=vertical-align:top", "style=vertical-align:top", "style=vertical-align:top", @@ -396,7 +396,7 @@ sub showHostNameSet { my %hostnameset = $fw->GetHostNameSet($k); my %itemreferences = $fw->GetItemReferences($k); my $count = keys %itemreferences; - local @cols; + my @cols = (); my $href = &ui_link("edit_hostnameset.cgi?hostnameset=$k",$k); push(@cols, "$icons{HOSTNAMESET}{IMAGE}$href" ); my $hostnamesetlist; @@ -405,7 +405,7 @@ sub showHostNameSet { } push(@cols, $hostnamesetlist ); push(@cols, "".($hostnameset{'DESCRIPTION'} ne '' ? "$icons{DESCRIPTION}{IMAGE}$hostnameset{'DESCRIPTION'}" : ' ')."" ); - $href = &ui_link("list_itemreferences.cgi?item=$k",$count); + $href = $count > 0 ? &ui_link("list_itemreferences.cgi?item=$k", "${count}$icons{REF}{IMAGE}") : ' '; push(@cols, $href); print &ui_checked_columns_row(\@cols, \@tds, "d", $k); } @@ -419,10 +419,10 @@ sub showHostNameSet { sub showRiskSet { print &ui_subheading($icons{RISKSET}{IMAGE},$text{'riskset'}); print &ui_form_start("save_riskset.cgi", "post"); - @links = ( &select_all_link("d", $form), + my @links = ( &select_all_link("d", $form), &select_invert_link("d", $form), - "$text{'list_items_create_riskset'}" ); - @tds = ( "width=1% style=vertical-align:top", + &ui_link("edit_riskset.cgi?new=1", "$text{'list_items_create_riskset'}") ); + my @tds = ( "width=1% style=vertical-align:top", "style=vertical-align:top", "style=vertical-align:top", "style=vertical-align:top", @@ -437,17 +437,17 @@ sub showRiskSet { my %riskset = $fw->GetRiskSet($k); my %itemreferences = $fw->GetItemReferences($k); my $count = keys %itemreferences; - local @cols; + my @cols = (); my $href = &ui_link("edit_riskset.cgi?riskset=$k",$k); push(@cols, "$icons{RISKSET}{IMAGE}$href" ); my $risksetlist; for my $i (split(/,/, $riskset{'RISKS'})) { my %ndpirisk = $fw->GetNdpiRisk($i); - $risksetlist .= "$icons{RISK}{IMAGE}$i - $ndpirisk{'DESCRIPTION'}
"; + $risksetlist .= "$icons{RISK}{IMAGE}$i - $ndpirisk{'DESCRIPTION'} - $ndpirisk{'SEVERITY'}
"; } push(@cols, $risksetlist ); push(@cols, "".($riskset{'DESCRIPTION'} ne '' ? "$icons{DESCRIPTION}{IMAGE}$riskset{'DESCRIPTION'}" : ' ')."" ); - $href = &ui_link("list_itemreferences.cgi?item=$k",$count); + $href = $count > 0 ? &ui_link("list_itemreferences.cgi?item=$k", "${count}$icons{REF}{IMAGE}") : ' '; push(@cols, $href); print &ui_checked_columns_row(\@cols, \@tds, "d", $k); } @@ -461,10 +461,10 @@ sub showRiskSet { sub showRateLimit { print &ui_subheading($icons{RATELIMIT}{IMAGE},$text{'ratelimit'}); print &ui_form_start("save_ratelimit.cgi", "post"); - @links = ( &select_all_link("d", $form), + my @links = ( &select_all_link("d", $form), &select_invert_link("d", $form), - "$text{'list_items_create_ratelimit'}" ); - @tds = ( "width=1% style=vertical-align:top", + &ui_link("edit_ratelimit.cgi?new=1", "$text{'list_items_create_ratelimit'}") ); + my @tds = ( "width=1% style=vertical-align:top", "style=vertical-align:top", "style=vertical-align:top", "style=vertical-align:top", @@ -479,12 +479,12 @@ sub showRateLimit { my %ratelimit = $fw->GetRateLimit($k); my %itemreferences = $fw->GetItemReferences($k); my $count = keys %itemreferences; - local @cols; + my @cols = (); my $href = &ui_link("edit_ratelimit.cgi?ratelimit=$k",$k); push(@cols, "$icons{RATELIMIT}{IMAGE}$href" ); push(@cols, "$icons{RATE}{IMAGE}$ratelimit{'RATE'} Mbps" ); push(@cols, "".($ratelimit{'DESCRIPTION'} ne '' ? "$icons{DESCRIPTION}{IMAGE}$ratelimit{'DESCRIPTION'}" : ' ')."" ); - $href = &ui_link("list_itemreferences.cgi?item=$k",$count); + $href = $count > 0 ? &ui_link("list_itemreferences.cgi?item=$k", "${count}$icons{REF}{IMAGE}") : ' '; push(@cols, $href); print &ui_checked_columns_row(\@cols, \@tds, "d", $k); } @@ -498,10 +498,10 @@ sub showRateLimit { sub showTime { print &ui_subheading($icons{TIME}{IMAGE},$text{'time'}); print &ui_form_start("save_time.cgi", "post"); - @links = ( &select_all_link("d", $form), + my @links = ( &select_all_link("d", $form), &select_invert_link("d", $form), - "$text{'list_items_create_time'}" ); - @tds = ( "width=1% style=vertical-align:top", + &ui_link("edit_time.cgi?new=1", "$text{'list_items_create_time'}") ); + my @tds = ( "width=1% style=vertical-align:top", "style=vertical-align:top", "style=vertical-align:top", "style=vertical-align:top", @@ -520,14 +520,14 @@ sub showTime { my %time = $fw->GetTime($k); my %itemreferences = $fw->GetItemReferences($k); my $count = keys %itemreferences; - local @cols; + my @cols = (); my $href = &ui_link("edit_time.cgi?time=$k",$k); push(@cols, "$icons{TIME}{IMAGE}$href" ); push(@cols, "$icons{ITEM}{IMAGE}$time{'WEEKDAYS'}" ); push(@cols, "$icons{TIMESTART}{IMAGE}$time{'TIMESTART'}" ); push(@cols, "$icons{TIMESTOP}{IMAGE}$time{'TIMESTOP'}" ); push(@cols, "".($time{'DESCRIPTION'} ne '' ? "$icons{DESCRIPTION}{IMAGE}$time{'DESCRIPTION'}" : ' ')."" ); - $href = &ui_link("list_itemreferences.cgi?item=$k",$count); + $href = $count > 0 ? &ui_link("list_itemreferences.cgi?item=$k", "${count}$icons{REF}{IMAGE}") : ' '; push(@cols, $href); print &ui_checked_columns_row(\@cols, \@tds, "d", $k); } @@ -541,10 +541,10 @@ sub showTime { sub showTimeGroup { print &ui_subheading($icons{TIMEGROUP}{IMAGE},$text{'timegroup'}); print &ui_form_start("save_timegroup.cgi", "post" ); - @links = ( &select_all_link("d", $form), + my @links = ( &select_all_link("d", $form), &select_invert_link("d", $form), - "$text{'list_items_create_timegroup'}" ); - @tds = ( "width=1% style=vertical-align:top", + &ui_link("edit_timegroup.cgi?new=1", "$text{'list_items_create_timegroup'}") ); + my @tds = ( "width=1% style=vertical-align:top", "style=vertical-align:top", "style=vertical-align:top", "style=vertical-align:top", @@ -559,16 +559,16 @@ sub showTimeGroup { my %timegroup = $fw->GetTimeGroup($k); my %itemreferences = $fw->GetItemReferences($k); my $count = keys %itemreferences; - local @cols; + my @cols = (); 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 ); push(@cols, "".($timegroup{'DESCRIPTION'} ne '' ? "$icons{DESCRIPTION}{IMAGE}$timegroup{'DESCRIPTION'}" : ' ')."" ); - $href = &ui_link("list_itemreferences.cgi?item=$k",$count); + $href = $count > 0 ? &ui_link("list_itemreferences.cgi?item=$k", "${count}$icons{REF}{IMAGE}") : ' '; push(@cols, $href); print &ui_checked_columns_row(\@cols, \@tds, "d", $k); } diff --git a/src/turtlefirewall/list_manglerules.cgi b/src/turtlefirewall/list_manglerules.cgi index 740c746..da218d5 100644 --- a/src/turtlefirewall/list_manglerules.cgi +++ b/src/turtlefirewall/list_manglerules.cgi @@ -3,15 +3,15 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2026 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'}, "" ); +&ui_print_header( "$icons{ICON}{IMAGE}$text{'index_icon_manglerules'}", $text{'title'}, "" ); $form = 0; &showConnmarkPreroute(); @@ -27,10 +27,10 @@ print "

"; sub showConnmarkPreroute { print &ui_subheading($icons{MARK}{IMAGE},$text{'connmark_preroute'}); print &ui_form_start("save_connmarkpreroute.cgi", "post"); - @links = ( &select_all_link("d", $form), + my @links = ( &select_all_link("d", $form), &select_invert_link("d", $form), - "$text{'list_connmarkpreroutes_create_rule'}" ); - @tds = ( + &ui_link("edit_connmarkpreroute.cgi?new=1", "$text{'list_connmarkpreroutes_create_rule'}") ); + my @tds = ( "width=1% style=vertical-align:top", "width=1% style=vertical-align:top", "width=10% style=vertical-align:top;white-space:normal", @@ -41,7 +41,7 @@ sub showConnmarkPreroute { "style=vertical-align:top;white-space:normal", "style=vertical-align:top;white-space:normal", "width=5% style=vertical-align:top;white-space:normal", - "width=1% style=vertical-align:top" ); + "width=64 style=vertical-align:top" ); print &ui_columns_start([ '', "ID", @@ -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 ) { @@ -77,11 +77,11 @@ sub showConnmarkPreroute { for( my $i=1; $i<=$nConnmarkPreroutes; $i++ ) { my %attr = $fw->GetConnmarkPreroute($i); - local @cols; + my @cols = (); if( $attr{'TARGET'} eq '' ) { $attr{'TARGET'} = 'ACCEPT'; } - my $bb = $idx == $i ? '' : ''; # BoldBegin - my $be = $idx == $i ? '' : ''; # BoldEnd - my $sb = $attr{'ACTIVE'} eq 'NO' ? '' : ''; # StrikeBegin + 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}"); push(@cols, $href ); @@ -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}"); @@ -129,41 +129,18 @@ sub showConnmarkPreroute { $cimage = $icons{$type}{IMAGE}; } push(@cols, "${cimage}${sb}${bb}$attr{'TIME'}${be}${se}" ); - my $cb = $sb eq '' ? '' : ''; # ColourBegin + my $cb = $sb eq '' ? '' : ''; # ColourBegin my $ce = $se eq '' ? '' : ''; # ColourEnd my $mimage = $attr{'ACTIVE'} eq 'NO' ? $icons{MARK}{IMAGE} : $icons{MARK_A}{IMAGE}; 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 .= ""; - } else { - $mover .= ""; - } - if( $i > 1 ) { - $mover .= ""; - } else { - $mover .= ""; - } - # if( $i > 2 ) { - # $mover .= ""; - # } else { - # $mover .= ""; - # } - $mover .= "
V     - v - -      - - ^ - -    - A  
"; + my $mover = &ui_up_down_arrows( + "list_manglerules.cgi?table=connmarkpreroute&idx=$i&up=1", + "list_manglerules.cgi?table=connmarkpreroute&idx=$i&down=1", + $i > 1, + $i < $nConnmarkPreroutes, + "images/up.gif", + "images/down.gif" + ); push(@cols, $mover); print &ui_checked_columns_row(\@cols, \@tds, "d", $i); } @@ -178,10 +155,10 @@ sub showConnmarkPreroute { sub showConnmark { print &ui_subheading($icons{MARK}{IMAGE},$text{'connmark'}); print &ui_form_start("save_connmark.cgi", "post"); - @links = ( &select_all_link("d", $form), + my @links = ( &select_all_link("d", $form), &select_invert_link("d", $form), - "$text{'list_connmarks_create_rule'}" ); - @tds = ( + &ui_link("edit_connmark.cgi?new=1", "$text{'list_connmarks_create_rule'}") ); + my @tds = ( "width=1% style=vertical-align:top", "width=1% style=vertical-align:top", "width=10% style=vertical-align:top;white-space:normal", @@ -192,7 +169,7 @@ sub showConnmark { "style=vertical-align:top;white-space:normal", "style=vertical-align:top;white-space:normal", "width=5% style=vertical-align:top;white-space:normal", - "width=1% style=vertical-align:top" ); + "width=64 style=vertical-align:top" ); print &ui_columns_start([ '', "ID", @@ -208,8 +185,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 ) { @@ -228,11 +205,11 @@ sub showConnmark { for( my $i=1; $i<=$nConnmarks; $i++ ) { my %attr = $fw->GetConnmark($i); - local @cols; + my @cols = (); if( $attr{'TARGET'} eq '' ) { $attr{'TARGET'} = 'ACCEPT'; } - my $bb = $idx == $i ? '' : ''; # BoldBegin - my $be = $idx == $i ? '' : ''; # BoldEnd - my $sb = $attr{'ACTIVE'} eq 'NO' ? '' : ''; # StrikeBegin + 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}"); push(@cols, $href ); @@ -261,7 +238,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}"); @@ -290,41 +267,18 @@ sub showConnmark { $cimage = $icons{$type}{IMAGE}; } push(@cols, "${cimage}${sb}${bb}$attr{'TIME'}${be}${se}" ); - my $cb = $sb eq '' ? '' : ''; # ColourBegin + my $cb = $sb eq '' ? '' : ''; # ColourBegin my $ce = $se eq '' ? '' : ''; # ColourEnd my $mimage = $attr{'ACTIVE'} eq 'NO' ? $icons{MARK}{IMAGE} : $icons{MARK_A}{IMAGE}; 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 .= ""; - } else { - $mover .= ""; - } - if( $i > 1 ) { - $mover .= ""; - } else { - $mover .= ""; - } - # if( $i > 2 ) { - # $mover .= ""; - # } else { - # $mover .= ""; - # } - $mover .= "
V     - v - -      - - ^ - -    - A  
"; + my $mover = &ui_up_down_arrows( + "list_manglerules.cgi?table=connmark&idx=$i&up=1", + "list_manglerules.cgi?table=connmark&idx=$i&down=1", + $i > 1, + $i < $nConnmarks, + "images/up.gif", + "images/down.gif" + ); 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..2bafaad 100644 --- a/src/turtlefirewall/list_nat.cgi +++ b/src/turtlefirewall/list_nat.cgi @@ -3,15 +3,15 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2026 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'}, "" ); +&ui_print_header( "$icons{ICON}{IMAGE}$text{'index_icon_nat'}", $text{'title'}, "" ); $form = 0; &showNat(); @@ -31,17 +31,17 @@ print "

"; sub showNat { print &ui_subheading($icons{NAT}{IMAGE},$text{'nat'}); print &ui_form_start("save_nat.cgi", "post"); - @links = ( &select_all_link("d", $form), + my @links = ( &select_all_link("d", $form), &select_invert_link("d", $form), - "$text{'list_nat_create_nat'}" ); - @tds = ( "width=1% style=vertical-align:top", - "width=1% style=text-align:center;vertical-align:top", - "width=25% style=vertical-align:top;white-space:normal", - "width=25% style=vertical-align:top;white-space:normal", - "style=vertical-align:top;white-space:normal", - "width=1% style=vertical-align:top;text-align:center", - "width=1% style=vertical-align:top;white-space:normal", - "width=1% style=vertical-align:top" ); + &ui_link("edit_nat.cgi?new=1", "$text{'list_nat_create_nat'}") ); + my @tds = ( "width=1% style=vertical-align:top", + "width=1% style=text-align:center;vertical-align:top", + "width=25% style=vertical-align:top;white-space:normal", + "width=25% style=vertical-align:top;white-space:normal", + "style=vertical-align:top;white-space:normal", + "width=1% style=vertical-align:top;text-align:center", + "width=1% style=vertical-align:top;white-space:normal", + "width=64 style=vertical-align:top" ); print &ui_columns_start([ "", "ID", @@ -54,77 +54,68 @@ 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 $sb = $attr{'ACTIVE'} eq 'NO' ? '' : ''; # StrikeBegin + my @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}"); - my $cb = $sb eq '' ? '' : ''; # ColourBegin + 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}" ); - local $mover; - $mover .= ""; - - if( $i < $nNat ) { - $mover .= ""; - } else { - $mover .= ""; - } - if( $i > 1 ) { - $mover .= ""; - } else { - $mover .= ""; - } - $mover .= "
- down - -      - - up - -    -
"; + push(@cols, "${timage}${sb}${bb}$attr{'TOPORT'}${be}${se}" ); + my $mover = &ui_up_down_arrows( + "list_nat.cgi?table=nat&idx=$i&up=1", + "list_nat.cgi?table=nat&idx=$i&down=1", + $i > 1, + $i < $nNat, + "images/up.gif", + "images/down.gif" + ); push(@cols, $mover); print &ui_checked_columns_row(\@cols, \@tds, "d", $i); } @@ -139,16 +130,16 @@ sub showNat { sub showMasquerade { print &ui_subheading($icons{MASQUERADE}{IMAGE},$text{'masquerade'}); print &ui_form_start("save_masquerade.cgi", "post"); - @links = ( &select_all_link("d", $form), + my @links = ( &select_all_link("d", $form), &select_invert_link("d", $form), - "$text{'list_nat_create_masq'}" ); - @tds = ( "width=1% style=vertical-align:top", - "width=1% style=text-align:center;vertical-align:top", - "width=25% style=vertical-align:top;white-space:normal", - "width=25% style=vertical-align:top;white-space:normal", - "style=vertical-align:top;white-space:normal", - "width=1% style=vertical-align:top;text-align:center", - "width=1% style=vertical-align:top" ); + &ui_link("edit_masquerade.cgi?new=1", "$text{'list_nat_create_masq'}") ); + my @tds = ( "width=1% style=vertical-align:top", + "width=1% style=text-align:center;vertical-align:top", + "width=25% style=vertical-align:top;white-space:normal", + "width=25% style=vertical-align:top;white-space:normal", + "style=vertical-align:top;white-space:normal", + "width=1% style=vertical-align:top;text-align:center", + "width=64 style=vertical-align:top" ); print &ui_columns_start([ "", "ID", @@ -160,33 +151,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 $sb = $attr{'ACTIVE'} eq 'NO' ? '' : ''; # StrikeBegin + my @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,42 +193,29 @@ 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 $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 $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}" ); - } - local $mover; - $mover .= ""; - if( $i < $nMasq ) { - $mover .= ""; - } else { - $mover .= ""; + push(@cols, "${aimage}${sb}${bb}${cb}$text{YES}${ce}${be}${se}" ); } - if( $i > 1 ) { - $mover .= ""; - } else { - $mover .= ""; - } - $mover .= "
- down - -      - - up - -    -
"; + my $mover = &ui_up_down_arrows( + "list_nat.cgi?table=masquerade&idx=$i&up=1", + "list_nat.cgi?table=masquerade&idx=$i&down=1", + $i > 1, + $i < $nMasq, + "images/up.gif", + "images/down.gif" + ); push(@cols, $mover); print &ui_checked_columns_row(\@cols, \@tds, "d", $i); } @@ -247,17 +230,17 @@ sub showMasquerade { sub showRedirect { print &ui_subheading($icons{REDIRECT}{IMAGE},$text{'redirect_redirect'}); print &ui_form_start("save_redirect.cgi", "post"); - @links = ( &select_all_link("d", $form), + my @links = ( &select_all_link("d", $form), &select_invert_link("d", $form), - "$text{'list_nat_create_redirect'}" ); - @tds = ( "width=1% style=vertical-align:top", - "width=1% style=text-align:center;vertical-align:top", - "width=25% style=vertical-align:top;white-space:normal", - "width=25% style=vertical-align:top;white-space:normal", - "style=vertical-align:top;white-space:normal", - "width=1% style=vertical-align:top;text-align:center", - "width=1% style=vertical-align:top;white-space:normal", - "width=1% style=vertical-align:top" ); + &ui_link("edit_redirect.cgi?new=1", "$text{'list_nat_create_redirect'}") ); + my @tds = ( "width=1% style=vertical-align:top", + "width=1% style=text-align:center;vertical-align:top", + "width=25% style=vertical-align:top;white-space:normal", + "width=25% style=vertical-align:top;white-space:normal", + "style=vertical-align:top;white-space:normal", + "width=1% style=vertical-align:top;text-align:center", + "width=1% style=vertical-align:top;white-space:normal", + "width=64 style=vertical-align:top" ); print &ui_columns_start([ "", "ID", @@ -269,33 +252,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 $sb = $attr{'ACTIVE'} eq 'NO' ? '' : ''; # StrikeBegin + my @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,45 +295,32 @@ 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 $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 $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}" ); - } - local $mover; - $mover .= ""; - if( $i < $nRedirect ) { - $mover .= ""; - } else { - $mover .= ""; - } - if( $i > 1 ) { - $mover .= ""; - } else { - $mover .= ""; + push(@cols, "${timage}${sb}${bb}$attr{'TOPORT'}${be}${se}" ); } - $mover .= "
- down - -      - - up - -    -
"; + my $mover = &ui_up_down_arrows( + "list_nat.cgi?table=redirect&idx=$i&up=1", + "list_nat.cgi?table=redirect&idx=$i&down=1", + $i > 1, + $i < $nRedirect, + "images/up.gif", + "images/down.gif" + ); push(@cols, $mover); print &ui_checked_columns_row(\@cols, \@tds, "d", $i); } diff --git a/src/turtlefirewall/list_ndpiprotocols.cgi b/src/turtlefirewall/list_ndpiprotocols.cgi index 2959fbc..c85e2c5 100644 --- a/src/turtlefirewall/list_ndpiprotocols.cgi +++ b/src/turtlefirewall/list_ndpiprotocols.cgi @@ -3,14 +3,14 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2026 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'}, "" ); +&ui_print_header( "$icons{ICON}{IMAGE}$text{'index_icon_ndpiprotocols'}", $text{'title'}, "" ); &LoadNdpiProtocols($fw); &showNdpiProtocols(); @@ -21,12 +21,12 @@ print "

"; #============================================================================ sub showNdpiProtocols { - @tds = ( "width=20%", "width=80%" ); - print &ui_columns_start([ "$text{'name'}", "$text{'category'}" ], 100, 0, \@tds); + my @tds = ( "width=20%", "width=20%", "width=60%" ); + print &ui_columns_start([ "$text{'name'}", "$text{'category'}", "$text{'flag'}" ], 100, 0, \@tds); my @ndpiprotocols = $fw->GetNdpiProtocolsList(); foreach my $name (@ndpiprotocols) { my %ndpiprotocol = $fw->GetNdpiProtocol($name); - print &ui_columns_row([ "$icons{NDPISERVICE}{IMAGE}$name", "$icons{DESCRIPTION}{IMAGE}$ndpiprotocol{'CATEGORY'}" ], \@tds); + print &ui_columns_row([ "$icons{NDPISERVICE}{IMAGE}$name", "$icons{DESCRIPTION}{IMAGE}$ndpiprotocol{'CATEGORY'}", "$ndpiprotocol{'DPI'}" ], \@tds); } print &ui_columns_end(); } diff --git a/src/turtlefirewall/list_ndpirisks.cgi b/src/turtlefirewall/list_ndpirisks.cgi index 9b53724..d492b98 100644 --- a/src/turtlefirewall/list_ndpirisks.cgi +++ b/src/turtlefirewall/list_ndpirisks.cgi @@ -3,14 +3,14 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2026 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'}, "" ); +&ui_print_header( "$icons{ICON}{IMAGE}$text{'index_icon_ndpirisks'}", $text{'title'}, "" ); &LoadNdpiRisks($fw); &showNdpiRisks(); @@ -21,12 +21,12 @@ print "

"; #============================================================================ sub showNdpiRisks { - @tds = ( "width=5%", "width=95%" ); - print &ui_columns_start([ "$text{'id'}", "$text{'description'}" ], 100, 0, \@tds); + my @tds = ( "width=5%", "width=30%", "width=65%" ); + print &ui_columns_start([ "$text{'id'}", "$text{'description'}", "$text{'severity'}" ], 100, 0, \@tds); my @ndpirisks = $fw->GetNdpiRisksList(); foreach $id (sort { $a <=> $b } @ndpirisks) { my %ndpirisk = $fw->GetNdpiRisk($id); - print &ui_columns_row([ "$icons{RISK}{IMAGE}$id", "$icons{DESCRIPTION}{IMAGE}$ndpirisk{'DESCRIPTION'}" ], \@tds); + print &ui_columns_row([ "$icons{RISK}{IMAGE}$id", "$icons{DESCRIPTION}{IMAGE}$ndpirisk{'DESCRIPTION'}", "$ndpirisk{'SEVERITY'}" ], \@tds); } print &ui_columns_end(); } diff --git a/src/turtlefirewall/list_rawrules.cgi b/src/turtlefirewall/list_rawrules.cgi index b247a0c..2e129a6 100644 --- a/src/turtlefirewall/list_rawrules.cgi +++ b/src/turtlefirewall/list_rawrules.cgi @@ -3,22 +3,22 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2026 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'}, "" ); +&ui_print_header( "$icons{ICON}{IMAGE}$text{'index_icon_rawrules'}", $text{'title'}, "" ); $form = 0; -showConntrackPreroute(); +&showConntrackPreroute(); $form++; print "

"; -showConntrack(); +&showConntrack(); &ui_print_footer('index.cgi',$text{'index'}); @@ -27,17 +27,17 @@ showConntrack(); sub showConntrackPreroute { print &ui_subheading($icons{HELPER}{IMAGE},$text{'conntrack_preroute'}); print &ui_form_start("save_conntrackpreroute.cgi", "post"); - @links = ( &select_all_link("d", $form), + my @links = ( &select_all_link("d", $form), &select_invert_link("d", $form), - "$text{'list_conntrackpreroutes_create_rule'}" ); - @tds = ( + &ui_link("edit_conntrackpreroute.cgi?new=1", "$text{'list_conntrackpreroutes_create_rule'}") ); + my @tds = ( "width=1% style=vertical-align:top", "width=1% style=vertical-align:top", "width=25% style=vertical-align:top;white-space:normal", "width=25% style=vertical-align:top;white-space:normal", "style=vertical-align:top;white-space:normal", "width=1% style=vertical-align:top;white-space:normal", - "width=1% style=vertical-align:top" ); + "width=64 style=vertical-align:top" ); print &ui_columns_start([ '', "ID", @@ -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 ) { @@ -69,11 +69,11 @@ sub showConntrackPreroute { for( my $i=1; $i<=$nConntrackPreroutes; $i++ ) { my %attr = $fw->GetConntrackPreroute($i); - local @cols; + my @cols = (); if( $attr{'TARGET'} eq '' ) { $attr{'TARGET'} = 'ACCEPT'; } - my $bb = $idx == $i ? '' : ''; # BoldBegin - my $be = $idx == $i ? '' : ''; # BoldEnd - my $sb = $attr{'ACTIVE'} eq 'NO' ? '' : ''; # StrikeBegin + 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}"); push(@cols, $href ); @@ -82,42 +82,23 @@ 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}"); - my $cb = $sb eq '' ? '' : ''; # ColourBegin + 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 .= ""; - } else { - $mover .= ""; - } - if( $i > 1 ) { - $mover .= ""; - } else { - $mover .= ""; - } - # if( $i > 2 ) { - # $mover .= ""; - # } else { - # $mover .= ""; - # } - $mover .= "
V     - v - -      - - ^ - -    - A  
"; + my $mover = &ui_up_down_arrows( + "list_rawrules.cgi?table=conntrackpreroute&idx=$i&up=1", + "list_rawrules.cgi?table=conntrackpreroute&idx=$i&down=1", + $i > 1, + $i < $nConntrackPreroutes, + "images/up.gif", + "images/down.gif" + ); push(@cols, $mover); print &ui_checked_columns_row(\@cols, \@tds, "d", $i); } @@ -132,17 +113,17 @@ sub showConntrackPreroute { sub showConntrack { print &ui_subheading($icons{HELPER}{IMAGE},$text{'conntrack'}); print &ui_form_start("save_conntrack.cgi", "post"); - @links = ( &select_all_link("d", $form), + my @links = ( &select_all_link("d", $form), &select_invert_link("d", $form), - "$text{'list_conntracks_create_rule'}" ); - @tds = ( + &ui_link("edit_conntrack.cgi?new=1", "$text{'list_conntracks_create_rule'}") ); + my @tds = ( "width=1% style=vertical-align:top", "width=1% style=vertical-align:top", "width=25% style=vertical-align:top;white-space:normal", "width=25% style=vertical-align:top;white-space:normal", "style=vertical-align:top;white-space:normal", "width=1% style=vertical-align:top;white-space:normal", - "width=1% style=vertical-align:top" ); + "width=64 style=vertical-align:top" ); print &ui_columns_start([ '', "ID", @@ -154,8 +135,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 ) { @@ -174,11 +155,11 @@ sub showConntrack { for( my $i=1; $i<=$nConntracks; $i++ ) { my %attr = $fw->GetConntrack($i); - local @cols; + my @cols = (); if( $attr{'TARGET'} eq '' ) { $attr{'TARGET'} = 'ACCEPT'; } - my $bb = $idx == $i ? '' : ''; # BoldBegin - my $be = $idx == $i ? '' : ''; # BoldEnd - my $sb = $attr{'ACTIVE'} eq 'NO' ? '' : ''; # StrikeBegin + 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}"); push(@cols, $href ); @@ -187,42 +168,23 @@ 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}"); - my $cb = $sb eq '' ? '' : ''; # ColourBegin + 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 .= ""; - } else { - $mover .= ""; - } - if( $i > 1 ) { - $mover .= ""; - } else { - $mover .= ""; - } - # if( $i > 2 ) { - # $mover .= ""; - # } else { - # $mover .= ""; - # } - $mover .= "
V     - v - -      - - ^ - -    - A  
"; + my $mover = &ui_up_down_arrows( + "list_rawrules.cgi?table=conntrack&idx=$i&up=1", + "list_rawrules.cgi?table=conntrack&idx=$i&down=1", + $i > 1, + $i < $nConntracks, + "images/up.gif", + "images/down.gif" + ); 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..bdc16b0 100644 --- a/src/turtlefirewall/list_rules.cgi +++ b/src/turtlefirewall/list_rules.cgi @@ -3,15 +3,15 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2026 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'}, "" ); +&ui_print_header( "$icons{ICON}{IMAGE}$text{'index_icon_rules'}", $text{'title'}, "" ); &showRule(); @@ -20,11 +20,12 @@ do 'turtlefirewall-lib.pl'; #============================================================================ sub showRule { + print &ui_subheading($icons{RULE}{IMAGE},$text{'rule'}); print &ui_form_start("save_rule.cgi", "post"); - @links = ( &select_all_link("d"), + my @links = ( &select_all_link("d"), &select_invert_link("d"), - "$text{'list_rules_create_rule'}" ); - @tds = ( + &ui_link("edit_rule.cgi?new=1", "$text{'list_rules_create_rule'}") ); + my @tds = ( "width=1% style=vertical-align:top", "width=1% style=text-align:center;vertical-align:top", "width=10% style=vertical-align:top;white-space:normal", @@ -38,7 +39,7 @@ sub showRule { "style=vertical-align:top", "style=vertical-align:top", "style=vertical-align:top;white-space:normal", - "width=1% style=vertical-align:top" ); + "width=64 style=vertical-align:top" ); print &ui_columns_start([ '', "ID", @@ -63,19 +64,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(); @@ -84,11 +76,11 @@ sub showRule { for( my $i=1; $i<=$nRules; $i++ ) { my %attr = $fw->GetRule($i); - local @cols; + my @cols = (); if( $attr{'TARGET'} eq '' ) { $attr{'TARGET'} = 'ACCEPT'; } my $bb = $idx == $i ? '' : ''; # BoldBegin my $be = $idx == $i ? '' : ''; # BoldEnd - my $sb = $attr{'ACTIVE'} eq 'NO' ? '' : ''; # StrikeBegin + my $sb = $attr{'ACTIVE'} eq 'NO' ? '' : ''; # StrikeBegin my $se = $attr{'ACTIVE'} eq 'NO' ? '' : ''; # StrikeEnd my $href = &ui_link("edit_rule.cgi?idx=$i","${sb}${bb}${i}${be}${se}"); push(@cols, $href ); @@ -149,17 +141,17 @@ sub showRule { } push(@cols, "${cimage}${sb}${bb}$attr{'TIME'}${be}${se}" ); if( $attr{'TARGET'} eq 'ACCEPT' ) { - my $cb = $sb eq '' ? '' : ''; # ColourBegin + my $cb = $sb eq '' ? '' : ''; # ColourBegin my $ce = $se eq '' ? '' : ''; # ColourEnd my $aimage = $attr{'ACTIVE'} eq 'NO' ? $icons{ACCEPT}{IMAGE} : $icons{ACCEPT_A}{IMAGE}; push(@cols, "${aimage}${sb}${bb}${cb}$attr{'TARGET'}${ce}${be}${se}" ); } elsif( $attr{'TARGET'} eq 'DROP' ) { - my $cb = $sb eq '' ? '' : ''; # ColourBegin + my $cb = $sb eq '' ? '' : ''; # ColourBegin my $ce = $se eq '' ? '' : ''; # ColourEnd my $dimage = $attr{'ACTIVE'} eq 'NO' ? $icons{DROP}{IMAGE} : $icons{DROP_A}{IMAGE}; push(@cols, "${dimage}${sb}${bb}${cb}$attr{'TARGET'}${ce}${be}${se}" ); } elsif( $attr{'TARGET'} eq 'REJECT' ) { - my $cb = $sb eq '' ? '' : ''; # ColourBegin + my $cb = $sb eq '' ? '' : ''; # ColourBegin my $ce = $se eq '' ? '' : ''; # ColourEnd my $dimage = $attr{'ACTIVE'} eq 'NO' ? $icons{REJECT}{IMAGE} : $icons{REJECT_A}{IMAGE}; push(@cols, "${dimage}${sb}${bb}${cb}$attr{'TARGET'}${ce}${be}${se}" ); @@ -174,41 +166,18 @@ sub showRule { } my $iimage = $attr{'DESCRIPTION'} eq '' ? '' : $icons{DESCRIPTION}{IMAGE}; 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 .= ""; - } else { - $mover .= ""; - } - if( $i > 1 ) { - $mover .= ""; - } else { - $mover .= ""; - } - # if( $i > 2 ) { - # $mover .= ""; - # } else { - # $mover .= ""; - # } - $mover .= "
V     - v - -      - - ^ - -    - A  
"; + my $mover = &ui_up_down_arrows( + "list_rules.cgi?idx=$i&up=1", + "list_rules.cgi?idx=$i&down=1", + $i > 1, + $i < $nRules, + "images/up.gif", + "images/down.gif" + ); push(@cols, $mover); print &ui_checked_columns_row(\@cols, \@tds, "d", $i); } - print &ui_columns_row([undef, undef, "$icons{ZONE}{IMAGE}*", "$icons{ZONE}{IMAGE}*", "$icons{SERVICE}{IMAGE}all", "", "", "", "", "", "$icons{DROP_A}{IMAGE}DROP", "$icons{LOG_A}{IMAGE}ACT", "$icons{DESCRIPTION}{IMAGE}Implicit Deny", undef], \@tds); + print &ui_columns_row([undef, undef, "$icons{ZONE}{IMAGE}*", "$icons{ZONE}{IMAGE}*", "$icons{SERVICE}{IMAGE}all", "", "", "", "", "", "$icons{DROP_A}{IMAGE}DROP", "$icons{LOG_A}{IMAGE}ACT", "$icons{DESCRIPTION}{IMAGE}Implicit Deny", undef], \@tds); print &ui_columns_end(); print ""; print ''; diff --git a/src/turtlefirewall/list_services.cgi b/src/turtlefirewall/list_services.cgi index 22556b1..fb8e314 100644 --- a/src/turtlefirewall/list_services.cgi +++ b/src/turtlefirewall/list_services.cgi @@ -3,14 +3,14 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2026 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'}, "" ); +&ui_print_header( "$icons{ICON}{IMAGE}$text{'index_icon_services'}", $text{'title'}, "" ); &LoadServices($fw); &showServices(); @@ -21,7 +21,7 @@ print "

"; #============================================================================ sub showServices { - @tds = ( "width=20%", "width=80%" ); + my @tds = ( "width=20%", "width=80%" ); print &ui_columns_start([ "$text{'name'}", "$text{'description'}" ], 100, 0, \@tds); my @services = $fw->GetServicesList(); foreach my $name (@services) { diff --git a/src/turtlefirewall/module.info b/src/turtlefirewall/module.info index 832b6e2..4f485d8 100644 --- a/src/turtlefirewall/module.info +++ b/src/turtlefirewall/module.info @@ -1,7 +1,7 @@ os_support=*-linux -version=2.4 +version=2.7 longdesc=Configure a Linux firewall in a simple and fast way. name=turtlefirewall desc=Turtle Firewall category=net -depends=2.201 +depends=2.600 diff --git a/src/turtlefirewall/restore.cgi b/src/turtlefirewall/restore.cgi new file mode 100644 index 0000000..8b3894e --- /dev/null +++ b/src/turtlefirewall/restore.cgi @@ -0,0 +1,33 @@ +#!/usr/bin/perl + +#====================================================================== +# Turtle Firewall webmin module +# +# Copyright (c) 2001-2026 Andrea Frigido +# You may distribute under the terms of either the GNU General Public +# License +#====================================================================== + +require './turtlefirewall-lib.pl'; +&ReadParseMime(); + +&ui_print_header( "$icons{ICON}{IMAGE}$text{'index_icon_configuration'}", $text{'title'}, "" ); + +if( $in{backup} ) { + my $backup = $in{backup}; + my $output = &tempname(); + my $confdir = &confdir(); + + open TARGZ, "| tar xvz --directory $confdir fw.xml fwuserdefservices.xml >$output 2>&1" or &error( $text{configuration_error1} ); + syswrite(TARGZ, $backup, length($backup)); + close TARGZ; + + open FILE, "<$output"; + while (my $f = ) { print &ui_alert_box("${confdir}/${f} restored", 'success'); } + close FILE; + unlink $output; +} else { + print &ui_alert_box($text{configuration_error_title1}, 'danger'); +} + +&ui_print_footer('configuration.cgi',$text{'index_configuration'}); diff --git a/src/turtlefirewall/save_addresslist.cgi b/src/turtlefirewall/save_addresslist.cgi index eae56c4..632aded 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-2026 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..6481a86 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-2026 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..d3d930e 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-2026 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..d078b99 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-2026 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..bc26a7e 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-2026 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..2b5f153 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-2026 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..bc04660 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-2026 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..2802afb 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-2026 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..ecb4905 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-2026 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..015e34f 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-2026 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..281ed35 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-2026 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..e30d834 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-2026 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..0e7aebd 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-2026 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..27c3d69 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-2026 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..14bd3d6 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-2026 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..38550b0 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-2026 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..0136554 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-2026 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..cca8d71 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-2026 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..02309d3 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-2026 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..00ce192 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-2026 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..d3f90c4 100644 --- a/src/turtlefirewall/save_zone.cgi +++ b/src/turtlefirewall/save_zone.cgi @@ -3,18 +3,18 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2026 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'}; -$zone = $in{'zone'}; -$if = $in{'if'}; -$description = $in{'description'}; +my $newzone = $in{'newzone'}; +my $zone = $in{'zone'}; +my $if = $in{'if'}; +my $description = $in{'description'}; if( ! $fw->checkName($newzone) ) { &error( $text{save_zone_error8} ); } diff --git a/src/turtlefirewall/setup.cgi b/src/turtlefirewall/setup.cgi index 2f18161..a592388 100644 --- a/src/turtlefirewall/setup.cgi +++ b/src/turtlefirewall/setup.cgi @@ -3,7 +3,7 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2026 Andrea Frigido # You may distribute under the terms of either the GNU General Public # License #====================================================================== @@ -12,7 +12,8 @@ use WebminCore; &init_config(); &ReadParse(); -&ui_print_header( undef, $text{'title'}, "" ); +&ui_print_header( "$icons{ICON}{IMAGE} v ".$fw->Version(), $text{'title'}, "", undef, 1, 1, 0, + &help_search_link("iptables", "man", "doc")); # do you need to install startup scripts? if( -f "./setup/turtlefirewall" ) { @@ -24,14 +25,13 @@ if( -f "./setup/turtlefirewall" ) { chdir("../"); } if( $err == 0 ) { - print "

Congratulation: Turtle Firewall successfully installed, "; - print 'Return to index.

'; + print &ui_alert_box('Congratulations: Turtle Firewall successfully installed', 'success', undef, undef, ''); system( 'rm -rf setup' ); } else { - print "Installation error, Turtle Firewall is not successfully installed!"; + print &ui_alert_box('Installation error: Turtle Firewall was not successfully installed', 'danger', undef, undef, ''); } } print "

\n"; -&ui_print_footer('/',$text{'index'}); +&ui_print_footer('index.cgi',$text{'index'}); diff --git a/src/turtlefirewall/setup/TurtleFirewall.pm b/src/turtlefirewall/setup/TurtleFirewall.pm index 08e2e27..a1c4bc7 100644 --- a/src/turtlefirewall/setup/TurtleFirewall.pm +++ b/src/turtlefirewall/setup/TurtleFirewall.pm @@ -1,27 +1,28 @@ -# 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-2026 Andrea Frigido # You may distribute under the terms of either the GNU General Public # License #====================================================================== package TurtleFirewall; +use strict; +use warnings; use XML::Parser; # Turtle Firewall Version sub Version { - return '2.4'; + return '2.7'; } sub new { - my $this ={}; - #$this->{NOME} = undef; + my $this = {}; $this->{fw} = (); $this->{fwItems} = (); $this->{fwKeys} = (); @@ -40,127 +41,127 @@ sub new { # Public method for get firewall info (after LoadFirewall) sub GetZoneList { my $this = shift; - return sort( keys %{ $this->{fw}{ZONE} } ); + return exists($this->{fw}{ZONE}) ? sort( keys %{ $this->{fw}{ZONE} } ) : (); } sub GetGeoipList { my $this = shift; - return sort( keys %{ $this->{fw}{GEOIP} } ); + return exists($this->{fw}{GEOIP}) ? sort( keys %{ $this->{fw}{GEOIP} } ) : (); } sub GetNetList { my $this = shift; - return sort( keys %{ $this->{fw}{NET} } ); + return exists($this->{fw}{NET}) ? sort( keys %{ $this->{fw}{NET} } ) : (); } sub GetHostList { my $this = shift; - return sort( keys %{ $this->{fw}{HOST} } ); + return exists($this->{fw}{HOST}) ? sort( keys %{ $this->{fw}{HOST} } ) : (); } sub GetTimeList { my $this = shift; - return sort( keys %{ $this->{fw}{TIME} } ); + return exists($this->{fw}{TIME}) ? sort( keys %{ $this->{fw}{TIME} } ) : (); } sub GetGroupList { my $this = shift; - return @{$this->{fwKeys}{GROUP}}; + return exists($this->{fwKeys}{GROUP}) ? sort @{ $this->{fwKeys}{GROUP} } : (); } sub GetTimeGroupList { my $this = shift; - return @{$this->{fwKeys}{TIMEGROUP}}; + return exists($this->{fwKeys}{TIMEGROUP}) ? sort @{$this->{fwKeys}{TIMEGROUP}} : (); } sub GetHostNameSetList { my $this = shift; - return sort( keys %{ $this->{fw}{HOSTNAMESET} } ); + return exists($this->{fw}{HOSTNAMESET}) ? sort( keys %{ $this->{fw}{HOSTNAMESET} } ) : (); } sub GetRiskSetList { my $this = shift; - return sort( keys %{ $this->{fw}{RISKSET} } ); + return exists($this->{fw}{RISKSET}) ? sort( keys %{ $this->{fw}{RISKSET} } ) : (); } sub GetRateLimitList { my $this = shift; - return sort( keys %{ $this->{fw}{RATELIMIT} } ); + return exists($this->{fw}{RATELIMIT}) ? sort( keys %{ $this->{fw}{RATELIMIT} } ) : (); } sub GetAddressListList { my $this = shift; - return sort( keys %{ $this->{fw}{ADDRESSLIST} } ); + return exists($this->{fw}{ADDRESSLIST}) ? sort( keys %{ $this->{fw}{ADDRESSLIST} } ) : (); } sub GetIPSetList { my $this = shift; - return sort( keys %{ $this->{fw}{IPSET} } ); + return exists($this->{fw}{IPSET}) ? sort( keys %{ $this->{fw}{IPSET} } ) : (); } sub GetZone { my ($this,$name) = @_; - return %{ $this->{fw}{ZONE}{$name} }; + return exists($this->{fw}{ZONE}{$name}) ? %{ $this->{fw}{ZONE}{$name} } : (); } sub GetGeoip { my ($this,$name) = @_; - return %{ $this->{fw}{GEOIP}{$name} }; + return exists($this->{fw}{GEOIP}{$name}) ? %{ $this->{fw}{GEOIP}{$name} } : (); } sub GetNet { my ($this,$name) = @_; - return %{ $this->{fw}{NET}{$name} }; + return exists($this->{fw}{NET}{$name}) ? %{ $this->{fw}{NET}{$name} } : (); } sub GetHost { my ($this,$name) = @_; - return %{ $this->{fw}{HOST}{$name} }; + return exists($this->{fw}{HOST}{$name}) ? %{ $this->{fw}{HOST}{$name} } : (); } sub GetTime { my ($this,$name) = @_; - return %{ $this->{fw}{TIME}{$name} }; + return exists($this->{fw}{TIME}{$name}) ? %{ $this->{fw}{TIME}{$name} } : (); } sub GetGroup { my ($this,$name) = @_; - return %{ $this->{fw}{GROUP}{$name} }; + return exists($this->{fw}{GROUP}{$name}) ? %{ $this->{fw}{GROUP}{$name} } : (); } sub GetTimeGroup { my ($this,$name) = @_; - return %{ $this->{fw}{TIMEGROUP}{$name} }; + return exists($this->{fw}{TIMEGROUP}{$name}) ? %{ $this->{fw}{TIMEGROUP}{$name} } : (); } sub GetHostNameSet { my ($this,$name) = @_; - return %{ $this->{fw}{HOSTNAMESET}{$name} }; + return exists($this->{fw}{HOSTNAMESET}{$name}) ? %{ $this->{fw}{HOSTNAMESET}{$name} } : (); } sub GetRiskSet { my ($this,$name) = @_; - return %{ $this->{fw}{RISKSET}{$name} }; + return exists($this->{fw}{RISKSET}{$name}) ? %{ $this->{fw}{RISKSET}{$name} } : (); } sub GetRateLimit { my ($this,$name) = @_; - return %{ $this->{fw}{RATELIMIT}{$name} }; + return exists($this->{fw}{RATELIMIT}{$name}) ? %{ $this->{fw}{RATELIMIT}{$name} } : (); } sub GetAddressList { my ($this,$name) = @_; - return %{ $this->{fw}{ADDRESSLIST}{$name} }; + return exists($this->{fw}{ADDRESSLIST}{$name}) ? %{ $this->{fw}{ADDRESSLIST}{$name} } : (); } sub GetIPSet { my ($this,$name) = @_; - return %{ $this->{fw}{IPSET}{$name} }; + return exists($this->{fw}{IPSET}{$name}) ? %{ $this->{fw}{IPSET}{$name} } : (); } sub GetAllItemsList { my $this = shift; - return sort( keys %{ $this->{fwItems} } ); + return exists($this->{fwItems}) ? sort( keys %{ $this->{fwItems} } ) : (); } # GetItemsAllowToGroup( group ) @@ -170,26 +171,28 @@ sub GetItemsAllowToGroup { my $group = shift; my @items = (); push @items, 'FIREWALL'; - push @items, @{$this->{fwKeys}{ZONE}}; - push @items, @{$this->{fwKeys}{NET}}; - push @items, @{$this->{fwKeys}{HOST}}; - push @items, @{$this->{fwKeys}{GEOIP}}; - push @items, @{$this->{fwKeys}{IPSET}}; - foreach my $g ( @{$this->{fwKeys}{GROUP}} ) { - if( $g eq $group ) { - last; + push @items, exists($this->{fwKeys}{ZONE}) ? @{$this->{fwKeys}{ZONE}} : (); + push @items, exists($this->{fwKeys}{NET}) ? @{$this->{fwKeys}{NET}} : (); + push @items, exists($this->{fwKeys}{HOST}) ? @{$this->{fwKeys}{HOST}} : (); + push @items, exists($this->{fwKeys}{GEOIP}) ? @{$this->{fwKeys}{GEOIP}} : (); + push @items, exists($this->{fwKeys}{IPSET}) ? @{$this->{fwKeys}{IPSET}} : (); + if( exists($this->{fwKeys}{GROUP}) ) { + foreach my $g ( @{$this->{fwKeys}{GROUP}} ) { + if( $g eq $group ) { + last; + } + push @items, $g; } - push @items, $g; } - return @items; + return sort @items; } sub GetItemsAllowToTimeGroup { my $this = shift; my $timegroup = shift; my @items = (); - push @items, @{$this->{fwKeys}{TIME}}; - return @items; + push @items, exists($this->{fwKeys}{TIME}) ? @{$this->{fwKeys}{TIME}} : (); + return sort @items; } sub GetServicesList { @@ -242,7 +245,6 @@ sub GetMasqueradesCount { } sub GetMasquerade { - # param n = id of masquerade rule (1 .. MasqueradeCount) my ($this,$n) = @_; return %{ $this->{fw}{MASQUERADE}[$n-1] }; } @@ -435,7 +437,7 @@ sub AddZone { # AddMasquerade( $idx, $zone, $active ) if $idx==0 then add new Masquerade sub AddMasquerade { my ($this, $idx, $src, $dst, $service, $port, $masquerade, $active ) = @_; - + my %attr = ( 'SRC'=>$src, 'DST'=>$dst, 'SERVICE'=>$service); if( $port ne '' ) { $attr{PORT} = $port; } if( ! $masquerade ) { $attr{MASQUERADE} = 'NO'; } @@ -454,6 +456,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 +485,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 +514,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 ) = @_; @@ -812,7 +835,7 @@ sub DeleteItem { last; } } - + if( !$found ) { delete $this->{fw}{$type}{$name}; delete $this->{fwItems}{$name}; @@ -837,7 +860,7 @@ sub RenameItem { # An Item with this name exists return 0; } else { - $type = $this->{fwItems}{$oldname}; + my $type = $this->{fwItems}{$oldname}; %{$this->{fw}{$type}{$newname}} = %{$this->{fw}{$type}{$oldname}}; $this->{fw}{$type}{$newname}{NAME} = $newname; $this->{fwItems}{$newname} = $type; @@ -851,22 +874,22 @@ sub RenameItem { # If it's a zone, I need to change all items that use this zone. if( $type eq 'ZONE' ) { - foreach $k (@{$this->{fwKeys}{HOST}}) { + foreach my $k (@{$this->{fwKeys}{HOST}}) { if( $this->{fw}{HOST}{$k}{ZONE} eq $oldname ) { $this->{fw}{HOST}{$k}{ZONE} = $newname; } } - foreach $k (@{$this->{fwKeys}{NET}}) { + foreach my $k (@{$this->{fwKeys}{NET}}) { if( $this->{fw}{NET}{$k}{ZONE} eq $oldname ) { $this->{fw}{NET}{$k}{ZONE} = $newname; } } - foreach $k (@{$this->{fwKeys}{GEOIP}}) { + foreach my $k (@{$this->{fwKeys}{GEOIP}}) { if( $this->{fw}{GEOIP}{$k}{ZONE} eq $oldname ) { $this->{fw}{GEOIP}{$k}{ZONE} = $newname; } } - foreach $k (@{$this->{fwKeys}{IPSET}}) { + foreach my $k (@{$this->{fwKeys}{IPSET}}) { if( $this->{fw}{IPSET}{$k}{ZONE} eq $oldname ) { $this->{fw}{IPSET}{$k}{ZONE} = $newname; } @@ -875,7 +898,7 @@ sub RenameItem { # If it's an addresslist, I need to change all ipsets that use this addresslist. if( $type eq 'ADDRESSLIST' ) { - foreach $k (@{$this->{fwKeys}{IPSET}}) { + foreach my $k (@{$this->{fwKeys}{IPSET}}) { if( $this->{fw}{IPSET}{$k}{IP} eq $oldname ) { $this->{fw}{IPSET}{$k}{IP} = $newname; } @@ -903,7 +926,7 @@ sub RenameItem { # Change item name in all rules foreach my $ruletype ('RULE','CONNMARKPREROUTE','CONNMARK','CONNTRACKPREROUTE','CONNTRACK','NAT','MASQUERADE','REDIRECT') { for( my $i=0; $i<=$#{$this->{fw}{$ruletype}}; $i++ ) { - foreach $item ('SRC','DST','ZONE','VIRTUAL','REAL','TIME','HOSTNAMESET','RISKSET','RATELIMIT') { + foreach my $item ('SRC','DST','ZONE','VIRTUAL','REAL','TIME','HOSTNAMESET','RISKSET','RATELIMIT') { my @item_list = split( /,/, $this->{fw}{$ruletype}[$i]{$item} ); if( grep( /^$oldname$/, @item_list ) ) { s/^$oldname$/$newname/ for @item_list; @@ -926,25 +949,25 @@ sub GetItemReferences { my %references = (); if( $type eq 'ZONE' ) { - foreach $k (@{$this->{fwKeys}{HOST}}) { + foreach my $k (@{$this->{fwKeys}{HOST}}) { if( $this->{fw}{HOST}{$k}{ZONE} eq $item ) { $references{$k} = 'HOST'; } } - foreach $k (@{$this->{fwKeys}{NET}}) { + foreach my $k (@{$this->{fwKeys}{NET}}) { if( $this->{fw}{NET}{$k}{ZONE} eq $item ) { $references{$k} = 'NET'; } } - foreach $k (@{$this->{fwKeys}{GEOIP}}) { + foreach my $k (@{$this->{fwKeys}{GEOIP}}) { if( $this->{fw}{GEOIP}{$k}{ZONE} eq $item ) { $references{$k} = 'GEOIP'; } } - foreach $k (@{$this->{fwKeys}{IPSET}}) { + foreach my $k (@{$this->{fwKeys}{IPSET}}) { if( $this->{fw}{IPSET}{$k}{ZONE} eq $item ) { $references{$k} = 'IPSET'; } @@ -952,7 +975,7 @@ sub GetItemReferences { } if( $type eq 'ADDRESSLIST' ) { - foreach $k (@{$this->{fwKeys}{IPSET}}) { + foreach my $k (@{$this->{fwKeys}{IPSET}}) { if( $this->{fw}{IPSET}{$k}{IP} eq $item ) { $references{$k} = 'IPSET'; } @@ -977,10 +1000,10 @@ sub GetItemReferences { foreach my $ruletype ('RULE','CONNMARKPREROUTE','CONNMARK','CONNTRACKPREROUTE','CONNTRACK','NAT','MASQUERADE','REDIRECT') { for( my $i=0; $i<=$#{$this->{fw}{$ruletype}}; $i++ ) { - foreach $ruleitem ('SRC','DST','ZONE','VIRTUAL','REAL','TIME','HOSTNAMESET','RISKSET','RATELIMIT') { + foreach my $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; } } } @@ -1134,9 +1157,9 @@ sub LoadFirewall { my $name = uc($tree[$i]); if ($name eq 'FIREWALL') { my @list = @{$tree[$i+1]}; - my %attr = shift @list; + 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]} ); } @@ -1174,9 +1197,10 @@ sub _LoadFirewallItem { my %attrs = upperKeys( %{shift @list} ); my $name = $attrs{'NAME'}; - if( $this->{fwItems}{$name} ne '' ) { - print STDERR qq~Error: "$name" item is already present.\n~; + if( defined($this->{fwItems}{$name}) && $this->{fwItems}{$name} ne '' ) { + print STDERR "Error: $name item is already present.\n"; } + $this->{fwItems}{$name} = $type; push @{$this->{fwKeys}{$type}}, $name; %{$this->{fw}{$type}{$name}} = %attrs; @@ -1215,9 +1239,8 @@ sub _LoadFirewallNat { my $this = shift; my $type = shift; my @list = @_; - #my $name = $list[$i]; my %attrs = upperKeys( %{shift @list} ); - + ### # Backward compatibility with TurtleFirewall < 1.29 configuration file if( $type eq 'MASQUERADE' ) { @@ -1229,7 +1252,7 @@ sub _LoadFirewallNat { $attrs{SERVICE} = 'all'; } } - + %{$this->{fw}{$type}[$#{$this->{fw}{$type}}+1]} = %attrs; } @@ -1241,14 +1264,14 @@ sub _LoadFirewallRule { my @srcs = split(/,/,$attrs{'SRC'}); foreach my $src (@srcs) { - if( $this->{fwItems}{$src} eq '' && $src ne '*' ) { + if( defined($this->{fwItems}{$src}) && $this->{fwItems}{$src} eq '' && $src ne '*' ) { print STDERR "Error: rule number ".($#{$this->{fw}{RULE}}+2)." has an invalid source item ($src).\n"; } } my @dsts = split(/,/,$attrs{'DST'}); foreach my $dst (@dsts) { - if( $this->{fwItems}{$dst} eq '' && $dst ne '*' ) { + if( defined($this->{fwItems}{$dst}) && $this->{fwItems}{$dst} eq '' && $dst ne '*' ) { print STDERR "Error: rule number ".($#{$this->{fw}{RULE}}+2)." has an invalid destination item ($dst).\n"; } } @@ -1263,12 +1286,12 @@ sub _LoadFirewallConnmarkPreroute { my %attrs = upperKeys( %{shift @list} ); my $src = $attrs{'SRC'}; - if( $this->{fwItems}{$src} eq '' && $src ne '*' ) { + if( defined($this->{fwItems}{$src}) && $this->{fwItems}{$src} eq '' && $src ne '*' ) { print STDERR "Error: rule number ".($#{$this->{fw}{CONNMARKPREROUTE}}+2)." has an invalid source item ($src).\n"; } my $dst = $attrs{'DST'}; - if( $this->{fwItems}{$dst} eq '' && $dst ne '*' ) { + if( defined($this->{fwItems}{$dst}) && $this->{fwItems}{$dst} eq '' && $dst ne '*' ) { print STDERR "Error: rule number ".($#{$this->{fw}{CONNMARKPREROUTE}}+2)." has an invalid destination item ($dst).\n"; } @@ -1283,14 +1306,14 @@ sub _LoadFirewallConnmark { my @srcs = split(/,/,$attrs{'SRC'}); foreach my $src (@srcs) { - if( $this->{fwItems}{$src} eq '' && $src ne '*' ) { + if( defined($this->{fwItems}{$src}) && $this->{fwItems}{$src} eq '' && $src ne '*' ) { print STDERR "Error: rule number ".($#{$this->{fw}{CONNMARK}}+2)." has an invalid source item ($src).\n"; } } my @dsts = split(/,/,$attrs{'DST'}); foreach my $dst (@dsts) { - if( $this->{fwItems}{$dst} eq '' && $dst ne '*' ) { + if( defined($this->{fwItems}{$dst}) && $this->{fwItems}{$dst} eq '' && $dst ne '*' ) { print STDERR "Error: rule number ".($#{$this->{fw}{CONNMARK}}+2)." has an invalid destination item ($dst).\n"; } } @@ -1305,12 +1328,12 @@ sub _LoadFirewallConntrackPreroute { my %attrs = upperKeys( %{shift @list} ); my $src = $attrs{'SRC'}; - if( $this->{fwItems}{$src} eq '' && $src ne '*' ) { + if( defined($this->{fwItems}{$src}) && $this->{fwItems}{$src} eq '' && $src ne '*' ) { print STDERR "Error: rule number ".($#{$this->{fw}{CONNTRACKPREROUTE}}+2)." has an invalid source item ($src).\n"; } my $dst = $attrs{'DST'}; - if( $this->{fwItems}{$dst} eq '' && $dst ne '*' ) { + if( defined($this->{fwItems}{$dst}) && $this->{fwItems}{$dst} eq '' && $dst ne '*' ) { print STDERR "Error: rule number ".($#{$this->{fw}{CONNTRACKPREROUTE}}+2)." has an invalid destination item ($dst).\n"; } @@ -1324,12 +1347,12 @@ sub _LoadFirewallConntrack { my %attrs = upperKeys( %{shift @list} ); my $src = $attrs{'SRC'}; - if( $this->{fwItems}{$src} eq '' && $src ne '*' ) { + if( defined($this->{fwItems}{$src}) && $this->{fwItems}{$src} eq '' && $src ne '*' ) { print STDERR "Error: rule number ".($#{$this->{fw}{CONNTRACK}}+2)." has an invalid source item ($src).\n"; } my $dst = $attrs{'DST'}; - if( $this->{fwItems}{$dst} eq '' && $dst ne '*' ) { + if( defined($this->{fwItems}{$dst}) && $this->{fwItems}{$dst} eq '' && $dst ne '*' ) { print STDERR "Error: rule number ".($#{$this->{fw}{CONNTRACK}}+2)." has an invalid destination item ($dst).\n"; } @@ -1337,12 +1360,6 @@ sub _LoadFirewallConntrack { } # Internal method for add OPTIONS to firewall object -# -# XML: -# -# \n"; $xml .= "\n"; - foreach my $k (keys %{$fw{'ZONE'}}) { - if( $k ne 'FIREWALL' ) { - $xml .= $this->attr2xml( 'zone', %{$fw{'ZONE'}{$k}} ); + if( exists($fw{'ZONE'}) ) { + foreach my $k (keys %{$fw{'ZONE'}}) { + if( $k ne 'FIREWALL' ) { + $xml .= $this->attr2xml( 'zone', %{$fw{'ZONE'}{$k}} ); + } } + $xml .= "\n"; } - $xml .= "\n"; - foreach my $k (keys %{$fw{'NET'}}) { - $xml .= $this->attr2xml( 'net', %{$fw{'NET'}{$k}} ); + if( exists($fw{'NET'}) ) { + foreach my $k (keys %{$fw{'NET'}}) { + $xml .= $this->attr2xml( 'net', %{$fw{'NET'}{$k}} ); + } + $xml .= "\n"; } - if( %{$fw{'NET'}} ) { $xml .= "\n"; } - foreach my $k (keys %{$fw{'HOST'}}) { - $xml .= $this->attr2xml( 'host', %{$fw{'HOST'}{$k}} ); + if( exists($fw{'HOST'}) ) { + foreach my $k (keys %{$fw{'HOST'}}) { + $xml .= $this->attr2xml( 'host', %{$fw{'HOST'}{$k}} ); + } + $xml .= "\n"; } - if( %{$fw{'HOST'}} ) { $xml .= "\n"; } - foreach my $k (keys %{$fw{'GEOIP'}}) { - $xml .= $this->attr2xml( 'geoip', %{$fw{'GEOIP'}{$k}} ); + if( exists($fw{'GEOIP'}) ) { + foreach my $k (keys %{$fw{'GEOIP'}}) { + $xml .= $this->attr2xml( 'geoip', %{$fw{'GEOIP'}{$k}} ); + } + $xml .= "\n"; } - if( %{$fw{'GEOIP'}} ) { $xml .= "\n"; } - foreach my $k (keys %{$fw{'ADDRESSLIST'}}) { - $xml .= $this->attr2xml( 'addresslist', %{$fw{'ADDRESSLIST'}{$k}} ); + if( exists($fw{'ADDRESSLIST'}) ) { + foreach my $k (keys %{$fw{'ADDRESSLIST'}}) { + $xml .= $this->attr2xml( 'addresslist', %{$fw{'ADDRESSLIST'}{$k}} ); + } + $xml .= "\n"; } - if( %{$fw{'ADDRESSLIST'}} ) { $xml .= "\n"; } - foreach my $k (keys %{$fw{'IPSET'}}) { - $xml .= $this->attr2xml( 'ipset', %{$fw{'IPSET'}{$k}} ); + if( exists($fw{'IPSET'}) ) { + foreach my $k (keys %{$fw{'IPSET'}}) { + $xml .= $this->attr2xml( 'ipset', %{$fw{'IPSET'}{$k}} ); + } + $xml .= "\n"; } - if( %{$fw{'IPSET'}} ) { $xml .= "\n"; } - foreach my $k (@{$this->{fwKeys}{GROUP}}) { - $xml .= "_clean($fw{'GROUP'}{$k}{DESCRIPTION})."\">\n"; - foreach my $item (@{$fw{'GROUP'}{$k}{ITEMS}}) { - $xml .= "\t_clean($item)."\"/>\n"; + if( exists($this->{fwKeys}{GROUP}) ) { + foreach my $k (@{$this->{fwKeys}{GROUP}}) { + $xml .= "_clean($fw{'GROUP'}{$k}{DESCRIPTION})."\">\n"; + foreach my $item (@{$fw{'GROUP'}{$k}{ITEMS}}) { + $xml .= "\t_clean($item)."\"/>\n"; + } + $xml .= "\n"; } - $xml .= "\n"; + $xml .= "\n"; } - if( @{$this->{fwKeys}{GROUP}} ) { $xml .= "\n"; } - foreach my $k (keys %{$fw{'TIME'}}) { - $xml .= $this->attr2xml( 'time', %{$fw{'TIME'}{$k}} ); + if( exists($fw{'TIME'}) ) { + foreach my $k (keys %{$fw{'TIME'}}) { + $xml .= $this->attr2xml( 'time', %{$fw{'TIME'}{$k}} ); + } + $xml .= "\n"; } - if( %{$fw{'TIME'}} ) { $xml .= "\n"; } - foreach my $k (@{$this->{fwKeys}{TIMEGROUP}}) { - $xml .= "_clean($fw{'TIMEGROUP'}{$k}{DESCRIPTION})."\">\n"; - foreach my $item (@{$fw{'TIMEGROUP'}{$k}{ITEMS}}) { - $xml .= "\t_clean($item)."\"/>\n"; + if( exists($this->{fwKeys}{TIMEGROUP}) ) { + foreach my $k (@{$this->{fwKeys}{TIMEGROUP}}) { + $xml .= "_clean($fw{'TIMEGROUP'}{$k}{DESCRIPTION})."\">\n"; + foreach my $item (@{$fw{'TIMEGROUP'}{$k}{ITEMS}}) { + $xml .= "\t_clean($item)."\"/>\n"; + } + $xml .= "\n"; } - $xml .= "\n"; + $xml .= "\n"; } - if( @{$this->{fwKeys}{TIMEGROUP}} ) { $xml .= "\n"; } - foreach my $k (keys %{$fw{'HOSTNAMESET'}}) { - $xml .= $this->attr2xml( 'hostnameset', %{$fw{'HOSTNAMESET'}{$k}} ); + if( exists($fw{'HOSTNAMESET'}) ) { + foreach my $k (keys %{$fw{'HOSTNAMESET'}}) { + $xml .= $this->attr2xml( 'hostnameset', %{$fw{'HOSTNAMESET'}{$k}} ); + } + $xml .= "\n"; } - if( %{$fw{'HOSTNAMESET'}} ) { $xml .= "\n"; } - foreach my $k (keys %{$fw{'RISKSET'}}) { - $xml .= $this->attr2xml( 'riskset', %{$fw{'RISKSET'}{$k}} ); + if( exists($fw{'RISKSET'}) ) { + foreach my $k (keys %{$fw{'RISKSET'}}) { + $xml .= $this->attr2xml( 'riskset', %{$fw{'RISKSET'}{$k}} ); + } + $xml .= "\n"; } - if( %{$fw{'RISKSET'}} ) { $xml .= "\n"; } - foreach my $k (keys %{$fw{'RATELIMIT'}}) { - $xml .= $this->attr2xml( 'ratelimit', %{$fw{'RATELIMIT'}{$k}} ); + if( exists($fw{'RATELIMIT'}) ) { + foreach my $k (keys %{$fw{'RATELIMIT'}}) { + $xml .= $this->attr2xml( 'ratelimit', %{$fw{'RATELIMIT'}{$k}} ); + } + $xml .= "\n"; } - if( %{$fw{'RATELIMIT'}} ) { $xml .= "\n"; } - my @nats = @{$fw{'NAT'}}; - for my $i (0..$#nats) { - $xml .= $this->attr2xml( 'nat', %{$nats[$i]} ); + if( exists($fw{'NAT'}) ) { + my @nats = @{$fw{'NAT'}}; + for my $i (0..$#nats) { + $xml .= $this->attr2xml( 'nat', %{$nats[$i]} ); + } + $xml .= "\n"; } - if( @{$fw{'NAT'}} ) { $xml .= "\n"; } - my @masq = @{$fw{'MASQUERADE'}}; - for my $i (0..$#masq) { - $xml .= $this->attr2xml( 'masquerade', %{$masq[$i]} ); + if( exists($fw{'MASQUERADE'}) ) { + my @masq = @{$fw{'MASQUERADE'}}; + for my $i (0..$#masq) { + $xml .= $this->attr2xml( 'masquerade', %{$masq[$i]} ); + } + $xml .= "\n"; } - if( @{$fw{'MASQUERADE'}} ) { $xml .= "\n"; } - my @redirectlist = @{$fw{'REDIRECT'}}; - for my $i (0..$#redirectlist) { - $xml .= $this->attr2xml( 'redirect', %{$redirectlist[$i]} ); + if( exists($fw{'REDIRECT'}) ) { + my @redirectlist = @{$fw{'REDIRECT'}}; + for my $i (0..$#redirectlist) { + $xml .= $this->attr2xml( 'redirect', %{$redirectlist[$i]} ); + } + $xml .= "\n"; } - if( @{$fw{'REDIRECT'}} ) { $xml .= "\n"; } - my @conntrackpreroutes = @{$fw{'CONNTRACKPREROUTE'}}; - for my $i (0..$#conntrackpreroutes) { - $xml .= $this->attr2xml( 'conntrackpreroute', %{$conntrackpreroutes[$i]} ); + if( exists($fw{'CONNTRACKPREROUTE'}) ) { + my @conntrackpreroutes = @{$fw{'CONNTRACKPREROUTE'}}; + for my $i (0..$#conntrackpreroutes) { + $xml .= $this->attr2xml( 'conntrackpreroute', %{$conntrackpreroutes[$i]} ); + } + $xml .= "\n"; } - if( @{$fw{'CONNTRACKPREROUTE'}} ) { $xml .= "\n"; } - my @conntracks = @{$fw{'CONNTRACK'}}; - for my $i (0..$#conntracks) { - $xml .= $this->attr2xml( 'conntrack', %{$conntracks[$i]} ); + if( exists($fw{'CONNTRACK'}) ) { + my @conntracks = @{$fw{'CONNTRACK'}}; + for my $i (0..$#conntracks) { + $xml .= $this->attr2xml( 'conntrack', %{$conntracks[$i]} ); + } + $xml .= "\n"; } - if( @{$fw{'CONNTRACK'}} ) { $xml .= "\n"; } - my @connmarkpreroutes = @{$fw{'CONNMARKPREROUTE'}}; - for my $i (0..$#connmarkpreroutes) { - $xml .= $this->attr2xml( 'connmarkpreroute', %{$connmarkpreroutes[$i]} ); + if( exists($fw{'CONNMARKPREROUTE'}) ) { + my @connmarkpreroutes = @{$fw{'CONNMARKPREROUTE'}}; + for my $i (0..$#connmarkpreroutes) { + $xml .= $this->attr2xml( 'connmarkpreroute', %{$connmarkpreroutes[$i]} ); + } + $xml .= "\n"; } - if( @{$fw{'CONNMARKPREROUTE'}} ) { $xml .= "\n"; } - my @connmarks = @{$fw{'CONNMARK'}}; - for my $i (0..$#connmarks) { - $xml .= $this->attr2xml( 'connmark', %{$connmarks[$i]} ); + if( exists($fw{'CONNMARK'}) ) { + my @connmarks = @{$fw{'CONNMARK'}}; + for my $i (0..$#connmarks) { + $xml .= $this->attr2xml( 'connmark', %{$connmarks[$i]} ); + } + $xml .= "\n"; } - if( @{$fw{'CONNMARK'}} ) { $xml .= "\n"; } - my @rules = @{$fw{'RULE'}}; - for my $i (0..$#rules) { - $xml .= $this->attr2xml( 'rule', %{$rules[$i]} ); + if( exists($fw{'RULE'}) ) { + my @rules = @{$fw{'RULE'}}; + for my $i (0..$#rules) { + $xml .= $this->attr2xml( 'rule', %{$rules[$i]} ); + } + $xml .= "\n"; } - $xml .= "\n"; $xml .= "\n"; @@ -1692,14 +1750,14 @@ sub attr2xml { return $appo; } -# Translate """ to "'", "<" to "<" and ">" to ">" and "&" to "&" +# Translate """ to "'", "&" to "&", "<" to "<" and ">" to ">" sub _clean { my $this = shift; my $s = shift; $s =~ s/\"/\'/g; + $s =~ s/\&/&/g; $s =~ s/\/>/g; - $s =~ s/\&/&/g; return $s; } @@ -1714,13 +1772,11 @@ sub checkName { sub GetStatus { my $iptables = qx{iptables -L -n}; return $iptables =~ /Chain BACK/g; - #my $nftables = qx{nft list table ip filter 2>&1}; - #return $nftables =~ /chain BACK/g } sub startFirewall { my $this = shift; - + # PreLoad modules print "nftables_module: on\n"; $this->command('modprobe nf_tables', '/dev/null'); @@ -1775,16 +1831,16 @@ sub startFirewall { # PreLoad module for nDPI print "ndpi_module: on\n"; - $this->command('modprobe xt_ndpi ndpi_enable_flow=1 ndpi_flow_opt=cCFVR', '/dev/null'); - + $this->command('modprobe xt_ndpi ndpi_enable_flow=1 ndpi_flow_opt=cFR', '/dev/null'); + # Enable IP forwarding $this->command('echo "1"', '/proc/sys/net/ipv4/ip_forward'); - - if( $this->{fw}{OPTION}{rp_filter} eq 'unchange' ) { + + if( !defined($this->{fw}{OPTION}{rp_filter}) || $this->{fw}{OPTION}{rp_filter} eq 'unchange' ) { print "rp_filter: unchange\n"; } else { my $flag; - if( $this->{fw}{OPTION}{rp_filter} eq 'off' ) { + if( defined($this->{fw}{OPTION}{rp_filter}) && $this->{fw}{OPTION}{rp_filter} eq 'off' ) { print "rp_filter: off\n"; $flag = 0; } else { @@ -1794,11 +1850,11 @@ sub startFirewall { $this->command( "for f in /proc/sys/net/ipv4/conf/*/rp_filter; do echo $flag > \$f; done" ); } - if( $this->{fw}{OPTION}{log_martians} eq 'unchange' ) { + if( !defined($this->{fw}{OPTION}{log_martians}) || $this->{fw}{OPTION}{log_martians} eq 'unchange' ) { print "log_martians: unchange\n"; } else { my $flag; - if( $this->{fw}{OPTION}{log_martians} eq 'off' ) { + if( defined($this->{fw}{OPTION}{log_martians}) && $this->{fw}{OPTION}{log_martians} eq 'off' ) { print "log_martians: off\n"; $flag = 0; } else { @@ -1807,12 +1863,12 @@ sub startFirewall { } $this->command( "for f in /proc/sys/net/ipv4/conf/*/log_martians; do echo $flag > \$f; done" ); } - + # I want all icmp_echo_ignore_all set to off. Turtle Firewall uses iptables # rules for drop or allow icmp echo packets. Andrea Frigido 2004-07-17 $this->command( 'echo "1"', '/proc/sys/net/ipv4/icmp_echo_ignore_broadcasts' ); $this->command( 'echo "0"', '/proc/sys/net/ipv4/icmp_echo_ignore_all' ); - + # Disable tcp_ecn flag. $this->command( 'echo 0', '/proc/sys/net/ipv4/tcp_ecn' ); @@ -1828,9 +1884,9 @@ sub startFirewall { # Enable bad error message protection. $this->command( 'echo 1', '/proc/sys/net/ipv4/icmp_ignore_bogus_error_responses' ); - + # Other options - if( $this->{fw}{OPTION}{nf_conntrack_max} > 0 ) { + if( defined($this->{fw}{OPTION}{nf_conntrack_max}) && $this->{fw}{OPTION}{nf_conntrack_max} > 0 ) { open( FILE, ">/proc/sys/net/netfilter/nf_conntrack_max" ); print FILE $this->{fw}{OPTION}{nf_conntrack_max}; close FILE; @@ -1838,22 +1894,17 @@ sub startFirewall { } # Ensure ipset item present for IP Blacklist - if( $this->{fw}{OPTION}{drop_ip_blacklist} ne 'off' ) { + if( !defined($this->{fw}{OPTION}{drop_ip_blacklist}) || $this->{fw}{OPTION}{drop_ip_blacklist} ne 'off' ) { $this->command('/usr/lib/turtlefirewall/ip_blacklist -I', '/dev/null'); } # Ensure dpi item present for Domain Blacklist - if( $this->{fw}{OPTION}{drop_domain_blacklist} ne 'off' ) { + if( !defined($this->{fw}{OPTION}{drop_domain_blacklist}) || $this->{fw}{OPTION}{drop_domain_blacklist} ne 'off' ) { $this->command('/usr/lib/turtlefirewall/domain_blacklist -I', '/dev/null'); } - # Ensure dpi item present for JA3 Blacklist - if( $this->{fw}{OPTION}{drop_ja3_blacklist} ne 'off' ) { - $this->command('/usr/lib/turtlefirewall/ja3_blacklist -I', '/dev/null'); - } - # Ensure dpi item present for SHA1 Blacklist - if( $this->{fw}{OPTION}{drop_sha1_blacklist} ne 'off' ) { + if( !defined($this->{fw}{OPTION}{drop_sha1_blacklist}) || $this->{fw}{OPTION}{drop_sha1_blacklist} ne 'off' ) { $this->command('/usr/lib/turtlefirewall/sha1_blacklist -I', '/dev/null'); } @@ -1864,7 +1915,7 @@ sub startFirewall { my @item_list = (); push(@item_list, split( /,/, $this->{fw}{RULE}[$i]{SRC} ) ); push(@item_list, split( /,/, $this->{fw}{RULE}[$i]{DST} ) ); - if( grep( /^$s$/, @item_list ) && $this->{fw}{RULE}[$i]{ACTIVE} ne 'NO') { + if( grep( /^$s$/, @item_list ) && !$this->{fw}{RULE}[$i]{ACTIVE} ) { my $addresslist_file = $this->{fw}{ADDRESSLIST}{$ipset{'IP'}}{FILE}; my $addresslist_type = $this->{fw}{ADDRESSLIST}{$ipset{'IP'}}{TYPE}; if( ! -e $addresslist_file ) { @@ -1878,35 +1929,30 @@ sub startFirewall { } } + # Restore IPtables Rules my $rules = $this->getIptablesRules(); - - my $use_iptables_restore = 1; - - if( $use_iptables_restore ) { - umask 0077; - open FILE, ">/etc/turtlefirewall/iptables.dat"; - print FILE $rules; - close FILE; - if( -x '/usr/sbin/iptables-nft-restore' ) { - print "run iptables-nft-restore\n"; - $this->command('cat /etc/turtlefirewall/iptables.dat | /usr/sbin/iptables-nft-restore'); - } elsif( -x '/usr/sbin/iptables-restore' ) { - print "run iptables-restore\n"; - $this->command('cat /etc/turtlefirewall/iptables.dat | /usr/sbin/iptables-restore'); - } else { - print STDERR "Error: iptables-restore needed\n"; - } - # doesn't unlink, for debugging - #unlink "/etc/turtlefirewall/iptables.dat"; - } else { - $this->iptables_restore_emu( $rules ); + + umask 0077; + open FILE, ">/etc/turtlefirewall/iptables.dat"; + print FILE $rules; + close FILE; + if( -x '/usr/sbin/iptables-nft-restore' ) { + print "run iptables-nft-restore\n"; + $this->command('cat /etc/turtlefirewall/iptables.dat | /usr/sbin/iptables-nft-restore'); + } elsif( -x '/usr/sbin/iptables-restore' ) { + print "run iptables-restore\n"; + $this->command('cat /etc/turtlefirewall/iptables.dat | /usr/sbin/iptables-restore'); + } else { + print STDERR "Error: iptables-restore needed\n"; } + # Don't unlink, for debugging + unlink "/etc/turtlefirewall/iptables.dat"; # Apply Rate Limits for my $r ($this->GetRateLimitList()) { my %ratelimit = $this->GetRateLimit($r); for( my $i=0; $i<=$#{$this->{fw}{RULE}}; $i++ ) { - if( $this->{fw}{RULE}[$i]{RATELIMIT} eq $r && $this->{fw}{RULE}[$i]{ACTIVE} ne 'NO') { + if( defined($this->{fw}{RULE}[$i]{RATELIMIT}) && $this->{fw}{RULE}[$i]{RATELIMIT} eq $r && !$this->{fw}{RULE}[$i]{ACTIVE} ) { # Convert to bps my $rate = $ratelimit{'RATE'} * 1024000; print "run ratelimit-restore $r($ratelimit{'RATE'} Mbps)\n"; @@ -1924,22 +1970,22 @@ sub startFirewall { my @item_list = (); push(@item_list, split( /,/, $this->{fw}{RULE}[$i]{SRC} ) ); push(@item_list, split( /,/, $this->{fw}{RULE}[$i]{DST} ) ); - if( grep( /^$s$/, @item_list ) && $this->{fw}{RULE}[$i]{ACTIVE} ne 'NO') { + if( grep( /^$s$/, @item_list ) && !$this->{fw}{RULE}[$i]{ACTIVE} ) { print "run ipset-restore $s($ipset{'IP'})\n"; my $addresslist_file = $this->{fw}{ADDRESSLIST}{$ipset{'IP'}}{FILE}; my $addresslist_type = $this->{fw}{ADDRESSLIST}{$ipset{'IP'}}{TYPE}; $this->command( "ipset flush $ipset{'IP'}", "/dev/null 2>&1" ); my @items = (); open( FILE, "<", "$addresslist_file" ); - while( ) { + while(my $l = ) { if( $addresslist_type eq "hash:ip" ) { - if( $_ =~ /(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/ ) { push(@items, $1); } + if( $l =~ /(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/ ) { push(@items, $1); } } if( $addresslist_type eq "hash:net" ) { - if( $_ =~ /(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\/\b([0-9]|[12][0-9]|3[0-2])\b)/ ) { push(@items, $1); } + if( $l =~ /(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\/\b([0-9]|[12][0-9]|3[0-2])\b)/ ) { push(@items, $1); } } if( $addresslist_type eq "hash:mac" ) { - if( $_ =~ /([0-9a-fA-F]{2}\:[0-9a-fA-F]{2}\:[0-9a-fA-F]{2}\:[0-9a-fA-F]{2}\:[0-9a-fA-F]{2}\:[0-9a-fA-F]{2})/ ) { push(@items, $1); } + if( $l =~ /([0-9a-fA-F]{2}\:[0-9a-fA-F]{2}\:[0-9a-fA-F]{2}\:[0-9a-fA-F]{2}\:[0-9a-fA-F]{2}\:[0-9a-fA-F]{2})/ ) { push(@items, $1); } } } close( FILE ); @@ -1966,26 +2012,27 @@ sub stopFirewall { "iptables -P INPUT ACCEPT; ". "iptables -P OUTPUT ACCEPT; ". "iptables -P FORWARD ACCEPT" ); - #$this->command( 'nft flush ruleset' ); - - # enable ping + + # Enable ping $this->command( 'echo "0"', '/proc/sys/net/ipv4/icmp_echo_ignore_all' ); - # flush conntrack table + # Flush conntrack table $this->command( 'conntrack -F', '/dev/null 2>&1' ); } sub getIptablesRules { my $this = shift; - + my $chains = ''; my $rules = ''; my $chains_nat = ''; my $rules_nat = ''; - + my $chains_mangle = ''; my $rules_mangle = ''; + my $rules_mangle_option = ''; + my $chains_mangle_connmarkpreroute = ''; my $rules_mangle_connmarkpreroute = ''; @@ -2002,18 +2049,19 @@ sub getIptablesRules { my $rules_raw_conntrack = ''; my $log_limit=60; - my $log_limit_burst=5; - if( $this->{fw}{OPTION}{log_limit} > 0 ) { + if( defined($this->{fw}{OPTION}{log_limit}) && $this->{fw}{OPTION}{log_limit} > 0 ) { $log_limit = $this->{fw}{OPTION}{log_limit}; - print "log_limit: $log_limit\n"; } - if( $this->{fw}{OPTION}{log_limit_burst} > 0 ) { + $this->{log_limit} = $log_limit; + print "log_limit: $log_limit\n"; + + my $log_limit_burst=5; + if( defined($this->{fw}{OPTION}{log_limit_burst}) && $this->{fw}{OPTION}{log_limit_burst} > 0 ) { $log_limit_burst = $this->{fw}{OPTION}{log_limit_burst}; - print "log_limit_burst: $log_limit_burst\n"; } - $this->{log_limit} = $log_limit; $this->{log_limit_burst} = $log_limit_burst; - + print "log_limit_burst: $log_limit_burst\n"; + # Chains for filter table $chains .= "*filter\n". ":FORWARD DROP [0:0]\n". @@ -2039,10 +2087,6 @@ sub getIptablesRules { ":PREROUTING ACCEPT [0:0]\n". ":OUTPUT ACCEPT [0:0]\n"; - # Copy packet mark to connection mark and vice versa - $rules_mangle .= "-A PREROUTING -j CONNMARK --restore-mark\n"; - $rules_mangle .= "-A POSTROUTING -j CONNMARK --save-mark\n"; - # Enable access from/to the loopback interface. $rules .= "-A INPUT -i lo -j ACCEPT\n"; $rules .= "-A OUTPUT -o lo -j ACCEPT\n"; @@ -2051,9 +2095,9 @@ sub getIptablesRules { # START of INVALID Packets filter by Mark Francis $chains .= ":INVALID - [0:0]\n"; $chains .= ":CHECK_INVALID - [0:0]\n"; - + print "drop_invalid_state: "; - if( $this->{fw}{OPTION}{drop_invalid_state} ne 'off' ) { + if( !defined($this->{fw}{OPTION}{drop_invalid_state}) || $this->{fw}{OPTION}{drop_invalid_state} ne 'off' ) { $rules .= "-A CHECK_INVALID -m conntrack --ctstate INVALID -j INVALID\n"; $rules .= "-A INVALID -m conntrack --ctstate INVALID ". " -m limit --limit $log_limit/hour --limit-burst $log_limit_burst -j LOG --log-prefix \"TFW=INVALID-STATE(DRO) \"\n"; @@ -2061,9 +2105,9 @@ sub getIptablesRules { } else { print "off\n"; } - + print "drop_invalid_all: "; - if( $this->{fw}{OPTION}{drop_invalid_all} ne 'off' ) { + if( !defined($this->{fw}{OPTION}{drop_invalid_all}) || $this->{fw}{OPTION}{drop_invalid_all} ne 'off' ) { $rules .= "-A CHECK_INVALID -p tcp --tcp-flags ALL ALL -j INVALID\n"; $rules .= "-A INVALID -p tcp --tcp-flags ALL ALL ". " -m limit --limit $log_limit/hour --limit-burst $log_limit_burst -j LOG --log-prefix \"TFW=INVALID-ALL(DRO) \"\n"; @@ -2071,9 +2115,9 @@ sub getIptablesRules { } else { print "off\n"; } - + print "drop_invalid_none: "; - if( $this->{fw}{OPTION}{drop_invalid_none} ne 'off' ) { + if( !defined( $this->{fw}{OPTION}{drop_invalid_none}) || $this->{fw}{OPTION}{drop_invalid_none} ne 'off' ) { $rules .= "-A CHECK_INVALID -p tcp --tcp-flags ALL NONE -j INVALID\n"; $rules .= "-A INVALID -p tcp --tcp-flags ALL NONE ". " -m limit --limit $log_limit/hour --limit-burst $log_limit_burst -j LOG --log-prefix \"TFW=INVALID-NONE(DRO) \"\n"; @@ -2081,9 +2125,9 @@ sub getIptablesRules { } else { print "off\n"; } - + print "drop_invalid_fin_notack: "; - if( $this->{fw}{OPTION}{drop_invalid_fin_notack} ne 'off' ) { + if( !defined($this->{fw}{OPTION}{drop_invalid_fin_notack}) || $this->{fw}{OPTION}{drop_invalid_fin_notack} ne 'off' ) { $rules .= "-A CHECK_INVALID -p tcp --tcp-flags FIN,ACK FIN -j INVALID\n"; $rules .= "-A INVALID -p tcp --tcp-flags FIN,ACK FIN ". " -m limit --limit $log_limit/hour --limit-burst $log_limit_burst -j LOG --log-prefix \"TFW=INVALID-FIN,!ACK(DRO) \"\n"; @@ -2091,9 +2135,9 @@ sub getIptablesRules { } else { print "off\n"; } - + print "drop_invalid_sys_fin: "; - if( $this->{fw}{OPTION}{drop_invalid_syn_fin} ne 'off' ) { + if( !defined($this->{fw}{OPTION}{drop_invalid_syn_fin}) || $this->{fw}{OPTION}{drop_invalid_syn_fin} ne 'off' ) { $rules .= "-A CHECK_INVALID -p tcp --tcp-flags SYN,FIN SYN,FIN -j INVALID\n"; $rules .= "-A INVALID -p tcp --tcp-flags SYN,FIN SYN,FIN ". " -m limit --limit $log_limit/hour --limit-burst $log_limit_burst -j LOG --log-prefix \"TFW=INVALID-SYN,FIN(DRO) \"\n"; @@ -2103,7 +2147,7 @@ sub getIptablesRules { } print "drop_invalid_syn_rst: "; - if( $this->{fw}{OPTION}{drop_invalid_syn_rst} ne 'off' ) { + if( !defined($this->{fw}{OPTION}{drop_invalid_syn_rst}) || $this->{fw}{OPTION}{drop_invalid_syn_rst} ne 'off' ) { $rules .= "-A CHECK_INVALID -p tcp --tcp-flags SYN,RST SYN,RST -j INVALID\n"; $rules .= "-A INVALID -p tcp --tcp-flags SYN,RST SYN,RST ". " -m limit --limit $log_limit/hour --limit-burst $log_limit_burst -j LOG --log-prefix \"TFW=INVALID-SYN,RST(DRO) \"\n"; @@ -2111,9 +2155,9 @@ sub getIptablesRules { } else { print "off\n"; } - + print "drop_invalid_fragment: "; - if( $this->{fw}{OPTION}{drop_invalid_fragment} ne 'off' ) { + if( !defined($this->{fw}{OPTION}{drop_invalid_fragment}) || $this->{fw}{OPTION}{drop_invalid_fragment} ne 'off' ) { $rules .= "-A CHECK_INVALID -f -j INVALID\n"; $rules .= "-A INVALID -f ". " -m limit --limit $log_limit/hour --limit-burst $log_limit_burst -j LOG --log-prefix \"TFW=INVALID-FRAGMENT(DRO) \"\n"; @@ -2132,9 +2176,9 @@ sub getIptablesRules { $rules .= "-A FORWARD -j CHECK_INVALID\n"; # END of INVALID Packets filter by Mark Francis ############################################### - + print "drop_ip_blacklist: "; - if( $this->{fw}{OPTION}{drop_ip_blacklist} ne 'off' ) { + if( !defined($this->{fw}{OPTION}{drop_ip_blacklist}) || $this->{fw}{OPTION}{drop_ip_blacklist} ne 'off' ) { $chains .= ":IP_BLACKLIST - [0:0]\n"; $rules .= "-A IP_BLACKLIST -m limit --limit $log_limit/hour --limit-burst $log_limit_burst -j LOG --log-prefix \"TFW=IP-BLACKLIST(DRO) \"\n"; $rules .= "-A IP_BLACKLIST -j DROP\n"; @@ -2148,7 +2192,7 @@ sub getIptablesRules { } print "drop_domain_blacklist: "; - if( $this->{fw}{OPTION}{drop_domain_blacklist} ne 'off' ) { + if( !defined($this->{fw}{OPTION}{drop_domain_blacklist}) || $this->{fw}{OPTION}{drop_domain_blacklist} ne 'off' ) { $chains .= ":DOMAIN_BLACKLIST - [0:0]\n"; $rules .= "-A DOMAIN_BLACKLIST -m limit --limit $log_limit/hour --limit-burst $log_limit_burst -j LOG --log-prefix \"TFW=DOMAIN-BLACKLIST(DRO) \"\n"; $rules .= "-A DOMAIN_BLACKLIST -j DROP\n"; @@ -2165,22 +2209,8 @@ sub getIptablesRules { print "off\n"; } - print "drop_ja3_blacklist: "; - if( $this->{fw}{OPTION}{drop_ja3_blacklist} ne 'off' ) { - $chains .= ":JA3_BLACKLIST - [0:0]\n"; - $rules .= "-A JA3_BLACKLIST -m limit --limit $log_limit/hour --limit-burst $log_limit_burst -j LOG --log-prefix \"TFW=JA3-BLACKLIST(DRO) \"\n"; - $rules .= "-A JA3_BLACKLIST -j DROP\n"; - - $rules .= "-A INPUT -m ndpi --all --risk 28 -j JA3_BLACKLIST\n"; - $rules .= "-A OUTPUT -m ndpi --all --risk 28 -j JA3_BLACKLIST\n"; - $rules .= "-A FORWARD -m ndpi --all --risk 28 -j JA3_BLACKLIST\n"; - print "on\n"; - } else { - print "off\n"; - } - print "drop_sha1_blacklist: "; - if( $this->{fw}{OPTION}{drop_sha1_blacklist} ne 'off' ) { + if( !defined($this->{fw}{OPTION}{drop_sha1_blacklist}) || $this->{fw}{OPTION}{drop_sha1_blacklist} ne 'off' ) { $chains .= ":SHA1_BLACKLIST - [0:0]\n"; $rules .= "-A SHA1_BLACKLIST -m limit --limit $log_limit/hour --limit-burst $log_limit_burst -j LOG --log-prefix \"TFW=SHA1-BLACKLIST(DRO) \"\n"; $rules .= "-A SHA1_BLACKLIST -j DROP\n"; @@ -2192,7 +2222,16 @@ sub getIptablesRules { } else { print "off\n"; } - + + print "clamp_mss_to_pmtu: "; + if( !defined($this->{fw}{OPTION}{clamp_mss_to_pmtu}) || $this->{fw}{OPTION}{clamp_mss_to_pmtu} ne 'off' ) { + $rules_mangle_option .= "-A POSTROUTING -p tcp --tcp-flags SYN,RST SYN -o ppp+ -j TCPMSS --clamp-mss-to-pmtu\n"; + $rules_mangle .= $rules_mangle_option; + print "on\n"; + } else { + print "off\n"; + } + # Definition for the return chain # Return packet chain (NO new connections) $chains .= ":BACK - [0:0]\n"; @@ -2207,7 +2246,7 @@ sub getIptablesRules { $rules .= "-A ICMP-ACC -p icmp --icmp-type time-exceeded -j ACCEPT\n"; $rules .= "-A ICMP-ACC -p icmp --icmp-type parameter-problem -j ACCEPT\n"; $rules .= "-A ICMP-ACC -j RETURN\n"; - + # Application of CONNMARKPREROUTEs my $connmarkpreroutesCount = $this->GetConnmarkPreroutesCount(); if( $connmarkpreroutesCount > 0 ) { @@ -2231,10 +2270,10 @@ sub getIptablesRules { my $connmarksCount = $this->GetConnmarksCount(); if( $connmarksCount > 0 ) { my @zone = $this->GetZoneList(); - for(my $i=0; $i<=$#zone; $i++ ) { + for( my $i=0; $i<=$#zone; $i++ ) { my $z1 = $zone[$i]; my %zone1 = $this->GetZone($z1); - for($j=0; $j<=$#zone; $j++ ) { + for( my $j=0; $j<=$#zone; $j++ ) { my $z2 = $zone[$j]; my %zone2 = $this->GetZone($z2); if( $z1 eq 'FIREWALL' || $z2 eq 'FIREWALL' ) { @@ -2261,6 +2300,12 @@ sub getIptablesRules { $rules_mangle .= $rules_mangle_connmark; } + # Copy packet mark to connection mark and vice versa + if( $rules_mangle_connmarkpreroute || $rules_mangle_connmark ) { + $rules_mangle .= "-I PREROUTING -j CONNMARK --restore-mark\n"; + $rules_mangle .= "-A POSTROUTING -j CONNMARK --save-mark\n"; + } + # Application of CONNTRACKPREROUTEs my $conntrackpreroutesCount = $this->GetConntrackPreroutesCount(); if( $conntrackpreroutesCount > 0 ) { @@ -2300,7 +2345,6 @@ sub getIptablesRules { } # Application of NATs - my $rules_nat = ''; for( my $i=1; $i <= $this->GetNatsCount(); $i++ ) { $rules_nat .= $this->applyNat( $this->GetNat($i) ); } @@ -2317,7 +2361,7 @@ sub getIptablesRules { # Close the MASQ chain with a RETURN to the POSTROUTING parent chain $rules_nat .= "-A MASQ -j RETURN\n"; } - + # REDIRECT my $redirectCount = $this->GetRedirectCount(); if( $redirectCount > 0 ) { @@ -2333,10 +2377,10 @@ sub getIptablesRules { # Create the chains for the ZONES my @zone = $this->GetZoneList(); - for(my $i=0; $i<=$#zone; $i++ ) { + for( my $i=0; $i<=$#zone; $i++ ) { my $z1 = $zone[$i]; my %zone1 = $this->GetZone($z1); - for($j=0; $j<=$#zone; $j++ ) { + for( my $j=0; $j<=$#zone; $j++ ) { my $z2 = $zone[$j]; my %zone2 = $this->GetZone($z2); if( $z1 eq 'FIREWALL' || $z2 eq 'FIREWALL' ) { @@ -2362,12 +2406,12 @@ sub getIptablesRules { for( my $i=1; $i <= $rulesCount; $i++ ) { $rules .= $this->applyRule( 1, 0, 0, 0, $this->GetRule($i) ); } - + # Close the zone chains - for(my $i=0; $i<=$#zone; $i++ ) { - $z1 = $zone[$i]; - for($j=0; $j<=$#zone; $j++ ) { - $z2 = $zone[$j]; + for( my $i=0; $i<=$#zone; $i++ ) { + my $z1 = $zone[$i]; + for( my $j=0; $j<=$#zone; $j++ ) { + my $z2 = $zone[$j]; if( $z1 ne 'FIREWALL' || $z2 ne 'FIREWALL' ) { my $logprefix = "TFW=$z1-$z2"; # iptables --log-prefix max = 29 @@ -2384,9 +2428,9 @@ sub getIptablesRules { $rules .= "-A $chain -m limit --limit $log_limit/hour --limit-burst $log_limit_burst -j LOG --log-prefix \"$logprefix \"\n"; } print "DROP any other connections and LOG Action\n"; - + return ($rules_raw_conntrackpreroute || $rules_raw_conntrack ? $chains_raw.$rules_raw."COMMIT\n" : "*raw\nCOMMIT\n"). - ($rules_mangle_connmarkpreroute || $rules_mangle_connmark ? $chains_mangle.$rules_mangle."COMMIT\n" : "*mangle\nCOMMIT\n"). + ($rules_mangle_connmarkpreroute || $rules_mangle_connmark || $rules_mangle_option ? $chains_mangle.$rules_mangle."COMMIT\n" : "*mangle\nCOMMIT\n"). $chains.$rules."COMMIT\n".$chains_nat.$rules_nat."COMMIT\n"; } @@ -2399,25 +2443,25 @@ sub applyNat { my %services = %{$this->{services}}; my $rules = ''; - - if( $nat{ACTIVE} eq 'NO' ) { + + if( $nat{ACTIVE} ) { return ''; } - my $virtual = $nat{VIRTUAL}; - my $real = $nat{REAL}; - my $nmService = $nat{SERVICE}; - my $port = $nat{PORT}; # Optional port identifier - my $toport = $nat{TOPORT}; # Optional port identifier - my $virtual_ip=''; - my $virtual_if=''; - my $real_ip=''; + my $virtual = defined($nat{VIRTUAL}) ? $nat{VIRTUAL} : ''; + my $real = defined($nat{REAL}) ? $nat{REAL} : ''; + my $service = defined($nat{SERVICE}) ? $nat{SERVICE} : ''; + my $port = defined($nat{PORT}) ? $nat{PORT} : ''; # Optional port identifier + my $toport = defined($nat{TOPORT}) ? $nat{TOPORT} : ''; # Optional to port identifier + my $virtual_ip = ''; + my $virtual_if = ''; + my $real_ip = ''; # Service is a list of services? - if( $nmService =~ /,/ ) { - my @services = split( /,/, $nmService ); + if( $service =~ /,/ ) { + my @servicelist = split( /,/, $service ); my %newnat = %nat; - foreach my $serv (@services) { + foreach my $serv (@servicelist) { $newnat{SERVICE} = $serv; $rules .= $this->applyNat( %newnat ); } @@ -2425,16 +2469,15 @@ sub applyNat { } if( $virtual eq '' ) { - print STDERR "Error: VIRTUAL attribute missing in NAT rule definition.\n"; + print "Error: VIRTUAL attribute missing in NAT rule definition.\n"; return $rules; } if( $real eq '' ) { - print STDERR "Error: REAL attribute missing in NAT rule definition.\n"; + print "Error: REAL attribute missing in NAT rule definition.\n"; return $rules; } - if( $fwItems{$virtual} ne 'HOST' && $fwItems{$virtual} ne 'ZONE' ) { - print STDERR "Error: in a NAT rule definition, VIRTUAL attribute [$virtual] is not a valid host or zone name.\n"; + print "Error: in a NAT rule definition, VIRTUAL attribute [$virtual] is not a valid host or zone name.\n"; return $rules; } if( $fwItems{$virtual} eq 'HOST' ) { @@ -2443,14 +2486,18 @@ sub applyNat { if( $fwItems{$virtual} eq 'ZONE' ) { $virtual_if = $fw{ZONE}{$virtual}{IF}; } - if( $fwItems{$real} ne 'HOST' ) { - print STDERR "Error: in a NAT rule definition, REAL attribute is not a valid host name.\n"; + print "Error: in a NAT rule definition, REAL attribute is not a valid host name.\n"; + return $rules; + } + if( $fw{HOST}{$real}{IP} ne '' ) { + $real_ip = $fw{HOST}{$real}{IP}; + } else { + print "Error: in a NAT rule definition, IP attribute missing for $fw{HOST}{$real}{NAME}.\n"; return $rules; } - $real_ip = $fw{HOST}{$real}{IP}; - if( $nmService eq '' || $nmService eq 'all' ) { + if( $service eq '' || $service eq 'all' ) { # Interface-wide nat. This was the only way natting was used to be. if( $virtual_ip ne '' ) { # Virtual HOST to Real HOST nat @@ -2474,24 +2521,30 @@ sub applyNat { # Service-wide nat. This was introduced with v0.98. # On the 'go' way of the specified service we do a DNAT from $virtual_ip:$dport # to $real_ip:$dport, while on the 'back' way we do a SNAT from $real_ip:$sport - # to $virtual_ip:$sport. $state conditions and $jump tags are added to the iptable + # to $virtual_ip:$sport. $state conditions and $jump tags are added to the iptables # entries as well. - - print "NAT virtual($virtual),port($nmService". + + print "NAT virtual($virtual),port($service". ($port ne '' ? "/$port" : ''). ") --> real($real)". - ($toport ne '' ? ",port($nmService/$toport)" : ''). + ($toport ne '' ? ",port($service/$toport)" : ''). " \n"; - #$rules .= "#NAT virtual( $virtual ) -to-> real( $real ) on service( $nmService($port) )\n"; + #$rules .= "#NAT virtual( $virtual ) -to-> real( $real ) on service( $service($port) )\n"; - # Outputs a nat roule for each defined service channel - foreach my $filter (@{$services{$nmService}{FILTERS}}) { - my $direction = $filter->{DIRECTION}; - my $proto = $filter->{P}; - my $icmptype = $filter->{ICMPTYPE}; - my $sport = $filter->{SPORT}; - my $dport = $filter->{DPORT}; - my $state = $filter->{STATE}; + if( !grep /^$service$/, keys %services ) { + print "Error: NAT service $service invalid.\n"; + return $rules; + } + + # Outputs a nat rule for each defined service channel + foreach my $filter (@{$services{$service}{FILTERS}}) { + + my $direction = defined($filter->{DIRECTION}) ? $filter->{DIRECTION} : ''; + my $proto = defined($filter->{P}) ? $filter->{P} : ''; + my $icmptype = defined($filter->{ICMPTYPE}) ? $filter->{ICMPTYPE} : ''; + my $sport = defined($filter->{SPORT}) ? $filter->{SPORT} : ''; + my $dport = defined($filter->{DPORT}) ? $filter->{DPORT} : ''; + my $state = defined($filter->{STATE}) ? $filter->{STATE} : ''; # Fetches if( $sport eq 'PORT' ) { $sport = $port; } @@ -2517,8 +2570,8 @@ sub applyNat { if( $dport ne '' ) { $cmd .= "--dport $dport "; } if( $sport ne '' ) { $cmd .= "--sport $sport "; } } elsif( $proto ne 'icmp' ) { - # Well, I'm coding this... But what purpouse is supposed - # to have an icmp nat? Mmmmm... + # Well, I'm coding this... But what is the purpose + # of an icmp nat? Mmmmm... $cmd .= "-p $proto "; if( $icmptype ne '' ) { @@ -2553,7 +2606,7 @@ sub applyNat { # Finally, executes the command $rules .= "$cmd\n"; - # If is possible, now I apply the same rule to firewall itself + # If it is possible, now I apply the same rule to firewall itself if( $cmd =~ /PREROUTING/ && $cmd !~ / -i / ) { $cmd =~ s/PREROUTING/OUTPUT/; $rules .= "$cmd\n"; @@ -2566,23 +2619,23 @@ sub applyNat { sub applyMasquerade { my $this = shift; my %masq = @_; - + my %fw = %{$this->{fw}}; my %fwItems = %{$this->{fwItems}}; my %services = %{$this->{services}}; my $rules = ''; - if( $masq{ACTIVE} eq 'NO' ) { + if( $masq{ACTIVE} ) { return ''; } - + # Masquerade or don't masquerade? - my $is_masquerade = $masq{MASQUERADE} ne 'NO'; + my $is_masquerade = !$masq{MASQUERADE}; + + my $src = defined($masq{SRC}) ? $masq{SRC} : ''; + my $dst = defined($masq{DST}) ? $masq{DST} : ''; - my $src = $masq{SRC}; - my $dst = $masq{DST}; - ### # Backward compatibility with TurtleFirewall < 1.29 if( !$dst && $masq{ZONE} ) { @@ -2590,25 +2643,28 @@ sub applyMasquerade { } if( $dst eq '' ) { - print STDERR "Error: DST or ZONE attribute missing in MASQUERADE rule.\n"; + print "Error: DST or ZONE attribute missing in MASQUERADE rule.\n"; return $rules; } #if( $fwItems{$zone} ne 'ZONE' ) { - # print STDERR "Error: invalid ZONE attribute missing in MASQUERADE rule.\n"; + # print "Error: ZONE attribute missing in MASQUERADE rule.\n"; # return #} - # See if I have a group as source - if( $fwItems{$src} eq 'GROUP' ) { - my %newmasq = %masq; - foreach my $item ( @{$fw{GROUP}{$src}{ITEMS}} ) { - if( $item ne 'FIREWALL' ) { - $newmasq{SRC} = $item; - $rules .= $this->applyMasquerade( %newmasq ); + # Don't check group membership for * zone + if( $src ne '*' ) { + # See if I have a group as source + if( $fwItems{$src} eq 'GROUP' ) { + my %newmasq = %masq; + foreach my $item ( @{$fw{GROUP}{$src}{ITEMS}} ) { + if( $item ne 'FIREWALL' ) { + $newmasq{SRC} = $item; + $rules .= $this->applyMasquerade( %newmasq ); + } } + return $rules; } - return $rules; } # See if I have a group as destination @@ -2622,16 +2678,16 @@ sub applyMasquerade { } return $rules; } - + # Define the SERVICE - my $service = $masq{SERVICE}; - my $port = $masq{PORT}; + my $service = defined($masq{SERVICE}) ? $masq{SERVICE} : ''; + my $port = defined($masq{PORT}) ? $masq{PORT} : '';; # Service is a list of services? if( $service =~ /,/ ) { - my @services = split( /,/, $service ); + my @servicelist = split( /,/, $service ); my %newmasq = %masq; - foreach my $serv (@services) { + foreach my $serv (@servicelist) { $newmasq{SERVICE} = $serv; $rules .= $this->applyMasquerade( %newmasq ); } @@ -2643,18 +2699,27 @@ sub applyMasquerade { } my ($src_zone, $src_peer, $src_type, $src_mac) = $this->expand_item( $src ); - my %src_zone_attr = $this->GetZone( $src_zone ); - $src_if = $src_zone_attr{IF}; - my ($dst_zone, $dst_peer, $dst_type, undef) = $this->expand_item( $dst ); + my $src_if = ''; + if( $src ne '*' ) { + my %src_zone_attr = $this->GetZone( $src_zone ); + $src_if = $src_zone_attr{IF}; + } + my ($dst_zone, $dst_peer, $dst_type, $dst_mac) = $this->expand_item( $dst ); my %dst_zone_attr = $this->GetZone( $dst_zone ); - $dst_if = $dst_zone_attr{IF}; - + my $dst_if = $dst_zone_attr{IF}; + + # Invalid Masquerade, Ignore + if( $dst_mac ne '' && $dst_peer eq '' ) { + print "Error: MASQUERADE $dst (mac:$dst_mac) invalid.\n"; + return $rules; + } + print $is_masquerade ? '' : 'NOT ',"MASQUERADE port($service"; if( $service eq 'tcp' || $service eq 'udp' ) { print "/$port"; } print $src ? ") $src" : ' *'; if( $src_mac ne '' ) { print "(mac:$src_mac)"; } print " --> $dst IF $dst_if\n"; - + $rules .= $this->applyServiceMasquerade( \%services, $service, $src_if, $src_peer, $src_type, $src_mac, $dst_if, $dst_peer, $dst_type, $port, $is_masquerade); return $rules; } @@ -2668,36 +2733,38 @@ sub applyServiceMasquerade { sub _applyServiceMasquerade { my $this = shift; my ($ref_calledServices, $ref_services, $serviceName, $src_if, $src_peer, $src_type, $src_mac, $dst_if, $dst_peer, $dst_type, $port, $is_masquerade) = @_; - - my %service = %{$ref_services->{$serviceName}}; - # Service comment - #comment( "# $serviceName: ".$service{DESCRIPTION} ); + my $rules = ''; + + my %service = (); + if( !grep /^$serviceName$/, keys %{$ref_services} ) { + print "Error: MASQUERADE service $serviceName invalid.\n"; + return $rules; + } else { + %service = %{$ref_services->{$serviceName}}; + } $ref_calledServices->{$serviceName} = 1; - my $rules = ''; - # Loop on filering rules - my $i; - for( $i = 0; $i <= $#{$service{FILTERS}}; $i++ ) { + for( my $i=0; $i<=$#{$service{FILTERS}}; $i++ ) { my %filter = %{$service{FILTERS}[$i]}; - if( $filter{SERVICE} ne '' && !$ref_calledServices->{$filter{SERVICE}} ) { + if( defined($filter{SERVICE}) && $filter{SERVICE} ne '' && !$ref_calledServices->{$filter{SERVICE}} ) { # It is a subservice, recursion call to _applyServiceMasquerade $rules .= $this->_applyServiceMasquerade( $ref_calledServices, $ref_services, $filter{SERVICE}, $src_if, $src_peer, $src_type, $src_mac, $dst_if, $dst_peer, $dst_type, $port, $is_masquerade ); next; } - my $direction = $filter{DIRECTION}; - my $p = $filter{P}; - my $icmptype = $filter{ICMPTYPE}; - my $sport = $filter{SPORT}; - my $dport = $filter{DPORT}; - my $state = $filter{STATE}; - my $jump = $filter{JUMP}; + my $direction = defined($filter{DIRECTION}) ? $filter{DIRECTION} : ''; + my $p = defined($filter{P}) ? $filter{P} : ''; + my $icmptype = defined($filter{ICMPTYPE}) ? $filter{ICMPTYPE} : ''; + my $sport = defined($filter{SPORT}) ? $filter{SPORT} : ''; + my $dport = defined($filter{DPORT}) ? $filter{DPORT} : ''; + my $state = defined($filter{STATE}) ? $filter{STATE} : ''; + my $jump = defined($filter{JUMP}) ? $filter{JUMP} : ''; if( $direction ne 'go' ) { # Don't process Back filters, masquerade is apply only for go direction @@ -2734,15 +2801,17 @@ sub _applyServiceMasquerade { if( $sport ne '' ) { $cmd .= "--sport $sport "; } if( $dport ne '' ) { $cmd .= "--dport $dport "; } if( $state ne '' ) { $cmd .= "-m conntrack --ctstate $state "; } - + if( $is_masquerade ) { $cmd .= "-j MASQUERADE"; } else { # Don't masquerade and return to parent chain $cmd .= "-j RETURN"; } - + + # Print commands, for debugging #print "$cmd\n"; + $rules .= "$cmd\n"; } } @@ -2758,16 +2827,16 @@ sub applyRedirect { my %services = %{$this->{services}}; my $rules = ''; - - if( $redirect{ACTIVE} eq 'NO' ) { + + if( $redirect{ACTIVE} ) { return ''; } # Redirect or don't redirect? - my $is_redirect = $redirect{REDIRECT} ne 'NO'; + my $is_redirect = !$redirect{REDIRECT}; - my $src = $redirect{SRC}; - my $dst = $redirect{DST}; + my $src = defined($redirect{SRC}) ? $redirect{SRC} : ''; + my $dst = defined($redirect{DST}) ? $redirect{DST} : ''; # See if I have a group as source if( $fwItems{$src} eq 'GROUP' ) { @@ -2781,61 +2850,60 @@ sub applyRedirect { return $rules; } - # See if I have a group as destination - if( $fwItems{$dst} eq 'GROUP' ) { - my %newredirect = %redirect; - foreach my $item ( @{$fw{GROUP}{$dst}{ITEMS}} ) { - # Ignore ZONE items (PREROUTING don't accept -o option) - if( $item ne 'FIREWALL' && $fw{ZONE}{$item}{IF} eq '' ) { - $newredirect{DST} = $item; - $rules .= $this->applyRedirect( %newredirect ); - } else { - print "REDIRECT INVALID : IGNORING : $src --> $dst\n"; + # Don't check group membership for * zone + if( $dst ne '*' ) { + # See if I have a group as destination + if( $fwItems{$dst} eq 'GROUP' ) { + my %newredirect = %redirect; + foreach my $item ( @{$fw{GROUP}{$dst}{ITEMS}} ) { + # Ignore ZONE items (PREROUTING doesn't accept -o option) + if( $item ne 'FIREWALL' && $fw{ZONE}{$item}{IF} eq '' ) { + $newredirect{DST} = $item; + $rules .= $this->applyRedirect( %newredirect ); + } else { + print "Error: REDIRECT $src --> $dst invalid.\n"; + } } + return $rules; } - return $rules; } # I define the SERVICE - my $service = $redirect{SERVICE}; - my $port = $redirect{PORT}; - my $toport = $redirect{TOPORT}; + my $service = defined($redirect{SERVICE}) ? $redirect{SERVICE} : ''; + my $port = defined($redirect{PORT}) ? $redirect{PORT} : ''; + my $toport = defined($redirect{TOPORT}) ? $redirect{TOPORT} : ''; my ($src_zone, $src_peer, $src_type, $src_mac) = $this->expand_item( $src ); my %src_zone_attr = $this->GetZone( $src_zone ); my $src_if = $src_zone_attr{IF}; - - my $dst_zone; - my $dst_peer; - my $dst_if; - if( $dst eq '*' ) { - $dst_zone = '*'; - $dst_peer = '0.0.0.0/0'; - $dst_if = ''; - } else { - ($dst_zone, $dst_peer, $dst_type, undef) = $this->expand_item( $dst ); + my ($dst_zone, $dst_peer, $dst_type, $dst_mac) = $this->expand_item( $dst ); + my $dst_if = ''; + if( $dst ne '*' ) { my %dst_zone_attr = $this->GetZone( $dst_zone ); $dst_if = $dst_zone_attr{IF}; } - print $is_redirect ? '' : 'NOT ',"REDIRECT port($service"; - if( $service eq 'tcp' || $service eq 'udp' ) { print "/$port"; } # Invalid Redirect, Ignore - # print " $src"; - # if( $src_mac ne '' ) { print " (mac:$src_mac)"; } - if( $src_mac ne '' ) { print " : INVALID : IGNORING : $src (mac:$src_mac)"; - } else { - print ") $src"; + if( $src_mac ne '' && $src_peer eq '' ) { + print "Error: REDIRECT $src (mac:$src_mac) invalid.\n"; + return $rules; } - print " --> $dst"; + if( $dst_mac ne '' && $dst_peer eq '' ) { + print "Error: REDIRECT $dst (mac:$dst_mac) invalid.\n"; + return $rules; + } + + print $is_redirect ? '' : 'NOT ',"REDIRECT port($service"; + if( $service eq 'tcp' || $service eq 'udp' ) { print "/$port"; } + print ") $src --> $dst"; if( $is_redirect ) { print " TO LOCAL PORT $toport"; } print "\n"; # I create the 2 return chains - $rules .= $this->applyServiceRedirect( \%services, $service, $src_if, $src_peer, $src_type, $src_mac, $dst_if, $dst_peer, $dst_type, $port, $toport, $is_redirect); - + $rules .= $this->applyServiceRedirect( \%services, $service, $src_if, $src_peer, $src_type, $dst_if, $dst_peer, $dst_type, $port, $toport, $is_redirect); + return $rules; } @@ -2847,37 +2915,43 @@ sub applyServiceRedirect { sub _applyServiceRedirect { my $this = shift; - my ($ref_calledServices, $ref_services, $serviceName, $src_if, $src_peer, $src_type, $src_mac, $dst_if, $dst_peer, $dst_type, $port, $toport, $is_redirect) = @_; + my ($ref_calledServices, $ref_services, $serviceName, $src_if, $src_peer, $src_type, $dst_if, $dst_peer, $dst_type, $port, $toport, $is_redirect) = @_; my $rules = ''; - - my %service = %{$ref_services->{$serviceName}}; + + my %service = (); + if( !grep /^$serviceName$/, keys %{$ref_services} ) { + print "Error: REDIRECT service $serviceName invalid.\n"; + return $rules; + } else { + %service = %{$ref_services->{$serviceName}}; + } $ref_calledServices->{$serviceName} = 1; # loop on filering rules - for( my $i = 0; $i <= $#{$service{FILTERS}}; $i++ ) { + for( my $i=0; $i<=$#{$service{FILTERS}}; $i++ ) { my %filter = %{$service{FILTERS}[$i]}; - if( $filter{SERVICE} ne '' && !$ref_calledServices->{$filter{SERVICE}} ) { + if( defined($filter{SERVICE}) && $filter{SERVICE} ne '' && !$ref_calledServices->{$filter{SERVICE}} ) { # It is a subservice, recursion call to _applyService $rules .= $this->_applyServiceRedirect( $ref_calledServices, $ref_services, $filter{SERVICE}, - $src_if, $src_peer, $src_type, $src_mac, $dst_if, $dst_peer, $dst_type, $port, $toport, $is_redirect ); + $src_if, $src_peer, $src_type, $dst_if, $dst_peer, $dst_type, $port, $toport, $is_redirect ); next; } - my $direction = $filter{DIRECTION}; - my $p = $filter{P}; - my $icmptype = $filter{ICMPTYPE}; - my $sport = $filter{SPORT}; - my $dport = $filter{DPORT}; - my $state = $filter{STATE}; - my $jump = $filter{JUMP}; + my $direction = defined($filter{DIRECTION}) ? $filter{DIRECTION} : ''; + my $p = defined($filter{P}) ? $filter{P} : ''; + my $icmptype = defined($filter{ICMPTYPE}) ? $filter{ICMPTYPE} : ''; + my $sport = defined($filter{SPORT}) ? $filter{SPORT} : ''; + my $dport = defined($filter{DPORT}) ? $filter{DPORT} : ''; + my $state = defined($filter{STATE}) ? $filter{STATE} : ''; + my $jump = defined($filter{JUMP}) ? $filter{JUMP} : ''; # I only use the first tcp/udp filter rule if( $direction eq 'go' && ($p eq 'tcp' || $p eq 'udp' || $p eq '') && - ($filter{JUMP} eq '' || $filter{JUMP} eq 'ACCEPT') ) { + ($jump eq '' || $jump eq 'ACCEPT') ) { if( $dport eq 'PORT' ) { $dport = $port; @@ -2891,12 +2965,7 @@ sub _applyServiceRedirect { if( $src_type =~ /HOST|NET/ ) { $cmd .= "-s $src_peer "; } } - # Invalid Redirect, Ignore - #if( $src_mac =~ /^[0-9a-fA-F]{2}\:[0-9a-fA-F]{2}\:[0-9a-fA-F]{2}\:[0-9a-fA-F]{2}\:[0-9a-fA-F]{2}\:[0-9a-fA-F]{2}$/ ) { - # $cmd .= "-m mac --mac-source $src_mac "; - #} - - # iptables prerouting chain don't accept -o option. + # iptables prerouting chain doesn't accept -o option. #if( $dst_if ne '' ) { $cmd .= "-o $dst_if "; } if( $dst_peer ne '' ) { if( $dst_type eq 'GEOIP' ) { $cmd .= "-m geoip --destination-country $dst_peer "; } @@ -2949,32 +3018,35 @@ sub applyRule { my $preroute = shift; my %rule = @_; - if( $rule{ACTIVE} eq 'NO' ) { + if( $rule{ACTIVE} ) { return ''; } - + my %fw = %{$this->{fw}}; my %fwItems = %{$this->{fwItems}}; my %services = %{$this->{services}}; + my %ndpiprotocols = %{$this->{ndpiprotocols}}; my $rules = ''; - - my $src = $rule{SRC}; - my $dst = $rule{DST}; - my $time = $rule{TIME}; - my $target = $rule{TARGET}; - my $service = $rule{SERVICE}; - my $ndpi = $rule{NDPI}; - my $category = $rule{CATEGORY}; - my $hostnameset = $rule{HOSTNAMESET}; - my $hostname = $rule{HOSTNAME}; - my $riskset = $rule{RISKSET}; - my $risk = $rule{RISK}; - my $ratelimit = $rule{RATELIMIT}; - my $port = $rule{PORT}; - my $mark = $rule{MARK}; - my $helper = $rule{HELPER}; - my $log = $rule{LOG}; + + my $src = defined($rule{SRC}) ? $rule{SRC} : ''; + my $dst = defined($rule{DST}) ? $rule{DST} : ''; + my $time = defined($rule{TIME}) ? $rule{TIME} : ''; + my $target = defined($rule{TARGET}) ? $rule{TARGET} : ''; + my $service = defined($rule{SERVICE}) ? $rule{SERVICE} : ''; + my $ndpi = defined($rule{NDPI}) ? $rule{NDPI} : ''; + my $category = defined($rule{CATEGORY}) ? $rule{CATEGORY} : ''; + my $hostnameset = defined($rule{HOSTNAMESET}) ? $rule{HOSTNAMESET} : ''; + my $hostname = defined($rule{HOSTNAME}) ? $rule{HOSTNAME} : ''; + my $riskset = defined($rule{RISKSET}) ? $rule{RISKSET} : ''; + my $risk = defined($rule{RISK}) ? $rule{RISK} : ''; + my $ratelimit = defined($rule{RATELIMIT}) ? $rule{RATELIMIT} : ''; + my $port = defined($rule{PORT}) ? $rule{PORT} : ''; + my $mark = defined($rule{MARK}) ? $rule{MARK} : ''; + my $helper = defined($rule{HELPER}) ? $rule{HELPER} : ''; + my $log = defined($rule{LOG}) ? $rule{LOG} : ''; + + my $prev = ''; if( $display ) { if( $target ne '' ) { @@ -2997,7 +3069,6 @@ sub applyRule { if( $hostnameset ne '' ) { print " hostname($hostnameset)"; } if( $riskset ne '' ) { print " risk($riskset)"; } print " $src --> $dst"; - #if( $src_mac ne '' ) { print "(mac:$src_mac)"; } if( $ratelimit ne '' ) { print " WHEN rate($ratelimit)"; } if( $time ne '' ) { print " AT $time"; } if( $mark ne '' ) { print " WITH mark($mark)"; } @@ -3035,7 +3106,7 @@ sub applyRule { # sort @srcs = sort(@srcs); # unique values - my $prev = '***none***'; + $prev = '***none***'; @srcs = grep($_ ne $prev && (($prev) = $_), @srcs); if( $#srcs > 0 ) { # more then one element @@ -3052,11 +3123,13 @@ sub applyRule { my @dsts = (); my @dst_list = split( /,/, $dst ); foreach my $d (@dst_list) { - if( $d eq '*' && not $preroute ) { - # all zones - foreach my $item ( sort(keys(%{$fw{ZONE}})) ) { - if( $item ne 'FIREWALL' ) { - push @dsts, $item; + if( $d eq '*' ) { + if( ! $preroute ) { + # all zones + foreach my $item ( sort(keys(%{$fw{ZONE}})) ) { + if( $item ne 'FIREWALL' ) { + push @dsts, $item; + } } } } elsif( $fwItems{$d} eq 'GROUP' ) { @@ -3071,7 +3144,7 @@ sub applyRule { # sort @dsts = sort(@dsts); # unique values - my $prev = '***none***'; + $prev = '***none***'; @dsts = grep($_ ne $prev && (($prev) = $_), @dsts); if( $#dsts > 0 ) { # more then one element @@ -3087,9 +3160,9 @@ sub applyRule { # service is a list of services? if( $service =~ /,/ ) { - my @services = split( /,/, $service ); + my @servicelist = split( /,/, $service ); my %newrule = %rule; - foreach my $serv (@services) { + foreach my $serv (@servicelist) { $newrule{SERVICE} = $serv; $rules .= $this->applyRule( 0, $mangle, $raw, $preroute, %newrule ); } @@ -3099,26 +3172,40 @@ sub applyRule { # ndpi services within category if( $category ne '' ) { my @items = (); - my @ndpiprotocols = $this->GetNdpiProtocolsList(); - foreach my $k (@ndpiprotocols) { + foreach my $k (keys %ndpiprotocols) { my %ndpiprotocol = $this->GetNdpiProtocol($k); if( $ndpiprotocol{CATEGORY} eq $category ) { push(@items, $k); } } $ndpi = join(",", @items); + if( $ndpi eq '' ) { + print "Error: nDPI category $category invalid.\n"; + return $rules; + } } + # ndpi service is a list of ndpi services? + if( $ndpi =~ /,/ ) { + my @ndpilist = split( /,/, $ndpi ); + my %newrule = %rule; + foreach my $ndpiproto (@ndpilist) { + $newrule{NDPI} = $ndpiproto; + $newrule{CATEGORY} = ''; + $rules .= $this->applyRule( 0, $mangle, $raw, $preroute, %newrule ); + } + return $rules; + } + # hostnameset items if( $hostnameset ne '' ) { my ($hostname_list) = $this->expand_hostnameset_item( $hostnameset ); - my @hostnames = (); my @hostnames = split( /,/, $hostname_list ); # sort @hostnames = sort(@hostnames); # unique values - my $prev = '***none***'; + $prev = '***none***'; @hostnames = grep($_ ne $prev && (($prev) = $_), @hostnames); if( $#hostnames > 0 ) { # more than one element @@ -3141,20 +3228,25 @@ sub applyRule { } my ($src_zone, $src_peer, $src_type, $src_mac) = $this->expand_item( $src ); - my ($dst_zone, $dst_peer, $dst_type, undef) = $this->expand_item( $dst ); + my ($dst_zone, $dst_peer, $dst_type, $dst_mac) = $this->expand_item( $dst ); if( $src_zone eq 'FIREWALL' && $dst_zone eq 'FIREWALL' ) { # ignore chain FIREWALL-FIREWALL if( !$mangle ) { - print "** FIREWALL-->FIREWALL ignored **\n"; + print "Error: FIREWALL-->FIREWALL invalid.\n"; } return $rules; } + if( $dst_mac ne '' && $dst_peer eq '' ) { + print "Error: destination (mac:$dst_mac) invalid.\n"; + return $rules; + } + # time items - $t_days = ''; - $t_start = ''; - $t_stop = ''; + my $weekdays = ''; + my $timestart = ''; + my $timestop = ''; if( $time ne '' ) { my @times = (); if( $fwItems{$time} eq 'TIMEGROUP' ) { @@ -3168,7 +3260,7 @@ sub applyRule { # sort @times = sort(@times); # unique values - my $prev = '***none***'; + $prev = '***none***'; @times = grep($_ ne $prev && (($prev) = $_), @times); if( $#times > 0 ) { # more then one element @@ -3181,43 +3273,43 @@ sub applyRule { } else { $time = shift @times; } - ($t_days, $t_start, $t_stop) = $this->expand_time_item( $time ); + ($weekdays, $timestart, $timestop) = $this->expand_time_item( $time ); } #command( "" ); #comment( "# service $service: $src --> $dst ($src_peer -> $dst_peer) [$src_zone -> $dst_zone]" ); - + # Create the Chains - my $andata = ''; - my $ritorno = ''; + my $goChain = ''; + my $backChain = ''; if( $preroute ) { - $andata = "$src_zone-IN"; + $goChain = "$src_zone-IN"; } else { - $andata = "$src_zone-$dst_zone"; + $goChain = "$src_zone-$dst_zone"; } if( $preroute || $raw ) { - $ritorno = ''; + $backChain = ''; } else { - $ritorno = "$dst_zone-$src_zone"; + $backChain = "$dst_zone-$src_zone"; } - + # Create the Rules if( $mangle ) { # Mangle Rule - $rules .= $this->applyService( \%services, $service, $andata, $ritorno, $src_peer, $src_type, $src_mac, $dst_peer, $dst_type, - $port, $ndpi, $category, $hostname, $risk, '', $t_days, $t_start, $t_stop, '', '', $mark, '' ); + $rules .= $this->applyService( \%services, $service, $goChain, $backChain, $src_peer, $src_type, $src_mac, $dst_peer, $dst_type, + $port, \%ndpiprotocols, $ndpi, $hostname, $risk, '', $weekdays, $timestart, $timestop, '', '', $mark, '' ); } elsif( $raw ) { # Raw Rule - $rules .= $this->applyService( \%services, $service, $andata, $ritorno, $src_peer, $src_type, $src_mac, $dst_peer, $dst_type, - $port, $ndpi, $category, $hostname, $risk, '', $t_days, $t_start, $t_stop, '', '', '', $helper ); + $rules .= $this->applyService( \%services, $service, $goChain, $backChain, $src_peer, $src_type, $src_mac, $dst_peer, $dst_type, + $port, \%ndpiprotocols, $ndpi, $hostname, $risk, '', $weekdays, $timestart, $timestop, '', '', '', $helper ); } else { # Filter Rule - $rules .= $this->applyService( \%services, $service, $andata, $ritorno, $src_peer, $src_type, $src_mac, $dst_peer, $dst_type, - $port, $ndpi, $category, $hostname, $risk, $ratelimit, $t_days, $t_start, $t_stop, $log, $target, '', '' ); + $rules .= $this->applyService( \%services, $service, $goChain, $backChain, $src_peer, $src_type, $src_mac, $dst_peer, $dst_type, + $port, \%ndpiprotocols, $ndpi, $hostname, $risk, $ratelimit, $weekdays, $timestart, $timestop, $log, $target, '', '' ); } - + return $rules; } @@ -3231,39 +3323,47 @@ sub applyService { sub _applyService { my $this = shift; my( $ref_calledServices, $ref_services, $serviceName, $goChain, $backChain, $src, $src_type, $src_mac, $dst, $dst_type, - $port, $ndpi, $category, $hostname, $risk, $ratelimit, $t_days, $t_start, $t_stop, $log, $target, $mangle_mark, $helper ) = @_; - - my %service = %{$ref_services->{$serviceName}}; + $port, $ref_ndpiprotocols, $ndpi, $hostname, $risk, $ratelimit, $weekdays, $timestart, $timestop, $log, $target, $mangle_mark, $helper ) = @_; my $rules = ''; - + + my %service = (); + if( !grep /^$serviceName$/, keys %{$ref_services} ) { + print "Error: service $serviceName invalid.\n"; + return $rules; + } else { + %service = %{$ref_services->{$serviceName}}; + } + $ref_calledServices->{$serviceName} = 1; - # service comment - #comment( "# $serviceName: ".$service{DESCRIPTION} ); - # - + if( $ndpi ne '' && $ndpi ne 'all' ) { + if( !grep /^$ndpi$/, keys %{$ref_ndpiprotocols} ) { + print "Error: nDPI service $ndpi invalid.\n"; + return $rules; + } + } + # loop on the filering rules - my $i; - for( $i = 0; $i <= $#{$service{FILTERS}}; $i++ ) { + for( my $i=0; $i<=$#{$service{FILTERS}}; $i++ ) { my %filter = %{$service{FILTERS}[$i]}; - - if( $filter{SERVICE} ne '' && !$ref_calledServices->{$filter{SERVICE}} ) { + + if( defined($filter{SERVICE}) && $filter{SERVICE} ne '' && !$ref_calledServices->{$filter{SERVICE}} ) { # It is a subservice, recursion call to _applyService $rules .= $this->_applyService( $ref_calledServices, $ref_services, $filter{SERVICE}, - $goChain, $backChain, $src, $src_type, $src_mac, $dst, $dst_type, $port, $ndpi, $category, $hostname, $risk, $ratelimit, - $t_days, $t_start, $t_stop, $log, $target, $mangle_mark, $helper ); + $goChain, $backChain, $src, $src_type, $src_mac, $dst, $dst_type, $port, $ref_ndpiprotocols, $ndpi, $hostname, $risk, $ratelimit, + $weekdays, $timestart, $timestop, $log, $target, $mangle_mark, $helper ); next; } - my $direction = $filter{DIRECTION}; - my $p = $filter{P}; - my $icmptype = $filter{ICMPTYPE}; - my $sport = $filter{SPORT}; - my $dport = $filter{DPORT}; - my $state = $filter{STATE}; - my $jump = $filter{JUMP}; + my $direction = defined($filter{DIRECTION}) ? $filter{DIRECTION} : ''; + my $p = defined($filter{P}) ? $filter{P} : '';; + my $icmptype = defined($filter{ICMPTYPE}) ? $filter{ICMPTYPE} : '';; + my $sport = defined($filter{SPORT}) ? $filter{SPORT} : '';; + my $dport = defined($filter{DPORT}) ? $filter{DPORT} : '';; + my $state = defined($filter{STATE}) ? $filter{STATE} : '';; + my $jump = defined($filter{JUMP}) ? $filter{JUMP} : '';; if( $target =~ /DROP|REJECT/ && $direction ne 'go' && $ratelimit eq '' ) { # Don't process Back filters @@ -3321,44 +3421,37 @@ sub _applyService { if( $dport ne '' ) { $cmd .= "--dport $dport "; } if( $ndpi ne '' ) { - if( $target eq 'ACCEPT' ) { - if( $ndpi eq 'all' ) { - print "** all nDPI service ignored on target $target **\n"; - } else { + if( $ndpi eq 'all' ) { + # First Packet Classification only + $cmd .= "-m ndpi --all "; + } else { + if( $this->{ndpiprotocols}{$ndpi}{'DPI'} && $mangle_mark eq '' ) { my $cmddpi = $cmd; - $cmddpi .= "-m ndpi --inprogress $ndpi -j $target "; + # Allow beyond First Packet Classification + $cmddpi .= "-m ndpi --inprogress $ndpi -j ACCEPT "; $rules .= "$cmddpi\n"; - $cmd .= "-m ndpi --clevel dpi --proto $ndpi "; - } - if( $hostname ne '' ) { print "** nDPI hostname ignored on target $target **\n"; } - if( $risk ne '' ) { print "** nDPI risk ignored on target $target **\n"; } - } else { - if( $ndpi eq 'all' ) { - $cmd .= "-m ndpi --all "; - } else { - $cmd .= "-m ndpi --proto $ndpi "; - } - if( $hostname ne '' ) { $cmd .= "--host /$hostname/ "; } - if( $risk ne '' ) { $cmd .= "--risk $risk "; } + } + $cmd .= "-m ndpi --proto $ndpi "; } + if( $hostname ne '' ) { $cmd .= "--host /$hostname/ "; } + if( $risk ne '' ) { $cmd .= "--risk $risk "; } } if( $state ne '' ) { $cmd .= "-m conntrack --ctstate $state "; } - if( $t_days ne '' && $t_start ne '' && $t_stop ne '' ) { - $cmd .= "-m time --timestart $t_start --timestop $t_stop --weekdays $t_days "; + if( $weekdays ne '' && $timestart ne '' && $timestop ne '' ) { + $cmd .= "-m time --timestart $timestart --timestop $timestop --weekdays $weekdays "; } # LOG before target if( $log eq "YES" ) { my $cmdlog = $cmd; if( $target =~ /DROP|REJECT/ ) { + my $logprefix = ''; if( $risk ne '' ) { $logprefix = "TFW=RISK-$risk"; } elsif( $hostname ne '') { $logprefix = "TFW=$hostname"; - } elsif( $category ne '') { - $logprefix = "TFW=$category"; } elsif( $ndpi ne '' ) { $logprefix = "TFW=$ndpi"; } elsif( $src_type eq 'GEOIP' || $dst_type eq 'GEOIP' ) { @@ -3418,6 +3511,7 @@ sub _applyService { } } + # Print commands, for debugging #print "\n$cmd\n"; $rules .= "$cmd\n"; @@ -3425,41 +3519,52 @@ sub _applyService { return $rules; } -# Given the name of the item it returns the zone, ip & netmask +# Given the name of the item it returns the zone, ip & netmask, type and mac sub expand_item { my $this = shift; my $item = shift; - + my %fw = %{$this->{fw}}; my %fwItems = %{$this->{fwItems}}; - my $type = $fwItems{$item}; my $zone = ''; my $ip = ''; + my $type = ''; my $mac = ''; - if( $type eq 'ZONE' ) { - $zone = $item; - $ip = '0.0.0.0/0'; - } - if( $type eq 'GEOIP' ) { - $zone = $fw{GEOIP}{$item}{ZONE}; - $ip = $fw{GEOIP}{$item}{IP}; - } - if( $type eq 'IPSET' ) { - $zone = $fw{IPSET}{$item}{ZONE}; - $ip = $fw{IPSET}{$item}{IP}; - } - if( $type eq 'NET' ) { - $zone = $fw{NET}{$item}{ZONE}; - $ip = $fw{NET}{$item}{IP}.'/'.$fw{NET}{$item}{NETMASK}; - } - if( $type eq 'HOST' ) { - $zone = $fw{HOST}{$item}{ZONE}; - $ip = $fw{HOST}{$item}{IP}; - if( $ip ne '' ) {$ip = $ip.'/32';} - $mac = $fw{HOST}{$item}{MAC}; + if( defined($item) ) { + + if( $item eq '*' ) { + $type = 'ZONE'; + } else { + $type = $fwItems{$item}; + } + + if( $type eq 'ZONE' ) { + $zone = $item; + $ip = '0.0.0.0/0'; + } + if( $type eq 'GEOIP' ) { + $zone = $fw{GEOIP}{$item}{ZONE}; + $ip = $fw{GEOIP}{$item}{IP}; + } + if( $type eq 'IPSET' ) { + $zone = $fw{IPSET}{$item}{ZONE}; + $ip = $fw{IPSET}{$item}{IP}; + } + if( $type eq 'NET' ) { + $zone = $fw{NET}{$item}{ZONE}; + $ip = $fw{NET}{$item}{IP}.'/'.$fw{NET}{$item}{NETMASK}; + } + if( $type eq 'HOST' ) { + $zone = $fw{HOST}{$item}{ZONE}; + $ip = $fw{HOST}{$item}{IP}; + if( $ip ne '' ) {$ip = $ip.'/32';} + $mac = $fw{HOST}{$item}{MAC}; + } + } + return ($zone, $ip, $type, $mac ); } @@ -3476,7 +3581,7 @@ sub expand_time_item { $weekdays = $fw{TIME}{$item}{WEEKDAYS}; $timestart = $fw{TIME}{$item}{TIMESTART}; $timestop = $fw{TIME}{$item}{TIMESTOP}; - + return ( $weekdays, $timestart, $timestop ); } @@ -3488,7 +3593,7 @@ sub expand_hostnameset_item { my $hostnames = ''; $hostnames = $fw{HOSTNAMESET}{$item}{HOSTNAMES}; - + return ($hostnames); } @@ -3503,38 +3608,4 @@ sub command { } } -sub iptables_restore_emu { - my $this = shift; - my $rules = shift; - - my $table = ''; - my @lines = split(/\n/, $rules); - foreach my $line (@lines) { - $line =~ s/\#(.*)$//; - if( !$line || $line eq 'COMMIT' ) { - next; - } - if( $line =~ /^\*(.*?)$/ ) { - $table = $1 eq 'filter' ? '' : $1; - next; - } - my $cmd = ''; - my $chain = ''; - my $policy = ''; - if( $line =~ /^\:(.*?) (.*?) (.*?)$/ ) { - $chain = $1; - $policy = $2; - if( $chain =~ /^(INPUT|OUTPUT|FORWARD)$/ ) { - next; - } - $cmd = "-N $chain". ($policy ne '-' ? " -P $policy" : ''); - } else { - $cmd = $line; - } - if( $table ) { $cmd = "-t $table $cmd"; } - - $this->command("iptables $cmd"); - } -} - 1; diff --git a/src/turtlefirewall/setup/convertflowinfo.pl b/src/turtlefirewall/setup/convertflowinfo.pl new file mode 100644 index 0000000..72a876a --- /dev/null +++ b/src/turtlefirewall/setup/convertflowinfo.pl @@ -0,0 +1,109 @@ +#!/usr/bin/env perl + +# Turtle Firewall : Convert Flow Info +# +# Software for configuring a linux firewall (netfilter) +# +# 2001/11/23 13:25:00 +# +#====================================================================== +# Copyright (c) 2001-2026 Andrea Frigido +# You may distribute under the terms of either the GNU General Public +# License +#====================================================================== + +use Tie::File; + +my $log; + +foreach my $arg (@ARGV) { + if( $arg =~ /^(--log)\=(.*)/ ) { + $log = $2; + } else { + if( $arg ne '--help' ) { + print "Wrong parameters...\n"; + } + print "Use: convertflowinfo.pl [--log=file] [--help]\n"; + print "Example: convertflowinfo.pl --log=/tmp/flowinfo.log\n"; + exit(1); + } +} + +if( $log eq '' ) { print "Error: no log provided\n"; exit(1); } +if( ! -f $log ) { print "Error: $log not found\n"; exit(1); } + +my $logtype = qx{file --brief --mime-type $log}; +if( $logtype =~ /sqlite3/ ) { print "Error: $log already converted\n"; exit(1); } + +&convert2psv($log); + +my $qsql = "${log}.qsql"; +system("q -C readwrite -Hp 'select * from $log' > /dev/null 2>&1"); +if( ! -f $qsql ) { print "Error: $qsql not found\n"; exit(1); } + +system("mv -f $qsql $log > /dev/null 2>&1"); + +#============================================================================ + +sub convert2psv { + + my $log = shift; + + tie @log_lines, 'Tie::File', $log; + + 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 $tlsfp = ''; + 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; + } + + if( $l =~ /CM=(.*?)( |$)/ ) { $connmark = $1; } + if( $l =~ /SN=(.*?)( |$)/ ) { $srcnat = $1; } + if( $l =~ /DN=(.*?)( |$)/ ) { $dstnat = $1; } + if( $l =~ /P=(.*?)( |$)/ ) { $protocol = $1; } + if( $l =~ /H=(.*?)( |$)/ && $l !~ /H=\"(.*?)\"( |$)/ ) { $hostname = $1; } + if( $l =~ /c=(.*?)( |$)/ ) { $ja4c = $1; } + if( $l =~ /F=(.*?)( |$)/ ) { $tlsfp = $1; } + if( $l =~ /R=(.*?)( |$)/ ) { $risk = $1; } + + $l = "$stime|$etime|$l3proto|$l4proto|$source|$sport|$destination|$dport|$ubytes|$dbytes|$upackets|$dpackets|$ifindex|$connmark|$srcnat|$dstnat|$protocol|$hostname|$ja4c|$tlsfp|$risk\n"; + } + my $psvheader = 'stime|etime|l3proto|l4proto|source|sport|destination|dport|ubytes|dbytes|upackets|dpackets|ifindex|connmark|srcnat|dstnat|protocol|hostname|ja4c|tlsfp|risk'; + unshift @log_lines, $psvheader; + + untie @log_lines; +} diff --git a/src/turtlefirewall/setup/domain_blacklist b/src/turtlefirewall/setup/domain_blacklist index 20aec45..c63f4e3 100644 --- a/src/turtlefirewall/setup/domain_blacklist +++ b/src/turtlefirewall/setup/domain_blacklist @@ -4,12 +4,11 @@ # ln -sf /usr/lib/turtlefirewall/domain_blacklist /etc/cron.daily/domain_blacklist # -echo -e "\nTurtle Firewall 2.4 - Domain Blacklist"; -echo -e "Copyright (c) 2001-2024 Andrea Frigido\n"; - -fw_file="/etc/turtlefirewall/fw.xml" +echo -e "\nTurtle Firewall 2.7 - Domain Blacklist"; +echo -e "Copyright (c) 2001-2026 Andrea Frigido \n"; blacklist_file="/etc/turtlefirewall/domain_blacklist.dat" +also_blacklist_file="/etc/turtlefirewall/also_domain_blacklist.dat" never_blacklist_file="/etc/turtlefirewall/never_domain_blacklist.dat" # Some older CPU's cant load large lists @@ -122,6 +121,15 @@ echo -e "Import : \c" if [ -s $blacklist_file ] then + # Ensure include + if [ -s $also_blacklist_file ] + then + while read blacklist_include + do + sed -i "1s/^/$blacklist_include\n/" $blacklist_file + done < $also_blacklist_file + fi + # Ensure exclude if [ -s $never_blacklist_file ] then diff --git a/src/turtlefirewall/setup/fixconfig.sh b/src/turtlefirewall/setup/fixconfig.sh index 846b8c5..610bee0 100644 --- a/src/turtlefirewall/setup/fixconfig.sh +++ b/src/turtlefirewall/setup/fixconfig.sh @@ -15,12 +15,6 @@ if [ $? != 0 ] sed -i '/^<\/options>$/ i\
'.&ui_links_row(\@links).'
-
"; +print " +
"; print "
\n";
-print qx{/usr/sbin/turtlefirewall --start 2>&1};
+print @output;
 print "
"; print "
"; diff --git a/src/turtlefirewall/stop.cgi b/src/turtlefirewall/stop.cgi index 9e59256..8337d31 100644 --- a/src/turtlefirewall/stop.cgi +++ b/src/turtlefirewall/stop.cgi @@ -3,19 +3,24 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2026 Andrea Frigido # You may distribute under the terms of either the GNU General Public # License #====================================================================== -do 'turtlefirewall-lib.pl'; +require './turtlefirewall-lib.pl'; + +@output = (); +foreach my $l (qx{/usr/sbin/turtlefirewall --stop 2>&1}) { + push @output, $fw->_clean($l); +} &ui_print_header( undef, $text{'title'}, "" ); -print " -
"; +print " +
"; print "
\n";
-print qx{/usr/sbin/turtlefirewall --stop 2>&1};
+print @output;
 print "
"; print "
"; diff --git a/src/turtlefirewall/turtlefirewall-lib.pl b/src/turtlefirewall/turtlefirewall-lib.pl index f88316b..76fe424 100644 --- a/src/turtlefirewall/turtlefirewall-lib.pl +++ b/src/turtlefirewall/turtlefirewall-lib.pl @@ -1,7 +1,7 @@ #====================================================================== # Turtle Firewall webmin module # -# Copyright (c) Andrea Frigido +# Copyright (c) 2001-2026 Andrea Frigido # You may distribute under the terms of either the GNU General Public # License #====================================================================== @@ -22,8 +22,7 @@ } if( ! $gotXmlParser ) { &ui_print_header( undef, $text{'title'}, "" ); - print "

XML::Parser perl module is needed, please install it!
"; - print 'install XML::Parser from CPAN

'; + print &ui_alert_box("Perl XML::Parser not found.", 'danger'); &ui_print_footer('/',$text{'index'}); exit; } @@ -31,17 +30,13 @@ # do you need to install startup scripts? if( -f "./setup/turtlefirewall" ) { &ui_print_header( undef, $text{'title'}, "" ); - print "
"; - print "This is the first execution of Turtle Firewall, you need to install/update startup scripts.\n"; - print "

"; + print &ui_alert_box('This is the first execution of Turtle Firewall, you need to install/update startup scripts.', 'warn'); + print "
\n"; print &ui_form_start("setup.cgi","post"); print &ui_submit("Install Turtle Firewall Startup scripts","install"); print &ui_form_end(); - print "
Notes: "; - print "Remember to install xt_ndpi, xt_geoip and xt_ratelimit kernel modules."; - #print "Remember to enable your Linux box to act as a router "; - #print "(select \"Act as router\"=yes in Hardware->Network->Routing webmin form)."; - #print "
  • Remember to install XML::Parser Perl module
  • "; + print "
    \n"; + print &ui_alert_box('Remember to install xt_ndpi, xt_geoip and xt_ratelimit kernel modules.', 'warn'); print "
    \n"; &ui_print_footer('/',$text{'index'}); exit; @@ -49,54 +44,67 @@ my $tfwlib = '/usr/lib/turtlefirewall/TurtleFirewall.pm'; if( ! -f $tfwlib ) { - &error( 'Turtle Firewall Library not found. Install Turtle Firewall.' ); + &ui_print_header( undef, $text{'title'}, "" ); + print &ui_alert_box("Turtle Firewall Library not found.", 'danger'); + &ui_print_footer('/',$text{'index'}); + exit; } if( -f $config{fw_logfile} ) { $SysLogFile = $config{fw_logfile}; -} elsif( -f "/var/log/messages" ) { +} elsif( -f "/var/log/messages" ) { $SysLogFile = "/var/log/messages"; -} elsif( -f "/var/log/syslog" ) { +} elsif( -f "/var/log/syslog" ) { $SysLogFile = "/var/log/syslog"; } +if( -f $config{fw_file} ) { + $tfwconf = $config{fw_file}; +} elsif( -f "/etc/turtlefirewall/fw.xml" ) { + $tfwconf = "/etc/turtlefirewall/fw.xml"; +} else { + &ui_print_header( undef, $text{'title'}, "" ); + print &ui_alert_box("Turtle Firewall Configuration not found.", 'danger'); + &ui_print_footer('/',$text{'index'}); + exit; +} + $FlowLogFile = "/var/log/flowinfo.log"; require $tfwlib; $fw = new TurtleFirewall(); -if( -f $config{fw_file} ) { - $fw->LoadFirewall( $config{fw_file} ); -} else { - $fw->LoadFirewall( "/etc/turtlefirewall/fw.xml" ); -} +$fw->LoadFirewall( $tfwconf ); sub confdir { if( $config{fw_file} =~ /(.*)\// ) { return $1; } else { - #return '/tmp'; return '/etc/turtlefirewall'; } } %flowreports = ( - 'source' => { LOGIDX => '4', ICOIDX => 'SRC', TXTIDX => 'flowstat_type_source' }, - 'destination' => { LOGIDX => '6', ICOIDX => 'DST', TXTIDX => 'flowstat_type_destination' }, - 'dport' => { LOGIDX => '7', ICOIDX => 'SERVICE', TXTIDX => 'flowstat_type_dport' }, - 'protocol' => { LOGIDX => '16', ICOIDX => 'NDPISERVICE', TXTIDX => 'flowstat_type_protocol' }, - 'hostname' => { LOGIDX => '17', ICOIDX => 'HOSTNAME', TXTIDX => 'flowstat_type_hostname' }, - 'risk' => { LOGIDX => '22', ICOIDX => 'RISK', TXTIDX => 'flowstat_type_risk' } + 'source' => { ICOIDX => 'SRC', NAMEIDX => 'flowstat_type_source_name', DESCIDX => 'flowstat_type_source_desc' }, + 'destination' => { ICOIDX => 'DST', NAMEIDX => 'flowstat_type_destination_name', DESCIDX => 'flowstat_type_destination_desc' }, + 'dport' => { ICOIDX => 'SERVICE', NAMEIDX => 'flowstat_type_dport_name', DESCIDX => 'flowstat_type_dport_desc' }, + 'protocol' => { ICOIDX => 'NDPISERVICE', NAMEIDX => 'flowstat_type_protocol_name', DESCIDX => 'flowstat_type_protocol_desc' }, + 'hostname' => { ICOIDX => 'HOSTNAME', NAMEIDX => 'flowstat_type_hostname_name', DESCIDX => 'flowstat_type_hostname_desc' }, + 'risk' => { ICOIDX => 'RISK', NAMEIDX => 'flowstat_type_risk_name', DESCIDX => 'flowstat_type_risk_desc' } +); + +%sqloperators = ( + '=' => { DESCIDX => 'sql_operator_equal_desc' }, + 'like' => { DESCIDX => 'sql_operator_like_desc' } ); %blacklists = ( - 'ip_blacklist' => { FILE => '/etc/turtlefirewall/ip_blacklist.dat', TYPE => 'hash:ip', DESCRIPTION => 'IP Address' }, - 'domain_blacklist' => { FILE => '/etc/turtlefirewall/domain_blacklist.dat', TYPE => 'ndpi:domain', DESCRIPTION => 'DNS Domain Name' }, - 'ja3_blacklist' => { FILE => '/etc/turtlefirewall/ja3_blacklist.dat', TYPE => 'ndpi:ja3', DESCRIPTION => 'SSL Handshake Fingerprint' }, - 'sha1_blacklist' => { FILE => '/etc/turtlefirewall/sha1_blacklist.dat', TYPE => 'ndpi:sha1', DESCRIPTION => 'SSL Certificate Fingerprint' } + 'ip_blacklist' => { FILE => '/etc/turtlefirewall/ip_blacklist.dat', TYPE => 'hash:ip', DESCIDX => 'item_ip_blacklist_desc' }, + 'domain_blacklist' => { FILE => '/etc/turtlefirewall/domain_blacklist.dat', TYPE => 'ndpi:domain', DESCIDX => 'item_domain_blacklist_desc' }, + 'sha1_blacklist' => { FILE => '/etc/turtlefirewall/sha1_blacklist.dat', TYPE => 'ndpi:sha1', DESCIDX => 'item_sha1_blacklist_desc' } ); %icons = ( - 'SHIELD' => { IMAGE => '' }, + 'ICON' => { IMAGE => '' }, 'ADDRESSLIST' => { IMAGE => '' }, 'FIREWALL' => { IMAGE => '' }, 'ZONE' => { IMAGE => '' }, @@ -163,7 +171,8 @@ sub confdir { 'HELPER_A' => { IMAGE => '' }, 'MARK' => { IMAGE => '' }, 'MARK_A' => { IMAGE => '' }, - 'TOPORT' => { IMAGE => '' } + 'TOPORT' => { IMAGE => '' }, + 'REF' => { IMAGE => '' } ); sub LoadServices { @@ -215,46 +224,42 @@ sub formService { my( $service, $port, $multiple ) = @_; my $this = ''; - my @services = split( /,/, $service ); + my @selected_services = (); + my @services = (); + my $selected_service3 = ''; + my @services3 = ('tcp','udp'); + # Default selection for new rules + my $servicetype = '2'; + + if( $service eq 'all' ) { + $servicetype = '1'; + } elsif( $service =~ /^(tcp|udp)$/ ) { + $servicetype = '3'; + $selected_service3 = $service; + } else { + # servicetype 2 + @selected_services = split( /,/, $service ); + } - my $options_service = ''; &LoadServices($fw); for my $k ($fw->GetServicesList()) { if( !($k =~ /^(tcp|udp|all)$/) ) { my %service = $fw->GetService($k); - my $selected = 0; - foreach my $s (@services) { - if( $k eq $s ) { - $selected = 1; - last; - } - } - $options_service .= qq~"; + my @opts = ( "$k", "$k - $service{DESCRIPTION}" ); + push(@services, \@opts); } } - $this .= ''; - $this .= '"; - - $this .= ''; - if( $multiple ) { - $this .= ''; - - $this .= ''; - $this .= '
    $text{rule_all_services}
    '; - $this .= " $text{rule_port} : $text{port_help}
    "; + my @opts = ( + [ 1, "$text{rule_all_services}
    " ], + [ 2, "".&ui_select("service2", \@selected_services, \@services, 5, $multiple)."
    " ], + [ 3, "".&ui_select("service3", $selected_service3, \@services3, 1)." $text{rule_port} : ".&ui_textbox("port", $port, 11, 0, 11)."$text{port_help}" ] + ); + $this = &ui_radio("servicetype", $servicetype, \@opts); return $this; } -# Parse service inputs and return name of service choosed +# Parse service inputs and return name of service chosen sub formServiceParse { my ($servicetype, $service2, $service3, $port ) = @_; @@ -276,23 +281,27 @@ sub formNdpiProtocol { my( $ndpiprotocol, $category, $multiple ) = @_; my $this = ''; - my @ndpiprotocols = split( /,/, $ndpiprotocol ); - + my @selected_ndpiprotocols = (); + my @ndpiprotocols = (); my @categorys = (); + # Default selection for new rules + my $ndpiprotocoltype = '2'; + + if( $ndpiprotocol eq 'all' ) { + $ndpiprotocoltype = '1'; + } elsif( $category ne '' ) { + $ndpiprotocoltype = '3'; + } else { + # ndpiprotocoltype 2 + @selected_ndpiprotocols = split( /,/, $ndpiprotocol ); + } - my $options_ndpiprotocol = ''; &LoadNdpiProtocols($fw); for my $k ($fw->GetNdpiProtocolsList()) { if( !($k =~ /^(all)$/) ) { my %ndpiprotocol = $fw->GetNdpiProtocol($k); - my $selected = 0; - foreach my $n (@ndpiprotocols) { - if( $k eq $n ) { - $selected = 1; - last; - } - } - $options_ndpiprotocol .= qq~"; + my @opts = ( "$k", "$k - $ndpiprotocol{CATEGORY}" ); + push(@ndpiprotocols, \@opts); push(@categorys, $ndpiprotocol{CATEGORY}); } } @@ -303,33 +312,16 @@ sub formNdpiProtocol { my $prev = '***none***'; @categorys = grep($_ ne $prev && (($prev) = $_), @categorys); - for my $k (@categorys) { - my $selected = 0; - if( $k eq $category ) { $selected = 1; } - $options_category .= qq~