summarylogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.SRCINFO24
-rw-r--r--PKGBUILD42
-rw-r--r--openvpn-2.3.6-obfs.patch214
-rw-r--r--openvpn-obfs@.service11
4 files changed, 291 insertions, 0 deletions
diff --git a/.SRCINFO b/.SRCINFO
new file mode 100644
index 000000000000..bfe5d076ee23
--- /dev/null
+++ b/.SRCINFO
@@ -0,0 +1,24 @@
+pkgbase = openvpn-obfs
+ pkgdesc = OpenVPN binary with obfs patch
+ pkgver = 2.3.6
+ pkgrel = 2
+ url = https://www.gsea.com.cn/blog/topic/traffic-obsfucate-patch-for-openvpn/
+ arch = i686
+ arch = x86_64
+ license = custom
+ makedepends = systemd
+ depends = openssl
+ depends = lzo
+ depends = iproute2
+ depends = openvpn>=2.3.0
+ depends = libsystemd
+ options = !libtool
+ source = http://swupdate.openvpn.net/community/releases/openvpn-2.3.6.tar.gz
+ source = openvpn-2.3.6-obfs.patch
+ source = openvpn-obfs@.service
+ sha256sums = 7baed2ff39c12e1a1a289ec0b46fcc49ff094ca58b8d8d5f29b36ac649ee5b26
+ sha256sums = fef778ed0b4facdb20d65d7d7803ab512f36ed7ae6f295e5664a3c953c23bfcf
+ sha256sums = 0f9830b732160523713cd03be3201ba3c5a5bad79fe8bbedc36776558a9feb90
+
+pkgname = openvpn-obfs
+
diff --git a/PKGBUILD b/PKGBUILD
new file mode 100644
index 000000000000..d87bd4394fc1
--- /dev/null
+++ b/PKGBUILD
@@ -0,0 +1,42 @@
+# Maintainer: Zhuoyun Wei <wzyboy@wzyboy.org>
+
+pkgname=openvpn-obfs
+_pkgname=openvpn
+pkgver=2.3.6
+pkgrel=2
+pkgdesc="OpenVPN binary with obfs patch"
+arch=('i686' 'x86_64')
+url="https://www.gsea.com.cn/blog/topic/traffic-obsfucate-patch-for-openvpn/"
+depends=('openssl' 'lzo' 'iproute2' 'openvpn>=2.3.0' 'libsystemd')
+makedepends=('systemd')
+license=('custom')
+source=(http://swupdate.openvpn.net/community/releases/openvpn-${pkgver}.tar.gz
+ openvpn-2.3.6-obfs.patch
+ openvpn-obfs@.service)
+sha256sums=('7baed2ff39c12e1a1a289ec0b46fcc49ff094ca58b8d8d5f29b36ac649ee5b26'
+ 'fef778ed0b4facdb20d65d7d7803ab512f36ed7ae6f295e5664a3c953c23bfcf'
+ '0f9830b732160523713cd03be3201ba3c5a5bad79fe8bbedc36776558a9feb90')
+options=(!libtool)
+
+build() {
+ cd $srcdir/$_pkgname-$pkgver
+ patch -p0 -F10 -i $srcdir/openvpn-2.3.6-obfs.patch
+ CFLAGS="$CFLAGS -DPLUGIN_LIBDIR=\\\"/usr/lib/openvpn\\\"" ./configure \
+ --prefix=/usr \
+ --sbindir=/usr/bin \
+ --enable-password-save \
+ --mandir=/usr/share/man \
+ --enable-iproute2 \
+ --enable-systemd
+ make
+}
+
+package() {
+ cd $srcdir/$_pkgname-$pkgver
+ make DESTDIR=$pkgdir install
+ mv $pkgdir/usr/bin/openvpn{,-obfs}
+ rm -r $pkgdir/usr/{share,lib,include}
+ cd ..
+ install -Dm644 openvpn-obfs@.service \
+ $pkgdir/usr/lib/systemd/system/openvpn-obfs@.service
+}
diff --git a/openvpn-2.3.6-obfs.patch b/openvpn-2.3.6-obfs.patch
new file mode 100644
index 000000000000..6b579cb18030
--- /dev/null
+++ b/openvpn-2.3.6-obfs.patch
@@ -0,0 +1,214 @@
+--- 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,
diff --git a/openvpn-obfs@.service b/openvpn-obfs@.service
new file mode 100644
index 000000000000..46ea0cc10713
--- /dev/null
+++ b/openvpn-obfs@.service
@@ -0,0 +1,11 @@
+[Unit]
+Description=OpenVPN connection to %i
+After=network.target
+
+[Service]
+Type=forking
+ExecStart=/usr/bin/openvpn-obfs --cd /etc/openvpn --config /etc/openvpn/%i.conf --daemon openvpn-obfs@%i --writepid /run/openvpn@%i.pid
+PIDFile=/run/openvpn@%i.pid
+
+[Install]
+WantedBy=multi-user.target