diff --git a/tools/dhtnode.cpp b/tools/dhtnode.cpp
index b0dbc31dd6f4ef718a5a69e00c19496379c9d62d..06d7799f416d63ca5b2fbe872ca03e2b562cc1dc 100644
--- a/tools/dhtnode.cpp
+++ b/tools/dhtnode.cpp
@@ -242,10 +242,10 @@ void cmd_loop(std::shared_ptr<DhtRunner>& node, dht_params& params
                 iss >> idstr;
 #endif // OPENDHT_PUSH_NOTIFICATIONS
             try {
-                if (params.id.first and params.id.second){
+                if (params.proxy_id.first and params.proxy_id.second){
                     unsigned int port = std::stoi(idstr);
                     proxies.emplace(port, std::unique_ptr<DhtProxyServer>(
-                        new DhtProxyServer(params.id, node, port
+                        new DhtProxyServer(params.proxy_id, node, port
 #ifdef OPENDHT_PUSH_NOTIFICATIONS
                                            ,pushServer
 #endif
@@ -575,10 +575,10 @@ main(int argc, char **argv)
 #ifdef OPENDHT_PROXY_SERVER
         std::map<in_port_t, std::unique_ptr<DhtProxyServer>> proxies;
 #endif
-        if (params.proxyserverssl and params.id.first and params.id.second){
+        if (params.proxyserverssl and params.proxy_id.first and params.proxy_id.second){
 #ifdef OPENDHT_PROXY_SERVER
             proxies.emplace(params.proxyserverssl, std::unique_ptr<DhtProxyServer>(
-                new DhtProxyServer(params.id,
+                new DhtProxyServer(params.proxy_id,
                                    node, params.proxyserverssl, params.pushserver, context.logger)));
         }
         if (params.proxyserver) {
diff --git a/tools/tools_common.h b/tools/tools_common.h
index 7a6b2a1a10a2d8ffe67507849a6fcc8048403635..bd682a03bc473274d2b45849c726776b6e378bf6 100644
--- a/tools/tools_common.h
+++ b/tools/tools_common.h
@@ -127,34 +127,39 @@ struct dht_params {
     std::string devicekey {};
     std::string persist_path {};
     dht::crypto::Identity id {};
+    dht::crypto::Identity proxy_id {};
     std::string privkey_pwd {};
+    std::string proxy_privkey_pwd {};
     std::string save_identity {};
 };
 
 static const constexpr struct option long_options[] = {
-    {"help",             no_argument      , nullptr, 'h'},
-    {"port",             required_argument, nullptr, 'p'},
-    {"net",              required_argument, nullptr, 'n'},
-    {"bootstrap",        required_argument, nullptr, 'b'},
-    {"identity",         no_argument      , nullptr, 'i'},
-    {"save-identity",    required_argument, nullptr, 'I'},
-    {"certificate",      required_argument, nullptr, 'c'},
-    {"privkey",          required_argument, nullptr, 'k'},
-    {"privkey-password", required_argument, nullptr, 'm'},
-    {"verbose",          no_argument      , nullptr, 'v'},
-    {"daemonize",        no_argument      , nullptr, 'd'},
-    {"service",          no_argument      , nullptr, 's'},
-    {"peer-discovery",   no_argument      , nullptr, 'D'},
-    {"persist",          required_argument, nullptr, 'f'},
-    {"logfile",          required_argument, nullptr, 'l'},
-    {"syslog",           no_argument      , nullptr, 'L'},
-    {"proxyserver",      required_argument, nullptr, 'S'},
-    {"proxyserverssl",   required_argument, nullptr, 'e'},
-    {"proxyclient",      required_argument, nullptr, 'C'},
-    {"pushserver",       required_argument, nullptr, 'y'},
-    {"devicekey",        required_argument, nullptr, 'z'},
-    {"version",          no_argument      , nullptr, 'V'},
-    {nullptr,            0                , nullptr,  0}
+    {"help",                    no_argument      , nullptr, 'h'},
+    {"port",                    required_argument, nullptr, 'p'},
+    {"net",                     required_argument, nullptr, 'n'},
+    {"bootstrap",               required_argument, nullptr, 'b'},
+    {"identity",                no_argument      , nullptr, 'i'},
+    {"save-identity",           required_argument, nullptr, 'I'},
+    {"certificate",             required_argument, nullptr, 'c'},
+    {"privkey",                 required_argument, nullptr, 'k'},
+    {"privkey-password",        required_argument, nullptr, 'm'},
+    {"verbose",                 no_argument      , nullptr, 'v'},
+    {"daemonize",               no_argument      , nullptr, 'd'},
+    {"service",                 no_argument      , nullptr, 's'},
+    {"peer-discovery",          no_argument      , nullptr, 'D'},
+    {"persist",                 required_argument, nullptr, 'f'},
+    {"logfile",                 required_argument, nullptr, 'l'},
+    {"syslog",                  no_argument      , nullptr, 'L'},
+    {"proxyserver",             required_argument, nullptr, 'S'},
+    {"proxyserverssl",          required_argument, nullptr, 'e'},
+    {"proxy-certificate",       required_argument, nullptr, 'w'},
+    {"proxy-privkey",           required_argument, nullptr, 'K'},
+    {"proxy-privkey-password",  required_argument, nullptr, 'M'},
+    {"proxyclient",             required_argument, nullptr, 'C'},
+    {"pushserver",              required_argument, nullptr, 'y'},
+    {"devicekey",               required_argument, nullptr, 'z'},
+    {"version",                 no_argument      , nullptr, 'V'},
+    {nullptr,                   0                , nullptr,  0}
 };
 
 dht_params
@@ -162,6 +167,7 @@ parseArgs(int argc, char **argv) {
     dht_params params;
     int opt;
     std::string privkey;
+    std::string proxy_privkey;
     while ((opt = getopt_long(argc, argv, "hidsvDp:n:b:f:l:", long_options, nullptr)) != -1) {
         switch (opt) {
         case 'p': {
@@ -245,12 +251,26 @@ parseArgs(int argc, char **argv) {
             }
             break;
         }
+        case 'w': {
+            try {
+                params.proxy_id.second = std::make_shared<dht::crypto::Certificate>(loadFile(optarg));
+            } catch (const std::exception& e) {
+                throw std::runtime_error(std::string("Error loading proxy certificate: ") + e.what());
+            }
+            break;
+        }
         case 'k':
             privkey = optarg;
             break;
+        case 'K':
+            proxy_privkey = optarg;
+            break;
         case 'm':
             params.privkey_pwd = optarg;
             break;
+        case 'M':
+            params.proxy_privkey_pwd = optarg;
+            break;
         case 'I':
             params.save_identity = optarg;
             break;
@@ -260,11 +280,20 @@ parseArgs(int argc, char **argv) {
     }
     if (not privkey.empty()) {
         try {
-            params.id.first = std::make_shared<dht::crypto::PrivateKey>(loadFile(privkey), params.privkey_pwd);
+            params.id.first = std::make_shared<dht::crypto::PrivateKey>(loadFile(privkey),
+                                                                        params.privkey_pwd);
         } catch (const std::exception& e) {
             throw std::runtime_error(std::string("Error loading private key: ") + e.what());
         }
     }
+    if (not proxy_privkey.empty()) {
+        try {
+            params.proxy_id.first = std::make_shared<dht::crypto::PrivateKey>(loadFile(proxy_privkey),
+                                                                              params.proxy_privkey_pwd);
+        } catch (const std::exception& e) {
+            throw std::runtime_error(std::string("Error loading proxy private key: ") + e.what());
+        }
+    }
     if (params.save_identity.empty())
         params.privkey_pwd.clear();
     return params;