Skip to content

Commit

Permalink
#115 feat: editable on up and on down interface rules
Browse files Browse the repository at this point in the history
  • Loading branch information
joseantmazonsb committed Feb 28, 2022
1 parent 42d1eb3 commit 13989d8
Show file tree
Hide file tree
Showing 18 changed files with 166 additions and 68 deletions.
3 changes: 2 additions & 1 deletion Linguard/Cli.Test/AddClientCommandShould.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using Linguard.Cli.Commands;
using Linguard.Core.Managers;
using Linguard.Core.Models.Wireguard;
using Linguard.Core.OS;
using Linguard.Core.Services;
using Moq;
using Typin.Attributes;
Expand Down Expand Up @@ -152,6 +153,6 @@ public async Task CreateClientWithAllowedIPs() {

private Interface GenerateInterface(IConfigurationManager configuration) {
return new DefaultInterfaceGenerator(configuration,
WireguardServiceMock.Object).Generate();
WireguardServiceMock.Object, new SystemWrapper(configuration)).Generate();
}
}
3 changes: 2 additions & 1 deletion Linguard/Cli.Test/ListClientsCommandShould.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Linguard.Cli.Commands;
using Linguard.Core.Managers;
using Linguard.Core.Models.Wireguard;
using Linguard.Core.OS;
using Linguard.Core.Services;
using Moq;
using Typin.Attributes;
Expand Down Expand Up @@ -61,7 +62,7 @@ public async Task ListPeersForSpecificInterface() {
}

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

Expand Down
3 changes: 2 additions & 1 deletion Linguard/Cli.Test/ListInterfacesCommandShould.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Linguard.Cli.Commands;
using Linguard.Core.Managers;
using Linguard.Core.Models.Wireguard;
using Linguard.Core.OS;
using Linguard.Core.Services;
using Moq;
using Typin.Attributes;
Expand Down Expand Up @@ -35,6 +36,6 @@ public async Task ListOneInterface() {
}

private Interface GenerateInterface(IConfigurationManager configuration) {
return new DefaultInterfaceGenerator(configuration, WireguardServiceMock.Object).Generate();
return new DefaultInterfaceGenerator(configuration, WireguardServiceMock.Object, new SystemWrapper(configuration)).Generate();
}
}
3 changes: 2 additions & 1 deletion Linguard/Cli.Test/ShowInterfaceCommandShould.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using Linguard.Cli.Commands;
using Linguard.Core.Managers;
using Linguard.Core.Models.Wireguard;
using Linguard.Core.OS;
using Linguard.Core.Services;
using Moq;
using Typin.Attributes;
Expand Down Expand Up @@ -36,6 +37,6 @@ public async Task ShowInterface() {

private static Interface GenerateInterface(IConfigurationManager configuration) {
return new DefaultInterfaceGenerator(configuration,
WireguardServiceMock.Object).Generate();
WireguardServiceMock.Object, new SystemWrapper(configuration)).Generate();
}
}
4 changes: 2 additions & 2 deletions Linguard/Cli/Commands/AddInterfaceCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,10 @@ public AddInterfaceCommand(IConfigurationManager configurationManager, ILogger l
public bool? Auto { get; set; } = default;

[CommandOption("onUp", Description = "Commands to execute right after the interface is brought up.")]
public ICollection<string>? OnUp { get; set; } = default;
public ICollection<Rule>? OnUp { get; set; } = default;

[CommandOption("onDown", Description = "Commands to execute right after the interface is brought down.")]
public ICollection<string>? OnDown { get; set; } = default;
public ICollection<Rule>? OnDown { get; set; } = default;

[CommandOption("pubkey", Description = "The peer's public key.")]
public string? PublicKey { get; set; } = default;
Expand Down
4 changes: 3 additions & 1 deletion Linguard/Core.Test/DefaultClientGeneratorShould.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.Models.Wireguard.Validators;
using Linguard.Core.OS;
using Linguard.Core.Services;
using Moq;
using Xunit;
Expand All @@ -14,9 +15,10 @@ public class DefaultClientGeneratorShould {

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

private static IInterfaceGenerator InterfaceGenerator =>
new DefaultInterfaceGenerator(ConfigurationManagerMock.Object, WireguardServiceMock.Object);
new DefaultInterfaceGenerator(ConfigurationManagerMock.Object, WireguardServiceMock.Object, SystemWrapper);
private static IClientGenerator ClientGenerator =>
new DefaultClientGenerator(WireguardServiceMock.Object, ConfigurationManagerMock.Object);
private static AbstractValidator<Client> Validator => new ClientValidator(ConfigurationManagerMock.Object);
Expand Down
10 changes: 7 additions & 3 deletions Linguard/Core.Test/DefaultInterfaceGeneratorShould.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.Models.Wireguard.Validators;
using Linguard.Core.OS;
using Linguard.Core.Services;
using Moq;
using Xunit;
Expand All @@ -14,9 +15,12 @@ public class DefaultInterfaceGeneratorShould {

private static readonly Mock<IConfigurationManager> ConfigurationManagerMock = new DefaultConfigurationManager();
private static readonly Mock<IWireguardService> WireguardServiceMock = new();
private static IInterfaceGenerator Generator =>
new DefaultInterfaceGenerator(ConfigurationManagerMock.Object, WireguardServiceMock.Object);
private static AbstractValidator<Interface> Validator => new InterfaceValidator(ConfigurationManagerMock.Object);
private static readonly ISystemWrapper SystemWrapper = new SystemWrapper(ConfigurationManagerMock.Object);

private static IInterfaceGenerator Generator =>
new DefaultInterfaceGenerator(ConfigurationManagerMock.Object, WireguardServiceMock.Object, SystemWrapper);
private static AbstractValidator<Interface> Validator =>
new InterfaceValidator(ConfigurationManagerMock.Object, SystemWrapper);

[Fact]
public void AlwaysGenerateValidInterfaces() {
Expand Down
11 changes: 7 additions & 4 deletions Linguard/Core.Test/InterfaceShould.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
using System;
using System.Linq;
using System.Net.NetworkInformation;
using Core.Test.Mocks;
using FluentAssertions;
using Linguard.Core;
using Linguard.Core.Models.Wireguard;
using Linguard.Core.OS;
using Linguard.Core.Utils.Wireguard;
using Xunit;

namespace Core.Test;

public class InterfaceShould {
private readonly ISystemWrapper _system = new SystemMock().Object;

[Fact]
public void CreateValidWireguardConfiguration() {

Expand Down Expand Up @@ -42,17 +45,17 @@ public void CreateValidWireguardConfiguration() {
IPv6Address = IPAddressCidr.Parse("47cc:ec62:b8b4:d4c0:9c90:4c5c:1df5:a13f/64"),
PublicKey = "c892a52a-1fad-4564-af83-641744cd4dc3",
PrivateKey = "16116afc-3068-4ff5-88e0-0662ef57641a",
OnUp = new [] {
OnUp = new Rule[] {
"/usr/sbin/iptables -I FORWARD -i wg0 -j ACCEPT",
"/usr/sbin/iptables -I FORWARD -o wg0 -j ACCEPT",
"/usr/sbin/iptables -t nat -I POSTROUTING -o eth0 -j MASQUERADE"
},
OnDown = new [] {
OnDown = new Rule[] {
"/usr/sbin/iptables -D FORWARD -i wg0 -j ACCEPT",
"/usr/sbin/iptables -D FORWARD -o wg0 -j ACCEPT",
"/usr/sbin/iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE"
},
Gateway = NetworkInterface.GetAllNetworkInterfaces().First(),
Gateway = _system.NetworkInterfaces.First(),
Clients = new[] {
new Client {
Endpoint = new Uri("vpn.example.com", UriKind.RelativeOrAbsolute),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
using System.Net.NetworkInformation;
using Core.Test.Mocks;
using System.Collections.Generic;
using System.Linq;
using System.Net.NetworkInformation;
using Linguard.Core.Models.Wireguard;
using Linguard.Core.OS;
using Moq;

namespace WebMock;
namespace Core.Test.Mocks;

public class SystemMock : Mock<ISystemWrapper> {
private readonly List<NetworkInterface> _networkInterfaces = new();

private readonly List<NetworkInterface> _networkInterfaces = new() {
new NetworkInterfaceMock("eth0", OperationalStatus.Up).Object,
new NetworkInterfaceMock("eth1", OperationalStatus.Down).Object,
new NetworkInterfaceMock("wlan0", OperationalStatus.Up).Object,
new NetworkInterfaceMock("wlan1").Object
};

public SystemMock() {
SetupGet(o => o.NetworkInterfaces).Returns(_networkInterfaces);

Expand Down
4 changes: 2 additions & 2 deletions Linguard/Core/Models/Wireguard/Interface.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ public class Interface : WireguardPeerBase, ICloneable {
public int Port { get; set; }
public bool Auto { get; set; }
public ICollection<Client> Clients { get; set; } = new List<Client>();
public ICollection<string> OnUp { get; set; } = new List<string>();
public ICollection<string> OnDown { get; set; } = new List<string>();
public ICollection<Rule> OnUp { get; set; } = new List<Rule>();
public ICollection<Rule> OnDown { get; set; } = new List<Rule>();
/// <summary>
/// Default primary DNS for all peers if none specified.
/// </summary>
Expand Down
12 changes: 12 additions & 0 deletions Linguard/Core/Models/Wireguard/Rule.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace Linguard.Core.Models.Wireguard;

public class Rule {
public string Command { get; set; }

public static implicit operator Rule(string command)
{
return new Rule {
Command = command
};
}
}
10 changes: 6 additions & 4 deletions Linguard/Core/Models/Wireguard/Validators/InterfaceValidator.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
using System.Net.NetworkInformation;
using System.Text.RegularExpressions;
using System.Text.RegularExpressions;
using FluentValidation;
using FluentValidation.Results;
using Linguard.Core.Configuration;
using Linguard.Core.Managers;
using Linguard.Core.OS;
using Linguard.Core.Utils.Comparers;

namespace Linguard.Core.Models.Wireguard.Validators;
Expand All @@ -15,9 +15,11 @@ public class InterfaceValidator : AbstractValidator<Interface> {

private readonly IConfigurationManager _configurationManager;
private IWireguardConfiguration Configuration => _configurationManager.Configuration.Wireguard;
private readonly ISystemWrapper _system;

public InterfaceValidator(IConfigurationManager configurationManager) {
public InterfaceValidator(IConfigurationManager configurationManager, ISystemWrapper system) {
_configurationManager = configurationManager;
_system = system;
}

public override ValidationResult Validate(ValidationContext<Interface> context) {
Expand Down Expand Up @@ -51,7 +53,7 @@ private void SetGatewayRules() {
.WithMessage($"{field} {Validation.CannotBeEmpty}")
.DependentRules(() => {
RuleFor(i => i.Gateway)
.Must(i => NetworkInterface.GetAllNetworkInterfaces()
.Must(i => _system.NetworkInterfaces
.Contains(i, new NetworkInterfaceNameComparer()))
.WithMessage(Validation.InvalidGateway);
});
Expand Down
7 changes: 5 additions & 2 deletions Linguard/Core/Services/DefaultInterfaceGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,23 @@
using Linguard.Core.Configuration;
using Linguard.Core.Managers;
using Linguard.Core.Models.Wireguard;
using Linguard.Core.OS;
using Linguard.Core.Utils.Wireguard;

namespace Linguard.Core.Services;

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

public DefaultInterfaceGenerator(IConfigurationManager configurationManager,
IWireguardService wireguardService) {
IWireguardService wireguardService, ISystemWrapper system) {
_configurationManager = configurationManager;
_wireguardService = wireguardService;
_system = system;
}

public Interface Generate() {
Expand All @@ -32,7 +35,7 @@ public Interface Generate() {
.RuleFor(i => i.Auto, true)
.RuleFor(i => i.Description, f => f.Lorem.Sentence())
.RuleFor(i => i.Gateway, f => {
var gateways = NetworkInterface.GetAllNetworkInterfaces()
var gateways = _system.NetworkInterfaces
.Where(i => i.NetworkInterfaceType != NetworkInterfaceType.Loopback)
.ToArray();
return f.PickRandomParam(gateways);
Expand Down
8 changes: 4 additions & 4 deletions Linguard/Core/Utils/Wireguard/WireguardUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ namespace Linguard.Core.Utils.Wireguard;

public static class WireguardUtils {

public static string[] GenerateOnUpRules(string iptablesBin, string interfaceName, NetworkInterface gateway) {
return new[] {
public static ICollection<Rule> GenerateOnUpRules(string iptablesBin, string interfaceName, NetworkInterface gateway) {
return new List<Rule> {
$"{iptablesBin} -I FORWARD -i {interfaceName} -j ACCEPT",
$"{iptablesBin} -I FORWARD -o {interfaceName} -j ACCEPT",
$"{iptablesBin} -t nat -I POSTROUTING -o {gateway.Name} -j MASQUERADE",
Expand All @@ -16,8 +16,8 @@ public static string[] GenerateOnUpRules(string iptablesBin, string interfaceNam
};
}

public static string[] GenerateOnDownRules(string iptablesBin, string interfaceName, NetworkInterface gateway) {
return new[] {
public static ICollection<Rule> GenerateOnDownRules(string iptablesBin, string interfaceName, NetworkInterface gateway) {
return new List<Rule> {
$"{iptablesBin} -D FORWARD -i {interfaceName} -j ACCEPT",
$"{iptablesBin} -D FORWARD -o {interfaceName} -j ACCEPT",
$"{iptablesBin} -t nat -D POSTROUTING -o {gateway.Name} -j MASQUERADE",
Expand Down
8 changes: 3 additions & 5 deletions Linguard/Web/Pages/Wireguard.razor
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
@page "/wireguard"
@using Linguard.Core.Utils
@using Linguard.Core.Models.Wireguard
@using Linguard.Core.Managers
@using System.Net.NetworkInformation
@using Linguard.Core.Configuration
@using Linguard.Core.Models.Wireguard
@using Linguard.Core.OS
@using Linguard.Core.Services
@using Linguard.Core.Utils
@using Linguard.Web.Services
@using Linguard.Core.Configuration

<PageTitle>@($"{AssemblyInfo.Product} | {Title}")</PageTitle>

Expand Down Expand Up @@ -124,7 +123,6 @@
bool _stoppingAll;

protected override void OnInitialized() {
NetworkInterface.GetAllNetworkInterfaces();
_wireguardInterfaces = Configuration.Wireguard.Interfaces
.OrderBy(i => i.Name)
.ToList();
Expand Down
7 changes: 5 additions & 2 deletions Linguard/Web/Services/LifetimeService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using Linguard.Core.Configuration.Exceptions;
using Linguard.Core.Managers;
using Linguard.Core.Models.Wireguard;
using Linguard.Core.OS;
using Linguard.Core.Services;
using Linguard.Core.Utils;

Expand All @@ -15,17 +16,19 @@ public class LifetimeService : ILifetimeService {
private static readonly string WorkingDirectoryEnvironmentVariable = $"{AssemblyInfo.Product}Workdir";

private readonly Log.ILogger _logger;
private readonly ISystemWrapper _system;
private readonly IWireguardService _wireguardService;
private readonly IConfigurationManager _configurationManager;
private IWireguardConfiguration Configuration => _configurationManager.Configuration.Wireguard;

#endregion

public LifetimeService(IConfigurationManager configurationManager, IWireguardService wireguardService,
Log.ILogger logger) {
Log.ILogger logger, ISystemWrapper system) {
_configurationManager = configurationManager;
_wireguardService = wireguardService;
_logger = logger;
_system = system;
}

public void OnAppStarted() {
Expand Down Expand Up @@ -113,7 +116,7 @@ private void StopInterfaces() {
}

private IEnumerable<Interface> GetStartedInterfaces() {
var networkInterfaces = NetworkInterface.GetAllNetworkInterfaces()
var networkInterfaces = _system.NetworkInterfaces
.Where(i => i.OperationalStatus == OperationalStatus.Up);
return Configuration.Interfaces
.Where(i => networkInterfaces.Any(ni => ni.Name.Equals(i.Name)));
Expand Down
Loading

0 comments on commit 13989d8

Please sign in to comment.