As Jenkins adoption continues to rise, one thing that we are starting to see is a collision with some corporate IT Security policies.
For various reasons (and let’s not worry about whether we agree with those reasons or not) there are some corporations where IT Security policy requires that every machine display a warning notice about unauthorized usage any time somebody connects to a machine.
Image Public Domain , Source
Typically you will see something like
$ ssh somehost.acme.com #### WARNING #### # BIG SCARY TEXT IN ALL CAPS # #### WARNING #### Last login: Fri Aug 1 02:10:17 2014 from otherhost.acme.com $
This is typically implemented by having sshd_config use a Banner, e.g.
Banner /some/path/to/banner
Which is fine. Jenkins doesn’t care about that type of warning message.
Of course there is an issue with the above solution from the IT Security policy… what happens if somebody logs into the machine not via SSH but instead on the console directly?
So somebody goes an implements a shell profile solution to display the warning message for on-console login also. Here is where the problem starts to creep in. There are many ways to get the warning message to show. If I were to summarise them I would break them into two schools of thought:
Add warning to places where I know it is missing - risking that there are some cases that need the banner but I don’t know about
Remove warning from places where I know it is redundant - risking that I might display the banner when it is not necessary
It is the second school of thought that can cause problems for Jenkins. You know you have a system where this might be a problem if, when you login by SSH, you see something like
$ ssh somehost.acme.com #### WARNING #### # BIG SCARY TEXT IN ALL CAPS # #### WARNING #### Last login: Fri Aug 1 02:12:34 2014 from otherhost.acme.com #### WARNING #### # BIG SCARY TEXT IN ALL CAPS # #### WARNING #### $
In the above case something in either the shell profile or .bashrc is outputting the second warning. To check if this is really an issue for you try the following command:
$ ssh somehost.acme.com ‘echo hello world' #### WARNING #### # BIG SCARY TEXT IN ALL CAPS # #### WARNING #### hello world
If you see the above then you are in the clear… if you see the following then you have an issue
$ ssh somehost.acme.com ‘echo hello world' #### WARNING #### # BIG SCARY TEXT IN ALL CAPS # #### WARNING #### #### WARNING #### # BIG SCARY TEXT IN ALL CAPS # #### WARNING #### hello world
The solution is to change how the warning is displayed so that the warning is only displayed for interactive shells, or change it so that the warning is suppressed for SSH sessions (as they already have the banner)
If you then try to connect an SSH agent to Jenkins your agent launch log will look something like:
[08/01/14 10:43:53] [SSH] Authentication successful. SSH connection reports a garbage before a command execution. Check your .bashrc, .profile, and so on to make sure it is quiet. The received junk text is as follows: #### WARNING #### # BIG SCARY TEXT IN ALL CAPS # #### WARNING #### hudson.AbortException at hudson.plugins.sshslaves.SSHLauncher.verifyNoHeaderJunk(SSHLauncher.java:713) at hudson.plugins.sshslaves.SSHLauncher.launch(SSHLauncher.java:590) at hudson.slaves.SlaveComputer$1.call(SlaveComputer.java:228) at java.util.concurrent.FutureTask.run(FutureTask.java:262) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at java.lang.Thread.run(Thread.java:745) [08/01/14 10:43:53] [SSH] Connection closed.
The exact solution will need to be agreed with your corporate IT Security people, but a simple starting point would be to wrap the banner display logic in something like
case $- in *i*) # interactive shell cat /some/path/to/banner ;; *) # non-interactive shell ;; esac
That is by no means the only way to fix the issue, and it may leave some connection mechanisms open that your IT Security people want the warning displayed for, but it is a reasonable starting point to open up the dialog. Once they know what the problem is, and that this is to cover a non-interactive connection, together you should be able to craft an acceptable solution.
Stephen Connolly
Elite Developer and Architect
CloudBees