编程语言:python
主要模块:pyftpdlib
代码格式方面没有经过整理,根据实际需求修改!
ftphome文件夹是服务器的工作目录
ftpserver.log是服务器端日志文件,(启动时加上‘-l’参数,就会写入日志文件)
white.txt是白名单,白名单里面的IP才被允许访问
#coding=utf-8
from hashlib import md5
import os,sys,logging,getopt
from pyftpdlib.authorizers import DummyAuthorizer,AuthenticationFailed
from pyftpdlib.handlers import FTPHandler
from pyftpdlib.handlers import ThrottledDTPHandler
from pyftpdlib.servers import ThreadedFTPServer
ftp_port=2121
maxcons=100
maxcons_per_ip=5
read_limit=30720
write_limit=30720
flag=0
log=0
logpath='./'
jobpath='./ftphome'
def usage():
print "FTP-Server"
print
print "-h --help how to use it"
print "-p --port set the ftp port"
print "-s --stop stop the ftp_server"
print "-o --open start the ftp_server"
print "-m --maxcon set a limit for connections"
print "-u --useradd add a user"
print "-r --userdel remove a user"
print "-l --log use logs other than echo on screen"
print
print "Example:"
print "python ftp_server -o"
print "python ftp_server -o -p 2121 -m 100"
sys.exit(0)
class DummyMD5Authorizer(DummyAuthorizer):
def validate_authentication(self, username, password, handler):
if sys.version_info >= (3, 0):
password = md5(password.encode('latin1'))
hash = md5(password).hexdigest()
try:
if self.user_table[username]['pwd'] != hash:
raise KeyError
except KeyError:
raise AuthenticationFailed
class MyHandler(FTPHandler):
def on_connect(self):
client_ip=self.remote_ip
client_port=self.remote_port
print "%s:%s connected" % (client_ip, client_port)
state=white_list(client_ip)
if state!=1:
print "warnning !! you have no permission "
try:
self.close()
sys.exit(0)
except Exception:
print "warnning !! you have no permission "
else:
pass
def useradd():
try:
username=raw_input("username:")
password=raw_input("password:")
permission=raw_input("permission:")
hash = md5(password).hexdigest()
os.mkdir('/home/huajian/Desktop/ftp/%s'%(username))
authorizer = DummyMD5Authorizer()
# Define a new user having full r/w permissions(r/w : perm='elradfmw')
authorizer.add_user(username, hash, '/home/huajian/Desktop/ftp/%s'%(username), perm=permission)
print "please remember your username and the password , have fun !"
except KeyboardInterrupt:
print
print "failed to add a user"
sys.exit(0)
def userdel(username):
authorizer = DummyMD5Authorizer()
authorizer.remove_user(username)
print "username: %s is removed !"%(username)
sys.exit(0)
def ftp_log(log):
if log==1:
print "[listing on] 127.0.0.1:%s"%(ftp_port)
print "all behavior is recorded in ftppyftpd.log!"
print "road is %s"%(logpath)
logging.basicConfig(filename='ftpserver.log', level=logging.INFO)
else:
print ("if you want to use logging,please use \"-l\"")
def server_loop(flag):
hash_user = md5('12345').hexdigest()
authorizer = DummyMD5Authorizer()
# Define a new user having full r/w permissions
authorizer.add_user('user', hash_user, jobpath, perm='elradfmw')
#authorizer.add_anonymous(os.getcwd()) # add a "#" to ban the anonymous
# Instantiate FTP handler class
ftp_handler = MyHandler
ftp_handler.authorizer = authorizer
#ftp_handler.banner = "connection is ok!" # welcome information
dtp_handler = ThrottledDTPHandler
dtp_handler.read_limit = read_limit # 30 Kb/sec (30 * 1024)
dtp_handler.write_limit = write_limit # 30 Kb/sec (30 * 1024)
# Define a customized banner (string returned when client connects)
#Maximum number of wrong authentications before disconnecting (default 3)
ftp_handler.dtp_handler = dtp_handler
#ftp_handler.max_login_attempts
#if log=1 ,use log
ftp_log(log)
address = ('0.0.0.0', ftp_port)
server = ThreadedFTPServer(address, ftp_handler)
# set a limit for connections
server.max_cons = maxcons
server.max_cons_per_ip = maxcons_per_ip
if flag==1:
server.serve_forever()
else:
server.close_all()
def white_list(client_ip):
ip_state=0
f=open('white.txt').readlines()
for ip_ok in f:
ip_ok=ip_ok.strip('\n')
if client_ip in ip_ok:
ip_state=1
return ip_state
def main():
global ftp_port
global maxcons
global maxcons_per_ip
global read_limit
global write_limit
global flag
global log
global jobpath
global logpath
if not len(sys.argv[1:]):
usage()
try:
opts,args=getopt.getopt(sys.argv[1:],"hp:osm:url") #["help","port","stop","open","maxcon","useradd","userdel","log"]
except getopt.GetoptError as err:
print str(err)
usage()
for o,a in opts:
if o in ("-h","--help"):
usage()
elif o in ("-p","--port"):
ftp_port=int(a)
elif o in ("-s","--stop"):
flag=0
elif o in ("-o","--open"):
flag=1
elif o in ("-m","--maxcon"):
maxcons=a
elif o in ("-l","--log"):
log=1
elif o in ("-u","--useradd"):
useradd()
elif o in ("-r","--userdel"):
userdel()
else:
print "error: can't handle your Option"
if flag==1:
try:
server_loop(1)
except KeyboardInterrupt:
sys.exit(0)
if __name__ == '__main__':
main()