forbid Tor exit nodes to request private servers ()

This commit is contained in:
CommonLoon102 2020-02-01 21:16:09 +00:00 committed by GitHub
parent 639fe15957
commit e3e6af2371
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 74 additions and 0 deletions

View File

@ -13,16 +13,19 @@ namespace WebInterface.Controllers
{
private readonly IPrivateServerService _privateServerService;
private readonly IRateLimiterService _rateLimiterService;
private readonly ITorCheckService _torCheckService;
private readonly ICustomMapService _customMapService;
private readonly ILogger<PrivateController> _logger;
public PrivateController(IPrivateServerService privateServerService,
IRateLimiterService rateLimiterService,
ITorCheckService torCheckService,
ICustomMapService customMapService,
ILogger<PrivateController> logger)
{
_privateServerService = privateServerService;
_rateLimiterService = rateLimiterService;
_torCheckService = torCheckService;
_customMapService = customMapService;
_logger = logger;
}
@ -51,6 +54,9 @@ namespace WebInterface.Controllers
if (!ModelState.IsValid)
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))
throw new WebInterfaceException("Sorry, you have requested too many servers recently, you need to wait some time.");

View 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);
}
}

View 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());
}
}
}

View File

@ -45,6 +45,7 @@ namespace WebInterface
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(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.Configure<FormOptions>(options =>