-
-
Save wzyboy/1fe3dae6a243e1502d7d to your computer and use it in GitHub Desktop.
| --- src/openvpn/options.c.orig 2012-12-17 17:36:07.000000000 +0800 | |
| +++ src/openvpn/options.c 2013-03-07 23:21:26.230153027 +0800 | |
| @@ -62,6 +62,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 | |
| @@ -6727,6 +6731,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 (streq (p[0], "peer-id")) | |
| { | |
| VERIFY_PERMISSION (OPT_P_PEER_ID); | |
| options->use_peer_id = true; | |
| --- src/openvpn/socket.c.orig 2012-12-13 23:46:01.000000000 +0800 | |
| +++ src/openvpn/socket.c 2013-03-07 23:24:43.943121487 +0800 | |
| @@ -41,6 +41,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 */ | |
| 0, | |
| IPv4_UDP_HEADER_SIZE, /* IPv4 */ | |
| @@ -52,6 +56,49 @@ | |
| 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.orig 2012-12-20 16:56:00.000000000 +0800 | |
| +++ src/openvpn/socket.h 2013-03-07 23:35:02.442141344 +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. | |
| */ | |
| @@ -877,28 +882,60 @@ | |
| 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(D_LINK_RW_VERBOSE, "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(D_LINK_RW_VERBOSE, "1, read buflen=%d, padlen=%d", BLEN(buf), pad_len); | |
| + | |
| + free_buf(&tbuf); | |
| + | |
| + res -= 4; | |
| + res -= pad_len; | |
| + | |
| + } | |
| + | |
| + return res; | |
| } | |
| /* | |
| @@ -941,6 +978,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(D_LINK_RW_VERBOSE, "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(D_LINK_RW_VERBOSE, "2, write buflen=%d", BLEN(buf)); | |
| + | |
| + free_buf(&tbuf); | |
| + } | |
| + | |
| + | |
| #if ENABLE_IP_PKTINFO | |
| int link_socket_write_udp_posix_sendmsg (struct link_socket *sock, | |
| struct buffer *buf, |
https://gist.github.com/pentie/b1d5d75cdbc47b53bf9b
修改了LOG Level. 补丁中的MSG信息属于链路层的调试信息,原来那样的输出会太多了。
@Pentie 赞改 log level。其实我自己编译的时候都是把 msg() 那行注释掉的 -_-
TLS ERROR when used with TCP mode.
Server log:
TLS ERROR: initial packet local/remote key_method mismatch, local key_method=2, op=P_CONTROL_HARD_RESET_CLIENT_V1
Fatal TLS error (check_tls_errors_co), restarting
Client side just TCP resetted everytime
Any fix?
您好,UDP模式下连接还是会断流,请问有解决方法么?
怎么安装呢?
can I use it with the version 2.3.4?
编译的时候报错:
can't find file to patch at input line 3
Perhaps you should have used the -p or --strip option?
The text leading up to this was:
|--- src/openvpn/options.c.orig 2012-12-17 17:36:07.000000000 +0800
|+++ src/openvpn/options.c 2013-03-07 23:21:26.230153027 +0800
怎么解决?
我针对2.3.12修改了
https://gist.github.com/dawei1/769379564917dca6af2dee45dc943e02
@Itwastaken
把patch文件放到openvpn-2.3.12/src/openvpn/ , 然后在openvpn-2.3.12/src/openvpn/目录下执行patch命令
我也试试