-
-
Save greensea/4372285 to your computer and use it in GitHub Desktop.
--- openvpn-2.2.2.orig/options.c 2011-12-14 00:58:56.000000000 +0800 | |
+++ openvpn-2.2.2/options.c 2012-12-21 10:44:57.683130505 +0800 | |
@@ -54,6 +54,10 @@ | |
#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 | |
" " TARGET_ALIAS | |
@@ -6008,6 +6012,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) | |
--- openvpn-2.2.2.orig/socket.c 2011-12-14 00:58:56.000000000 +0800 | |
+++ openvpn-2.2.2/socket.c 2012-12-21 10:44:57.707131191 +0800 | |
@@ -35,6 +35,10 @@ | |
#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 */ | |
IPv4_UDP_HEADER_SIZE, | |
IPv4_TCP_HEADER_SIZE, | |
@@ -42,6 +46,49 @@ | |
IPv4_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 | |
*/ | |
--- openvpn-2.2.2.orig/socket.h 2011-12-14 00:58:56.000000000 +0800 | |
+++ openvpn-2.2.2/socket.h 2013-01-24 10:48:37.559033278 +0800 | |
@@ -36,6 +36,11 @@ | |
#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. | |
*/ | |
@@ -740,28 +745,60 @@ | |
int maxsize, | |
struct link_socket_actual *from) | |
{ | |
+ int res; | |
+ | |
+ struct buffer tbuf; | |
+ | |
+ | |
if (sock->info.proto == PROTO_UDPv4) | |
{ | |
- 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 (sock->info.proto == PROTO_TCPv4_SERVER || sock->info.proto == PROTO_TCPv4_CLIENT) | |
{ | |
/* from address was returned by accept */ | |
from->dest.sa = sock->info.lsa->actual.dest.sa; | |
- 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; | |
} | |
/* | |
@@ -846,6 +883,37 @@ | |
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 (sock->info.proto == PROTO_UDPv4) | |
{ | |
return link_socket_write_udp (sock, buf, to); |
在Visual Studio 2010里出错! m:\openvpn-build\openvpn-2.2.2\socket.h(906) : error C2036: “void ”: 未知的大
我改成 buf_write(&tbuf, (char)&r + i % 4, 1); 这样!
unsigned char iv[randlen + _socket_obfs_salt_len + SHA_DIGEST_LENGTH]; 这里还是编译不过!
socket.c(56) : error C2057: 应输入常量表达式
socket.c(56) : error C2466: 不能分配常量大小为 0 的数组
socket.c(56) : error C2133: “iv”: 未知的大小
哈哈!有人帮忙吗!
unsigned char *iv=(unsigned char * ) malloc(randlen + _socket_obfs_salt_len + SHA_DIGEST_LENGTH);
暂时改成这样! 有人知道vc10 怎样静态编译!啊!
在socket.c中加上
define MD5_DIGEST_LENGTH 16
define SHA_DIGEST_LENGTH 20
我这么编译过的
现在openvpn出2.3版了,更新很多的功能,能再搞个2.3版本的流量混淆补丁么?
最好联系一下samuli,叫他把流量混淆补丁放到官方的分支里面,要不然以后官方升级还是个麻烦事
在freebsd系统中
测试超过半个小时 发现挺稳定 继续看效果
@welkinwalker Patch for 2.3.0: https://gist.github.com/wzyboy/1fe3dae6a243e1502d7d
I am plan to make a obsfucated port forward program, obsfucate method can be customize, so both OpenVPN and SSH and other protocol traffic could be obsfucated.
我打了楼主说的最新的补丁可是还是不支持TCP.会显示socket.c什么什么的错误.
Windows下也编译成功了,版本是2.2.2的
https://www.gsea.com.cn/blog/wp-content/uploads/2012/12/OpenVPN-2.2.2-obfs1.patch
今天突然使用有一个奇怪的问题就是上去半个小时-一个小时就会突然自动断开重新连接
由于只能使用UDP所以我把如下参数调整成30了.
keepalive 10 30
可是发现过一段时间还是会断也没有什么特殊的日志显示
希望楼主留个联系方式...
我也是再在socket.c中加上这么编译过的
define MD5_DIGEST_LENGTH 16
define SHA_DIGEST_LENGTH 20
@greensea,obfsproxy from tor project do the same thing as you want, here is the link: https://www.torproject.org/projects/obfsproxy.html.en
@welkinwalker 求windows版本,windows实在搞不定哈Tunnelblick倒是用的很爽
好像现在握手比较困难 握手后倒是蛮流畅的
win下咋编译呢。。。。。悲剧
这个补丁也失效了吗??
编译好,在连接PPTP的情况下测试连接正常
但是断开pptp 再连接 还是卡在tls那里,,和没补丁一样,,,53、80端口都这样
日志如下:
Wed Apr 10 19:28:36 2013 us=374965 UDPv4 link local: [undef]
Wed Apr 10 19:28:36 2013 us=374973 UDPv4 link remote: 198.xx.xx.xx:80
Wed Apr 10 19:28:36 2013 us=375003 1, write buflen=14
Wed Apr 10 19:28:36 2013 us=375010 2, write buflen=26
Wed Apr 10 19:28:36 2013 us=583592 1, read buflen=33
Wed Apr 10 19:28:36 2013 us=583624 1, read buflen=26, padlen=3
Wed Apr 10 19:28:36 2013 us=583641 TLS: Initial packet from 198.xx.xx.xx:80, sid=72c47717 75864f06
Wed Apr 10 19:28:36 2013 us=583706 1, write buflen=22
Wed Apr 10 19:28:36 2013 us=583716 2, write buflen=49
Wed Apr 10 19:28:36 2013 us=583794 1, write buflen=102
Wed Apr 10 19:28:36 2013 us=583806 2, write buflen=131
Wed Apr 10 19:28:36 2013 us=794376 1, read buflen=139
Wed Apr 10 19:28:36 2013 us=794416 1, read buflen=126, padlen=9
Wed Apr 10 19:28:36 2013 us=794479 1, write buflen=22
Wed Apr 10 19:28:36 2013 us=794487 2, write buflen=45
Wed Apr 10 19:28:36 2013 us=794594 1, read buflen=141
Wed Apr 10 19:28:36 2013 us=794606 1, read buflen=114, padlen=23
Wed Apr 10 19:28:36 2013 us=794625 1, write buflen=22
Wed Apr 10 19:28:36 2013 us=794632 2, write buflen=48
Wed Apr 10 19:28:36 2013 us=794708 1, read buflen=124
Wed Apr 10 19:28:36 2013 us=794719 1, read buflen=114, padlen=6
Wed Apr 10 19:28:36 2013 us=794738 1, write buflen=22
Wed Apr 10 19:28:36 2013 us=794745 2, write buflen=35
Wed Apr 10 19:28:36 2013 us=794794 1, read buflen=137
Wed Apr 10 19:28:36 2013 us=794806 1, read buflen=114, padlen=19
Wed Apr 10 19:28:36 2013 us=794824 1, write buflen=22
Wed Apr 10 19:28:36 2013 us=794831 2, write buflen=53
Wed Apr 10 19:28:37 2013 us=54876 1, read buflen=120
Wed Apr 10 19:28:37 2013 us=54911 1, read buflen=114, padlen=2
Wed Apr 10 19:28:37 2013 us=54958 1, write buflen=22
Wed Apr 10 19:28:37 2013 us=54965 2, write buflen=26
Wed Apr 10 19:28:37 2013 us=55032 1, read buflen=126
Wed Apr 10 19:28:37 2013 us=55044 1, read buflen=114, padlen=8
Wed Apr 10 19:28:37 2013 us=55063 1, write buflen=22
Wed Apr 10 19:28:37 2013 us=55069 2, write buflen=52
Wed Apr 10 19:28:37 2013 us=68431 1, read buflen=145
Wed Apr 10 19:28:37 2013 us=68466 1, read buflen=114, padlen=27
Wed Apr 10 19:28:37 2013 us=68514 1, write buflen=22
Wed Apr 10 19:28:37 2013 us=68521 2, write buflen=42
Wed Apr 10 19:28:37 2013 us=69470 1, read buflen=140
Wed Apr 10 19:28:37 2013 us=69505 1, read buflen=114, padlen=22
Wed Apr 10 19:28:37 2013 us=69551 1, write buflen=22
Wed Apr 10 19:28:37 2013 us=69558 2, write buflen=30
Wed Apr 10 19:28:37 2013 us=361670 1, read buflen=137
Wed Apr 10 19:28:37 2013 us=361706 1, read buflen=114, padlen=19
Wed Apr 10 19:28:37 2013 us=361844 1, write buflen=22
Wed Apr 10 19:28:37 2013 us=361857 2, write buflen=55
Wed Apr 10 19:28:41 2013 us=836458 1, read buflen=128
Wed Apr 10 19:28:41 2013 us=836516 1, read buflen=114, padlen=10
Wed Apr 10 19:28:42 2013 us=876067 1, read buflen=121
Wed Apr 10 19:28:42 2013 us=876117 1, read buflen=114, padlen=3
Wed Apr 10 19:28:51 2013 us=828841 1, read buflen=147
Wed Apr 10 19:28:51 2013 us=828876 1, read buflen=114, padlen=29
Wed Apr 10 19:28:55 2013 us=332424 1, read buflen=136
Wed Apr 10 19:28:55 2013 us=332494 1, read buflen=114, padlen=18
Wed Apr 10 19:29:37 2013 us=70255 TLS Error: TLS key negotiation failed to occur within 60 seconds (check your network connectivity)
Wed Apr 10 19:29:37 2013 us=70291 TLS Error: TLS handshake failed
Wed Apr 10 19:29:37 2013 us=70385 TCP/UDP: Closing socket
https://gist.github.com/warriorpaw/5354603
我在怀疑是不是GFW会随机的改数据包 ,就照着本patch 稍微修改下,加进去CRC,放在发送buf最前端,然后用CRC值对随机数XOR了一下
可是证明我错了,还是挂上pptp就OK;直接连,无限卡TLS握手
但至少发现发送和接收的CRC是一致的。。。。。。
唉,这什么蛋疼问题造成的啊~~!
--------------------蛋疼的分割线-----------------------
貌似不是GFW的问题,我弄了个国内电信的PPTP连接上去,然后连openvpn居然也连接上去了。。。
艹!!谁能告诉我为啥...
--------------------蛋疼的分割线2-----------------------
发现问题了,丢包,对比vps上openvpn输出和本地的,在握手这段,vps那边write 一大堆,这边就read到没几个
应该是各地GFW规则还不太一样,我这哈尔滨联通
@warriorpaw 北京联通 遇到和你相同的问题 但是 一般 重试5分钟左右 就可以连上。 家里宽带好像走重庆移动 所以没这个问题
@Ksyou 你的问题可能是 mss 大小不对,调整为 1380 左右试试?
mark 一下
修复在 TCP 模式下客户端无法连接的问题。只修改了两行代码,diff 文件的 diff 如下:
Fix connection in TCP mode, two lines changed, diff of diff is below: