Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add documentation for manual persistence #14

Open
superjamie opened this issue Aug 15, 2024 · 9 comments
Open

Add documentation for manual persistence #14

superjamie opened this issue Aug 15, 2024 · 9 comments

Comments

@superjamie
Copy link

superjamie commented Aug 15, 2024

As the script says, Busybox crond doesn't support @reboot.

It could be helpful to advise users how they can implement persistence themselves.

I presume the main place such an environment will be encountered is Alpine Linux, which has OpenRC and its local service to run arbitrary scripts at startup, so instructions could be like:

  • Create a script at /etc/local.d/90-geoip-shell-restore.start with contents:
#!/bin/sh
/path/to/geoip-shell/geoip-shell-run.sh restore -a 1>/dev/null 2>/dev/null
  • Set the script executable: chmod +x /etc/local.d/90-geoip-shell-restore.start
  • Enable the local script service: rc-update add local

I thought of implementing this in the script directly but I wasn't sure if you wanted to specifically detect OpenRC init and tie the script to that.

Maybe there are other environments where Busybox cron is used but OpenRC is not present. Such a feature would not be useful in those environments.

If you would like that feature, I'm happy to write it and send a PR for your review.

@friendly-bits
Copy link
Owner

friendly-bits commented Aug 15, 2024

Hi

There are numerous distributions based on Busybox, including some embedded distributions. So I can not really provide a detailed guide in the manual for each one. I will add some basic info on how to call the -run script from a custom init script.

Generally I'm open to implementing support for init systems which need it. I will gladly review your PR. The code should be tied to OpenRC because then additional potential systems using OpenRC would benefit from it. Note that the code related to init system detection and persistence implementation (and subsequent checks) is somewhat convoluted and several scripts will require changes (out the top of my head: -install, -uninstall, -lib-common, -lib-status). So to save you the trouble, I could implement this feature by myself, but I'll need you to test the implementation.

@friendly-bits
Copy link
Owner

friendly-bits commented Aug 15, 2024

The init system detection is done by detect_init() in the -install script. It tries to make the detection as accurate as possible, so there are several steps with each step falling back to the next one. The relevant steps for this case are checking the /sbin/init strings and checking the process with pid 1.

So the first thing to do in order to implement OpenRC detection is to see the output of these commands:

awk 'match($0, /(upstart|systemd|OpenRC|procd|sysvinit|busybox)/) { print substr($0, RSTART, RLENGTH);exit; }' /sbin/init

ls -l /proc/1/exe

Ideally both commands should produce an OpenRC-specific string which can be used for detection. If not, some more tinkering may be needed.

@friendly-bits
Copy link
Owner

Also I've been planning for some time to implement native init-based persistence support for Systemd, so I could as well use this opportunity to add a generic framework for handling init scripts installation, checks and uninstallation. Just saying this before you started your implementation (in case you want to implement this feature by yourself) because there may be an upcoming change in related code structure.

@superjamie
Copy link
Author

Thanks for the quick reply and tips!

Alpine's /sbin/init is busybox, it calls OpenRC through /etc/inittab, and there isn't an openrc daemon left running.

I guess one option is to re-detect busybox init and see if busybox is actually openrc, eg:

case "$initsys" in
  busybox) if [ "$(grep -Ec "::sysinit::/sbin/openrc sysinit" /etc/inittab 2>/dev/null)" -gt 0 ]; then initsys="openrc"; fi ;;

Your existing systemd detection works for me on Debian 12. I think the systemd-native way to implement this would be a few oneshot systemd units which run the required existing scripts at the right time.

Restoring existing rules without update would be ordered Before=network-pre.target and After=nftables.service. Fetching an update would need to be After=network-online.target.

@superjamie
Copy link
Author

An untested first attempt on this branch:

https://github.com/superjamie/geoip-shell/tree/openrc-persistence

I'll test tomorrow or over the weekend.

TODO: make local_d_script common, and use the p_name variable in it

I tried to adhere to your existing style. Any feedback welcome.

@friendly-bits
Copy link
Owner

Thank you, I'll take a look at this hopefully later today. In the meantime, it would be helpful if you could post the output of these commands

awk 'match($0, /(upstart|systemd|OpenRC|procd|sysvinit|busybox)/) { print substr($0, RSTART, RLENGTH);exit; }' /sbin/init

ls -l /proc/1/exe

These are run by detect_init() regardless, and further execution depends on the output, so it'll help if we know what the output is on your system, to figure out which branch the code is currently taking - then we can amend it in an informed way.

@friendly-bits
Copy link
Owner

Never mind, just tested with an iso of Alpine - both commands indicate busybox.

@friendly-bits
Copy link
Owner

friendly-bits commented Aug 15, 2024

So far I've come up with this method which detects OpenRC on both Alpine and Gentoo:

{
	rc_service_f="$(command -v 'rc-service')" && 
		awk 'match($0, /(OpenRC|openrc)/) { print substr($0, RSTART, RLENGTH);exit; }' "$rc_service_f" |
			grep . && initsys=openrc
} 1>/dev/null 2>/dev/null

Your method with /etc/inittab could work as well, with a slight modification:

grep 'sysinit:/sbin/openrc sysinit' /etc/inittab 1>/dev/null 2>/dev/null && initsys=openrc

Probably your method is better because the rc-service binary could be present in the system regardless of the actual init used in it.

@superjamie
Copy link
Author

Yes, that was my intention. OpenRC might be installed but not necessarily the init system.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants