diff --git a/.dockerignore b/.dockerignore index 70bf279396a..5c38865bb5b 100644 --- a/.dockerignore +++ b/.dockerignore @@ -5,6 +5,8 @@ docker-compose*.yml docker/ !docker/msfconsole.rc !docker/entrypoint.sh +!docker/database.yml +Dockerfile README.md .git/ .github/ diff --git a/Dockerfile b/Dockerfile index 667a197a32d..eaa04a5d6ed 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,11 +2,11 @@ FROM ruby:2.5.1-alpine3.7 AS builder LABEL maintainer="Rapid7" ARG BUNDLER_ARGS="--jobs=8 --without development test coverage" -ENV APP_HOME /usr/src/metasploit-framework/ +ENV APP_HOME=/usr/src/metasploit-framework ENV BUNDLE_IGNORE_MESSAGES="true" WORKDIR $APP_HOME -COPY Gemfile* metasploit-framework.gemspec Rakefile $APP_HOME +COPY Gemfile* metasploit-framework.gemspec Rakefile $APP_HOME/ COPY lib/metasploit/framework/version.rb $APP_HOME/lib/metasploit/framework/version.rb COPY lib/metasploit/framework/rails_version_constraint.rb $APP_HOME/lib/metasploit/framework/rails_version_constraint.rb COPY lib/msf/util/helper.rb $APP_HOME/lib/msf/util/helper.rb @@ -40,23 +40,28 @@ RUN apk add --no-cache \ FROM ruby:2.5.1-alpine3.7 LABEL maintainer="Rapid7" -ENV APP_HOME /usr/src/metasploit-framework/ +ENV APP_HOME=/usr/src/metasploit-framework ENV NMAP_PRIVILEGED="" +ENV METASPLOIT_GROUP=metasploit -COPY --from=builder /usr/local/bundle /usr/local/bundle -COPY . $APP_HOME +# used for the copy command +RUN addgroup -S $METASPLOIT_GROUP RUN apk add --no-cache bash sqlite-libs nmap nmap-scripts nmap-nselibs postgresql-libs python python3 ncurses libcap su-exec 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) +COPY --chown=root:metasploit --from=builder /usr/local/bundle /usr/local/bundle +COPY --chown=root:metasploit . $APP_HOME/ +RUN cp -f $APP_HOME/docker/database.yml $APP_HOME/config/database.yml + WORKDIR $APP_HOME + # we need this entrypoint to dynamically create a user # matching the hosts UID and GID so we can mount something # from the users home directory. If the IDs don't match -# it results in access denied errors. Once docker has -# a solution for this we can revert it back to normal +# it results in access denied errors. ENTRYPOINT ["docker/entrypoint.sh"] -CMD ["./msfconsole", "-r", "docker/msfconsole.rc"] +CMD ["./msfconsole", "-r", "docker/msfconsole.rc", "-y", "$APP_HOME/config/database.yml"] diff --git a/docker-compose.override.yml b/docker-compose.override.yml index 134c1e8503f..9f41384d249 100644 --- a/docker-compose.override.yml +++ b/docker-compose.override.yml @@ -9,6 +9,6 @@ services: BUNDLER_ARGS: --jobs=8 image: metasploit:dev environment: - DATABASE_URL: postgres://postgres@db:5432/msf_dev + DATABASE_URL: postgres://postgres@db:5432/msf_dev?pool=200&timeout=5 volumes: - .:/usr/src/metasploit-framework diff --git a/docker-compose.yml b/docker-compose.yml index 725f3985001..cd729666cdb 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,14 +3,13 @@ services: ms: image: metasploitframework/metasploit-framework:latest environment: - DATABASE_URL: postgres://postgres@db:5432/msf + DATABASE_URL: postgres://postgres@db:5432/msf?pool=200&timeout=5 links: - db ports: - 4444:4444 volumes: - $HOME/.msf4:/home/msf/.msf4 - - /etc/localtime:/etc/localtime:ro db: image: postgres:10-alpine diff --git a/docker/database.yml b/docker/database.yml new file mode 100644 index 00000000000..e55084ba9c3 --- /dev/null +++ b/docker/database.yml @@ -0,0 +1,5 @@ +development: &pgsql + url: <%= ENV['DATABASE_URL'] %> + +production: &production + <<: *pgsql diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh index 2acd432c2c4..ad41a350df3 100755 --- a/docker/entrypoint.sh +++ b/docker/entrypoint.sh @@ -5,16 +5,29 @@ MSF_GROUP=msf TMP=${MSF_UID:=1000} TMP=${MSF_GID:=1000} -# don't recreate system users like root -if [ "$MSF_UID" -lt "1000" ]; then - MSF_UID=1000 +# if the user starts the container as root or another system user, +# don't use a low privileged user as we mount the home directory +if [ "$MSF_UID" -eq "0" ]; then + "$@" +else + # if the users group already exists, create a random GID, otherwise + # reuse it + if ! grep ":$MSF_GID:" /etc/group > /dev/null; then + echo "asdf" + addgroup -g $MSF_GID $MSF_GROUP + else + addgroup $MSF_GROUP + fi + + # check if user id already exists + if ! grep ":$MSF_UID:" /etc/passwd > /dev/null; then + echo "cvbb" + adduser -u $MSF_UID -D $MSF_USER -g $MSF_USER -G $MSF_GROUP $MSF_USER + # add user to metasploit group so it can read the source + addgroup $MSF_USER $METASPLOIT_GROUP + su-exec $MSF_USER "$@" + # fall back to root exec if the user id already exists + else + "$@" + fi fi - -if [ "$MSF_GID" -lt "1000" ]; then - MSF_GID=1000 -fi - -addgroup -g $MSF_GID $MSF_GROUP -adduser -u $MSF_UID -D $MSF_USER -g $MSF_USER -G $MSF_GROUP $MSF_USER - -su-exec $MSF_USER "$@"