Unable to authorise using jsch private key - java

I am trying to connect to a local ssh for testing purposes.
I am trying to login using ssh keys with jsch.
This is what I am putting in config:
config.put(STRICT_HOST_KEY_CHECK, strictHostKeyCheckValue); // no
config.put("PreferredAuthentications", "publickey");
The keys are valid and I am passing in the correct path to them.
The sever is running in background.
But I am not able to connect to it.
The error is “Auth failed”.
Can anyone suggest where should I look further.
I am working on macos.

I've never used ssh where the client and server are the same host, but I just tried. The server STILL uses ~/.ssh/authorized_keys to look for the public key. IS it there? Make sure with cat ~/.ssh/id_rsa.pub >>~/.ssh/authorized_keys. That at least is what my public key file is. Yours might be different.

Related

Nifi and Postgresql with certificate: how to set client certificate and key?

I have a NIFI image running in openshift and a postgres in the cloud "owned" by another department.
They sent to us a certificate(".crt") and a key(".key"), since the log-in is made trough client certificate, instead of username and password. I have succeeded to log-in in pgAdmin 4, but not to connect the NIFI to the Postgres with certificate and key.
I have uploaded the certificate and the key to the image (using a secret and mounting it) so if I go to the pod terminal I can access it.
But, when I pass to a DBCPConnectionPoll service the connection string bellow and activates an ExecuteSQL processor, I receive an exception that the certificate is not valid, as follows:
ERROR
ExecuteSQL[id=...] Unable to execute SQL query <...>;
due to java.sql.SQLException: Cannot create a PoolableConnectionFactory (FATAL: connection requires a valid client certificate).
No FlowFile to route to failure: org.apache.nifi.processor.exception.ProcessException: java.sql.SQLException: Cannot create a PoolableConnectionFactory (FATAL: connection requires a valid client certificate)
I have tried to pass the certificate in two ways to the DBCPConnectionPoll service:
1) as parameters in the connection string ("database connection url" property:
jdbc:postgresql://<ip>:<port>/<username>?user=<username>&sslTrue&sslcert=/etc/.../mycerts/mycert.der&sslkey=/etc/.../mycerts/mykey.key.pk8
2) adding properties in the service (+ button and the just parameter name and the path as the value) and just passing this as url:
jdbc:postgresql://<ip>:<port>/<username>
Both seems to work generally speaking, since I can connect to another postgres I have which not requires ssl certification.
Some considerations:
1) My assumption here is that the connection string in the NIFI does not know to read properly the file path for the certificate and key.
2) I have converted the certificates a bunch of times to different types that java can receive in order to see if that was the problem, but I still receive the same exception. So it seems that the connection pool just does not "achieve" the files at all. Nevertheless, if some one has a say in this topic, it can be handy, after the main problem is solved. So appreciate some tips here as well.
3) I have also read the NIFI source code and it seems that NIFI uses normally JDBC classes to create the connection pool, so a connection string as I passed would have worked in java code, but somehow doesn't work in NIFI (which is written in java).
4) The jdbc driver and everything else is configured properly, since I can work with a non-secure postgres in NIFI.
Thank you very much.
A co-worker found the 'simple solution' to the problem I asked and I would like to share so it can help others.
What was missing was the property sslmode = require. After including that, the service worked perfectly. Actually, I am not sure why it didn't work with sslmode = prefer, since it is what my pgadmin is using for the same database and there it works perfectly. It seems like we must 'force' nifi to use ssl in this case - see documentation here: https://jdbc.postgresql.org/documentation/head/ssl-client.html.
Moreover, some insights:
It worked with certificate in '.der' and key in '.pk8' formats (didn't have to use trust-store and key-store as needed in other services).
One can add in the 'plus' button the properties and give them the right name as we would do in java code, instead of concatenating every property in the connection string (see second option in the question above).
Make it helps others as well.

SSH from inside a docker container

So, I haven't worked with docker for very long. But this is the first time where I've had a requirement to ssh OUT of a docker container. It should be straight forward because I know I can connect to databases pull files from repositories. But for some reason I cannot seem to connect to a remote sftp server. Interestingly on my local it runs fine (no docker), but when building on Jenkins the tests cannot connect. Even to a MOCK server that I set up and put a test file on before the tests run. Running on Jenkins also makes it difficult to debug what the issue is.
Im using Jcraft to get the connection below:
public static Session getSession (String host, String user) throws JSchException{
JSch jsch = null;
int port = 22;
if (JunitHelperContext.getInstance.isJunit()){
port = JunitHelperContext.getInstance.getSftpPort();
Session session = jsch.getSession(user,host,port);
java.util.Properties config = new java.util.Properties();
config.put(“StrictHostKeyChecking”, “no”);
if (!JunitHelperContext.getInstance.isJunit()){
config.put(“PreferredAuthentications”, “publickey”);
jsch.setKnownHosts(”~/.ssh/known_hosts”);
jsch.addIdentity(“~/.ssh/id_rsa”);
}
session.setConfig(config);
session.connect();
return session;
}
}
My requirement is to go out and read a file and process it. I can build the kit fine using a non-docker template. The file is found and processed. Running it inside a docker container though, I get this error when I try to connect:
Invalid Key Exception: the security strength of SHA-1 digest algorithm is not sufficient for this key size.
com.jcraft.jsch.JSchException: Session.connect: java.io.IOException: End of IO Stream Read
So this seems like a security issue. In production, the certificates are on the server and they can be read in that /.ssh directory. But this is a mock Jcraft server, and I shouldnt need to authenticate.
Is there a piece I am missing here? Configuration in the docker file ?Thanks in advance.
You probably need to enable Java's JCE unlimited strength stuff in the docker container:
http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html
There are export restrictions on this cryptography stuff and I'll bet your docker container has the weak strength exportable jars.
Copy local_policy.jar and US_export_policy.jar into the docker container with the Dockerfile and overwrite what's there.
Follow the instructions at that link.

How to connect opc kepware server through a Java program, without the username and the password?

I am trying to connect opc kepware server through a Java program, I want to know what jar files can be used to connect to KepwareserverEx.V5 and what is the code without the use of password and username.
I have referenced http://www.opcconnect.com/uakit.php, and https://github.com/digitalpetri/ua-server-sdk, but it doesn't have anything that doesn't connect without a username and a pawssword. I have a program in vb that connects to kepware using Interop.OPCAutomation.dll file and uses the code:
ConnectedOPCServer = New OPCAutomation.OPCServer
ConnectedOPCServer.Connect("Kepware.KEPServerEX.V5", "")
ConnectedGroup = ConnectedOPCServer.OPCGroups.Add("MPM Group")
ConnectedGroup.UpdateRate = 1000
ConnectedGroup.IsSubscribed = True
ConnectedGroup.IsActive = True
I want to write Java code in a similar way. Searched through the internet to see various examples, but none have the above connection without a username and password not being specified.
First of all, I assume that you have created an "anonymous" and "SecurityPolicy.None" endpoint on KepServerEX.
You refer to digitalpetri's old and server SDK. The new project is called "Milo". I can recommend you take a look at the Milo project's client SDK examples using this link. There is an application of anonymous identity and none security policy.
In terms of jar, you can either build your client-sdk (see example here) or directly download the client-sdk jar from Maven Central.
NB Milo is considered to be in incubation. That is to say, it is not mature yet. Be careful using it in production systems.
Yes that's right. The security policy is none on the KepwareServerEX. I made some permission changes on the server where Kepware exists, so that my localhost computer would be able to talk to the Kepware server host. Provided credentials for my localhost, and able to connect.

How to execute ssh bash command from java code?

I know there is a lot of thread about this problem but I dont found right: I follow this example: Want to invoke a linux shell command from Java to run command. Problem with ssh command is in authentication. When I run it I need to set password
$ ssh root#server 'fgrep Exception *.log*'
Enter passphrase for key '/././.ssh/id_rsa':
How can I pass here password ?
There are libraries are available to invoke ssh. The Java Secure Channel (JSCH) is a very popular library, used by maven, ant and eclipse. It is open source with a BSD style license.
If you need authentication for ssh, you can use through java.
If your still need to by pass password passing, there are two ways to do what you want. One involves a stored password, and one does not.
Both are non-interactive, meaning that they can work when you're not there to enter a password.
The way that does not require a password. You can use public/private
key authentication instead of passwords with SSH. I'm going to
assume that you're using OpenSSH, which comes with practically every
Linux distribution.
Steps :
Configure your SSH server to accept private key logins. In /etc/ssh/sshd_config make sure that there's a line that says PubkeyAuthentication yes (and that there is no # infront of it). If you change this file, you need to restart the sshd service.
On your local machine (not the server), create yourself a pair of keys with ssh-keygen -t rsa (you can use other options than rsa, but I'm keeping it simple). Do not specify a password. Save the keys in the locations prompted.
Open the contents of the id_rsa.pub file that you just created (it's one very long line of text), and copy the contents into the end of the file $HOME/.ssh/authorized_keys on the server machine. Create the file if it doesn't exist.
Further Detail refer here.
The basic idea is to use expect, which is an
administration automation tool, to type your password in to ssh when
prompted. It might not always work, and when it doesn't, it's hard
to figure out why not. I recommend the first method.
Anyway, here's a command that you can poke at until it does what you
want.
The script Code is:
expect -c 'spawn ssh user#remote.host ; expect assword ; send "passphrase\n" ; interact'
Expect might not be installed on your system. Make sure install that
You need to get the InputStream (which has the output) from the execution and wait for it to ask you for the password, then get the OutputStream (into which you give the command its input) and send it the password you want.
Have a read of this article

How can I make the JSch API log in to a Unix server without a password?

I'm trying to make a Java application, that executes shell scripts on a remote Unix server, using the JSch API.
I was wondering if it's possible to login to the server without a password. If so - how? Should I generate a pair of authentication keys on the servers, then make the application read information from the key file?
The Java application is on a Windows station.
Since it took awhile before made it work, here is a whole modified example:
JSch jsch=new JSch();
Session session=jsch.getSession("my_username", "my_host", my_port);
session.setConfig("PreferredAuthentications", "publickey");
jsch.setKnownHosts("~/.ssh/known_hosts");
jsch.addIdentity("~/.ssh/id_rsa");
session.setConfig("StrictHostKeyChecking", "no");
session.connect(30000);
Channel channel=session.openChannel("shell");
channel.setInputStream(System.in);
channel.setOutputStream(System.out);
channel.connect(3*1000);
Beware whether you have copied rsa or dsa key to the server and add a corresponding identity at line addIdentity - id_rsa or id_dsa.
(cat .ssh/id_rsa.pub | ssh me#servername 'cat >> .ssh/).
This is certainly doable. Have a look at the examples directory provided with jsch.
UserAuthPubKey.java is showing how to authenticate with a public key and and KeyGen.java is chowing how to create the public and private keys.
Once you have sorted out your keys there is a single line to enable connecting with a key rather than a password:
JSch jsch = new JSch();
jsch.addIdentity(".ssh/privateKey.pem");
The addIdentity method takes a single argument that points at the location of your private key file on your machine.
As said by jlliagre, it is possible.
Generate a key pair for your application, make the public key known to the server (often putting it in ~/.ssh/authorized_keys is a good way), and give both keys to the client JSch object, either as files or as byte[]. You might also want to change the PreferredAuthentications option to allow only public-key auth, to avoid asking for a password or trying something else.
Note: If you deliver your application to hosts not controlled by you, anyone which can access the application's files can use the private key to login to your server.
Thus you should make sure the account can't do anything harmful, or that the client machine (your account and any privileged one) is under your (or only known friendlies') total control. (Encrypting the private key with a passphrase does not help if the passphrase is distributed with your program. Neither does putting it in the program's jar file.)

Categories

Resources