Derek Coleman & Associates Inc logoDerek Coleman & Associates Inc

Home / Docs / DCA Hardened CI Server — for Jenkins® / Configuration

Configure DCA Hardened CI Server — for Jenkins®

Jenkins® LTS 2.580 with 70 pinned, checksum-verified plugins, the web UI on loopback, and the setup wizard kept: the unlock password and keys are generated on each VM's first start.

On this page: Installed version · First-start credentials and the setup wizard · Unlock and log in · Plugins: the 70 pinned, and what is held back · Network access · Data and logs · Upgrades · Backup and restore

Loopback only by default: the Jenkins web UI and API answer on 127.0.0.1:8080, and the inbound-agent TCP port stays disabled. Nothing but SSH listens beyond loopback.

Installed version

Jenkins® LTS 2.580.1 — the upstream jenkins.war, verified when the image was built (a pinned sha256 equal to the release's own .sha256 and to repo.jenkins-ci.org's, plus the Jenkins Project's GPG signature) and installed as /opt/jenkins/jenkins.war, with the version in /opt/jenkins/version.txt. It runs on Ubuntu's OpenJDK 21 as the jenkins user under jenkins.service (java -jar; not the pkg.jenkins.io package). Base OS: Ubuntu 24.04 LTS. Image built 2026-10-07; every build is gated on zero fixable HIGH or CRITICAL vulnerability findings across the OS, the WAR and every plugin.

cat /opt/jenkins/version.txt
curl -sI http://127.0.0.1:8080/login | grep -i '^x-jenkins:'

First-start credentials and the setup wizard

The setup wizard is kept, not skipped, and nothing credential-like ships: JENKINS_HOME (/var/lib/jenkins) holds only the pinned plugin archives. On its first start on your VM, Jenkins itself generates the unlock password and its keys. jenkins-verify-firstboot.service then proves the unlock password signs in as admin, a wrong one gets 401 and anonymous access gets 403, and that the version and every pinned plugin are the ones this image ships.

FileOwner / modeContents
/var/lib/jenkins/secrets/initialAdminPasswordjenkins, not world-readableThe setup wizard's unlock password. Jenkins deletes it when the wizard completes
/var/lib/jenkins/secrets/master.keyjenkins, not world-readableEncrypts every credential Jenkins stores — unique to this VM; back it up with JENKINS_HOME, never share it
/var/lib/jenkins/secret.key, /var/lib/jenkins/identity.key.encjenkinsThis instance's secret and identity, also generated on first start

Unlock and log in

  1. Connect with gcloud compute ssh INSTANCE_NAME --zone ZONE --tunnel-through-iap. The deployment package enables OS Login, so IAM decides who can SSH in; reading the credential files needs sudo, which OS Login grants to principals with the OS Admin Login role (roles/compute.osAdminLogin). IAP TCP forwarding needs a firewall rule that allows 35.235.240.0/20 to tcp:22 on the VM's network — the deployment package does not create one.
  2. Open an SSH session that forwards the UI, and read the unlock password in it:
    gcloud compute ssh INSTANCE_NAME --zone ZONE --tunnel-through-iap -- -L 8080:127.0.0.1:8080
    sudo cat /var/lib/jenkins/secrets/initialAdminPassword
  3. On your workstation, open http://localhost:8080/, paste the password into Unlock Jenkins, choose plugins (next section), create your first administrator, and set the Jenkins URL.

Plugins: the 70 pinned, and what is held back

The image ships 70 plugins in /var/lib/jenkins/plugins, pinned by name, version and sha256 in /opt/jenkins/plugins.lock: the setup wizard's own suggested set for 2.580.1 with its dependencies, minus the plugins held back below. The first-boot check confirmed every one is loaded and active at its pinned version.

Held back because, on 2026-10-07, libraries they bundle had fixable HIGH-severity findings and no fixed plugin release existed:

  • jackson2-api 2.22.2-445 — bundles jackson-core and jackson-databind 2.22.2, fixed upstream in 2.22.3. Everything that needs it is held back with it: Declarative Pipeline (workflow-aggregator and the pipeline-model-* plugins), gradle, github-branch-source, pipeline-graph-view and email-ext.
  • ldap 825 — bundles spring-ldap-core 3.2.11, fixed in 3.3.8.

Scripted Pipeline ships (workflow-job, workflow-cps, workflow-multibranch and the steps they need). The setup wizard still offers the held-back plugins: "Install suggested plugins" downloads them from the Jenkins update center, while "Select plugins to install" lets you leave them out. Installing them is your choice — weigh the findings above, and check the Plugin Manager for newer releases first. The lock file records what the image shipped; it does not stop you updating plugins later (Manage Jenkins → Plugins → Updates).

The 70 pinned plugins: ant, antisamy-markup-formatter, apache-httpcomponents-client-4-api, asm-api, bootstrap5-api, bouncycastle-api, branch-api, build-timeout, caffeine-api, checks-api, cloudbees-folder, commons-lang3-api, commons-text-api, credentials, credentials-binding, dark-theme, display-url-api, durable-task, echarts-api, eddsa-api, font-awesome-api, git, git-client, gson-api, instance-identity, ionicons-api, jackson-annotations2-api, jackson3-api, jakarta-activation-api, jakarta-mail-api, jquery3-api, json-path-api, junit, mailer, matrix-auth, matrix-project, mina-sshd-api-common, mina-sshd-api-core, pipeline-build-step, pipeline-github-lib, pipeline-groovy-lib, pipeline-input-step, pipeline-milestone-step, pipeline-stage-step, plain-credentials, plugin-util-api, prism-api, resource-disposer, scm-api, script-security, snakeyaml-engine-api, ssh-credentials, ssh-slaves, structs, theme-manager, timestamper, token-macro, trilead-api, variant, woodstox-core-api, workflow-api, workflow-basic-steps, workflow-cps, workflow-durable-task-step, workflow-job, workflow-multibranch, workflow-scm-step, workflow-step-api, workflow-support, ws-cleanup. On the VM: cat /opt/jenkins/plugins.lock.

Network access

PortBound toDeployment package
8080 (web UI and API)127.0.0.1 — JENKINS_LISTEN_ADDRESS in /etc/jenkins/jenkins.envtcp:8080 toggle, off by default
Inbound-agent TCP portdisablednone
22 (SSH)all interfacesno rule — your VPC's own firewall rules apply

Jenkins serves plain HTTP. To give users on your network access:

  1. Preferred: put HTTPS in front — a load balancer, or a reverse proxy on the VM forwarding to 127.0.0.1:8080 — so Jenkins itself stays on loopback. Then set Manage Jenkins → System → Jenkins URL to the HTTPS address.
  2. To have Jenkins listen directly instead, set JENKINS_LISTEN_ADDRESS in /etc/jenkins/jenkins.env to the VM's internal IP (or 0.0.0.0, which keeps the tunnel working) and restart:
    # /etc/jenkins/jenkins.env
    JENKINS_LISTEN_ADDRESS=0.0.0.0
    
    sudo systemctl restart jenkins
  3. Open the port with the deployment package's firewall toggle: in its Networking section, tick "Allow TCP port 8080 traffic from the Internet" and enter your clients' CIDR ranges under "Source IP ranges for TCP port 8080 traffic". The toggle creates one VPC firewall rule, DEPLOYMENT-tcp-8080, allowing tcp:8080 from those ranges to VMs tagged DEPLOYMENT-deployment (DEPLOYMENT is your deployment name; the VM is DEPLOYMENT-vm). Use the narrowest ranges that work — 0.0.0.0/0, which the field shows only as a format example, would publish the port through the VM's external IP. Already deployed without the toggle? Create the same rule yourself:
    gcloud compute firewall-rules create DEPLOYMENT-tcp-8080 \
      --network NETWORK --direction INGRESS --allow tcp:8080 \
      --source-ranges 10.10.0.0/24 --target-tags DEPLOYMENT-deployment

Agents: the SSH Build Agents plugin (ssh-slaves) ships, and SSH agents are connected from the controller outward, so they need no inbound port on the controller.

Two more things decide who can reach an opened port on Google Cloud. If the VM sits on a default network that still has its pre-created default-allow-internal rule (all ports from 10.128.0.0/9), every VM in that network can connect as soon as the service listens on the internal IP — toggle or not. And the deployment package gives the VM an ephemeral external IP by default (its External IP field), so a rule open to 0.0.0.0/0 would put the service on the internet. Put authentication in place first, then open the narrowest range that works.

Data and logs

WhatWhere
JENKINS_HOME/var/lib/jenkins — jobs, builds, configuration, secrets and plugins
Unpacked WAR/var/cache/jenkins/war
Service settings/etc/jenkins/jenkins.env — JENKINS_LISTEN_ADDRESS, JENKINS_PORT, JAVA_OPTS, JENKINS_OPTS
Logsthe systemd journal — journalctl -u jenkins -f; also Manage Jenkins → System Log
DiskThe deployment package creates one boot disk (default 50 GB, balanced persistent disk) and no separate data disk, so the data above lives on the boot disk — size it for your data, or mount a persistent disk at the data path.

Upgrades

  • Jenkins core: /opt/jenkins/jenkins.war is owned by root and is not an apt package, so neither Jenkins' own updater (Jenkins runs as jenkins) nor unattended-upgrades (enabled, for Ubuntu's updates including OpenJDK 21) replaces it. Back up JENKINS_HOME, download the newer LTS jenkins.war with its .sha256 and .asc from get.jenkins.io, verify them, then:
    sudo install -m 0644 jenkins.war /opt/jenkins/jenkins.war
    echo NEW_VERSION | sudo tee /opt/jenkins/version.txt
    sudo systemctl restart jenkins
  • Plugins: Manage Jenkins → Plugins → Updates.
  • Or deploy the newest image version and move JENKINS_HOME across: stop jenkins on both VMs, copy /var/lib/jenkins (it carries secrets/master.key, without which stored credentials cannot be decrypted), sudo chown -R jenkins:jenkins /var/lib/jenkins, and start. Your plugins come with it, so update them afterwards.

Backup and restore

Stop jenkins and copy /var/lib/jenkins — keep secrets/ with it — or snapshot the boot disk. Restore by putting the directory back, owned by jenkins, before starting the service.

Monitoring

  • Health: curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:8080/login → 200 — wire this into an uptime check or your monitoring agent.
  • The deployment package disables the Cloud Logging and Monitoring agents in instance metadata (google-logging-enable=0, google-monitoring-enable=0), and the image pre-installs no monitoring agent. Install the Google Cloud Ops Agent if you want logs and metrics in Cloud Logging and Cloud Monitoring; nothing phones home by default.

More: install · troubleshooting · security notes · support card. Questions: support@dcassociatesgroup.com — first response within 1 business day.

Jenkins® is a registered trademark of LF Charities Inc.