Set Kestrel Unix socket file permissions in ASP.NET Core?

女生的网名这么多〃 提交于 2020-03-04 20:31:43

问题


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.

What is a simple and reliable method to ensure Kestrel's Unix socket permissions are opened up on creation?


回答1:


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.

Code for Chmod class largely lifted from: https://silvercircle.github.io/2018/08/26/serving-net-core-kestrel-linux-unix-sockets/

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


来源:https://stackoverflow.com/questions/60272453/set-kestrel-unix-socket-file-permissions-in-asp-net-core

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!