Last active
March 22, 2023 09:17
-
-
Save greensea/4372285 to your computer and use it in GitHub Desktop.
The obfs patch obsfucate OpenVPN traffic, make it looks like random traffic. The obfs patch add two options for OpenVPN. --obfs-salt <string> is a secret to generate the input XOR stream. To enable the obfs patch, this options must be set.
--obfs-padlen <num> is a positive integer max to 255. This option tells obfs patch to padding random conten…
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- 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); |
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 一下
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
这个补丁也失效了吗??
编译好,在连接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