sickcodes / Docker-OSX

Run macOS VM in a Docker! Run near native OSX-KVM in Docker! X11 Forwarding! CI/CD for OS X Security Research! Docker mac Containers.
https://hub.docker.com/r/sickcodes/docker-osx
GNU General Public License v3.0
36.13k stars 1.78k forks source link

How can I modify MacOS image #698

Open ddkurguzikova opened 9 months ago

ddkurguzikova commented 9 months ago

I want to modify image of macos (add some libs for automatic running)

  1. I do all my steps (as installing homebrew)
  2. copy mac_hdd_ng.img from container to host
  3. create new docker image containing modifying image instead of old one

In running stage I stuck in ssh: Connection refused loop

What should I do?

Output for command you asked _Linux buildserver-ubuntu-v2 5.4.0-70-generic #78~18.04.1-Ubuntu SMP Sat Mar 20 14:10:07 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux :0 1 NAME="Ubuntu" PRETTY_NAME="Ubuntu 18.04.6 LTS" VERSION_CODENAME=bionic UBUNTUCODENAME=bionic Filesystem Size Used Avail Use% Mounted on /dev/sda1 458G 302G 133G 70% / QEMU emulator version 2.11.1(Debian 1:2.11+dfsg-1ubuntu7.42) Copyright (c) 2003-2017 Fabrice Bellard and the QEMU Project developers libvirtd (libvirt) 4.0.0 total used free shared buff/cache available Mem: 15G 2,1G 559M 36M 12G 13G Swap: 31G 6,2G 25G 12 12 crw-rw---- 1 root kvm 10, 232 сен 21 17:20 /dev/kvm total 1,9M drwxrwxrwt 2 root root 4,0K авг 4 19:14 . drwxrwxrwt 48204 root root 1,9M сен 21 17:07 .. srwxrwxrwx 1 root root 0 авг 4 19:14 X0 buildse+ 2268 0.0 0.0 15648 968 pts/6 S+ 17:32 0:00 grep --color=auto dockerd root 2365 0.6 0.4 2265116 65512 ? Ssl авг04 449:47 dockerd --group docker --exec-root=/run/snap.docker --data-root=/var/snap/docker/common/var-lib-docker --pidfile=/run/snap.docker/docker.pid --config-file=/var/snap/docker/2893/config/daemon.json kvm:x:127: libvirt:x:129:buildserver,docker libvirt-qemu:x:64055:libvirt-qemu libvirt-dnsmasq:x:130: docker:x:1001:buildserver

ddkurguzikova commented 9 months ago

Could you give me info step by step how can I save all the changes I made inside of docker image?

ddkurguzikova commented 9 months ago

My Dockerfile

FROM sickcodes/docker-osx:latest

USER root
WORKDIR /root

# For taking screenshots of the Xfvb screen, useful during development.
ARG SCROT

# OPTIONAL: Arch Linux server mirrors for super fast builds
# set RANKMIRRORS to any value other that nothing, e.g. -e RANKMIRRORS=true
RUN perl -i -p -e s/^\#Color/Color$'\n'ParallelDownloads\ =\ 30/g /etc/pacman.conf 
ARG RANKMIRRORS
ARG MIRROR_COUNTRY=US
ARG MIRROR_COUNT=10

RUN tee /etc/pacman.d/mirrorlist <<< 'Server = https://geo.mirror.pkgbuild.com/$repo/os/$arch' \
    && tee -a /etc/pacman.d/mirrorlist <<< 'Server = http://mirror.rackspace.com/archlinux/$repo/os/$arch' \
    && tee -a /etc/pacman.d/mirrorlist <<< 'Server = https://mirror.rackspace.com/archlinux/$repo/os/$arch'

# Fixes issue with invalid GPG keys: update the archlinux-keyring package to get the latest keys, then remove and regenerate gnupg keys
RUN pacman -Sy archlinux-keyring --noconfirm \
    && rm -rf /etc/pacman.d/gnupg \
    && pacman-key --init \
    && pacman-key --populate archlinux

RUN if [[ "${RANKMIRRORS}" ]]; then \
        { pacman -Sy wget --noconfirm || pacman -Syu wget --noconfirm ; } \
        ; wget -O ./rankmirrors "https://raw.githubusercontent.com/sickcodes/Docker-OSX/${BRANCH:=master}/rankmirrors" \
        ; wget -O- "https://www.archlinux.org/mirrorlist/?country=${MIRROR_COUNTRY:-US}&protocol=https&use_mirror_status=on" \
        | sed -e 's/^#Server/Server/' -e '/^#/d' \
        | head -n "$((${MIRROR_COUNT:-10}+1))" \
        | bash ./rankmirrors --verbose --max-time 5 - > /etc/pacman.d/mirrorlist \
        && cat /etc/pacman.d/mirrorlist \
    ; fi

RUN tee -a /etc/pacman.d/gnupg/gpg.conf <<< 'keyserver hkp://keyserver.ubuntu.com' \
    && tee -a /etc/pacman.d/gnupg/gpg.conf <<< 'keyserver hkps://hkps.pool.sks-keyservers.net:443' \
    && tee -a /etc/pacman.d/gnupg/gpg.conf <<< 'keyserver hkp://pgp.mit.edu:11371' \
    && tee -a /etc/pacman.d/gnupg/gpg.conf <<< 'keyserver hkps://keys.openpgp.org' \
    && tee -a /etc/pacman.d/gnupg/gpg.conf <<< 'keyserver hkps://keys.mailvelope.com'

RUN pacman -Syu xorg-server-xvfb wget xterm xorg-xhost xorg-xrandr --noconfirm \
    && if [[ "${SCROT}" ]]; then \
        pacman -Syu scrot base-devel --noconfirm \
        && git clone --recurse-submodules --depth 1 https://github.com/stolk/imcat.git \
        && cd imcat \
        && make \
        && sudo cp imcat /usr/bin/imcat \
        && touch /usr/bin/scrotcat \
        && tee -a /usr/bin/scrotcat <<< '/usr/bin/imcat <(scrot -o /dev/stdout)' \
        && chmod +x /usr/bin/scrotcat \
    ; else \
        touch /usr/bin/scrotcat \
        && echo echo >> /usr/bin/scrotcat \
        && chmod +x /usr/bin/scrotcat \
    ; fi \
    ; yes | pacman -Scc

RUN pacman -S sshpass --noconfirm \
    && yes | pacman -Scc 
RUN pacman -Sy sshfs  --noconfirm

USER arch
ENV USER arch
WORKDIR /home/arch/OSX-KVM

RUN mkdir -p ~/.ssh \
    && touch ~/.ssh/authorized_keys \
    && touch ~/.ssh/config \
    && chmod 700 ~/.ssh \
    && chmod 600 ~/.ssh/config \
    && chmod 600 ~/.ssh/authorized_keys \
    && tee -a ~/.ssh/config <<< 'Host *' \
    && tee -a ~/.ssh/config <<< '    StrictHostKeyChecking no' \
    && tee -a ~/.ssh/config <<< '    UserKnownHostsFile=/dev/null'

ARG COMPLETE=true

# use the COMPLETE arg, for a complete image, ready to boot.
# otherwise use your own image: -v "$PWD/disk.img":/image
ARG WGET_OPTIONS=
# ARG WGET_OPTIONS='--no-verbose'
ARG IMAGE_URL='https://images.sick.codes/mac_hdd_ng_auto.img'

RUN if [[ "${COMPLETE}" ]]; then \
        echo "Downloading 20GB image... This step might take a while... Press Ctrl+C if you want to abort." \
        ; rm -f /home/arch/OSX-KVM/mac_hdd_ng.img \
        && wget ${WGET_OPTIONS} -O /home/arch/OSX-KVM/mac_hdd_ng.img "${IMAGE_URL}" \
    ; fi

# symlink the old directory, for redundancy
RUN ln -s /home/arch/OSX-KVM/OpenCore /home/arch/OSX-KVM/OpenCore-Catalina || true

#### SPECIAL RUNTIME ARGUMENTS BELOW

ENV ADDITIONAL_PORTS=
# add additional QEMU boot arguments
ENV BOOT_ARGS=
ENV BOOTDISK=
# edit the CPU that is beign emulated
ENV CPU=Penryn
ENV DISPLAY=:99
ENV HEADLESS=false
ENV ENV=/env

# Boolean for generating a bootdisk with new random serials.
ENV GENERATE_UNIQUE=false

# Boolean for generating a bootdisk with specific serials.
ENV GENERATE_SPECIFIC=false

ENV IMAGE_PATH=/home/arch/OSX-KVM/mac_hdd_ng.img
ENV IMAGE_FORMAT=qcow2
ENV KVM='accel=kvm:tcg'
ENV NETWORKING=vmxnet3
ENV NOPICKER=true

# set the username and password for automatically logging in
ENV USERNAME=user
ENV PASSWORD=alpine

# dynamic RAM options for runtime
ENV RAM=3

# The x and y coordinates for resolution.
# Must be used with either -e GENERATE_UNIQUE=true or -e GENERATE_SPECIFIC=true.
ENV WIDTH=1920
ENV HEIGHT=1080

# libguestfs verbose
ENV LIBGUESTFS_DEBUG=1
ENV LIBGUESTFS_TRACE=1

ENV OSX_COMMANDS=' \
    sudo ls \
    && NONINTERACTIVE=1 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" \ 
    && ls /usr/local/bin/brew \
    && (echo; echo "eval $(/usr/local/bin/brew shellenv)") >> /Users/user/.zprofile \
    && eval "$(/usr/local/bin/brew shellenv)" \
    && curl -JOL  ./MacPorts-2.8.1-10.15-Catalina.pkg https://github.com/macports/macports-base/releases/download/v2.8.1/MacPorts-2.8.1-10.15-Catalina.pkg --output MacPorts-2.8.1-10.15-Catalina.pkg  \
    && echo "alpine" | sudo -S installer -pkg /Users/user/MacPorts-2.8.1-10.15-Catalina.pkg -target / \
    && export PATH=$PATH:/opt/local/bin \
    && echo "alpine" | sudo -S port install clang-10 \
    && export PATH=/opt/local/libexec/llvm-10/bin:$PATH \
'

ENV RIGHT_PATH=/home/arch/OSX-KVM

ENTRYPOINT echo "Disk is being copied between layers... Please wait a minute..."  \
    ; sudo touch /dev/kvm /dev/snd "${IMAGE_PATH}" "${BOOTDISK}" "${ENV}" 2>/dev/null || true \
    ; sudo chown -R $(id -u):$(id -g) /dev/kvm /dev/snd "${IMAGE_PATH}" "${BOOTDISK}" "${ENV}" 2>/dev/null || true \
    ; [[ "${NOPICKER}" == true ]] && { \
        sed -i '/^.*InstallMedia.*/d' "${RIGHT_PATH}"/Launch.sh  \
        && export BOOTDISK="${BOOTDISK:=/home/arch/OSX-KVM/OpenCore/OpenCore-nopicker.qcow2}" \
    ; } \
    || export BOOTDISK="${BOOTDISK:=/home/arch/OSX-KVM/OpenCore/OpenCore.qcow2}" \
    ; [[ "${GENERATE_UNIQUE}" == true ]] && { \
        "${RIGHT_PATH}"/Docker-OSX/osx-serial-generator/generate-unique-machine-values.sh \
            --master-plist-url="${MASTER_PLIST_URL}" \
            --count 1 \
            --tsv ./serial.tsv \
            --bootdisks \
            --width "${WIDTH:-1920}" \
            --height "${HEIGHT:-1080}" \
            --output-bootdisk "${BOOTDISK:=/home/arch/OSX-KVM/OpenCore/OpenCore.qcow2}" \
            --output-env "${ENV:=/env}"  \
    || exit 1 ; } \
    ; [[ "${GENERATE_SPECIFIC}" == true ]] && { \
            source "${ENV:=/env}" 2>/dev/null \
            ; "${RIGHT_PATH}"/Docker-OSX/osx-serial-generator/generate-specific-bootdisk.sh \
            --master-plist-url="${MASTER_PLIST_URL}" \
            --model "${DEVICE_MODEL}" \
            --serial "${SERIAL}" \
            --board-serial "${BOARD_SERIAL}" \
            --uuid "${UUID}" \
            --mac-address "${MAC_ADDRESS}" \
            --width "${WIDTH:-1920}" \
            --height "${HEIGHT:-1080}" \
            --output-bootdisk "${BOOTDISK:=/home/arch/OSX-KVM/OpenCore/OpenCore.qcow2}"  \
      || exit 1 ; } \
    ; { [[ "${DISPLAY}" = ':99' ]] || [[ "${HEADLESS}" == true ]] ; } && { \
        nohup Xvfb :99 -screen 0 1920x1080x16 \
        & until [[ "$(xrandr --query 2>/dev/null)" ]]; do sleep 1 ; done \
    ; } \
    ; stat "${IMAGE_PATH}" \
    ; echo "Large image is being copied between layers, please wait a minute..." \
    ; "${RIGHT_PATH}"/enable-ssh.sh \
    ; [[ -e ~/.ssh/id_docker_osx ]] || { \
        /usr/bin/ssh-keygen -t rsa -f ~/.ssh/id_docker_osx -q -N ""  \
        && chmod 600 ~/.ssh/id_docker_osx \
    ; } \
    ; /bin/bash -c "${RIGHT_PATH}"/Launch.sh  \
    & echo "Booting Docker-OSX in the background. Please wait..."  \
    ; until [[ "$(sshpass -p alpine ssh-copy-id -f -i ~/.ssh/id_docker_osx.pub -p 10022 user@127.0.0.1)" ]]; do \
        echo "Disk is being copied between layers. Repeating until able to copy SSH key into OSX..." \
        ; sleep 1 \
    ; done \
    ; grep id_docker_osx ~/.ssh/config || { \
        tee -a ~/.ssh/config <<< 'Host 127.0.0.1' \
        ; tee -a ~/.ssh/config <<< "    User ${USERNAME}" \
        ; tee -a ~/.ssh/config <<< '    Port 10022' \
        ; tee -a ~/.ssh/config <<< '    IdentityFile ~/.ssh/id_docker_osx' \
        ; tee -a ~/.ssh/config <<< '    StrictHostKeyChecking no' \
        ; tee -a ~/.ssh/config <<< '    UserKnownHostsFile=/dev/null' \
    ; } \
    && echo "Default username: ${USERNAME}" \
    && echo "Default password: ${PASSWORD}" \
    && echo "Change it immediately using the command: passwd" \
    && echo "${PASSWORD}" | ssh -tt -tt -i ~/.ssh/id_docker_osx ${USERNAME}@127.0.0.1 -p 10022 "${OSX_COMMANDS}"\
    && tail -f /dev/null
ddkurguzikova commented 9 months ago

And than I copy with docker cp mac_hdd_ng_auto to host And than I modify Dockerfile and copy with COPY command image