I have created an Amazon Linux 2 instance where I have deployed a Java program launched with systemd. The Java program is a vertx-shell application which is using Apache Mina to start a SSH server on port 2000. It should possible to connect to the SSH server with 2 ways : public key or password auth.
After a classical ssh authentication on port 22 to access my amazon instance, I can connect to the java ssh server running on port 2000 locally with password auth. However, when I try to connect to SSH server from my local machine providing the Amazon private key, the connection is stuck on 'debug1: Local version string SSH-2.0-OpenSSH_7.5' line and finally refused after a timeout of 2 minutes :
ssh -i /Users/toto/.ssh/my_amazon_key.pem -p 2000 ec2-user#my-application.server.com -vvv
OpenSSH_7.5p1, LibreSSL 2.5.4
debug1: Reading configuration data /Users/toto/.ssh/config
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config line 52: Applying options for *
debug2: resolving "my-application.server.com" port 2000
debug2: ssh_connect_direct: needpriv 0
debug1: Connecting to my-application.server.com [35.XXX.XX.XX] port 2000.
debug1: Connection established.
debug1: key_load_public: No such file or directory
debug1: identity file /Users/toto/.ssh/my_amazon_key.pem type -1
debug1: key_load_public: No such file or directory
debug1: identity file /Users/toto/.ssh/my_amazon_key.pem-cert type -1
debug1: Enabling compatibility mode for protocol 2.0
debug1: Local version string SSH-2.0-OpenSSH_7.5
ssh_exchange_identification: Connection closed by remote host
On the Java application log, I can see a log of somebody trying to connect to the SSH server but failing to authenticate after 2 minutes.
Of course, I have checked in my Amazon security group that I have opened port 2000. There is no denied IP in my case.
Here is the Java code running the SSH server :
ShellService service = ShellService.create(vertx,
new ShellServiceOptions()
.setTelnetOptions(
new TelnetTermOptions().
setHost("localhost").
setPort(5000))
.setSSHOptions(
new SSHTermOptions().
setHost("0.0.0.0").
setPort(2000).
setKeyPairOptions(new JksOptions().
setPath("ssh/keystore.jks").
setPassword("wibble")).
setAuthOptions(new ShiroAuthOptions().
setConfig(new JsonObject().put("properties_path", "classpath:ssh/auth.properties"))))
);
Any idea ? Vertx/Apache Mina config ? Conflict between SSHD running on port 22 and port 2000 ?
Ok, I finally found out the problem. Actually, I had to do 2 things :
I changed the port from 2000 to 3000, and then I was not stuck anymore, at least I was able to authenticate with password. But public key authentication was still failing. So I suppose something else was already running on initial port 2000, causing the connection stuck.
I was launching my java application with a specific user vertx, so Apache Mina SSH server was looking for an un-existing authorized_keys file for user vertx. As soon as I created it with the public key inside in its own .ssh directory in vertx user home directory, with the right permissions, then I could authenticate providing the corresponding private key.
Related
I want to run a simple Spring Boot application on my Ubuntu 16.04.6 x64 droplet. To allow incoming connections I had to open the 8080 port, since this is where the embedded tomcat server in the spring boot jar will listen for connections.
I used the ufw allow 8080 command and now I see this on me droplet.
#ufw status
Status: active
To Action From
-- ------ ----
8080 ALLOW Anywhere
22 ALLOW Anywhere
80 ALLOW Anywhere
8080 (v6) ALLOW Anywhere (v6)
22 (v6) ALLOW Anywhere (v6)
80 (v6) ALLOW Anywhere (v6)
I made sure I have my application running:
java -jar myservice.jar &
Netstat reports that something is listening on 8080:
# netstat -aon
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State Timer
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN off (0.00/0/0)
tcp 0 XXX XX.XXX.XX.XXX:22 XX.XX.XXX.XX:64021 ESTABLISHED on (0.11/0/0)
tcp6 0 0 :::8080 :::* LISTEN off (0.00/0/0)
tcp6 0 0 :::22 :::* LISTEN off (0.00/0/0)
Yet when I do telnet outside the server I get:
telnet XX.XXX.XX.XXX 8080
Connecting To XX.XXX.XX.XXX...Could not open connection to the host, on port 8080: Connect failed
And when I do telnet on the server I get:
# telnet localhost 8080
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
In Digital Ocean's Firewall control panel I have the following setup:
HTTP requests to the server just hang and never return. They don't even reach the tomcat server, judging by the lack of logs.
What am I missing? Any suggestions would be really appreciated!
UPDATE 1:
Local (inside the server) curl requests to my healthcheck endpoint were also hanging. However I left one for longer period and I got this application log:
2019-05-13 18:39:48.723 WARN 5873 --- [nio-8080-exec-2] o.a.c.util.SessionIdGeneratorBase : Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [214,287] milliseconds.
This explained why the request was hanging, so applying the answer from this post fixed that. Now I'm able to hit my endpoint on the server and it's responding.
However outside the box, requests are still not making it to the server. Telnet outside still says Could not open connection to the host, on port 8080.
I'm not 100% sure why, but the Firewall rules from the Digital Ocean Firewall Control panel were interfering with my droplet configuration.
I've deleted the Firewall rules from the control panel and now netstat reports that my 8080 port is open and I'm able to talk to the server from the outside world, finally.
#nmap -sS -O XX.XXX.XX.XXX
Starting Nmap 7.01 ( https://nmap.org ) at 2019-05-13 21:13 UTC
Nmap scan report for myservice (XX.XXX.XX.XXX)
Host is up (0.000024s latency).
Not shown: 998 closed ports
PORT STATE SERVICE
22/tcp open ssh
8080/tcp open http-proxy
Device type: general purpose
Running: Linux 3.X
OS CPE: cpe:/o:linux:linux_kernel:3
OS details: Linux 3.8 - 3.19
Network Distance: 0 hops
Also check UPDATE 1 from the question as it was also causing bizarre confusion.
When trying to upload file to FTP with java program:
public void upload(String localFile,String remoteFile) throws Exception{
ftp = new FTPClient();
ftp.setControlKeepAliveTimeout(300);
ftp.connect(host,21);
ftp.enterLocalPassiveMode();
ftp.setUseEPSVwithIPv4(false);
ftp.login(user,password);
ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
FileInputStream in = null;
in = new FileInputStream(localFile);
ftp.storeFile(remoteFile,in);
in.close();
ftp.disconnect();
}
I'm getting:
java.net.ConnectException: Connection refused
at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:381)
at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:243)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:230)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:377)
at java.net.Socket.connect(Socket.java:539)
at org.apache.commons.net.SocketClient._connect(SocketClient.java:243)
at org.apache.commons.net.SocketClient.connect(SocketClient.java:202)
When I try to upload the same file with command line (from linux), I'm able to do it only when using EPSV:
llnx:~ ftp anonymous#9.20.1.116
Connected to 9.20.1.116.
220 Microsoft FTP Service
331 Anonymous access allowed, send identity (e-mail name) as password.
Password:
230 User logged in.
Remote system type is Windows_NT.
ftp> epsv
EPSV/EPRT on IPv4 off.
ftp> put /tmp/file1.xml /dir_1/file1.xml
local: /tmp/file1.xml remote: /dir_1/file1.xml
227 Entering Passive Mode (10,40,1,149,233,168).
125 Data connection already open; Transfer starting.
100% |*************************************| 117 KB 28.66 MB/s --:-- ETA
226 Transfer complete.
120032 bytes sent in 00:00 (7.96 MB/s)
So, Why does my java code getting Connection refused?
Maybe I'm not using the enterLocalPassiveMode() or setUseEPSVwithIPv4() method the right way?
*** I think the answer is how to run the EPSV command from Java program.
Thank you all.
Eithan.
This is purely a guess but java.net.ConnectException: Connection refused normally happens when there is nothing listening on the target host/port. You don't specify a port in the CLI example so maybe that is the problem. Try changing ftp.connect(host,21); to ftp.connect(host); to use the default. Also confirm the the hostnames are exactly the same.
This assumes that the error is on the call to connect(). You haven't provided a big enough stack trace to indicate either way.
Connection refused means that your TCP connection request has reached the remote server (or more correctly >>a<< remote server) but the server is not expecting / listening for an incoming connection. So it "refuses" it.
Here are the things to check:
Check that you have the correct remote hostname or IP address for the FTP server.
Check that you are using the correct port for the FTP server. Port 21 is the default, but it is possible that the server is on a non-standard port.
Check that the FTP server is actually running.
It is also possible that the problem is due to a firewall doing something deliberately confusing. But that is unlikely for a publicly routable FTP server.
Maybe I'm not using the enterLocalPassiveMode() or setUseEPSVwithIPv4() method the right way?
That can't be the problem. The stacktrace shows that your application failed while trying to establish the initial connection to the server. You haven't gotten to the point where the you can make those calls.
I need some help with doing netty socket io over https. I have got it to in my local env but not on a server with secure domain. The server starts but client isn't able to connect. Tried by starting the socket server with IP as well as domain name. For the server to start with domain name as hostname value in setHostname method, I added an entry in /etc/hosts file as following
127.0.0.1 localhost example.com
Socket server started by giving example.com as hostname but client isn't able to connect using the same hostname over https as following
var socket = io.connect('https://example.com:10443')
Tried with options - { secure: true, reconnect: true, rejectUnauthorized : false } too but the same issue.
On server side my configuration is as following
Configuration configuration = new Configuration();
configuration.setHostname("example.com");
configuration.setPort(10443);
configuration.setKeyStorePassword("mypassword");
InputStream stream = getClass().getClassLoader().getResourceAsStream("keystore.jks");
configuration.setKeyStore(stream);
The jsk file was created using keytool command for the same domain (example.com)
Is there something more to be done for the port - 10443 to be used by the socket server? Or is there any other configuration to be done?
Got the solution! I had not mentioned that the domain was set up on cloudflare. Here the issue was with the port I used - 10443. It's not supported by cloudflare. Changed it to 8443 and it worked!
For those who come across this, please find here the list of supported ports that Cloudflare work with. May save much of your time unlike me.
Also, please note that I used my public IP as hostname in setHostname() method so that I don't need anything added in my hosts file. Then gave the actual domain name with https on client side to connect to the server. That's it. Thank you all!
Sandeep
I am using apache commons-net 3.6 library to connect FTPS server. FTPS server is behind NAT of thirdparty. and I can't change any settings on server side.
I can login to server, but can not list files. I've tried same code with some public FTP and FTPS servers, and result was successfull. Seems that they are not behind NAT. But filezilla can successfully connect and list files from my problematic server.
There is my code
ftps.connect(server, port);
System.out.println("Connected to " + server + ".");
reply = ftps.getReplyCode();
ftps.enterLocalPassiveMode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftps.disconnect();
System.err.println("FTP server refused connection.");
System.exit(1);
}
if (!ftps.login(username, password)) {
ftps.logout();
}
// ftps.setEnabledSessionCreation(false);
ftps.feat();
ftps.execPBSZ(0);
ftps.execPROT("P");
ftps.setFileType(FTP.BINARY_FILE_TYPE);
FTPFile dirs[] = ftps.listDirectories();
And there is my ftps log:
220 FTP Server ready.
AUTH TLS
234 AUTH TLS successful
Connected to x.x.x.x
USER *******
331 Password required for azercell
PASS *******
230 User myuser logged in
FEAT
211-Features:
MDTM
MFMT
LANG bg-BG;en-US;fr-FR;it-IT;ja-JP;ko-KR;ru-RU;zh-CN;zh-TW
TVFS
UTF8
AUTH TLS
MFF modify;UNIX.group;UNIX.mode;
MLST modify*;perm*;size*;type*;unique*;UNIX.group*;UNIX.mode*;UNIX.owner*;
PBSZ
PROT
REST STREAM
SIZE
211 End
PBSZ 0
200 PBSZ 0 successful
PROT P
200 Protection set to Private
TYPE I
200 Type set to I
SYST
215 UNIX Type: L8
PASV
227 Entering Passive Mode (192,168,2,50,192,12).
[Replacing PASV mode reply address 192.168.2.50 with x.x.x.x]
LIST
150 Opening BINARY mode data connection for file list
425 Unable to build data connection: Operation not permitted
I'd read that prior to version 3.6 commons-net library prior couldnt handle behind NAT connections properly.
Can anyone help me? What is wrong with my code?
So my conclusion is problem was not related to NAT technology, apache-commons 3.6 does not handle all FTPS options properly. As I mentioned before we were integrating with 3rd party and had not option to change FTPS settings, at least we installed filezilla ftp server and were able to reproduce error. Fortunately I found solution at http://eng.wealthfront.com/2016/06/10/connecting-to-an-ftps-server-with-ssl-session-reuse-in-java-7-and-8/ by Luke Hansen. Great thanks him
I'm modifying some code that was previously working with an FTPS library I wrote myself. I've been asked to start using the Apache Commons Net library (FTPClient and FTPSClient mainly) and I'm running into problems doing a file listing. I've read other questions and it's not the enterLocalPassiveMode problem (Apache Commons Net FTPClient and listFiles()), as I'm using that after connecting, but before logging in. The same code works fine on a test server I set up (also using Apache FTP), but doesn't work on the server I need it for.
I've also tried using the "PBSZ 0" and "PROT P" commands, but they're not implemented on the remote system.
502 PBSZ Command not implemented.
502 PROT Command not implemented.
Code:
FTPSClient ftpsclient = new FTPSClient(true); // Implicit SSL
ftpsclient.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out), true));
ftpsclient.connect(HOST_ADDR, HOST_PORT); // Using port 990
ftpsclient.enterLocalPassiveMode();
ftpsclient.user(USERID);
ftpsclient.pass(PASSWORD);
ftpsclient.setFileType(FTP.BINARY_FILE_TYPE);
ftpsclient.changeWorkingDirectory(REMOTE_DIR);
ftpsclient.printWorkingDirectory();
FTPFile[] ftpfiles = ftpsclient.listFiles(); // This is where it breaks
I've tried specifying the directory explicitly and using the default:
FTPFile[] ftpfiles = ftpsclient.listFiles();
FTPFile[] ftpfiles = ftpsclient.listFiles(REMOTE_DIR);
... but both give the same result. This is the output of the debugging info:
220 FTPS (Version Thu Dec 10 17:23:00 2015) server ready.
USER ****
331 Password required for ****.
PASS ****
230 User **** logged in.
TYPE I
200 Type set to I
CWD outbound/directory
250 CWD Command successful.
PWD
257 "/usr/path/to/outbound/directory" is current directory.
SYST
215 UNIX
PASV
227 Entering Passive Mode (XX,XX,XX,XX,24,140) ***Edit: port 6284
LIST
150 Opening data connection for '/bin/ls'.
Then it times out after 30 seconds with this stack trace:
Stack Trace: org.apache.commons.net.ftp.FTPConnectionClosedException: Connection closed without indication.
at org.apache.commons.net.ftp.FTP.__getReply(FTP.java:317)
at org.apache.commons.net.ftp.FTP.__getReply(FTP.java:294)
at org.apache.commons.net.ftp.FTP.getReply(FTP.java:692)
at org.apache.commons.net.ftp.FTPClient.completePendingCommand(FTPClient.java:1813)
at org.apache.commons.net.ftp.FTPClient.initiateListParsing(FTPClient.java:3308)
at org.apache.commons.net.ftp.FTPClient.initiateListParsing(FTPClient.java:3271)
at org.apache.commons.net.ftp.FTPClient.listFiles(FTPClient.java:2930)
I've checked my firewall settings and that host is allowed to connect via port 990 and 6200-6300.
I've also read FTPClient.listFiles not working and Java application hanging during LIST command to FTP Server (Apache Commons FTPClient) and neither of these have helped with my problem.
EDIT: It looks as though FTPClient is not recognizing the data channel. I tried uploading a file instead of doing a listing, and it died after the "150 Opening data connection" message. I've confirmed that the ports assigned to the data connection from the PASV command are NOT blocked by our firewall.
Any ideas?
I fixed it. Turns out I was doing a directory listing with an invalid path. Instead of returning an error message, Apache FTP closed the connection. Not sure why. Anyway, it's working now.