[
  {
    "path": "README.md",
    "content": "# FreeBSD Toolbox\n\nThis a collection of commands and intstructions to accomplish common tasks on FreeBSD\n\n\n* [Commands](https://github.com/hukl/freebsd-toolbox/blob/master/commands.md)\n\n\n## Performance Analysis Tools\n\n![Image of FreeBSD Tools](https://raw.githubusercontent.com/hukl/freebsd-toolbox/master/FreeBSD_Performance_Observability_Tools.png)\n\n\n## ZFS Pool Composition Tips\n\n* https://klarasystems.com/articles/choosing-the-right-zfs-pool-layout/\n"
  },
  {
    "path": "commands.md",
    "content": "# Users\n```\nadduser                                 # wrapper script to add users\nchsh                                    # change user shell and other info\npw groupadd teamtwo                     # add a group to the system\npw groupmod teamtwo -m <username>       # add a user to a group\n/etc/group                              # file to edit groups manually\nid                                      # show group membership for current user\n```\n\n\n\n# System Configuration\n\n```\ncat /var/run/dmesg.boot                 # show boot log with info about disks and pci devices\nkenv                                    # show bios, board and chassi info (dump from kernel env)\npciconf -l -cv                          # show info about PCI devices of the machine\ncamcontrol devlist -v                   # list of attached ATA devices\nifconfig                                # show and configure network interface parameters\nsysctl                                  # tool to show/set all system/kernel coniguration variables\nsysctl -a                               # show all system/kernel configuration variables\nsysctl hw                               # show hardware related info and settings\nsysctl net                              # show all network related info and settings\nsysctl hw.model                         # show CPU model\nsysctl net.inet.tcp.delayed_ack=0       # disable delayed ack in tcp\n```\n\n\n# System Statistics\n\n```\ntop                                     # display and update information about the top cpu processes\nps auxwww | grep <processname>          # display process status\nCTRL-t                                  # on running commands will output useful info\nsystat -vmstat 1                        # show general overview of load, memory, interrupts, disk io\nsystat -iostat 1                        # show disk throughput\nsystat -ifstat 1                        # show network throughput for all interfaces\nsystat -netstat 1                       # show netstat output but automatically refreshed\nsystat -tcp 1                           # show tcp statistics\n```\n\n# ZFS\n\n```\nzfs list                                # list all zfs datasets (volumes)\nzfs list -t snapshot                    # list all zfs snapshots\nzfs list -r -t snapshot <pool>          # list zfs snapshots for a given pool\nzfs snapshot <pool>/<dataset>@<name>    # generic way of creating a snapshot of a dataset in a storage pool\nzfs snapshot -r tank@2014021301         # create a snapshot of all datasets in the pool \"tank\"\nzfs create <pool>/<dataset>             # create a new dataset\nzfs rollback <pool>/<dataset>@name      # rollback of a dataset to a given snapshot\nzfs destroy <pool>/<dataset>            # destroy a dataset / remove it from the pool\nzfs destroy <pool>/<dataset>@name       # destroy a snapshot\nzfs set <key>=<val> <pool>/<dataset>    # generic way of setting options on a given dataset\nzfs set compression=lz4 tank/var/log    # enable LZ4 compression on /var/logs\nzfs get compressratio <pool>/<dataset>  # show the current compression ratio of a dataset\nzfs send -R tank@snapshot | \\           # send all datasets@snapshot recursively to another host\nssh root@[IP] zfs recv -F tank\nzfs unmount <pool>/<dataset>            # unmount a zfs dataset\nzfs upgrade -r <pool>                   # upgrade all volumes in the pool (technically its the root volume e.g. tank)\nzpool status                            # show health info about currently imported ZFS storage pools\nzpool scrub                             # check all written blocks for consistency\nzpool iostat -v tank                    # show more information about the pool including log devices\nzpool add <pool> mirror <dev1> <dev1>   # add two disks as mirror to a storage pool\nzpool remove <pool> <device>            # remove single devices or mirror sets from the storage pool\nzpool upgrade <pool>                    # upgrade the storage pool to latest version\nzpool labelclear [-f] <pool>            # Clear vdev headers on disk of previous / faulted / obsolete pools\nzfs send pool/volume@snapshot \\         # Compress and Encrypt a snapshot and send it to a remote host for backups\n  | lz4 \\                               # Decrypt with: openssl enc -d -aes-256-cbc -a -in /path/to/backup/snapshot.lz4.ssl | unlz4 > /path/to/dest \n  | openssl enc -aes-256-cbc -a -salt -pbkdf2 \\ # OR | zfs receive tank/volume\n  | ssh u@h \"cat > /snapshot.lz4.ssl\n```\n\n# Software\n\n```\n# Ports\nportsnap fetch                          # fetch the latest portfiles\nportsnap update                         # update the portfiles on disk with the previously fetched portfiles\nportsnap update -p /usr/jails/basejail/usr/ports # update ports tree for jails\nwhereis <portname>                      # show the directory of the portfile\ncd /usr/ports/*/<portname>              # find the parent directory of a given portname\nlocate <portname> | grep ports          # manual way of searching for ports\ncd <portdir> && make install            # compile and install a port\ncd <portdir> && make config             # re-run configuration of a port when available\ncd <portdir> && sudo make deinstall clean reinstall # upgrade the port\n\n# Packages\npkg search <packagename>                # search for binary packages\npkg install <packagename>               # install binary package and its dependencies\npkg delete  <packagename>               # delete an installed package\npkg autoremove                          # remove unneeded dependencies\npkg info                                # show list of currently installed ports/packages with version info\npkg version                             # show which ports/packages are outdated and need an update\npkg upgrade <packagename>               # upgrade a packages\npkg which <filename>                    # find out which package installed a given file\npkg audit -F                            # look for ports/packages with security vulnerabilities\n\n# System\nfreebsd-update fetch                    # fetch updates from server\nfreebsd-update -r <target> upgrade      # fetch upgrades to specified version (e.g. '10.1-RELEASE') from server\nfreebsd-update install                  # install downloaded updates/upgrades\n```\n\n# Services\n\n```\nservice -l                              # list all available services\nservice -e                              # list all enabled services\nservice <servicename> status            # show the status of the service with the given servicename\nservice <servicename> start             # start the service with the given servicename\nservice <servicename> stop              # stop the service with the given servicename\nservice <servicename> restart           # restart the service with the given servicename\nservice <servicename> reload            # reload the configuration of the service with the given servicename\n```\n\n# Network\n\n```\nifconfig <iface> inet <ip/mask>         # configure IP address on interface\nifconfig <iface> inet <ip/mask> alias   # configure IP address alias on interface\nifconfig <iface> del <ip>               # remove IP address from interface\nroute add -net default <gw_ip>          # add default route\nroute add -net <ip/mask> <gw_ip>        # add a custom route for given network\n/etc/rc.d/netif restart && \\            # restart networking and routing after changing the configuration\n/etc/rc.d/routing restart                 without rebooting. Execute in tmux or screen session\nnetstat -rn                             # display routing table\nnetstat -an                             # display all connections\nnetstat -m                              # display buffer usage\nnetstat -Lan                            # display status of listen queues\nnetstat -s                              # display extensive statistics per protocol (use -p tcp to only show tcp)\nsockstat -l                             # display listening sockets, process names and pids\nsockstat -4                             # display all IPv4 sockets - good with -l as above\nsysctl kern.ipc.numopensockets          # display number of open sockets\nvmstat -z | egrep \"ITEM|tcpcb\"          # number of hash table buckets to handle incoming tcp connections\n                                          increase net.inet.tcp.tcbhashsize if hitting the limit\nsysctl net.inet.tcp.hostcache.list      # display current content of hostcache with its parameters per IP\nssh <host> sudo tcpdump \\               # Send remote tcpdump output to local wireshark for live analysis\n  -i em0 -U \\\n  -w - \"not port 22\" | wireshark -i - -k\n```\n\n# Firewall\n\n```\npfctl -si                               # show current state table and counters (useful for tuning)\npfctl -s state                          # show current content of state table\n```\n\n# IPsec\n\n```\nipsec start                             # start VPN and establish (auto=start) VPN connections\nsetkey -D                               # show extensive Kernel information about current connections\nsetkey -DP                              # show more condensed connection information\nipsec statusall [conn]                  # show returns detailed status information either on connection or all \n                                          connections if no name is provided\nipsec leases                            # show current leases from virtual IP address pool\nipsec rereadsecrets                     # flushes and rereads all secrets defined in ipsec.secrets\nipsec rereadall                         # flushes and rereads all secrets defined in ipsec.secrets as well as all \n                                          certificates and and certificate revocation lists\nipsec update                            # sends a HUP signal to the daemon that determines any changes in ipsec.conf \n                                          and updates the configuration on the running IKE daemon charon\nipsec reload                            # sends a USR1 signal to the daemon that reloads the whole configuration \n                                          on the running IKE daemon charon based on the actual ipsec.conf\nipsec restart                           # terminates all ipsec connections, sends a TERM signal to the daemon and     \n                                          restarts it afterwards\nipsec stroke up [conn]                  # initiate connection [conn]\nipsec stroke down [conn]                # terminate connection [conn]\n```\n\n# ezjail\n\n```\nezjail-admin start|stop                 # start and stop all the jails\nezjail-admin start|stop <JID>|<hostname># start and stop individual jail\nezjail-admin list                       # list all the jails on the host system\nezjail-admin console <JID>|<hostname>   # open root shell into jail\nezjail-admin create -f exmaple <hostname> <IP> # create a new jail\nezjail-admin delete -w hostname         # delete the jail (in case you use zfs also delete the volume)\nezjail-admin update -U -s 11.1-RELEASE  # update basejail from -s <RELEASE> to current host system\n```\n\n# Boot Environments\n```\nbectl list                              # List existing boot environments\nbectl create <envname>                  # Create a new boot environment e.g. 13_1_RELEASE\nbectl mount <envname>                   # Mount boot environment temporary mountpoint like /tmp/be_mount.JO5Y\nbectl activate -t <envname>             # Activate new boot environment for one-time-boot\nbectl activate <envname>                # Activate new boot environment permanently\n---\nfreebsd-update \\                        # Example for upgrading FreeBSD to a release in a boot environment\n-b /tmp/be_mount.JO5Y \\\n-d /tmp/be_mount.JO5Y/var/db/freebsd-update \\\n-r 13.1-RELEASE upgrade\n"
  },
  {
    "path": "mailserver.md",
    "content": "# Upgrading Postfix & Dovecot\n\nFirst lock the ports so they don't get upgraded by pkg\n```\nsudo pkg lock postfix dovecot dovecot-pigeonhole\n```\nUpgrade all other packages through pkg\n```\nsudo pkg upgrade\n```\nUnlock postfix, dovecot and dovecot-pigeonhole\n```\nsudo pkg unlock postfix dovecot dovecot-pigeonhole\n```\nUpgrade postfix, dovecot and dovecot-pigeonhole via ports\n```\ncd /usr/ports/mail/postfix\nsudo make deinstall clean reinstall\n\ncd /usr/ports/mail/dovecot\nsudo make deinstall clean reinstall\n\ncd /usr/ports/mail/dovecot-pigeonhole\nsudo make deinstall clean reinstall\n```\nAfter that, lock ports again to prevent accidental binary upgrades\n```\nsudo pkg lock postfix dovecot dovecot-pigeonhole\n```\n\n\n\n# Dovecot\n\n### Create Password\n\n```\ndoveadm pw -s SHA512-CRYPT\n```\n\n### Migrate a User from old Server\n```\nsudo -u vmail doveadm -o imapc_user=user@domain -o imapc_password=foobar backup -R -u user@domain imapc:\n```\n"
  },
  {
    "path": "quicketc.sh",
    "content": "#!/bin/sh\n\n# This was tested from ZSH - not sure if the glob is auto expanded in other shells\n\nunset TARBALL\n\nusage() {\n  echo \"USAGE: quicketc -h | -t <path/to/tarfile> directory_or_glob_pattern\"\n  exit 1\n}\n\nwhile getopts j:t:h opt; do\n    case $opt in\n        t)      TARBALL=$OPTARG\n                ;;\n        h)      echo $USAGE\n                exit 0\n                ;;\n        '?')    echo \"$0: invalid option -$OPTARG\" >&2\n                usage\n                ;;\n    esac done\n    shift $((OPTIND - 1))\n\n# Check if TARBALL arg was provided\n[ -z \"$TARBALL\" ] && usage\n\n# Go through list of Jail from expanded glob pattern and build internal list\nNUMBER_OF_JAILS=0\nNUMBER_OF_JAIL_ARGS=$#\nJAILS=\"\"\n\nwhile [ $NUMBER_OF_JAILS -lt $NUMBER_OF_JAIL_ARGS ]\ndo\n    JAILS=\"$JAILS$1 \"\n    NUMBER_OF_JAILS=$(($NUMBER_OF_JAILS+1))\n    shift\ndone\n\n# Build Tarball if specified file does not yet exist\nif [ -f $TARBALL ]\nthen\n    echo \"Found existing Tarball at $TARBALL\"\nelse\n    echo \"Generate Source Tarball $TARBALL\"\n    etcupdate build $TARBALL\nfi\n\n# Loop through each subdirectory in JAIL_DIR\nfor jail_sub_dir in $JAILS; do\n    # Check if the directory exists\n    if [ -d \"$jail_sub_dir\" ]; then\n        # Run etcupdate commands with the current subdirectory\n        echo \"Updating: $jail_sub_dir\"\n        etcupdate -t $TARBALL -D \"$jail_sub_dir\"\n        etcupdate resolve -D \"$jail_sub_dir\"\n    fi\ndone\n"
  },
  {
    "path": "upgrade_guide.md",
    "content": "## References\n\n* https://docs.freebsd.org/en/books/handbook/cutting-edge/\n* https://klarasystems.com/articles/managing-boot-environments/\n\n## Preparations\n\nhttps://www.freebsd.org/releases/13.1R/relnotes/\n\n\n## General Procedure\n\n* Check Release Notes for potentially breaking changes (which is rare)\n* Upgrade pkg and packages to latest versions on host `sudo pkg upgrade`\n* ZFS Snapshot `zfs snapshot -r tank@2022-08-05_01`\n* Create Boot Environemnt `bectl create 13_1_RELEASE`\n* Mount Boot Environment `bectl mount 13_1_RELEASE`\n* Run FreeBSD Upgrade \n  ```sh\n  freebsd-update \\                     \n  -b /tmp/be_mount.JO5Y \\\n  -d /tmp/be_mount.JO5Y/var/db/freebsd-update \\\n  -r 13.1-RELEASE upgrade\n  ```\n* Run the following command 2x in a row without rebooting \n  ```sh\n  freebsd-update \\                     \n  -b /tmp/be_mount.JO5Y \\\n  -d /tmp/be_mount.JO5Y/var/db/freebsd-update \\\n  install\n  ````\n* Disable ezjail in rc.conf\n* Temporarily activate boot environment `bectl activate -t 13_1_RELEASE`\n* After successful reboot, permanently activate boot environment  `bectl activate 13_1_RELEASE`\n* Delete ezjail basejail and newjail `zfs destroy tank/ezjail/basejail` and `zfs destroy tank/ezjail/newjail`\n* Re-install ezjail basejail and newjail `ezjail-admin install -s`\n* Mergemaster jails, starting with the most important ones `etcupdate -D /path/to/jail` or use the `quicketc.sh` script included in this repo to speed up the process\n* Check ZFS `zpool status`\n"
  },
  {
    "path": "zfs_bootstrap.sh",
    "content": "#!/bin/sh\n\n# Check:\n# https://wiki.freebsd.org/RootOnZFS/GPTZFSBoot/9.0-RELEASE\n# http://wp.strahlert.net/wordpress/zfs-2/expanding-zpool/\n\n# Tested on FreeBSD 10, 11 and 12\n\n###############################################################\n# WARNING: Go through line by line and adjust where necessary #\n###############################################################\n\n# Create Partition Table\necho \"Create Partition Table\"\ngpart create -s gpt ada0 # Main HDD\ngpart create -s gpt ada1 # Main HDD\n\n# Optional if you have SSDs for ZIL and L2ARC\n# gpart create -s gpt ada2 # ZIL and L2ARC SSD\n# gpart create -s gpt ada3 # ZIL and L2ARC SSD\n\n\n# Create Boot Partition\necho \"Create Boot Partition\"\ngpart add -a 4k -s 512k -t freebsd-boot ada0\ngpart add -a 4k -s 512k -t freebsd-boot ada1\n\n\n# Create Swap Partitions\necho \"Create Swap Partitions\"\ngpart add -a 4k -s 8G -t freebsd-swap -l swap0 ada0\ngpart add -a 4k -s 8G -t freebsd-swap -l swap1 ada1\n\n\n# Create Main Partitions\necho \"Create Main Partitions\"\ngpart add -a 4k -t freebsd-zfs -l disk0 ada0\ngpart add -a 4k -t freebsd-zfs -l disk1 ada1\n\n\n# Write Bootcode\necho \"Write Bootcode\"\ngpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ada0\ngpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ada1\n\n\n# Create ZIL Partions\n# echo \"Create ZIL Partions\"\n# gpart add -a 4k -b 2048 -s 10G -t freebsd-zfs -l zil0 ada2\n# gpart add -a 4k -b 2048 -s 10G -t freebsd-zfs -l zil1 ada3\n\n\n# Create L2ARC Partitions\n# echo \"Create L2ARC Partitions\"\n# gpart add -a 4k -t freebsd-zfs -l l2arc0 ada2\n# gpart add -a 4k -t freebsd-zfs -l l2arc1 ada3\n\n\n# Load ZFS extensions\nkldload opensolaris.ko\nkldload zfs.ko\n\n\n# Force ZFS to use 4k sectors\nsysctl vfs.zfs.min_auto_ashift=12\n\n# Create ZFS Pool\necho \"Create ZFS Pool\"\nzpool create -f tank mirror /dev/gpt/disk0 /dev/gpt/disk1\n\n# Set proper mountpoint\necho \"Setting Mountpoint\"\nzfs set mountpoint=/ tank\n\n# Export and import the Pool\nzpool export tank\nzpool import -o altroot=/mnt -o cachefile=/var/tmp/zpool.cache tank\n\n# Enable Compression\necho \"Enabling Compression\"\nzfs set compression=lz4 tank\n\n# Add ZIL and L2ARC\n# echo \"Add ZIL and L2ARC\"\n# zpool add tank log mirror /dev/gpt/zil0 /dev/gpt/zil1\n# zpool add tank cache /dev/gpt/l2arc0 /dev/gpt/l2arc1\n\n\n# Set BOOTFS\necho \"Set BOOTFS\"\nzpool set bootfs=tank tank\n\n\n# Copy FreeBSD files\necho \"Installing FreeBSD\"\n\ncd /usr/freebsd-dist\nexport DESTDIR=/mnt\nfor f in base.txz lib32.txz kernel.txz doc.txz ports.txz src.txz;do\n  (cat $f | tar --unlink -xvpJf - -C ${DESTDIR:-/});\ndone\n\ncp /var/tmp/zpool.cache /mnt/boot/zfs/\n\necho \"Enter hostname FQDN\"\nread HOSTNAME\n\necho \"Enter last public IP octet\"\nread IP_ENDING\n\necho \"Enter username\"\nread USERNAME\n\ncat > /mnt/etc/rc.conf << RCCONF\nhostname=\"$HOSTNAME\"\n\nzfs_enable=\"YES\"\n\n# Network\n\ndefaultrouter=\"0.0.0.0\"\nifconfig_igb0=\"inet 0.0.0.$IP_ENDING/32\"\n\n# Services\nsendmail_enable=\"NONE\"\nsshd_enable=\"YES\"\nRCCONF\n\n\ncat > /mnt/etc/fstab << FSTAB\n# Device                       Mountpoint              FStype  Options         Dump    Pass#\n/dev/gpt/swap0                 none                    swap    sw              0       0\n/dev/gpt/swap1                 none                    swap    sw              0       0\nFSTAB\n\n\ncat >> /mnt/boot/loader.conf << LOADER\nzfs_load=\"YES\"\nvfs.root.mountfrom=\"zfs:tank\"\nvfs.zfs.arc_max=\"8G\"\nLOADER\n\ncat >> /mnt/etc/sysctl.conf << SYSCTL\nvfs.zfs.min_auto_ashift=12\nSYSCTL\n\n\ncat > /mnt/etc/resolv.conf << RESOLV\nnameserver 0.0.0.0\nnameserver 0.0.0.0\nRESOLV\n\n\n# Mount a devfs to have /dev/random /dev/zero etc in our chroot\nmount -t devfs none /mnt/dev\n\n# Bootstap pkg and install minimal packages for ansible\nchroot -u root -g wheel /mnt/ env ASSUME_ALWAYS_YES=YES pkg bootstrap\nchroot -u root -g wheel /mnt/ env ASSUME_ALWAYS_YES=YES pkg install sudo zsh\n\n# Add user\nchroot -u root -g wheel /mnt/ pw useradd -n $USERNAME -u 1001 -s /usr/local/bin/zsh -m -d /home/$USERNAME -G wheel -h 0\n\n# Fetch user pub key from github\nmkdir -p /mnt/home/$USERNAME/.ssh\n\n# This fetches the pub key from the sepcified github users and adds them \n# to the .authorized_keys of the new system user\necho \"List of Github users for pubkey retrieval (space separated):\"\nread users\n\nfor user in $users; do\n  fetch https://github.com/$user.keys --no-verify-peer -o - >> /mnt/home/deploy/.ssh/authorized_keys\ndone\n\nchown -R 1001:1001 /mnt/home/$USERNAME/.ssh\n\n# Unmount tank and re-set mountpoint\nzfs unmount -f tank\nzfs set mountpoint=/ tank\necho \"Done\"\n"
  },
  {
    "path": "zfs_bootstrap_be.sh",
    "content": "#!/bin/sh\n\n# Check:\n# https://wiki.freebsd.org/RootOnZFS/GPTZFSBoot/9.0-RELEASE\n# http://wp.strahlert.net/wordpress/zfs-2/expanding-zpool/\n# This script will add ZFS Boot-Enironment support\n\n# Tested on FreeBSD 10, 11 and 12\n\n###############################################################\n# WARNING: Go through line by line and adjust where necessary #\n###############################################################\n\n# Create Partition Table\necho \"Create Partition Table\"\ngpart create -s gpt ada0 # Main HDD\ngpart create -s gpt ada1 # Main HDD\n\n# Optional if you have SSDs for ZIL and L2ARC\n# gpart create -s gpt ada2 # ZIL and L2ARC SSD\n# gpart create -s gpt ada3 # ZIL and L2ARC SSD\n\n\n# Create Boot Partition\necho \"Create Boot Partition\"\ngpart add -a 4k -s 512k -t freebsd-boot ada0\ngpart add -a 4k -s 512k -t freebsd-boot ada1\n\n\n# Create Swap Partitions\necho \"Create Swap Partitions\"\ngpart add -a 4k -s 8G -t freebsd-swap -l swap0 ada0\ngpart add -a 4k -s 8G -t freebsd-swap -l swap1 ada1\n\n\n# Create Main Partitions\necho \"Create Main Partitions\"\ngpart add -a 4k -t freebsd-zfs -l disk0 ada0\ngpart add -a 4k -t freebsd-zfs -l disk1 ada1\n\n\n# Write Bootcode\necho \"Write Bootcode\"\ngpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ada0\ngpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ada1\n\n\n# Create ZIL Partions\n# echo \"Create ZIL Partions\"\n# gpart add -a 4k -b 2048 -s 10G -t freebsd-zfs -l zil0 ada2\n# gpart add -a 4k -b 2048 -s 10G -t freebsd-zfs -l zil1 ada3\n\n\n# Create L2ARC Partitions\n# echo \"Create L2ARC Partitions\"\n# gpart add -a 4k -t freebsd-zfs -l l2arc0 ada2\n# gpart add -a 4k -t freebsd-zfs -l l2arc1 ada3\n\n\n# Load ZFS extensions\nkldload opensolaris.ko\nkldload zfs.ko\n\n\n# Force ZFS to use 4k sectors\nsysctl vfs.zfs.min_auto_ashift=12\n\n# Create ZFS Pool\necho \"Create ZFS Pool\"\nzpool create -o altroot=/mnt -o cachefile=/var/tmp/zpool.cache -f tank mirror /dev/ada0p3 /dev/ada1p3\n\n# Enable Compression\necho \"Enabling Compression\"\nzfs set compression=lz4 tank\n\n# Add ZIL and L2ARC\n# echo \"Add ZIL and L2ARC\"\n# zpool add tank log mirror /dev/gpt/zil0 /dev/gpt/zil1\n# zpool add tank cache /dev/gpt/l2arc0 /dev/gpt/l2arc1\n\n# Create a very minimal ZFS Boot Environment Layout\n# https://wiki.freebsd.org/BootEnvironments\n# https://klarasystems.com/articles/managing-boot-environments/\necho \"Creating zfs boot-environment layout\"\nzfs create -o mountpoint=none tank/ROOT\nzfs create -o mountpoint=/ tank/ROOT/default\n\n# Set BOOTFS\necho \"Set BOOTFS\"\nzpool set bootfs=tank/ROOT/default tank\nzpool set cachefile=/var/tmp/zpool.cache tank\n\n# Copy FreeBSD files\necho \"Installing FreeBSD\"\n\ncd /usr/freebsd-dist\nexport DESTDIR=/mnt\nfor f in base.txz kernel.txz doc.txz ports.txz src.txz;do\n  (cat $f | tar --unlink -xvpJf - -C ${DESTDIR:-/});\ndone\n\necho \"Enter hostname FQDN\"\nread HOSTNAME\n\necho \"Enter last public IP octet\"\nread IP_ENDING\n\necho \"Enter username\"\nread USERNAME\n\ncat > /mnt/etc/rc.conf << RCCONF\nhostname=\"$HOSTNAME\"\n\nzfs_enable=\"YES\"\n\n# Network\n\ndefaultrouter=\"0.0.0.0\"\nifconfig_igb0=\"inet 0.0.0.$IP_ENDING/32\"\n\n# Services\nsendmail_enable=\"NONE\"\nsshd_enable=\"YES\"\nRCCONF\n\n\ncat > /mnt/etc/fstab << FSTAB\n# Device                       Mountpoint              FStype  Options         Dump    Pass#\n/dev/ada0p2                    none                    swap    sw              0       0\n/dev/ada1p2                    none                    swap    sw              0       0\nFSTAB\n\n\ncat >> /mnt/boot/loader.conf << LOADER\nopensolaris_load=\"YES\"\nzfs_load=\"YES\"\nvfs.zfs.arc_max=\"8G\"\nLOADER\n\ncat >> /mnt/etc/sysctl.conf << SYSCTL\nvfs.zfs.min_auto_ashift=12\nSYSCTL\n\n\ncat > /mnt/etc/resolv.conf << RESOLV\nnameserver 0.0.0.0\nnameserver 0.0.0.0\nRESOLV\n\n\n# Mount a devfs to have /dev/random /dev/zero etc in our chroot\nmount -t devfs none /mnt/dev\n\n# Bootstap pkg and install minimal packages for ansible\nchroot -u root -g wheel /mnt/ env ASSUME_ALWAYS_YES=YES pkg bootstrap\nchroot -u root -g wheel /mnt/ env ASSUME_ALWAYS_YES=YES pkg install sudo zsh\n\n# Add user\nchroot -u root -g wheel /mnt/ pw useradd -n $USERNAME -u 1001 -s /usr/local/bin/zsh -m -d /home/$USERNAME -G wheel -h 0\n\n# Fetch user pub key from github\nmkdir -p /mnt/home/$USERNAME/.ssh\n\n# This fetches the pub key from the sepcified github users and adds them \n# to the .authorized_keys of the new system user\necho \"List of Github users for pubkey retrieval (space separated):\"\nread users\n\nfor user in $users; do\n  fetch https://github.com/$user.keys --no-verify-peer -o - >> /mnt/home/deploy/.ssh/authorized_keys\ndone\n\nchown -R 1001:1001 /mnt/home/$USERNAME/.ssh\n\n# Disabling auto mount of default boot environment otherwise it will overlay future environments which\n# will prevent the new environment from booting successfully\nzfs set canmount=noauto tank/ROOT/default\n\necho \"Done\"\n"
  }
]