Zigbee2MqttAssistant icon indicating copy to clipboard operation
Zigbee2MqttAssistant copied to clipboard

[BUG] System.Net.Sockets.SocketException (13): Permission denied

Open wwebers opened this issue 4 years ago • 9 comments

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, Func2 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_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, Func2 createBinding) at Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer.StartAsync[TContext](IHttpApplication1 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

wwebers avatar Mar 26 '20 16:03 wwebers

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 avatar Mar 30 '20 21:03 magpern

@magpern Same here :-)

carldebilly avatar Mar 31 '20 13:03 carldebilly

@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?

wwebers avatar Mar 31 '20 13:03 wwebers

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.

carldebilly avatar Apr 01 '20 00:04 carldebilly

If it work... could you make a PR documenting this in the README.md, please? ;-)

carldebilly avatar Apr 01 '20 00:04 carldebilly

Sure, as soon as I find a minute.

wwebers avatar Apr 01 '20 14:04 wwebers

Did it worked?

carldebilly avatar Apr 01 '20 15:04 carldebilly

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

wwebers avatar Apr 02 '20 15:04 wwebers

looks like on docker 20.10.17 this issue is not happening. on 19.03 it happens.

fragpit avatar Jul 07 '22 08:07 fragpit