diff --git a/tools/common.cpp b/tools/common.cpp
index aeb21ed83fec1d87d70f2387f2babed6bc4df796..7b10bfd817cb77cc31e6fd9341fda3e7674d94bb 100644
--- a/tools/common.cpp
+++ b/tools/common.cpp
@@ -29,6 +29,20 @@
 
 namespace dhtnet {
 
+std::filesystem::path cachePath()
+{
+    auto* cache_path = getenv("DHTNET_CACHE_DIR");
+    if (cache_path) {
+        return std::filesystem::path(cache_path);
+    }
+    auto* home = getenv("HOME");
+    if (home) {
+        return std::filesystem::path(home) / ".cache" / "dhtnet";
+    }
+    // If user got no HOME and no DHTNET_CACHE_DIR set, use /tmp
+    return std::filesystem::path("/tmp");
+}
+
 std::unique_ptr<ConnectionManager::Config>
 connectionManagerConfig(dht::crypto::Identity identity,
                         const std::string& bootstrap,
@@ -41,7 +55,6 @@ connectionManagerConfig(dht::crypto::Identity identity,
                         const std::string& turn_pass,
                         const std::string& turn_realm)
 {
-    std::filesystem::create_directories(PATH/"certstore");
     // DHT node creation: To make a connection manager at first a DHT node should be created
     dht::DhtRunner::Config dhtConfig;
     dhtConfig.dht_config.id = identity;
@@ -70,7 +83,7 @@ connectionManagerConfig(dht::crypto::Identity identity,
     config->id = identity;
     config->ioContext = ioContext;
     config->certStore = certStore;
-    config->cachePath = PATH;
+    config->cachePath = cachePath();
     config->factory = iceFactory;
     config->logger = logger;
     if (!turn_host.empty()){
diff --git a/tools/common.h b/tools/common.h
index d08512d7f0aaf7d576a64270645a058c62c436d1..b1bde5cfde72875491355c7652bc304ca7bbb6a0 100644
--- a/tools/common.h
+++ b/tools/common.h
@@ -25,7 +25,8 @@ namespace dhtnet {
 
 using Buffer = std::shared_ptr<std::vector<uint8_t>>;
 constexpr size_t BUFFER_SIZE = 64 * 1024;
-const std::filesystem::path PATH = std::filesystem::path(getenv("HOME")) / ".dhtnet";
+
+std::filesystem::path cachePath();
 
 std::unique_ptr<ConnectionManager::Config> connectionManagerConfig(
     dht::crypto::Identity identity,
diff --git a/tools/dnc/README.md b/tools/dnc/README.md
index 6fe274857decf99a5492959b83855f4468778e9f..fffb379b915221084ca003040b1df37aa193a6d0 100644
--- a/tools/dnc/README.md
+++ b/tools/dnc/README.md
@@ -46,8 +46,10 @@ To facilitate SSH connections to a remote device, dnc establishes a DHT network
 To initiate, generate a certificate authority and a server certificate:
 
 ```shell
-sudo dhtnet-crtmgr --setup -o /etc/dhtnet/
+sudo dhtnet-crtmgr --setup -o /usr/local/etc/dhtnet/
 ```
+The server will cache some values in `/var/run/dhtnet`. If this must be changed,
+you can remove the line `Environment="DHTNET_CACHE_DIR=/var/run/dhtnet"` in `dnc.service.in`.
 Then, launch the dnc service:
 ```shell
 systemctl start dnc.service
diff --git a/tools/dnc/dnc.cpp b/tools/dnc/dnc.cpp
index 3923716c6a561c0b583ad6c3c11d08591b934cc4..bce0388098323ed7c3840d0db8afd4e961299c97 100644
--- a/tools/dnc/dnc.cpp
+++ b/tools/dnc/dnc.cpp
@@ -62,9 +62,7 @@ Dnc::Dnc(dht::crypto::Identity identity,
          const bool anonymous)
     : logger(dht::log::getStdLogger())
     , ioContext(std::make_shared<asio::io_context>()),
-    iceFactory(std::make_shared<IceTransportFactory>(logger)),
-    certStore(std::make_shared<tls::CertificateStore>(PATH/"certstore", logger)),
-    trustStore(std::make_shared<tls::TrustStore>(*certStore))
+    iceFactory(std::make_shared<IceTransportFactory>(logger))
 {
     ioContextRunner = std::thread([context = ioContext, logger = logger] {
         try {
@@ -76,6 +74,9 @@ Dnc::Dnc(dht::crypto::Identity identity,
         }
     });
 
+    certStore = std::make_shared<tls::CertificateStore>(cachePath()/"certStore", logger);
+    trustStore = std::make_shared<tls::TrustStore>(*certStore);
+
     auto ca = identity.second->issuer;
     trustStore->setCertificateStatus(ca->getId().toString(), tls::TrustStore::PermissionStatus::ALLOWED);
 
diff --git a/tools/dnc/systemd/dnc.service.in b/tools/dnc/systemd/dnc.service.in
index dedcea4a587810953c46fe5eb14d0c524f11cba0..3f0568e318aa1fb25132afdae43424fafe2fbe7b 100644
--- a/tools/dnc/systemd/dnc.service.in
+++ b/tools/dnc/systemd/dnc.service.in
@@ -2,42 +2,20 @@
 Description=Dnc server
 Documentation=man:dnc(1)
 After=network.target
+Wants=network-online.target
+Documentation=https://git.jami.net/savoirfairelinux/dhtnet/blob/master/tools/dvpn/README.md
 
 [Service]
-Type=simple
-User=dnc
-Group=dnc
+Type=exec
+Environment="DHTNET_CACHE_DIR=/var/run/dhtnet"
 ExecStart=@bindir@/dnc -l -d @sysconfdir@/dhtnet/dnc.yaml -c @sysconfdir@/dhtnet/id/id-server.crt -p @sysconfdir@/dhtnet/id/id-server.pem
 Restart=on-failure
-RestartSec=2s
-LimitNOFILE=65536
-DynamicUser=yes
-KillMode=process
-WorkingDirectory=/tmp
-
-# Hardening
-CapabilityBoundingSet=CAP_NET_BIND_SERVICE
-LockPersonality=yes
-NoNewPrivileges=yes
-PrivateDevices=yes
-PrivateTmp=yes
-PrivateUsers=yes
-ProtectClock=yes
-ProtectControlGroups=yes
-ProtectHome=yes
-ProtectHostname=yes
-ProtectKernelLogs=yes
-ProtectKernelModules=yes
-ProtectKernelTunables=yes
 ProtectSystem=strict
-ReadOnlyDirectories=/
-ReadWriteDirectories=-/proc/self
-ReadWriteDirectories=-/var/run
-RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
-RestrictNamespaces=yes
-RestrictRealtime=yes
-SystemCallArchitectures=native
+ProtectKernelTunables=yes
+ProtectKernelModules=yes
+ProtectControlGroups=yes
+PrivateDevices=yes
 SystemCallFilter=@system-service
 
 [Install]
-WantedBy=multi-user.target
+WantedBy=multi-user.target
\ No newline at end of file
diff --git a/tools/dsh/dsh.cpp b/tools/dsh/dsh.cpp
index 9da05443d60a100c67b9a9cf426f6e58f363a022..84566128757ffea9b890745a03f1af9edea310fa 100644
--- a/tools/dsh/dsh.cpp
+++ b/tools/dsh/dsh.cpp
@@ -95,7 +95,7 @@ dhtnet::Dsh::Dsh(dht::crypto::Identity identity,
     :logger(dht::log::getStdLogger())
     , ioContext(std::make_shared<asio::io_context>()),
     iceFactory(std::make_shared<IceTransportFactory>(logger)),
-    certStore(std::make_shared<tls::CertificateStore>(PATH/"certstore", logger)),
+    certStore(std::make_shared<tls::CertificateStore>(cachePath()/"certstore", logger)),
     trustStore(std::make_shared<tls::TrustStore>(*certStore))
 {
     ioContext = std::make_shared<asio::io_context>();
diff --git a/tools/dvpn/dvpn.cpp b/tools/dvpn/dvpn.cpp
index 021b000b0e952e923326c2d9163b486cfc795bc4..f6214a34b1ce9c9f3a9419ddabbffdaa1826a92b 100644
--- a/tools/dvpn/dvpn.cpp
+++ b/tools/dvpn/dvpn.cpp
@@ -166,7 +166,7 @@ dhtnet::Dvpn::Dvpn(dht::crypto::Identity identity,
     : logger(dht::log::getStdLogger())
     , ioContext(std::make_shared<asio::io_context>()),
     iceFactory(std::make_shared<IceTransportFactory>(logger)),
-    certStore(std::make_shared<tls::CertificateStore>(PATH/"certstore", logger)),
+    certStore(std::make_shared<tls::CertificateStore>(cachePath()/"certstore", logger)),
     trustStore(std::make_shared<tls::TrustStore>(*certStore))
 {
     ioContextRunner = std::thread([context = ioContext, logger = logger] {