UDP打洞原理与N2N内网穿透

UDP打洞原理与N2N内网穿透

      • UDP打洞原理
        • 原理
        • Server 端部分代码
        • Client 端部分代码
      • N2N网络穿透
        • 安装N2N
        • 配置Supernode
        • 配置Edgenode
        • Ping测试
        • 一键脚本代码

UDP打洞原理

通过UDP路由验证实现NAT穿越是一种在处于使用了NAT的私有网络中的Internet主机之间建立双向UDP连接的方法。由于NAT的行为是非标准化的,因此它并不能应用于所有类型的NAT。
其基本思想是这样的:让位于NAT后的两台主机都与处于公共地址空间的、众所周知的第三台服务器相连,然后,一旦NAT设备建立好UDP状态信息就转为直接通信,并寄希望于NAT设备会在分组其实是从另外一个主机传送过来的情况下仍然保持当前状态。
这项技术需要一个圆锥型NAT设备才能够正常工作。对称型NAT不能使用这项技术。
这项技术在P2P软件和VoIP电话领域被广泛采用。它是Skype用以绕过防火墙和NAT设备的技术之一。
相同的技术有时还被用于TCP连接——尽管远没有UDP成功。

原理

UDP打洞原理与N2N内网穿透_第1张图片
假设有两台分别处于各自的私有网络中的主机:A和B;NA和NB是两个网络的NAT设备,分别拥有IP地址P1和P2;S是一个使用了一个众所周知的、从全球任何地方都能访问得到的IP地址的公共服务器

步骤一:A和B分别和S建立UDP连接;NAT设备NA和NB创建UDP转换状态并分配临时的外部端口号

步骤二:S检查UDP包,看A和B的端口是否是正在被使用的(否则的话N1和N2应该是应用了端口随机分配,这会让路由验证变得更麻烦)

步骤三:如果端口不是随机化的,那么A和B各自选择端口X和Y,并告知S。S会让A发送UDP包到P2:Y,让B发送UDP包到P1:X

步骤四:A和B通过转换好的IP地址和端口直接联系到对方的NAT设备;

Server 端部分代码

	//这里是对UDT的启动记性初始化操作
	 if (UDT::ERROR == UDT::startup())
	 {
		 cout<<"startup: "<

Client 端部分代码

	 //startup
	 if (UDT::ERROR == UDT::startup())
	 {
		cout<<"startup: "<

以上代码使用UDT协议进行互相打洞,没有经过Server服务器(没有),简单的实现了网络穿透,可穿越防火墙。

N2N网络穿透

N2N是一个开放源代码的2层跨越3层的×××程序,该程序利用了点对点的架构来处理网络间的成员关系和路由,N2N的原理如下图,在搭建的过程中需要一个super节点和多个edge节点,super节点建立一个通信中心,用来路由edge之间的通讯,对于×××使用来说,super node节点必须有一个公网的IP地址

UDP打洞原理与N2N内网穿透_第2张图片

安装N2N

N2N GitHub地址

sudo apt-get install libssl-dev //安装openssl
git clone https://github.com/meyerd/n2n
cd n2n/n2n_v2
cmake CMakeLists.txt
make
make install

需要root权限

配置Supernode

supernode -l 1000 -v >/dev/null &   //监听1000端口
root@ubuntu16:# supernode -h  //可使用 -h查看命令参数
supernode usage
-l       Set UDP main listen port to   // UDP 监听端口
-f              Run in foreground.    //前台运行
-u         User ID (numeric) to use when privileges are dropped.  // 指定运行所用的UID
-g         Group ID (numeric) to use when privileges are dropped. // 指定运行所用的GID
-v              Increase verbosity. Can be used multiple times.   // 输出比较详细的log
-h              This help message.

配置Edgenode

edge -d n2n0 -c mynetwork -k encryptme -a 10.10.10.3 -l X.55.150.X:1000 >/dev/null &
-d 虚拟网卡名
-a [static:| dhcp:](虚拟网段ip)
-c 用于区分节点的组名
-k 用于加密的字符串
-l supernode的IP:端口,可以指定多个supernode

以上为节点配置,配置完成后 ifconfig 会多出个虚拟网卡
UDP打洞原理与N2N内网穿透_第3张图片
可在服务器上配置 supernode节点, 其余内网client配置edge节点,-a 自定义ip(网段需一致)-l 参数填服务器与监听的端口

Ping测试

UDP打洞原理与N2N内网穿透_第4张图片
搭建成功则可互相ping通

一键脚本代码

shell脚本代码(抄来的,略作修改),需root权限运行,centos系统 apt-get 改为 yum

#!/bin/bash
#####此脚本用来实现安装N2N的客户端,实现内网之间的穿透
####应用场景:
###客服的服务器有A、B、C三台,其中有一台可以上外网,此处以A为例子,ABC之间的SSH互通
####N2N的server,即super node为114.114.114.114,端口1000,在阿里云端,可以实现外网访问
####此脚本用来在客户的内网搭建N2N的client,可以实现和阿里云supernode的通信,这样通过阿里云端就可以SSH到客户服务器内网
N2N_super_node_ip=100.100.100.100 ###改为自己的服务器IP
N2N_super_node_port=1000	   ###自行更改
###N2N_edge_ip为搭建的edge的IP,需要设置,网段为10.10.10.*
####但有一个前提,设置的这个IP地址在虚拟局域网中不能冲突,所以需要先判断IP地址是否冲突
N2N_edge_ip=10.10.10.3   ###自行更改
judge_ip_confilct() {
    if `ping -c 2 ${N2N_edge_ip} &>/dev/null`;then
            echo -e "\033[32m                               ${N2N_edge_ip} can ping,has client used,please motified N2N_edge_ip,系统退出\033[0m" 
            exit 0
    else
        echo -e "\033[31m                               ${N2N_edge_ip} not can ping,N2N_edge_ip can be userd\033[0m"
    fi
}
check_super_node_service() {
    ping -c 6 ${N2N_super_node_ip}
    if `ping -c 2 ${N2N_super_node_ip} &>/dev/null`;then
        echo -e "\033[32m                               super node :${N2N_edge_ip} can ping, N2N server can be used\033[0m"
    else    
        echo -e "\033[31m                               super node :${N2N_edge_ip} can not ping ,n2n server can not be used ,please check system quit\033[0m"
        exit
    fi
}
n2n_install_super_node() {
    if `sudo apt-get install bc &>/dev/null`;then
        echo -e "\033[32m                yum can be use,starting yum install n2n relative paket:\033[0m"
        sudo apt-get install subversion gcc-c++ openssl-devel
        echo "git clone install n2n:"
        git clone   https://svn.ntop.org/svn/ntop/trunk/n2n
        if [ -e n2n ];then
            echo "n2n file download successful,beging install n2n"
            cd n2n/n2n_v2
            cmake CMakeLists.txt
            make
            make
            sudo make install
        else
            echo "n2n file download failed ,has some problems ,please check"
            exit 0
        fi
        echo "n2n install over,beginging start n2n services"
        supernode -l ${N2N_super_node_port} -v >/dev/null &
        
        echo "查看 ps -ef | grep supernode"
        ps -ef | grep supernode
        echo "supernode -l ${N2N_super_node_port} -v >/dev/null &"  >> /etc/rc.local
    else
        echo -e "\033[31m                yum not can be use,yum install n2 has some problem,please check\033[0m"
        exit
    fi
}
n2n_install_edge_node() {
    if `sudo apt-get install bc &>/dev/null`;then
        echo -e "\033[32m               yum can be use,starting yum install n2n relative paket:\033[0m"
        sudo apt-get install subversion gcc-c++ openssl-devel
        echo "git clone install n2n:"
        git clone https://github.com/meyerd/n2n.git
        if [ -e n2n ];then
            echo "n2n file download successful,beging install n2n"
            cd n2n/n2n_v2
            cmake CMakeLists.txt
            make
            make
            sudo make install
        else
            echo "n2n file download failed ,has some problems ,please check"
            exit 0
        fi
        echo "check super node server is ok or not"
        check_super_node_service
        echo "n2n install over,begining start edge node"
        edge -d n2n0 -c mynetwork -k encryptme -M 1200 -a $N2N_edge_ip -l $N2N_super_node_ip:$N2N_super_node_port >/dev/null &
    
        echo "查看 ps -ef | grep edge,进程是否启动OK"
        ps -ef | grep edge
        sudo echo "edge -d n2n0 -c mynetwork -k encryptme -a $N2N_edge_ip -l $N2N_super_node_ip:$N2N_super_node_port" >> /etc/rc.local
    else
        echo -e "\033[31m               yum not can be use,yum install n2 has some problem,please check\033[0m"
        exit
    fi
}
real=`grep -l '\^H' /root/.bash_profile`   
if [ $? -eq 1 ];then   
    echo  'stty erase ^H' >> /root/.bash_profile   
    source /root/.bash_profile   #这几行主要就是让在使用read键时能使用回删键。写错了,回删了,重启写。不用这段的话,回删键会变成乱码。 
fi
echo -e '\033[0;33;1m #################nagios################## \033[0m' #让echo能弄点颜色出来好看点。。。     
echo "n2n supernode install please input : 1" 
echo "n2n edgenode  install please input : 2"   
echo -e '\033[0;33;1m ######################################### \033[0m'
read -p "please chose : " frist   #定义输入的值 
if [ $frist -eq 1 ];then
    n2n_install_super_node
else
    n2n_install_edge_node
fi

你可能感兴趣的:(网络穿透)