This article mainly introduces the Python implementation of the FTP server method, small series feel very good, and now share to everyone, but also for everyone to do a reference. Let's take a look at it with a little knitting.
Active mode and passive mode for FTP service
Before you start, talk about the FTP active mode and the passive mode, the difference between the two graphs to indicate that it may be more clear:
Active mode:
Active Mode working process:
1. The client initiates a connection to server-side 21 port with a random non-privileged port N, which is a port greater than 1024
2. The client starts listening to the n+1 port;
3. The server will actively connect to the client's n+1 port at 20 ports.
Advantages of Active Mode:
Server-side configuration is simple, good for server security management, servers only need to open 21 port
Disadvantages of Active mode:
If the client has a firewall turned on, or the client is in the intranet (after the Nat Gateway), the server's connection to the client port may fail
Passive mode:
Passive mode working process:
1. The client connects to port 21 on the server with a random, non-privileged port
2. The server opens a non-privileged port for the passive port and returns it to the client
3. The client actively connects to the passive port on the server with a port of non-privileged port +1
Passive Mode disadvantages:
Server configuration management is slightly more complex, not conducive to security, the server needs to open a random high port so that clients can connect, so most FTP service software can manually configure the scope of the passive port
Advantages of Passive mode: No requirement for client network environment
After learning about FTP, start using Python to implement the FTP service
Preparatory work
This time using Python version: Python 3.4.3
Mounting Module Pyftpdlib
PIP3 Install Pyftpdlib
Create a code file ftpserver.py
Code
Enables simple local validation
From pyftpdlib.authorizers import dummyauthorizerfrom pyftpdlib.handlers import Ftphandlerfrom pyftpdlib.servers Import ftpserver# instantiates the virtual user, which is the first condition of FTP authentication authorizer = Dummyauthorizer () #添加用户权限和路径, the parameters in parentheses are (user name, password, user directory, permissions) Authorizer.add_user (' user ', ' 12345 ', '/home/', perm= ' ELRADFMW ') #添加匿名用户 only need path authorizer.add_anonymous ('/home/ Huangxm ') #初始化ftp句柄handler = Ftphandlerhandler.authorizer = authorizer# Listen IP and port, because non-root users in Linux cannot use port 21, So I used the 2121 port server = Ftpserver ((' 192.168.0.108 ', 2121), Handler) #开始服务server. Serve_forever ()
Open service
$python ftpserver.py
Test it:
Enter an error password to try:
Verification does not pass and cannot log on.
But this seems to be the active mode of FTP, how to implement the passive mode?
Add the passive port using the following code:
Handler.passive_ports = Range (2000,2333)
Full code:
From pyftpdlib.authorizers import dummyauthorizerfrom pyftpdlib.handlers import Ftphandlerfrom pyftpdlib.servers Import ftpserver# instantiates the virtual user, which is the first condition of FTP authentication authorizer = Dummyauthorizer () #添加用户权限和路径, the parameters in parentheses are (user name, password, user directory, permissions) Authorizer.add_user (' user ', ' 12345 ', '/home/', perm= ' ELRADFMW ') #添加匿名用户 only need path authorizer.add_anonymous ('/home/ Huangxm ') #初始化ftp句柄handler = Ftphandlerhandler.authorizer = authorizer# Add passive port range Handler.passive_ports = Range (2000, 2333) #监听ip and Port server = Ftpserver ((' 192.168.0.108 ', 2121), Handler) #开始服务server. Serve_forever ()
To open the service, you can see the passive port information:
$ python ftpserver.py [I 2017-01-11 15:18:37] >>> starting FTP server on 192.168.0.108:2121, pid=46296 <<&L T [I 2017-01-11 15:18:37] concurrency model:async[i 2017-01-11 15:18:37] Masquerade (NAT) address:none[i 2017-01-11 15:18: PNS] Passive ports:2000->2332
FTP User management:
Through the above practice, the FTP server has been able to work properly, but if you need a lot of FTP users, how to do? Does every user write it again?
In fact, we can define a user file user.py
#用户名 Password permissions directory # root 12345 elradfmwm /homehuangxm 12345 elradfmwm /Home
Then traverse the file, adding lines that do not start with # to the User_list list
Full code:
From pyftpdlib.authorizers import dummyauthorizerfrom pyftpdlib.handlers import Ftphandlerfrom pyftpdlib.servers Import Ftpserverdef Get_user (userfile): #定义一个用户列表 user_list = [] with open (userfile) as F:for line in F:print (Len (Line.split ())) if not Line.startswith (' # ') and Line:if Len (Line.split ()) = = 4:user_list.appen D (Line.split ()) else:print ("user.conf configuration Error") Return user_list# instantiate virtual user, this is the first condition of FTP authentication authorizer = Dummyauthor Izer () #添加用户权限和路径, the parameters in parentheses are (username, password, user directory, permissions) #authorizer. Add_user (' user ', ' 12345 ', '/home/', perm= ' ELRADFMW ') user_list = Get_user ('/home/huangxm/test_py/ftpserver/user.conf ') for the user in User_list:name, passwd, permit, Homedir = user try: Authorizer.add_user (name, passwd, Homedir, perm=permit) except Exception as E:print (e) #添加匿名用户 only requires path authorizer.add_ Anonymous ('/HOME/HUANGXM ') #初始化ftp句柄handler = Ftphandlerhandler.authorizer = authorizer# Add passive port range handler.passive_ Ports = Range (2333) #监听ip and port server = FtpseRVer ((' 192.168.0.108 ', 2121), Handler) #开始服务server. Serve_forever ()
Here, the FTP service has been completed.
Standardize the Code
First create the Conf directory, storing the settings.py and user.py
Directory structure (no tubes inside the cache):
setting.py
ip = ' 0.0.0.0 ' port = ' 2121 ' #上传速度 300kb/smax_upload = 300 * 1024# Download speed 300kb/smax_download = 300 * 1024# Maximum number of connections max_cons = 150# Maximum IP number max_per_ip = 10# Passive port range, note that the number of passive ports is more than the maximum number of IP, or there may be no connection Passive_ports = (A, 2200) #是否开启匿名访问 On|offenable_ anonymous = ' off ' #匿名用户目录anonymous_path = '/home/huangxm ' #是否开启日志 on|offenable_logging = ' off ' #日志文件loging_name = ' Pyftp.log ' #欢迎信息welcome_msg = ' Welcome to my FTP '
user.py
#用户名 Password permissions directory #root 12345 elradfmwm /home/huangxm 12345 elradfmwm /home/ Test 12345 elradfmwm /HOME/HUANGXM
ftpserver.py
From pyftpdlib.authorizers import dummyauthorizerfrom pyftpdlib.handlers import Ftphandler, Throttleddtphandlerfrom Pyftpdlib.servers import ftpserverfrom conf import settingsimport loggingdef Get_user (userfile): #定义一个用户列表 user_list = [ ] with open (userfile) as F:for line in F:if not Line.startswith (' # ') and Line:if Len (Line.split ()) = = 4 : User_list.append (Line.split ()) else:print ("user.conf configuration Error") return User_listdef Ftp_server (): #实例化虚拟用户, this is the first condition of FTP authentication authorizer = Dummyauthorizer () #添加用户权限和路径, the parameters in parentheses are (user name, password, user directory, permissions) #authorizer. Add_user (' Use R ', ' 12345 ', '/home/', perm= ' ELRADFMW ') user_list = Get_user (' conf/user.py ') for the user in User_list:name, passwd, per MIT, Homedir = user Try:authorizer.add_user (name, passwd, Homedir, perm=permit) except Exception as E:PR Int (e) #添加匿名用户 only need path if settings.enable_anonymous = = ' on ': authorizer.add_anonymous (Settings.anonymous_path) #下载上传 Speed Setting Dtp_handler = ThrottleddTphandler Dtp_handler.read_limit = settings.max_download dtp_handler.write_limit = settings.max_upload #初始化ftp句柄 Handl ER = Ftphandler Handler.authorizer = Authorizer #日志记录 if settings.enable_logging = = ' on ': Logging.basicconfig (Filena Me=settings.loging_name, level=logging.info) #欢迎信息 Handler.banner = settings.welcome_msg #添加被动端口范围 handler.passive_p Orts = Range (Settings.passive_ports[0], settings.passive_ports[1]) #监听ip and Port server = Ftpserver ((Settings.ip, settings. Port), handler) #最大连接数 server.max_cons = settings.max_cons server.max_cons_per_ip = settings.max_per_ip #开始服务 pri NT (' Start service ') Server.serve_forever () if __name__ = = "__main__": Ftp_server ()
Finally, let's talk about permissions.
Read permissions:
E |
Change file directory |
L |
List files |
R |
Receiving files from the server |
Write permission:
A |
File Upload |
D |
deleting files |
F |
File Rename |
M |
Create a file |
W |
Write permissions |
M |
File transfer Mode (set file permissions via FTP) |
M Example:
To view permissions on the server:
You can see that the permissions have been modified.