add allowed_ips config option for peers, formatting
This commit is contained in:
parent
a8957c9558
commit
af07d1653c
2 changed files with 50 additions and 17 deletions
|
@ -74,6 +74,8 @@ address = "10.14.1.2"
|
|||
endpoint = "77.207.15.215"
|
||||
# (Optional) endpoint port
|
||||
port = 33722
|
||||
# (Optional) Subnets allowed to be routed through this peer. If no value is given, this defaults to only the peers address itself.
|
||||
allowed_ips = ["10.14.1.2/32","192.168.0.0/16"]
|
||||
|
||||
[[peers]]
|
||||
interface = "wg0"
|
||||
|
|
65
src/main.rs
65
src/main.rs
|
@ -9,6 +9,7 @@ use std::thread;
|
|||
use std::time::Duration;
|
||||
|
||||
use anyhow::{anyhow, bail, Result};
|
||||
use ipnet::{IpNet, Ipv4Net, Ipv6Net};
|
||||
use log::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
|
@ -58,7 +59,7 @@ struct Config {
|
|||
interfaces: Vec<InterfaceSetting>,
|
||||
|
||||
#[serde(default)]
|
||||
forbidden_nets: Vec<ipnet::IpNet>,
|
||||
forbidden_nets: Vec<IpNet>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
|
@ -73,6 +74,9 @@ struct Peer {
|
|||
port: Option<u16>,
|
||||
/// An optional Wireguard endpoint used to initialize a connection to this peer
|
||||
endpoint: Option<String>,
|
||||
/// Subnets allowed to be routed through this peer. Defaults to only the IP of the peer itself if no value is given.
|
||||
#[serde(default)]
|
||||
allowed_ips: Vec<IpNet>,
|
||||
}
|
||||
/// Settings for Wireguard interfaces
|
||||
#[derive(Deserialize)]
|
||||
|
@ -101,6 +105,15 @@ fn main() -> Result<()> {
|
|||
let config_str = std::fs::read_to_string(config_path)?;
|
||||
toml::from_str(&config_str)?
|
||||
};
|
||||
for peer in &mut config.peers {
|
||||
if peer.allowed_ips.is_empty() {
|
||||
let ip_net = match peer.address {
|
||||
IpAddr::V4(ipv4) => IpNet::V4(Ipv4Net::new(ipv4, 32)?),
|
||||
IpAddr::V6(ipv6) => IpNet::V6(Ipv6Net::new(ipv6, 128)?),
|
||||
};
|
||||
peer.allowed_ips.push(ip_net);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(f) = &config.gossip_secret_file {
|
||||
if config.gossip_secret.is_some() {
|
||||
|
@ -471,15 +484,21 @@ impl Daemon {
|
|||
});
|
||||
}
|
||||
}
|
||||
fn generate_portmaps(&self) -> (HashMap<u16,u16>, Vec<u16>) {
|
||||
fn generate_portmaps(&self) -> (HashMap<u16, u16>, Vec<u16>) {
|
||||
let mut portmap_v4: HashMap<u16, u16> = HashMap::new();
|
||||
//collect interfaces that have peers with IPv4 addresses (-> IPv4 port mappings need to exist)
|
||||
let binding = self.state.lock().unwrap();
|
||||
let interfaces = binding.interfaces.iter();
|
||||
let v4ifs: Vec<_> = binding.interfaces.iter()
|
||||
let v4ifs: Vec<_> = binding
|
||||
.interfaces
|
||||
.iter()
|
||||
.filter_map(|(ifname, ifinfo)| {
|
||||
if ifinfo.listen_port != 0
|
||||
&& self.config.peers.iter().any(|peer| peer.interface == **ifname && peer.address.is_ipv4())
|
||||
&& self
|
||||
.config
|
||||
.peers
|
||||
.iter()
|
||||
.any(|peer| peer.interface == **ifname && peer.address.is_ipv4())
|
||||
{
|
||||
Some((ifname, ifinfo))
|
||||
} else {
|
||||
|
@ -490,9 +509,8 @@ impl Daemon {
|
|||
//create portmap
|
||||
for ifsetting in &self.config.interfaces {
|
||||
if let Some(external_port) = ifsetting.upnp_ext_port_v4 {
|
||||
if let Some((_ifname, ifinfo)) = v4ifs
|
||||
.iter()
|
||||
.find(|(ifname, _)| **ifname == ifsetting.name)
|
||||
if let Some((_ifname, ifinfo)) =
|
||||
v4ifs.iter().find(|(ifname, _)| **ifname == ifsetting.name)
|
||||
{
|
||||
portmap_v4.insert(ifinfo.listen_port, external_port);
|
||||
}
|
||||
|
@ -501,16 +519,16 @@ impl Daemon {
|
|||
//collect ports of interfaces that have peers with IPv6 addresses (-> pinholes for the IPv6 listen ports should be created)
|
||||
let v6ports: Vec<u16> = interfaces
|
||||
.filter(|(ifname, ifinfo)| {
|
||||
ifinfo.listen_port!=0
|
||||
&& self.config
|
||||
.peers
|
||||
.iter()
|
||||
.any(|peer| peer.interface == **ifname && peer.address.is_ipv6())
|
||||
ifinfo.listen_port != 0
|
||||
&& self
|
||||
.config
|
||||
.peers
|
||||
.iter()
|
||||
.any(|peer| peer.interface == **ifname && peer.address.is_ipv6())
|
||||
})
|
||||
.map(|(_, ifinfo)|ifinfo.listen_port)
|
||||
.map(|(_, ifinfo)| ifinfo.listen_port)
|
||||
.collect();
|
||||
(portmap_v4, v6ports)
|
||||
|
||||
}
|
||||
|
||||
fn make_packet(&self, gossip: &Gossip) -> Result<Vec<u8>> {
|
||||
|
@ -674,7 +692,10 @@ impl State {
|
|||
|
||||
// if peer is connected and endpoint is the correct one,
|
||||
// set higher keepalive and then skip reconfiguring it
|
||||
if !bad_endpoint && peer.last_seen != u64::MAX && !forbidden_endpoint && now < peer.last_seen + TIMEOUT.as_secs()
|
||||
if !bad_endpoint
|
||||
&& peer.last_seen != u64::MAX
|
||||
&& !forbidden_endpoint
|
||||
&& now < peer.last_seen + TIMEOUT.as_secs()
|
||||
{
|
||||
Command::new("wg")
|
||||
.args([
|
||||
|
@ -754,7 +775,12 @@ impl State {
|
|||
"persistent-keepalive",
|
||||
"10",
|
||||
"allowed-ips",
|
||||
"::/0,0.0.0.0/0",
|
||||
&peer_cfg
|
||||
.allowed_ips
|
||||
.iter()
|
||||
.map(|ip| ip.to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join(","),
|
||||
])
|
||||
.output()?;
|
||||
let packet = daemon.make_packet(&Gossip::Ping)?;
|
||||
|
@ -772,7 +798,12 @@ impl State {
|
|||
"peer",
|
||||
&peer_cfg.pubkey,
|
||||
"allowed-ips",
|
||||
"::/0,0.0.0.0/0",
|
||||
&peer_cfg
|
||||
.allowed_ips
|
||||
.iter()
|
||||
.map(|ip| ip.to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join(","),
|
||||
])
|
||||
.output()?;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue