We run code inside an Ubuntu [5.15.76-v8+
] Docker container, as part of a test system, which needs to open a socket on a specific interface (ppp0
, created inside the Docker container by pppd
, which is in turn connected to the device under test, also running inside the Docker container), rather than sneaking it out through eth0
.
When this Docker container is run under Raspbian [5.15.76-v8+
], setsockopt()
does this and all is fine:
struct ifreq interface = {0};
int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
snprintf(interface.ifr_name, sizeof(interface.ifr_name), "ppp0");
if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE,
&interface, sizeof(interface)) == 0) {
// Things routed through sock() appear on ppp0
...
However, when running the same Docker container in the same way (this is all done under Jenkins) on Centos8 [4.18.0-408.el8.x86_64
], setsockopt()
returns -1 and errno
is EPERM
.
I understand that setsockopt()
requires CAP_NET_RAW
permissions: can anyone advise why the socket permissions might be different when the Docker container is run on Centos8 and how I can make the Centos8 case work in the same way as the Raspbian case?
In case it is useful, the part of Dockerfile
relevant to pppd
is this:
RUN chown root /usr/sbin/pppd && chmod 4755 /usr/sbin/pppd && \
sed 's/^auth/noauth/' /etc/ppp/options > options && \
cp options /etc/ppp/options && \
rm options
[since this is an internal test system talking to a bit-pipe-under-test rather than a server we have no worries about security] and docker
is run with parameters -i -u username --rm --privileged
.