完善DnscryptProxy服务
This commit is contained in:
parent
2e357e58d4
commit
09ee688ba0
@ -1,8 +1,6 @@
|
|||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
@ -14,15 +12,19 @@ namespace FastGithub.Dns.DnscryptProxy
|
|||||||
sealed class DnscryptProxyHostedService : BackgroundService
|
sealed class DnscryptProxyHostedService : BackgroundService
|
||||||
{
|
{
|
||||||
private bool isStopped = false;
|
private bool isStopped = false;
|
||||||
private const string dnscryptProxyFile = "dnscrypt-proxy";
|
private readonly DnscryptProxyService dnscryptProxyService;
|
||||||
private readonly ILogger<DnscryptProxyHostedService> logger;
|
private readonly ILogger<DnscryptProxyHostedService> logger;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// DnscryptProxy后台服务
|
/// DnscryptProxy后台服务
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <param name="dnscryptProxyService"></param>
|
||||||
/// <param name="logger"></param>
|
/// <param name="logger"></param>
|
||||||
public DnscryptProxyHostedService(ILogger<DnscryptProxyHostedService> logger)
|
public DnscryptProxyHostedService(
|
||||||
|
DnscryptProxyService dnscryptProxyService,
|
||||||
|
ILogger<DnscryptProxyHostedService> logger)
|
||||||
{
|
{
|
||||||
|
this.dnscryptProxyService = dnscryptProxyService;
|
||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,27 +33,19 @@ namespace FastGithub.Dns.DnscryptProxy
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="cancellationToken"></param>
|
/// <param name="cancellationToken"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public override Task StartAsync(CancellationToken cancellationToken)
|
public override async Task StartAsync(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (OperatingSystem.IsWindows())
|
await this.dnscryptProxyService.StartAsync(cancellationToken);
|
||||||
{
|
this.logger.LogInformation($"{this.dnscryptProxyService}启动成功");
|
||||||
StartDnscryptProxy("-service install", waitForExit: true);
|
|
||||||
StartDnscryptProxy("-service start", waitForExit: true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
StartDnscryptProxy(string.Empty, waitForExit: false);
|
|
||||||
}
|
|
||||||
this.logger.LogInformation($"{dnscryptProxyFile}启动成功");
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
this.logger.LogWarning($"{dnscryptProxyFile}启动失败:{ex.Message}");
|
this.logger.LogWarning($"{this.dnscryptProxyService}启动失败:{ex.Message}");
|
||||||
}
|
}
|
||||||
|
|
||||||
return base.StartAsync(cancellationToken);
|
await base.StartAsync(cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -63,14 +57,10 @@ namespace FastGithub.Dns.DnscryptProxy
|
|||||||
{
|
{
|
||||||
await Task.Yield();
|
await Task.Yield();
|
||||||
|
|
||||||
var process = Process.GetProcessesByName(dnscryptProxyFile).FirstOrDefault();
|
this.dnscryptProxyService.WaitForExit();
|
||||||
if (process != null)
|
|
||||||
{
|
|
||||||
process.WaitForExit();
|
|
||||||
}
|
|
||||||
if (this.isStopped == false)
|
if (this.isStopped == false)
|
||||||
{
|
{
|
||||||
this.logger.LogCritical($"{dnscryptProxyFile}已停止运行,{nameof(FastGithub)}将无法解析域名。你可以把配置文件的{nameof(FastGithubOptions.PureDns)}修改为其它可用的DNS以临时使用。");
|
this.logger.LogCritical($"{this.dnscryptProxyService}已停止运行,{nameof(FastGithub)}将无法解析域名。你可以把配置文件的{nameof(FastGithubOptions.PureDns)}修改为其它可用的DNS以临时使用。");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,45 +74,14 @@ namespace FastGithub.Dns.DnscryptProxy
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
this.isStopped = true;
|
this.isStopped = true;
|
||||||
if (OperatingSystem.IsWindows())
|
this.dnscryptProxyService.Stop();
|
||||||
{
|
this.logger.LogInformation($"{this.dnscryptProxyService}已停止");
|
||||||
StartDnscryptProxy("-service stop", waitForExit: true);
|
|
||||||
StartDnscryptProxy("-service uninstall", waitForExit: true);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var process in Process.GetProcessesByName(dnscryptProxyFile))
|
|
||||||
{
|
|
||||||
process.Kill();
|
|
||||||
}
|
|
||||||
this.logger.LogInformation($"{dnscryptProxyFile}已停止");
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
this.logger.LogWarning($"{dnscryptProxyFile}停止失败:{ex.Message}");
|
this.logger.LogWarning($"{this.dnscryptProxyService}停止失败:{ex.Message}");
|
||||||
}
|
}
|
||||||
return base.StopAsync(cancellationToken);
|
return base.StopAsync(cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 启动DnscryptProxy进程
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="arguments"></param>
|
|
||||||
/// <param name="waitForExit"></param>
|
|
||||||
private static void StartDnscryptProxy(string arguments, bool waitForExit)
|
|
||||||
{
|
|
||||||
var process = Process.Start(new ProcessStartInfo
|
|
||||||
{
|
|
||||||
FileName = OperatingSystem.IsWindows() ? $"{dnscryptProxyFile}.exe" : dnscryptProxyFile,
|
|
||||||
Arguments = arguments,
|
|
||||||
UseShellExecute = true,
|
|
||||||
CreateNoWindow = true,
|
|
||||||
WindowStyle = ProcessWindowStyle.Hidden
|
|
||||||
});
|
|
||||||
|
|
||||||
if (waitForExit && process != null)
|
|
||||||
{
|
|
||||||
process.WaitForExit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
116
FastGithub.Dns.DnscryptProxy/DnscryptProxyService.cs
Normal file
116
FastGithub.Dns.DnscryptProxy/DnscryptProxyService.cs
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace FastGithub.Dns.DnscryptProxy
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// DnscryptProxy服务
|
||||||
|
/// </summary>
|
||||||
|
sealed class DnscryptProxyService
|
||||||
|
{
|
||||||
|
private readonly FastGithubConfig fastGithubConfig;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取文件名
|
||||||
|
/// </summary>
|
||||||
|
public string Name => "dnscrypt-proxy";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// DnscryptProxy服务
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fastGithubConfig"></param>
|
||||||
|
public DnscryptProxyService(FastGithubConfig fastGithubConfig)
|
||||||
|
{
|
||||||
|
this.fastGithubConfig = fastGithubConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 启动dnscrypt-proxy
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="cancellationToken"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task StartAsync(CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
var tomlPath = $"{this.Name}.toml";
|
||||||
|
await TomlUtil.SetListensAsync(tomlPath, this.fastGithubConfig.PureDns, cancellationToken);
|
||||||
|
|
||||||
|
foreach (var process in Process.GetProcessesByName(this.Name))
|
||||||
|
{
|
||||||
|
process.Kill();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OperatingSystem.IsWindows())
|
||||||
|
{
|
||||||
|
this.StartDnscryptProxy("-service install", waitForExit: true);
|
||||||
|
this.StartDnscryptProxy("-service start", waitForExit: true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.StartDnscryptProxy(string.Empty, waitForExit: false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 停止dnscrypt-proxy
|
||||||
|
/// </summary>
|
||||||
|
public void Stop()
|
||||||
|
{
|
||||||
|
if (OperatingSystem.IsWindows())
|
||||||
|
{
|
||||||
|
this.StartDnscryptProxy("-service stop", waitForExit: true);
|
||||||
|
this.StartDnscryptProxy("-service uninstall", waitForExit: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var process in Process.GetProcessesByName(this.Name))
|
||||||
|
{
|
||||||
|
process.Kill();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 等待退出
|
||||||
|
/// </summary>
|
||||||
|
public void WaitForExit()
|
||||||
|
{
|
||||||
|
var process = Process.GetProcessesByName(this.Name).FirstOrDefault();
|
||||||
|
if (process != null)
|
||||||
|
{
|
||||||
|
process.WaitForExit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 启动DnscryptProxy进程
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="arguments"></param>
|
||||||
|
/// <param name="waitForExit"></param>
|
||||||
|
private void StartDnscryptProxy(string arguments, bool waitForExit)
|
||||||
|
{
|
||||||
|
var process = Process.Start(new ProcessStartInfo
|
||||||
|
{
|
||||||
|
FileName = OperatingSystem.IsWindows() ? $"{this.Name}.exe" : this.Name,
|
||||||
|
Arguments = arguments,
|
||||||
|
UseShellExecute = true,
|
||||||
|
CreateNoWindow = true,
|
||||||
|
WindowStyle = ProcessWindowStyle.Hidden
|
||||||
|
});
|
||||||
|
|
||||||
|
if (waitForExit && process != null)
|
||||||
|
{
|
||||||
|
process.WaitForExit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 转换为字符串
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return this.Name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -15,7 +15,9 @@ namespace FastGithub
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static IServiceCollection AddDnscryptProxy(this IServiceCollection services)
|
public static IServiceCollection AddDnscryptProxy(this IServiceCollection services)
|
||||||
{
|
{
|
||||||
return services.AddHostedService<DnscryptProxyHostedService>();
|
return services
|
||||||
|
.AddSingleton<DnscryptProxyService>()
|
||||||
|
.AddHostedService<DnscryptProxyHostedService>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
78
FastGithub.Dns.DnscryptProxy/TomlUtil.cs
Normal file
78
FastGithub.Dns.DnscryptProxy/TomlUtil.cs
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Net;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace FastGithub.Dns.DnscryptProxy
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// doml配置工具
|
||||||
|
/// </summary>
|
||||||
|
static class TomlUtil
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 设置监听地址
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="tomlPath"></param>
|
||||||
|
/// <param name="endpoint"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static Task SetListensAsync(string tomlPath, IPEndPoint endpoint, CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
return SetAsync(tomlPath, "listen_addresses", $"['{endpoint}']");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设置指定键的值
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="tomlPath"></param>
|
||||||
|
/// <param name="key"></param>
|
||||||
|
/// <param name="value"></param>
|
||||||
|
public static async Task SetAsync(string tomlPath, string key, object? value, CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
var lines = await File.ReadAllLinesAsync(tomlPath, cancellationToken);
|
||||||
|
var toml = Set(lines, key, value);
|
||||||
|
await File.WriteAllTextAsync(tomlPath, toml, cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设置值
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="lines"></param>
|
||||||
|
/// <param name="key"></param>
|
||||||
|
/// <param name="value"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private static string Set(string[] lines, string key, object? value)
|
||||||
|
{
|
||||||
|
var updated = false;
|
||||||
|
var builder = new StringBuilder();
|
||||||
|
|
||||||
|
foreach (var line in lines)
|
||||||
|
{
|
||||||
|
var span = line.AsSpan();
|
||||||
|
if (span.IsEmpty || span[0] == '#')
|
||||||
|
{
|
||||||
|
builder.AppendLine(line);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var index = span.IndexOf('=');
|
||||||
|
if (index <= 0 || span.Slice(0, index).Trim().SequenceEqual(key) == false)
|
||||||
|
{
|
||||||
|
builder.AppendLine(line);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.Append(key).Append(" = ").AppendLine(value?.ToString());
|
||||||
|
updated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (updated == false)
|
||||||
|
{
|
||||||
|
builder.Append(key).Append(" = ").AppendLine(value?.ToString());
|
||||||
|
}
|
||||||
|
return builder.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -16,7 +16,10 @@ namespace FastGithub.Upgrade
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public ReverseProxyHttpHandler()
|
public ReverseProxyHttpHandler()
|
||||||
{
|
{
|
||||||
this.InnerHandler = new HttpClientHandler();
|
this.InnerHandler = new HttpClientHandler
|
||||||
|
{
|
||||||
|
ServerCertificateCustomValidationCallback = delegate { return true; }
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@ -1,46 +1,43 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFrameworks>net5.0;net6.0</TargetFrameworks>
|
<TargetFrameworks>net5.0;net6.0</TargetFrameworks>
|
||||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||||
<ApplicationIcon>app.ico</ApplicationIcon>
|
<IsWebConfigTransformDisabled>true</IsWebConfigTransformDisabled>
|
||||||
<IsWebConfigTransformDisabled>true</IsWebConfigTransformDisabled>
|
<ApplicationIcon>app.ico</ApplicationIcon>
|
||||||
</PropertyGroup>
|
<ApplicationManifest>app.manifest</ApplicationManifest>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(TargetFramework)' == 'net6.0'">
|
<PropertyGroup Condition="'$(TargetFramework)' == 'net6.0'">
|
||||||
<EnableCompressionInSingleFile>true</EnableCompressionInSingleFile>
|
<EnableCompressionInSingleFile>true</EnableCompressionInSingleFile>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
|
<ItemGroup>
|
||||||
<ApplicationManifest>app.manifest</ApplicationManifest>
|
<PackageReference Include="PInvoke.AdvApi32" Version="0.7.104" />
|
||||||
</PropertyGroup>
|
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="5.0.1" />
|
||||||
|
<ProjectReference Include="..\FastGithub.Dns.DnscryptProxy\FastGithub.Dns.DnscryptProxy.csproj" />
|
||||||
|
<ProjectReference Include="..\FastGithub.Dns\FastGithub.Dns.csproj" />
|
||||||
|
<ProjectReference Include="..\FastGithub.ReverseProxy\FastGithub.ReverseProxy.csproj" />
|
||||||
|
<ProjectReference Include="..\FastGithub.Upgrade\FastGithub.Upgrade.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="PInvoke.AdvApi32" Version="0.7.104" />
|
<None Update="appsettings.github.json">
|
||||||
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="5.0.1" />
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
<ProjectReference Include="..\FastGithub.Dns.DnscryptProxy\FastGithub.Dns.DnscryptProxy.csproj" />
|
</None>
|
||||||
<ProjectReference Include="..\FastGithub.Dns\FastGithub.Dns.csproj" />
|
<None Update="appsettings.json">
|
||||||
<ProjectReference Include="..\FastGithub.ReverseProxy\FastGithub.ReverseProxy.csproj" />
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
<ProjectReference Include="..\FastGithub.Upgrade\FastGithub.Upgrade.csproj" />
|
</None>
|
||||||
</ItemGroup>
|
<None Update="FastGithub.cer">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
<ItemGroup>
|
</None>
|
||||||
<None Update="appsettings.github.json">
|
<None Update="README.html">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
<None Update="appsettings.json">
|
<None Update="README.md">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
<None Update="FastGithub.cer">
|
</ItemGroup>
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</None>
|
|
||||||
<None Update="README.html">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</None>
|
|
||||||
<None Update="README.md">
|
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
|
||||||
</None>
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user