In the previous post I’ve explained how to configure the login over ssh to execute remote commands with Jenkins with a Build Step, now it’s the same but using Pipeline Step.
Avoid login prompt
To avoid logging prompt on each execution with the pipeline script is necessary copy the ssh key to remote server.
-
Create a ssh key pair, login in the Jenkins server with the user that are executing the Jenkins as a service and execute the next commands:
sudo su -s /bin/bash jenkins ssh-keygen -t -rsa
Leave the options by default, a file
$HOME/.ssh/id_rsa
is generated, take care if you have a previous file, you will not be able to authenticate using the previous key anymore if you choose overwrite -
Copy the public key to remote server use only one of this commands:
# Using pub key by default ~/.ssh/id_rsa.pub ssh-copy-id user@host # Using another key ssh-copy-id -i ~/.ssh/otherKey.pub user@host # if ssh-copy-id is not available, do it manually cat ~/.ssh/id_rsa.pub | ssh user@host"mkdir -p ~/.ssh && touch ~/.ssh/authorized_keys && chmod -R go= ~/.ssh && cat >> ~/.ssh/authorized_keys"
-
Test the connection
# Test the login with the private key ssh -i ~/.ssh/id_rsa user@host # Then connect without prompt password ssh user@host
For more detail check this post
If the authentication fails
If the above steps were followed and ssh’ing to the appropriate user is still prompting for passwords, inspect the permissions on both the local and remote user’s files, per the following command:
[user@ssh-server ~]$ ls -ld ~/{,.ssh,.ssh/authorized_keys*}
drwx------. 25 user user 4096 Aug 21 11:01 /home/user/
drwx------. 2 user user 4096 Aug 17 13:13 /home/user/.ssh
-rw-------. 1 user user 420 Aug 17 13:13 /home/user/.ssh/authorized_keys
And set the permissions as follow:
chmod 600 ~/.ssh/authorized_keys
chmod 700 ~/.ssh/
Don’t forget it, the PubkeyAuthentication yes must be enabled in the server into /etc/ssh/sshd_config
Configure the Pipeline
Create a new Pipeline project and set the next script, notice the end of the pseudo script is intentionally aligned at left, if I indent the text does not work.
pipeline {
agent any
stages {
stage('execute') {
steps {
script {
echo 'Using remote command over ssh'
sh 'echo "Today is:" date'
echo '*** Executing remote commands ***'
sh '''#!/bin/bash
date
ssh devops@hostname << ENDSSH
java -version
date
cd /tmp
pwd
ENDSSH
'''
sh '''
date
ssh devops@hostname << ENDSSH
javac -version
date
cd /tmp
pwd
ENDSSH
'''
}
}
}
}
}
Then save it and execute the job.
Checking the job log
The script have different ways to call a sh command, let’s check each one.
sh 'echo "Today is:" date'
The first is a simple sh command to get date, the interesting part is how Jenkins execute this, if see the job log each command is executed by separate, the echo
first and date
after.
[Pipeline] echo
Using remote command over ssh
[Pipeline] sh
[PL_REMOTE_COMMAND] Running shell script
+ echo Today is:
Today is:
+ date
mié dic 18 05:05:06 CST 2019
The second command is executed line by line, one per command:
echo '*** Executing local commands ***'
sh '''
ls -l
date
cd /tmp
pwd
'''
output:
[Pipeline] echo
*** Executing local commands ***
[Pipeline] sh
[PL_REMOTE_COMMAND] Running shell script
+ ls -l
total 0
+ date
mié dic 18 05:05:07 CST 2019
+ cd /tmp
+ pwd
/tmp
The next command use a pseudo script style to hide the commands and connect to remote server, note my servers have a different date time, that means the commands in the script are hidden in the log and only shows the result of each one:
echo '*** Executing remote commands ***'
sh '''#!/bin/bash
date
ssh devops@hostname << ENDSSH
java -version
date
cd /tmp
pwd
ENDSSH
'''
output:
*** Executing remote commands ***
[Pipeline] sh
[PL_REMOTE_COMMAND] Running shell script
mié dic 18 05:31:05 CST 2019
Pseudo-terminal will not be allocated because stdin is not a terminal.
java version "1.6.0_45"
Java(TM) SE Runtime Environment (build 1.6.0_45-b06)
Java HotSpot(TM) Server VM (build 20.45-b01, mixed mode)
vie dic 20 18:20:22 CST 2019
/tmp
This is a good option if you don’t want to show sensible commands in other way, remove the script header to show them.
echo '*** Executing remote commands ***'
sh '''
date
ssh devops@hostname << ENDSSH
java -version
date
cd /tmp
pwd
ENDSSH
'''
output:
[Pipeline] echo
[Pipeline] sh
[PL_REMOTE_COMMAND] Running shell script
+ date
mié dic 18 05:31:05 CST 2019
+ ssh devops@hostname
Pseudo-terminal will not be allocated because stdin is not a terminal.
javac 1.6.0_45
vie dic 20 18:20:22 CST 2019
/tmp
This is the full output of the job:
References
- https://access.redhat.com/solutions/9194
- https://support.cloudbees.com/hc/en-us/articles/222838288-SSH-Credentials-Management-with-Jenkins
- https://www.karthikeyan.tech/devops/ssh-agent-blue-ocean-via-jenkins-pipeline-as-code.html
Cheers!
Hey, thanks for the steps, but i was getting permission denied when i use the script.
Pseudo-terminal will not be allocated because stdin is not a terminal.
— WARNING — This system is for the use of authorized users only. Individuals
using this computer system without authority or in excess of their authority
are subject to having all their activities on this system monitored and
recorded by system personnel. Anyone using this system expressly consents to
such monitoring and is advised that if such monitoring reveals possible
evidence of criminal activity system personal may provide the evidence of such
monitoring to law enforcement officials.
Permission denied, please try again.
Permission denied, please try again.
Received disconnect from port 22:2: Too many authentication failures
This is a great article, Thanks for sharing this.
If you have ever encountered an issue with not connecting the Jenkins server from a remote PC, the below article might help you.
https://techiewheel.blogspot.com/2022/02/why-i-cannot-access-jenkins-server-from.html
Thanks for sharing, every tip is welcome.
I am getting permission denied error while runningthe job, even though through jenkins server I can ssh into my remote server. Please suggest what needs to be done in this case.
Hi, I’ve written a new entry of this topic and is more easy to configure, may you want to read it.
Regarding of your question may you could verify this:
1. Execute a telnet command from the jenkins server to the remote ssh server, in order to verify the port 22 is open
2. Enruse the /etc/ssh/sshd_config has the property PubkeyAuthentication yes in the remote ssh server
bye