Windows WSL2 docker-dekstop tftp server in devcontainer

I’ve been trying to add a tftp server to my container, because I need to transfer files between two devices on the local network. I’ve set up a devcontainer on Ubuntu and it worked great, but the goal is to make the devcontainer usable on Windows aswell. When I tried to running the container in windows I was not able to setup the tftp server properly it was unreachable at all even on the host machine.

devcontainer

{
"name": "Python 3",
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
"build": {
	"dockerfile": "Dockerfile"
},
"runArgs": ["--device=/dev/ttyUSB0", "--privileged","--network=host", "-P"],
// Features to add to the dev container. More info: https://containers.dev/features.
// "features": {},

// Use 'forwardPorts' to make a list of ports inside the container available locally.
//"forwardPorts": ["5002:5002"],

// Use 'postCreateCommand' to run commands after the container is created.
// "postCreateCommand": "pip3 install --user -r requirements.txt",
"postStartCommand": "chmod 777 -R bashscripts && bashscripts/configure_tftp.sh && service tftpd-hpa start && flask run --host 0.0.0.0 --port 5050",
"customizations": {
	"vscode": {
		"extensions": [
			"mhutchie.git-graph",
			"ms-azuretools.vscode-docker",
			"ms-python.python",
			"ecmel.vscode-html-css",
			"ms-vscode.vscode-typescript-next"
		]
	}
},

// Configure tool-specific properties.
// "customizations": {},
"mounts": [
	"source=${localEnv:HOME}${localEnv:USERPROFILE}/Downloads,target=/home/vscode/Downloads,type=bind,consistency=cached"
  ]
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
// "remoteUser": "root"

}

Dockerfile

FROM python:3.11
COPY requirements.txt ./

RUN pip install -r requirements.txt 
RUN apt-get update 
RUN apt-get install -y tftpd-hpa xinetd nano 
RUN mkdir /tftpboot && chmod -R 777 /tftpboot && chown -R nobody /tftpboot

configure_tftp.sh

#!/bin/bash
config='# /etc/default/tftpd-hpa TFTP_USERNAME="nobody" TFTP_DIRECTORY="/tftpboot" TFTP_ADDRESS="0.0.0.0:69" TFTP_OPTIONS="-s -c"
service tftpd-hpa stop 
rm /etc/default/tftpd-hpa 
echo "$config" | tee -a /etc/default/tftpd-hpa 
service tftpd-hpa restart

Any suggestions on how to make it work on Windows?

Port 69 is just the control port. Google consulting says the data connection uses a different port range. You need to identify (and ideally configure) and publish the port range for the data connection as well.

You might want to make sure the port range you want to publish is not bigger than necessary, as every additional published port will slow down container start, as the ports will be published one by one (yes, even if a range is published)

Note: I don’t use tftp-hpa and can not tell you how to configure the range for the data connection.

Thanks for the response. I’ve launched this container on ubuntu and it worked with only the 69 port fowarded. But if i had to port foward the whole range it would be all ports above 1023, since it uses a different port for each packet, so I dont believe port fowarding all port above 1023 is viable. Also what I’ve found when port fowarding the devcontainer it added +1 to the port. Have you came across this issue?
Screenshot from 2023-05-15 08-27-32

If you just want another container in the same container network to access tftp-pha, it should work as published ports don’t matter in this scenario.

But, if you want your windows host or other lan devices to use it, it gets more complicated…

It seems if the kernel is compiled with nf_conntrack_tftp and nf_nat_tftp, publishing port 69/udp indeed would be enough. WSL2 does not support to load modules, it requires a custom kernel with the modules compiles into the kernel. Google should yield plenty of results on how to build a custom kernel for WSL2.

If building a custom kernel is not feasible for you then, you still need to pin down the port range for the data connection and publish it.

Though, I don’t know if any of this will actually work, as I don’t know what ftpt-hpa tells the client over the command connection, when it it tells the exported port for the data connection. If it’s just a port, it should be fine, if it’s ip:port then you need to figure out how to make it return the (hopefully static) lan ip of your windows host.

Sadly, I need another lan device to access the tftp server.

yeah building a custom kernel is not in my expertise :grinning:

I’ve had ideas of making the container to be more like a vm to connect to the router and be assign an IP, but I couldnt get that to work or pass the wsl NIC to the container.

I tried passing a range of ports, but as you said starting the container took way too long

Actually it seems way easier than that.

Can you try if this compose file works for your:

version: '2.4'

services:
  tftpd-hpa:
    image: 3x3cut0r/tftpd-hpa
    environment:
        TZ: Europe/Berlin
    command:
    - in.tftpd --foreground --address 0.0.0.0:69 --user tftp  --create --port-range 4000:4030 --map-file /mapfile --secure --verbose --verbosity 3 /tftpboot
    volumes:
      - ./files:/tftpboot
    ports:
      - 69:69/udp
      - 4000:4030/udp

If I am not mistaken --port-range 4000:4030 sets the port range for the data connection, which allows publishing a smaller port range.

Really appreciate the reply, I tried this compose file on my ubuntu machine and on my windows machine. On the Ubuntu machine it worked great I could get the file from the host machine and from any other device on the network. However on the windows machine which I need it to work on, it wouldn’t budge. Couldn’t get it to work it only worked inside the container. Unless I’m really missing something with the networking ? There is the host machine ip, host wsl adapter ip, wsl ip and docker container ip and I probably tried getting the file from all of them, but I keep getting “Connect request failed”. I’ve read there are problems with WSL and UDP packages could it be it’s just not possible for the time being to make a tftp server with docker windos?

Indeed, it looks like udp packages are not forwarded.

I have seen people suggesting using the ip of the wsl distribution, to facilitate udp communication between the Windows host and the WSL2 distribution. Of course other devices in your lan won’t be able to do this.