Skip to content

Commit c4267de

Browse files
Add rules for forwarding traffic from local clients
1 parent 3627b34 commit c4267de

File tree

1 file changed

+38
-0
lines changed

1 file changed

+38
-0
lines changed

talpid-core/src/firewall/linux.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ const FORWARD_CHAIN_NAME: &CStr = c"forward";
6767
const PREROUTING_CHAIN_NAME: &CStr = c"prerouting";
6868
const MANGLE_CHAIN_NAME: &CStr = c"mangle";
6969
const NAT_CHAIN_NAME: &CStr = c"nat";
70+
const SRCNAT_CHAIN_NAME: &CStr = c"srcnat";
7071

7172
/// Allows controlling whether firewall rules should have packet counters or not from an env
7273
/// variable. Useful for debugging the rules.
@@ -269,6 +270,7 @@ struct PolicyBatch<'a> {
269270
prerouting_chain: Chain<'a>,
270271
mangle_chain: Chain<'a>,
271272
nat_chain: Chain<'a>,
273+
srcnat_chain: Chain<'a>,
272274
}
273275

274276
impl<'a> PolicyBatch<'a> {
@@ -314,6 +316,12 @@ impl<'a> PolicyBatch<'a> {
314316
nat_chain.set_policy(nftnl::Policy::Accept);
315317
batch.add(&nat_chain, nftnl::MsgType::Add);
316318

319+
let mut srcnat_chain = Chain::new(SRCNAT_CHAIN_NAME, table);
320+
srcnat_chain.set_type(nftnl::ChainType::Nat);
321+
srcnat_chain.set_hook(nftnl::Hook::PostRouting, libc::NF_IP_PRI_NAT_SRC);
322+
srcnat_chain.set_policy(nftnl::Policy::Accept);
323+
batch.add(&srcnat_chain, nftnl::MsgType::Add);
324+
317325
PolicyBatch {
318326
batch,
319327
in_chain,
@@ -322,6 +330,7 @@ impl<'a> PolicyBatch<'a> {
322330
prerouting_chain,
323331
mangle_chain,
324332
nat_chain,
333+
srcnat_chain,
325334
}
326335
}
327336

@@ -333,6 +342,8 @@ impl<'a> PolicyBatch<'a> {
333342
firewall: &Firewall,
334343
) -> Result<FinalizedBatch> {
335344
self.add_loopback_rules()?;
345+
// TODO: if router { .. }
346+
self.add_local_clients_forwaring_rules()?;
336347
// TODO: Investigate if these rules could/should be handled by PidManager instead.
337348
// It would allow for the firewall to be set up in a secure way even though split tunneling
338349
// 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> {
507518
Ok(())
508519
}
509520

521+
/// TODO: Don't forget sysctl net.ipv4.forwarding ..
522+
fn add_local_clients_forwaring_rules(&mut self) -> Result<()> {
523+
// Forward traffic stemming from (local) private IP ranges to wherever they want.
524+
// TODO: Make sure to document this in nft if we ever add comment expressions..
525+
// LAN -> forward
526+
for net in ALLOWED_LAN_NETS {
527+
let mut forward_from_local_clients = Rule::new(&self.forward_chain);
528+
check_net(&mut forward_from_local_clients, End::Src, net);
529+
add_verdict(&mut forward_from_local_clients, &Verdict::Accept);
530+
if *ADD_COUNTERS {
531+
forward_from_local_clients.add_expr(&nft_expr!(counter));
532+
};
533+
self.batch
534+
.add(&forward_from_local_clients, nftnl::MsgType::Add);
535+
536+
// Src Nat
537+
let mut srcnat_rule = Rule::new(&self.srcnat_chain);
538+
check_net(&mut srcnat_rule, End::Src, net);
539+
srcnat_rule.add_expr(&nft_expr!(masquerade));
540+
if *ADD_COUNTERS {
541+
srcnat_rule.add_expr(&nft_expr!(counter));
542+
};
543+
self.batch.add(&srcnat_rule, nftnl::MsgType::Add);
544+
}
545+
Ok(())
546+
}
547+
510548
fn add_dhcp_client_rules(&mut self) {
511549
use self::TransportProtocol::Udp;
512550
// Outgoing DHCPv4 request

0 commit comments

Comments
 (0)