zAppendix - xenophon61/Znapzend-recipes-for-mixed-MacOS-Linux-environment GitHub Wiki
The network environment, as of August, 2024 - configuration files for ssh
> cat /Library/LaunchDaemons/org.znapzend.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>EnvironmentVariables</key>
<dict>
<key>PATH</key>
<string>/usr/local/zfs/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
</dict>
<key>KeepAlive</key>
<dict>
<key>Crashed</key>
<false/>
</dict>
<key>Label</key>
<string>org.znapzend</string>
<key>ProgramArguments</key>
<array>
<string>/opt/znapzend-0.22.1/bin/znapzend</string>
<string>--connectTimeout=512</string>
<string>--features=oracleMode,compressed</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>StandardErrorPath</key>
<string>/var/log/org.znapzend.stderr</string>
<key>StandardOutPath</key>
<string>/var/log/org.znapzend.stdout</string>
<key>ThrottleInterval</key>
<integer>30</integer>
</dict>
</plist>
sudo launchctl load -w /Library/LaunchDaemons/org.znapzend.plist
> sudo launchctl list | grep znap
49960 0 org.znapzend
sudo launchctl unload /Library/LaunchDaemons/org.znapzend.plist
Note: after startup, the znapzend daemon fails to load properly (launchctl error code 255). Have not been able to figure out the cause, and resorted to manually running the commands to load it after a system restart.
Also keep in mind that installing znapzend
via Homebrew is slightly different (and quite simpler, perhaps better?). Invoking the daemon is as simple as:
sudo brew services start znapzend
sudo brew services stop znapzend
# added April 29, 2024
ServerAliveInterval 240
ServerAliveCountMax 10
# added March, 2024
HostkeyAlgorithms +ssh-rsa
PubkeyAcceptedAlgorithms +ssh-rsa
# May 8, 2024
PermitLocalCommand yes
Host (MacOStarget).local
Hostname (MacOStarget).local
PubKeyAuthentication yes
# added May 21, 2024 (znapzend man-in-the-middle errors otherwise, possiibly
#
StrictHostKeyChecking no
# added May 23, 2024
IdentityFile /var/root/.ssh/id_ed25519
SendEnv LANG LC_*
Only relevant information shown
Match host (MacOStarget).local exec "/usr/local/bin/wakeonlan ax:ax:5x:bx:7x:bx &"
#ServerAliveInterval 120
Host (Linuxtarget).local
Hostname (Linuxtarget).local
User <my-user-name>
PubKeyAuthentication yes
IdentityFile /Users/<my-user-name>/.ssh/id_linuxtarget
Host (MacOStarget).local
Hostname (MacOStarget).local
User <my-user-name>
PubKeyAuthentication yes
# added May 21, 2024 (znapzend man-in-the-middle errors otherwise, possiibly
#
StrictHostKeyChecking no
IdentityFile /Users/<my-user-name>/.ssh/id_ed25519
# added May 17, 2024
SendEnv LANG LC_*
# when disabled, what happens? ZNAPZENDZTATZ THROWS LANG_ ERRORS!
PermitLocalCommand yes
LocalCommand caffeinate -w $PPID &
Serves as a znapzend
target, but also as an rsync
source via a crontab
schedule
/etc/ssh/ssh_config.d/100_(MacOStarget).conf
Match host (MacOStarget).local exec "/usr/sbin/etherwake -i enp6s0 ax:ax:5x:bx:7x:bx -b (MacOStarget).local && sleep 20 &"
Actually, it's best to include this in the /etc/ssh/ssh_config file
cat /etc/ssh/ssh_config
#
#
#
Match host (MacOStarget).local exec "/usr/sbin/etherwake -i enp6s0 ax:ax:5x:bx:7x:bx -b (MacOStarget).local && /usr/sbin/etherwake -i enp6s0 ax:ax:5x:bx:7x:x0 -b (MacOStarget).local && sleep 16 & "
#
ServerAliveInterval 240
ServerAliveCountMax 10
PermitLocalCommand yes
A sample crontab
entry; note that a /var/log/rsync-devo
folder has been created for log files.
0 2 * * Thu /usr/bin/rsync -azh --progress --timeout=256 --no-perms --no-owner --no-group --log-file=/var/log/rsync-devo/"$(date +\%F_\%I_\%M)"_share_name.txt --delete --exclude='.DocumentRevisions-V*' --exclude='.AppleDouble' --exclude='.fseventsd' --exclude='.metadata_never_index' --exclude='.Spotlight-V*' --exclude='.Trashes' --exclude='.TemporaryItems' --rsync-path="/usr/bin/caffeinate -i /usr/local/bin/rsync --timeout=128 " /<zpool name>/<zfs directory>/ <username>@(MacOStarget).local:/Volumes/<zpool destination>/<zfs dataset>
Of note, the --rsync-path="/usr/bin/caffeinate -i /usr/local/bin/rsync"
component keeps the MacOS target machine awake during the rsync
transfer, and is VERY important. This assumes a Homebrew install of rsync
, rather than the built-in MacOS command (which is an older version).
This is the machine that accepts ssh
(i.e. znapzend
) and rsync
transfers.
Important note: Sonoma OS updates overwrite the /etc/ssh/sshd_config
file with a default one. For this reason, it's best to specify the options listed below in a .conf
file at the /etc/ssh/sshd_config.d
directory (note it's "sshd" in the name, not "ssh").
❯ cat ~/.ssh/environment
PATH=/usr/local/bin:/usr/local/sbin:/usr/local/bin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin:/usr/local/zfs/bin
❯ cat /etc/ssh/sshd_config.d/<macostarget>.conf | more
# Options set by macOS that differ from the OpenSSH defaults.
UsePAM yes
AcceptEnv LANG LC_*
PermitUserEnvironment yes
TCPKeepAlive yes
ClientAliveInterval 0
ClientAliveCountMax 3
Check this reference if rsync throws i/o errors, and adjust accordingly.
Regarding rsync
in, say, other machine's crontabs: the source machine should include this flag to prevent sleep: --rsync-path="/usr/bin/caffeinate -i /usr/local/bin/rsync"
. This assumes a Homebrew install of rsync
, rather than the built-in MacOS command (which is an older version).
Sometimes, despite appropriate configuration of the sshd
server daemon, the MacOS target sleeps during zfs
or rsync
transfers (via ssh
). This can be overcome by introducing the following:
- first, create a local script (and chmod +x it), as follows
cat /usr/local/bin/sshd_caffeinate
#! /bin/bash
if [[ -n $SSH_ORIGINAL_COMMAND ]] # command given, so run it
then
# exec /bin/bash -c "$SSH_ORIGINAL_COMMAND"
# exec /usr/bin/caffeinate -i '/bin/bash -c $SSH_ORIGINAL_COMMAND'
#exec /bin/bash -c "/usr/bin/caffeinate -i $SSH_ORIGINAL_COMMAND"
exec /bin/bash -c "/usr/bin/caffeinate -s $SSH_ORIGINAL_COMMAND"
else # no command, so interactive login shell
# exec bash -il
exec /bin/zsh -il
fi
# source https://unix.stackexchange.com/questions/526848/ssh-forcecommand-for-shell-while-keeping-regular-login-and-remote-command-execut
- then, add this entry at the end of
/etc/ssh/sshd_config.d/<macostarget>.conf
#Match User anoncvs
# X11Forwarding no
# AllowTcpForwarding no
# PermitTTY no
# ForceCommand cvs server
ForceCommand /usr/local/bin/sshd_caffeinate
as well as edit the following:
#
MaxSessions 100
#
# enabled Aug 11, 2024
#
MaxStartups 10:30:100
That should prevent the target sleeping, as the caffeinate -s
command is invoked during all ssh
connections (non-interactive ones, obviously). For some reason, the -i
argument as outlined in the man page does not work.