This works, sort of: $ sudo cat /etc/runit/sv/autotunnel-[port]/run
#!/bin/sh
exec chpst -u autotunnel /usr/bin/autossh -M 0 -i /home/autotunnel/.ssh/[sshkey] -NTR [muhport]:localhost:[muhport] [user]@[ip.ad.dre.ss] -o ServerAliveInterval=10 -o ServerAliveCountMax=5
While this runs and establishs the tunnel on any port I see fit, the ServerAliveCountMax option is ignored.
The intention was that it will self-terminate if 5 "ping" failures occur, and it will be restarted by the process monitor, reestablishing the reverse ssh tunnel. I never got to test that because autossh fails to obey ServerAliveCountMax. It never self-terminates no matter how many "ping" failures there are, so I have no idea if a monitor would or would not restart it. Not a runit problem. Yet... If it ever self-terminates as directed, I fully expect that runit will not restart the service. I have no faith in runit actually doing it's job. I've come to expect a cascade of failures/dysfunction and I'll have another nonsensical hell to sort out...
So, the crude/sloppy/stupid workarounds begin...
I created a second service to function as a watchdog. It attempts to curl through the port being forwarded. If this fails a number of times, the machine reboots itself, and this causes the autotunnel to run at boot and re-establish. Yes. I know that this is a terrible idea, but since doing it correctly isn't an option (autossh refuses to obey ServerAliveCountMax), I settled on it as a dumb way to at least get something working, sort of. It's also double terrible because it has to be run as root. The whole point of having an isolated service user for autossh was to avoid this kind of stupidity. But, I am forced to find a work around because, again, autossh doesn't obey it's own ServerAliveCountMax directive.
It looks like this:$ sudo cat /etc/runit/sv/check-connectivity/run
#!/bin/sh
exec chpst -u root /root/check.sh
$ sudo cat /root/check.sh
#!/bin/bash
while true
do
sleep 5m
curl -m 5 -L --silent https://[domain].com/ > /dev/null
fail=$?
if [ "$fail" -ne "0" ]
then
/usr/bin/reboot
fi
done
I don't like this, but it gets the job done.
This has been runit hell #1.
Runit hell #2 consists of those things that runit simply will not do at all no matter what.
1) start a VM at boot. It just won't.$ cat ./startvms.sh
VBoxManage startvm [vm01] --type headless
VBoxManage startvm [vm02] --type headless ...
There also exists a manual VM shutdown shell script.
2) recently, I was tinkering with ssh-chat. I got it working, manually, as I see fit. However, I have the same problem with it as I do the VMs. Runit simply won't do it no matter what.$ sudo cat /root/ssh-chat.sh
runuser -u ssh-chat -- ssh-chat --bind=[ip.ad.dre.ss]:[port] --identity=/path/to/key --motd=/path/to/motd.txt --allowlist=/path/to/allowlist
The simple shell scripts (really just a single command) run fine when manually executed. But, nothing can convince runit to execute these commands. Yes. I understand that the syntax isn't going to work in a runit script. I tried the correct stuff (exec chpst -u etc...) to the working autotunnel scripts, which do work, and it still gives me the useless: timeout: down: [service name]: 1s, normally up, want up
It also refuses to do the cheesy "execute the shell script" work around as seen in the crude curl/reboot example above. So, the exact same thing works there, but not here... [shrug].
Since R-ing the FM has been pointless and I have learned absolutely nothing from it, I looked at several other repo-provided runit service files to see if I could learn from the examples, but they don't help. It's incredibly simple, as intended. I'm left holding the bag of "What works there doesn't work here; no explanation. It just doesn't."
Also, I have showed both of these:#!/bin/bash
#!/bin/sh
It either works, or it doesn't, and this line makes no difference.