问题描述
可以将Kestrel配置为使用Unix套接字与反向代理(即nginx)进行通信,以获取轻微的性能优势.但是,每次kestrel服务器停止/启动时,都会删除并重新创建套接字文件,从而重置套接字的权限,并取决于系统配置,从而阻止nginx访问套接字.
Kestrel can be configured to use a Unix socket to communicate with a reverse proxy (i.e. nginx) for a slight performance advantage. However, the socket file is deleted and recreated each time the kestrel server stops/starts, resetting the socket's permissions and depending on system configuration, blocking nginx from accessing the socket.
一种简单可靠的方法来确保在创建时打开Kestrel的Unix套接字权限?
What is a simple and reliable method to ensure Kestrel's Unix socket permissions are opened up on creation?
推荐答案
下面的示例Program.Main通过P/Invoke演示了chmod的用法.此解决方案允许在Windows上使用托管套接字,并通过appsettings.json配置ListenUnixSocket
时切换到libuv,在这种情况下,在启动时直接调用chmod
来建立套接字权限.
The following sample Program.Main demonstrates the use of chmod via P/Invoke. This solution allows for use of managed sockets on Windows and switches to libuv when ListenUnixSocket
is configured via appsettings.json, and in that case, calls chmod
directly on startup to establish socket permissions.
Chmod
类的代码很大程度上来自于: https://silvercircle.github.io/2018/08/26/serving-net-core-kestrel-linux-unix-sockets/
Code for Chmod
class largely lifted from: https://silvercircle.github.io/2018/08/26/serving-net-core-kestrel-linux-unix-sockets/
UseLibuv
需要通过NuGet依赖Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv
.
UseLibuv
requires dependency on Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv
via NuGet.
namespace UnixSocketDemo
{
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using System;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using static System.String;
public class Program
{
private static string _unixSocket = null;
public static async Task Main(string[] args)
{
var webHost = BuildWebHost(args);
await webHost.StartAsync();
if (!IsNullOrWhiteSpace(_unixSocket))
Chmod.Set(_unixSocket);
await webHost.WaitForShutdownAsync();
}
public static IWebHost BuildWebHost(string[] args)
{
var builder = WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostingContext, config) => config.SetBasePath(Directory.GetCurrentDirectory()))
.UseStartup<Startup>();
var config = new ConfigurationBuilder().AddJsonFile("appsettings.json").Build();
var kestrelConfig = config.GetSection("Kestrel");
if (kestrelConfig.Exists())
{
_unixSocket = kestrelConfig.GetValue<string>("ListenUnixSocket");
if (!IsNullOrWhiteSpace(_unixSocket))
builder.UseLibuv();
builder.ConfigureKestrel((hostingContext, serverOptions) =>
{
serverOptions.Configure(kestrelConfig);
if (!IsNullOrWhiteSpace(_unixSocket))
serverOptions.ListenUnixSocket(_unixSocket);
});
}
return builder.Build();
}
private static class Chmod
{
[DllImport("libc", EntryPoint="chmod", SetLastError = true)]
[SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "interop")]
private static extern int chmod(string pathname, int mode);
// user permissions
const int S_IRUSR = 0x100;
const int S_IWUSR = 0x80;
const int S_IXUSR = 0x40;
// group permission
const int S_IRGRP = 0x20;
const int S_IWGRP = 0x10;
const int S_IXGRP = 0x8;
// other permissions
const int S_IROTH = 0x4;
const int S_IWOTH = 0x2;
const int S_IXOTH = 0x1;
public static void Set(string filename)
{
const int _0755 =
S_IRUSR | S_IXUSR | S_IWUSR
| S_IRGRP | S_IXGRP | S_IWGRP
| S_IROTH | S_IXOTH | S_IWOTH;
if (0 != chmod(Path.GetFullPath(filename), (int)_0755))
throw new Exception("Could not set Unix socket permissions");
}
}
}
}
这篇关于在ASP.NET Core中设置Kestrel Unix套接字文件权限?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!