mirror of
https://github.com/CommonLoon102/NBloodServerSupervisor.git
synced 2025-01-26 12:14:28 +01:00
forbid Tor exit nodes to request private servers (#14)
This commit is contained in:
parent
639fe15957
commit
e3e6af2371
@ -13,16 +13,19 @@ namespace WebInterface.Controllers
|
|||||||
{
|
{
|
||||||
private readonly IPrivateServerService _privateServerService;
|
private readonly IPrivateServerService _privateServerService;
|
||||||
private readonly IRateLimiterService _rateLimiterService;
|
private readonly IRateLimiterService _rateLimiterService;
|
||||||
|
private readonly ITorCheckService _torCheckService;
|
||||||
private readonly ICustomMapService _customMapService;
|
private readonly ICustomMapService _customMapService;
|
||||||
private readonly ILogger<PrivateController> _logger;
|
private readonly ILogger<PrivateController> _logger;
|
||||||
|
|
||||||
public PrivateController(IPrivateServerService privateServerService,
|
public PrivateController(IPrivateServerService privateServerService,
|
||||||
IRateLimiterService rateLimiterService,
|
IRateLimiterService rateLimiterService,
|
||||||
|
ITorCheckService torCheckService,
|
||||||
ICustomMapService customMapService,
|
ICustomMapService customMapService,
|
||||||
ILogger<PrivateController> logger)
|
ILogger<PrivateController> logger)
|
||||||
{
|
{
|
||||||
_privateServerService = privateServerService;
|
_privateServerService = privateServerService;
|
||||||
_rateLimiterService = rateLimiterService;
|
_rateLimiterService = rateLimiterService;
|
||||||
|
_torCheckService = torCheckService;
|
||||||
_customMapService = customMapService;
|
_customMapService = customMapService;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
@ -51,6 +54,9 @@ namespace WebInterface.Controllers
|
|||||||
if (!ModelState.IsValid)
|
if (!ModelState.IsValid)
|
||||||
throw new WebInterfaceException("Something went off the rails.");
|
throw new WebInterfaceException("Something went off the rails.");
|
||||||
|
|
||||||
|
if (_torCheckService.IsTorExit(HttpContext.Connection.RemoteIpAddress))
|
||||||
|
throw new WebInterfaceException("Requesting private servers through Tor is not allowed.");
|
||||||
|
|
||||||
if (!_rateLimiterService.IsRequestAllowed(HttpContext.Connection.RemoteIpAddress))
|
if (!_rateLimiterService.IsRequestAllowed(HttpContext.Connection.RemoteIpAddress))
|
||||||
throw new WebInterfaceException("Sorry, you have requested too many servers recently, you need to wait some time.");
|
throw new WebInterfaceException("Sorry, you have requested too many servers recently, you need to wait some time.");
|
||||||
|
|
||||||
|
13
WebInterface/Services/ITorCheckService.cs
Normal file
13
WebInterface/Services/ITorCheckService.cs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace WebInterface.Services
|
||||||
|
{
|
||||||
|
public interface ITorCheckService
|
||||||
|
{
|
||||||
|
bool IsTorExit(IPAddress address);
|
||||||
|
}
|
||||||
|
}
|
54
WebInterface/Services/TorCheckService.cs
Normal file
54
WebInterface/Services/TorCheckService.cs
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace WebInterface.Services
|
||||||
|
{
|
||||||
|
public class TorCheckService : ITorCheckService
|
||||||
|
{
|
||||||
|
private const string torExitNodesListUrl = "https://check.torproject.org/exit-addresses";
|
||||||
|
|
||||||
|
private static DateTime lastListUpdate = DateTime.MinValue;
|
||||||
|
private static DateTime lastUpdateFail = DateTime.MinValue;
|
||||||
|
private static string list = string.Empty;
|
||||||
|
|
||||||
|
public bool IsTorExit(IPAddress address)
|
||||||
|
{
|
||||||
|
if (!IsListActual())
|
||||||
|
UpdateList();
|
||||||
|
|
||||||
|
bool isInList = IsInList(address);
|
||||||
|
return isInList;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool IsListActual()
|
||||||
|
{
|
||||||
|
return !(string.IsNullOrWhiteSpace(list) || DateTime.UtcNow - lastListUpdate > TimeSpan.FromDays(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateList()
|
||||||
|
{
|
||||||
|
if (DateTime.UtcNow - lastUpdateFail > TimeSpan.FromMinutes(30))
|
||||||
|
{
|
||||||
|
WebClient webClient = new WebClient();
|
||||||
|
var listTask = webClient.DownloadStringTaskAsync(new Uri(torExitNodesListUrl));
|
||||||
|
if (listTask.Wait(TimeSpan.FromSeconds(2)))
|
||||||
|
{
|
||||||
|
list = listTask.Result;
|
||||||
|
lastListUpdate = DateTime.UtcNow;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lastUpdateFail = DateTime.UtcNow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool IsInList(IPAddress address)
|
||||||
|
{
|
||||||
|
return list.Contains(address.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -45,6 +45,7 @@ namespace WebInterface
|
|||||||
services.Add(new ServiceDescriptor(typeof(IStateService), typeof(StateService), ServiceLifetime.Singleton));
|
services.Add(new ServiceDescriptor(typeof(IStateService), typeof(StateService), ServiceLifetime.Singleton));
|
||||||
services.Add(new ServiceDescriptor(typeof(IPrivateServerService), typeof(PrivateServerService), ServiceLifetime.Transient));
|
services.Add(new ServiceDescriptor(typeof(IPrivateServerService), typeof(PrivateServerService), ServiceLifetime.Transient));
|
||||||
services.Add(new ServiceDescriptor(typeof(IRateLimiterService), typeof(RateLimiterService), ServiceLifetime.Singleton));
|
services.Add(new ServiceDescriptor(typeof(IRateLimiterService), typeof(RateLimiterService), ServiceLifetime.Singleton));
|
||||||
|
services.Add(new ServiceDescriptor(typeof(ITorCheckService), typeof(TorCheckService), ServiceLifetime.Singleton));
|
||||||
services.Add(new ServiceDescriptor(typeof(ICustomMapService), typeof(CustomMapService), ServiceLifetime.Transient));
|
services.Add(new ServiceDescriptor(typeof(ICustomMapService), typeof(CustomMapService), ServiceLifetime.Transient));
|
||||||
|
|
||||||
services.Configure<FormOptions>(options =>
|
services.Configure<FormOptions>(options =>
|
||||||
|
Loading…
Reference in New Issue
Block a user