--- - hosts: - 127.0.0.1 gather_facts: true become: true vars: kernel: min: "6.6" full: "6.6.31+rpt-rpi-v6" pwnagotchi: hostname: "{{ lookup('env', 'PWN_HOSTNAME') | default('pwnagotchi', true) }}" version: "{{ lookup('env', 'PWN_VERSION') | default('pwnagotchi', true) }}" services: enable: - bettercap.service - fstrim.timer - pwnagotchi.service - pwngrid-peer.service disable: - apt-daily-upgrade.service - apt-daily-upgrade.timer - apt-daily.service - apt-daily.timer - bluetooth.service - ifup@wlan0.service packages: caplets: source: "https://github.com/jayofelony/caplets.git" branch: "lite" # or master bettercap: source: "https://github.com/jayofelony/bettercap.git" branch: "lite" # or master pwngrid: source: "https://github.com/jayofelony/pwngrid.git" url: "https://github.com/jayofelony/pwngrid/releases/download/v1.10.7/pwngrid-1.10.7-armhf.zip" torch: wheel: "torch-2.1.0a0+gita8e7c98-cp311-cp311-linux_armv6l.whl" url: "https://github.com/Sniffleupagus/Torch4Pizero/releases/download/py0torch-bookworm-2024-05/torch-2.1.0a0+gita8e7c98-cp311-cp311-linux_armv6l.whl" torchvision: wheel: "torchvision-0.16.0+fbb4cc5-cp311-cp311-linux_armv6l.whl" url: "https://github.com/Sniffleupagus/Torch4Pizero/releases/download/py0torch-bookworm-2024-05/torchvision-0.16.0+fbb4cc5-cp311-cp311-linux_armv6l.whl" apt: downgrade: - libpcap-dev_1.9.1-4_armhf.deb - libpcap0.8-dbg_1.9.1-4_armhf.deb - libpcap0.8-dev_1.9.1-4_armhf.deb - libpcap0.8_1.9.1-4_armhf.deb hold: - firmware-atheros - firmware-brcm80211 - firmware-libertas - firmware-misc-nonfree - firmware-realtek - libpcap-dev - libpcap0.8 - libpcap0.8-dbg - libpcap0.8-dev remove: - nfs-common - triggerhappy install: - aircrack-ng - autoconf - bison - bluez - bluez-tools - build-essential - curl - dphys-swapfile - fbi - firmware-atheros - firmware-brcm80211 - firmware-libertas - firmware-misc-nonfree - firmware-realtek - flex - g++ - gawk - gcc-arm-none-eabi - git - libatlas-base-dev - libc6-dev - libcpuinfo-dev - libcurl-ocaml-dev - libdbus-1-dev - libdbus-glib-1-dev - libfl-dev - libgmp3-dev - libnetfilter-queue-dev - libopenblas-dev # https://stackoverflow.com/questions/14570011/explain-why-numpy-should-not-be-imported-from-source-directory - libopenjp2-7 - libpcap-dev - libraspberrypi-bin - libraspberrypi-dev - libraspberrypi-doc - libraspberrypi0 - libsleef-dev - libssl-dev - libssl-ocaml-dev - libtool - libusb-1.0-0-dev - make - ntp - pkg-config - python3-dev - python3-pip - python3-protobuf - python3-setuptools - python3-smbus - qpdf - raspberrypi-kernel-headers - rsync - tcpdump - texinfo - unzip - wget - wl - xxd - zlib1g-dev environment: ARCHFLAGS: "-arch armv6l" tasks: # First we install packages - name: install packages apt: name: "{{ packages.apt.install }}" state: latest update_cache: yes install_recommends: no - name: update pip3, setuptools, wheel shell: "python3 -m pip install --upgrade pip setuptools wheel --break-system-packages" args: executable: /bin/bash chdir: /usr/local/src - name: install 32bit torch shell: "python3 -m pip install {{ packages.torch.url }} {{ packages.torchvision.url }} --break-system-packages" args: executable: /bin/bash environment: QEMU_UNAME: "{{ kernel.full }}" ARCHFLAGS: "-arch armv6l" # Now we set up /boot/firmware - name: Create pi user copy: dest: /boot/firmware/userconf content: | pi:$5$733Efsksay$SEFUKemv8FaNAu6X4GUfxdSzSDh6PbpOcdtNe5b7Nt0 - name: enable ssh on boot file: path: /boot/firmware/ssh state: touch - name: remove current rc.local file: path: /etc/rc.local state: absent - name: change root partition replace: dest: /boot/firmware/cmdline.txt backup: no regexp: "root=PARTUUID=[a-zA-Z0-9\\-]+" replace: "root=/dev/mmcblk0p2" - name: configure /boot/firmware/cmdline.txt lineinfile: path: /boot/firmware/cmdline.txt backrefs: True state: present backup: no regexp: '(.*)$' line: '\1 modules-load=dwc2,g_ether' - name: setup /boot/firmware/config.txt blockinfile: path: /boot/firmware/config.txt insertafter: EOF block: | dtparam=i2c1=on dtparam=i2c_arm=on dtparam=spi=on gpu_mem=1 dtoverlay=dwc2 #dtoverlay=disable-wifi enable_uart=1 [pi0] dtoverlay=spi0-2cs #dtoverlay=disable-wifi - name: change hostname lineinfile: dest: /etc/hostname regexp: '^raspberrypi' line: "{{pwnagotchi.hostname}}" state: present when: lookup('file', '/etc/hostname') == "raspberrypi" register: hostname - name: add hostname to /etc/hosts lineinfile: dest: /etc/hosts regexp: '^127\.0\.1\.1[ \t]+raspberrypi' line: "127.0.1.1\t{{pwnagotchi.hostname}}" state: present when: hostname.changed # Now we disable sap and a2dp, we don't use them on rpi - name: disable sap plugin for bluetooth.service lineinfile: dest: /lib/systemd/system/bluetooth.service regexp: '^ExecStart=/usr/libexec/bluetooth/bluetoothd$' line: 'ExecStart=/usr/libexec/bluetooth/bluetoothd --noplugin=sap,a2dp' state: present ########################################### # # libpcap v1.9 - build from source # ########################################### # check for presence, then it can re-run in later parts if needed # use the "make" built in # install libpcap before bettercap and pwngrid, so they use it - name: clone libpcap v1.9 from github git: repo: 'https://github.com/the-tcpdump-group/libpcap.git' dest: /usr/local/src/libpcap version: libpcap-1.9 - name: build and install libpcap into /usr/local/lib shell: "./configure && make && make install" args: executable: /bin/bash chdir: /usr/local/src/libpcap - name: remove libpcap build folder file: state: absent path: /usr/local/src/libpcap - name: create symlink /usr/local/lib/libpcap.so.1.9.1 file: src: /usr/local/lib/libpcap.so.1.9.1 dest: /usr/local/lib/libpcap.so.0.8 state: link # install latest hcxtools - name: clone hcxtools git: repo: https://github.com/ZerBea/hcxtools.git dest: /usr/local/src/hcxtools - name: install hcxtools shell: "make && make install" args: executable: /bin/bash chdir: /usr/local/src/hcxtools - name: remove hcxtools directory file: state: absent path: /usr/local/src/hcxtools # Installing nexmon - name: clone nexmon repository git: repo: https://github.com/DrSchottky/nexmon.git dest: /usr/local/src/nexmon - name: make firmware shell: "source ./setup_env.sh && make" args: executable: /bin/bash chdir: /usr/local/src/nexmon/ environment: QEMU_UNAME: "{{ kernel.full }}" ARCHFLAGS: "-arch armv6l" - name: make firmware patch (bcm43430a1) shell: "source ./setup_env.sh && cd /usr/local/src/nexmon/patches/bcm43430a1/7_45_41_46/nexmon/ && make" args: executable: /bin/bash chdir: /usr/local/src/nexmon/ environment: QEMU_UNAME: "{{ kernel.full }}" ARCHFLAGS: "-arch armv6l" - name: install new firmware (bcm43430a1) copy: src: /usr/local/src/nexmon/patches/bcm43430a1/7_45_41_46/nexmon/brcmfmac43430-sdio.bin dest: /usr/lib/firmware/brcm/brcmfmac43430-sdio.bin follow: true - name: copy modified driver copy: src: "/usr/local/src/nexmon/patches/driver/brcmfmac_{{ kernel.min }}.y-nexmon/brcmfmac.ko" dest: "/usr/lib/modules/{{ kernel.full }}/kernel/drivers/net/wireless/broadcom/brcm80211/brcmfmac/brcmfmac.ko" environment: QEMU_UNAME: "{{ kernel.full }}" ARCHFLAGS: "-arch armv6l" - name: copy 43430-sdio as 43436s-sdio for the special 43430/1 /2 copy: src: /usr/lib/firmware/brcm/brcmfmac43430-sdio.bin dest: /usr/lib/firmware/brcm/brcmfmac43436s-sdio.bin follow: true # delete blob files that make nexmon sad - name: Delete the firmware blob files to avoid some nexmon crashing file: state: absent path: '{{ item }}' loop: - /usr/lib/firmware/brcm/brcmfmac43430-sdio.clm_blob - /usr/lib/firmware/brcm/brcmfmac43430-sdio.raspberrypi,model-zero-w.clm_blob - name: backup original driver command: "mv /usr/lib/modules/{{ kernel.full }}/kernel/drivers/net/wireless/broadcom/brcm80211/brcmfmac/brcmfmac.ko.xz /usr/lib/modules/{{ kernel.full }}/kernel/drivers/net/wireless/broadcom/brcm80211/brcmfmac/brcmfmac.ko.xz.orig" - name: load brcmfmac drivers command: "/sbin/depmod {{ kernel.full }}" environment: QEMU_UNAME: "{{ kernel.full }}" # To shrink the final image, remove the nexmon directory (takes 2.5G of space) post build and installation - name: Delete nexmon content & directory file: state: absent path: /usr/local/src/nexmon/ - name: Create custom config directory file: path: /etc/pwnagotchi/conf.d/ state: directory #- name: clone pwnagotchi repository # git: # repo: https://github.com/jayofelony/pwnagotchi.git # dest: /usr/local/src/pwnagotchi - name: build pwnagotchi wheel command: "pip3 install . --no-cache-dir --break-system-packages" args: chdir: /usr/local/src/pwnagotchi - name: create /usr/local/share/pwnagotchi/ folder file: path: /usr/local/share/pwnagotchi/ state: directory - name: Create custom plugin directory file: path: /usr/local/share/pwnagotchi/custom-plugins/ state: directory - name: remove pwnagotchi folder file: state: absent path: /usr/local/src/pwnagotchi ########################################## # # pwngrid, bettercap # ########################################## - name: Install go-1.21 unarchive: src: https://go.dev/dl/go1.22.3.linux-armv6l.tar.gz dest: /usr/local remote_src: yes register: golang - name: Update .bashrc for go-1.21 blockinfile: dest: /etc/profile state: present block: | export GOPATH=$HOME/go export PATH=/usr/local/go/bin:$PATH:$GOPATH/bin when: golang.changed - name: download pwngrid git: repo: "{{ packages.pwngrid.source }}" dest: /usr/local/src/pwngrid - name: install pwngrid shell: "export GOPATH=$HOME/go && export PATH=/usr/local/go/bin:$PATH:$GOPATH/bin && go mod tidy && make && make install" args: executable: /bin/bash chdir: /usr/local/src/pwngrid - name: remove pwngrid folder file: state: absent path: /usr/local/src/pwngrid - name: download bettercap git: repo: "{{ packages.bettercap.source }}" version: "{{ packages.bettercap.branch }} " dest: /usr/local/src/bettercap - name: install bettercap 2.32.4 shell: "export GOPATH=$HOME/go && export PATH=/usr/local/go/bin:$PATH:$GOPATH/bin && go mod tidy && make && make install" args: executable: /bin/bash chdir: /usr/local/src/bettercap - name: remove bettercap folder file: state: absent path: /usr/local/src/bettercap - name: clone bettercap caplets git: repo: "{{ packages.caplets.source }}" version: "{{ packages.caplets.branch }}" dest: /tmp/caplets register: capletsgit - name: install bettercap caplets make: chdir: /tmp/caplets target: install when: capletsgit.changed - name: create /etc/pwnagotchi folder file: path: /etc/pwnagotchi state: directory - name: check if user configuration exists stat: path: /etc/pwnagotchi/config.toml register: user_config - name: create /etc/pwnagotchi/config.toml copy: dest: /etc/pwnagotchi/config.toml content: | # Add your configuration overrides on this file any configuration changes done to default.toml will be lost! # Example: # ui.display.enabled = true # ui.display.type = "waveshare_4" when: not user_config.stat.exists - name: Delete motd file: state: absent path: /etc/motd - name: Delete motd 10-uname file: state: absent path: /etc/update-motd.d/10-uname - name: add firmware packages to hold dpkg_selections: name: "{{ item }}" selection: hold with_items: "{{ packages.apt.hold }}" - name: disable unnecessary services systemd: name: "{{ item }}" state: stopped enabled: no with_items: "{{ services.disable }}" - name: enable services systemd: name: "{{ item }}" enabled: true state: stopped with_items: "{{ services.enable }}" register: enabled - name: make /root readable, becauase that's where all the files are file: path: /root mode: '755' - name: fix permissions on /home/pi file: path: /home/pi owner: pi group: pi recurse: true - name: remove pre-collected packages zip file: path: /root/go_pkgs.tgz state: absent - name: remove /root/go folder file: state: absent path: /root/go - name: remove /usr/local/go folder file: state: absent path: /usr/local/go - name: remove pip cache file: state: absent path: /root/.cache/pip - name: remove ssh keys file: state: absent path: "{{ item }}" with_fileglob: - "/etc/ssh/ssh_host*_key*" - name: regenerate ssh keys shell: "dpkg-reconfigure openssh-server" args: executable: /bin/bash # Now we remove packages - name: remove unnecessary apt packages apt: name: "{{ packages.apt.remove }}" state: absent purge: yes register: removed - name: remove dependencies that are no longer required apt: autoremove: yes when: removed.changed - name: install rpi-sys-mods again? apt: state: present name: raspberrypi-sys-mods update_cache: yes install_recommends: no - name: clean apt cache apt: autoclean: true when: removed.changed handlers: - name: reload systemd services systemd: daemon_reload: yes when: enabled.changed