4

I'm building a package containing a web service that needs to listen on port 443. The service itself is written in Go, so I can't use authbind to manage the port permissions. Instead, I've opted to use setcap:

me@buildbox $ setcap CAP_NET_BIND_SERVICE=+eip opt/myservice/myservice
me@buildbox $ getcap opt/myservice/myservice
opt/myservice/myservice = cap_net_bind_service+eip

However, this capability is not preserved when I install the package on my servers.

me@myserver $ apt-get install myservice
...
# installs normally
...
me@myserver $ getcap /opt/myservice/myservice
me@myserver $ # ^ No output == no capabilities

I really don't want this service to be run as root ever, but I'm having trouble coming up with a solution that is preserved when the package is installed. Can I somehow set capabilities in a debian package? Is there another method that achieves the desired end result (service can bind to port 443, but doesn't run as root).

  • 2
    Maybe setup a `postinst` script that sets the capabilities? – Zoredache Jun 16 '16 at 17:15
  • @Zoredache wow. I never knew that was a thing (I'm rather new to debian packaging). Thanks for pointing me in that direction, I'm guessing that will work. – vastlysuperiorman Jun 16 '16 at 17:18
  • BTW, looks like it isn't possible. http://unix.stackexchange.com/questions/156421/can-capabilities-be-specified-in-debian-packages and https://bugs.launchpad.net/ubuntu/+source/debhelper/+bug/1371695 – Zoredache Jun 16 '16 at 17:26
  • @Zoredache it actually works! My postinst contains the line `setcap CAP_NET_BIND_SERVICE=+eip /opt/myservice/myservice`. After installation, the service has the correct capabilities. If you post as an answer, I'll accept. – vastlysuperiorman Jun 16 '16 at 18:19

1 Answers1

0

User Zoredache answered this in the comments. I'm posting this answer to make sure that people finding this question are aware that the problem was resolved.

In the debian package, I added a postinst file to DEBIAN/, which dpkg executes after copying files to the filesystem. The postinst contains the following:

#!/bin/sh
set -e
setcap CAP_NET_BIND_SERVICE=+eip /opt/myservice/myservice

This worked for me. I don't remember now, but I believe the package did need to be installed by a user with sudo access on the destination machine.