Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

.NET 8 isolated process run Docker image as non-root user #10164

Open
dsikorska opened this issue May 15, 2024 · 3 comments
Open

.NET 8 isolated process run Docker image as non-root user #10164

dsikorska opened this issue May 15, 2024 · 3 comments

Comments

@dsikorska
Copy link

Investigative information

Please provide the following:

  • Timestamp: 2024-05-15T10:54:06 UTC
  • Function App version: v4
  • Function App name: func-agsDataRetentionManager-euwe-dev-01
  • Region: West Europe

Context

We updated our function apps to .NET 8 isolated process, then we created Docker images running as root user.
In the Azure Portal everything works as long as function is run by Docker as root user.
Following best practices, we wanted to run Docker container as non-root user - in-built within .NET 8 base image.

Repro steps

  1. Update Dockerfile to run container as non-root in-built user
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
COPY . ./DataRetentionManager
WORKDIR "/src/DataRetentionManager"
RUN mkdir -p /home/site/wwwroot
RUN dotnet publish "DataRetentionManager.csproj" -c Release -o /home/site/wwwroot
 
FROM mcr.microsoft.com/azure-functions/dotnet-isolated:4-dotnet-isolated8.0
ENV AzureWebJobsScriptRoot=/home/site/wwwroot \
    AzureFunctionsJobHost__Logging__Console__IsEnabled=true

COPY --from=build ["/home/site/wwwroot", "/home/site/wwwroot"]

USER $APP_UID
 
EXPOSE 80
EXPOSE 443
ENV ASPNETCORE_HTTP_PORTS 80

HEALTHCHECK NONE

Expected behavior

Azure Function is running correctly.
No additional permissions should be required for in-built user or at least it should be achieved in secure way.

Actual behavior

There are runtime exceptions
image
And here are logs from Azure Portal

2024-05-15T10:54:06.692585735Z: [INFO]        Starting Host (HostId=func-agsDataRetentionManager-euwe-dev-01, InstanceId=94ce87d9-add2-45fd-8129-cb64f18abcaa, Version=4.34.1.1, ProcessId=9, AppDomainId=1, InDebugMode=True, InDiagnosticMode=False, FunctionsExtensionVersion=~4)
2024-05-15T10:54:06.693834049Z: [INFO]  fail: Host.Startup[515]
2024-05-15T10:54:06.693854949Z: [INFO]        A host error has occurred during startup operation 'a4e9a887-da42-4883-8330-aa01a0e6f320'.
2024-05-15T10:54:06.695899371Z: [INFO]        System.UnauthorizedAccessException: Access to the path '/home/LogFiles/Application/Functions/Host' is denied.
2024-05-15T10:54:06.695919371Z: [INFO]         ---> System.IO.IOException: Permission denied
2024-05-15T10:54:06.695925071Z: [INFO]           --- End of inner exception stack trace ---
2024-05-15T10:54:06.695929571Z: [INFO]           at System.IO.FileSystem.CreateDirectory(String fullPath)
2024-05-15T10:54:06.695934171Z: [INFO]           at System.IO.Directory.CreateDirectory(String path)
2024-05-15T10:54:06.696039073Z: [INFO]           at System.IO.Abstractions.DirectoryWrapper.CreateDirectory(String path)
2024-05-15T10:54:06.696079873Z: [INFO]           at Microsoft.Azure.WebJobs.Script.FileUtility.EnsureDirectoryExists(String path) in /src/azure-functions-host/src/WebJobs.Script/Extensions/FileUtility.cs:line 38
2024-05-15T10:54:06.696176874Z: [INFO]           at Microsoft.Azure.WebJobs.Script.ScriptHost.InitializeFileSystem() in /src/azure-functions-host/src/WebJobs.Script/Host/ScriptHost.cs:line 488
2024-05-15T10:54:06.696515178Z: [INFO]           at Microsoft.Azure.WebJobs.Script.ScriptHost.PreInitialize() in /src/azure-functions-host/src/WebJobs.Script/Host/ScriptHost.cs:line 461
2024-05-15T10:54:06.696529978Z: [INFO]           at Microsoft.Azure.WebJobs.Script.ScriptHost.InitializeAsync(CancellationToken cancellationToken) in /src/azure-functions-host/src/WebJobs.Script/Host/ScriptHost.cs:line 278
2024-05-15T10:54:06.696534778Z: [INFO]           at Microsoft.Azure.WebJobs.Script.ScriptHost.StartAsyncCore(CancellationToken cancellationToken) in /src/azure-functions-host/src/WebJobs.Script/Host/ScriptHost.cs:line 259
2024-05-15T10:54:06.696539078Z: [INFO]           at Microsoft.Extensions.Hosting.Internal.Host.StartAsync(CancellationToken cancellationToken)
2024-05-15T10:54:06.696543278Z: [INFO]           at Microsoft.Azure.WebJobs.Script.WebHost.WebJobsScriptHostService.UnsynchronizedStartHostAsync(ScriptHostStartupOperation activeOperation, Int32 attemptCount, JobHostStartupMode startupMode) in /src/azure-functions-host/src/WebJobs.Script.WebHost/WebJobsScriptHostService.cs:line 376
2024-05-15T10:54:06.696554978Z: [INFO]  MS_FUNCTION_AZURE_MONITOR_EVENT 2,func-agsdataretentionmanager-euwe-dev-01.azurewebsites.net,Microsoft.Web/sites/functions/log,FunctionAppLogs,westeurope,"{'appName':'func-agsdataretentionmanager-euwe-dev-01','roleInstance':'6ef9c9795ca7adf6d4220b9465e94987bc1fb6c3766193398f3713e13cd11d7f','message':'A host error has occurred during startup operation a4e9a887-da42-4883-8330-aa01a0e6f320.','category':'Host.Startup','hostVersion':'4.34.1.1','hostInstanceId':'94ce87d9-add2-45fd-8129-cb64f18abcaa','level':'Error','levelId':4,'processId':9,'exceptionDetails':'System.UnauthorizedAccessException : Access to the path /home/LogFiles/Application/Functions/Host is denied. ---> System.IO.IOException : Permission denied\n   End of inner exception\n   at System.IO.FileSystem.CreateDirectory(String fullPath)\n   at System.IO.Directory.CreateDirectory(String path)\n   at System.IO.Abstractions.DirectoryWrapper.CreateDirectory(String path)\n   at Microsoft.Azure.WebJobs.Script.FileUtility.EnsureDirectoryExists(String path) at /src/azure-functions-host/src/WebJobs.Script/Extensions/FileUtility.cs : 38\n   at Microsoft.Azure.WebJobs.Script.ScriptHost.InitializeFileSystem() at /src/azure-functions-host/src/WebJobs.Script/Host/ScriptHost.cs : 488\n   at Microsoft.Azure.WebJobs.Script.ScriptHost.PreInitialize() at /src/azure-functions-host/src/WebJobs.Script/Host/ScriptHost.cs : 461\n   at async Microsoft.Azure.WebJobs.Script.ScriptHost.InitializeAsync(CancellationToken cancellationToken) at /src/azure-functions-host/src/WebJobs.Script/Host/ScriptHost.cs : 278\n   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\n   at async Microsoft.Azure.WebJobs.Script.ScriptHost.StartAsyncCore(CancellationToken cancellationToken) at /src/azure-functions-host/src/WebJobs.Script/Host/ScriptHost.cs : 259\n   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\n   at async Microsoft.Extensions.Hosting.Internal.Host.StartAsync(CancellationToken cancellationToken)\n   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()\n   at async Microsoft.Azure.WebJobs.Script.WebHost.WebJobsScriptHostService.UnsynchronizedStartHostAsync(ScriptHostStartupOperation activeOperation,Int32 attemptCount,JobHostStartupMode startupMode) at /src/azure-functions-host/src/WebJobs.Script.WebHost/WebJobsScriptHostService.cs : 376','exceptionMessage':'Permission denied','exceptionType':'System.IO.IOException','eventId':515,'eventName':'ErrorOccurredDuringStartupOperation'}",05/15/2024 10:54:06

Known workarounds

Set additional permissions to in-built user
RUN chown -R $APP_UID:$APP_UID /azure-functions-host && chown -R $APP_UID:$APP_UID /home && chmod g+s /home

FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
COPY . ./DataRetentionManager
WORKDIR "/src/DataRetentionManager"
RUN mkdir -p /home/site/wwwroot
RUN dotnet publish "DataRetentionManager.csproj" -c Release -o /home/site/wwwroot
 
FROM mcr.microsoft.com/azure-functions/dotnet-isolated:4-dotnet-isolated8.0
ENV AzureWebJobsScriptRoot=/home/site/wwwroot \
    AzureFunctionsJobHost__Logging__Console__IsEnabled=true

COPY --from=build ["/home/site/wwwroot", "/home/site/wwwroot"]
RUN chown -R $APP_UID:$APP_UID /azure-functions-host && chown -R $APP_UID:$APP_UID /home && chmod g+s /home

USER $APP_UID
 
EXPOSE 80
EXPOSE 443
ENV ASPNETCORE_HTTP_PORTS 80

HEALTHCHECK NONE
@jviau
Copy link
Contributor

jviau commented May 15, 2024

@CooperLink - can you take a look at this issue?

@CooperLink
Copy link
Contributor

At this time Linux Dedicated images run in Root. As mentioned in known workarounds, running in Non-root mode can be achieved by assigning permissions to the home and azure-functions-host directories. Prior to dotnet8, the user APP was not in-built to dotnet docker images. To match existing docker images this will not be updated. Customer's that would like to run in user APP in Azure Functions on Linux Dedicated can use custom images with the proposed workarounds or they can migrate to Linux Consumption or the upcoming FlexConsumption sku where images are run in APP by default

@jviau
Copy link
Contributor

jviau commented May 15, 2024

Thanks @CooperLink. Is it safe to close this issue as by design?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants