diff --git a/go.mod b/go.mod
index 126fbd4ee1e47a9dee7fa28f44ce84e736407c05..9c80dc6d2666b018cb8f32e36755341cf73d1b15 100644
--- a/go.mod
+++ b/go.mod
@@ -5,7 +5,7 @@ go 1.15
 require (
 	git.autistici.org/ai3/go-common v0.0.0-20220912095004-9a984189694c
 	git.autistici.org/id/go-sso v0.0.0-20221216110623-a98dfc78fec5
-	github.com/coreos/go-systemd/v22 v22.3.2
+	github.com/coreos/go-systemd/v22 v22.5.0
 	github.com/go-ldap/ldap/v3 v3.4.4
 	github.com/go-sql-driver/mysql v1.7.0
 	github.com/lib/pq v1.10.1
diff --git a/go.sum b/go.sum
index 46ee6a84fc9bd483a356e96098e1fbee7ee6785b..6888c223e259f620cfffe61d5c7ac86825faf9bd 100644
--- a/go.sum
+++ b/go.sum
@@ -235,6 +235,8 @@ github.com/coreos/go-systemd/v22 v22.2.0 h1:BBmbNtSc5PuUM3Byxs7yE5rLdxQO4/FMoEXY
 github.com/coreos/go-systemd/v22 v22.2.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk=
 github.com/coreos/go-systemd/v22 v22.3.2 h1:D9/bQk5vlXQFZ6Kwuu6zaiXJ9oTPe68++AzAJc1DzSI=
 github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
+github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs=
+github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
 github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
 github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
 github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk=
diff --git a/vendor/github.com/coreos/go-systemd/v22/activation/files_unix.go b/vendor/github.com/coreos/go-systemd/v22/activation/files_unix.go
index fc7db98fb41b60d84325c9c4b470a2a34aef0855..bf7671dd2b2f0f9893cb0031a0e5e19c8e1f476f 100644
--- a/vendor/github.com/coreos/go-systemd/v22/activation/files_unix.go
+++ b/vendor/github.com/coreos/go-systemd/v22/activation/files_unix.go
@@ -12,6 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+//go:build !windows
 // +build !windows
 
 // Package activation implements primitives for systemd socket activation.
diff --git a/vendor/github.com/coreos/go-systemd/v22/daemon/watchdog.go b/vendor/github.com/coreos/go-systemd/v22/daemon/watchdog.go
index 7a0e0d3a51b1412884b32bb93b66960a7f157550..25d9c1aa93870e1bbd4bd083ddab4619b46c27af 100644
--- a/vendor/github.com/coreos/go-systemd/v22/daemon/watchdog.go
+++ b/vendor/github.com/coreos/go-systemd/v22/daemon/watchdog.go
@@ -30,8 +30,8 @@ import (
 // It returns one of the following:
 // (0, nil) - watchdog isn't enabled or we aren't the watched PID.
 // (0, err) - an error happened (e.g. error converting time).
-// (time, nil) - watchdog is enabled and we can send ping.
-//   time is delay before inactive service will be killed.
+// (time, nil) - watchdog is enabled and we can send ping.  time is delay
+// before inactive service will be killed.
 func SdWatchdogEnabled(unsetEnvironment bool) (time.Duration, error) {
 	wusec := os.Getenv("WATCHDOG_USEC")
 	wpid := os.Getenv("WATCHDOG_PID")
diff --git a/vendor/github.com/coreos/go-systemd/v22/journal/journal_unix.go b/vendor/github.com/coreos/go-systemd/v22/journal/journal_unix.go
index 8d58ca0fbca04c827a84e2a24108715dca903b17..c5b23a81968f6f32ac001c60df07cf568d04fce2 100644
--- a/vendor/github.com/coreos/go-systemd/v22/journal/journal_unix.go
+++ b/vendor/github.com/coreos/go-systemd/v22/journal/journal_unix.go
@@ -12,6 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+//go:build !windows
 // +build !windows
 
 // Package journal provides write bindings to the local systemd journal.
@@ -53,15 +54,9 @@ var (
 	onceConn sync.Once
 )
 
-func init() {
-	onceConn.Do(initConn)
-}
-
 // Enabled checks whether the local systemd journal is available for logging.
 func Enabled() bool {
-	onceConn.Do(initConn)
-
-	if (*net.UnixConn)(atomic.LoadPointer(&unixConnPtr)) == nil {
+	if c := getOrInitConn(); c == nil {
 		return false
 	}
 
@@ -74,6 +69,58 @@ func Enabled() bool {
 	return true
 }
 
+// StderrIsJournalStream returns whether the process stderr is connected
+// to the Journal's stream transport.
+//
+// This can be used for automatic protocol upgrading described in [Journal Native Protocol].
+//
+// Returns true if JOURNAL_STREAM environment variable is present,
+// and stderr's device and inode numbers match it.
+//
+// Error is returned if unexpected error occurs: e.g. if JOURNAL_STREAM environment variable
+// is present, but malformed, fstat syscall fails, etc.
+//
+// [Journal Native Protocol]: https://systemd.io/JOURNAL_NATIVE_PROTOCOL/#automatic-protocol-upgrading
+func StderrIsJournalStream() (bool, error) {
+	return fdIsJournalStream(syscall.Stderr)
+}
+
+// StdoutIsJournalStream returns whether the process stdout is connected
+// to the Journal's stream transport.
+//
+// Returns true if JOURNAL_STREAM environment variable is present,
+// and stdout's device and inode numbers match it.
+//
+// Error is returned if unexpected error occurs: e.g. if JOURNAL_STREAM environment variable
+// is present, but malformed, fstat syscall fails, etc.
+//
+// Most users should probably use [StderrIsJournalStream].
+func StdoutIsJournalStream() (bool, error) {
+	return fdIsJournalStream(syscall.Stdout)
+}
+
+func fdIsJournalStream(fd int) (bool, error) {
+	journalStream := os.Getenv("JOURNAL_STREAM")
+	if journalStream == "" {
+		return false, nil
+	}
+
+	var expectedStat syscall.Stat_t
+	_, err := fmt.Sscanf(journalStream, "%d:%d", &expectedStat.Dev, &expectedStat.Ino)
+	if err != nil {
+		return false, fmt.Errorf("failed to parse JOURNAL_STREAM=%q: %v", journalStream, err)
+	}
+
+	var stat syscall.Stat_t
+	err = syscall.Fstat(fd, &stat)
+	if err != nil {
+		return false, err
+	}
+
+	match := stat.Dev == expectedStat.Dev && stat.Ino == expectedStat.Ino
+	return match, nil
+}
+
 // Send a message to the local systemd journal. vars is a map of journald
 // fields to values.  Fields must be composed of uppercase letters, numbers,
 // and underscores, but must not start with an underscore. Within these
@@ -82,7 +129,7 @@ func Enabled() bool {
 // (http://www.freedesktop.org/software/systemd/man/systemd.journal-fields.html)
 // for more details.  vars may be nil.
 func Send(message string, priority Priority, vars map[string]string) error {
-	conn := (*net.UnixConn)(atomic.LoadPointer(&unixConnPtr))
+	conn := getOrInitConn()
 	if conn == nil {
 		return errors.New("could not initialize socket to journald")
 	}
@@ -126,6 +173,16 @@ func Send(message string, priority Priority, vars map[string]string) error {
 	return nil
 }
 
+// getOrInitConn attempts to get the global `unixConnPtr` socket, initializing if necessary
+func getOrInitConn() *net.UnixConn {
+	conn := (*net.UnixConn)(atomic.LoadPointer(&unixConnPtr))
+	if conn != nil {
+		return conn
+	}
+	onceConn.Do(initConn)
+	return (*net.UnixConn)(atomic.LoadPointer(&unixConnPtr))
+}
+
 func appendVariable(w io.Writer, name, value string) {
 	if err := validVarName(name); err != nil {
 		fmt.Fprintf(os.Stderr, "variable name %s contains invalid character, ignoring\n", name)
@@ -194,7 +251,7 @@ func tempFd() (*os.File, error) {
 }
 
 // initConn initializes the global `unixConnPtr` socket.
-// It is meant to be called exactly once, at program startup.
+// It is automatically called when needed.
 func initConn() {
 	autobind, err := net.ResolveUnixAddr("unixgram", "")
 	if err != nil {
diff --git a/vendor/github.com/coreos/go-systemd/v22/journal/journal_windows.go b/vendor/github.com/coreos/go-systemd/v22/journal/journal_windows.go
index 677aca68ed20ab5b631797c2f3f93ce06fb77193..322e41e74c3e6a1c3f1bf59fd9e9c06f2fb7b8e3 100644
--- a/vendor/github.com/coreos/go-systemd/v22/journal/journal_windows.go
+++ b/vendor/github.com/coreos/go-systemd/v22/journal/journal_windows.go
@@ -33,3 +33,11 @@ func Enabled() bool {
 func Send(message string, priority Priority, vars map[string]string) error {
 	return errors.New("could not initialize socket to journald")
 }
+
+func StderrIsJournalStream() (bool, error) {
+	return false, nil
+}
+
+func StdoutIsJournalStream() (bool, error) {
+	return false, nil
+}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 3c8efb02014c3c237156befe9a893a51ee572985..e5299cb4f8891d265b52105d5fd5933861dd19b2 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -43,7 +43,7 @@ github.com/cncf/xds/go/udpa/annotations
 github.com/cncf/xds/go/xds/core/v3
 # github.com/coreos/go-semver v0.3.0
 github.com/coreos/go-semver/semver
-# github.com/coreos/go-systemd/v22 v22.3.2
+# github.com/coreos/go-systemd/v22 v22.5.0
 ## explicit
 github.com/coreos/go-systemd/v22/activation
 github.com/coreos/go-systemd/v22/daemon