Skip to content

Commit

Permalink
#115 refactor: WireguardUtils is now a static class similarly to Wire…
Browse files Browse the repository at this point in the history
…guardDumpParser

+ More mock related stuff
+ Added logic to add/remove wg interfaces
  • Loading branch information
joseantmazonsb committed Feb 27, 2022
1 parent fadc76c commit ed56e90
Show file tree
Hide file tree
Showing 22 changed files with 170 additions and 172 deletions.
3 changes: 2 additions & 1 deletion Linguard/Cli.Test/AddClientCommandShould.cs
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ public async Task CreateClientWithAllowedIPs() {
}

private Interface GenerateInterface(IConfigurationManager configuration) {
return new DefaultInterfaceGenerator(configuration, WireguardServiceMock.Object).Generate();
return new DefaultInterfaceGenerator(configuration,
WireguardServiceMock.Object).Generate();
}
}
3 changes: 2 additions & 1 deletion Linguard/Cli.Test/ListClientsCommandShould.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ public async Task ListPeersForSpecificInterface() {
}

private Interface GenerateInterface(IConfigurationManager configuration) {
return new DefaultInterfaceGenerator(configuration, WireguardServiceMock.Object).Generate();
return new DefaultInterfaceGenerator(configuration, WireguardServiceMock.Object)
.Generate();
}

private Client GeneratePeer(IConfigurationManager configuration, Interface iface) {
Expand Down
5 changes: 3 additions & 2 deletions Linguard/Cli.Test/ShowInterfaceCommandShould.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ public async Task ShowInterface() {
output.Should().Be(iface.ToString().Trim());
}

private Interface GenerateInterface(IConfigurationManager configuration) {
return new DefaultInterfaceGenerator(configuration, WireguardServiceMock.Object).Generate();
private static Interface GenerateInterface(IConfigurationManager configuration) {
return new DefaultInterfaceGenerator(configuration,
WireguardServiceMock.Object).Generate();
}
}
12 changes: 3 additions & 9 deletions Linguard/Core.Test/ClientShould.cs
Original file line number Diff line number Diff line change
@@ -1,19 +1,13 @@
using System;
using Core.Test.Mocks;
using FluentAssertions;
using Linguard.Core;
using Linguard.Core.Managers;
using Linguard.Core.Models.Wireguard;
using Linguard.Core.Services;
using Moq;
using Linguard.Core.Utils.Wireguard;
using Xunit;

namespace Core.Test;

public class ClientShould {
private static readonly Mock<IConfigurationManager> ConfigurationManagerMock = new DefaultConfigurationManager();
private static IWireguardService WireguardService =>
new WireguardService(ConfigurationManagerMock.Object, new Linguard.Core.OS.SystemWrapper(ConfigurationManagerMock.Object));
[Fact]
public void CreateValidWireguardConfig() {

Expand Down Expand Up @@ -43,7 +37,7 @@ public void CreateValidWireguardConfig() {
AllowedIPs = new[] { IPAddressCidr.Parse("1.1.2.0/24") },
PrimaryDns = new Uri("8.8.8.8", UriKind.RelativeOrAbsolute)
};
var output = WireguardService.GenerateWireguardConfiguration(peer);
var output = WireguardUtils.GenerateWireguardConfiguration(peer);
output.Should().Be(expected);
}

Expand Down Expand Up @@ -78,7 +72,7 @@ public void CreateAnotherValidWireguardConfig() {
PrimaryDns = new Uri("dns1.example.com", UriKind.RelativeOrAbsolute),
SecondaryDns = new Uri("dns2.example.com", UriKind.RelativeOrAbsolute),
};
var output = WireguardService.GenerateWireguardConfiguration(peer);
var output = WireguardUtils.GenerateWireguardConfiguration(peer);
output.Trim().Should().Be(expected.Trim());
}
}
1 change: 1 addition & 0 deletions Linguard/Core.Test/DefaultClientGeneratorShould.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public class DefaultClientGeneratorShould {

private static readonly Mock<IConfigurationManager> ConfigurationManagerMock = new DefaultConfigurationManager();
private static readonly Mock<IWireguardService> WireguardServiceMock = new();

private static IInterfaceGenerator InterfaceGenerator =>
new DefaultInterfaceGenerator(ConfigurationManagerMock.Object, WireguardServiceMock.Object);
private static IClientGenerator ClientGenerator =>
Expand Down
13 changes: 3 additions & 10 deletions Linguard/Core.Test/InterfaceShould.cs
Original file line number Diff line number Diff line change
@@ -1,22 +1,15 @@
using System;
using System.Linq;
using System.Net.NetworkInformation;
using Core.Test.Mocks;
using FluentAssertions;
using Linguard.Core;
using Linguard.Core.Managers;
using Xunit;
using Linguard.Core.Models.Wireguard;
using Linguard.Core.Services;
using Moq;
using Linguard.Core.Utils.Wireguard;
using Xunit;

namespace Core.Test;

public class InterfaceShould {
private static readonly Mock<IConfigurationManager> ConfigurationManagerMock = new DefaultConfigurationManager();
private static IWireguardService WireguardService =>
new WireguardService(ConfigurationManagerMock.Object, new Linguard.Core.OS.SystemWrapper(ConfigurationManagerMock.Object));

[Fact]
public void CreateValidWireguardConfiguration() {

Expand Down Expand Up @@ -86,7 +79,7 @@ public void CreateValidWireguardConfiguration() {
}
}
};
var output = WireguardService.GenerateWireguardConfiguration(iface);
var output = WireguardUtils.GenerateWireguardConfiguration(iface);
output.Trim().Should().Be(expected.Trim());
}
}
2 changes: 1 addition & 1 deletion Linguard/Core.Test/SystemShould.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace Core.Test;
public class SystemShould {

private static readonly Mock<IConfigurationManager> ConfigurationManagerMock = new DefaultConfigurationManager();
private readonly ISystemWrapper _systemWrapper = new Linguard.Core.OS.SystemWrapper(ConfigurationManagerMock.Object);
private readonly ISystemWrapper _systemWrapper = new SystemWrapper(ConfigurationManagerMock.Object);

[Fact]
public void RunSingleCommand() {
Expand Down
2 changes: 1 addition & 1 deletion Linguard/Core.Test/WireguardDumpParserShould.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
using Linguard.Core.Configuration;
using Linguard.Core.Managers;
using Linguard.Core.Models.Wireguard;
using Linguard.Core.Utils;
using Linguard.Core.Utils.Wireguard;
using Moq;
using Xunit;

Expand Down
8 changes: 6 additions & 2 deletions Linguard/Core/OS/SystemWrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using Linguard.Core.Managers;
using Linguard.Core.Models.Wireguard;
using Linguard.Core.Services.Exceptions;
using Linguard.Core.Utils.Wireguard;

namespace Linguard.Core.OS;

Expand All @@ -27,13 +28,16 @@ public ICommandResult RunCommand(string command) {
}

public void AddNetworkInterface(Interface iface) {
var result = RunCommand($"sudo {Configuration.WireguardQuickBin} up {iface.Name}");
var filepath = _configurationManager.WorkingDirectory.GetInterfaceConfigurationFile(iface).FullName;
File.WriteAllText(filepath, WireguardUtils.GenerateWireguardConfiguration(iface));
var result = RunCommand($"sudo {Configuration.WireguardQuickBin} up {filepath}");
if (!result.Success) throw new WireguardException(result.Stderr);
}

public void RemoveNetworkInterface(Interface iface) {
var result = RunCommand($"sudo {Configuration.WireguardQuickBin} up {iface.Name}");
var result = RunCommand($"sudo {Configuration.WireguardQuickBin} down {iface.Name}");
if (!result.Success) throw new WireguardException(result.Stderr);
_configurationManager.WorkingDirectory.GetInterfaceConfigurationFile(iface).Delete();
}

public bool IsInterfaceUp(Interface iface) {
Expand Down
16 changes: 9 additions & 7 deletions Linguard/Core/Services/DefaultInterfaceGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,20 @@
using Linguard.Core.Configuration;
using Linguard.Core.Managers;
using Linguard.Core.Models.Wireguard;
using Linguard.Core.Utils.Wireguard;

namespace Linguard.Core.Services;

public class DefaultInterfaceGenerator : IInterfaceGenerator {
private readonly IWireguardService _wireguard;
private readonly IWireguardService _wireguardService;
private readonly IConfigurationManager _configurationManager;
private const int MaxTries = 100;
private IWireguardConfiguration Configuration => _configurationManager.Configuration.Wireguard;

public DefaultInterfaceGenerator(IConfigurationManager configurationManager, IWireguardService wireguard) {
public DefaultInterfaceGenerator(IConfigurationManager configurationManager,
IWireguardService wireguardService) {
_configurationManager = configurationManager;
_wireguard = wireguard;
_wireguardService = wireguardService;
}

public Interface Generate() {
Expand Down Expand Up @@ -54,12 +56,12 @@ public Interface Generate() {
return default;
})
.RuleFor(i => i.OnDown,
(_, i) => _wireguard.GenerateOnDownRules(i.Name, i.Gateway))
(_, i) => WireguardUtils.GenerateOnDownRules(Configuration.IptablesBin, i.Name, i.Gateway))
.RuleFor(i => i.OnUp,
(_, i) => _wireguard.GenerateOnUpRules(i.Name, i.Gateway))
.RuleFor(i => i.PrivateKey, _wireguard.GenerateWireguardPrivateKey())
(_, i) => WireguardUtils.GenerateOnUpRules(Configuration.IptablesBin, i.Name, i.Gateway))
.RuleFor(i => i.PrivateKey, _wireguardService.GenerateWireguardPrivateKey())
.RuleFor(i => i.PublicKey,
(_, i) => _wireguard.GenerateWireguardPublicKey(i.PrivateKey))
(_, i) => _wireguardService.GenerateWireguardPublicKey(i.PrivateKey))
.RuleFor(i => i.IPv4Address, f => {
for (var tries = 0; tries < MaxTries; tries++) {
var addr = f.Internet.IpAddress();
Expand Down
6 changes: 1 addition & 5 deletions Linguard/Core/Services/IWireguardService.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System.Net.NetworkInformation;
using Linguard.Core.Models;
using Linguard.Core.Models;
using Linguard.Core.Models.Wireguard;

namespace Linguard.Core.Services;
Expand All @@ -12,9 +11,6 @@ public interface IWireguardService {
void RemoveClient(Interface iface, Client client);
string? GenerateWireguardPrivateKey();
string? GenerateWireguardPublicKey(string privateKey);
string[] GenerateOnUpRules(string interfaceName, NetworkInterface gateway);
string[] GenerateOnDownRules(string interfaceName, NetworkInterface gateway);
string GenerateWireguardConfiguration(IWireguardPeer peer);
DateTime GetLastHandshake(Client client);
IEnumerable<TrafficData> GetTrafficData();
IEnumerable<TrafficData> GetTrafficData(Interface iface);
Expand Down
100 changes: 2 additions & 98 deletions Linguard/Core/Services/WireguardService.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
using System.Net.NetworkInformation;
using System.Text;
using Linguard.Core.Configuration;
using Linguard.Core.Configuration;
using Linguard.Core.Managers;
using Linguard.Core.Models;
using Linguard.Core.Models.Wireguard;
using Linguard.Core.OS;
using Linguard.Core.Services.Exceptions;
using Linguard.Core.Utils;
using Linguard.Core.Utils.Wireguard;

namespace Linguard.Core.Services;

Expand Down Expand Up @@ -63,32 +61,6 @@ public string GenerateWireguardPublicKey(string privateKey) {
return result.Stdout;
}

public string[] GenerateOnUpRules(string interfaceName, NetworkInterface gateway) {
return new[] {
$"{Configuration.IptablesBin} -I FORWARD -i {interfaceName} -j ACCEPT",
$"{Configuration.IptablesBin} -I FORWARD -o {interfaceName} -j ACCEPT",
$"{Configuration.IptablesBin} -t nat -I POSTROUTING -o {gateway.Name} -j MASQUERADE",
"sysctl net.ipv4.ip_forward=1",
"sysctl net.ipv6.conf.all.forwarding=1"
};
}

public string[] GenerateOnDownRules(string interfaceName, NetworkInterface gateway) {
return new[] {
$"{Configuration.IptablesBin} -D FORWARD -i {interfaceName} -j ACCEPT",
$"{Configuration.IptablesBin} -D FORWARD -o {interfaceName} -j ACCEPT",
$"{Configuration.IptablesBin} -t nat -D POSTROUTING -o {gateway.Name} -j MASQUERADE",
};
}

public string GenerateWireguardConfiguration(IWireguardPeer peer) {
return peer switch {
Interface @interface => GenerateWireguardConfiguration(@interface),
Client client => GenerateWireguardConfiguration(client),
_ => throw new ArgumentException($"Type not supported: {peer.GetType()}")
};
}

public DateTime GetLastHandshake(Client client) {
var rawData = _systemWrapper
.RunCommand($"{Configuration.WireguardBin} show {GetInterface(client).Name} dump")
Expand Down Expand Up @@ -122,72 +94,4 @@ public IEnumerable<TrafficData> GetTrafficData(Interface iface) {
? Enumerable.Empty<TrafficData>()
: WireguardDumpParser.GetTrafficData(rawData, iface);
}

private string GenerateWireguardConfiguration(Interface @interface) {
var interfaceSection =
$"[Interface]{Environment.NewLine}" +
$"PrivateKey = {@interface.PrivateKey}{Environment.NewLine}" +
$"Address = {GetWireguardAddress(@interface)}{Environment.NewLine}" +
$"ListenPort = {@interface.Port}{Environment.NewLine}" +
$@"PostUp = {string.Join(Environment.NewLine+"PostUp = ", @interface.OnUp)}{Environment.NewLine}" +
$@"PostDown = {string.Join(Environment.NewLine+"PostDown = ", @interface.OnDown)}{Environment.NewLine}" +
$"{Environment.NewLine}";
var peersSection = new StringBuilder();
foreach (var peer in @interface.Clients) {
var peerSection =
$"[Peer]{Environment.NewLine}" +
$"PublicKey = {peer.PublicKey}{Environment.NewLine}";
if (peer.IPv4Address != default) {
peerSection += $"AllowedIPs = {peer.IPv4Address.IPAddress}/32";
if (peer.IPv6Address != default) {
peerSection += $", {peer.IPv6Address.IPAddress}/128{Environment.NewLine}";
}
else {
peerSection += Environment.NewLine;
}
peersSection.Append(peerSection);
continue;
}
if (peer.IPv6Address != default) {
peerSection += $"AllowedIPs = {peer.IPv6Address.IPAddress}/128{Environment.NewLine}";
}
peersSection.Append(peerSection);
}
return interfaceSection + peersSection;
}

private string GenerateWireguardConfiguration(Client client) {
var interfaceSection =
$"[Interface]{Environment.NewLine}" +
$"PrivateKey = {client.PrivateKey}{Environment.NewLine}" +
$"Address = {GetWireguardAddress(client)}{Environment.NewLine}" +
$"DNS = {GetWireguardDns()}{Environment.NewLine}" +
$"{Environment.NewLine}";
var allowedIps = string.Join(", ", client.AllowedIPs.Select(ip => ip.ToString()));
var peerSection =
$"[Peer]{Environment.NewLine}" +
$"PublicKey = {client.PublicKey}{Environment.NewLine}" +
$"AllowedIPs = {allowedIps}{Environment.NewLine}" +
$"Endpoint = {client.Endpoint}" +
(client.Nat ? $"{Environment.NewLine}PersistentKeepalive = 25" : "");
return interfaceSection + peerSection;

string GetWireguardDns() {
return $"{client.PrimaryDns}" + (client.SecondaryDns != default ? $", {client.SecondaryDns}" : "");
}
}

private static string GetWireguardAddress(IWireguardPeer peer) {
string address;
if (peer.IPv4Address != default) {
address = peer.IPv4Address.ToString();
if (peer.IPv6Address != default) {
address += $", {peer.IPv6Address}";
}
}
else {
address = peer.IPv6Address!.ToString();
}
return address;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
using Linguard.Core.Models;
using Linguard.Core.Models.Wireguard;

namespace Linguard.Core.Utils;
namespace Linguard.Core.Utils.Wireguard;

public static class WireguardDumpParser {

Expand Down
Loading

0 comments on commit ed56e90

Please sign in to comment.