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"
|
endpoint = "77.207.15.215"
|
||||||
# (Optional) endpoint port
|
# (Optional) endpoint port
|
||||||
port = 33722
|
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]]
|
[[peers]]
|
||||||
interface = "wg0"
|
interface = "wg0"
|
||||||
|
|
59
src/main.rs
59
src/main.rs
|
@ -9,6 +9,7 @@ use std::thread;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use anyhow::{anyhow, bail, Result};
|
use anyhow::{anyhow, bail, Result};
|
||||||
|
use ipnet::{IpNet, Ipv4Net, Ipv6Net};
|
||||||
use log::*;
|
use log::*;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
@ -58,7 +59,7 @@ struct Config {
|
||||||
interfaces: Vec<InterfaceSetting>,
|
interfaces: Vec<InterfaceSetting>,
|
||||||
|
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
forbidden_nets: Vec<ipnet::IpNet>,
|
forbidden_nets: Vec<IpNet>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
|
@ -73,6 +74,9 @@ struct Peer {
|
||||||
port: Option<u16>,
|
port: Option<u16>,
|
||||||
/// An optional Wireguard endpoint used to initialize a connection to this peer
|
/// An optional Wireguard endpoint used to initialize a connection to this peer
|
||||||
endpoint: Option<String>,
|
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
|
/// Settings for Wireguard interfaces
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
|
@ -101,6 +105,15 @@ fn main() -> Result<()> {
|
||||||
let config_str = std::fs::read_to_string(config_path)?;
|
let config_str = std::fs::read_to_string(config_path)?;
|
||||||
toml::from_str(&config_str)?
|
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 let Some(f) = &config.gossip_secret_file {
|
||||||
if config.gossip_secret.is_some() {
|
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();
|
let mut portmap_v4: HashMap<u16, u16> = HashMap::new();
|
||||||
//collect interfaces that have peers with IPv4 addresses (-> IPv4 port mappings need to exist)
|
//collect interfaces that have peers with IPv4 addresses (-> IPv4 port mappings need to exist)
|
||||||
let binding = self.state.lock().unwrap();
|
let binding = self.state.lock().unwrap();
|
||||||
let interfaces = binding.interfaces.iter();
|
let interfaces = binding.interfaces.iter();
|
||||||
let v4ifs: Vec<_> = binding.interfaces.iter()
|
let v4ifs: Vec<_> = binding
|
||||||
|
.interfaces
|
||||||
|
.iter()
|
||||||
.filter_map(|(ifname, ifinfo)| {
|
.filter_map(|(ifname, ifinfo)| {
|
||||||
if ifinfo.listen_port != 0
|
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))
|
Some((ifname, ifinfo))
|
||||||
} else {
|
} else {
|
||||||
|
@ -490,9 +509,8 @@ impl Daemon {
|
||||||
//create portmap
|
//create portmap
|
||||||
for ifsetting in &self.config.interfaces {
|
for ifsetting in &self.config.interfaces {
|
||||||
if let Some(external_port) = ifsetting.upnp_ext_port_v4 {
|
if let Some(external_port) = ifsetting.upnp_ext_port_v4 {
|
||||||
if let Some((_ifname, ifinfo)) = v4ifs
|
if let Some((_ifname, ifinfo)) =
|
||||||
.iter()
|
v4ifs.iter().find(|(ifname, _)| **ifname == ifsetting.name)
|
||||||
.find(|(ifname, _)| **ifname == ifsetting.name)
|
|
||||||
{
|
{
|
||||||
portmap_v4.insert(ifinfo.listen_port, external_port);
|
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)
|
//collect ports of interfaces that have peers with IPv6 addresses (-> pinholes for the IPv6 listen ports should be created)
|
||||||
let v6ports: Vec<u16> = interfaces
|
let v6ports: Vec<u16> = interfaces
|
||||||
.filter(|(ifname, ifinfo)| {
|
.filter(|(ifname, ifinfo)| {
|
||||||
ifinfo.listen_port!=0
|
ifinfo.listen_port != 0
|
||||||
&& self.config
|
&& self
|
||||||
|
.config
|
||||||
.peers
|
.peers
|
||||||
.iter()
|
.iter()
|
||||||
.any(|peer| peer.interface == **ifname && peer.address.is_ipv6())
|
.any(|peer| peer.interface == **ifname && peer.address.is_ipv6())
|
||||||
})
|
})
|
||||||
.map(|(_, ifinfo)|ifinfo.listen_port)
|
.map(|(_, ifinfo)| ifinfo.listen_port)
|
||||||
.collect();
|
.collect();
|
||||||
(portmap_v4, v6ports)
|
(portmap_v4, v6ports)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_packet(&self, gossip: &Gossip) -> Result<Vec<u8>> {
|
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,
|
// if peer is connected and endpoint is the correct one,
|
||||||
// set higher keepalive and then skip reconfiguring it
|
// 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")
|
Command::new("wg")
|
||||||
.args([
|
.args([
|
||||||
|
@ -754,7 +775,12 @@ impl State {
|
||||||
"persistent-keepalive",
|
"persistent-keepalive",
|
||||||
"10",
|
"10",
|
||||||
"allowed-ips",
|
"allowed-ips",
|
||||||
"::/0,0.0.0.0/0",
|
&peer_cfg
|
||||||
|
.allowed_ips
|
||||||
|
.iter()
|
||||||
|
.map(|ip| ip.to_string())
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join(","),
|
||||||
])
|
])
|
||||||
.output()?;
|
.output()?;
|
||||||
let packet = daemon.make_packet(&Gossip::Ping)?;
|
let packet = daemon.make_packet(&Gossip::Ping)?;
|
||||||
|
@ -772,7 +798,12 @@ impl State {
|
||||||
"peer",
|
"peer",
|
||||||
&peer_cfg.pubkey,
|
&peer_cfg.pubkey,
|
||||||
"allowed-ips",
|
"allowed-ips",
|
||||||
"::/0,0.0.0.0/0",
|
&peer_cfg
|
||||||
|
.allowed_ips
|
||||||
|
.iter()
|
||||||
|
.map(|ip| ip.to_string())
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join(","),
|
||||||
])
|
])
|
||||||
.output()?;
|
.output()?;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue