Page 1 of 1

add obfuscate for openvpn

Posted: Mon Apr 08, 2013 4:41 am
by sadan9
China Grate Firewall can block openvpn connections.
please look this..

http://en.wikipedia.org/wiki/Great_Firewall_of_China

"Starting late 2012, GFW is able to "learn, discover and block" the encrypted communications methods used by a number of different VPN systems.China Unicom, one of the biggest telecoms providers in the country, is now killing connections where a VPN is detected, according to one company with a number of users in China."

Re: add obfuscate for openvpn

Posted: Tue Apr 09, 2013 2:32 am
by sadan9
this is a patch for openvpn 2.3.1


#cat patch.openvpn.2.3.1

--- src/openvpn/options.c.orgi 2013-04-07 14:35:14.000000000 +0800
+++ src/openvpn/options.c 2013-04-07 14:40:44.000000000 +0800
@@ -61,6 +61,9 @@
#include <ctype.h>

#include "memdbg.h"
+extern char* _socket_obfs_salt;
+extern int _socket_obfs_salt_len;
+extern int _socket_obfs_padlen;

const char title_string[] =
PACKAGE_STRING
@@ -6820,6 +6823,19 @@
options->persist_mode = 1;
}
#endif
+ else if (streq (p[0], "obfs-salt") && p[1])
+ {
+ VERIFY_PERMISSION (OPT_P_GENERAL);
+ _socket_obfs_salt = p[1];
+ _socket_obfs_salt_len = strlen(_socket_obfs_salt);
+ }
+ else if (streq (p[0], "obfs-padlen") && p[1])
+ {
+ VERIFY_PERMISSION (OPT_P_GENERAL);
+ _socket_obfs_padlen = atoi(p[1]);
+ if (_socket_obfs_padlen < 0)
+ msg(M_ERR, "--obfs-padlen must be positive");
+ }
else
{
if (file)
--- src/openvpn/socket.c.orgi 2013-04-07 14:41:25.000000000 +0800
+++ src/openvpn/socket.c 2013-04-07 14:43:55.000000000 +0800
@@ -40,6 +40,9 @@
#include "misc.h"

#include "memdbg.h"
+const char* _socket_obfs_salt = NULL;
+int _socket_obfs_salt_len = 0;
+int _socket_obfs_padlen = 0;

const int proto_overhead[] = { /* indexed by PROTO_x */
0,
@@ -52,6 +55,50 @@
IPv6_TCP_HEADER_SIZE,
};

+/**
+ * @return int The length of the random string that should be padding to the packet
+ */
+int obfs_buffer(const struct buffer* buf, const void* rand, int randlen, int maxpadlen) {
+ unsigned char md[SHA_DIGEST_LENGTH];
+ unsigned char iv[randlen + _socket_obfs_salt_len + SHA_DIGEST_LENGTH];
+ unsigned char *c;
+ int i, len, pad_len = 0;
+
+ if (maxpadlen > 255)
+ maxpadlen = 255;
+
+ /* key_1 = SHA1(rand + obfs_salt) */
+ /* pad_len = Low _rand_pad_level_ bits of (unsigned char)MD5(rand + obfs_salt)[0] */
+ memcpy(iv, rand, randlen);
+ memcpy(iv + randlen, _socket_obfs_salt, _socket_obfs_salt_len);
+
+ /* Caculate length of padding string */
+ ASSERT(SHA_DIGEST_LENGTH >= MD5_DIGEST_LENGTH);
+ MD5(iv, randlen + _socket_obfs_salt_len, md); /* SHA_DIGEST_LENGTH is bigger than MD5_DIGEST_LENGTH, it's safe here */
+ if (maxpadlen <= 0)
+ pad_len = 0;
+ else
+ pad_len = md[0] % (maxpadlen + 1);
+
+ /* Obsfucation data */
+ len = BLEN(buf);
+ SHA1(iv, randlen + _socket_obfs_salt_len, md);
+ for (i = 0, c = BPTR(buf); i < len; i++, c++)
+ {
+ *c ^= md[i % SHA_DIGEST_LENGTH];
+
+ /* Regenerate obsfuction key: key_n+1 = SHA1(key_n) */
+ if (i % SHA_DIGEST_LENGTH == SHA_DIGEST_LENGTH - 1)
+ {
+ memcpy(iv, md, SHA_DIGEST_LENGTH);
+ SHA1(iv, SHA_DIGEST_LENGTH, md);
+ }
+ }
+
+ return pad_len;
+}
+
+
/*
* Convert sockflags/getaddr_flags into getaddr_flags
*/
--- src/openvpn/socket.h.orgi 2013-04-07 14:44:10.000000000 +0800
+++ src/openvpn/socket.h 2013-04-07 14:53:29.000000000 +0800
@@ -35,6 +35,9 @@
#include "proxy.h"
#include "socks.h"
#include "misc.h"
+extern int _socket_obfs_salt_len;
+extern int _socket_obfs_padlen;
+int obfs_buffer(const struct buffer* buf, const void* rand, int randlen, int rand_pad_level);

/*
* OpenVPN's default port number as assigned by IANA.
@@ -877,28 +880,58 @@
int maxsize,
struct link_socket_actual *from)
{
+ int res;
+ struct buffer tbuf;
if (proto_is_udp(sock->info.proto)) /* unified UDPv4 and UDPv6 */
{
- int res;
-
#ifdef WIN32
res = link_socket_read_udp_win32 (sock, buf, from);
#else
res = link_socket_read_udp_posix (sock, buf, maxsize, from);
#endif
- return res;
+
}
else if (proto_is_tcp(sock->info.proto)) /* unified TCPv4 and TCPv6 */
{
/* from address was returned by accept */
addr_copy_sa(&from->dest, &sock->info.lsa->actual.dest);
- return link_socket_read_tcp (sock, buf);
+ res = link_socket_read_tcp (sock, buf);
}
else
{
ASSERT (0);
return -1; /* NOTREACHED */
}
+ /* Decode obsfucated traffic */
+ if (_socket_obfs_salt_len > 0 && BLEN(buf) > 4)
+ {
+ int r;
+ int pad_len = 0;
+
+ memcpy((void*)&r, BPTR(buf), 4);
+
+ //msg(M_DEBUG, "1, read buflen=%d", BLEN(buf));
+
+ tbuf = alloc_buf(BLEN(buf) - 4);
+ buf_copy_range(&tbuf, 0, buf, 4, BLEN(buf) - 4);
+ pad_len = obfs_buffer(&tbuf, &r, 4, _socket_obfs_padlen);
+
+ /* Remove padding random string */
+ buf_clear(buf);
+ buf_prepend(buf, BLEN(&tbuf) - pad_len);
+ buf_copy_range(buf, 0, &tbuf, 0, BLEN(&tbuf) - pad_len);
+
+ //msg(M_DEBUG, "1, read buflen=%d, padlen=%d", BLEN(buf), pad_len);
+
+ free_buf(&tbuf);
+
+ res -= 4;
+ res -= pad_len;
+
+ }
+
+ return res;
+
}

/*
@@ -984,6 +1017,36 @@
struct buffer *buf,
struct link_socket_actual *to)
{
+ struct buffer tbuf;
+
+ /* Obsfucate traffic */
+ if (_socket_obfs_salt_len > 0)
+ {
+ int pad_len, i;
+ int r = rand();
+
+ //msg(M_DEBUG, "1, write buflen=%d", BLEN(buf));
+
+ pad_len = obfs_buffer(buf, &r, sizeof(r), _socket_obfs_padlen);
+
+ tbuf = alloc_buf(BLEN(buf) + 4 + pad_len);
+ buf_write(&tbuf, (void*)&r, 4);
+ buf_copy_range(&tbuf, 4, buf, 0, BLEN(buf));
+ for (i = 0; i < pad_len; i++)
+ {
+ if (unlikely(i % 4 == 0))
+ r = rand();
+
+ buf_write(&tbuf, (void*)&r + i % 4, 1);
+ }
+
+ buf_copy_range(buf, 0, &tbuf, 0, BLEN(&tbuf));
+
+ //msg(M_DEBUG, "2, write buflen=%d", BLEN(buf));
+
+ free_buf(&tbuf);
+ }
+
if (proto_is_udp(sock->info.proto)) /* unified UDPv4 and UDPv6 */
{
return link_socket_write_udp (sock, buf, to);

Re: add obfuscate for openvpn

Posted: Tue Jun 11, 2013 3:16 pm
by cnzhangquan
when will we see this patch included in the official release package ?

Re: add obfuscate for openvpn

Posted: Sat Jun 29, 2013 3:08 am
by rollingscissors
I will patch and compile these goodies today.

How do I use the new function? Will this need a new line in the config file for a key, or does it automatically insert n number of random bits to a packet to confuse the DPI filters?

The GFW is really hammering OpenVPN right now, and this software really needs to regain the upper hand in this battle.

Re: add obfuscate for openvpn

Posted: Sun Jun 30, 2013 3:32 am
by sadan9
rollingscissors wrote:I will patch and compile these goodies today.

How do I use the new function? Will this need a new line in the config file for a key, or does it automatically insert n number of random bits to a packet to confuse the DPI filters?

The GFW is really hammering OpenVPN right now, and this software really needs to regain the upper hand in this battle.
you must add new lines in config file.
========================================
obfs-salt [osfb Key] #this must the same in the server and client.
obfs-padlen [Number] #this is optional. it will add random bytes data in the end of package

Re: add obfuscate for openvpn

Posted: Fri Jul 19, 2013 10:01 am
by vipp
Awesome work! Is it possible to bring this into the branch of openvpn source code?

Re: add obfuscate for openvpn

Posted: Wed Aug 21, 2013 2:32 am
by vipp
Nobody likes this feature?

Re: add obfuscate for openvpn

Posted: Wed Sep 04, 2013 4:37 pm
by pahanedition
This patch is suitable for version openvpn 2.3.2?

Re: add obfuscate for openvpn

Posted: Fri Sep 06, 2013 7:06 am
by pahanedition
Help please! I can not build the patched openvpn for Windows.
Build for Linux was successful.
But when building for Windows error occurs:

Code: Select all

i686-w64-mingw32-gcc -DHAVE_CONFIG_H -I. -I../.. -I../../include -I../../src/compat  -DWIN32_LEAN_AND_MEAN -DNTDDI_VERSION=NTDDI_WINXP -D_WIN32_WINNT=_WIN32_WINNT_WINXP -I/root/openvpn-build-master/generic/image-win32/openvpn/include -I/root/openvpn-build-master/generic/image-win32/openvpn/include -I/root/openvpn-build-master/generic/image-win32/openvpn/include -I/root/openvpn-build-master/generic/image-win32/openvpn/include -I/root/openvpn-build-master/generic/image-win32/openvpn/include -municode -UUNICODE  -MT socks.o -MD -MP -MF .deps/socks.Tpo -c -o socks.o socks.c
In file included from options.h:38:0,
                 from openvpn.h:29,
                 from init.h:28,
                 from sig.c:36:
socket.h: In function ‘link_socket_set_tos’:
socket.h:1089:5: warning: passing argument 4 of ‘setsockopt’ from incompatible pointer type [enabled by default]
/usr/lib/gcc/i686-w64-mingw32/4.6/../../../../i686-w64-mingw32/include/winsock2.h:1016:34: note: expected ‘const char *’ but argument is of type ‘int *’
In file included from socket.c:33:0:
socket.h: In function ‘link_socket_set_tos’:
socket.h:1089:5: warning: passing argument 4 of ‘setsockopt’ from incompatible pointer type [enabled by default]
/usr/lib/gcc/i686-w64-mingw32/4.6/../../../../i686-w64-mingw32/include/winsock2.h:1016:34: note: expected ‘const char *’ but argument is of type ‘int *’
socket.c: In function ‘obfs_buffer’:
socket.c:63:19: error: ‘MD5_DIGEST_LENGTH’ undeclared (first use in this function)
socket.c:63:19: note: each undeclared identifier is reported only once for each function it appears in
make[4]: *** [socket.o] Error 1
make[4]: *** Waiting for unfinished jobs....
mv -f .deps/sig.Tpo .deps/sig.Po
In file included from socks.c:46:0:
socket.h: In function ‘link_socket_set_tos’:
socket.h:1089:5: warning: passing argument 4 of ‘setsockopt’ from incompatible pointer type [enabled by default]
/usr/lib/gcc/i686-w64-mingw32/4.6/../../../../i686-w64-mingw32/include/winsock2.h:1016:34: note: expected ‘const char *’ but argument is of type ‘int *’
mv -f .deps/socks.Tpo .deps/socks.Po
make[4]: Leaving directory `/root/openvpn-build-master/generic/tmp/openvpn-2.3.1/src/openvpn'
make[3]: *** [install-recursive] Error 1
make[3]: Leaving directory `/root/openvpn-build-master/generic/tmp/openvpn-2.3.1/src'
make[2]: *** [install-recursive] Error 1
make[2]: Leaving directory `/root/openvpn-build-master/generic/tmp/openvpn-2.3.1'
make[1]: *** [install] Error 2
make[1]: Leaving directory `/root/openvpn-build-master/generic/tmp/openvpn-2.3.1'
make: *** [install-strip] Error 2
FATAL: make openvpn
How can I fix this error - socket.c:63:19: error: ‘MD5_DIGEST_LENGTH’ undeclared (first use in this function) ?

Re: add obfuscate for openvpn

Posted: Fri Jan 24, 2014 3:53 am
by rollingscissors
Here we are, more than a year after working code was written, with no obfuscation in OpenVPN. Maybe the developers don't care if OpenVPN slips into irrelevance among internet users.

Here in China, unobfuscated OpenVPN lasts about 10 or 20 minutes before the connection is detected and blocked. My Android phone's ratty L2TP/IPsec connection lasts longer, but is much weaker.

What's it going to be? Survive or fade away, OpenVPN?

Re: add obfuscate for openvpn

Posted: Sat Jan 25, 2014 3:00 am
by niels
Why would it slip into irrelevance? The world is bigger than China. Besides, people using OpenVPN in China or providing services to others in China, still have many options:
  • Patch OpenVPN themselves.
  • Use a patched version maintained by others (ArchLinux maintains a openvpn-obfs package, as do several Chinese BBS websites).
  • Hire someone to maintain a customized version. There's a ton of businesses, large and small, providing services related to open source software development.
etc..

Re: add obfuscate for openvpn

Posted: Tue Jan 28, 2014 6:09 am
by ecrist
This is not the correct method for posting a patch. Also, we really are not interested in obfuscating OpenVPN.