mirror of
https://git.proxmox.com/git/proxmox-firewall
synced 2025-10-04 15:03:17 +00:00
ipsets: autogenerate ipsets for vnets and ipam
They act like virtual ipsets, similar to ipfilter-net, that can be used for defining firewall rules for sdn objects dynamically. The changes in proxmox-ve-config also introduced a dedicated struct for representing ip ranges, so we update the existing code, so that it uses that struct as well. Signed-off-by: Stefan Hanreich <s.hanreich@proxmox.com> Reviewed-by: Wolfgang Bumiller <w.bumiller@proxmox.com> Tested-by: Gabriel Goller <g.goller@proxmox.com> Tested-by: Hannes Dürr <h.duerr@proxmox.com>
This commit is contained in:
parent
669f99801b
commit
6f01ca780b
@ -197,6 +197,27 @@ impl Firewall {
|
|||||||
self.reset_firewall(&mut commands);
|
self.reset_firewall(&mut commands);
|
||||||
|
|
||||||
let cluster_host_table = Self::cluster_table();
|
let cluster_host_table = Self::cluster_table();
|
||||||
|
let guest_table = Self::guest_table();
|
||||||
|
|
||||||
|
if let Some(sdn_config) = self.config.sdn() {
|
||||||
|
let ipsets = sdn_config
|
||||||
|
.ipsets(None)
|
||||||
|
.map(|ipset| (ipset.name().to_string(), ipset))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
self.create_ipsets(&mut commands, &ipsets, &cluster_host_table, None)?;
|
||||||
|
self.create_ipsets(&mut commands, &ipsets, &guest_table, None)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(ipam_config) = self.config.ipam() {
|
||||||
|
let ipsets = ipam_config
|
||||||
|
.ipsets(None)
|
||||||
|
.map(|ipset| (ipset.name().to_string(), ipset))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
self.create_ipsets(&mut commands, &ipsets, &cluster_host_table, None)?;
|
||||||
|
self.create_ipsets(&mut commands, &ipsets, &guest_table, None)?;
|
||||||
|
}
|
||||||
|
|
||||||
if self.config.host().is_enabled() {
|
if self.config.host().is_enabled() {
|
||||||
log::info!("creating cluster / host configuration");
|
log::info!("creating cluster / host configuration");
|
||||||
@ -242,7 +263,6 @@ impl Firewall {
|
|||||||
commands.push(Delete::table(TableName::from(Self::cluster_table())));
|
commands.push(Delete::table(TableName::from(Self::cluster_table())));
|
||||||
}
|
}
|
||||||
|
|
||||||
let guest_table = Self::guest_table();
|
|
||||||
let enabled_guests: BTreeMap<&Vmid, &GuestConfig> = self
|
let enabled_guests: BTreeMap<&Vmid, &GuestConfig> = self
|
||||||
.config
|
.config
|
||||||
.guests()
|
.guests()
|
||||||
|
@ -72,19 +72,36 @@ impl ToNftObjects for Ipset {
|
|||||||
let mut nomatch_elements = Vec::new();
|
let mut nomatch_elements = Vec::new();
|
||||||
|
|
||||||
for element in self.iter() {
|
for element in self.iter() {
|
||||||
let cidr = match &element.address {
|
let expression = match &element.address {
|
||||||
IpsetAddress::Cidr(cidr) => cidr,
|
IpsetAddress::Range(range) => {
|
||||||
IpsetAddress::Alias(alias) => env
|
if family != range.family() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Expression::from(range)
|
||||||
|
}
|
||||||
|
IpsetAddress::Cidr(cidr) => {
|
||||||
|
if family != cidr.family() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Expression::from(Prefix::from(cidr))
|
||||||
|
}
|
||||||
|
IpsetAddress::Alias(alias) => {
|
||||||
|
let cidr = env
|
||||||
.alias(alias)
|
.alias(alias)
|
||||||
.ok_or(format_err!("could not find alias {alias} in environment"))?
|
.ok_or_else(|| {
|
||||||
.address(),
|
format_err!("could not find alias {alias} in environment")
|
||||||
};
|
})?
|
||||||
|
.address();
|
||||||
|
|
||||||
if family != cidr.family() {
|
if family != cidr.family() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let expression = Expression::from(Prefix::from(cidr));
|
Expression::from(Prefix::from(cidr))
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if element.nomatch {
|
if element.nomatch {
|
||||||
nomatch_elements.push(expression);
|
nomatch_elements.push(expression);
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,5 @@
|
|||||||
use crate::types::{ElemConfig, Verdict};
|
use crate::types::{ElemConfig, Verdict};
|
||||||
|
use proxmox_ve_config::firewall::types::address::IpRange;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
|
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
|
||||||
|
|
||||||
@ -50,6 +51,10 @@ pub enum Expression {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Expression {
|
impl Expression {
|
||||||
|
pub fn range(start: impl Into<Expression>, last: impl Into<Expression>) -> Self {
|
||||||
|
Expression::Range(Box::new((start.into(), last.into())))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn set(expressions: impl IntoIterator<Item = Expression>) -> Self {
|
pub fn set(expressions: impl IntoIterator<Item = Expression>) -> Self {
|
||||||
Expression::Set(Vec::from_iter(expressions))
|
Expression::Set(Vec::from_iter(expressions))
|
||||||
}
|
}
|
||||||
@ -169,12 +174,22 @@ impl From<&IpList> for Expression {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "config-ext")]
|
||||||
|
impl From<&IpRange> for Expression {
|
||||||
|
fn from(value: &IpRange) -> Self {
|
||||||
|
match value {
|
||||||
|
IpRange::V4(range) => Expression::range(range.start(), range.last()),
|
||||||
|
IpRange::V6(range) => Expression::range(range.start(), range.last()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "config-ext")]
|
#[cfg(feature = "config-ext")]
|
||||||
impl From<&IpEntry> for Expression {
|
impl From<&IpEntry> for Expression {
|
||||||
fn from(value: &IpEntry) -> Self {
|
fn from(value: &IpEntry) -> Self {
|
||||||
match value {
|
match value {
|
||||||
IpEntry::Cidr(cidr) => Expression::from(Prefix::from(cidr)),
|
IpEntry::Cidr(cidr) => Expression::from(Prefix::from(cidr)),
|
||||||
IpEntry::Range(beg, end) => Expression::Range(Box::new((beg.into(), end.into()))),
|
IpEntry::Range(range) => Expression::from(range),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user