Problem and solutions
I got a simple task to restart reverse proxy process after certificate was updated. It sounds simple, but there is a complication in my case, certificates are generated on different server and get presented to system where reverse proxy runs.
There are two approaches to it:
- Use inotifywait or similar tool to run restart when file is updated. Proxy process could be restarted almost instantly after certs are upgraded. But you need to install inotifywait separately and then create shell script plus systemd service to run it. I do not like this approach.
- Periodically check if certificate file is updated and restart reverse proxy when it happen. It may take long time to detect changes, but it can be done using standard utilities and single systemd timer. Usually there is no need to apply new certificate immediately, it can way for next re-scan. This also allow you to schedule restart for time when it going to be less impacting, like middle of the night. This guide based on this approach.
Setup
- ha-proxy started by haproxy.service
- Site certificate stored in /etc/haproxy/mysite.pem
- ha-proxy PID file in */var/run/haproxy.pid
- system is Debian
Steps
- Create .timer file .
/etc/systemd/system/check-cert.timer
I’m not sure that /etc/systemd/system is right place for that file[Unit] Description=Check if certificate was updated and restart haproxy if it was [Timer] OnCalendar=*-*-* 3:00:00 Persistent=false [Install] WantedBy=timers.target
Timer will be triggered once a day at 3:00am. Adjust
OnCalendar
to match your needs -
Create .service file.
/etc/systemd/system/check-cert.service
Name of service should match name of timer. (you can overwrite it if you wish)[Unit] Description=Check if certificate was updated and restart haproxy if it was [Service] Type=oneshot ExecStart=/usr/bin/find /etc/haproxy/mysite.pem -cnewer /var/run/haproxy.pid -print -exec /bin/systemctl restart haproxy \;
How does it work:
find will search for all files in /etc/haproxy/mysite.pem ( which means just that file), check if it created after creation of /var/run/haproxy.pid and if it does execute command after -exec restarting haproxy. /var/run/haproxy.pid is created every time haproxy process restarted. So if haproxy was started before /etc/haproxy/mysite.pem was created, then /etc/haproxy/mysite.pem will match, and find will restart haproxy. if /etc/haproxy/mysite.pem is older than /var/run/haproxy.pid nothing will happen. - Signal systemd to reload config files
sudo systemctl daemon-reload
- Run your service manually to ensure it works
# touch /etc/haproxy/mysite.pem # systemctl start check-cert.service # systemctl status check-cert.service ● check-cert.service - Check if certificate was updated and restart haproxy if it was Loaded: loaded (/etc/systemd/system/check-cert.service; static; vendor preset: enabled) Active: inactive (dead) since Sat 2021-12-04 22:46:55 AEDT; 31s ago Process: 23145 ExecStart=/etc/haproxy/mysite.pem -cnewer /var/run/haproxy.pid -print -exec /bin/systemctl restart haproxy ; (code=exited, status=0/SUCCESS) Main PID: 23145 (code=exited, status=0/SUCCESS) Dec 04 22:46:54 jellyfin systemd[1]: Starting Check if certificate was updated and restart haproxy if it was... Dec 04 22:46:54 jellyfin find[23145]: /etc/haproxy/mysite.pem Dec 04 22:46:55 jellyfin systemd[1]: Check if certificate was updated and restart haproxy if it was.
and then check that haproxy been restarted.
- If haproxy got restarted as expected, enable and start timer
# systemctl enable check-cert.timer Created symlink /etc/systemd/system/timers.target.wants/check-cert.timer → /etc/systemd/system/check-cert.timer. # systemctl start check-cert.timer
- Check that new timer is running
# systemctl list-timers --all NEXT LEFT LAST PASSED UNIT ACTIVATES Sun 2021-12-05 03:00:00 AEDT 4h 21min left n/a n/a check-cert.timer check-cert.service
It is all, folks. You are done.