Search code examples
jenkinsartifactorynexus

Jenkins plugin repo as proxy repo when behind a corporate proxy


Is there a way - or a tool - that let me setup the jenkins plugin site as proxy repo so that within Jenkins I can get the plugin updates from the proxy repo rather than the original site?

The issue arises specially in environments where you cannot have direct access to the internet. So in my scenario I have a Nexus Repo Server which has access to the internet. The Jenkins server has not. So my approach was to

  1. Setup a proxy repo (let's say https://nexus.intra/repository/updates.jenkins.io/ which is a proxy to https://updates.jenkins.io/
  2. Configure Jenkins so that the plugins are gathered from the proxy repo. Thus I configure the plugin udate site to https://nexus.intra/repository/updates.jenkins.io/update-center.json

This does not work. I get the notification of new plugins, but when I try to download the plugin the connection fails, as within the update-center.json the pointer to the plugins is still https://updates.jenkins.io/. See here ...

updateCenter.post(
....
,"url":"http://updates.jenkins-ci.org/download/plugins/AnchorChain/1.0/AnchorChain.hpi",
....

So any ideas how to achieve this?


Solution

  • One solution I have implemented is to modify the hosts file on the Jenkins host to point to the artifact repo when querying updates.jenkins-ci.org. However this requires a reverse proxy in front of your artifact repo.

    Step-by-Step

    1. On Jenkins host update the hosts file as follows

      <artifact repo ip> plugins.jenkins.io updates.jenkins.io updates.jenkins-ci.org mirrors.jenkins.io
      
    2. Setup a reverse proxy in front of the artifact repo which handles traffic for updates.jenkins.io, updates.jenkins-ci.org, plugins.jenkins.io and mirrors.jenkins.io to your artifact repo

      If you are running your artifact repo in k8s your Ingress may look as follows:

      apiVersion: extensions/v1beta1
      kind: Ingress
      metadata:
      name: artifactory-repo-jenkins
      annotations:
          nginx.ingress.kubernetes.io/rewrite-target: /artifactory/remote-generic-updates.jenkins/
          nginx.ingress.kubernetes.io/upstream-vhost: "artifactory.intra"
          nginx.ingress.kubernetes.io/ssl-redirect: "false"
      spec:
      tls:
      - hosts:
          - updates.jenkins.io
          - updates.jenkins-ci.org
          - mirrors.jenkins.io
          secretName: artifactory-jenkins-ingress-cert
      rules:
      - host: jenkins.intra
          http:
          paths:
          - backend:
              serviceName: artifactory-artifactory
              servicePort: 8081
              path: /
      - host: updates.jenkins.io
          http:
          paths:
          - backend:
              serviceName: artifactory-artifactory
              servicePort: 8081
              path: /
      - host: updates.jenkins-ci.org
          http:
          paths:
          - backend:
              serviceName: artifactory-artifactory
              servicePort: 8081
              path: /
      - host: mirrors.jenkins.io
          http:
          paths:
          - backend:
              serviceName: artifactory-artifactory
              servicePort: 8081
              path: /
      
    3. Optionally if you want to use ssl, you have to create a certificate which includes the urls as alternate names.

      [req]
      distinguished_name = req_distinguished_name
      req_extensions = v3_req
      prompt = no
      [req_distinguished_name]
      C = CH
      O=My Company
      OU = Artifactory
      CN = jenkins.intra
      [v3_req]
      keyUsage = keyEncipherment, dataEncipherment
      extendedKeyUsage = serverAuth
      subjectAltName = @alt_names
      [alt_names]
      DNS.1 = jenkins.intra
      DNS.2 = updates.jenkins-ci.org
      DNS.3 = plugins.jenkins.io
      DNS.4 = updates.jenkins.io
      DNS.5 = mirrors.jenkins.io
      

    Firewall

    In addition, if you have restricted connection I recommend to white-list all mirrors for your artifact repository so it can get the artifacts properly

    • plugins.jenkins.io
    • updates.jenkins-ci.org
    • mirrors.tuna.tsinghua.edu.cn
    • ftp.yz.yamagata-u.ac.jp
    • mirror.esuni.jp
    • mirrors.seville-jam.es
    • mirror.xmission.com
    • archives.jenkins-ci.org
    • ftp-chi.osuosl.org ftp-nyc.osuosl.org

    Or maybe an easier solution is to configure artifactory to only pick updates from a particular mirror.