Skip to content

container not able receive UDP traffic when disabled userland-proxy #2423

Description

@sergey-safarov

Before container is started, docker daemon check available of published port by binding to published port. For sip port 5060 this looks as

[root@aeyears ~]# netstat -anp | grep 5060
udp6       0      0 :::5060                 :::*                                102113/dockerd

If bind successful, then configured iptables rules for container.
Issue rise when inbound UDP packet populate conntrack table when dockerd daemon bound to host port, but iptables rules for container is not populated.

In this case conntrarck tables contains row like

udp      17 17 src=208.68.17.52 dst=192.168.4.16 sport=5060 dport=5060 [UNREPLIED] src=192.168.4.16 dst=208.68.17.52 sport=5060 dport=5060 mark=0 secctx=system_u:object_r:unlabeled_t:s0 use=1

Here you can find substring

dst=192.168.4.16 sport=5060 dport=5060 [UNREPLIED] src=192.168.4.16

Where dst address is packet L3 destination address when packet is received.
And src address of process/daemon bind that receive packet stream.

As you can see here packets received to IP 192.168.4.16 via UDP transport to port 5060 and processed by daemon that bound to socket IP 192.168.4.16 via UDP transport to port 5060.
To this socket is bound dockerd daemon. This daemon silently drop received UDP traffic when userland-proxy disabled.

In this case permanent UDP streams like syslog messages, SIP OPTIONS check newer reach container process and always connected to docker daemon black hole bind.

How it can be reproduced
On other host need to start UDP stream like

export SERVER_IP=217.12.247.220
nc -u ${SERVER_IP} 5060 < /dev/zero

Then on docker host need to populate /etc/docker/daemon.json file like this:

{
  "userland-proxy": false
}

Restart docker daemon

systemctl restart docker

Then start test using command

conntrack -D
docker run --rm=true -d --network=host --name host_bind kamailio/kamailio-ci
sleep 10 \
docker stop host_bind \
docker run -it --rm -p 5060:5060/udp --entrypoint=tcpdump --name tcpdump kamailio/kamailio-ci -ni any

After last command container not able to receive UDP stream started on other host.

How to fix
When userland-proxy disabled and dockerd daemon received packet, then need reset related connection tracking record using command like

conntrack -D \
          --reply-src {dockerd_bind_ip} \
          --proto ${dockerd_bind_proto} \
          --reply-port-src {dockerd_bind_port} \
          --src ${client_source_ip} \
          --sport ${client_source_port}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions