Search code examples
python-3.xftpftp-server

How do I make a python FTP server PUBLIC?


I have made an FTP server with Pyftpdlib and I would like to be able to connect to the server from another country/IP and I've tried to upload my script (in exe form) to a friend in another part of the country and I could not connect (simple timeout/invalid err). How do I connect to an ftp server that is not near me?

Server

from pyftpdlib.authorizers import DummyAuthorizer
from pyftpdlib.handlers import FTPHandler
from pyftpdlib.servers import FTPServer
import requests

import mysql.connector
sqlpass = "THIS ISNT THE PASSWORD"

def ftp_main():
    mydb = mysql.connector.connect(
        host="remotemysql.com",
        port="3306",
        user="NOT TELLING",
        passwd=sqlpass,
        database="NO THANKS"
    )
    mycursor = mydb.cursor()

    mycursor.execute("SELECT Username, Password FROM NO-THANKS")
    myresult = mycursor.fetchall()
    Username, Password = myresult[0]
    print(Username + " " + Password)


    authorizer = DummyAuthorizer()


    authorizer.add_user(Username, Password, 'C:/', perm='elradfmwMT')
    authorizer.add_anonymous('C:/')


    handler = FTPHandler
    handler.authorizer = authorizer

    handler.banner = "Test Banner"



    # Instantiate FTP server class and listen on 0.0.0.0:2121
    address = ('0.0.0.0', 21)
    server = FTPServer(address, handler)


    # start ftp server
    server.serve_forever()


ftp_main()

Client

from ftplib import FTP

ftp = FTP('104.193.20.211')
ftp.login("user", "pass")

ftp.retrlines('LIST')
ftp.cwd("Users/TEST/Desktop")
ftp.retrlines('LIST')

getfile = 'test1.txt'
command = 'RETR'

ftp.retrbinary(command + " " + getfile, open('test1.txt', 'wb').write)

I expect to connect and be able to list files, but I just cannot connect.


Solution

  • (From what you say I assume that it does not work only if you are connecting to remote network.)

    Because you have problem with connecting, it seems like problem is caused by network. From programming point of view, it shouldn't matter if you connect to IP on your local network or not.

    Check for these possible issues:

    • Server is behind NAT: Typical consumer router performs network address translation between public and private addresses. It's useful when your ISP provides you with single IP, but you want to use multiple devices. When typical home router sees packet from local computer to somewhere in internet, it changes it's source IP to IP provided by your ISP, changes source port if necessary, and remembers this connection. Router can later use this remembered information to translate everything back when reply arrives. In this case, you can create connections only from inside of local network. If you want to receive connection from internet, you'll have to explicitly set which computer on local network should receive this connection. Search for "port forwarding" or "virtual servers" or something similar in routers settings. Some protocols (like FTP) have problems with NATs, your router will need to support these application protocols.
    • There is firewall somewhere on network, or OS on server side doesn't allow using low port numbers (this is less likely. You would probably get some error on server side).