Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dockerfile for arm64 and amd64 using multi-stage build #18601

Merged
merged 3 commits into from
Dec 12, 2023

Conversation

MikeAnast
Copy link
Contributor

This pull request (PR) adds a new multi-stage Dockerfile that can be used to build the metasploit for both ARM and AMD architectures.

According to issue #18588, Metasploit does not run on ARM architectures. Therefore, i added a multi-stage Dockerfile to build an image for both ARM and AMD architectures.

To build the image, you need to specify an additional argument named architecture, where you define either amd64 or arm64.

For example,

docker build --build-arg architecture=amd64 -t metasploit_amd .
docker build --build-arg architecture=arm64 -t metasploit_arm .

Verification

The build images are functional for both ARM and AMD architectures. I have tested them on some use-cases, but additional testi is, of course, required.

Many thanks to @adfoster-r7 !

@adfoster-r7 adfoster-r7 added the arm arm label Dec 6, 2023
@adfoster-r7
Copy link
Contributor

adfoster-r7 commented Dec 6, 2023

Thanks! Building on your changes - do you think something like this would work? Making changes from the master Dockerfile to be:

diff --git a/Dockerfile b/Dockerfile
index c7885edab2..ccd5d711ee 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,6 +1,8 @@
 FROM ruby:3.1.4-alpine3.18 AS builder
 LABEL maintainer="Rapid7"
 
+ARG TARGETPLATFORM
+ARG TARGETARCH
 ARG BUNDLER_CONFIG_ARGS="set clean 'true' set no-cache 'true' set system 'true' set without 'development test coverage'"
 ENV APP_HOME=/usr/src/metasploit-framework
 ENV TOOLS_HOME=/usr/src/tools
@@ -52,6 +54,9 @@ RUN mkdir -p $TOOLS_HOME/bin && \
 FROM ruby:3.1.4-alpine3.18
 LABEL maintainer="Rapid7"
 
+ARG TARGETPLATFORM
+ARG TARGETARCH
+
 ENV APP_HOME=/usr/src/metasploit-framework
 ENV TOOLS_HOME=/usr/src/tools
 ENV NMAP_PRIVILEGED=""
@@ -62,7 +67,14 @@ RUN addgroup -S $METASPLOIT_GROUP
 
 RUN apk add --no-cache bash sqlite-libs nmap nmap-scripts nmap-nselibs \
     postgresql-libs python3 py3-pip ncurses libcap su-exec alpine-sdk \
-    openssl-dev nasm mingw-w64-gcc
+    openssl-dev nasm
+
+RUN echo "building for TARGETARCH=$TARGETARCH"; \
+    if [ "$TARGETARCH" = "arm64" ]; then \
+        apk add --no-cache gcc musl-dev python3-dev libffi-dev gcompat; \
+    else \
+        apk add --no-cache mingw-w64-gcc; \
+    fi
 
 RUN /usr/sbin/setcap cap_net_raw,cap_net_bind_service=+eip $(which ruby)
 RUN /usr/sbin/setcap cap_net_raw,cap_net_bind_service=+eip $(which nmap)

Building with:

docker buildx build --platform=linux/arm64 --output type=docker --tag build_test:latest .

And running with:

docker run -it build_test:latest /bin/bash

It looks like you needed to add nokogiri manually too, but I think that can be skipped - did you hit any specific issues with nokogiri? 👀

@MikeAnast
Copy link
Contributor Author

MikeAnast commented Dec 7, 2023

Yes something like that will work and is more efficient i think !
Regarding nokogiri, i had an issue yes i needed to add the gcompat package and then the nokogiri library as this issue suggests nokogiri v1.13.0 fails to load on ARM alpine linux .
image

Cheers !

Dockerfile Outdated
RUN gem install nokogiri
# -- #
RUN cp -f $APP_HOME/docker/database.yml $APP_HOME/config/database.yml
RUN curl -L -O https://raw.githubusercontent.com/pypa/get-pip/f84b65709d4b20221b7dbee900dbf9985a81b5d4/public/get-pip.py && python3 get-pip.py && rm get-pip.py
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this necessary? It appears you're installing py3-pip above on line 66.

Copy link
Contributor Author

@MikeAnast MikeAnast Dec 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not very sure what you are referring to, because the package py3-pip already exists on the official Dockerfile. But i added the package python3-dev because there is an issue with the impacket python library.
image

@jheysel-r7
Copy link
Contributor

The docker build is currently failing. Do we need to update the tests to match the new format of the docker build command that now accepts an architecture argument? It would be good to add functionality that if the arg is not passed in it defaults to the old behaviour.

Service 'ms' failed to build: invalid reference format

@adfoster-r7
Copy link
Contributor

The docker build is currently failing. Do we need to update the tests to match the new format of the docker build command that now accepts an architecture argument? It would be good to add functionality that if the arg is not passed in it defaults to the old behaviour.

I believe if this PR is updated to follow the pattern in #18601 (comment) there shouldn't be any changes needed for CI

@MikeAnast
Copy link
Contributor Author

MikeAnast commented Dec 8, 2023

Are you sure that your pattern works ? Because i can not make it work for some reason. The variables TARGETPLATFORM, TARGETARCH stay empty during the build so it goes to else every time. Check if you can to modify the if for amd64 architecture in your case and i will adjust that for arm. Example if [ "$TARGETARCH" = "amd64" ]; then

I will try it also and come back to you during the day.

@MikeAnast
Copy link
Contributor Author

updated the Dockerfile now it works on arm64 architectures with the following build command:

docker buildx build --platform=linux/arm64 --output type=docker -t metasploit_arm .

it should be fine also on amd architectures as @adfoster-r7 suggested

@adfoster-r7
Copy link
Contributor

adfoster-r7 commented Dec 12, 2023

@MikeAnast Thanks! Does this image from Dockerhub work for you now too?

docker pull metasploitframework/metasploit-framework:6.3.47

amd64 and arm64 tag now available:

image

Behind the scenes I built and pushed this pull request on an arm64 mac with:

docker buildx build --platform linux/amd64,linux/arm64 -t metasploitframework/metasploit-framework:6.3.47 --push .
docker buildx build --platform linux/amd64,linux/arm64 -t metasploitframework/metasploit-framework:latest --push .

If that works out of the box, we should be able to get this PR landed 🤞

@MikeAnast
Copy link
Contributor Author

Hello, i tested it in a few cases like:

  • Scan with nmap connect with db and check services for example:
docker run -it --rm --net=host -v /tmp/:/tmp/:rw metasploitframework/metasploit-framework /bin/bash -c "./msfconsole -x 'db_connect postgresql://postgres:[email protected]:5432/postgres ; db_nmap -sV <target>;spool /tmp/results.txt; services -c port,info;exit'"
  • Run a few exploits and reverse shells

So i think we are good to go :)

@adfoster-r7
Copy link
Contributor

Awesome, thanks very much! 🎉

@adfoster-r7 adfoster-r7 merged commit 5f00410 into rapid7:master Dec 12, 2023
@adfoster-r7 adfoster-r7 added the rn-enhancement release notes enhancement label Dec 12, 2023
@adfoster-r7
Copy link
Contributor

Release Notes

Adds arm64 support to Metasploit's Dockerfile. This new image is available from Dockerhub via docker pull metasploitframework/metasploit-framework:6.3.47 or through the wrapper script ./docker/bin/msfconsole

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
arm arm rn-enhancement release notes enhancement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants