[ASP.NET CORE] non-root container error System.Net.Sockets.SocketException (13): Permission denied

หลังจากปรับ Image ของ .NET Core จากเดิมที่ใน Container จะให้ User root เป็นคนรัน WebAPI ขึ้นมา มาเป็น User Non-Root แทน พอ Start Container ขึ้นมาก็ Error เลยครับ

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

สาเหตุ

  • Non-Root ไม่สามารถ Run Container หากกำหนด Port ต่ำกว่า 1024

แนวทางแก้ไข

  • ดังนั้นต้องมาดู Script ที่สร้าง Container เพื่อมาปรับ Param ของคำสั่งที่เกี่ยวข้อง เช่น ปรับ Port จากเดิมที่กำหนดเป็น 80 มาเป็น Port อื่นๆ เช่น 10456
  • สำหรับใน Blog นี้ ผมจะใช้ Podman มาเป็น container Engine นะครับ
  • ก่อนแก้ไข
version=$1
cerf_file=investapp.ds.p12
cerf_pass='myPassword'
echo "Create invest-service From localhost/invest-service:$version"
podman create -itd \
--name invest-service \
--userns keep-id \
--healthcheck-command 'curl --insecure https://localhost:80/winserv/heartbeat || exit 1' \
--healthcheck-interval 0 \
--runroot /home/BNZContainers \
-p 10456:80\
-e ASPNETCORE_URLS="https://+" \
-e ASPNETCORE_Kestrel__Certificates__Default__Password=$cerf_pass \
-e ASPNETCORE_Kestrel__Certificates__Default__Path=/app/server.p12 \
-v /DSApp1/Config/winserv/appsettings.json:/app/appsettings.json:z  \
-v /DSApp1/Key/winserv/ca/$cerf_file:/app/server.p12:z \
-v /DSApp1/Logs/winserv/:/app/logs/:z \
localhost/wmsl-invest-service:$version
  • หลังแก้ไข ผมได้ปรับ parameter ดังนี้
    • -p 10456:10456
    • -e ASPNETCORE_URLS="https://+:10456"
    • --healthcheck-command (ถ้ามี)
version=$1
cerf_file=investapp.ds.p12
cerf_pass='myPassword'
echo "Create invest-service From localhost/invest-service:$version"
podman create -itd \
--name invest-service \
--userns keep-id \
--healthcheck-command 'curl --insecure https://localhost:10456/winserv/heartbeat || exit 1' \
--healthcheck-interval 0 \
--runroot /home/BNZContainers \
-p 10456:10456 \
-e ASPNETCORE_URLS="https://+:10456" \
-e ASPNETCORE_Kestrel__Certificates__Default__Password=$cerf_pass \
-e ASPNETCORE_Kestrel__Certificates__Default__Path=/app/server.p12 \
-v /DSApp1/Config/winserv/appsettings.json:/app/appsettings.json:z  \
-v /DSApp1/Key/winserv/ca/$cerf_file:/app/server.p12:z \
-v /DSApp1/Logs/winserv/:/app/logs/:z \
localhost/wmsl-invest-service:$version

Reference


Discover more from naiwaen@DebuggingSoft

Subscribe to get the latest posts to your email.