Как отключить проверки безопасности для сборок конвейера Jenkins

Я запускаю Jenkins в локальной доверенной среде, где я пытаюсь запустить этот конвейер. Этот Jenkinsfile проверен в git.

#!groovy
node('master') {
    def ver = pomVersion()
    echo "Building version $ver"
}

def pomVersion(){
    def pomtext = readFile('pom.xml')
    def pomx = new XmlParser().parseText(pomtext)
    pomx.version.text()
}

Первые несколько раз, когда я запускал сборку, мне нужно было вручную утверждать изменения (Jenkins->Mange Jenkins-> In-process Script Approval). Теперь я получаю это исключение, и мне нечего утверждать. Все, что я хочу сделать, это разобрать файл XML. Можно ли полностью обойти эти проверки безопасности при сборке конвейера?

org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: unclassified field groovy.util.Node version
    at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.unclassifiedField(SandboxInterceptor.java:367)
    at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onGetProperty(SandboxInterceptor.java:363)
    at org.kohsuke.groovy.sandbox.impl.Checker$4.call(Checker.java:241)
    at org.kohsuke.groovy.sandbox.impl.Checker.checkedGetProperty(Checker.java:238)
    at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.getProperty(SandboxInvoker.java:23)
    at com.cloudbees.groovy.cps.impl.PropertyAccessBlock.rawGet(PropertyAccessBlock.java:17)
    at WorkflowScript.pomVersion(WorkflowScript:10)
    at WorkflowScript.run(WorkflowScript:3)
    at ___cps.transform___(Native Method)
    at com.cloudbees.groovy.cps.impl.PropertyishBlock$ContinuationImpl.get(PropertyishBlock.java:62)
    at com.cloudbees.groovy.cps.LValueBlock$GetAdapter.receive(LValueBlock.java:30)
    at com.cloudbees.groovy.cps.impl.PropertyishBlock$ContinuationImpl.fixName(PropertyishBlock.java:54)
    at sun.reflect.GeneratedMethodAccessor479.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.cloudbees.groovy.cps.impl.ContinuationPtr$ContinuationImpl.receive(ContinuationPtr.java:72)
    at com.cloudbees.groovy.cps.impl.ConstantBlock.eval(ConstantBlock.java:21)
    at com.cloudbees.groovy.cps.Next.step(Next.java:58)
    at com.cloudbees.groovy.cps.Continuable.run0(Continuable.java:154)
    at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.access$001(SandboxContinuable.java:18)
    at org.jenkinsci.plugins.workflow.cps.SandboxContinuable$1.call(SandboxContinuable.java:32)
    at org.jenkinsci.plugins.workflow.cps.SandboxContinuable$1.call(SandboxContinuable.java:29)
    at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.GroovySandbox.runInSandbox(GroovySandbox.java:108)
    at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.run0(SandboxContinuable.java:29)
    at org.jenkinsci.plugins.workflow.cps.CpsThread.runNextChunk(CpsThread.java:164)
    at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.run(CpsThreadGroup.java:276)
    at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.access$000(CpsThreadGroup.java:78)
    at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:185)
    at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:183)
    at org.jenkinsci.plugins.workflow.cps.CpsVmExecutorService$2.call(CpsVmExecutorService.java:47)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at hudson.remoting.SingleLaneExecutorService$1.run(SingleLaneExecutorService.java:112)
    at jenkins.util.ContextResettingExecutorService$1.run(ContextResettingExecutorService.java:28)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Finished: FAILURE

4 ответа

Решение

В настоящее время это невозможно. Есть открытый билет на эту проблему https://issues.jenkins-ci.org/browse/JENKINS-28178

Вы можете решить проблему, выполнив следующие действия:

  1. установить плагин Permissive Script Security (версия 0.3 или новее)
  2. добавлять permissive-script-security.enabled параметр командной строки для мастера Jenkins со значением:

    • true если вы хотите отключить необходимость утверждать сценарии, но потенциально опасные подписи будут записываться:

      -Dpermissive-script-security.enabled=true
      
    • no_security если вы хотите отключить необходимость утверждать сценарии и отключить также запись потенциально опасных подписей:

      -Dpermissive-script-security.enabled=no_security
      

Попробуйте следующий плагин jenkins: https://wiki.jenkins-ci.org/display/JENKINS/Permissive+Script+Security+Plugin Отключает песочницу. Работает для меня.

Я хотел бы предложить хак, который я в итоге реализовал после того, как поискал решение в сети и попробовал некоторые из предложенных здесь решений.

Небольшая предыстория моей настройки:

  • Мастер Дженкинса (без рабов)
  • Докеризованный экземпляр Jenkins с постоянным томом для каталога jenkins_home
  • Задания Jenkins доставляются через плагин Jenkins Job DSL с заданиями, написанными на.groovy.

Мой сценарий: каждый раз, когда кто-то изменял существующий конвейер Jenkins (через groovy) и вводил новые функции, в которых использовался некоторый настраиваемый groovy, Jenkins не выполнял задание и отмечал фрагмент кода для утверждения. Утверждение было ручным и утомительным.

Я пробовал решения, опубликованные выше, и они не помогли мне. Итак, мой взлом состоял в том, чтобы создать задание Jenkins, которое запускает задание оболочки, которое берет список подписей, которые необходимо одобрить, а затем добавляет их в файл /var/jenkins_home/scriptApproval.xml.

Некоторые ошибки:

  • Неправильное задание все равно должно потерпеть неудачу, чтобы я нашел / скопировал проблемный код / ​​подпись
  • Чтобы изменения вступили в силу, вы не можете "перезагрузить с диска", чтобы файл был поднят. Вам необходимо перезапустить процесс Jenkins (в нашем случае удалить контейнер и вернуть его в рабочее состояние). Для меня это не было большой проблемой, поскольку Дженкинс перезапускается каждое утро.
  • В нашем мире мы доверяем разработчикам, которые изменяют наши задания Jenkins, поэтому они могут свободно добавлять подписи, требующие утверждения, по мере необходимости. Кроме того, работа связана с контролем версий, чтобы мы могли видеть, кто что добавил.
  • В моем контейнере Jenkins также есть xmlstarlet, поэтому моя работа оболочки использует его для обновления файла

Пример команды оболочки моей работы Jenkins:

#!/bin/bash
echo ""

#default location of the Jenkins approval file
APPROVE_FILE=/var/jenkins_home/scriptApproval.xml

#creating an array of the signatures that need approved
SIGS=(
'method hudson.model.ItemGroup getItem java.lang.String'
'staticMethod jenkins.model.Jenkins getInstance'
)

#stepping through the array
for i in "${SIGS[@]}"; do
   echo "Adding :"
   echo "$i"
   echo "to $APPROVE_FILE"
   echo ""
   #checking the xml file to see if it has already been added, then deleting. this is a trick to keep xmlstarlet from creatine duplicates
   xmlstarlet -q ed --inplace -d "/scriptApproval/approvedSignatures/string[text()=\"$i\"]" $APPROVE_FILE

   #adding the entry
   xmlstarlet -q ed --inplace -s /scriptApproval/approvedSignatures -t elem -n string -v "$i" $APPROVE_FILE
   echo ""
done

echo "##### Completed updating "$APPROVE_FILE", displaying file: #####"
cat "$APPROVE_FILE"

Как уже было сказано выше: в более новых версиях Jenkins была повышена безопасность скриптов. Однако для конкретного случая использования чтения версии из Maven pom.xml можно использовать readMavenPom из плагина Pipeline Utility Steps:

pom = readMavenPom file: 'pom.xml'
pom.version

С некоторыми другими решениями в этом вопросе Stackru также.

Другие вопросы по тегам