mirror of
https://github.com/PurpleI2P/i2pd.git
synced 2025-01-09 19:47:54 +00:00
commit
b4864831e0
@ -113,6 +113,7 @@ namespace config {
|
|||||||
("log", value<std::string>()->default_value(""), "Logs destination: stdout, file (stdout if not set, file - otherwise, for compatibility)")
|
("log", value<std::string>()->default_value(""), "Logs destination: stdout, file (stdout if not set, file - otherwise, for compatibility)")
|
||||||
("logfile", value<std::string>()->default_value(""), "Path to logfile (stdout if not set, autodetect if daemon)")
|
("logfile", value<std::string>()->default_value(""), "Path to logfile (stdout if not set, autodetect if daemon)")
|
||||||
("loglevel", value<std::string>()->default_value("info"), "Set the minimal level of log messages (debug, info, warn, error)")
|
("loglevel", value<std::string>()->default_value("info"), "Set the minimal level of log messages (debug, info, warn, error)")
|
||||||
|
("family", value<std::string>()->default_value(""), "Specify a family, router belongs to")
|
||||||
("datadir", value<std::string>()->default_value(""), "Path to storage of i2pd data (RI, keys, peer profiles, ...)")
|
("datadir", value<std::string>()->default_value(""), "Path to storage of i2pd data (RI, keys, peer profiles, ...)")
|
||||||
("host", value<std::string>()->default_value("0.0.0.0"), "External IP")
|
("host", value<std::string>()->default_value("0.0.0.0"), "External IP")
|
||||||
("port", value<uint16_t>()->default_value(0), "Port to listen for incoming connections (default: auto)")
|
("port", value<uint16_t>()->default_value(0), "Port to listen for incoming connections (default: auto)")
|
||||||
|
@ -132,6 +132,11 @@ namespace i2p
|
|||||||
i2p::context.SetLowBandwidth ();
|
i2p::context.SetLowBandwidth ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string family; i2p::config::GetOption("family", family);
|
||||||
|
i2p::context.SetFamily (family);
|
||||||
|
if (family.length () > 0)
|
||||||
|
LogPrint(eLogInfo, "Daemon: family set to ", family);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
99
Family.cpp
99
Family.cpp
@ -1,7 +1,9 @@
|
|||||||
|
#include <string.h>
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include <openssl/evp.h>
|
#include <openssl/evp.h>
|
||||||
#include <openssl/ssl.h>
|
#include <openssl/ssl.h>
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
|
#include "Crypto.h"
|
||||||
#include "Family.h"
|
#include "Family.h"
|
||||||
|
|
||||||
namespace i2p
|
namespace i2p
|
||||||
@ -24,12 +26,19 @@ namespace data
|
|||||||
{
|
{
|
||||||
SSL * ssl = SSL_new (ctx);
|
SSL * ssl = SSL_new (ctx);
|
||||||
X509 * cert = SSL_get_certificate (ssl);
|
X509 * cert = SSL_get_certificate (ssl);
|
||||||
// verify
|
|
||||||
if (cert)
|
if (cert)
|
||||||
{
|
{
|
||||||
|
std::shared_ptr<i2p::crypto::Verifier> verifier;
|
||||||
// extract issuer name
|
// extract issuer name
|
||||||
char name[100];
|
char name[100];
|
||||||
X509_NAME_oneline (X509_get_issuer_name(cert), name, 100);
|
X509_NAME_oneline (X509_get_issuer_name(cert), name, 100);
|
||||||
|
char * cn = strstr (name, "CN=");
|
||||||
|
if (cn)
|
||||||
|
{
|
||||||
|
cn += 3;
|
||||||
|
char * family = strstr (cn, ".family");
|
||||||
|
if (family) family[0] = 0;
|
||||||
|
}
|
||||||
auto pkey = X509_get_pubkey (cert);
|
auto pkey = X509_get_pubkey (cert);
|
||||||
int keyType = EVP_PKEY_type(pkey->type);
|
int keyType = EVP_PKEY_type(pkey->type);
|
||||||
switch (keyType)
|
switch (keyType)
|
||||||
@ -39,13 +48,37 @@ namespace data
|
|||||||
break;
|
break;
|
||||||
case EVP_PKEY_EC:
|
case EVP_PKEY_EC:
|
||||||
{
|
{
|
||||||
//EC_KEY * ecKey = EVP_PKEY_get0_EC_KEY (pkey);
|
EC_KEY * ecKey = EVP_PKEY_get1_EC_KEY (pkey);
|
||||||
|
if (ecKey)
|
||||||
|
{
|
||||||
|
auto group = EC_KEY_get0_group (ecKey);
|
||||||
|
if (group)
|
||||||
|
{
|
||||||
|
int curve = EC_GROUP_get_curve_name (group);
|
||||||
|
if (curve == NID_X9_62_prime256v1)
|
||||||
|
{
|
||||||
|
uint8_t signingKey[64];
|
||||||
|
BIGNUM * x = BN_new(), * y = BN_new();
|
||||||
|
EC_POINT_get_affine_coordinates_GFp (group,
|
||||||
|
EC_KEY_get0_public_key (ecKey), x, y, NULL);
|
||||||
|
i2p::crypto::bn2buf (x, signingKey, 32);
|
||||||
|
i2p::crypto::bn2buf (y, signingKey + 32, 32);
|
||||||
|
BN_free (x); BN_free (y);
|
||||||
|
verifier = std::make_shared<i2p::crypto::ECDSAP256Verifier>(signingKey);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
LogPrint (eLogWarning, "Family: elliptic curve ", curve, " is not supported");
|
||||||
|
}
|
||||||
|
EC_KEY_free (ecKey);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
LogPrint (eLogWarning, "Family: Certificate key type ", keyType, " is not supported");
|
LogPrint (eLogWarning, "Family: Certificate key type ", keyType, " is not supported");
|
||||||
}
|
}
|
||||||
EVP_PKEY_free (pkey);
|
EVP_PKEY_free (pkey);
|
||||||
|
if (verifier && cn)
|
||||||
|
m_SigningKeys[cn] = verifier;
|
||||||
}
|
}
|
||||||
SSL_free (ssl);
|
SSL_free (ssl);
|
||||||
}
|
}
|
||||||
@ -72,6 +105,68 @@ namespace data
|
|||||||
if (numCertificates > 0)
|
if (numCertificates > 0)
|
||||||
LogPrint (eLogInfo, "Family: ", numCertificates, " certificates loaded");
|
LogPrint (eLogInfo, "Family: ", numCertificates, " certificates loaded");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Families::VerifyFamily (const std::string& family, const IdentHash& ident,
|
||||||
|
const char * signature, const char * key)
|
||||||
|
{
|
||||||
|
uint8_t buf[50], signatureBuf[64];
|
||||||
|
size_t len = family.length (), signatureLen = strlen (signature);
|
||||||
|
memcpy (buf, family.c_str (), len);
|
||||||
|
memcpy (buf + len, (const uint8_t *)ident, 32);
|
||||||
|
len += 32;
|
||||||
|
Base64ToByteStream (signature, signatureLen, signatureBuf, 64);
|
||||||
|
auto it = m_SigningKeys.find (family);
|
||||||
|
if (it != m_SigningKeys.end ())
|
||||||
|
return it->second->Verify (buf, len, signatureBuf);
|
||||||
|
// TODO: process key
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string CreateFamilySignature (const std::string& family, const IdentHash& ident)
|
||||||
|
{
|
||||||
|
std::string sig;
|
||||||
|
auto filename = i2p::util::filesystem::GetDefaultDataDir() / "family" / (family + ".key");
|
||||||
|
SSL_CTX * ctx = SSL_CTX_new (TLSv1_method ());
|
||||||
|
int ret = SSL_CTX_use_PrivateKey_file (ctx, filename.string ().c_str (), SSL_FILETYPE_PEM);
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
SSL * ssl = SSL_new (ctx);
|
||||||
|
EVP_PKEY * pkey = SSL_get_privatekey (ssl);
|
||||||
|
EC_KEY * ecKey = EVP_PKEY_get1_EC_KEY (pkey);
|
||||||
|
if (ecKey)
|
||||||
|
{
|
||||||
|
auto group = EC_KEY_get0_group (ecKey);
|
||||||
|
if (group)
|
||||||
|
{
|
||||||
|
int curve = EC_GROUP_get_curve_name (group);
|
||||||
|
if (curve == NID_X9_62_prime256v1)
|
||||||
|
{
|
||||||
|
uint8_t signingPrivateKey[32], buf[50], signature[64];
|
||||||
|
i2p::crypto::bn2buf (EC_KEY_get0_private_key (ecKey), signingPrivateKey, 32);
|
||||||
|
i2p::crypto::ECDSAP256Signer signer (signingPrivateKey);
|
||||||
|
size_t len = family.length ();
|
||||||
|
memcpy (buf, family.c_str (), len);
|
||||||
|
memcpy (buf + len, (const uint8_t *)ident, 32);
|
||||||
|
len += 32;
|
||||||
|
signer.Sign (buf, len, signature);
|
||||||
|
len = Base64EncodingBufferSize (64);
|
||||||
|
char * b64 = new char[len+1];
|
||||||
|
len = ByteStreamToBase64 (signature, 64, b64, len);
|
||||||
|
b64[len] = 0;
|
||||||
|
sig = b64;
|
||||||
|
delete[] b64;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
LogPrint (eLogWarning, "Family: elliptic curve ", curve, " is not supported");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SSL_free (ssl);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
LogPrint (eLogError, "Family: Can't open keys file ", filename.string ());
|
||||||
|
SSL_CTX_free (ctx);
|
||||||
|
return sig;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
8
Family.h
8
Family.h
@ -1,10 +1,11 @@
|
|||||||
#ifndef FAMILY_H__
|
#ifndef FAMILY_H__
|
||||||
#define FAMILY_H_
|
#define FAMILY_H__
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include "Signature.h"
|
#include "Signature.h"
|
||||||
|
#include "Identity.h"
|
||||||
|
|
||||||
namespace i2p
|
namespace i2p
|
||||||
{
|
{
|
||||||
@ -17,6 +18,8 @@ namespace data
|
|||||||
Families ();
|
Families ();
|
||||||
~Families ();
|
~Families ();
|
||||||
void LoadCertificates ();
|
void LoadCertificates ();
|
||||||
|
bool VerifyFamily (const std::string& family, const IdentHash& ident,
|
||||||
|
const char * signature, const char * key = nullptr);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -26,6 +29,9 @@ namespace data
|
|||||||
|
|
||||||
std::map<std::string, std::shared_ptr<i2p::crypto::Verifier> > m_SigningKeys;
|
std::map<std::string, std::shared_ptr<i2p::crypto::Verifier> > m_SigningKeys;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
std::string CreateFamilySignature (const std::string& family, const IdentHash& ident);
|
||||||
|
// return base64 signature of empty string in case of failure
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
1
NetDb.h
1
NetDb.h
@ -62,6 +62,7 @@ namespace data
|
|||||||
void PostI2NPMsg (std::shared_ptr<const I2NPMessage> msg);
|
void PostI2NPMsg (std::shared_ptr<const I2NPMessage> msg);
|
||||||
|
|
||||||
void Reseed ();
|
void Reseed ();
|
||||||
|
Families& GetFamilies () { return m_Families; };
|
||||||
|
|
||||||
// for web interface
|
// for web interface
|
||||||
int GetNumRouters () const { return m_RouterInfos.size (); };
|
int GetNumRouters () const { return m_RouterInfos.size (); };
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
|
#include "Family.h"
|
||||||
#include "RouterContext.h"
|
#include "RouterContext.h"
|
||||||
|
|
||||||
namespace i2p
|
namespace i2p
|
||||||
@ -141,12 +142,29 @@ namespace i2p
|
|||||||
{
|
{
|
||||||
m_RouterInfo.SetCaps (m_RouterInfo.GetCaps () & ~i2p::data::RouterInfo::eFloodfill);
|
m_RouterInfo.SetCaps (m_RouterInfo.GetCaps () & ~i2p::data::RouterInfo::eFloodfill);
|
||||||
// we don't publish number of routers and leaseset for non-floodfill
|
// we don't publish number of routers and leaseset for non-floodfill
|
||||||
m_RouterInfo.DeleteProperty (ROUTER_INFO_PROPERTY_LEASESETS);
|
m_RouterInfo.DeleteProperty (i2p::data::ROUTER_INFO_PROPERTY_LEASESETS);
|
||||||
m_RouterInfo.DeleteProperty (ROUTER_INFO_PROPERTY_ROUTERS);
|
m_RouterInfo.DeleteProperty (i2p::data::ROUTER_INFO_PROPERTY_ROUTERS);
|
||||||
}
|
}
|
||||||
UpdateRouterInfo ();
|
UpdateRouterInfo ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RouterContext::SetFamily (const std::string& family)
|
||||||
|
{
|
||||||
|
std::string signature;
|
||||||
|
if (family.length () > 0)
|
||||||
|
signature = i2p::data::CreateFamilySignature (family, GetIdentHash ());
|
||||||
|
if (signature.length () > 0)
|
||||||
|
{
|
||||||
|
m_RouterInfo.SetProperty (i2p::data::ROUTER_INFO_PROPERTY_FAMILY, family);
|
||||||
|
m_RouterInfo.SetProperty (i2p::data::ROUTER_INFO_PROPERTY_FAMILY_SIG, signature);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_RouterInfo.DeleteProperty (i2p::data::ROUTER_INFO_PROPERTY_FAMILY);
|
||||||
|
m_RouterInfo.DeleteProperty (i2p::data::ROUTER_INFO_PROPERTY_FAMILY_SIG);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void RouterContext::SetHighBandwidth ()
|
void RouterContext::SetHighBandwidth ()
|
||||||
{
|
{
|
||||||
if (!m_RouterInfo.IsHighBandwidth () || m_RouterInfo.IsExtraBandwidth ())
|
if (!m_RouterInfo.IsHighBandwidth () || m_RouterInfo.IsExtraBandwidth ())
|
||||||
@ -284,8 +302,8 @@ namespace i2p
|
|||||||
if (m_IsFloodfill)
|
if (m_IsFloodfill)
|
||||||
{
|
{
|
||||||
// update routers and leasesets
|
// update routers and leasesets
|
||||||
m_RouterInfo.SetProperty (ROUTER_INFO_PROPERTY_LEASESETS, boost::lexical_cast<std::string>(i2p::data::netdb.GetNumLeaseSets ()));
|
m_RouterInfo.SetProperty (i2p::data::ROUTER_INFO_PROPERTY_LEASESETS, boost::lexical_cast<std::string>(i2p::data::netdb.GetNumLeaseSets ()));
|
||||||
m_RouterInfo.SetProperty (ROUTER_INFO_PROPERTY_ROUTERS, boost::lexical_cast<std::string>(i2p::data::netdb.GetNumRouters ()));
|
m_RouterInfo.SetProperty (i2p::data::ROUTER_INFO_PROPERTY_ROUTERS, boost::lexical_cast<std::string>(i2p::data::netdb.GetNumRouters ()));
|
||||||
UpdateRouterInfo ();
|
UpdateRouterInfo ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,9 +16,6 @@ namespace i2p
|
|||||||
const char ROUTER_KEYS[] = "router.keys";
|
const char ROUTER_KEYS[] = "router.keys";
|
||||||
const int ROUTER_INFO_UPDATE_INTERVAL = 1800; // 30 minutes
|
const int ROUTER_INFO_UPDATE_INTERVAL = 1800; // 30 minutes
|
||||||
|
|
||||||
const char ROUTER_INFO_PROPERTY_LEASESETS[] = "netdb.knownLeaseSets";
|
|
||||||
const char ROUTER_INFO_PROPERTY_ROUTERS[] = "netdb.knownRouters";
|
|
||||||
|
|
||||||
enum RouterStatus
|
enum RouterStatus
|
||||||
{
|
{
|
||||||
eRouterStatusOK = 0,
|
eRouterStatusOK = 0,
|
||||||
@ -60,6 +57,7 @@ namespace i2p
|
|||||||
void SetReachable ();
|
void SetReachable ();
|
||||||
bool IsFloodfill () const { return m_IsFloodfill; };
|
bool IsFloodfill () const { return m_IsFloodfill; };
|
||||||
void SetFloodfill (bool floodfill);
|
void SetFloodfill (bool floodfill);
|
||||||
|
void SetFamily (const std::string& family);
|
||||||
void SetHighBandwidth ();
|
void SetHighBandwidth ();
|
||||||
void SetLowBandwidth ();
|
void SetLowBandwidth ();
|
||||||
void SetExtraBandwidth ();
|
void SetExtraBandwidth ();
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include "Base.h"
|
#include "Base.h"
|
||||||
#include "Timestamp.h"
|
#include "Timestamp.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
|
#include "NetDb.h"
|
||||||
#include "RouterInfo.h"
|
#include "RouterInfo.h"
|
||||||
|
|
||||||
namespace i2p
|
namespace i2p
|
||||||
@ -262,11 +263,26 @@ namespace data
|
|||||||
if (!strcmp (key, "caps"))
|
if (!strcmp (key, "caps"))
|
||||||
ExtractCaps (value);
|
ExtractCaps (value);
|
||||||
// check netId
|
// check netId
|
||||||
if (!strcmp (key, "netId") && atoi (value) != I2PD_NET_ID)
|
else if (!strcmp (key, ROUTER_INFO_PROPERTY_NETID) && atoi (value) != I2PD_NET_ID)
|
||||||
{
|
{
|
||||||
LogPrint (eLogError, "Unexpected netid=", value);
|
LogPrint (eLogError, "Unexpected ", ROUTER_INFO_PROPERTY_NETID, "=", value);
|
||||||
m_IsUnreachable = true;
|
m_IsUnreachable = true;
|
||||||
}
|
}
|
||||||
|
// family
|
||||||
|
else if (!strcmp (key, ROUTER_INFO_PROPERTY_FAMILY))
|
||||||
|
{
|
||||||
|
m_Family = value;
|
||||||
|
boost::to_lower (m_Family);
|
||||||
|
}
|
||||||
|
else if (!strcmp (key, ROUTER_INFO_PROPERTY_FAMILY_SIG))
|
||||||
|
{
|
||||||
|
if (!netdb.GetFamilies ().VerifyFamily (m_Family, GetIdentHash (), value))
|
||||||
|
{
|
||||||
|
LogPrint (eLogWarning, "RouterInfo: family signature verification failed");
|
||||||
|
m_Family.clear ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!s) return;
|
if (!s) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,6 +14,12 @@ namespace i2p
|
|||||||
{
|
{
|
||||||
namespace data
|
namespace data
|
||||||
{
|
{
|
||||||
|
const char ROUTER_INFO_PROPERTY_LEASESETS[] = "netdb.knownLeaseSets";
|
||||||
|
const char ROUTER_INFO_PROPERTY_ROUTERS[] = "netdb.knownRouters";
|
||||||
|
const char ROUTER_INFO_PROPERTY_NETID[] = "netId";
|
||||||
|
const char ROUTER_INFO_PROPERTY_FAMILY[] = "family";
|
||||||
|
const char ROUTER_INFO_PROPERTY_FAMILY_SIG[] = "family.sig";
|
||||||
|
|
||||||
const char CAPS_FLAG_FLOODFILL = 'f';
|
const char CAPS_FLAG_FLOODFILL = 'f';
|
||||||
const char CAPS_FLAG_HIDDEN = 'H';
|
const char CAPS_FLAG_HIDDEN = 'H';
|
||||||
const char CAPS_FLAG_REACHABLE = 'R';
|
const char CAPS_FLAG_REACHABLE = 'R';
|
||||||
@ -180,7 +186,7 @@ namespace data
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
std::string m_FullPath;
|
std::string m_FullPath, m_Family;
|
||||||
std::shared_ptr<const IdentityEx> m_RouterIdentity;
|
std::shared_ptr<const IdentityEx> m_RouterIdentity;
|
||||||
uint8_t * m_Buffer;
|
uint8_t * m_Buffer;
|
||||||
size_t m_BufferLen;
|
size_t m_BufferLen;
|
||||||
|
13
contrib/certificates/family/i2pd-dev.crt
Normal file
13
contrib/certificates/family/i2pd-dev.crt
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIB6TCCAY+gAwIBAgIJAI7G9MXxh7OjMAoGCCqGSM49BAMCMHoxCzAJBgNVBAYT
|
||||||
|
AlhYMQswCQYDVQQIDAJYWDELMAkGA1UEBwwCWFgxHjAcBgNVBAoMFUkyUCBBbm9u
|
||||||
|
eW1vdXMgTmV0d29yazEPMA0GA1UECwwGZmFtaWx5MSAwHgYDVQQDDBdpMnBkLWRl
|
||||||
|
di5mYW1pbHkuaTJwLm5ldDAeFw0xNjAyMjAxNDE2MzhaFw0yNjAyMTcxNDE2Mzha
|
||||||
|
MHoxCzAJBgNVBAYTAlhYMQswCQYDVQQIDAJYWDELMAkGA1UEBwwCWFgxHjAcBgNV
|
||||||
|
BAoMFUkyUCBBbm9ueW1vdXMgTmV0d29yazEPMA0GA1UECwwGZmFtaWx5MSAwHgYD
|
||||||
|
VQQDDBdpMnBkLWRldi5mYW1pbHkuaTJwLm5ldDBZMBMGByqGSM49AgEGCCqGSM49
|
||||||
|
AwEHA0IABMlWL3loKVOfsA8Rm91QR53Il69mQiaB7n3rUhfPkJb9MYc1S4198azE
|
||||||
|
iSnNZSXicKDPIifaCgvONmbACzElHc8wCgYIKoZIzj0EAwIDSAAwRQIgYWmSFuai
|
||||||
|
TJvVrlB5RlbiiNFCEootjWP8BFM3t/yFeaQCIQDkg4xcQIRGTHhjrCsxmlz9KcRF
|
||||||
|
G+eIF+ATfI93nPseLw==
|
||||||
|
-----END CERTIFICATE-----
|
@ -21,6 +21,7 @@ Command line options
|
|||||||
* --notransit - Router will not accept transit tunnels at startup
|
* --notransit - Router will not accept transit tunnels at startup
|
||||||
* --floodfill - Router will be floodfill
|
* --floodfill - Router will be floodfill
|
||||||
* --bandwidth= - L if bandwidth is limited to 32Kbs/sec, O - to 256Kbs/sec, P - unlimited
|
* --bandwidth= - L if bandwidth is limited to 32Kbs/sec, O - to 256Kbs/sec, P - unlimited
|
||||||
|
* --family= - Name of a family, router belongs to
|
||||||
* --svcctl= - Windows service management (--svcctl="install" or --svcctl="remove")
|
* --svcctl= - Windows service management (--svcctl="install" or --svcctl="remove")
|
||||||
|
|
||||||
* --http.address= - The address to listen on (HTTP server)
|
* --http.address= - The address to listen on (HTTP server)
|
||||||
|
32
docs/family.md
Normal file
32
docs/family.md
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
Family configuration
|
||||||
|
====================
|
||||||
|
|
||||||
|
Your might want to specify a family, your router belongs to.
|
||||||
|
There are two possibilities: create new family or joing to existing.
|
||||||
|
|
||||||
|
New family
|
||||||
|
-----------
|
||||||
|
You must create family self-signed certificate and key.
|
||||||
|
The only key type supposted is prime256v1.
|
||||||
|
Use the following list of commands:
|
||||||
|
openssl ecparam -name prime256v1 -genkey -out <your family name>.key
|
||||||
|
openssl req -new -key <your family name>.key -out <your family name>.csr
|
||||||
|
touch v3.ext
|
||||||
|
openssl x509 -req -days 3650 -in <your family name>.csr -signkey <your family name>.key -out <your family name>.crt -extfile v3.ext
|
||||||
|
|
||||||
|
specify <your family name>.family.i2p.net for CN.
|
||||||
|
|
||||||
|
Once you are done with it place <your family name>.key and <your family name>.crt to <ip2d data>/family folder (for exmple ~/.i2pd/family).
|
||||||
|
You should provide these two files to other members joining your family.
|
||||||
|
If you want to register you family and let I2P network recorgnize it, create pull request for you .crt file into contrib/certificate/family.
|
||||||
|
It will appear in i2pd and I2P next releases packages. Don't place .key file, it must be shared betwwen you family members only.
|
||||||
|
|
||||||
|
Join existing family
|
||||||
|
--------------------
|
||||||
|
Once you and that family agree to do it, they must give you .key and .crt file and you must place to <ip2d data>/family folder.
|
||||||
|
|
||||||
|
Publish your family
|
||||||
|
------------------
|
||||||
|
Run i2pd with parameter 'family=<your family name>', make sure you have <your family name>.key and <your family name>.crt in your 'family' folder.
|
||||||
|
If everything is set properly, you router.info will contain two new fields: 'family' and 'family.sig'.
|
||||||
|
|
Loading…
Reference in New Issue
Block a user