wangyu- / udp2raw

A Tunnel which Turns UDP Traffic into Encrypted UDP/FakeTCP/ICMP Traffic by using Raw Socket,helps you Bypass UDP FireWalls(or Unstable UDP Environment)
MIT License
7.18k stars 1.16k forks source link

Contribution Guide #17

Open wangyu- opened 7 years ago

wangyu- commented 7 years ago

1.Better automation for --lower-level option (done)

Many connection issues are caused by in-compatible iptables rules. --lower-level enables the ablity to bypass any local iptables rules,so that one can use udp2raw in any complicated environment without worrying about iptables .However,currently,--lower-level option needs user to specify if_name and dest_mac_adress manually,for example: --lower-level eth0#00:23:45:67:89:b9. we need to get this automatically for specific ip.Such a function need to be implemented:

int get_lower_level_info(IN u32_t ip,OUT char * if_name,OUT uint8_t hw_addr[6])
{
/* parse /proc/net/route  and /proc/net/arp */
return 0;
}

To implement this,you only need to parse /proc/net/route and /proc/net/arp.This will be not hard but some patient is needed.You will write some code of string parsing and route pre_fix search. If you implement this,i can get everything esle done,or you can implement everything by yourself.

(There is also a better way . You can get those info without parsing strings by using ioctl/sysctl ,any method is okay,as long as its robust.)

I will give more details if anyone is interested.

2.Implement a GUI for andoird.

Currently udp2raw works stablely on rooted android device,however there is no GUI.Need to make an andoird app to wrap android binary to provide better experience.Only android experience is necessary.

3.Implement luci-app-udp2raw-tunnel (done)

Implement luci-app-udp2raw-tunnel to wrap openwrt binary. repo at: https://github.com/sensec/luci-app-udp2raw thanks @sensec

4.Support PolarSSL or OpenSSL (maybe not necessary any more,since we already have hardware/asm aes acceleration for almost all common platforms )

Support PolarSSL or OpenSSL while keep tiny-AES-c supported

5.hardware/asm AES acceleration for MIPS and ARM (done)

Support this without using PolarSSL or OpenSSL if possible.For easier compilation.

great thx to @linusyang,this has been done.

6.BSD system(include MacOs) support (done)

Need to change epoll to kqueue or libuv. iptables rules to PF rules. done. check https://github.com/wangyu-/udp2raw-multiplatform

7.Windows support (complicated) (done)

epoll to libevent libuv. raw socket to winpcap.Find a way to disable windows kernel processing of tcp for specific port. done. check https://github.com/wangyu-/udp2raw-multiplatform

8. crypto

Implement HMAC-md5 (to replace plain md5) , Encryp-then-MAC scheme. (done) HMAC-SHA1 is supported instead. Encryp-then-MAC scheme is used.

AEAD support ( optional ).

Currently encryption is mainly implement in encrypt.cpp,which contains of only 300 lines of code(not include aes and md5 implemention).

You can get start from the following two functions:

int my_encrypt(const char *data,char *output,int &len,char * key)

int my_decrypt(const char *data,char *output,int &len,char * key)

9. domain support and ipv6 support

10.http and https obfuscate

pretend to use http/https protocol,to bypass special Qos

11.peformance optimize

especially for eliminating those unnecessary memcpy()s capture

12. share port with other tcp programs

In a way similiar to https://github.com/yrutschle/sslh . Complicated, since raw socket is involved.

Discussions at: https://github.com/wangyu-/udp2raw-tunnel/issues/131

13. allow udp2raw to run without iptables

details at:

https://github.com/wangyu-/udp2raw-tunnel/issues/9

https://github.com/linhua55/lkl_study/issues/11

(done in udp2raw-multiplatform)

linhua55 commented 7 years ago

For 1. some url https://stackoverflow.com/questions/548105/default-gateway-in-c-on-linux image from "Unix network programming" https://pan.baidu.com/s/1o7ARCpk P352

wangyu- commented 7 years ago

@linhua55 Thanks for the info. This looks like a better way.One can get all the information by using ioctl and sysctl without parsing strings. Parsing /proc/net/route and /proc/net/arp is also acceptable,this has been a stable and common interface(even exists on Android).

CyanBuckeye commented 7 years ago

@wangyu- Hi, Could you add some comments in source code? Now it is kind of hard for me to understand your code....

wangyu- commented 7 years ago

@CyanBuckeye Hi,I will add some after I have finished 1. .

linhua55 commented 7 years ago

For 6 and 7, use third party library: libuv http://blog.csdn.net/lijinqi1987/article/details/71214974

CyanBuckeye commented 7 years ago

Hi, I am kind of confused: it seems that you have to run the command on server side to connect it with the actual server. But ideally, the tunnel server should create connection with actual server based on the information received from client, right?

wangyu- commented 7 years ago

Hi,@CyanBuckeye:

But ideally, the tunnel server should create connection with actual server based on the information received from client, right?

You are right.I didnt implement it in this way,beacuse this program was originally designed to work with OpenVPN or Kcptun+socks5. OpenVPN or socks5 can do similiar work to what you have mentioned.

Have to admit,if you use udp2raw independtly,the current method is not convenient enough.

Maybe an option like udp2raw -s -l***** -r unspecified can be implemented in furture for convenience.(The current method will not be removed,bc someone may not want to expose every port/machine behind a udp2raw server)

CyanBuckeye commented 7 years ago

Hi, I am quite interested in task 2 (Android GUI Implementation). But I still want to know more about your requirement. In other words, what is the App designed for? To make users send messages in tunnel more easily? If so, it sounds like that OpenVPN needs to be incorporated?

wangyu- commented 7 years ago

But I still want to know more about your requirement. In other words, what is the App designed for? To make users send messages in tunnel more easily?

Udp2raw is designed for bypassing UDP firewalls,the Android App is designed for using udp2raw without the need of running it from a terminal(typing terminal command on an android device can be very tedious)

If so, it sounds like that OpenVPN needs to be incorporated?

Users may not stick to OpenVPN,they can aslo choose other udp-based VPNs,or a socks5 solution,or a transparent proxy solution.

Udp2raw 's job is to establish a "lower-level" channel which can bypass UDP firewalls.Some other tools can be used to establish a "higher-level" channel on the "lower-level" channel.

I am not against incorporating an OpenVPN client to the gui.I just think it maybe a bit complicated,while it may not be useful for every user.There are many choices to work at "higher-level",it will be a huge work to incorporate them all.

But ideally, the tunnel server should create connection with actual server based on the information received from client, right?

Lets continue this topic.

Even if we have implemented the feature of udp2raw -s -l******* -r unspecified and udp2raw -c -l******** -r<server_ip>:<server_port> -t<target_ip>:<target_port> . Its still not enough,because you still have to start a new client for every new <target_ip>:<target_port>.

If we go one step further ,we can implement an integrated socks5(just like ssh -D),but this still doesnt work for everyone(not every program supports socks5).If we go antoher step further ,we have to implement an integrated VPN or transparent proxy.It seems over-complicated.There are already good solutions which can work stably with udp2raw together.Instead of making udp2raw an "all-in-one" solution,we can keep udp2raw simple and let user choose a "high-level solution" depend on his favor.

NOTE:we can still have udp2raw -s -l******* -r unspecified and udp2raw -c -l******** -r<server_ip>:<server_port> -t<target_ip>:<target_port> ,since its simple enough.

CyanBuckeye commented 7 years ago

Hi, I have a question that a cellphone's IP address is not fixed, right? Then how should I deal with that? Will the tunnel be influenced by that?

wangyu- commented 7 years ago

Hi, I have a question that a cellphone's IP address is not fixed, right?

I m not sure.Maybe it depends on your ISP.

Then how should I deal with that? Will the tunnel be influenced by that?

udp2raw client can deal with it correctly.So,dont worry about that.

upd2raw server can also deal with it correctly.But,of cousre,you need to use the new ip to connect to server after ip changed.

By the way,option --lower-level may break this ability on client side,but its not necessary to use this option on android.

CyanBuckeye commented 7 years ago

Hi. I compile your code in Android Studio but it appears that there are some issues. I am sure that your code is correct but I fail to find the reason. Could you help me on that? error

By the way, I am also confused by vpaes_set_encrypt_key. (Line 196: aesacc.c) Thank you very much!

wangyu- commented 7 years ago

Hi. I compile your code in Android Studio but it appears that there are some issues. I am sure that your code is correct but I fail to find the reason. Could you help me on that?

It looks like the makefile is not imported correctly.Sorry, I dont know how to do it in Android Studio.

You dont actually need to compile udp2raw in Android Studio. You can pack udp2raw binary(udp2raw_arm_asm_aes) into your apk,and call it from your GUI(just like the android terminal does).

CyanBuckeye commented 7 years ago

Ha ha. Your idea really works. But I still prefer compiling c++ code in Android Studio. Are you familiar with CMake which Android Studio uses for compilation. Now I am facing a new error: unsupported ARM architecture. error2 Could you give me some hints on that?

wangyu- commented 7 years ago

Ha ha. Your idea really works. But I still prefer compiling c++ code in Android Studio. Are you familiar with CMake which Android Studio uses for compilation. Now I am facing a new error: unsupported ARM architecture.

Sorry. I have little knowledge about CMake and Android Studio.

By the way,I tried to compile udp2raw by using the toolchain created by Android NDK before,I failed and finally had to switch to a general arm toolchain.

CyanBuckeye commented 7 years ago

Aha I manage to compile your code in Android Studio! But I face a bizarre error: error3 The program exits at this line. I use emulator as client and host as server.

wangyu- commented 7 years ago

@CyanBuckeye

This is an expected error.Because popen()/system() function is not supported on Android.To use udp2raw on android I have to add iptables manually(as have been mentioned in https://github.com/wangyu-/udp2raw-tunnel/blob/master/doc/android_guide.md)

To bypass this problem,taking a look at Android Terminal 's code maybe helpful(it can successfully invoke an externel program.I guess it uses some lower-level api such as fork and exec).

CyanBuckeye commented 7 years ago

Hi, I implement popen and pclose. However, error4 execv() function doesn't work. Could you help me find the reason? I try a simple example, just as shown in pic. But execv() keeps returning -1.

CyanBuckeye commented 7 years ago

I find the reason.... No more bother

CyanBuckeye commented 7 years ago

Hi! I meet a new problem. It seems that some mistakes occur when running command: problem5

And when I manually run this command in Android shell, it shows that iptables: No chain/target/match by that name. Could you help me on that? Sorry I am totally novice to it.

wangyu- commented 7 years ago

You cant insert anything to a chain/table without having created it first.

Those commands generated by udp2raw need to be run one by one,you cant run from the middle:

[2017-09-20 20:56:58][INFO]run_command iptables -N udp2rawDwrW_85b2685b_C0
[2017-09-20 20:56:58][INFO]run_command iptables -F udp2rawDwrW_85b2685b_C0
[2017-09-20 20:56:58][INFO]run_command iptables -I udp2rawDwrW_85b2685b_C0 -j DROP
[2017-09-20 20:56:58][INFO]run_command iptables -I INPUT -p tcp -m tcp --dport 123 -j udp2rawDwrW_85b2685b_C0

To debug those commands,you may need to take a look at some iptables tutorial first.

CyanBuckeye commented 7 years ago

Hello. Could you tell me how to root an emulator? I try ./adb root, but it does not help.

jiangtiandao commented 7 years ago

@CyanBuckeye You may need to root your device first. Then try su - root

wangyu- commented 7 years ago

@CyanBuckeye

If you meant a standalone emulator,such as bluestacks.You can find some pre-rooted version on google,it worked for me. If you meant the emulator in android studio,I have no idea.

CyanBuckeye commented 7 years ago

I meet a really bizarre problem: the code only works under x86_64 architecture. Under x86 architecture, it throws a compilation error like this: error 6

I feel really confused about it.

CyanBuckeye commented 7 years ago

Lol. I missed one flag in CMake. Now it works. XD

wangyu- commented 6 years ago

For 6 and 7, use third party library: libuv

@linhua55

I finally chose libev. Libev supports standalone mode(embed the source code directl into a project without build it as a lib), make it very conveninent . Libev is also much more lightweight than libuv.

For windows platform there is a special patched libev version[0] with wepoll[1] backend(implemented with IOCP) which has decent performance.

[0] https://github.com/piscisaureus/wepoll [1] https://github.com/shadowsocks/libev/archive/mingw.zip