Zigbee2MqttAssistant
Zigbee2MqttAssistant copied to clipboard
[BUG] System.Net.Sockets.SocketException (13): Permission denied
Describe the bug
When trying to start the docker container with another user than root, I receive an exception.
To Reproduce
Steps to reproduce the behavior: docker run --user 1000:1000 -p 8880:8880 -e "Z2MA_SETTINGS__MQTTSERVER=my.mqtt.server" carldebilly/zigbee2mqttassistant
Expected behavior Process should start just fine with UID=1000
Steps I took to try resolve the problem
Have to start the container with UID=0
Pertinent logs
Starting Zigbee2MqttAssistant v0.3.147+Branch.master.Sha.92d831d1df50a48c4a2fd38c201e9465dc7e88dd...
warn: Microsoft.AspNetCore.DataProtection.Repositories.EphemeralXmlRepository[50]
Using an in-memory repository. Keys will not be persisted to storage.
warn: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[59]
Neither user profile nor HKLM registry available. Using an ephemeral key repository. Protected data will be unavailable when application exits.
warn: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[35]
No XML encryptor configured. Key {6608132c-8484-4a30-86b4-af7e2d2fbdd4} may be persisted to storage in unencrypted form.
crit: Microsoft.AspNetCore.Server.Kestrel[0]
Unable to start Kestrel.
System.Net.Sockets.SocketException (13): Permission denied
at System.Net.Sockets.Socket.UpdateStatusAfterSocketErrorAndThrowException(SocketError error, String callerName)
at System.Net.Sockets.Socket.DoBind(EndPoint endPointSnapshot, SocketAddress socketAddress)
at System.Net.Sockets.Socket.Bind(EndPoint localEP)
at Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.SocketConnectionListener.Bind()
at Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.SocketTransportFactory.BindAsync(EndPoint endpoint, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer.<>c__DisplayClass21_01.<<StartAsync>g__OnBind|0>d.MoveNext() --- End of stack trace from previous location where exception was thrown --- at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.BindEndpointAsync(ListenOptions endpoint, AddressBindContext context) at Microsoft.AspNetCore.Server.Kestrel.Core.ListenOptions.BindAsync(AddressBindContext context) at Microsoft.AspNetCore.Server.Kestrel.Core.AnyIPListenOptions.BindAsync(AddressBindContext context) at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.AddressesStrategy.BindAsync(AddressBindContext context) at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.BindAsync(IServerAddressesFeature addresses, KestrelServerOptions serverOptions, ILogger logger, Func
2 createBinding)
at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer.StartAsync[TContext](IHttpApplication1 application, CancellationToken cancellationToken) Unhandled exception. System.Net.Sockets.SocketException (13): Permission denied at System.Net.Sockets.Socket.UpdateStatusAfterSocketErrorAndThrowException(SocketError error, String callerName) at System.Net.Sockets.Socket.DoBind(EndPoint endPointSnapshot, SocketAddress socketAddress) at System.Net.Sockets.Socket.Bind(EndPoint localEP) at Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.SocketConnectionListener.Bind() at Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.SocketTransportFactory.BindAsync(EndPoint endpoint, CancellationToken cancellationToken) at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer.<>c__DisplayClass21_0
1.<<StartAsync>g__OnBind|0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.BindEndpointAsync(ListenOptions endpoint, AddressBindContext context)
at Microsoft.AspNetCore.Server.Kestrel.Core.ListenOptions.BindAsync(AddressBindContext context)
at Microsoft.AspNetCore.Server.Kestrel.Core.AnyIPListenOptions.BindAsync(AddressBindContext context)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.AddressesStrategy.BindAsync(AddressBindContext context)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.AddressBinder.BindAsync(IServerAddressesFeature addresses, KestrelServerOptions serverOptions, ILogger logger, Func2 createBinding) at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer.StartAsync[TContext](IHttpApplication
1 application, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Hosting.WebHost.StartAsync(CancellationToken cancellationToken)
at Microsoft.AspNetCore.Hosting.WebHostExtensions.RunAsync(IWebHost host, CancellationToken token, String startupMessage)
at Microsoft.AspNetCore.Hosting.WebHostExtensions.RunAsync(IWebHost host, CancellationToken token, String startupMessage)
at Microsoft.AspNetCore.Hosting.WebHostExtensions.RunAsync(IWebHost host, CancellationToken token)
at Microsoft.AspNetCore.Hosting.WebHostExtensions.Run(IWebHost host)
at Zigbee2MqttAssistant.Program.Main(String[] args) in d:\a\1\s\Zigbee2MqttAssistant\Program.cs:line 14
Is this really a bad thing? Z2MA is running in its own docker container, if it can be adim in this bubble, does that do any bad? I google it and it looks like it is a microsoft problem... anyhow..
Just so you all know, the last week there has been like 7 new bugs/issues/requests. I/we (@carldebilly) are not ignoring them, it is just a fact that the SARS-Covid-19 virus is causing some problems focusing on this project. Day-job is in quarantine, meaning normal work hours vary, and available extra hours are limited. I/we will get back on this when things settle down.
@magpern Same here :-)
@magpern Well, maybe it's a Microsoft thing. However, processes inside Docker with "root" UID are running with "root" permission even outside the container. A successful attack on z2massist will therefore expose the host as well. If that's fine for you (or Microsoft).... not for me. And this has nothing to do with Corona, but with security-by-design.
See also https://github.com/dotnet/aspnetcore/issues/4699
Maybe using another port than 80 for Docker will do?
You can change the default port to something higher than 1024 if you want...
The fix is described in issue https://github.com/yllibed/Zigbee2MqttAssistant/issues/151#issuecomment-571297379 and https://github.com/yllibed/Zigbee2MqttAssistant/issues/67#issuecomment-540004743.
If it work... could you make a PR documenting this in the README.md
, please? ;-)
Sure, as soon as I find a minute.
Did it worked?
I did not really succeed in fixing this inside your code (am not a .Net developer). However, I found that adding the environment variable:
"ASPNETCORE_URLS=http://+:8880"
to my docker-compose file solved the problem. Now, the Kestrel server listens to port 8880 and I can run the container as a non-root user.
As such my docker-compose file looks like this:
version: '3.7'
services:
z2massist:
container_name: z2massist
image: "carldebilly/zigbee2mqttassistant"
restart: always
network_mode: host
ports:
- "8880:8880"
environment:
- TZ=Europe/Stockholm
- Z2MA_SETTINGS__MQTTSERVER=my.mqtt.server
- ASPNETCORE_URLS=http://+:8880
user: "${UID:?err}:20"
BTW: The Microsoft article recommends to not to use the older WebHost:
https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/web-host?view=aspnetcore-3.1
looks like on docker 20.10.17 this issue is not happening. on 19.03 it happens.