Repository : http://git.fedorahosted.org/cgit/firewalld-recode.git
On branch : master
commit 99fa453cccd526c24fb7092da104eb86e49abd6b Author: Daniel Kopecek dkopecek@redhat.com Date: Mon Oct 20 14:07:34 2014 +0200
Use a transaction based backend abstraction
- use a simple transaction protocol for interacting with the system firewall via a firewall backend implementation (initial implementation) - got rid of useless methods in XTables derived classes - require implementation of getTableRef, listTables and the execute methods in XTables derived classes - Adapt EB/IPTables code
CMakeLists.txt | 3 +- src/Daemon/Backends/Linux/EBTables.cpp | 66 +-------- src/Daemon/Backends/Linux/EBTables.hpp | 16 +-- src/Daemon/Backends/Linux/IPTables.cpp | 138 +++++------------- src/Daemon/Backends/Linux/IPTables.hpp | 31 +--- src/Daemon/Backends/Linux/XTables.hpp | 54 +++++-- src/Daemon/Backends/LinuxXTables.cpp | 255 ++++++++++++++++++++++++++++++++ src/Daemon/Backends/LinuxXTables.hpp | 38 +++++ src/Daemon/Firewall/Backend.cpp | 12 ++- src/Daemon/Firewall/Backend.hpp | 10 +- src/Daemon/Firewall/BackendOpTable.hpp | 30 ++++ src/Daemon/Firewall/Firewall.cpp | 25 +-- src/Daemon/Firewall/Firewall.hpp | 9 +- src/Daemon/Firewall/Transaction.cpp | 4 +- src/Daemon/Firewall/Transaction.hpp | 6 +- tests/iptables/test_iptables.cpp | 4 +- 16 files changed, 448 insertions(+), 253 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt index 90c5357..9233894 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,6 +25,7 @@ file(GLOB daemon_dbus_methods_SOURCES file(GLOB daemon_SOURCES "src/Daemon/*.cpp" "src/Daemon/*.hpp" + "src/Daemon/Backends/*.[ch]pp" "src/Daemon/Backends/Linux/*.cpp" "src/Daemon/Backends/Linux/*.hpp" "src/Daemon/Firewall/*.cpp" @@ -49,7 +50,7 @@ include_directories(${CMAKE_SOURCE_DIR}/src/) add_executable(glib-vgsupp-helper glib-vgsupp-helper.cpp) target_link_libraries(glib-vgsupp-helper ${GLIBMM_LIBRARIES} ${GIOMM_LIBRARIES})
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DUNITTEST") +#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DUNITTEST")
# Compile test: sysctl add_executable(test_sysctl diff --git a/src/Daemon/Backends/Linux/EBTables.cpp b/src/Daemon/Backends/Linux/EBTables.cpp index f25b960..c7b80fa 100644 --- a/src/Daemon/Backends/Linux/EBTables.cpp +++ b/src/Daemon/Backends/Linux/EBTables.cpp @@ -33,10 +33,10 @@ namespace firewalld setChainPolicy("filter", "OUTPUT", "ACCEPT"); }
- int EBTables::listTables(StringVector &tables) const + const StringVector EBTables::listTables() const { - tables = { "filter", "nat", "broute" }; - return 0; + const StringVector tables({ "filter", "nat", "broute" }); + return tables; }
XTable& EBTables::getTableRef(const String& table) @@ -47,66 +47,6 @@ namespace firewalld throw std::runtime_error("Unknown EBtables table name"); }
- int EBTables::appendRule(const String& table, const String& chain, const String& rule_spec, int rule_priority) - { - return XTables::appendRule(getTableRef(table), chain, rule_spec, rule_priority); - } - - int EBTables::deleteRule(const String& table, const String& chain, const String& rule_spec, int rule_priority) - { - return XTables::deleteRule(getTableRef(table), chain, rule_spec, rule_priority); - } - - bool EBTables::ruleExists(const String& table, const String& chain, const String& rule_spec, int rule_priority) - { - return XTables::ruleExists(getTableRef(table), chain, rule_spec, rule_priority); - } - - int EBTables::insertRule(const String& table, const String& chain, const String& rule_spec, int rule_priority) - { - return XTables::insertRule(getTableRef(table), chain, rule_spec, rule_priority); - } - - int EBTables::listRules(const String& table, const String& chain, StringVectorMap<int>& rule_specs) - { - return XTables::listRules(getTableRef(table), chain, rule_specs); - } - - int EBTables::newChain(const String& table, const String& chain, bool user_defined) - { - return XTables::newChain(getTableRef(table), chain, user_defined); - } - - int EBTables::setChainPolicy(const String& table, const String& chain, const String& policy) - { - return XTables::setChainPolicy(getTableRef(table), chain, policy); - } - - int EBTables::renameChain(const String& table, const String& old_chain_name, const String& new_chain_name) - { - return XTables::renameChain(getTableRef(table), old_chain_name, new_chain_name); - } - - int EBTables::deleteChain(const String& table, const String& chain) - { - return XTables::deleteChain(getTableRef(table), chain); - } - - int EBTables::listChains(const String& table, StringVector& chains) - { - return XTables::listChains(getTableRef(table), chains); - } - - bool EBTables::chainExists(const String& table, const String& chain) - { - return XTables::chainExists(getTableRef(table), chain); - } - - int EBTables::passthrough(const String& table, const String& direct_specification) - { - return XTables::direct(getTableRef(table), direct_specification); - } - int EBTables::execute(const XTables::Operation &op) { StringVector args; diff --git a/src/Daemon/Backends/Linux/EBTables.hpp b/src/Daemon/Backends/Linux/EBTables.hpp index c1dd93e..1398ab4 100644 --- a/src/Daemon/Backends/Linux/EBTables.hpp +++ b/src/Daemon/Backends/Linux/EBTables.hpp @@ -34,21 +34,7 @@ namespace firewalld public: EBTables();
- int listTables(StringVector& tables) const; - - int appendRule(const String& table, const String& chain, const String& rule_spec, int rule_priority); - int deleteRule(const String& table, const String& chain, const String& rule_spec, int rule_priority); - bool ruleExists(const String& table, const String& chain, const String& rule_spec, int rule_priority); - int insertRule(const String& table, const String& chain, const String& rule_spec, int rule_priority); - int listRules(const String& table, const String& chain, StringVectorMap<int>& rule_specs); - - int newChain(const String& table, const String& chain, bool user_defined = true); - int setChainPolicy(const String& table, const String& chain, const String& policy); - int renameChain(const String& table, const String& old_chain_name, const String& new_chain_name); - int deleteChain(const String& table, const String& chain); - int listChains(const String& table, StringVector& chains); - bool chainExists(const String& table, const String& chain); - int passthrough(const String& table, const String& direct_specification); + const StringVector listTables() const;
protected: XTable& getTableRef(const String& table); diff --git a/src/Daemon/Backends/Linux/IPTables.cpp b/src/Daemon/Backends/Linux/IPTables.cpp index 84fa330..f6d36ee 100644 --- a/src/Daemon/Backends/Linux/IPTables.cpp +++ b/src/Daemon/Backends/Linux/IPTables.cpp @@ -27,122 +27,52 @@ namespace firewalld : _filter("filter"), _nat("nat"), _mangle("mangle"), + _security("security"), + _raw("raw"), _ipXtables_path(ipXtables_path) { - XTables::newChain(_filter, "INPUT", false, true); - XTables::setChainPolicy(_filter, "INPUT", "ACCEPT"); - XTables::newChain(_filter, "FORWARD", false, true); - XTables::setChainPolicy(_filter, "FORWARD", "ACCEPT"); - XTables::newChain(_filter, "OUTPUT", false, true); - XTables::setChainPolicy(_filter, "OUTPUT", "ACCEPT"); - - XTables::newChain(_nat, "PREROUTING", false, true); - XTables::setChainPolicy(_nat, "PREROUTING", "ACCEPT"); - XTables::newChain(_nat, "INPUT", false, true); - XTables::setChainPolicy(_nat, "INPUT", "ACCEPT"); - XTables::newChain(_nat, "OUTPUT", false, true); - XTables::setChainPolicy(_nat, "OUTPUT", "ACCEPT"); - XTables::newChain(_nat, "POSTROUTING", false, true); - XTables::setChainPolicy(_nat, "POSTROUTING", "ACCEPT"); - - XTables::newChain(_mangle, "PREROUTING", false, true); - XTables::setChainPolicy(_mangle, "PREROUTING", "ACCEPT"); - XTables::newChain(_mangle, "INPUT", false, true); - XTables::setChainPolicy(_mangle, "INPUT", "ACCEPT"); - XTables::newChain(_mangle, "FORWARD", false, true); - XTables::setChainPolicy(_mangle, "FORWARD", "ACCEPT"); - XTables::newChain(_mangle, "OUTPUT", false, true); - XTables::setChainPolicy(_mangle, "OUTPUT", "ACCEPT"); - XTables::newChain(_mangle, "POSTROUTING", false, true); - XTables::setChainPolicy(_mangle, "POSTROUTING", "ACCEPT"); - } - - XTable& IPTables::getTableRef(Table table) - { - switch(table) { - case Table::Filter: return _filter; - case Table::NAT: return _nat; - case Table::Mangle: return _mangle; - } + newChain("filter", "INPUT", false, true); + setChainPolicy("filter", "INPUT", "ACCEPT"); + newChain("filter", "FORWARD", false, true); + setChainPolicy("filter", "FORWARD", "ACCEPT"); + newChain("filter", "OUTPUT", false, true); + setChainPolicy("filter", "OUTPUT", "ACCEPT"); + + newChain("nat", "PREROUTING", false, true); + setChainPolicy("nat", "PREROUTING", "ACCEPT"); + newChain("nat", "INPUT", false, true); + setChainPolicy("nat", "INPUT", "ACCEPT"); + newChain("nat", "OUTPUT", false, true); + setChainPolicy("nat", "OUTPUT", "ACCEPT"); + newChain("nat", "POSTROUTING", false, true); + setChainPolicy("nat", "POSTROUTING", "ACCEPT"); + + newChain("mangle", "PREROUTING", false, true); + setChainPolicy("mangle", "PREROUTING", "ACCEPT"); + newChain("mangle", "INPUT", false, true); + setChainPolicy("mangle", "INPUT", "ACCEPT"); + newChain("mangle", "FORWARD", false, true); + setChainPolicy("mangle", "FORWARD", "ACCEPT"); + newChain("mangle", "OUTPUT", false, true); + setChainPolicy("mangle", "OUTPUT", "ACCEPT"); + newChain("mangle", "POSTROUTING", false, true); + setChainPolicy("mangle", "POSTROUTING", "ACCEPT"); }
XTable& IPTables::getTableRef(const String& table) { + if (table == "security") return _security; + if (table == "raw") return _raw; if (table == "filter") return _filter; if (table == "nat") return _nat; if (table == "mangle") return _mangle; throw std::runtime_error("Unknown IPTables table name"); }
- int IPTables::listTables(StringVector &tables) const - { - tables = { "filter", "nat", "mangle" }; - return 0; - } - - int IPTables::appendRule(Table table, const String& chain, const String& rule_spec, int rule_priority) - { - return XTables::appendRule(getTableRef(table), chain, rule_spec, rule_priority); - } - - int IPTables::appendRule(const String& table, const String& chain, const String& rule_spec, int rule_priority) - { - return XTables::appendRule(getTableRef(table), chain, rule_spec, rule_priority); - } - - int IPTables::deleteRule(const String& table, const String& chain, const String& rule_spec, int rule_priority) - { - return XTables::deleteRule(getTableRef(table), chain, rule_spec, rule_priority); - } - - bool IPTables::ruleExists(const String& table, const String& chain, const String& rule_spec, int rule_priority) - { - return XTables::ruleExists(getTableRef(table), chain, rule_spec, rule_priority); - } - - int IPTables::insertRule(const String& table, const String& chain, const String& rule_spec, int rule_priority) - { - return XTables::insertRule(getTableRef(table), chain, rule_spec, rule_priority); - } - - int IPTables::listRules(const String& table, const String& chain, StringVectorMap<int>& rule_specs) - { - return XTables::listRules(getTableRef(table), chain, rule_specs); - } - - int IPTables::newChain(const String& table, const String& chain, bool user_defined) - { - return XTables::newChain(getTableRef(table), chain, user_defined); - } - - int IPTables::setChainPolicy(const String& table, const String& chain, const String& policy) - { - return XTables::setChainPolicy(getTableRef(table), chain, policy); - } - - int IPTables::renameChain(const String& table, const String& old_chain_name, const String& new_chain_name) - { - return XTables::renameChain(getTableRef(table), old_chain_name, new_chain_name); - } - - int IPTables::deleteChain(const String& table, const String& chain) - { - return XTables::deleteChain(getTableRef(table), chain); - } - - int IPTables::listChains(const String& table, StringVector& chains) - { - return XTables::listChains(getTableRef(table), chains); - } - - bool IPTables::chainExists(const String& table, const String& chain) - { - return XTables::chainExists(getTableRef(table), chain); - } - - int IPTables::passthrough(const String& table, const String& direct_specification) + const StringVector IPTables::listTables() const { - return XTables::direct(getTableRef(table), direct_specification); + StringVector tables({"security", "raw", "nat", "mangle", "filter"}); + return tables; }
int IPTables::execute(const XTables::Operation& op) @@ -239,8 +169,8 @@ namespace firewalld
int IPTables::execute(const StringVector& args) { -#ifdef UNITTEST LOG(DEBUG) << _ipXtables_path << " " << args; +#ifdef UNITTEST return 0; #else return runCommand(_ipXtables_path, args); diff --git a/src/Daemon/Backends/Linux/IPTables.hpp b/src/Daemon/Backends/Linux/IPTables.hpp index 16263e6..81b0881 100644 --- a/src/Daemon/Backends/Linux/IPTables.hpp +++ b/src/Daemon/Backends/Linux/IPTables.hpp @@ -34,42 +34,23 @@ namespace firewalld class IPTables : public XTables { public: - enum class Table { - Filter, - NAT, - Mangle - }; - IPTables(const char * const ipXtables_path);
- int listTables(StringVector& tables) const; - - int appendRule(Table table, const String& chain, const String& rule_spec, int rule_priority); - int appendRule(const String& table, const String& chain, const String& rule_spec, int rule_priority); - int deleteRule(const String& table, const String& chain, const String& rule_spec, int rule_priority); - bool ruleExists(const String& table, const String& chain, const String& rule_spec, int rule_priority); - int insertRule(const String& table, const String& chain, const String& rule_spec, int rule_priority); - int listRules(const String& table, const String& chain, StringVectorMap<int>& rule_specs); - - int newChain(const String& table, const String& chain, bool user_defined = true); - int setChainPolicy(const String& table, const String& chain, const String& policy); - int renameChain(const String& table, const String& old_chain_name, const String& new_chain_name); - int deleteChain(const String& table, const String& chain); - int listChains(const String& table, StringVector& chains); - bool chainExists(const String& table, const String& chain); - int passthrough(const String& table, const String& direct_specification); + const StringVector listTables() const;
protected: - XTable& getTableRef(Table table); XTable& getTableRef(const String& table); int execute(const XTables::Operation& op); int execute(const StringVector& args);
private: const char * const _ipXtables_path; - XTable _filter; - XTable _nat; + + XTable _security; + XTable _raw; XTable _mangle; + XTable _nat; + XTable _filter; };
class IP4Tables : public IPTables diff --git a/src/Daemon/Backends/Linux/XTables.hpp b/src/Daemon/Backends/Linux/XTables.hpp index 62ff2f1..6994300 100644 --- a/src/Daemon/Backends/Linux/XTables.hpp +++ b/src/Daemon/Backends/Linux/XTables.hpp @@ -38,14 +38,16 @@ namespace firewalld void deleteRule(const String& chain, const String& rule_spec, int rule_priority); bool ruleExists(const String& name, const String& rule_spec, int rule_priority); void insertRule(const String& chain, const String& rule_spec, int rule_priority); - //void replaceRule(const String& chain, int old_rule_num, const String& rule_spec); void listRules(const String& chain, StringVectorMap<int>& rules); + void newChain(const String& chain, bool user_defined = true); void setChainPolicy(const String& chain, const String& policy); void renameChain(const String& old_chain_name, const String& new_chain_name); + void flushChain(const String& name); void deleteChain(const String& name); void listChains(StringVector& chains); bool chainExists(const String& chain); + void addDirect(const String& direct_specification);
private: @@ -139,10 +141,11 @@ namespace firewalld Glib::Threads::Mutex::Lock _lock; };
- virtual int listTables(StringVector& tables) const = 0; + virtual const StringVector listTables() const = 0;
- virtual int appendRule(XTable& table, const String& chain, const String& rule_spec, int rule_priority) + int appendRule(const String& table_name, const String& chain, const String& rule_spec, int rule_priority) { + XTable& table = getTableRef(table_name); Operation op(table, chain, Command::Append, rule_spec, rule_priority); int return_code = execute(op); if (return_code == 0) { @@ -151,14 +154,16 @@ namespace firewalld return return_code; }
- virtual int checkRule(XTable& table, const String& chain, const String& rule_spec) + int checkRule(const String& table_name, const String& chain, const String& rule_spec) { + XTable& table = getTableRef(table_name); Operation op(table, chain, Command::Check, rule_spec); return execute(op); }
- virtual int deleteRule(XTable& table, const String& chain, const String& rule_spec, int rule_priority) + int deleteRule(const String& table_name, const String& chain, const String& rule_spec, int rule_priority) { + XTable& table = getTableRef(table_name); Operation op(table, chain, Command::Delete, rule_spec, rule_priority); int return_code = execute(op); if (return_code == 0) { @@ -167,14 +172,16 @@ namespace firewalld return return_code; }
- virtual bool ruleExists(XTable& table, const String& chain, const String& rule_spec, int rule_priority) + bool ruleExists(const String& table_name, const String& chain, const String& rule_spec, int rule_priority) { + XTable& table = getTableRef(table_name); Operation op(table, chain, Command::ListRules, rule_spec, rule_priority); return table.ruleExists(chain, rule_spec, rule_priority); }
- virtual int insertRule(XTable& table, const String& chain, const String& rule_spec, int rule_priority) + int insertRule(const String& table_name, const String& chain, const String& rule_spec, int rule_priority) { + XTable& table = getTableRef(table_name); Operation op(table, chain, Command::Insert, rule_spec, rule_priority); int return_code = execute(op); if (return_code == 0) { @@ -183,15 +190,17 @@ namespace firewalld return return_code; }
- virtual int listRules(XTable& table, const String& chain, StringVectorMap<int>& rule_specs) + int listRules(const String& table_name, const String& chain, StringVectorMap<int>& rule_specs) { + XTable& table = getTableRef(table_name); Operation op(table, chain, Command::ListRules); table.listRules(chain, rule_specs); return 0; }
- virtual int newChain(XTable& table, const String& chain, bool user_defined = true, bool builtin = false) + int newChain(const String& table_name, const String& chain, bool user_defined = true, bool builtin = false) { + XTable& table = getTableRef(table_name); Operation op(table, chain, Command::New); int return_code; if (!builtin) { @@ -206,8 +215,9 @@ namespace firewalld return return_code; }
- virtual int setChainPolicy(XTable& table, const String& chain, const String& policy) + int setChainPolicy(const String& table_name, const String& chain, const String& policy) { + XTable& table = getTableRef(table_name); Operation op(table, chain, Command::SetPolicy, policy); int return_code = execute(op); if (return_code == 0) { @@ -216,8 +226,9 @@ namespace firewalld return return_code; }
- virtual int renameChain(XTable& table, const String& old_chain_name, const String& new_chain_name) + int renameChain(const String& table_name, const String& old_chain_name, const String& new_chain_name) { + XTable& table = getTableRef(table_name); Operation op(table, old_chain_name, Command::Rename, new_chain_name); int return_code = execute(op); if (return_code == 0) { @@ -226,8 +237,9 @@ namespace firewalld return return_code; }
- virtual int deleteChain(XTable& table, const String& chain) + int deleteChain(const String& table_name, const String& chain) { + XTable& table = getTableRef(table_name); Operation op(table, chain, Command::Delete); int return_code = execute(op); if (return_code == 0) { @@ -236,21 +248,32 @@ namespace firewalld return return_code; }
- virtual int listChains(XTable& table, StringVector& chains) + int listChains(const String& table_name, StringVector& chains) { + XTable& table = getTableRef(table_name); Operation op(table, Command::ListChains); table.listChains(chains); return 0; }
- virtual int chainExists(XTable& table, const String& chain) + StringVector listChains(const String& table_name) + { + XTable& table = getTableRef(table_name); + StringVector chains; + table.listChains(chains); + return std::move(chains); + } + + int chainExists(const String& table_name, const String& chain) { + XTable& table = getTableRef(table_name); Operation op(table, Command::ListChains); return table.chainExists(chain); }
- virtual int direct(XTable& table, const String& args) + int direct(const String& table_name, const String& args) { + XTable& table = getTableRef(table_name); Operation op(table, Command::Direct, args); int return_code = execute(op); if (return_code == 0) { @@ -262,6 +285,7 @@ namespace firewalld protected: virtual int execute(const Operation& op) = 0; virtual int execute(const StringVector& args) = 0; + virtual XTable& getTableRef(const String& table) = 0; };
} /* namespace firewalld */ diff --git a/src/Daemon/Backends/LinuxXTables.cpp b/src/Daemon/Backends/LinuxXTables.cpp new file mode 100644 index 0000000..782172f --- /dev/null +++ b/src/Daemon/Backends/LinuxXTables.cpp @@ -0,0 +1,255 @@ +#include "LinuxXTables.hpp" +#include "Common/Types.hpp" +#include "Common/Logging.hpp" + +namespace firewalld +{ + LinuxXTables::LinuxXTables() + : Backend("LinuxXTables"), + _ip4tables(FIREWALLD_IP4TABLES_PATH), + _ip6tables(FIREWALLD_IP6TABLES_PATH) + { + initDefaultChains(); + + registerOperationHandler("ZONE", &LinuxXTables::opZone); + registerOperationHandler("ZONE_INTERFACE", &LinuxXTables::opZoneInterface); + registerOperationHandler("ZONE_PORT", &LinuxXTables::opZonePort); + registerOperationHandler("ZONE_PORT_FORWARD", &LinuxXTables::opZonePortForward); + registerOperationHandler("ZONE_ICMP_BLOCK", &LinuxXTables::opZoneICMPBlock); + registerOperationHandler("ZONE_MASQUERADE", &LinuxXTables::opZoneMasquerade); + registerOperationHandler("LOAD_HELPER", &LinuxXTables::opLoadHelper); + } + + void LinuxXTables::initDefaultChains() + { + for (IPTables * const ipXtables : { &_ip4tables, &_ip6tables }) { + String icmp, reject; + + if (ipXtables == &_ip4tables) { + icmp = "icmp"; + reject = "REJECT --reject-with icmp-host-prohibited"; + } else { + icmp = "ipv6-icmp"; + reject = "REJECT --reject-with icmp6-adm-prohibited"; + } + + // + // Initialize _direct chains + // + // <CHAIN>_direct chains are used for rules added via the + // direct interface. If a built-in chain named `CHAIN` is + // used, it is replaced with `CHAIN_direct` before executing + // the requested {ip,ip6,eb}tables command. + // + for (const String& table : ipXtables->listTables()) { + for (const String& chain : ipXtables->listChains(table)) { + ipXtables->newChain(table, chain + "_direct"); + ipXtables->appendRule(table, chain, "-j " + chain + "_direct", 0); + } + } + + // + // Initialize -t filter chains + // + ipXtables->newChain("filter", "INPUT_ZONES"); + ipXtables->newChain("filter", "INPUT_ZONES_SOURCE"); + + ipXtables->insertRule("filter", "INPUT", "-m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT", 1); + ipXtables->insertRule("filter", "INPUT", "-i lo -j ACCEPT", 3); + ipXtables->insertRule("filter", "INPUT", "-j INPUT_ZONES_SOURCE", 4); + ipXtables->insertRule("filter", "INPUT", "-j INPUT_ZONES", 5); + ipXtables->insertRule("filter", "INPUT", "-p " + icmp + " -j ACCEPT", 6); + ipXtables->insertRule("filter", "INPUT", "-j " + reject, 7); + + ipXtables->newChain("filter", "FORWARD_IN_ZONES"); + ipXtables->newChain("filter", "FORWARD_IN_ZONES_SOURCE"); + ipXtables->newChain("filter", "FORWARD_OUT_ZONES"); + ipXtables->newChain("filter", "FORWARD_OUT_ZONES_SOURCE"); + + ipXtables->insertRule("filter", "FORWARD", "-m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT", 1); + ipXtables->insertRule("filter", "FORWARD", "-i lo -j ACCEPT", 3); + ipXtables->insertRule("filter", "FORWARD", "-j FORWARD_IN_ZONES_SOURCE", 4); + ipXtables->insertRule("filter", "FORWARD", "-j FORWARD_IN_ZONES", 5); + ipXtables->insertRule("filter", "FORWARD", "-j FORWARD_OUT_ZONES_SOURCE", 6); + ipXtables->insertRule("filter", "FORWARD", "-j FORWARD_OUT_ZONES", 7); + ipXtables->insertRule("filter", "FORWARD", "-p " + icmp + " -j ACCEPT", 8); + ipXtables->insertRule("filter", "FORWARD", "-j " + reject, 9); + + // + // Initialize -t mangle chains + // + ipXtables->newChain("mangle", "PREROUTING_ZONES"); + ipXtables->newChain("mangle", "PREROUTING_ZONES_SOURCE"); + + ipXtables->insertRule("mangle", "PREROUTING", "-j PREROUTING_ZONES_SOURCE", 1); + ipXtables->insertRule("mangle", "PREROUTING", "-j PREROUTING_ZONES", 2); + + // + // Initialize -t nat chains + // + + } + } + + void LinuxXTables::cleanup() + { + } + + void LinuxXTables::processOperation(const UStringVector& op, bool undo) + { + if (op.size() < 1) { + /* NOOP */ + return; + } + + auto op_handler = operationHandler(op.front()); + + if (op_handler) { + VLOG(4) << "OP: " << (undo ? "-" : "+") << op; + (*this.*op_handler)(op, undo); + } + + return; + } + + void LinuxXTables::opZone(const UStringVector& op, bool undo) + { + String zone_name = op[1]; + + // XXX: Do we trust the input values? + + for (IPTables * const ipXtables : { &_ip4tables, &_ip6tables }) { + for (const String& prefix : { "IN_", "FWDI_", "FWDO_" }) { + for (const String& suffix : { "", "_allow", "_deny", "_log" }) { + if (!undo) { + ipXtables->newChain("filter", prefix + zone_name + suffix); + } else { + ipXtables->deleteChain("filter", prefix + zone_name + suffix); + } + } + } + + if (!undo) { + for (const String& prefix : { "IN_", "FWDI_", "FWDO_" }) { + for (const String& suffix : { "_log", "_deny", "_allow" }) { + ipXtables->appendRule("filter", prefix + zone_name, "-j " + prefix + zone_name + suffix, 0); + } + } + } + + for (const String& prefix : { "PRE_" }) { + for (const String& suffix : { "", "_allow", "_deny", "_log" }) { + if (!undo) { + ipXtables->newChain("mangle", prefix + zone_name + suffix); + } else { + ipXtables->deleteChain("mangle", prefix + zone_name + suffix); + } + } + } + + if (!undo) { + for (const String& prefix : { "PRE_" }) { + for (const String& suffix : { "_log", "_deny", "_allow" }) { + ipXtables->appendRule("mangle", prefix + zone_name, "-j " + prefix + zone_name + suffix, 0); + } + } + } + } + + return; + } + + void LinuxXTables::opZoneInterface(const UStringVector& op, bool undo) + { + String zone_name = op[1]; + String interface = op[2]; + + for (IPTables * const ipXtables : { &_ip4tables, &_ip6tables }) { + if (!undo) { + ipXtables->appendRule("filter", "INPUT_ZONES", "-i " + interface + " -g IN_" + zone_name, 0); + ipXtables->appendRule("filter", "FORWARD_IN_ZONES", "-i " + interface + " -g FWDI_" + zone_name, 0); + ipXtables->appendRule("filter", "FORWARD_OUT_ZONES", "-o " + interface + " -g FWDO_" + zone_name, 0); + } else { + ipXtables->deleteRule("filter", "INPUT_ZONES", "-i " + interface + " -g IN_" + zone_name, 0); + ipXtables->deleteRule("filter", "FORWARD_IN_ZONES", "-i " + interface + " -g FWDI_" + zone_name, 0); + ipXtables->deleteRule("filter", "FORWARD_OUT_ZONES", "-o " + interface + " -g FWDO_" + zone_name, 0); + } + } + + return; + } + + void LinuxXTables::opZonePort(const UStringVector& op, bool undo) + { + String zone_name = op[1]; + String protocol = op[2]; + String port_from = op[3]; + String port_to; + + if (op.size() == 5) { + port_to = op[4]; + } else { + port_to = op[3]; + } + + String rule_spec; + + if (protocol == "tcp") { + rule_spec = "-p tcp -m tcp --dport "; + } + else if (protocol == "udp") { + rule_spec = "-p udp -m udp --dport "; + } + + rule_spec += port_from + (port_from != port_to ? ":" + port_to : ""); + rule_spec += " -m conntrack --ctstate NEW -j ACCEPT"; + + for (IPTables * const ipXtables : { &_ip4tables, &_ip6tables }) { + if (!undo) { + ipXtables->appendRule("filter", "IN_" + zone_name + "_allow", rule_spec, 0); + } else { + ipXtables->deleteRule("filter", "IN_" + zone_name + "_allow", rule_spec, 0); + } + } + + return; + } + + void LinuxXTables::opZonePortForward(const UStringVector& op, bool undo) + { + } + + void LinuxXTables::opZoneICMPBlock(const UStringVector& op, bool undo) + { + String zone_name = op[1]; + String icmptype = op[2]; + String protocol = op[3]; + String rule_spec; + IPTables * ipXtables; + + if (protocol == "ipv4") { + rule_spec = "-p icmp -m icmp --icmp-type " + icmptype; + rule_spec += " -j REJECT --reject-with icmp-host-prohibited"; + ipXtables = &_ip4tables; + } + else if (protocol == "ipv6") { + rule_spec = "-p ipv6-icmp -m icmp6 --icmpv6-type " + icmptype; + rule_spec += " -j REJECT --reject-with icmp6-adm-prohibited"; + ipXtables = &_ip6tables; + } + + ipXtables->appendRule("filter", "IN_" + zone_name + "_deny", rule_spec, 0); + ipXtables->appendRule("filter", "FWDI_" + zone_name + "_deny", rule_spec, 0); + + return; + } + + void LinuxXTables::opZoneMasquerade(const UStringVector& op, bool undo) + { + } + + void LinuxXTables::opLoadHelper(const UStringVector& op, bool undo) + { + } + +} /* namespace firewalld */ diff --git a/src/Daemon/Backends/LinuxXTables.hpp b/src/Daemon/Backends/LinuxXTables.hpp new file mode 100644 index 0000000..4abc9ab --- /dev/null +++ b/src/Daemon/Backends/LinuxXTables.hpp @@ -0,0 +1,38 @@ +#ifndef FIREWALLD_BACKENDS_LINUXXTABLES_HPP +#define FIREWALLD_BACKENDS_LINUXXTABLES_HPP + +#include "Daemon/Backends/Linux/IPTables.hpp" +#include "Daemon/Backends/Linux/EBTables.hpp" + +#include "Daemon/Firewall/Backend.hpp" +#include "Daemon/Firewall/BackendOpTable.hpp" + +namespace firewalld +{ + class LinuxXTables : public Backend, private BackendOpTable<LinuxXTables> + { + public: + LinuxXTables(); + + protected: + void processOperation(const UStringVector& op, bool undo = false); + + void initDefaultChains(); + void cleanup(); + + void opZone(const UStringVector& op, bool undo); + void opZoneInterface(const UStringVector& op, bool undo); + void opZonePort(const UStringVector& op, bool undo); + void opZonePortForward(const UStringVector& op, bool undo); + void opZoneICMPBlock(const UStringVector& op, bool undo); + void opZoneMasquerade(const UStringVector& op, bool undo); + void opLoadHelper(const UStringVector& op, bool undo); + + private: + IPTables _ip4tables; + IPTables _ip6tables; + EBTables _ebtables; + }; +} /* namespace firewalld */ + +#endif /* FIREWALLD_BACKENDS_LINUXXTABLES_HPP */ diff --git a/src/Daemon/Firewall/Backend.cpp b/src/Daemon/Firewall/Backend.cpp index cab311e..0ece111 100644 --- a/src/Daemon/Firewall/Backend.cpp +++ b/src/Daemon/Firewall/Backend.cpp @@ -25,11 +25,21 @@
namespace firewalld { - Backend::Backend() + Backend::Backend(const UString& identifier) { + _identifier = identifier; _transaction_counter = 0; }
+ Backend::~Backend() + { + } + + const UString& Backend::identifier() const + { + return _identifier; + } + Pointer<Transaction> Backend::createTransaction() { std::lock_guardstd::mutex backend_lock(_backend_mutex); diff --git a/src/Daemon/Firewall/Backend.hpp b/src/Daemon/Firewall/Backend.hpp index 109520a..d227733 100644 --- a/src/Daemon/Firewall/Backend.hpp +++ b/src/Daemon/Firewall/Backend.hpp @@ -30,18 +30,22 @@ namespace firewalld class Backend { public: - Backend(); - virtual const UString& identifier() const = 0; + Backend(const UString& identifier); + virtual ~Backend(); + + const UString& identifier() const; + Pointer<Transaction> createTransaction(); void commitTransaction(Pointer<Transaction> transaction); void removeTransaction(const String& identifier); size_t countTransactions() const;
protected: - virtual void processOperation(const UStringList& op, bool undo = false) = 0; + virtual void processOperation(const UStringVector& op, bool undo = false) = 0; void removeTransactionUnlocked(const String& identifier);
private: + UString _identifier; PointerVector<Transaction> _transactions; mutable std::mutex _backend_mutex; uint64_t _transaction_counter; diff --git a/src/Daemon/Firewall/BackendOpTable.hpp b/src/Daemon/Firewall/BackendOpTable.hpp new file mode 100644 index 0000000..97bb6a8 --- /dev/null +++ b/src/Daemon/Firewall/BackendOpTable.hpp @@ -0,0 +1,30 @@ +#ifndef FIREWALLD_FIREWALL_BACKENDOPTABLE_HPP +#define FIREWALLD_FIREWALL_BACKENDOPTABLE_HPP + +#include "Common/Types.hpp" + +namespace firewalld +{ + template<class C> + class BackendOpTable + { + public: + typedef void(C::*OpMethodPointer)(const UStringVector&, bool); + + void registerOperationHandler(const UString& name, OpMethodPointer method_pointer) + { + _op_method_table[name] = method_pointer; + } + + OpMethodPointer operationHandler(const UString& name) const + { + return MapOp::findOne(_op_method_table, name); + } + + private: + typedef std::map<UString, OpMethodPointer> OpMethodTable; + OpMethodTable _op_method_table; + }; +} + +#endif /* FIREWALLD_FIREWALL_BACKENDOPTABLE_HPP */ diff --git a/src/Daemon/Firewall/Firewall.cpp b/src/Daemon/Firewall/Firewall.cpp index fa626c1..18a2c35 100644 --- a/src/Daemon/Firewall/Firewall.cpp +++ b/src/Daemon/Firewall/Firewall.cpp @@ -18,44 +18,37 @@ // #include "Daemon/FirewallD.hpp" #include "Daemon/Firewall/Firewall.hpp" +#include "Daemon/Firewall/Backend.hpp" +#include "Daemon/Backends/LinuxXTables.hpp" #include "Common/Types.hpp"
namespace firewalld { - Firewall::Firewall() { - // Insert the default zones - addZoneName("block"); - addZoneName("home"); - addZoneName("public"); - addZoneName("work"); - addZoneName("trusted"); - addZoneName("drop"); - // Initialize the default zone name - _default_zone = "public"; - - addInterfaceToZone("public", "eth0"); + _backend = new LinuxXTables(); }
bool Firewall::directIPv4getTables(StringVector& tables) { - return (_ip4tables.listTables(tables) == 0); + tables = _ip4tables.listTables(); + return true; }
bool Firewall::directIPv6getTables(StringVector& tables) { - return (_ip6tables.listTables(tables) == 0); + tables = _ip6tables.listTables(); + return true; }
bool Firewall::directIPv4Passthrough(const String& direct_specification) { - return (_ip4tables.passthrough("filter", direct_specification) == 0); + return (_ip4tables.direct("filter", direct_specification) == 0); }
bool Firewall::directIPv6Passthrough(const String& direct_specification) { - return (_ip6tables.passthrough("filter", direct_specification) == 0); + return (_ip6tables.direct("filter", direct_specification) == 0); }
bool Firewall::directIPv4AddChain(const String& table, const String& chain) diff --git a/src/Daemon/Firewall/Firewall.hpp b/src/Daemon/Firewall/Firewall.hpp index 3a4ab5d..7fa1115 100644 --- a/src/Daemon/Firewall/Firewall.hpp +++ b/src/Daemon/Firewall/Firewall.hpp @@ -20,11 +20,13 @@ #define _FIREWALL_H_
#include "Common/Types.hpp" -#include "Daemon/Backends/Linux/IPTables.hpp" -#include "Daemon/Backends/Linux/EBTables.hpp" #include "Daemon/Firewall/Zone.hpp" #include "Daemon/Firewall/Service.hpp" #include "Daemon/Firewall/ICMPType.hpp" +#include "Daemon/Firewall/Backend.hpp" + +#include "Daemon/Backends/Linux/IPTables.hpp" +#include "Daemon/Backends/Linux/EBTables.hpp"
#include <glibmm.h> #include <giomm.h> @@ -33,7 +35,6 @@
namespace firewalld { - class Firewall { public: @@ -95,6 +96,8 @@ namespace firewalld UString _default_zone; PointerMap<UString,Zone> _zone_map;
+ Backend *_backend; + IP4Tables _ip4tables; IP6Tables _ip6tables; EBTables _ebtables; diff --git a/src/Daemon/Firewall/Transaction.cpp b/src/Daemon/Firewall/Transaction.cpp index b9f59f4..73be1d2 100644 --- a/src/Daemon/Firewall/Transaction.cpp +++ b/src/Daemon/Firewall/Transaction.cpp @@ -32,7 +32,7 @@ namespace firewalld return _identifier; }
- const UStringList& Transaction::operation(size_t index) const + const UStringVector& Transaction::operation(size_t index) const { return _operations.at(index); } @@ -42,7 +42,7 @@ namespace firewalld return _operations.size(); }
- size_t Transaction::appendOperation(const UStringList& op) + size_t Transaction::appendOperation(const UStringVector& op) { _operations.push_back(op); return (_operations.size() - 1); diff --git a/src/Daemon/Firewall/Transaction.hpp b/src/Daemon/Firewall/Transaction.hpp index 5b23a48..07b49fb 100644 --- a/src/Daemon/Firewall/Transaction.hpp +++ b/src/Daemon/Firewall/Transaction.hpp @@ -33,17 +33,17 @@ namespace firewalld
const String& identifier() const;
- const UStringList& operation(size_t index) const; + const UStringVector& operation(size_t index) const; size_t countOperations() const;
- size_t appendOperation(const UStringList& op); + size_t appendOperation(const UStringVector& op); void removeOperation(size_t index);
bool operator==(const Transaction& rhs) const;
private: String _identifier; - std::vector<UStringList> _operations; + std::vector<UStringVector> _operations; };
class TransactionError : public std::runtime_error diff --git a/tests/iptables/test_iptables.cpp b/tests/iptables/test_iptables.cpp index e79ef12..99d6610 100644 --- a/tests/iptables/test_iptables.cpp +++ b/tests/iptables/test_iptables.cpp @@ -29,7 +29,7 @@ int main(int argc, char *argv[]) IP4Tables iptables; IP6Tables ip6tables;
- iptables.appendRule(IP4Tables::Table::Filter, "INPUT", "-s 127.0.0.1 -j DROP", 1); + iptables.appendRule("filter", "INPUT", "-s 127.0.0.1 -j DROP", 1); iptables.appendRule("filter", "INPUT", "-s 127.0.0.1 -j DROP", 1); iptables.deleteRule("filter", "INPUT", "-s 127.0.0.1 -j DROP", 1); iptables.insertRule("filter", "INPUT", "-s 127.0.0.2 -j DROP", 1); @@ -37,7 +37,7 @@ int main(int argc, char *argv[]) iptables.setChainPolicy("filter", "FOOchain", "RETURN"); iptables.renameChain("filter", "FOOchain", "BARchain"); iptables.deleteChain("filter", "BARchain"); - iptables.passthrough("filter", "-A OUTPUT -d 1.2.3.4 -j RETURN"); + iptables.direct("filter", "-A OUTPUT -d 1.2.3.4 -j RETURN");
return 0; }