aboutsummaryrefslogtreecommitdiff
path: root/src/wg2sd.cpp
diff options
context:
space:
mode:
authorflu0r1ne <flu0r1ne@flu0r1ne.net>2023-08-18 01:13:07 -0500
committerflu0r1ne <flu0r1ne@flu0r1ne.net>2023-08-18 01:13:07 -0500
commit2f0a9c87bd5acd8fc0852f599599d031cde44bbe (patch)
treec4adb81a041d3cb7428c7c11c9cf8d88751b9160 /src/wg2sd.cpp
parentd6e19ce0a112bd2403ad0cb274808ce3e749b459 (diff)
downloadwg2nd-2f0a9c87bd5acd8fc0852f599599d031cde44bbe.tar.xz
wg2nd-2f0a9c87bd5acd8fc0852f599599d031cde44bbe.zip
Add firewall rule generator
Diffstat (limited to 'src/wg2sd.cpp')
-rw-r--r--src/wg2sd.cpp63
1 files changed, 62 insertions, 1 deletions
diff --git a/src/wg2sd.cpp b/src/wg2sd.cpp
index 2087cf5..4c39a03 100644
--- a/src/wg2sd.cpp
+++ b/src/wg2sd.cpp
@@ -6,6 +6,7 @@
#include <regex>
#include <argon2.h>
+#include <string_view>
std::string hashed_keyfile_name(std::string const & priv_key) {
constexpr uint8_t const SALT[] = {
@@ -70,6 +71,16 @@ namespace wg2sd {
return std::regex_match(cidr, ipv4);
}
+ std::string_view _get_addr(std::string_view const & cidr) {
+ size_t suffix = cidr.rfind('/');
+
+ if(suffix == std::string::npos) {
+ return cidr;
+ } else {
+ return cidr.substr(0, suffix);
+ }
+ }
+
constexpr uint32_t MAIN_TABLE = 254;
constexpr uint32_t LOCAL_TABLE = 255;
@@ -292,6 +303,55 @@ namespace wg2sd {
return cfg;
}
+ static void _write_table(std::stringstream & firewall, Config const & cfg, std::vector<std::string_view> addrs, bool ipv4) {
+ char const * ip = ipv4 ? "ip" : "ip6";
+
+ firewall << "table " << ip << " " << cfg.intf.name << " {\n"
+ << " chain preraw {\n"
+ << " type filter hook prerouting priority raw; policy accept;\n";
+
+ for(std::string_view const & addr : addrs) {
+ firewall << " iifname != \"" << cfg.intf.name << "\" " << ip << " daddr " << addr << " fib saddr type != local drop;\n";
+ }
+
+ firewall << " }\n"
+ << "\n"
+ << " chain premangle {\n"
+ << " type filter hook prerouting priority mangle; policy accept;\n"
+ << " meta l4proto udp meta mark set ct mark;\n"
+ << " }\n"
+ << "\n"
+ << " chain postmangle {\n"
+ << " type filter hook postrouting priority mangle; policy accept;\n"
+ << " meta l4proto udp meta mark " << std::hex << cfg.intf.table << std::dec << "ct mark set meta mark;\n"
+ << " }\n"
+ << "}\n";
+
+ }
+
+ std::string _gen_nftables_firewall(Config const & cfg) {
+ std::stringstream firewall;
+
+ std::vector<std::string_view> ipv4_addrs;
+ std::vector<std::string_view> ipv6_addrs;
+
+ for(std::string const & addr : cfg.intf.addresses) {
+ if(_is_ipv4_route(addr)) {
+ ipv4_addrs.push_back(_get_addr(addr));
+ } else {
+ ipv6_addrs.push_back(_get_addr(addr));
+ }
+ }
+
+ _write_table(firewall, cfg, ipv4_addrs, true);
+
+ firewall << "\n";
+
+ _write_table(firewall, cfg, ipv6_addrs, false);
+
+ return firewall.str();
+ }
+
static std::string _gen_netdev_cfg(Config const & cfg, uint32_t fwd_table, std::string const & private_keyfile,
std::vector<SystemdFilespec> & symmetric_keyfiles, std::string const & output_path) {
std::stringstream netdev;
@@ -526,7 +586,8 @@ if(!cfg.intf.field_.empty()) { \
.contents = cfg.intf.private_key + "\n",
},
.symmetric_keyfiles = std::move(symmetric_keyfiles),
- .warnings = std::move(warnings)
+ .warnings = std::move(warnings),
+ .firewall = _gen_nftables_firewall(cfg),
};
}