关于内网穿透ftp的文件上传问题

  |   0 评论   |   0 浏览

问题: 场景是 一台内网Linux服务器,IP地址为 172.17.0.1 ,在这台服务器上搭建了 vsftp服务;假设公网IP为 1.1.1.1 ,为了能在互联网上 ssh 连接到服务器,对这台服务器 做了 ssh 端口的映射;对 ftp 的通信端口做端口映射;我们要在公网上能够实现 ftp的连接和文件上传

1、使用 fileZilla 连接ftp,发现显示登录成功,但是一直卡在读取目录那里

原因是因为没有映射 ftp 的数据端口,修改 vsftp.conf 将被动模式的数据端口 max 和 min 设置成同一个值 就可以实现固定端口。

ftp 有两种模式:主动模式和被动模式。可参考:https://blog.lacknb.cn/articles/2021/06/18/1624026653742.html#toc_h2_1

然后发现 可以成功读取目录,但是会提示 服务器发回了不可路由的地址。使用服务器地址代替。 这里后面会解释;

2、使用代码写ftp上传的时候,发现能连接成功,但是无法上传

原因:连接成功之后,服务器会将它的地址和数据端口返回到客户端,代表客户端可以向这个地址的这个端口传输文件了,当客户端拿到地址后,是无法上传文件的;因为返回的地址 是内网地址,解决办法就是 这里要判断下 服务器端传来的地址 是否和原来的地址(一开始配置的公网IP)一样,如果不一样了,要把这个地址换成公网 IP;

所以fileZilla 工具会一直提示 服务器发回了不可路由的地址。使用服务器地址代替。

        <!--        集成ftp-->
        <dependency>
            <groupId>commons-net</groupId>
            <artifactId>commons-net</artifactId>
            <version>3.3</version>
        </dependency>

对于这个工具,已经帮我们处理好这些了,最新版有更改,这里放的代码是旧版本的

if (__passiveNatWorkaround) {
            try {
                InetAddress host = InetAddress.getByName(__passiveHost);
                // reply is a local address, but target is not - assume NAT box changed the PASV reply
                if (host.isSiteLocalAddress()) {
                    InetAddress remote = getRemoteAddress();
                    if (!remote.isSiteLocalAddress()){
                        String hostAddress = remote.getHostAddress();
                        fireReplyReceived(0,
                                    "[Replacing site local address "+__passiveHost+" with "+hostAddress+"]\n");
                        __passiveHost = hostAddress;
                    }
                }
            } catch (UnknownHostException e) { // Should not happen as we are passing in an IP address
                throw new MalformedServerReplyException(
                        "Could not parse passive host information.\nServer Reply: " + reply);
            }
        }
public boolean isSiteLocalAddress() {
        // refer to RFC 1918
        // 10/8 prefix
        // 172.16/12 prefix
        // 192.168/16 prefix
        int address = holder().getAddress();
        return (((address >>> 24) & 0xFF) == 10)
            || ((((address >>> 24) & 0xFF) == 172)
                && (((address >>> 16) & 0xF0) == 16))
            || ((((address >>> 24) & 0xFF) == 192)
                && (((address >>> 16) & 0xFF) == 168));
    }

最新版本的代码有所不同

https://github.com/apache/commons-net/blob/master/src/main/java/org/apache/commons/net/ftp/FTPClient.java

950行


标题:关于内网穿透ftp的文件上传问题
作者:gitsilence
地址:https://blog.lacknb.cn/articles/2021/10/25/1635091315215.html