mirror of
https://github.com/tgstation/tgstation-server.git
synced 2026-08-22 20:47:28 +01:00
Merge pull request #1882 from tgstation/noroot
Warns when running TGS as root
This commit is contained in:
@@ -69,6 +69,7 @@ EXPOSE 5000
|
||||
|
||||
ENV General__ValidInstancePaths__0 /tgs_instances
|
||||
ENV FileLogging__Directory /tgs_logs
|
||||
ENV Internal__UsingDocker true
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
|
||||
@@ -130,6 +130,11 @@ namespace Tgstation.Server.Host.Components
|
||||
/// </summary>
|
||||
readonly SwarmConfiguration swarmConfiguration;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="InternalConfiguration"/> for the <see cref="InstanceManager"/>.
|
||||
/// </summary>
|
||||
readonly InternalConfiguration internalConfiguration;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="TaskCompletionSource"/> for <see cref="Ready"/>.
|
||||
/// </summary>
|
||||
@@ -177,6 +182,7 @@ namespace Tgstation.Server.Host.Components
|
||||
/// <param name="platformIdentifier">The value of <see cref="platformIdentifier"/>.</param>
|
||||
/// <param name="generalConfigurationOptions">The <see cref="IOptions{TOptions}"/> containing the value of <see cref="generalConfiguration"/>.</param>
|
||||
/// <param name="swarmConfigurationOptions">The <see cref="IOptions{TOptions}"/> containing the value of <see cref="swarmConfiguration"/>.</param>
|
||||
/// <param name="internalConfigurationOptions">The <see cref="IOptions{TOptions}"/> containing the value of <see cref="internalConfiguration"/>.</param>
|
||||
/// <param name="logger">The value of <see cref="logger"/>.</param>
|
||||
public InstanceManager(
|
||||
IInstanceFactory instanceFactory,
|
||||
@@ -193,6 +199,7 @@ namespace Tgstation.Server.Host.Components
|
||||
IPlatformIdentifier platformIdentifier,
|
||||
IOptions<GeneralConfiguration> generalConfigurationOptions,
|
||||
IOptions<SwarmConfiguration> swarmConfigurationOptions,
|
||||
IOptions<InternalConfiguration> internalConfigurationOptions,
|
||||
ILogger<InstanceManager> logger)
|
||||
{
|
||||
this.instanceFactory = instanceFactory ?? throw new ArgumentNullException(nameof(instanceFactory));
|
||||
@@ -209,6 +216,7 @@ namespace Tgstation.Server.Host.Components
|
||||
this.platformIdentifier = platformIdentifier ?? throw new ArgumentNullException(nameof(platformIdentifier));
|
||||
generalConfiguration = generalConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(generalConfigurationOptions));
|
||||
swarmConfiguration = swarmConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(swarmConfigurationOptions));
|
||||
internalConfiguration = internalConfigurationOptions?.Value ?? throw new ArgumentNullException(nameof(internalConfigurationOptions));
|
||||
this.logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
|
||||
originalConsoleTitle = console.Title;
|
||||
@@ -675,6 +683,11 @@ namespace Tgstation.Server.Host.Components
|
||||
{
|
||||
if (!systemIdentity.CanCreateSymlinks)
|
||||
throw new InvalidOperationException($"The user running {Constants.CanonicalPackageName} cannot create symlinks! Please try running as an administrative user!");
|
||||
|
||||
if (!platformIdentifier.IsWindows && systemIdentity.IsSuperUser && !internalConfiguration.UsingDocker)
|
||||
{
|
||||
logger.LogWarning("TGS is being run as the root account. This is not recommended.");
|
||||
}
|
||||
}
|
||||
|
||||
// This runs before the real socket is opened, ensures we don't perform reattaches unless we're fairly certain the bind won't fail
|
||||
|
||||
@@ -25,6 +25,11 @@
|
||||
/// </summary>
|
||||
public bool UsingSystemD { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// If the server is running inside of a Docker container.
|
||||
/// </summary>
|
||||
public bool UsingDocker { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The base path for the app settings configuration files.
|
||||
/// </summary>
|
||||
|
||||
@@ -24,6 +24,12 @@ namespace Tgstation.Server.Host.Security
|
||||
/// </summary>
|
||||
bool CanCreateSymlinks { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Is this identity a SuperUser for the OS.
|
||||
/// See Administrator on Windows or root on Linux.
|
||||
/// </summary>
|
||||
bool IsSuperUser { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Clone the <see cref="ISystemIdentity"/> creating another copy that must have <see cref="IDisposable.Dispose"/> called on it.
|
||||
/// </summary>
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Mono.Unix.Native;
|
||||
|
||||
namespace Tgstation.Server.Host.Security
|
||||
{
|
||||
/// <summary>
|
||||
@@ -9,6 +11,9 @@ namespace Tgstation.Server.Host.Security
|
||||
/// </summary>
|
||||
sealed class PosixSystemIdentity : ISystemIdentity
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public bool IsSuperUser => Syscall.getuid() == 0;
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Uid => throw new NotImplementedException();
|
||||
|
||||
|
||||
@@ -22,7 +22,10 @@ namespace Tgstation.Server.Host.Security
|
||||
public string Username => userPrincipal?.Name ?? identity!.Name;
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool CanCreateSymlinks => canCreateSymlinks ?? throw new NotSupportedException();
|
||||
public bool CanCreateSymlinks => IsSuperUser;
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool IsSuperUser => isAdmin ?? throw new NotSupportedException();
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="WindowsIdentity"/> for the <see cref="WindowsSystemIdentity"/>.
|
||||
@@ -35,9 +38,9 @@ namespace Tgstation.Server.Host.Security
|
||||
readonly UserPrincipal? userPrincipal;
|
||||
|
||||
/// <summary>
|
||||
/// Backing field for <see cref="CanCreateSymlinks"/>.
|
||||
/// Backing field for <see cref="IsSuperUser"/>.
|
||||
/// </summary>
|
||||
readonly bool? canCreateSymlinks;
|
||||
readonly bool? isAdmin;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="WindowsSystemIdentity"/> class.
|
||||
@@ -49,7 +52,7 @@ namespace Tgstation.Server.Host.Security
|
||||
if (identity.IsAnonymous)
|
||||
throw new ArgumentException($"Cannot use anonymous {nameof(WindowsIdentity)} as a {nameof(WindowsSystemIdentity)}!", nameof(identity));
|
||||
|
||||
canCreateSymlinks = new WindowsPrincipal(identity).IsInRole(WindowsBuiltInRole.Administrator);
|
||||
isAdmin = new WindowsPrincipal(identity).IsInRole(WindowsBuiltInRole.Administrator);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
Reference in New Issue
Block a user