summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--talpid-core/src/firewall/linux.rs38
1 files changed, 38 insertions, 0 deletions
diff --git a/talpid-core/src/firewall/linux.rs b/talpid-core/src/firewall/linux.rs
index 4fcbdb7a61..a734e0aa2e 100644
--- a/talpid-core/src/firewall/linux.rs
+++ b/talpid-core/src/firewall/linux.rs
@@ -67,6 +67,7 @@ const FORWARD_CHAIN_NAME: &CStr = c"forward";
const PREROUTING_CHAIN_NAME: &CStr = c"prerouting";
const MANGLE_CHAIN_NAME: &CStr = c"mangle";
const NAT_CHAIN_NAME: &CStr = c"nat";
+const SRCNAT_CHAIN_NAME: &CStr = c"srcnat";
/// Allows controlling whether firewall rules should have packet counters or not from an env
/// variable. Useful for debugging the rules.
@@ -269,6 +270,7 @@ struct PolicyBatch<'a> {
prerouting_chain: Chain<'a>,
mangle_chain: Chain<'a>,
nat_chain: Chain<'a>,
+ srcnat_chain: Chain<'a>,
}
impl<'a> PolicyBatch<'a> {
@@ -314,6 +316,12 @@ impl<'a> PolicyBatch<'a> {
nat_chain.set_policy(nftnl::Policy::Accept);
batch.add(&nat_chain, nftnl::MsgType::Add);
+ let mut srcnat_chain = Chain::new(SRCNAT_CHAIN_NAME, table);
+ srcnat_chain.set_type(nftnl::ChainType::Nat);
+ srcnat_chain.set_hook(nftnl::Hook::PostRouting, libc::NF_IP_PRI_NAT_SRC);
+ srcnat_chain.set_policy(nftnl::Policy::Accept);
+ batch.add(&srcnat_chain, nftnl::MsgType::Add);
+
PolicyBatch {
batch,
in_chain,
@@ -322,6 +330,7 @@ impl<'a> PolicyBatch<'a> {
prerouting_chain,
mangle_chain,
nat_chain,
+ srcnat_chain,
}
}
@@ -333,6 +342,8 @@ impl<'a> PolicyBatch<'a> {
firewall: &Firewall,
) -> Result<FinalizedBatch> {
self.add_loopback_rules()?;
+ // TODO: if router { .. }
+ self.add_local_clients_forwaring_rules()?;
// TODO: Investigate if these rules could/should be handled by PidManager instead.
// It would allow for the firewall to be set up in a secure way even though split tunneling
// does not work, which is okay. It would also allow us to de-duplicate some copy-paste
@@ -507,6 +518,33 @@ impl<'a> PolicyBatch<'a> {
Ok(())
}
+ /// TODO: Don't forget sysctl net.ipv4.forwarding ..
+ fn add_local_clients_forwaring_rules(&mut self) -> Result<()> {
+ // Forward traffic stemming from (local) private IP ranges to wherever they want.
+ // TODO: Make sure to document this in nft if we ever add comment expressions..
+ // LAN -> forward
+ for net in ALLOWED_LAN_NETS {
+ let mut forward_from_local_clients = Rule::new(&self.forward_chain);
+ check_net(&mut forward_from_local_clients, End::Src, net);
+ add_verdict(&mut forward_from_local_clients, &Verdict::Accept);
+ if *ADD_COUNTERS {
+ forward_from_local_clients.add_expr(&nft_expr!(counter));
+ };
+ self.batch
+ .add(&forward_from_local_clients, nftnl::MsgType::Add);
+
+ // Src Nat
+ let mut srcnat_rule = Rule::new(&self.srcnat_chain);
+ check_net(&mut srcnat_rule, End::Src, net);
+ srcnat_rule.add_expr(&nft_expr!(masquerade));
+ if *ADD_COUNTERS {
+ srcnat_rule.add_expr(&nft_expr!(counter));
+ };
+ self.batch.add(&srcnat_rule, nftnl::MsgType::Add);
+ }
+ Ok(())
+ }
+
fn add_dhcp_client_rules(&mut self) {
use self::TransportProtocol::Udp;
// Outgoing DHCPv4 request