Open paulgear opened 3 years ago
We need this too. We would like to enforce some of the policies from Azure Policy, which requires our pods to run with runAsNonRoot = true. Could you please fix this, so we can run the images in the most secure way?
thx,
Bart
we are using mcr.microsoft.com/azure-functions/dotnet:3.0 for running azure function apps inside AKS, when run as non-root, and to disallow privilege escalation are not working, workload just silently failed and not logging any errors. want to confirm if this is supported now? if not, can you please also explain the reason why it is not supported as run as non root user since this is a big security concern
I just hit this and it still doesn't appear to be supported. I see this in the logs:
Durable task hub worker started successfully after 28ms ... [ so far so good] Host started (851ms) ... [ nice ] Job host started ... [ but then everything falls apart ] Stopped the listener 'Microsoft.Azure.WebJobs.Extensions.Http.HttpTriggerAttributeBindingProvider+HttpTriggerBinding+NullListener' for function 'MyFunctionName' ... [ repeated for every endpoint, and finally ] Stopping task hub worker. IsGracefulStop: False. InstanceId: . Function: . HubName: MyHub. AppName: . SlotName: . ExtensionVersion: 2.5.1. SequenceNumber: 2. Durable task hub worker is stopping (isForced = True) ... Application is shutting down...
You'd think after the container escape that security features like running as a non-root user would be prioritized.
This should definitely be prioritized
I've had success recently running as a non-root user with the following steps in my own dockerfile that uses the mcr.microsoft.com/azure-functions/dotnet
base image:
nonuser
. (i.e. RUN groupadd
+ RUN useradd
)/azure-functions-host
ASPNETCORE_URLS
to a port above 1024, like 5000
. (e.g. ENV ASPNETCORE_URLS=http://+:5000
)USER nonroot
EXPOSE 5000
Although, I am only running durable functions and timer triggers.
Thanks for the workaround, @wsugarman! We tried it out on my team and it worked great!
With the announcement of .NET using Chiseled Ubuntu Containers and embracing non-root containers, it would be great if Azure Functions followed suit from both a container size and security perspective.
Hey, I can see that a lot of time has passed already. Is there any estimate of when this can be addressed?
I've had success recently running as a non-root user with the following steps in my own dockerfile that uses the
mcr.microsoft.com/azure-functions/dotnet
base image:
- Create a new user like
nonuser
. (i.e.RUN groupadd
+RUN useradd
)- Grant read permissions to the host folder
/azure-functions-host
- Set the environment variable
ASPNETCORE_URLS
to a port above 1024, like5000
. (e.g.ENV ASPNETCORE_URLS=http://+:5000
)- Set the user
USER nonroot
- Expose this higher port
EXPOSE 5000
Although, I am only running durable functions and timer triggers.
Thank you! It also worked for mcr.microsoft.com/azure-functions/python:4-python3.9 image.
Yeah, I also managed to set the non-root user for function app previously, it worked fine with the MS provided azure-function image. forgot to reply in this thread.
@EdmondAndy, can you plz post an example of your dockerfile? I have tried steps provided by wsugerman without luck. Pid 1 always run as root.
Here is an example: https://github.com/wsugarman/durabletask-azurestorage-scaler/blob/bc2559c160fae5dcbbd5882db9452f88afce6aa3/tests/Keda.Scaler.WebJobs.DurableFunctions.Examples/Dockerfile
FROM mcr.microsoft.com/azure-functions/dotnet:4 AS runtime
RUN groupadd nonroot -g 2000 && \
useradd -r -M -s /sbin/nologin -g nonroot -c nonroot nonroot -u 1000 && \
chown -R nonroot:nonroot /azure-functions-host
ENV ASPNETCORE_URLS=http://+:8080 \
AzureFunctionsJobHost__FileWatchingEnabled=false \
AzureFunctionsJobHost__Logging__Console__IsEnabled=true \
AzureFunctionsJobHost__Logging__FileLoggingMode=Never \
AzureWebJobsScriptRoot=/home/site/wwwroot \
DOTNET_EnableDiagnostics=0 \
FUNCTIONS_WORKER_RUNTIME=dotnet
USER nonroot
EXPOSE 8080
@vicrem fyi this is an example which I wrote last year. hopefully it helps
FROM mcr.microsoft.com/azure-functions/dotnet:4
ENV AzureWebJobsScriptRoot=/home/site/wwwroot \
AzureFunctionsJobHost__Logging__Console__IsEnabled=true
EXPOSE 8080
ENV ASPNETCORE_URLS=http://*:8080
COPY . /home/site/wwwroot
RUN chmod +x /home/site/wwwroot/run.sh && sed -i -e 's/\r$//' /home/site/wwwroot/run.sh
RUN useradd -ms /bin/bash -u 1000 appuser && chown -R appuser:appuser /home/site/wwwroot && \
chown -R appuser:appuser /azure-functions-host && chown -R appuser:appuser /FuncExtensionBundles
USER appuser
ENTRYPOINT ["/home/site/wwwroot/run.sh"]
CMD [ "/azure-functions-host/Microsoft.Azure.WebJobs.Script.WebHost" ]
@EdmondAndy/@wsugarman thanks both of you. The container is now running rootless.
I have an issue with running a function in a Docker image based on Node and Go (Custom Handler). We have also enabled authentication with Microsoft as the provider. Basically, everything works until I switch the function image to non-root. I receive a Bad Request (403) and cannot swap the function. Does anyone have an idea?
FROM mcr.microsoft.com/azure-functions/node:4.33.1
ENV AzureWebJobsScriptRoot=/home/site/wwwroot \
AzureFunctionsJobHost__Logging__Console__IsEnabled=true \
ASPNETCORE_URLS=http://+:8080 \
NODE_OPTIONS=--max-http-header-size=32768 \
HOME=/home \
FUNCTIONS_WORKER_RUNTIME=node \
DOTNET_USE_POLLING_FILE_WATCHER=true \
HOST_VERSION=4.33.0 \
ASPNETCORE_CONTENTROOT=/azure-functions-host
COPY functions/ /home/site/wwwroot/
RUN groupadd nonroot -g 2000 && \
useradd -r -M -s /sbin/nologin -g nonroot nonroot -u 1000 && \
chown -R nonroot:nonroot /azure-functions-host && \
chown -R nonroot:nonroot /FuncExtensionBundles && \
chown -R nonroot:nonroot /home/site/wwwroot
USER nonroot
EXPOSE 8080
CMD [ "/azure-functions-host/Microsoft.Azure.WebJobs.Script.WebHost" ]
So, I have this (runing azure function on k8s/aks) and it's working:
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS builder
WORKDIR /build
COPY ./ ./
RUN dotnet publish --configuration Release --output /dist/
RUN dotnet test
FROM mcr.microsoft.com/azure-functions/dotnet:4
ENV AzureWebJobsScriptRoot=/home/site/wwwroot \
ASPNETCORE_URLS=http://+:5000 \
DOTNET_EnableDiagnostics=0
COPY --from=builder /dist/ /home/site/wwwroot
EXPOSE 5000
but when I convert it to non-root it stops working
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS builder
WORKDIR /build
COPY ./ ./
RUN dotnet publish --configuration Release --output /dist/
RUN dotnet test
FROM mcr.microsoft.com/azure-functions/dotnet:4
ENV AzureWebJobsScriptRoot=/home/site/wwwroot \
ASPNETCORE_URLS=http://+:5000 \
DOTNET_EnableDiagnostics=0
COPY --from=builder /dist/ /home/site/wwwroot
RUN apt-get update && apt-get install -y procps
RUN groupadd nonroot -g 2000 && \
useradd -r -M -s /sbin/nologin -g nonroot -c nonroot nonroot -u 1000
RUN chown -R nonroot:nonroot /azure-functions-host
USER nonroot
EXPOSE 5000
The service starts but there is no host.startup / warmup.extensions...only this
Hosting environment: Production
Content root path: /azure-functions-host
Now listening on:
http://[::]:5000/
Application started. Press Ctrl+C to shut down.
So, the point is that the service/container doesn't crash when doing non-root but it somehow doesn't load the app.
Any suggestions what else to try?
Hi everyone,
We use mcr.microsoft.com/azure-functions/dotnet:3.0 to implement function apps via KEDA, and we want to run all of our containers with Azure's "Kubernetes cluster pod security restricted standards for Linux-based workloads" policy. This means we need both to run as non-root, and to disallow privilege escalation via setcap. Could you please consider adding this capability?
Thanks, Paul