add obfuscate for openvpn
Moderators: TinCanTech, TinCanTech, TinCanTech, TinCanTech, TinCanTech, TinCanTech
-
- OpenVpn Newbie
- Posts: 3
- Joined: Sun Apr 07, 2013 9:25 am
add obfuscate for openvpn
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."
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."
-
- OpenVpn Newbie
- Posts: 3
- Joined: Sun Apr 07, 2013 9:25 am
Re: add obfuscate for openvpn
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);
#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);
-
- OpenVpn Newbie
- Posts: 1
- Joined: Sun Nov 04, 2012 6:58 am
Re: add obfuscate for openvpn
when will we see this patch included in the official release package ?
-
- OpenVpn Newbie
- Posts: 5
- Joined: Tue Mar 12, 2013 5:01 am
Re: add obfuscate for openvpn
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.
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.
-
- OpenVpn Newbie
- Posts: 3
- Joined: Sun Apr 07, 2013 9:25 am
Re: add obfuscate for openvpn
you must add new lines in config file.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.
========================================
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
-
- OpenVpn Newbie
- Posts: 7
- Joined: Fri Jul 19, 2013 10:00 am
Re: add obfuscate for openvpn
Awesome work! Is it possible to bring this into the branch of openvpn source code?
-
- OpenVpn Newbie
- Posts: 7
- Joined: Fri Jul 19, 2013 10:00 am
Re: add obfuscate for openvpn
Nobody likes this feature?
-
- OpenVpn Newbie
- Posts: 5
- Joined: Fri Nov 23, 2012 6:24 pm
Re: add obfuscate for openvpn
This patch is suitable for version openvpn 2.3.2?
-
- OpenVpn Newbie
- Posts: 5
- Joined: Fri Nov 23, 2012 6:24 pm
Re: add obfuscate for openvpn
Help please! I can not build the patched openvpn for Windows.
Build for Linux was successful.
But when building for Windows error occurs:
How can I fix this error - socket.c:63:19: error: ‘MD5_DIGEST_LENGTH’ undeclared (first use in this function) ?
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
-
- OpenVpn Newbie
- Posts: 5
- Joined: Tue Mar 12, 2013 5:01 am
Re: add obfuscate for openvpn
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?
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?
-
- OpenVpn Newbie
- Posts: 11
- Joined: Tue Feb 21, 2012 7:50 am
Re: add obfuscate for openvpn
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.
- ecrist
- Forum Team
- Posts: 237
- Joined: Wed Nov 26, 2008 10:33 pm
- Location: Northern Minnesota, USA
- Contact:
Re: add obfuscate for openvpn
This is not the correct method for posting a patch. Also, we really are not interested in obfuscating OpenVPN.
OpenVPN Community Administrator
IRC: #openvpn, #openvpn-devel
Co-Author of Mastering OpenVPN
Author of Troubleshooting OpenVPN
IRC: #openvpn, #openvpn-devel
Co-Author of Mastering OpenVPN
Author of Troubleshooting OpenVPN