tun interface inside docker not able to read packets from host

血红的双手。 提交于 2021-01-29 17:30:04

问题


I am trying this tutorial for creating and using tun interface. In my case, I want to use it inside a docker container. My host and docker container both are Linux with mknod support. I am trying to get tun interface inside the container to read packets from host but without using --network=host.

Based on the docker run doc, I am mapping host /dev/net/tun inside docker using --device. Then adding capabilities NET_ADMIN (also tried adding MKNOD, NET_RAW but does not seem to help). Then using the example tun reader below; which is example from above tutorial; with code added to create interface; tried to read the packets.

It can read packets from ping on 10.0.0.2 from within the container. But not able to read from ping on host. With --network=host flag to docker run, the tunx interface is created on host and therefore ping works.

My question is, is there a to get it to work without using host network? Do I need any explicit iptables rules to forward traffic between container and host?

tun_alloc function is from this tutorial

docker command

docker run -it --device=/dev/net/tun:/dev/net/tun -cap-add=NET_ADMIN <image>

reader code

int main(void) {
  const char *ifname = "tunx";
  const char *ifaddr = "10.0.0.1/24";
  char tun_name[IFNAMSIZ];
  char buffer[2096];
  int tun_fd = -1;
  char cmd[1024] = "";
  int err = -1;

  strcpy(tun_name, ifname);
  tun_fd = tun_alloc(tun_name, IFF_TUN);  /* tun interface */
  if (tun_fd < 0) {
    fprintf(stderr, "failed to alloc_tun. tun_fd: %d\n", tun_fd);
    exit(1);
  }
  printf("tun_fd: %d\n", tun_fd);

  printf("ip commands \n");

  snprintf(cmd, sizeof(cmd), "/bin/ip addr add dev %s %s", ifname, ifaddr);
  err = system(cmd);
  fprintf(stdout, "Running: %s, err: %d\n", cmd, err);
  if (err < 0) {
          fprintf(stderr, "failed system. Cmd:%s, err: %d (%s)\n", cmd, err, strerror(errno));
          exit(1);
  }

  snprintf(cmd, sizeof(cmd), "/bin/ip link set %s up", ifname);
  err = system(cmd);
  fprintf(stdout, "Running: %s, err: %d\n", cmd, err);
  if (err < 0) {
          fprintf(stderr, "failed system. Cmd:%s, err: %d (%s)\n", cmd, err, strerror(errno));
          exit(1);
  }

  while (1) {
    /* Note that "buffer" should be at least the MTU size of the interface, eg 1500 bytes */
    int nread = read(tun_fd,buffer,sizeof(buffer));
    if(nread < 0) {
      perror("Reading from interface");
      close(tun_fd);
      exit(1);
    }

    /* Do whatever with the data */
    printf("Read %d bytes from device %s\n", nread, tun_name);
  }
  return 0;
}

来源:https://stackoverflow.com/questions/65555551/tun-interface-inside-docker-not-able-to-read-packets-from-host

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!