newServer2 {address="2620:0:ccd::2", qps=10}
newServer("192.168.1.2")
-$ dnsdist --local=0.0.0.0:5200
+$ dnsdist --local=0.0.0.0:5200 --daemon=no
Marking downstream [2001:4860:4860::8888]:53 as 'up'
Marking downstream [2001:4860:4860::8844]:53 as 'up'
Marking downstream [2620:0:ccc::2]:53 as 'up'
Incidentally, this is similar to setting: `setServerPolicy(roundrobin)`
which uses the C++ based roundrobin policy.
+Running it for real
+-------------------
+First run on the command line, and generate a key:
+
+```
+# dnsdist --daemon-no
+> makeKey()
+setKey("sepuCcHcQnSAZgNbNPCCpDWbujZ5esZJmrt/wh6ldkQ=")
+```
+
+Now add this setKey line to `dnsdistconf.lua`, followed by:
+
+```
+# dnsdist
+# dnsdist --client
+>
+```
return 0;
}
-struct {
- string pub;
- string sec;
-} g_accessKeys, g_serverKeys;
+string g_key;
void controlClientThread(int fd, ComboAddress client)
try
{
+ SodiumNonce theirs;
+ readn2(fd, (char*)theirs.value, sizeof(theirs.value));
+ SodiumNonce ours;
+ ours.init();
+ writen2(fd, (char*)ours.value, sizeof(ours.value));
+
for(;;) {
uint16_t len;
- getMsgLen(fd, &len);
+ if(!getMsgLen(fd, &len))
+ break;
char msg[len];
readn2(fd, msg, len);
string line(msg, len);
- line = sodDecrypt(line, g_accessKeys.pub, g_serverKeys.sec);
+ line = sodDecryptSym(line, g_key, theirs);
// cerr<<"Have decrypted line: "<<line<<endl;
string response;
try {
catch(std::exception& e) {
cerr<<"Error: "<<e.what()<<endl;
}
- response = sodEncrypt(response, g_serverKeys.sec, g_accessKeys.pub);
+ response = sodEncryptSym(response, g_key, ours);
putMsgLen(fd, response.length());
writen2(fd, response.c_str(), (uint16_t)response.length());
}
g_abuseDSS=dss;
});
- g_lua.writeFunction("newKeypair", newKeypair);
- g_lua.writeFunction("makeKeys", []() {
- string server(newKeypair()), client(newKeypair());
- return "serverKeys("+server+")\naccessKeys("+client+")";
+ g_lua.writeFunction("makeKey", []() {
+ return "setKey("+newKey()+")";
});
- g_lua.writeFunction("accessKeys", [](std::unordered_map<int, std::string> params) {
- if(B64Decode(params[1], g_accessKeys.pub))
- throw std::runtime_error("Unable to decode "+params[1]+" as Base64");
- if(B64Decode(params[2], g_accessKeys.sec))
- throw std::runtime_error("Unable to decode "+params[2]+" as Base64");
- });
-
- g_lua.writeFunction("serverKeys", [](std::unordered_map<int, std::string> params) {
- if(B64Decode(params[1], g_serverKeys.pub))
- throw std::runtime_error("Unable to decode "+params[1]+" as Base64");
- if(B64Decode(params[2], g_serverKeys.sec))
- throw std::runtime_error("Unable to decode "+params[2]+" as Base64");
+ g_lua.writeFunction("setKey", [](const std::string& key) {
+ if(B64Decode(key, g_key))
+ throw std::runtime_error("Unable to decode "+key+" as Base64");
});
g_lua.writeFunction("testCrypto", [](string testmsg)
{
- string encrypted = sodEncrypt(testmsg, g_accessKeys.sec, g_serverKeys.pub);
- string decrypted = sodDecrypt(encrypted, g_accessKeys.pub, g_serverKeys.sec);
+ SodiumNonce sn, sn2;
+ sn.init();
+ sn2=sn;
+ string encrypted = sodEncryptSym(testmsg, g_key, sn);
+ string decrypted = sodDecryptSym(encrypted, g_key, sn2);
if(testmsg == decrypted)
cerr<<"Everything is ok!"<<endl;
int fd=socket(server.sin4.sin_family, SOCK_STREAM, 0);
SConnect(fd, server);
+ SodiumNonce theirs, ours;
+ ours.init();
+
+ writen2(fd, (const char*)ours.value, sizeof(ours.value));
+ readn2(fd, (char*)theirs.value, sizeof(theirs.value));
+
set<string> dupper;
{
ifstream history(".history");
break;
string response;
- string msg=sodEncrypt(line, g_accessKeys.sec, g_serverKeys.pub);
+ string msg=sodEncryptSym(line, g_key, ours);
putMsgLen(fd, msg.length());
writen2(fd, msg);
uint16_t len;
char resp[len];
readn2(fd, resp, len);
msg.assign(resp, len);
- msg=sodDecrypt(msg, g_serverKeys.pub, g_accessKeys.sec);
+ msg=sodDecryptSym(msg, g_key, theirs);
cout<<msg<<endl;
}
-
-
}
void doConsole()
}
catch(std::exception& e) {
cerr<<"Error: "<<e.what()<<endl;
- }
-
+ }
}
}
vinfolog("Running in the foreground");
}
-
setupLua(false);
if(g_vm.count("remotes")) {
for(const auto& address : g_vm["remotes"].as<vector<string>>()) {
}
}
-
-
for(auto& dss : g_dstates) {
if(dss->availability==DownstreamState::Availability::Auto) {
bool newState=upCheck(dss->remote);
-serverKeys({"oYhvA4N2a+PfWJ1aBVG3OFD/BBO/8sdkzRgGQoDxVz0=","2JjfJbIH/2g+1cIxj7IXhv4j38+rCiXbpdjtn91p/04="})
-accessKeys({"9RM9r+olHDJU+87hBXT9DCCej/DUS1XjIKWTq84AfTs=","ghv/LTqRTOgVvK8A/XEWrFks+F5fng1Wn14Xe9Rblgg="})
-
controlSocket("0.0.0.0")
+setKey("MXNeLFWHUe4363BBKrY06cAsH8NWNb+Se2eXU5+Bb74=")
-- define the good servers
newServer("8.8.8.8", 2) -- 2 qps
#include "namespaces.hh"
#include "misc.hh"
#include "base64.hh"
+#include "sodcrypto.hh"
-string newKeypair()
-{
- unsigned char alice_publickey[crypto_box_PUBLICKEYBYTES];
- unsigned char alice_secretkey[crypto_box_SECRETKEYBYTES];
- crypto_box_keypair(alice_publickey, alice_secretkey);
-
- string ret("{\"");
- ret+=Base64Encode(string((char*)alice_publickey, crypto_box_PUBLICKEYBYTES));
- ret+="\",\"";
- ret+=Base64Encode(string((char*)alice_secretkey, crypto_box_SECRETKEYBYTES));
- ret+="\"}";
- return ret;
-}
-// return: nonce + ciphertext
-
-std::string sodEncrypt(const std::string& msg, const std::string& secretSource,
- const std::string& publicDest)
+string newKey()
{
- unsigned char nonce[crypto_box_NONCEBYTES];
- unsigned char ciphertext[msg.length() + crypto_box_MACBYTES];
- randombytes_buf(nonce, sizeof nonce);
- /*
- cerr<<"Encrypt plen: "<<msg.length()<<endl;
- cerr<<"Encrypt nonce: "<<makeHexDump(string((const char*)nonce, sizeof nonce))<<endl;
- cerr<<"keylen: "<<secretSource.length()<<", "<<publicDest.length()<<endl;
- */
- crypto_box_easy(ciphertext, (const unsigned char*)msg.c_str(), msg.length(),
- nonce, (const unsigned char*)publicDest.c_str(), // bob_pub
- (const unsigned char*) secretSource.c_str()); // alice_sec
- // cerr<<"MAC: "<<makeHexDump(string((const char*)ciphertext, crypto_box_MACBYTES))<<endl;
- string ret((const char*)nonce, crypto_box_NONCEBYTES);
- ret.append((const char*)ciphertext, sizeof(ciphertext));
- return ret;
+ unsigned char key[crypto_secretbox_KEYBYTES];
+ randombytes_buf(key, sizeof key);
+ return "\""+Base64Encode(string((char*)key, sizeof key))+"\"";
}
-std::string sodDecrypt(const std::string& msg, const std::string& publicSource,
- const std::string& secretDest)
+std::string sodEncryptSym(const std::string& msg, const std::string& key, SodiumNonce& nonce)
{
- auto plen = msg.size() - crypto_box_NONCEBYTES - crypto_box_MACBYTES;
- /*
- cerr<<"Payload len: "<<plen<<endl;
- cerr<<"Nonce: "<<makeHexDump(msg.substr(0, crypto_box_NONCEBYTES))<<endl;
- cerr<<"MAC: "<<makeHexDump(msg.substr(crypto_box_NONCEBYTES, crypto_box_MACBYTES))<<endl;
- cerr<<"keylen: "<<publicSource.length()<<", "<<secretDest.length()<<endl;
- */
- unsigned char decrypted[plen];
- if (crypto_box_open_easy(decrypted, (const unsigned char*)msg.c_str() + crypto_box_NONCEBYTES, plen + crypto_box_MACBYTES, (const unsigned char*)msg.c_str(),
- (const unsigned char*)publicSource.c_str(), // alice_pub
- (const unsigned char*)secretDest.c_str()) != 0) { // bob_sec
- /* message for Bob pretending to be from Alice has been forged! */
- throw runtime_error("Could not decrypt!");
- }
+ unsigned char ciphertext[msg.length() + crypto_secretbox_MACBYTES];
+ crypto_secretbox_easy(ciphertext, (unsigned char*)msg.c_str(), msg.length(), nonce.value, (unsigned char*)key.c_str());
- return string((char*)decrypted, plen);
+ nonce.increment();
+ return string((char*)ciphertext, sizeof(ciphertext));
}
-
-void sodTest()
+std::string sodDecryptSym(const std::string& msg, const std::string& key, SodiumNonce& nonce)
{
-#define MESSAGE (const unsigned char *) "test"
-#define MESSAGE_LEN 4
-#define CIPHERTEXT_LEN (crypto_box_MACBYTES + MESSAGE_LEN)
+ unsigned char decrypted[msg.length() - crypto_secretbox_MACBYTES];
- unsigned char alice_publickey[crypto_box_PUBLICKEYBYTES];
- unsigned char alice_secretkey[crypto_box_SECRETKEYBYTES];
- crypto_box_keypair(alice_publickey, alice_secretkey);
-
-
- unsigned char bob_publickey[crypto_box_PUBLICKEYBYTES];
- unsigned char bob_secretkey[crypto_box_SECRETKEYBYTES];
- crypto_box_keypair(bob_publickey, bob_secretkey);
-
- unsigned char nonce[crypto_box_NONCEBYTES];
- unsigned char ciphertext[CIPHERTEXT_LEN];
- randombytes_buf(nonce, sizeof nonce);
- crypto_box_easy(ciphertext, MESSAGE, MESSAGE_LEN, nonce,
- bob_publickey, alice_secretkey);
-
- unsigned char decrypted[MESSAGE_LEN];
- if (crypto_box_open_easy(decrypted, ciphertext, CIPHERTEXT_LEN, nonce,
- alice_publickey, bob_secretkey) != 0) {
- /* message for Bob pretending to be from Alice has been forged! */
- cerr<<"BAD!"<<endl;
+ if (crypto_secretbox_open_easy(decrypted, (const unsigned char*)msg.c_str(),
+ msg.length(), nonce.value, (const unsigned char*)key.c_str()) != 0) {
+ throw std::runtime_error("Could not decrypt message");
}
- else
- cerr<<"Decrypted: "<<string((char*)decrypted, MESSAGE_LEN)<<endl;
+ nonce.increment();
+ return string((char*)decrypted, sizeof(decrypted));
}
+
+
#pragma once
#include <string>
+#include <stdint.h>
void sodTest();
std::string newKeypair();
-std::string sodEncrypt(const std::string& msg, const std::string& secretSource,
+std::string sodEncryptAsym(const std::string& msg, const std::string& secretSource,
const std::string& publicDest);
-std::string sodDecrypt(const std::string& msg, const std::string& publicSource,
+std::string sodDecryptAsym(const std::string& msg, const std::string& publicSource,
const std::string& secretDest);
+
+struct SodiumNonce
+{
+ void init()
+ {
+ randombytes_buf(value, sizeof value);
+ }
+
+ void increment()
+ {
+ uint64_t* p = (uint64_t*)value;
+ (*p)++;
+ }
+
+ string toString() const
+ {
+ return string((const char*)value, crypto_secretbox_NONCEBYTES);
+ }
+
+ unsigned char value[crypto_secretbox_NONCEBYTES];
+};
+
+std::string sodEncryptSym(const std::string& msg, const std::string& key, SodiumNonce&);
+std::string sodDecryptSym(const std::string& msg, const std::string& key, SodiumNonce&);
+std::string newKey();