Bitcoin Forum

Bitcoin => Development & Technical Discussion => Topic started by: Hal on January 22, 2011, 08:26:13 PM



Title: Shy client patch
Post by: Hal on January 22, 2011, 08:26:13 PM
I made a patch to make the client "shy". On incoming connections, it won't send a version message until it receives one. This can help make port scanning identification harder.

Code:
diff --git a/main.cpp b/main.cpp
index b7dfd9f..cb4fad6 100644
--- a/main.cpp
+++ b/main.cpp
@@ -2290,6 +2290,10 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
             return true;
         }
 
+        // Be shy and don't send version until we hear
+        if (pfrom->fInbound)
+            pfrom->PushVersion();
+
         pfrom->fClient = !(pfrom->nServices & NODE_NETWORK);
 
         AddTimeData(pfrom->addr.ip, nTime);
diff --git a/net.h b/net.h
index f070816..12e415b 100644
--- a/net.h
+++ b/net.h
@@ -571,14 +571,9 @@ public:
         fGetAddr = false;
         vfSubscribe.assign(256, false);
 
-        // Push a version message
-        /// when NTP implemented, change to just nTime = GetAdjustedTime()
-        int64 nTime = (fInbound ? GetAdjustedTime() : GetTime());
-        CAddress addrYou = (fUseProxy ? CAddress("0.0.0.0") : addr);
-        CAddress addrMe = (fUseProxy ? CAddress("0.0.0.0") : addrLocalHost);
-        RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
-        PushMessage("version", VERSION, nLocalServices, nTime, addrYou, addrMe,
-                    nLocalHostNonce, string(pszSubVer), nBestHeight);
+        // Be shy and don't send version until we hear
+        if (!fInbound)
+            PushVersion();
     }
 
     ~CNode()
@@ -735,6 +730,19 @@ public:
 
 
 
+    void PushVersion()
+    {
+        /// when NTP implemented, change to just nTime = GetAdjustedTime()
+        int64 nTime = (fInbound ? GetAdjustedTime() : GetTime());
+        CAddress addrYou = (fUseProxy ? CAddress("0.0.0.0") : addr);
+        CAddress addrMe = (fUseProxy ? CAddress("0.0.0.0") : addrLocalHost);
+        RAND_bytes((unsigned char*)&nLocalHostNonce, sizeof(nLocalHostNonce));
+        PushMessage("version", VERSION, nLocalServices, nTime, addrYou, addrMe,
+                nLocalHostNonce, string(pszSubVer), nBestHeight);
+    }
+
+
+
 
     void PushMessage(const char* pszCommand)
     {

I noticed that the variable nLocalHostNonce is being used to detect connecting to ourself. But I'm not sure it is working, because we will (re-)randomize nLocalHostNonce on incoming connection before we compare with incoming version message. So even if we are connecting to ourself, nLocalHostNonce won't match. The shy patch should fix this.


Title: Re: Shy client patch
Post by: Hal on January 22, 2011, 08:36:20 PM
Meant to add, seems to work ok with other clients, I've got 30+ connections. It did turn my dot red on the bitcoin world map, I guess that scanner relies on noisy nodes.


Title: Re: Shy client patch
Post by: bitcoinex on January 23, 2011, 01:44:30 PM
How does it complicate the scan?


Title: Re: Shy client patch
Post by: Hal on January 23, 2011, 06:42:21 PM
Now, when you connect to the port, the client spews out a version message, which reveals its identity. With the shy patch, there's no response. It could be ssh, could be torrent, could be bitcoin, could be http, could be anything. The scanner would have to try to send crafted packets for each of dozens or hundreds of known protocols, to try to elicit a response.

Of course while we're all on 8333, it's pretty obvious what's what. But presumably that will change eventually.


Title: Re: Shy client patch
Post by: Gavin Andresen on January 30, 2011, 06:03:25 PM
This seems like a good idea; maybe not for the next (0.3.20) release, but 0.3.21.



Title: Re: Shy client patch
Post by: zipslack on January 30, 2011, 07:06:14 PM
This seems like a good idea

I agree.


Title: Re: Shy client patch
Post by: jgarzik on January 30, 2011, 10:51:20 PM
I made a patch to make the client "shy". On incoming connections, it won't send a version message until it receives one. This can help make port scanning identification harder.

FWIW, this can also be used in conjunction with TCP_DEFER_ACCEPT socket option, which does not indicate a socket is available to accept(2) until data arrives.


Title: Re: Shy client patch
Post by: bitcoinex on January 31, 2011, 12:30:07 AM
I made a patch to make the client "shy". On incoming connections, it won't send a version message until it receives one. This can help make port scanning identification harder.

FWIW, this can also be used in conjunction with TCP_DEFER_ACCEPT socket option, which does not indicate a socket is available to accept(2) until data arrives.

Similar features have also FreeBSD (accf_data) and Win32 (AcceptEx, FD_ACCEPT).


Title: Re: Shy client patch
Post by: Gavin Andresen on March 05, 2011, 10:16:13 PM
Pull request:
  https://github.com/bitcoin/bitcoin/pull/101