Azure / azure-functions-host

The host/runtime that powers Azure Functions
https://functions.azure.com
MIT License
1.92k stars 442 forks source link

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

Open dsikorska opened 4 months ago

dsikorska commented 4 months ago

Investigative information

Please provide the following:

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 \ AzureFunctionsJobHostLoggingConsole__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](https://github.com/Azure/azure-functions-host/assets/32565136/7b76147b-90c9-4f35-9783-1cb4cf8ee190)
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 \ AzureFunctionsJobHostLoggingConsole__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 commented 4 months ago

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

CooperLink commented 4 months ago

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 commented 4 months ago

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

peruzzof commented 2 months ago

Considering that all .Net prior versions reached EOL, and the only still being supported is 8 this decision could be reviewed?

CooperLink commented 5 days ago

@peruzzof this decision is being reviewed and I will keep this incident open until I am able to provide final resolution. Currently under review is introducing a breaking change to run Dedicated images in user APP defined as standard in dotnet8