ci/woodpecker/push/main-amd64-build Pipeline was successful
The hash a node reports about itself cannot be trusted (a swapped binary can copy the old hash), so the runtime binding only caught files that were replaced by something that did not lie. Provenance stays where it can be verified: the signed release manifest (digest) and the signed SHA256SUMS. - Remove BinaryBindingService, the node_bindings table (schema v15 drops it), BinaryPolicy, the handshake hash/manifest fields and the admin binary column. - Drop the per-platform "binaries" list from the release manifest, the hash scripts and the updater's installed.manifest copy. - ReleaseService.PublishAsync now verifies the release signature, so the admin POST /releases route is no longer an unsigned path; tests sign with a test key. - Docs: section 16 explains why the runtime check is gone.
67 lines
2.8 KiB
C#
67 lines
2.8 KiB
C#
using Fleet.Server;
|
|
using Microsoft.AspNetCore.Builder;
|
|
using Microsoft.Extensions.Configuration;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.Extensions.Logging;
|
|
using MoShiro.Backend.Api;
|
|
using MoShiro.Backend.Application;
|
|
using MoShiro.Backend.Gateway;
|
|
using MoShiro.Backend.Storage.Sqlite;
|
|
|
|
namespace MoShiro.Backend;
|
|
|
|
/// <summary>
|
|
/// 组合根:在这里显式注册所有层。配置来自 <c>appsettings.json</c>、环境变量(<c>MoShiro__DataDirectory</c> 等)和命令行。
|
|
/// 测试用 <see cref="Build"/> 在真实端口上启动整个后端。
|
|
/// </summary>
|
|
public static class BackendHost
|
|
{
|
|
public const string ConfigurationSection = "MoShiro";
|
|
public const int MaxRequestBodyBytes = 64 * 1024;
|
|
|
|
public static WebApplication Build(string[] args, Action<BackendOptions>? configureOptions = null, TimeProvider? time = null, Action<IServiceCollection>? configureServices = null)
|
|
{
|
|
WebApplicationBuilder builder = WebApplication.CreateSlimBuilder(args);
|
|
|
|
var options = new BackendOptions();
|
|
builder.Configuration.GetSection(ConfigurationSection).Bind(options);
|
|
configureOptions?.Invoke(options);
|
|
|
|
builder.WebHost.ConfigureKestrel(kestrel => kestrel.Limits.MaxRequestBodySize = MaxRequestBodyBytes);
|
|
builder.Logging.AddSimpleConsole(console =>
|
|
{
|
|
console.SingleLine = true;
|
|
console.UseUtcTimestamp = true;
|
|
console.TimestampFormat = "yyyy-MM-ddTHH:mm:ss.fffZ ";
|
|
});
|
|
|
|
IServiceCollection services = builder.Services;
|
|
services.AddSingleton(time ?? TimeProvider.System);
|
|
services.AddMoShiroSqlite(options.DataDirectory);
|
|
// 国家和运营商:Backend 用节点的来源地址查一次(Probe、Agent 不访问任何外部服务);地址留空就不查
|
|
if (string.IsNullOrWhiteSpace(options.GeoLookupUrl))
|
|
{
|
|
services.AddSingleton<IGeoLookup, NoGeoLookup>();
|
|
}
|
|
else
|
|
{
|
|
services.AddSingleton<IGeoLookup>(new HttpGeoLookup(options.GeoLookupUrl));
|
|
}
|
|
|
|
services.AddMoShiroApplication(options);
|
|
services.AddMoShiroGateway();
|
|
services.AddMoShiroApi();
|
|
configureServices?.Invoke(services); // 测试替换发布公钥这类服务
|
|
|
|
WebApplication app = builder.Build();
|
|
// 静默死亡的 Agent(断电、断网)不会关闭连接:15 秒一个 Ping,20 秒没有 Pong 就关闭,这样面板上的在线状态才可信
|
|
app.UseWebSockets(new WebSocketOptions { KeepAliveInterval = TimeSpan.FromSeconds(15), KeepAliveTimeout = TimeSpan.FromSeconds(20) });
|
|
app.UseMoShiroCors(options.CorsOrigins);
|
|
app.UseMoShiroApi();
|
|
app.MapMoShiroApi();
|
|
app.MapFleetEnrollment("/api/agent/v1/enroll");
|
|
app.MapFleetLink("/api/agent/v1/rpc");
|
|
return app;
|
|
}
|
|
}
|