1

前言

    很久不用python了,也就是回忆下python怎么使用。。。。都忘记了基本的语法了,再不试试,我都忘光了,。。。哈哈


    主要用来测试下FTP服务器的设置,从而使得在传输备份数据的时候,可以控制传输的速度。

    在使用下载的或者上传的时候,均是使用匿名用户来进行测试的,但是在生产环境中,一般都是建一个系统用户,然后不能登录,也就是shell的类型为/sbin/nologin。


2

实例代码

        具体代码如下所示(没有做异常捕获):

#!/usr/bin/env python 
# -*- coding: utf-8 -*- 

from ftplib import FTP
import datetime
import os

def ftp_upload(path,filename,host):
    ftp = createFTP(path,host)
    bufsize = 102400
    fileHandler = open(filename,'rb')
    ftp.storbinary('STOR %s' % os.path.basename(filename),fileHandler,bufsize)
    ftp.quit()
    print "upload file success"

def createFTP(path,host):
    ftp=FTP(timeout=30)
    ftp.connect(host,'21')
    ftp.login()
    ftp.cwd(path)
    ftp.set_pasv(False)
    return ftp

def ftp_down(path,filename,host):
    ftp = createFTP(path,host)
    bufsize = 1024000
    fileHandler = open(filename,'wb').write
    ftp.retrbinary('RETR %s' % os.path.basename(filename),fileHandler,bufsize)
    ftp.quit()
    print "dowload file success"

if __name__ == "__main__":
    starttime = datetime.datetime.now()
    HOST="192.168.20.128"
    PATH="pub/"
    FILE="fstab"
    ftp_upload(PATH,FILE,HOST)
    print datetime.datetime.now()-starttime

在这段代码中,主要需要注意的是bufsize的设置,如果设置的过小,那么存储的速度会很慢,设置的稍微大点,那么存储的时间会稍微加快。


    在设置为1024的时候,3.6G的数据传输时间需要9分钟;在设置为10240的时候,3.6G的数据传输时间需要6分钟;在设置为102400的时候,所花费的时间需要5分钟15秒。并不是线性增加,还要看网卡的传输速率,还要看服务端是否进行限速,网卡配置如下所示:

[root@RHEL1 pub]# ethtool eth0
Settings for eth0:
Supported ports: [ TP ]
Supported link modes:   10baseT/Half 10baseT/Full 


Supported pause frame use: No
Supports auto-negotiation: Yes
Advertised link modes:  10baseT/Half 10baseT/Full 


Advertised pause frame use: No
Advertised auto-negotiation: Yes
Speed: 1000Mb/s
Duplex: Full
Port: Twisted Pair
PHYAD: 0
Transceiver: internal
Auto-negotiation: on
MDI-X: Unknown
Supports Wake-on: d
Wake-on: d
Current message level: 0x00000007 (7)

Link detected: yes

可以看到虚拟机中为千兆网卡,不过算起来的传输速度为1000Mb/8=125M,其实最大的速度也就125MB每秒。

3

需要注意的问题

在使用FTP的时候,首先要注意服务端是主动模式还是被动模式,如果存在防火墙的话,那么模式不正确,那么会造成连接被拒绝,在有防火墙的场景中,一般是使用被动模式,也就是客户端来主动连接服务端的随即端口,这个随机端口是命令连接返回给客户端的,然后客户端来进行连接。

    在传输数据的时候,默认情况下都是被动模式,也就是PASV模式,要想进入主动模式,只需要(这个只是一个开关而已):

ftp> passive
Passive mode off.
ftp> passive
Passive mode on.
ftp>


    关于服务端速度的限制(不做限制的话,一分钟10M左右,和网络还是有关系的)

        当服务端速度限制anon_max_rate=100的时候,python会出现报错:

File "/usr/local/python/lib/python2.7/ftplib.py", line 416, in retrbinary
    data = conn.recv(blocksize)
socket.timeout: timed out

 速度为100个字节每秒。。。。3.6G的数据,每次都是传输到65535*2=131070的时候报错超时。。。。

当限定为anon_max_rate=10000000的时候,3.6G的数据传输需要1个小时多的时间。。。。

        设定速度和连接的主要配置参数如下:

最多的并发数设置:max_clients=100

每个ip最多的连接数设置:max_per_ip=2

匿名用户最大的传输速率:anon_max_rate=1000000

本地用户最大的传输速率:local_max_rate=100


    关于FTP服务端的日志信息

        由于FTP使用的是PAM进行认证,从而登录信息在文件/var/log/secure文件中,而日志文件需要开启相关的配置才能看到,传输日志在/var/log/xferlog中。


关于权限的控制

        其实在很多的软件配置中,权限控制都分为两套,也就是一种权限控制是在软件本身,例如FTP的配置文件中可以对权限进行控制,也就是写入的权限,创建目录的权限,上传的权限;而另外一种权限就是本地文件系统的权限,主要就是目录的属主和属组,然后运行进程的属主和属组,从而判断权限,在使用ftp的时候,可能会看到权限不足,这个是因为配置文件的问题,而出现不能创建文件的时候,就是由于本地文件系统的权限,在这里默认进行了配置,如下:

anon_upload_enable=YES  上传权限
anon_mkdir_write_enable=YES  创建目录的权限
anon_other_write_enable=YES删除目录和文件的权限
[root@RHEL1 ftp]# ls -l(本地文件系统修改了属主和属组)
total 8
drwxr-xr-x 2 ftp ftp 4096 Nov 24 23:52 kel
drwxr-xr-x 2 ftp ftp 4096 Nov 26 09:56 pub


    FTP诡异的进程属性


ftp上传文件到目录 python python ftp 上传_服务端

明明可以两个进程就能解决的问题,为啥还要开一个nodody的进程呢?然后再次派生一个ftp的进程,WHY???


    防火墙设置(被动模式)

pasv_min_port=10050
pasv_max_port=10060

ftp上传文件到目录 python python ftp 上传_服务端_02

    在使用本地用户的时候,注意将本地用户锁定在指定的家目录下,也就是chroot_local_user=YES