---
# System prepended metadata

title: '[Jenkins] Pipeline 編寫綁定免費證書'
tags: [jenkins]

---

# [Jenkins] Pipeline 編寫綁定免費證書
###### tags `jenkins`
:::info
:bulb: 舉例為kc213 租戶申請免費證書
:::
## :beginner: Product Info

- Product Name: 新增域名
- Stage: 
    - [ ] check
    - [ ] 配置腳本傳到指定租戶
    - [ ] 確認是否有安裝免費證書設定
    - [ ] 免費證書腳本傳到指定租戶
    - [ ] 執行處理
    - [ ] 清理腳本
    - [ ] 清除緩存檔案


## :triangular_flag_on_post: 問題探討

:::success
紀錄遇到問題及情況敘述
:::

- 權限問題 需要提權root操作

- 判斷是要規劃清楚
![](https://i.imgur.com/kElW8zt.png)

- 這邊會用git抓取腳本再去做操作 (腳本會貼在下面)
![](https://i.imgur.com/kVVSnf7.png)

## :feet: 流程架構圖

:::success
使用圖形表示流程
:::


``` mermaid
graph TD;
Start-->Check;
Check-->配置腳本傳到指定租戶;
配置腳本傳到指定租戶-->確認是否有安裝免費證書設定;
確認是否有安裝免費證書設定-->免費證書腳本傳到指定租戶;
免費證書腳本傳到指定租戶-->執行處理;
執行處理-->清理腳本;
清理腳本-->清除緩存檔案;
清除緩存檔案-->完成;
```

```yaml=
node {
     stage('Check') {
        echo "$tenantArray"
        echo "$zuhu"
     }
     stage('配置腳本傳到指定租戶') {
        sh ''' for i in $tenantArray ; do
                  cn=$(echo "$i" | cut -d "-" -f 1 )
                  ip=$(echo "$i" | cut -d "-" -f 2 )
                  port=$(echo "$i" | cut -d "-" -f 3 )
                  scp -P $port /ops/ops/domain-add/ssl-install.sh swadmin@$ip:/tmp
                  sleep 2
              done'''
        }
     stage('確認是否有安裝免費證書設定') {
        sh '''for i in ${tenantArray} ; do
                  cn=$(echo "$i" | cut -d"-" -f 1 )
                  ip=$(echo "$i" | cut -d"-" -f 2 )
                  port=$(echo "$i" | cut -d"-" -f 3 )
ssh -T -o StrictHostKeyChecking=No -p $port  jenk_adm@$ip <<EOF
sudo sh /tmp/ssl-install.sh
EOF
               done'''  
     }
     stage('免費證書腳本傳到指定租戶') {
        sh ''' for i in $tenantArray ; do
                  cn=$(echo "$i" | cut -d "-" -f 1 )
                  ip=$(echo "$i" | cut -d "-" -f 2 )
                  port=$(echo "$i" | cut -d "-" -f 3 )
                  scp -P $port /ops/ops/domain-add/NPTsslfree.sh swadmin@$ip:/tmp
                  sleep 2
ssh -T -o StrictHostKeyChecking=No -p $port  jenk_adm@$ip <<EOF
sudo mv /tmp/NPTsslfree.sh /root/.acme.sh/
EOF
              done'''
        }
     stage('執行處理') {
        sh ''' for i in $tenantArray ; do
                  cn=$(echo "$i" | cut -d "-" -f 1 )
                  ip=$(echo "$i" | cut -d "-" -f 2 )
                  port=$(echo "$i" | cut -d "-" -f 3 )
                  scp -P $port /ops/ops/domain-add/NPTsslfree.sh swadmin@$ip:/tmp
                  sleep 2
ssh -T -o StrictHostKeyChecking=No -p $port  jenk_adm@$ip <<EOF
sudo sh /root/.acme.sh/NPTsslfree.sh $zuhu
EOF
              done'''
        }
     stage('清理腳本') {
        sh '''for i in ${tenantArray} ; do
                  cn=$(echo "$i" | cut -d"-" -f 1 )
                  ip=$(echo "$i" | cut -d"-" -f 2 )
                  port=$(echo "$i" | cut -d"-" -f 3 )
ssh -T -o StrictHostKeyChecking=No -p $port  swadmin@$ip <<EOF
rm -rf /tmp/ssl-install.sh
EOF
               done'''  
     }
     stage('清除緩存檔案') {
        sh 'rm -rf /var/lib/jenkins/workspace/$JOB_BASE_NAME/*'
    }
}
```


## :feet: 使用的腳本
:::success
先行判斷是否安裝免費證書腳本
:::
```shell=
#!/bin/sh

###先判斷是否有裝過免費證書 
if [ -d "/root/.acme.sh/" ]; then
    # 目錄 /root/.acme.sh/ 存在
    echo "已有安裝免費證書申請 /root/.acme.sh/ exists."
else
    # 目錄 /root/.acme.sh/ 不存在
    echo "尚未安裝安裝免費證書申請 does not exists. 開始安裝"
    curl https://get.acme.sh | sh
    sleep 2
    sh /root/.acme.sh/acme.sh  --register-account -m TD-larry@mail.idcduty.com --server zerossl
    sh /root/.acme.sh/acme.sh  --set-default-ca --server letsencrypt
    sleep 2
fi  
```

:::success
跑申請免費證書腳本
:::

```shell=
#!/bin/sh

#tg群組跟機器人
chat_id='-1001589110734'
token='bot1033770595:AAH6-wqoOw37Z2A5LQruDQTt-c9cmcoLdtA'
 
#####查询以及整理域名
Tenant=`hostname  |awk -F'-' '{print $2}'`
#需要修改下證書放置路徑
SslPath=/opt/lucky/openresty/nginx/conf/keys/"$1"
#建立目錄
mkdir ${SslPath} && chown -R swadmin:swadmin ${SslPath}
#需要指定要的設定檔案
NginxPath=/opt/lucky/openresty/nginx/conf/vhosts/$Tenant/"$1".conf
cat ${NginxPath} |grep  "server_name " | awk -F 'server_name' '{print $2}' |awk -F';' '{print $1}' > /root/.acme.sh/domain.txt
  
expire_domain=/root/.acme.sh/ErrorDomainList.txt
 
#######清空
echo " " > /root/.acme.sh/ErrorDomainList.txt
echo " " > /root/.acme.sh/d-domain.txt
 
##判斷域名解析
DomainList=`cat /root/.acme.sh/domain.txt|xargs`
for i in $DomainList;do
echo "-d $i" >> /root/.acme.sh/d-domain.txt
#dig域名A紀錄
DomainResults=`dig $i |grep IN |grep A | tail -n 1 | awk '{print $NF}'`
#主機IP
DomainIP=`hostname -I| awk '{print $1}'`
if [ $DomainResults -eq $DomainIP ];then
 echo "$i 没有解析" >>/root/.acme.sh/ErrorDomainList.txt     
fi
done
 
#用檔案大小判斷 (沒用-s 因為他不是為0)
filesize=`ls -l /root/.acme.sh/ErrorDomainList.txt | awk '{print $5}'`
maxsize=$((1*10))
#######将解析异常的域名发送到TG
if [ $filesize -gt  ${maxsize} ];then
 message=`echo $Tenant '申請免費證書尚未解析域名,請查閱'`
 curl -F chat_id="$chat_id" -F document=@"$expire_domain" -F caption="$message" https://api.telegram.org/$token/sendDocument
 echo "有域名尚未解析停止運行" >&2 # 輸出至標準錯誤
 exit 1
fi
 
######## 开始执行申请证书处理
Ssl=`cat /root/.acme.sh/d-domain.txt|xargs`
#echo $Ssl
/root/.acme.sh/acme.sh --issue ${Ssl} -w /opt/letsencrypt --key-file ${SslPath}/server.key --fullchain-file ${SslPath}/server.crt --force
chown -R swadmin:swadmin ${SslPath}/*
 
#證書位置
ssl_key=`echo $SslPath |awk -F '/' '{print $8}'`
#開啟強跳
sed -i "s/keys\/wk311\//keys\/$ssl_key\//g" ${NginxPath}
sed -i "s/keys\/abcty1\//keys\/$ssl_key\//g" ${NginxPath}
sed -i "s/keys\/abcty\//keys\/$ssl_key\//g" ${NginxPath}
sed -i "s/keys\/kg\//keys\/$ssl_key\//g" ${NginxPath}
sed -i "s/#    if ( \$scheme \= http ){/    if ( \$scheme \= http ){/g" ${NginxPath} 
sed -i "s/#               return 301 https:\/\/\$server_name\$request_uri;/               return 301 https:\/\/\$host\$request_uri;/g" ${NginxPath}
sed -i "s/#               return 301 https:\/\/\$host\$request_uri;/               return 301 https:\/\/\$host\$request_uri;/g" ${NginxPath} 
sed -i "s/#    }/    }/g" ${NginxPath}
 
#nginx reload
/opt/lucky/openresty/nginx/sbin/nginx -t
/opt/lucky/openresty/nginx/sbin/nginx -s reload
/opt/lucky/openresty/nginx/sbin/nginx -t


#抓此次域名
newdomain=`cat /root/.acme.sh/domain.txt |xargs`

changeString="$Tenant 的免費證書已完成 %0A%0A此次證書配置為 $1.conf %0A%0A此次證書域名為 $newdomain"

#發送告警
curl -gs "https://api.telegram.org/bot1033770595:AAH6-wqoOw37Z2A5LQruDQTt-c9cmcoLdtA/sendMessage?chat_id=-1001589110734&text=$changeString"
```

## :feet: 操作實例
:::success
jenkins 操作圖解
:::
![](https://i.imgur.com/lHB48pz.png)
![](https://i.imgur.com/C9r77eE.png)
![](https://i.imgur.com/rK5GuOv.png)
![](https://i.imgur.com/AoYDVXT.png)
![](https://i.imgur.com/dqIJad9.png)
![](https://i.imgur.com/KA25Wvx.png)
![](https://i.imgur.com/4Lq6ou3.png)
