I have been trying to change a working FTP connection FTPClient to a FTPSClient provided by apache. The only changes made were changing the class and indicating what port the application is going to connect.
The server connects to another server within the same network. For external servers, a proxy is required.
I already tried setting up the constructor to true, it shows the following message:
Unrecognized SSL message, plaintext connection?
final FTPSClient ftp = new FTPSClient( true );
//same results
//final FTPSClient ftp = new FTPSClient("SSL", true );
//final FTPSClient ftp = new FTPSClient("TLS", true );
ftp.setDefaultPort(22);
When I set it up to false, the connection hangs up for a lot of time. It shows the following message:
Could not parse response code. Server Reply: SSH-2.0-OpenSSH_4.1
and tomcat shows the following page:
Proxy Error
The proxy server received an invalid response from an upstream server.
The proxy server could not handle the request POST /myapppath/APage.htm.
Reason: Error reading from remote server
final FTPSClient ftp = new FTPSClient( false );
ftp.setDefaultPort(22);
I tried connecting manually with WinSCP via SFTP and the connection is successful.
FTPS (FTP over SSL/TLS) is not the same as SFTP (SSH file transfer); these are two completely different protocols. The reason you are getting the error Unrecognized SSL message, plaintext connection? is because you are not connecting to a FTPS server.
You can read more about the difference here. If you want to make an SFTP connection rather than an FTPS connection, I would recommend using the JSch library.
Related
I created a client to test using a secure connection and encrypted payload so I wanted to use the default SSL configuration. I tried to do this but I got a ConnectionClosedException and the server immediately closely. Should I be configuring something on the server? I left code and the exception down below.
HiveMQ:
https://github.com/hivemq/hivemq-community-edition https://github.com/hivemq/hivemq-mqtt-client
Code:
// Creates the client object using Blocking API
subscriber = Mqtt5Client.builder()
.identifier(UUID.randomUUID().toString()) // the unique identifier of the MQTT client. The ID is randomly generated between
.serverHost("localhost") // the host name or IP address of the MQTT server. Kept it localhost for testing. localhost is default if not specified.
.serverPort(1883) // specifies the port of the server
.addConnectedListener(context -> ClientConnectionRetreiver.printConnected("Subscriber1")) // prints a string that the client is connected
.addDisconnectedListener(context -> ClientConnectionRetreiver.printDisconnected("Subscriber1")) // prints a string that the client is disconnected
.sslWithDefaultConfig()
.buildBlocking(); // creates the client builder
subscriber.connect();
Exception:
com.hivemq.client.mqtt.exceptions.ConnectionClosedException: Server closed connection without DISCONNECT.
at com.hivemq.client.internal.mqtt.MqttBlockingClient.connect(MqttBlockingClient.java:91)
at com.hivemq.client.mqtt.mqtt5.Mqtt5BlockingClient.connect(Mqtt5BlockingClient.java:64)
at com.main.SubThread.run(SubThread.java:71)
at java.base/java.lang.Thread.run(Thread.java:834)
In order to use Ssl communications I needed to set up the HiveMQ server to speak TLS. The server does not come pre configured and must be done manually. I followed this link:
https://github.com/hivemq/hivemq-community-edition/wiki/HowTos#howto-configure-server-side-tls-with-hivemq-and-keytool-self-signed
I try use ftp client in my application
first one I use org.apache.commons.net.ftp.FTPClient
but when running on linux server
can login to ftp server, can't get file list
return message is 425 Failed to establish connection.
if you close the firewall can be work
well, I try to change to sun.net.ftp.FtpClient
amazing thing happened
I can got file list
both are active modes, does anyone know why there is such a difference?
FTPClient ftpClient = new FTPClient();
ftpClient.connect("host");
ftpClient.login("account", "password");
ftpClient.listFiles("path"); // can't work if you not open firewall
FtpClient ftp = FtpClient.create("host");
ftp.login("account", "password".toCharArray());
ftp.listFiles("path"); // even if you do not open the firewall can work
It seems that the relevant difference is that sun.net.ftp.FtpClient defaults to using passive (PASV) mode, but org.apache.commons.net.ftp.FTPClient defaults to active.
At least, that is my reading of the respective source codes:
http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7-b147/sun/net/ftp/impl/FtpClient.java#FtpClient.0passiveMode
(line 79)
https://commons.apache.org/proper/commons-net/apidocs/src-html/org/apache/commons/net/ftp/FTPClient.html
(line 491)
You should be able to confirm this by running:
FtpClient ftp = FtpClient.create("host");
ftp.login("account", "password".toCharArray());
ftp.enablePassiveMode(false);
ftp.listFiles("path");
You should be able to use PASV mode (aka local passive mode) with the Apache FTP client; see the javadocs.
The initial problem we encountered was that a regular FTPs download started failing due to an untrusted server certificate. This prompted us to wonder whether the certificate had been updated without the counterparty notifying us so we wanted to download the current certificate and compare it to the one we have in our keystore.
This seems to be a trickier problem than we had anticipated. The usual suspects (firefox, filezilla, ...) did not seem up to the task of connecting to an FTPs server through an FTP proxy so out of curiosity I started playing around with a more low level java approach. I can not for the life of me get it to work though.
First (overly simplistic) java attempt:
// create proxy connection
SocketFactory plainFactory = SocketFactory.getDefault();
Socket proxy = plainFactory.createSocket(proxyServer, proxyPort);
// create ssl connection on top of it?
SSLSocketFactory sslFactory = getSocketFactory();
SSLSocket socket = (SSLSocket) sslFactory.createSocket(proxy, server, port, true);
This approach obviously does not work.
Next I started playing around with ftp4j (http://www.sauronsoftware.it/projects/ftp4j/) it seems to have a clean and accessible codebase:
FTPClient client = new FTPClient();
client.setConnector(new FTPProxyConnector(proxyHost, proxyPort));
client.getConnector().setConnectionTimeout(0);
client.getConnector().setReadTimeout(0);
client.setSSLSocketFactory(getSocketFactory());
// also tried SECURITY_FTPS
client.setSecurity(FTPClient.SECURITY_FTPES);
client.connect(server, port);
This outputs:
REPLY: 220 Blue Coat FTP Service
SEND: USER anonymous
REPLY: 530-User Access denied.
REPLY: 530-
REPLY: 530-Usage: USER username#hostname
REPLY: 331 PASS userpassword
Exception in thread "main" java.io.IOException: Invalid proxy response
The proxy server has optional authentication and on our development servers we generally use "user#host" without proxy authentication. As such I assume the username, hostname and password are those of the remote server?
So I tried adding the remote parameters, this does not work:
REPLY: 220 Blue Coat FTP Service
SEND: USER test#ftps.example.com
Exception in thread "main" java.io.IOException: FTPConnection closed
Adding the proxy user to match the bluecoat format does not seem to work either:
USER %u#%h %s
PASS %p
ACCT %w
Any help with either of these two problems would be most welcome:
how to retrieve the server certificate from an ftps server through an ftp proxy
how to connect to an ftps server through an ftp proxy in java
You might want to try Apache Net commons libs.
Here is a similar thread that uses that Net Commons library
Net commons also has a fully functional FTP Client Example so you can test with something you know works.
I want to upload file from my system to remote server as ftp.how i am to resolve this.I am using FTPClient client = new FTPClient(); and client.connect("sftp://something.com");But i am unable to connect it how i am check weather problem with my code or url.like ping command
I haven't used FTPClient (assume you mean Apache Commons FTPClient but a quick browse of apidocs shows two errors in your use:
The parameter to connect is server name, not url: client.connect("sftp://something.com") should be client.connect("something.com")
If you are using sftp you have to use FTPSClient
If you're connecting to an Sftp you might need to add the appropriate certificates (public/private keys) to the JVM where the code is running. Try your code on a regular FTP connection first, if that works, but not the sftp connections, it's almost sure is because of that.
I should be able to successfully send and receive file to/from FTP server.
But then, no changes occurred in the code and I started getting this :
Error: java.net.ConnectException: Connection timed out: connect
What I am doing is:
FTPClient ftp = new FTPClient();
ftp.connect( IPADDRESS of FTP server);
connect() is giving this execption. I am not understanding the cause for it.
The error message is telling you that the OS's attempt to connect to the server timed out. This typically means that:
the remote server has dropped off the network, or
something (e.g. a firewall) is "black holing" packets sent to the server on the FTP port.
Signals that an error occurred while attempting to connect a socket to a remote address and port. Typically, the connection was refused remotely (e.g., no process is listening on the remote address/port).
Source: JavaDoc.