Add option to change unix socket permissions

There is probably no way to do it when creating the socket
This commit is contained in:
knackebrot 2022-01-16 22:32:10 +01:00
parent bb7916767c
commit 52c61bd06f
2 changed files with 66 additions and 14 deletions

View File

@ -5,6 +5,7 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Net; using System.Net;
using System.Reflection; using System.Reflection;
using System.Runtime.InteropServices;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -198,6 +199,13 @@ namespace Jellyfin.Server
try try
{ {
await webHost.StartAsync(_tokenSource.Token).ConfigureAwait(false); await webHost.StartAsync(_tokenSource.Token).ConfigureAwait(false);
if (startupConfig.UseUnixSocket() && Environment.OSVersion.Platform == PlatformID.Unix)
{
var socketPath = GetUnixSocketPath(startupConfig, appPaths);
SetUnixSocketPermissions(startupConfig, socketPath);
}
} }
catch (Exception ex) when (ex is not TaskCanceledException) catch (Exception ex) when (ex is not TaskCanceledException)
{ {
@ -327,20 +335,7 @@ namespace Jellyfin.Server
// Bind to unix socket (only on unix systems) // Bind to unix socket (only on unix systems)
if (startupConfig.UseUnixSocket() && Environment.OSVersion.Platform == PlatformID.Unix) if (startupConfig.UseUnixSocket() && Environment.OSVersion.Platform == PlatformID.Unix)
{ {
var socketPath = startupConfig.GetUnixSocketPath(); var socketPath = GetUnixSocketPath(startupConfig, appPaths);
if (string.IsNullOrEmpty(socketPath))
{
var xdgRuntimeDir = Environment.GetEnvironmentVariable("XDG_RUNTIME_DIR");
if (xdgRuntimeDir == null)
{
// Fall back to config dir
socketPath = Path.Join(appPaths.ConfigurationDirectoryPath, "socket.sock");
}
else
{
socketPath = Path.Join(xdgRuntimeDir, "jellyfin-socket");
}
}
// Workaround for https://github.com/aspnet/AspNetCore/issues/14134 // Workaround for https://github.com/aspnet/AspNetCore/issues/14134
if (File.Exists(socketPath)) if (File.Exists(socketPath))
@ -664,5 +659,49 @@ namespace Jellyfin.Server
return "\"" + arg + "\""; return "\"" + arg + "\"";
} }
private static string GetUnixSocketPath(IConfiguration startupConfig, IApplicationPaths appPaths)
{
var socketPath = startupConfig.GetUnixSocketPath();
if (string.IsNullOrEmpty(socketPath))
{
var xdgRuntimeDir = Environment.GetEnvironmentVariable("XDG_RUNTIME_DIR");
var socketFile = "jellyfin.sock";
if (xdgRuntimeDir == null)
{
// Fall back to config dir
socketPath = Path.Join(appPaths.ConfigurationDirectoryPath, socketFile);
}
else
{
socketPath = Path.Join(xdgRuntimeDir, socketFile);
}
}
return socketPath;
}
private static void SetUnixSocketPermissions(IConfiguration startupConfig, string socketPath)
{
var socketPerms = startupConfig.GetUnixSocketPermissions();
if (!string.IsNullOrEmpty(socketPerms))
{
[DllImport("libc")]
static extern int chmod(string pathname, int mode);
var exitCode = chmod(socketPath, Convert.ToInt32(socketPerms, 8));
if (exitCode < 0)
{
_logger.LogError("Failed to set Kestrel unix socket permissions to {SocketPerms}, return code: {ExitCode}", socketPerms, exitCode);
}
else
{
_logger.LogInformation("Kestrel unix socket permissions set to {SocketPerms}", socketPerms);
}
}
}
} }
} }

View File

@ -49,6 +49,11 @@ namespace MediaBrowser.Controller.Extensions
/// </summary> /// </summary>
public const string UnixSocketPathKey = "kestrel:socketPath"; public const string UnixSocketPathKey = "kestrel:socketPath";
/// <summary>
/// The permissions for the unix socket.
/// </summary>
public const string UnixSocketPermissionsKey = "kestrel:socketPermissions";
/// <summary> /// <summary>
/// Gets a value indicating whether the application should host static web content from the <see cref="IConfiguration"/>. /// Gets a value indicating whether the application should host static web content from the <see cref="IConfiguration"/>.
/// </summary> /// </summary>
@ -97,5 +102,13 @@ namespace MediaBrowser.Controller.Extensions
/// <returns>The unix socket path.</returns> /// <returns>The unix socket path.</returns>
public static string GetUnixSocketPath(this IConfiguration configuration) public static string GetUnixSocketPath(this IConfiguration configuration)
=> configuration[UnixSocketPathKey]; => configuration[UnixSocketPathKey];
/// <summary>
/// Gets the permissions for the unix socket from the <see cref="IConfiguration" />.
/// </summary>
/// <param name="configuration">The configuration to read the setting from.</param>
/// <returns>The unix socket permissions.</returns>
public static string GetUnixSocketPermissions(this IConfiguration configuration)
=> configuration[UnixSocketPermissionsKey];
} }
} }