Add interface bridge config

This commit is contained in:
Aode (Lion) 2021-10-17 14:04:36 -05:00
parent 64a5509d9f
commit 850e9232a3
4 changed files with 72 additions and 83 deletions

View file

@ -15,6 +15,18 @@ shared-internal = true
nats = [
"wg2"
]
bridges = [
["wg0", "vlan20"],
["wg1", "vlan20"],
["wg3", "vlan20"],
["wg4", "vlan20"],
["wg0", "wg1"],
["wg0", "wg3"],
["wg0", "wg4"],
["wg1", "wg3"],
["wg1", "wg4"],
["wg3", "wg4"]
]
[server]
debug = true

View file

@ -26,9 +26,9 @@ struct InterfaceConfig {
#[derive(serde::Deserialize)]
#[serde(rename_all = "kebab-case")]
struct NetworkConfig {
shared_internal: bool,
#[serde(default)]
nats: Vec<String>,
bridges: Vec<[String; 2]>,
}
#[derive(serde::Deserialize)]
@ -42,8 +42,8 @@ pub struct Interfaces {
pub(crate) internal: Vec<InterfaceInfo>,
pub(crate) vlan: Vec<InterfaceInfo>,
pub(crate) tunnel: Vec<InterfaceInfo>,
pub(crate) shared_internal: bool,
pub(crate) nats: Vec<String>,
pub(crate) bridges: Vec<[String; 2]>,
}
#[derive(Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
@ -94,7 +94,7 @@ impl Interfaces {
mask: 24,
}],
vlan: vec![InterfaceInfo {
interface: String::from("vlan20@enp1s0"),
interface: String::from("vlan20"),
ip: "192.168.6.20".parse()?,
mask: 24,
}],
@ -115,8 +115,8 @@ impl Interfaces {
mask: 24,
},
],
shared_internal: false,
nats: Vec::new(),
bridges: Vec::new(),
});
}
@ -160,8 +160,8 @@ impl Interfaces {
internal,
vlan,
tunnel,
shared_internal: config.network.shared_internal,
nats: config.network.nats.clone(),
bridges: config.network.bridges.clone(),
})
}

View file

@ -123,50 +123,24 @@ fn filter(interfaces: &Interfaces) -> String {
);
}
if interfaces.shared_internal {
for iface in &interfaces.internal {
// jface (jeans iface)
for jface in &interfaces.internal {
// Allow internal traffic across all internal interfaces
filter += &format!(
"-A OUTPUT -o {intif} -s {extip}/{extmask} -d {jntip}/{jntmask} -j ACCEPT\n",
intif = iface.interface,
extip = interfaces.external.ip,
extmask = interfaces.external.mask,
jntip = jface.ip, // jeans IP
jntmask = jface.mask, // jeans mask
);
for iface in &interfaces.internal {
// Allow internal traffic only on network associated with interface
filter += &format!(
"-A OUTPUT -o {intif} -s {extip}/{extmask} -d {intip}/{intmask} -j ACCEPT\n",
intif = iface.interface,
extip = interfaces.external.ip,
extmask = interfaces.external.mask,
intip = iface.ip,
intmask = iface.mask,
);
// Allow internal traffic from self to internal networks
filter += &format!(
"-A OUTPUT -o {intif} -s {intip}/32 -d {jntip}/{jntmask} -j ACCEPT\n",
intif = iface.interface,
intip = iface.ip,
jntip = jface.ip, // jeans IP
jntmask = jface.mask, // jeans mask
);
}
}
} else {
for iface in &interfaces.internal {
// Allow internal traffic only on network associated with interface
filter += &format!(
"-A OUTPUT -o {intif} -s {extip}/{extmask} -d {intip}/{intmask} -j ACCEPT\n",
intif = iface.interface,
extip = interfaces.external.ip,
extmask = interfaces.external.mask,
intip = iface.ip,
intmask = iface.mask,
);
// Allow traffic from self to networks associated with interface
filter += &format!(
"-A OUTPUT -o {intif} -s {intip}/32 -d {intip}/{intmask} -j ACCEPT\n",
intif = iface.interface,
intip = iface.ip,
intmask = iface.mask,
);
}
// Allow traffic from self to networks associated with interface
filter += &format!(
"-A OUTPUT -o {intif} -s {intip}/32 -d {intip}/{intmask} -j ACCEPT\n",
intif = iface.interface,
intip = iface.ip,
intmask = iface.mask,
);
}
for iface in interfaces.internal.iter().chain(&interfaces.vlan) {
@ -272,19 +246,15 @@ fn filter(interfaces: &Interfaces) -> String {
}
}
// Accept packets over tunnel interfaces
// Allow forwarding packets over tunnel interfaces
for iface in &interfaces.tunnel {
filter += &format!(
"-A FORWARD -i {tunface} -j ACCEPT\n",
tunface = iface.interface,
);
filter += &format!(
"-A FORWARD -o {tunface} -j ACCEPT\n",
"-A FORWARD -i {tunface} -o {tunface} -j ACCEPT\n",
tunface = iface.interface,
);
}
// Accept TCP packets
// Allow VLANs to respond to related external traffic
for iface in interfaces.internal.iter().chain(&interfaces.vlan) {
filter += &format!(
"-A FORWARD -i {extif} -o {intif} -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT\n",
@ -293,34 +263,35 @@ fn filter(interfaces: &Interfaces) -> String {
);
}
// Allow packets across VLAN interface
for iface in &interfaces.vlan {
// Allow packets across vlan interface
filter += &format!(
"-A FORWARD -i {intif} -o {intif} -j ACCEPT\n",
intif = iface.interface,
);
}
if interfaces.shared_internal {
for iface in &interfaces.internal {
// jface (jeans interface)
for jface in &interfaces.internal {
// Allow packets across internal interfaces
filter += &format!(
"-A FORWARD -i {intif} -o {jntif} -j ACCEPT\n",
intif = iface.interface,
jntif = jface.interface, // jntif (jeans intif)
);
}
}
} else {
for iface in &interfaces.internal {
// Allow packets across internal interface
filter += &format!(
"-A FORWARD -i {intif} -o {intif} -j ACCEPT\n",
intif = iface.interface,
);
}
for iface in &interfaces.internal {
// Allow packets across internal interface
filter += &format!(
"-A FORWARD -i {intif} -o {intif} -j ACCEPT\n",
intif = iface.interface,
);
}
// Bridge interfaces
for [left, right] in interfaces.bridges.iter() {
filter += &format!(
"-A FORWARD -i {left} -o {right} -m conntrack --ctstate NEW,ESTABLISHED,RELATED -j ACCEPT\n",
left = left,
right = right,
);
filter += &format!(
"-A FORWARD -i {right} -o {left} -m conntrack --ctstate NEW,ESTABLISHED,RELATED -j ACCEPT\n",
left = left,
right = right,
);
}
// Forward packets to the internet
@ -389,10 +360,3 @@ fn nat(interfaces: &Interfaces) -> String {
nat
}
// TODO: SSH
// # Internal interface, SSH traffic accepted on port 3128
// -A INPUT -i $INTIF -p tcp --dport 3128 -j ACCEPT
//
// # External interface, SSH traffic allowed on port 3128
// -A INPUT -i $EXTIF -m conntrack -p tcp -s $UNIVERSE -d $EXTIP --dport 3128 -j ACCEPT

View file

@ -44,6 +44,19 @@
</ul>
</div>
</section>
<section>
<h4>VLANs</h4>
<div class="content">
<ul>
@for iface in &interfaces.vlan {
<li class="interface">
<p><span class="title">IP:</span> @iface.ip</p>
<p><span class="title">Interface:</span> @iface.interface</p>
</li>
}
</ul>
</div>
</section>
<section>
<h4>Admin</h4>
<nav class="content">