VSFTPD

一、简介

1、Linux的一个组件(一个软件),安装到Linux后通过java代码(FtpClient)实现文件上传(上传和下载的功能)

2、VSFTPD基于FTP协议

3、为什么使用VSFTPD

  3.1 之前实现文件上传

    客户端浏览器          tomcat  图片上传到tomcat

                    tomcat 集群

    问题:

      访问时跟存储不是同一个tomcat

      重启容易丢失

  3.2 使用VSFTP优化后

    上传:                           存图片需要文件夹,给到权限,可以直接创建在home下改用户拥有全部权限

    客户端浏览器          tomcat集群   tomcat1      图片服务器(安装了VSFTPD的服务器)

                    tomcat2

    3.2.1 如果希望直接在客户端直接访问图片服务器,由于VSFTPD是基于ftp协议,客户端浏览器是基于http协议

    3.2.2 解决使用Nginx进行反向代理

二、VSFTPD安装

1、通过yum源安装

  yum -y install vsftpd   -y遇到需要确定的地方通通yes      安装完成后,有/etc/vsftpd/vsftpd.conf文件,是vsftp的配置文件

  

 

2、添加一个ftp用户

  此用户是用来登录ftp服务器用的

  useradd ftpuser            这样一个用户创建完成

  passwd ftpuser    输入两次密码后修改密码

  

 

3、防火墙开启21端口

  3.1 因为ftp默认端口是21端口,而censo是默认没有开启的,需要修改iptables文件

    vim /etc/sysconfig/iptables

    

  3.2 重启service iptables restart

  3.3 修改selinux

    外网可以访问上去,可是发现没办法返回目录(使用ftp主动模式,被动模式还是无法访问),也上传不了,需要修改selinux。

    修改selinux:

    执行以下命令查看 getsebool -a|grep ftp

     

    allow_ftpd_full_access 和ftp_home_dir 是off状态,需要开启

    setsebool -P allow_ftpd_full_access on

    setsebool -P ftp_home_dir on

    这样一般就没有问题了,如果还不能访问,查看ftp客户端工具是否使用了passive模式访问,如果提示Entering Passive mode,就代表是passive模式。

4、关闭匿名访问(不用用户密码也能访问)

  修改 /etc/vsftpd/vsftpd.conf 文件 anonymous_enable=YES改为NO

  

   重启ftp服务service vsftpd restart

5、开启被动模式(可能导致通过21端口连不上ftp)

  默认是开启的,但是要指定一个端口范围,打开vsftpd.conf文件,在后面加上

  pasv_min_port=30000

  pasv_max_port=30999

  表示端口范围为 30000~30999,这个可以随意改动。改完重启vsftpd。

  同时,在防火墙里放开这个端口段。

  

6、设置开机启动vsftpd ftp服务

  chkconfig vsftpd on

7、登录并取a.png文件    

   ftp://用户名:密码@IP/a.png (不推荐)

  

  但是切换浏览器以后路径会更改。在IE中会访问到Linux的根目录,在谷歌访问到home下的ftpuser。

三、FTPClient

1、java技术,使用FTPClient,使用java代码上传到服务器

   不依赖于容器jar项目都可以用。

  1.1 连接IP和端口

  1.2 用户名和密码登录

  1.3 设置文件类型

  1.4 上传文件

  1.5 登出

  

   工具类: 

 1 public static FTPClient connectFTPServer(String host , int port, String username ,String password){
 2         
 3         FTPClient ftpClient = new FTPClient();
 4         try {            
 5             ftpClient.connect(host, port);
 6             int reply = ftpClient.getReplyCode();   
 7             if (!FTPReply.isPositiveCompletion(reply)) {   
 8                 ftpClient.disconnect();   
 9                 logger.error("FTP服务器 [" + host +":" + port+ "]拒绝连接");   
10                 return null;
11             }   
12             
13             if (!ftpClient.login(username, password)) {
14                 ftpClient.disconnect();   
15                 logger.error("登陆[" + username +":" + port+ ","+ username +":" + username+ "]验证失败,请检查账号和密码是否正确");   
16                 return null;   
17             } 
18             
19             ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
20         } catch (SocketException e) {
21             logger.error("FTP服务器 [" + host +":" + port+ "]拒绝连接",e);   
22         } catch (IOException e) {
23             logger.error("登陆[" + host +":" + port+ ","+ username +":" + password+ "]验证失败,请检查账号和密码是否正确",e);  
24         } catch (Exception e){
25             logger.error("登陆[" + host +":" + port+ ","+ username +":" + password+ "]验证失败,请检查账号和密码是否正确",e); 
26         } 
27         
28         return ftpClient;
29     }

下载文件

 1 public static File download(String fileFtpUrl,String targetFileName)
 2     {
 3         URI ftpUrl = null;
 4         File targetFile;
 5         //String name;
 6         try {
 7             ftpUrl = new URI(fileFtpUrl);
 8         } catch (URISyntaxException e) {
 9             logger.error("路径格式非法", e);
10         }
11         String userInfo = ftpUrl.getUserInfo();
12         if(StringUtils.isEmpty(userInfo))
13         {
14             userInfo = ":";
15         }
16         String[] userApass = userInfo.split(":");
17         FTPClient ftpClient = FtpUtil.connectFTPServer(ftpUrl.getHost(), ftpUrl.getPort()<0?21:ftpUrl.getPort(), 
18                 userApass[0], userApass[1]);
19         OutputStream os = null;
20         try {
21             if(StringUtils.isEmpty(targetFileName)){
22                 targetFileName = String.valueOf(System.currentTimeMillis());
23             }
24             /*if(targetFileName.contains(File.separator)){
25                 name = targetFileName.substring(targetFileName.lastIndexOf(File.separator)+1);
26             }else{
27                 name = targetFileName;
28             }*/
29             targetFile = new File(targetFileName);
30             targetFile.setWritable(true);
31             targetFile.setReadable(true);
32             ftpClient.enterLocalPassiveMode();
33             try {
34                 os = new FileOutputStream(targetFile);
35             } catch (Exception e) {
36                 e.printStackTrace();
37             }finally{
38                 if(os != null){
39                     os.close();
40                 }
41             }
42             
43             Long startTime = System.currentTimeMillis();
44             logger.info("下载开始时间为"+startTime);
45             boolean flag = ftpClient.retrieveFile(ftpUrl.getPath()+targetFileName, os);
46             if(flag){
47                 logger.info("下载成功");
48             }
49             os.flush();            
50             Long endTime = System.currentTimeMillis();
51             logger.info("下载结束时间为"+endTime);
52             Long time = endTime-startTime;
53             logger.info("本次下载共耗时"+time+"毫秒");
54             return targetFile;
55             
56         }   
57         catch (FileNotFoundException e) 
58         {
59             logger.error("ftp下载失败",e); 
60         } 
61         catch (IOException e) 
62         {
63             logger.error("ftp下载失败",e); 
64         } 
65         finally
66         {
67             IOUtils.closeQuietly(os);
68             FtpUtil.closeConnect(ftpClient);
69         }
70         return null;
71     }

 切换路径(创建)

 

 1 public static boolean mkDir(FTPClient ftpClient, String dir){
 2         logger.info("待切换的FTP目录为:" + dir);
 3         String pathChar = "/";
 4         String a = "\\";
 5         if(dir.contains(a)){
 6             dir = dir.replace("\\", pathChar);
 7         }
 8     
 9         try {
10             if(pathChar.equalsIgnoreCase(dir)){
11                 return true;
12             }
13             if(!ftpClient.changeWorkingDirectory(dir)){
14                 String[] dirArray = dir.split(pathChar);
15                 for(String dirTmp : dirArray){
16                     //不存在
17                     if(!StringUtils.isEmpty(dirTmp)&&!ftpClient.changeWorkingDirectory(dirTmp)){
18                         if(ftpClient.makeDirectory(dirTmp)){
19                             logger.info("从FTP服务器创建目录" + dirTmp + "成功");
20                             ftpClient.changeWorkingDirectory(dirTmp);
21                         }
22                         else{
23                             logger.info("从FTP服务器创建目录" + dirTmp + "失败");
24                             return false;
25                         }
26                     }
27                 }
28             }
29             //切回根目录
30             ftpClient.changeWorkingDirectory("/");
31         } catch (IOException e) {
32             logger.error("FTP切换目录失败",e); 
33             return false;
34         }
35         return true;
36     }

2、web项目结合FTPClient完成

  浏览器 -------> tomcat中的web项目,MultipartFile获取上传文件流,使用FtpClient    ----->  上传到Linux中VSFTPD

        <form id="dlg_form" method="post" enctype="multipart/form-data" action="upload">
            <table class="input">
                <tr id="iconInfo">
                    <th align="right">应用图标:</th>
                    <td colspan="3">
                        <input  type="file"  name="icon" id="icon"  class="input" style="width: 375px; height: 40px; float: left;" data-options='required:true'>&nbsp;
                        <span
                        style="font-size: 12px; -align: center;">支持.jpg;.png;.gif;<br>.tif;.psd;.ico格式的图片
                        </span>
                        <div id="iconNameInfo"> 
                    </div>
                    </td>
                </tr>
                <tr id="photoInfo">
                    <th align="right">应用图片:</th>
                    <td colspan="3">
                    <input onchange="getPhotosName()"  multiple="multiple" type="file" name="photos" id="photos" class="input" 
              style
="width: 375px; height: 40px; float: left;" data-options='required:true'>&nbsp; <span style="font-size: 12px; -align: center;">支持.jpg;.png;.gif;<br>.tif;.psd;.ico格式的图片 </span> <div id="photosNameInfo"></div> </td> </tr> <tr id="fileMessageInfo"> <th align="right">升级包:</th> <td colspan="3"> <input type="file" name="file" id="file" class="input" style="width: 300px;" data-options='required:true'>&nbsp; <div id="fielNameInfo"> <a href="#" onclick="downfile();"> <font style="white-space: pre-line; word-break:break-all" id="fileInfo" title="单击可以进行升级包的下载"></font> </a> </div> </td> </tr> </table> </form>
@Controller
public class UploadController{
    @Resource
    private UploadService uploadService;

     @RequestMapping("/upload")   
     public String Upload(MultipartFile file) throws IOException{
            try{
                boolean result = uploadService.upload(file);
                if(result){
                     return "/success.jsp";   
                }
            } catch(IOException e){

            }
             return "/error.jsp";  
     }

}



@Service
public class UploadService{

    @Value("${ftpclient.host}")
    private String host;
    @Value("${ftpclient.port}")
    private int port;
    @Value("${ftmclient.userName}")
    private String userName;
    @Value("${ftpclient.password}")
    private String password;
    @Value("${ftpclient.basePath}")
    private String basePath;
    @Value("${ftpclient.filePath}")
    private String filePath;

     public boolean upload(MultipartFile file) throws IOException{
        
       String fileName=UUID.randomUUID()+file.getOriginalFilename.substring(file.getOriginalFilename.lastIndexOf("."));
     return FTPUtil.uploadFile(host,port,userName,password,basePath,filePath,fileName,file.getInputStream); 
           
     }


}       

 

 四、正向代理和反向代理

 1、概念

  1.1 正向代理服务器:客户端知道最终要访问的服务器地址。(FQ软件)

  1.2 反向代理服务器:客户端只知道代理服务器地址,而不知道真实要访问的服务器地址。

    

 

     Nginx反向代理服务,去访问图片服务器。

     Nginx只能代理http,所以Nginx要跟图片服务器安装在同一个服务器上。

 

五、安装Nginx(俄罗斯C语言)

1、安装nginx之前(安装版,也可以解压tar.gz包)

  1.1 如果没有gcc类库,安装gcc:yum install gcc-c++ -y      -y需要确定的全yes

  1.2 PCRE:yum install  -y pcre pcre-devel    pcre-devel是使用pcre开发的一个二次开发库。

    PCRE是一个Perl库,包含perl兼容的正则表达式库。nginx的http模块使用pcre来解析正则表达式,所以要在linux上装pcre库。

  1.3 zlib:yum install -y zlib zlib-devel

    zlib库提供了很多压缩和解压缩的方式,nginx使用zlib对http包含的内容进行gzip,所以要在linux上装zlib库。

  1.4 openssl:yum install -y openssl openssl-devel

    openssl是一个强大的安全套接字层密码库,囊括主要的密码算法、常用的密钥和证书封装管理功能以及SSL协议,并提供丰富的应用程序供测试或其他摸底使用。

    nginx不仅支持http协议,还支持https(即在ssl协议上传输http),所以需要在linux安装openssl库。

2、编译和安装(所有用C语言的linux都需要编译安装)

  2.1 解压nginx包,cd进nginx目录

  2.2 configure  配置文件

    

 

     --prefix=/usr/local/nginx 是安装目录

   2.3 make 编译

   2.4 makeinstall 安装

   2.5 在nginx目录下的sbin中找到nginx可执行文件,./nginx 启动nginx,默认端口是80

   2.6 快速停止nginx   cd /usr/local/nginx/sbin   ./nginx -s stop  此方式相当于先查出nginx进程id,再使用kill命令强制杀掉进程。

    完全停止nginx   cd /usr/local/nginx/sbin   ./nginx -s quit   此方式停止步骤是待nginx进程处理任务完毕进行停止。(建议使用)

   2.7 重启nginx 先停止再启动 ./nginx -s quit   ./nginx(建议使用)

    重新加载配置文件,当nginx的配置文件nginx.conf修改后,要想让配置文件生效,需要重启,使用 -s reload不用先停止nginx再启动nginx即可生效

    cd /usr/local/nginx/sbin  ./nginx -s reload

   2.8 测试nginx安装成功,启动nginx,访问nginx出现welcome to nginx!表示成功

   2.9 开机自启动nginx

    编写shell脚本

    vi /etc/init.d/nginx

    设置文件权限

    chmod a+x /etc/init.d/nginx    (a+x : all user can execute 所有用户可以执行)

    这样控制台就很容易操作nginxl

    /etc/init.d/nginx status

    /etc/init.d/nginx start

    /etc/init.d/nginx stop

    /etc/init.d/nginx restart

    /etc/init.d/nginx reload

    如果修改了nginx的配置文件nginx.conf,也可以使用上面的命令重新加载新的配置文件并运行,

    可以将此命令加入到rc.local文件中,这样开机的时候nginx就默认启动了。

    vi /etc/rc.local

    加入一行  /etc/init.d/nginx start     保存并退出,下次重启会生效。

六、配置Nginx代理ftpuser目录

  1、修改nginx配置文件

    cd /usr/local/nginx/conf

    vim nginx.conf

    

 

 

     重启nginx。

     再次访问,页面报403(没有权限)。

    

 

 

    修改nginx.conf配置文件,赋予ftpuser权限。

    

 

 

    重启nginx,再次访问nginx。(欢迎页也要配置)

  2、在代码里访问文件

    src定位到nginx中的文件地址就可以访问了。

    <img src="http://IP:Port/文件.jpg">

    

 

posted @ 2020-07-01 11:23  归零19  阅读(404)  评论(0编辑  收藏  举报