cd
This commit is contained in:
parent
2f87a95828
commit
c838711e3e
23 changed files with 454 additions and 25 deletions
57
README.md
Normal file
57
README.md
Normal file
|
@ -0,0 +1,57 @@
|
|||
# Nyangate
|
||||
|
||||
NYANET reverse proxy for HTTP
|
||||
|
||||
## Features
|
||||
|
||||
- [ ] configurable routing
|
||||
- [ ] load balancing
|
||||
- [ ] access control
|
||||
- [ ] integration with IPMeow IPAM
|
||||
- [ ] header stripping and rewriting
|
||||
- [ ] intrusion detection
|
||||
- [ ] rate limiting
|
||||
- [ ] CLI interface
|
||||
- [ ] REST API
|
||||
|
||||
## Building
|
||||
|
||||
Building with Docker
|
||||
|
||||
```bash
|
||||
docker build . --tag nyangate
|
||||
```
|
||||
|
||||
Local compilation
|
||||
|
||||
```bash
|
||||
dotnet build
|
||||
```
|
||||
|
||||
## Running
|
||||
|
||||
To run with Docker
|
||||
|
||||
```bash
|
||||
docker run -it nyanet/nyangate
|
||||
```
|
||||
|
||||
or docker-compose
|
||||
|
||||
```yaml
|
||||
version: '3.3'
|
||||
services:
|
||||
nyangate:
|
||||
ports:
|
||||
- '80:80'
|
||||
- '443:443'
|
||||
volumes:
|
||||
- './data:/srv/nyangate/config'
|
||||
- './certs:/etc/tls/certs:ro'
|
||||
restart: always
|
||||
image: nyanet/nyangate
|
||||
```
|
||||
|
||||
```bash
|
||||
docker-compose up -d
|
||||
```
|
52
main.key.pem
Normal file
52
main.key.pem
Normal file
|
@ -0,0 +1,52 @@
|
|||
-----BEGIN PRIVATE KEY-----
|
||||
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
|
||||
A6a/XxsG5QEM+okhljJX1TmpmsjsiA==
|
||||
-----END PRIVATE KEY-----
|
29
main.pem
Normal file
29
main.pem
Normal file
|
@ -0,0 +1,29 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIFAzCCAuugAwIBAgIUSSnKwcDCcz5MhNWZ/eV+uhBap6kwDQYJKoZIhvcNAQEL
|
||||
BQAwETEPMA0GA1UEAwwGTllBTkVUMB4XDTIzMDMyODEwMzMxM1oXDTI0MDMyNzEw
|
||||
MzMxM1owETEPMA0GA1UEAwwGTllBTkVUMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A
|
||||
MIICCgKCAgEAtxOJBxEe9EWGYZgzQfH9mnvoTwVMVPgIPpos4PYYFvJeXrCitwIA
|
||||
j0ZCmT4Pekvq/5RH4n4NOltpSEXjM1ghbt8Yo/W5y5YquQGO74nK6HQhQBT+ix0l
|
||||
9M3xKvZZv8H8R6FLHT0Y0IHz5dV0BjAXsztT2tFvYDOXZHz+gehp9fZ2ToqJKa4W
|
||||
2avhMWL4v/OaP48WmW/42q6sDIqbvQ+TvAQKMFRrDSKoeC8wN1uOh2BFv0FIsrA5
|
||||
PhGlFnD9GmNYW5HZAi0RmiQVdlq6abZud9Ve/ny9SpT7+3XP2QjE737lRbkELnfQ
|
||||
KTo17eHfFGv82yUY0PImzkSBojuZg4wf44dpml5RiXYprJGVirxeTkMVOS3tnFA4
|
||||
75Ux0MoS9xSxwznHJpDQ+7NMooxQSDk1KY5cBqAdymSAptAL0jJBMg83hkBpGEx6
|
||||
tzEoIlH4skGKoV4HuSBlihk8uLcV/NpW49Th8THVr55lZZwXCma8JgWpFd9eF1Es
|
||||
mPGzQzRUeiunBpWwDvGKjWZ6jxXR/2OCofKPQOMOkWq8TXZiV0Xbg6KXFJTisZB2
|
||||
nwC6hqKzaudGxuBnbogwMaLBqqfndrcWO9pJhEMIow6OEUhEIvmUl8B8HFXu+dOR
|
||||
dxRyNQldEBU7erN+dLrhIjbO0LayRHIQge6mjiikLJF0IHEVL4v5GOECAwEAAaNT
|
||||
MFEwHQYDVR0OBBYEFPwC9awfqcrGqfdfByhXS7eF0/9JMB8GA1UdIwQYMBaAFPwC
|
||||
9awfqcrGqfdfByhXS7eF0/9JMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL
|
||||
BQADggIBAKN1U3DSTamMqHb5mETk55wokbGGOJfxz7WDfqzbOnpUkyuvMEiZ0QI9
|
||||
nMHFJd7LHGca2f28y3yZWAcvGkhLk2A6LDeBBoE1q+V2Ss4LR7dMK/UU895yJKLC
|
||||
whs+04cR8kKPLOlaOUdO/uqCJ0JDBxXTsIj2VIHVeF3FybvRgPSjuO0nej+SQDT1
|
||||
dG3ZJV09AVujWBA9gYLl/7Cr9GdgJmfx+JJ685R7qDrO5n7hpW5P7HAa+7viXzhd
|
||||
x34er0l8b4pLzBXn2bl2gsaKvXCBXs6TkL2i+FwoihDk7rMiMpxKvzaHmk/9F6xD
|
||||
HrOrJHCSv5vTxsPTHsfgGa2D8eNg7qK8rySEbzOiMw2CgT6peQMlDTvQbSCE4E/q
|
||||
7g5rOc4GSFOd6C6HMP18BGBFNW3iGwrB7I3s+sonLzEesKlG9JnmQTTIC0bnZjzl
|
||||
5RDkpaQjawBkU0jVYx7//2Fmj7SplLCuAj54LHTh1bhk8kduEi7qX2TmaTJboVX2
|
||||
J1JB3OhEOkaJ4rd+u3LED6sbkO8TWNsI7/Vyz3gbfB5E/nop8jibpoZ67LI1Yjf4
|
||||
eior7k6HOJ7uisnCp3n69aVkUd0FEEVEXr1+LcNt2V5iR24jhs76XSLYqsUwVdU/
|
||||
6zfPt1qT//7MS/KZNU69oJzstqkprXRkelc0SoBB+BY4oWUIvSXR
|
||||
-----END CERTIFICATE-----
|
|
@ -1,5 +1,9 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Nyangate.Lib\Nyangate.Lib.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
|
|
33
src/Nyangate.Lib/Data/IPRoute.cs
Normal file
33
src/Nyangate.Lib/Data/IPRoute.cs
Normal file
|
@ -0,0 +1,33 @@
|
|||
using System.Net;
|
||||
|
||||
namespace Nyangate.Lib.Data;
|
||||
|
||||
public enum RouteType : byte
|
||||
{
|
||||
STATIC_ADDRESS = 0x0,
|
||||
HOSTNAME = 0x1
|
||||
}
|
||||
|
||||
public class IPRoute
|
||||
{
|
||||
public IPRoute(string addrOrName)
|
||||
{
|
||||
if (!IPAddress.TryParse(addrOrName, out _addr))
|
||||
{
|
||||
_dnsName = addrOrName;
|
||||
}
|
||||
}
|
||||
|
||||
private readonly IPAddress? _addr;
|
||||
private readonly string? _dnsName;
|
||||
public RouteType Type { get; set; }
|
||||
public IPAddress Resolve()
|
||||
{
|
||||
return _addr ?? Dns.GetHostEntry(_dnsName!, System.Net.Sockets.AddressFamily.Unspecified).AddressList.First();//TODO: Cleanup
|
||||
}
|
||||
|
||||
public string GetHost()
|
||||
{
|
||||
return _dnsName ?? _addr!.ToString();
|
||||
}
|
||||
}
|
8
src/Nyangate.Lib/Data/RoutingInfo.cs
Normal file
8
src/Nyangate.Lib/Data/RoutingInfo.cs
Normal file
|
@ -0,0 +1,8 @@
|
|||
namespace Nyangate.Lib.Data;
|
||||
|
||||
public class RoutingInfo
|
||||
{
|
||||
public bool UsesTls { get; set; }
|
||||
public required IPRoute Route { get; set; }
|
||||
public required int Port { get; set; }
|
||||
}
|
15
src/Nyangate.Lib/Data/ServerHost.cs
Normal file
15
src/Nyangate.Lib/Data/ServerHost.cs
Normal file
|
@ -0,0 +1,15 @@
|
|||
namespace Nyangate.Lib.Data;
|
||||
|
||||
public class ServerHost
|
||||
{
|
||||
public required string Hostname { get; set; }
|
||||
public ICollection<string> Aliases { get; set; } = Array.Empty<string>();
|
||||
public required RoutingInfo Route { get; set; }
|
||||
|
||||
public Uri CreateBaseUri() => new UriBuilder()
|
||||
{
|
||||
Scheme = Route.UsesTls ? "https" : "http",
|
||||
Host = Route.Route.GetHost(),
|
||||
Port = Route.Port,
|
||||
}.Uri;
|
||||
}
|
27
src/Nyangate.Lib/Http/HttpContextAdapter.cs
Normal file
27
src/Nyangate.Lib/Http/HttpContextAdapter.cs
Normal file
|
@ -0,0 +1,27 @@
|
|||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Extensions;
|
||||
|
||||
namespace Nyangate.Lib.Http;
|
||||
|
||||
public class HttpContextAdapter
|
||||
{
|
||||
public HttpContextAdapter(HttpContext ctx)
|
||||
{
|
||||
_ctx = ctx;
|
||||
|
||||
_msg = new HttpRequestMessage(new HttpMethod(ctx.Request.Method), ctx.Request.GetEncodedUrl());
|
||||
|
||||
foreach (var header in ctx.Request.Headers)
|
||||
{
|
||||
_msg.Headers.Add(header.Key, header.Value.AsEnumerable());
|
||||
}
|
||||
|
||||
_msg.VersionPolicy = HttpVersionPolicy.RequestVersionOrHigher;
|
||||
}
|
||||
|
||||
private readonly HttpContext _ctx;
|
||||
|
||||
public HttpRequestMessage _msg;
|
||||
|
||||
public HttpRequestMessage Message => _msg;
|
||||
}
|
|
@ -6,4 +6,8 @@
|
|||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore" Version="2.2.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
8
src/Nyangate.Lib/Routing/RoutingStrategy.cs
Normal file
8
src/Nyangate.Lib/Routing/RoutingStrategy.cs
Normal file
|
@ -0,0 +1,8 @@
|
|||
using Nyangate.Lib.Data;
|
||||
|
||||
namespace Nyangate.Lib.Routing;
|
||||
|
||||
public abstract class RoutingStrategy
|
||||
{
|
||||
public abstract IPRoute Next();
|
||||
}
|
21
src/Nyangate/Filters/ContextFilter.cs
Normal file
21
src/Nyangate/Filters/ContextFilter.cs
Normal file
|
@ -0,0 +1,21 @@
|
|||
namespace Nyangate.Filters;
|
||||
|
||||
public class ContextFilter
|
||||
{
|
||||
private readonly List<IFilter> _filters = typeof(IFilter).Assembly.GetTypes().Where(t => t.IsAssignableFrom(typeof(IFilter))).Select(t => (IFilter)Activator.CreateInstance(t)!).ToList();
|
||||
public void ApplyAll(FilterType type, HttpContext ctx)
|
||||
{
|
||||
foreach (var filter in _filters.Where(f => f.Type.HasFlag(type)))
|
||||
{
|
||||
filter.Apply(ctx); //TODO: Priorities
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum FilterType : int
|
||||
{
|
||||
Proxy = 0x1,
|
||||
Sensitive = 0x2,
|
||||
All = 0xff
|
||||
}
|
8
src/Nyangate/Filters/IFilter.cs
Normal file
8
src/Nyangate/Filters/IFilter.cs
Normal file
|
@ -0,0 +1,8 @@
|
|||
namespace Nyangate.Filters;
|
||||
|
||||
public interface IFilter
|
||||
{
|
||||
public void Apply(HttpContext context);
|
||||
|
||||
public FilterType Type { get; }
|
||||
}
|
40
src/Nyangate/Filters/ProxyHeaderFilter.cs
Normal file
40
src/Nyangate/Filters/ProxyHeaderFilter.cs
Normal file
|
@ -0,0 +1,40 @@
|
|||
using System.Collections.Immutable;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
|
||||
namespace Nyangate.Filters;
|
||||
|
||||
public class ProxyHeaderFilter : IFilter
|
||||
{
|
||||
private static readonly HashSet<string> _headersToExclude = new(18, StringComparer.OrdinalIgnoreCase)
|
||||
{
|
||||
HeaderNames.Connection,
|
||||
HeaderNames.TransferEncoding,
|
||||
HeaderNames.KeepAlive,
|
||||
HeaderNames.Upgrade,
|
||||
HeaderNames.ProxyConnection,
|
||||
HeaderNames.ProxyAuthenticate,
|
||||
"Proxy-Authentication-Info",
|
||||
HeaderNames.ProxyAuthorization,
|
||||
"Proxy-Features",
|
||||
"Proxy-Instruction",
|
||||
"Security-Scheme",
|
||||
"ALPN",
|
||||
"Close",
|
||||
"HTTP2-Settings",
|
||||
HeaderNames.UpgradeInsecureRequests,
|
||||
HeaderNames.TE,
|
||||
HeaderNames.AltSvc,
|
||||
HeaderNames.StrictTransportSecurity,
|
||||
};
|
||||
|
||||
public FilterType Type => FilterType.Proxy;
|
||||
|
||||
public void Apply(HttpContext context)
|
||||
{
|
||||
foreach (var header in context.Request.Headers.Where(x => _headersToExclude.Contains(x.Key, StringComparer.OrdinalIgnoreCase)).ToArray())
|
||||
{
|
||||
context.Request.Headers.Remove(header);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
17
src/Nyangate/Middleware/Annotator.cs
Normal file
17
src/Nyangate/Middleware/Annotator.cs
Normal file
|
@ -0,0 +1,17 @@
|
|||
namespace Nyangate.Middleware;
|
||||
|
||||
public class Annotator
|
||||
{
|
||||
private readonly RequestDelegate _next;
|
||||
|
||||
public Annotator(RequestDelegate next)
|
||||
{
|
||||
_next = next;
|
||||
}
|
||||
|
||||
public async Task Invoke(HttpContext ctx)
|
||||
{
|
||||
ctx.Request.Headers.Add("Forwarded", $"for={ctx.Connection.RemoteIpAddress};by={ctx.Connection.LocalIpAddress};proto={ctx.Request.Scheme}");
|
||||
await _next.Invoke(ctx);
|
||||
}
|
||||
}
|
|
@ -1,8 +1,3 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Nyangate.Middleware;
|
||||
|
||||
public class Filter
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
using Microsoft.Extensions.Primitives;
|
||||
using Nyangate.Filters;
|
||||
using Nyangate.Lib.Http;
|
||||
using Nyangate.Services;
|
||||
|
||||
namespace Nyangate.Middleware
|
||||
|
@ -15,11 +18,50 @@ namespace Nyangate.Middleware
|
|||
|
||||
public async Task Invoke(HttpContext ctx)
|
||||
{
|
||||
string host = ctx.Request.Host.Host;
|
||||
string hostname = ctx.Request.Host.Host;
|
||||
//check ctx.Request.IsHttps if strict https required
|
||||
|
||||
var host = _map.Get(hostname) ?? _map.GetFallback();
|
||||
|
||||
if (host is null)
|
||||
{
|
||||
ctx.Response.StatusCode = 404;
|
||||
await ctx.Response.WriteAsync("meowless~");
|
||||
await ctx.Response.CompleteAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
ctx.Request.Host = new HostString(host.Route.Route.GetHost(), host.Route.Port);
|
||||
ctx.Request.Scheme = host.Route.UsesTls ? "https" : "http";
|
||||
|
||||
new ProxyHeaderFilter().Apply(ctx);
|
||||
|
||||
using HttpClient http = new();
|
||||
|
||||
HttpRequestMessage request = new HttpContextAdapter(ctx).Message;
|
||||
|
||||
if (ctx.Request.Body.CanRead)
|
||||
{
|
||||
request.Content = new StreamContent(ctx.Request.Body);
|
||||
}
|
||||
|
||||
var response = await http.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
|
||||
|
||||
Console.WriteLine($"meow: {ctx.Connection.RemoteIpAddress}");
|
||||
ctx.Response.StatusCode = 200;
|
||||
await _next.Invoke(ctx);
|
||||
|
||||
ctx.Response.StatusCode = (int)response.StatusCode;
|
||||
ctx.Response.Headers.Clear();
|
||||
|
||||
foreach (var header in response.Headers.NonValidated)
|
||||
{
|
||||
ctx.Response.Headers.Add(header.Key, new StringValues(header.Value.ToArray()));
|
||||
}
|
||||
|
||||
ctx.Response.ContentType = response.Content.Headers.ContentType?.ToString();
|
||||
ctx.Response.Headers.Add("Content-Encoding", new StringValues(response.Content.Headers.ContentEncoding.ToArray()));
|
||||
|
||||
await response.Content.CopyToAsync(ctx.Response.Body);
|
||||
await ctx.Response.CompleteAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Nyangate.Lib\Nyangate.Lib.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
using Microsoft.AspNetCore.Components.Routing;
|
||||
using Nyangate;
|
||||
using Nyangate.Middleware;
|
||||
using Nyangate.Services;
|
||||
|
||||
|
@ -29,6 +27,9 @@ var app = builder.Build();
|
|||
|
||||
app.UseMiddleware<Authenticator>();
|
||||
app.UseMiddleware<Filter>();
|
||||
app.UseMiddleware<IPFilter>();
|
||||
app.UseMiddleware<IDSFilter>();
|
||||
app.UseMiddleware<Annotator>();
|
||||
app.UseMiddleware<Nyangate.Middleware.Router>();
|
||||
|
||||
app.Run();
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Nyangate.Services;
|
||||
|
||||
public class BlacklistRegistry
|
||||
{
|
||||
public BlacklistRegistry()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private readonly Dictionary<string, long> Blacklisted = new();
|
||||
|
||||
public async Task<bool> IsBlacklisted(HttpContext ctx)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
|
26
src/Nyangate/Services/RateLimitService.cs
Normal file
26
src/Nyangate/Services/RateLimitService.cs
Normal file
|
@ -0,0 +1,26 @@
|
|||
using System.Net;
|
||||
|
||||
namespace Nyangate.Services;
|
||||
|
||||
public class RateLimitService
|
||||
{
|
||||
public async Task<bool> IsRateLimited(IPAddress addr, bool update = true)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public async Task<bool> IsRateLimited(HttpContext ctx, bool update = true)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public async Task UpdateActivity(HttpContext ctx)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public async Task UpdateActivity(IPAddress addr)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
|
@ -1,11 +1,43 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Nyangate.Lib.Data;
|
||||
|
||||
namespace Nyangate.Services;
|
||||
|
||||
public class RoutingMap
|
||||
{
|
||||
|
||||
public RoutingMap()
|
||||
{
|
||||
_hosts.Add("meow", new()
|
||||
{
|
||||
Hostname = "meow",
|
||||
Route = new()
|
||||
{
|
||||
UsesTls = false,
|
||||
Port = 8888,
|
||||
Route = new("localhost")
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private readonly Dictionary<string, ServerHost> _hosts = new();
|
||||
private readonly ServerHost? _fallbackHost;
|
||||
|
||||
public ServerHost? Get(string hostname)
|
||||
{
|
||||
return GetByMainHostname(hostname) ?? GetByAlias(hostname);
|
||||
}
|
||||
|
||||
public ServerHost? GetByMainHostname(string hostname)
|
||||
{
|
||||
return _hosts.GetValueOrDefault(hostname);
|
||||
}
|
||||
|
||||
public ServerHost? GetByAlias(string alias)
|
||||
{
|
||||
return _hosts.SingleOrDefault(x => x.Value.Aliases.Contains(alias)).Value;
|
||||
}
|
||||
|
||||
public ServerHost? GetFallback()
|
||||
{
|
||||
return _fallbackHost;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Nyangate.Services;
|
||||
|
||||
public class ServerCertificateRegistry
|
||||
{
|
||||
public ServerCertificateRegistry()
|
||||
{
|
||||
_main = X509Certificate2.CreateFromPemFile("/home/nya/Dev/csharp/nyangate/main.pem", "/home/nya/Dev/csharp/nyangate/main.key.pem");
|
||||
}
|
||||
|
||||
private readonly Dictionary<string, X509Certificate2> _registry = new();
|
||||
private readonly X509Certificate2 _main;
|
||||
public X509Certificate2 GetOrDefault(string hostname)
|
||||
{
|
||||
return _registry.GetValueOrDefault(hostname, Default());
|
||||
|
@ -16,6 +18,6 @@ public class ServerCertificateRegistry
|
|||
|
||||
public X509Certificate2 Default()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
return _main;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
global using Xunit;
|
Loading…
Reference in a new issue