'Trouble creating a FTP connection from within a docker container to an external host
So the setup is as followed: I have a host machine on which i run a docker container. From this i want to open a connection to a ftp server on the web and download a test file. The programm is written in go and works when executed directly on the host machine without the container.
The minimum example script looks as follows and I use the ftp package github.com/jlaffaye/ftp: (This should work out of the box as is - at least it does for me)
package main
import (
"fmt"
"io/ioutil"
"log"
"strings"
"time"
"github.com/jlaffaye/ftp"
)
func main() {
URL := "ftp://speedtest.tele2.net/1MB.zip"
User := "anonymous"
Password := "anonymous"
urlElements := strings.Split(URL, "/")
dialTarget := fmt.Sprintf("%s:%s", urlElements[2], "21")
fmt.Println("Attempting FTP connection to ", dialTarget)
c, err := ftp.Dial(dialTarget, ftp.DialWithTimeout(5*time.Second))
if err != nil {
log.Fatalf("TCP dial failed: %v", err)
}
defer c.Quit()
err = c.Login(User, Password)
if err != nil {
log.Fatalf("FTP login failed: %v", err)
}
defer c.Logout()
data, err := c.Retr(strings.Join(urlElements[3:], "/"))
if err != nil {
log.Fatalf("Failed to get file: %v", err)
}
_, err = ioutil.ReadAll(data)
if err != nil {
log.Fatalf("Failed to read file: %v", err)
}
fmt.Println("success!")
}
Since this code part will be part of a larger container later on running this on the host network with --network=host in docker options is not possible. (Apart this did not work for some reason -> lead to timeouts or EOF errors on dial)
Solution I considered:
Open an ssh-bridge to the target machine. I tried this using the package github.com/elliotchance/sshtunnel which provides a (imo) comprehensive example of how to use it: See here for reference. The idea was to basically tunnel from the container through the host directly onto the target. However while the tunnel returned a connection success, the ftp client still failed with timeouts or EOF errors.
For this reason: Is there a good way to do this? If so which direction would be the best to go in? I am somewhat lost on this, especially since since connecting an samba client to a remote machine works without any issue from within the container for some reason.
Thx in advance for any leads - please let me know if i missed to provide any information/details.
For reference the docker file looks like this:
FROM golang:alpine AS BUILDER
# install certificates to enable usage for http
RUN apk update \
&& apk upgrade \
&& apk add --no-cache \
ca-certificates \
&& update-ca-certificates 2>/dev/null || true
# all prerequsites should be done before this point.
WORKDIR /src
COPY . .
RUN go get -d -v
RUN CGO_ENABLED=0 GOOS=linux GOARCH=arm GOARM=5 go build -o ./out/ftp-test .
FROM scratch
COPY --from=BUILDER /src/out/ftp-test /ftp-test
COPY --from=BUILDER /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
# Run the executable
ENTRYPOINT ["/ftp-test"]
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
