1

We have a Perl script we've been using (launched from crontab) for several years to upload images using Net::FTP. Recently we began to notice problems where the images were not uploading and errors were appearing in the logs.

In troubleshooting, I've found that presently the program works just fine when launched from cmd line, but when launched from crontab it errors consistently. On the remote server, I can see in the FTP log that the connection is still active, the client is changing directories but the STOR command never appears as it does under normal circumstance. On the client side, when the ftp->put is issued, the response appears to be '227 Entering Passive Mode'

I've tried everything I can think of to track down the cause (firewalls, ephemeral ports, memory leaks) but so far my only solution is to run it manually from the cmd line.

Does anyone have any idea what might be the cause of this problem?

Update: here is some output from Debug => 1:

When run from crontab and it fails (the last line 'ERROR' is from the perl script and includes the $ftp->message which is "Entering Passive Mode"):

Net::FTP=GLOB(0xa004910)>>> CWD /images/shots
Net::FTP=GLOB(0xa004910)<<< 250 CWD command successful
Net::FTP=GLOB(0xa004910)>>> PASV
Net::FTP=GLOB(0xa004910)<<< 227 Entering Passive Mode (181,71,41,114,114,112).
ERROR: Couldn't put file /home/user/data/shot/212/212474.000078.jpg to f/4/f41891045708388275a0b1d1fe8a34fa.jpg on 127.0.0.1 because Entering Passive Mode (181,71,41,114,114,112).

When run from command line and it succeeds:

Net::FTP=GLOB(0x8619170)>>> CWD /images/shots
Net::FTP=GLOB(0x8619170)<<< 250 CWD command successful
Net::FTP=GLOB(0x8619170)>>> PASV
Net::FTP=GLOB(0x8619170)<<< 227 Entering Passive Mode (181,71,41,114,113,179).
Net::FTP=GLOB(0x8619170)>>> STOR 5/6/569e214479a6f99f5bdf920e75f8351e.jpg
Net::FTP=GLOB(0x8619170)<<< 150 Opening BINARY mode data connection for 5/6/569e214479a6f99f5bdf920e75f8351e.jpg
Net::FTP=GLOB(0x8619170)<<< 226 Transfer complete

And here's the portion of the script that's doing this:

      if ( ! ( $ftp->put($src_file, $target_file) ) ) {
        print STDERR "ERROR: Couldn't put file $src_file to $target_file on $ftp_host because " . $ftp->message . "\n";
      } else {
        $mv_result = 1;
      }

The server runs stunnel so the FTP connection is initiated through a port on the localhost (127.0.0.1)

Update: OK I figured out what's going on, there's an argument passed in from crontab that tells it which network to use. Turns out the modem on that network is going bad and I stupidly wasn't passing that argument on cmd line, our default network works great. we just need a new modem for our dedicated upload line. thanks a lot for your help Steffen.

  • Please use Debug => 1 setting for Net::FTP so that it logs all commands. Then compare the output you get from the non-working cronjob to the output from the working command line. – Steffen Ullrich Jul 17 '14 at 19:19
  • thanks Steffen, run from cmd this line if ( ! ( $ftp->put($src_file, $target_file) ) ) { produces this output Net::FTP=GLOB(0x8619170)>>> STOR but from crontab the STOR never shows up. – user16081-JoeT Jul 17 '14 at 19:56
  • Is this really the only difference? How about the PORT/PASV command that must be before the STOR? – Steffen Ullrich Jul 17 '14 at 20:15
  • Thanks for trying to help Steffen; I've updated my question with the debug output and the snippet of the script that does this. – user16081-JoeT Jul 17 '14 at 22:15
0

The server runs stunnel so the FTP connection is initiated through a port on the localhost (127.0.0.1)

I doubt this will work. FTP needs a control connection which you might tunnel through stunnel. But additionally to this it needs data connections for each data transfer (STOR, RETR, LIST...).

Do you really use the same setup on the working command line?

<<< 227 Entering Passive Mode (181,71,41,114,114,112).

This means, that the server wants to have the data connection on IP 181.71.41.114, port 28024 (114*245+112). Net::FTP will thus try to connect to this address directly, because it does not know anything about a tunnel and would also not be able to deal with it. I assume you have the stunnel because direct connection to the target server does not work, so this connection attempt will fail.

| improve this answer | |
  • Yes I used the exact same program from cmd line, and yes this exact same program / configuration has worked for years. We're using stunnel to initiate the connection through a proxy because the remote FTP server is firewalled on port 21, but has its ephemeral ports open to the world. Anyway, thanks for trying. – user16081-JoeT Jul 18 '14 at 19:56
  • OK I figured out what's going on, there's an argument passed in from crontab that tells it which network to use. Turns out the modem on that network is going bad and I stupidly wasn't passing that argument on cmd line, our default network works great. we just need a new modem for our dedicated upload line. thanks a lot for your help Steffen. – user16081-JoeT Jul 19 '14 at 3:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.