Add certificate watcher for external certs to reload nginx
In case of TLS_FLAVOR=[mail,cert], the user supplies their own certificates. However, since nginx is not aware of changes to these files, it cannot reload itself e.g. when the certs get renewed. To solve this, let’s add a small daemon in the place of `letsencrypt.py`, which uses a flexible file-watching framework and reloads nginx in the case the certificates change ….master
parent
c25c646909
commit
1aa97c9914
@ -0,0 +1,63 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
"""
|
||||||
|
Certificate watcher which reloads nginx or reconfigures it, depending on what
|
||||||
|
happens to externally supplied certificates. Only executed by start.py in case
|
||||||
|
of TLS_FLAVOR=[mail, cert]
|
||||||
|
"""
|
||||||
|
|
||||||
|
from os.path import exists, split as path_split
|
||||||
|
from os import system
|
||||||
|
import time
|
||||||
|
from watchdog.observers import Observer
|
||||||
|
from watchdog.events import FileSystemEventHandler, FileDeletedEvent, \
|
||||||
|
FileCreatedEvent, FileModifiedEvent, FileMovedEvent
|
||||||
|
|
||||||
|
class ChangeHandler(FileSystemEventHandler):
|
||||||
|
"watchdog-handler listening on any event, executing the correct configuration/reload steps"
|
||||||
|
@staticmethod
|
||||||
|
def reload_nginx():
|
||||||
|
"merely reload nginx without re-configuring everything"
|
||||||
|
if exists("/var/run/nginx.pid"):
|
||||||
|
print("Reloading a running nginx")
|
||||||
|
system("nginx -s reload")
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def reexec_config():
|
||||||
|
"execute a reconfiguration of the system, which also reloads"
|
||||||
|
print("Reconfiguring system")
|
||||||
|
system("/config.py")
|
||||||
|
|
||||||
|
def on_any_event(self, event):
|
||||||
|
"event-listener checking if the affected files are the cert-files we're interested in"
|
||||||
|
if event.is_directory:
|
||||||
|
return
|
||||||
|
|
||||||
|
filename = path_split(event.src_path)[-1]
|
||||||
|
if isinstance(event, FileMovedEvent):
|
||||||
|
filename = path_split(event.dest_path)[-1]
|
||||||
|
|
||||||
|
if filename in ['cert.pem', 'key.pem']:
|
||||||
|
# all cases except for FileModified need re-configure
|
||||||
|
if isinstance(event, (FileCreatedEvent, FileMovedEvent, FileDeletedEvent)):
|
||||||
|
ChangeHandler.reexec_config()
|
||||||
|
# file modification needs only a nginx reload without config.py
|
||||||
|
elif isinstance(event, FileModifiedEvent):
|
||||||
|
ChangeHandler.reload_nginx()
|
||||||
|
# cert files have been moved away, re-configure
|
||||||
|
elif isinstance(event, FileMovedEvent) and path_split(event.src_path)[-1] in ['cert.pem', 'key.pem']:
|
||||||
|
ChangeHandler.reexec_config()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
observer = Observer()
|
||||||
|
handler = ChangeHandler()
|
||||||
|
observer.schedule(handler, "/certs", recursive=False)
|
||||||
|
observer.start()
|
||||||
|
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
time.sleep(1)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
observer.stop()
|
||||||
|
|
||||||
|
observer.join()
|
Loading…
Reference in New Issue