Jenkins setup:
Hello,
I am using Jenkins CasC as well as some SSH agents via AWS SSM.
In order to connect to these agents, I needed to write an ssh config file placed at ~/.ssh/config with the following contents.
# SSH over Session Manager
host i-* mi-*
ProxyCommand sh -c "aws ssm start-session --target %h --document-name AWS-StartSSHSession --parameters 'portNumber=%p'"
I also needed to create a helper script that would transfer the Jenkins.jar file to the remote host and execute it, ref Command Agent Launcher
sshHelper.sh
#!/usr/bin/env bash
# $1 = hostname (mi-abcdefg)
# $2 = username for host
set -euxo pipefail
# get copy of agent.jar
local_tmp_dir=$(mktemp -d -t agent-XXXX)
cd "$local_tmp_dir"
agent_fname="${STAGE}-agent.jar"
wget http://127.0.0.1:8080/jnlpJars/agent.jar -O "${agent_fname}"
# get remote directory to transfer agent to
agent_remote_dir=$(ssh "$2@$1" "mktemp -d -t agent-remote-XXXX" < /dev/null)
# SCP to that remote directory
scp -v "$local_tmp_dir/$agent_fname" "$2@$1:$agent_remote_dir/"
# connect stdout / stderr to the java agent, and let Jenkins take the wheel
ssh -v "$2@$1" java -jar "$agent_remote_dir/$agent_fname"
This allowed me to use the system SSH to connect to my agents using AWS SSM
When connecting to my agents, I find that I need to approve the script to run manually, and this results in the hash of the script being added to the approved signatures XML file.
What I would like to do is to add the path to the script itself to approved Signatures block and use CasC to define this, eg
security:
scriptApproval:
approvedSignatures:
- "method hudson.model.Computer isOnline"
but for my script’s path
From looking at the documentation, and the traceback encountered, I should be allowing the Hudson CommandLauncher function, but I am not sure
2024-02-27 09:09:53.555+0000 [id=173] SEVERE hudson.slaves.CommandLauncher#launch: Unable to launch the agent for pi-001
java.io.EOFException: unexpected stream termination
at hudson.remoting.ChannelBuilder.negotiate(ChannelBuilder.java:459)
at hudson.remoting.ChannelBuilder.build(ChannelBuilder.java:404)
at hudson.slaves.SlaveComputer.setChannel(SlaveComputer.java:440)
at hudson.slaves.CommandLauncher.launch(CommandLauncher.java:170)
at hudson.slaves.SlaveComputer.lambda$_connect$0(SlaveComputer.java:297)
at jenkins.util.ContextResettingExecutorService$2.call(ContextResettingExecutorService.java:46)
at jenkins.security.ImpersonatingExecutorService$2.call(ImpersonatingExecutorService.java:80)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:829)
The config file that my agents are defined in is similar to this
jenkins:
nodes:
- permanent:
name: "dev-001"
nodeDescription: "dev-001 machine in the lab"
numExecutors: 1
remoteFS: "/home/user"
labelString: "dev-001"
retentionStrategy: 'always'
launcher:
command:
command: "/apollo/env/AlFpgaJenkinsConfig/bin/sshHelper.sh mi-redacted-id user"
mode: EXCLUSIVE
How do I find the right classpath to add to Jenkins’s CasC that will let me allow all invocations of my custom script and not just the specific invocation?
redefined in the config file
I want to use approvedSignatures
and not approvedScriptHashes
so that when I add more machines to my config, they will already be approved and not need their hashes to be approved in the config file.