知识的荒漠

不积跬步无以至千里,不积小流无以成江海;千里之行,始于足下!

用户工具

站点工具


服务器:路由器:n2n

github:https://github.com/ntop/n2n https://github.com/lucktu/n2n
相关参考:https://bugxia.com/ https://github.com/woOzZ1/n2n-padavan
v1,v2s安装方式详padavan

新版获取安装

访问https://github.com/lucktu/n2n 根据自己的路由器系统,选择合适的版本,我用的是padavan,选择的是n2n_v2_linux_mipsel_v2.7.0_r525_all_by_heiye.zip版本
注意,因为raw.githubusercontent.com被墙,所以需要设置hosts,访问http://ip.tool.chinaz.com/raw.githubusercontent.com,获得ip地址(当前获得的是151.101.8.133),在hosts末尾添加

151.101.8.133 raw.githubusercontent.com

设置完毕后即可正常下载
2020-08-08:v.2.7.0_r523,在超级节点中添加-d,为边缘提供了动态IP,超级节点的管理得到了增强。v.2.8.0没有此功能。
解压下载的文件,目录如下:
Castrated:没啥用
dynamic:缺运行库,无法直接运行
static:已包含运行库,可直接运行,推荐,upx是压缩过的文件(会小一点)
上传n2n_v2_linux_mipsel_v2.7.0_r525_all_by_heiye\static\supernode_upx到路由器/etc/storage/目录下,设置权限为755
参考padavan,删除原v1,v2s相关文件
进入系统管理->恢复/导出/上传设置,点击保存/etc/​stor­age/内容到闪存旁的提交
在路由器启动后执行:末尾修改代码如下(禁用原先的v1,v2s)

#/etc/storage/bin/n2n/supernode -l 82 &
#export LD_LIBRARY_PATH=/etc/storage:$LD_LIBRARY_PATH
#/etc/storage/supernode21 -l 86 &
/etc/storage/supernode_upx -l 86 -- d&

防火墙规则启动后执行:在logger -t "【防火墙规则】" "脚本完成"前面修改代码如下:

#iptables -A INPUT -p tcp --dport 82 -j ACCEPT
#iptables -A INPUT -p udp --dport 82 -j ACCEPT
#iptables -A INPUT -p tcp --dport 86 -j ACCEPT
iptables -A INPUT -p udp --dport 86 -j ACCEPT
#echo "1" > /proc/sys/net/ipv4/ip_forward &
#iptables -t nat -A POSTROUTING -j MASQUERADE &
#iptables -I INPUT -i v21 -j ACCEPT

等待路由器重启完成,一般即可连接;可ssh登陆路由器查看进程ps | grep supernode是否启动

客户端

原先v1,v2s可用客户端:n2n_windows中文版_V0.6_100M网卡_已替换为x64v2.1客户端.7z,N2N启动器 v1.2.zip
v2.7.0_r525客户端:EasyN2N(N2N启动器)v1.7.zip 教程
注意:路由下面的内网主机服务器处要输入路由器的ip地址,而不是域名
如无法ping通,注意关闭电脑的防火墙

超级节点共享

v2.7.0_r525:cwz1.f3322.net:86

魔兽3联机

下载ForceBindIP-1.32_2020083788 指定程序使用某个网卡并解压 官网:https://r1ch.net/projects/forcebindip
cmd进入到解压目录,复制下面到cmd中运行,172.17.12.3替换为n2n连接后虚拟网卡获取的ip地址,E:\SingleGame\魔兽争霸\war3.exe替换为你自己的魔兽路径

ForceBindIP.exe 172.17.12.3 "E:\SingleGame\魔兽争霸\war3.exe"

带图形界面的几个推荐
ForceBindIP GUI v1.51 by LibTiff:https://sourceforge.net/projects/forcebindip-gui/
ForceBindIP GUI V2.0 by LibTiff: https://sourceforge.net/projects/forcebindip-gui-by-libtiff/
ForceBindIP GUI 1.0 Beta by Michael Jones:找不到下载地址
ForceBindIP GUI by Donlawat:https://raymondcc.r.worldssl.net/ForceBindIP_GUI.exe


顺带总结下Linux程序绑定IP地址和端口:
bindp-基于LD_PRELOAD机制:https://github.com/yongboy/bindp

git clone https://github.com/yongboy/bindp.git
cd bindp
make

使用案例:
假设本地多个可用 IP 地址包含 10.10.10.10 ,并且假设端口 49999 没被占用,那么我们可以在作为客户端访问远程服务器时进行制定 IP 地址和端口:

REUSE_PORT=1 BIND_ADDR="10.10.10.10" BIND_PORT=49999 LD_PRELOAD=/the_path/libindp.so nc 10.10.10.11 80

假设 Nginx 配置监听 80 端口,不想修改配置文件的话而使之监听 9090 端口,我们可以这样做:

BIND_PORT=9090 LD_PRELOAD=/your_path/libindp.so /usr/sbin/nginx -c /etc/nginx/nginx.conf

参考:http://www.senra.me/tools-recommendation-linux-bindp-rebind-ip-and-port-for-application/
参考:https://www.kutu66.com/GitHub/article_113111
参考:https://www.raymond.cc/blog/bind-windows-application-to-specific-network-adapter-with-forcebindip/
Daniel Ryde写的bind.c源码

/*
   Copyright (C) 2000  Daniel Ryde
   Small amendment by Daniel Lange, 2010
   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.
   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.
*/
/*
   LD_PRELOAD library to make bind and connect to use a virtual
   IP address as localaddress. Specified via the enviroment
   variable BIND_ADDR.
   Compile on Linux with:
   gcc -nostartfiles -fpic -shared bind.c -o bind.so -ldl -D_GNU_SOURCE
   Example in bash to make inetd only listen to the localhost
   lo interface, thus disabling remote connections and only
   enable to/from localhost:
   BIND_ADDR="127.0.0.1" LD_PRELOAD=./bind.so /sbin/inetd
   Example in bash to use your virtual IP as your outgoing
   sourceaddress for ircII:
   BIND_ADDR="your-virt-ip" LD_PRELOAD=./bind.so ircII
   Note that you have to set up your servers virtual IP first.
   This program was made by Daniel Ryde
   email: daniel@ryde.net
   web:   http://www.ryde.net/
   TODO: I would like to extend it to the accept calls too, like a
   general tcp-wrapper. Also like an junkbuster for web-banners.
   For libc5 you need to replace socklen_t with int.
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <dlfcn.h>
#include <errno.h>
int (*real_bind)(int, const struct sockaddr *, socklen_t);
int (*real_connect)(int, const struct sockaddr *, socklen_t);
char *bind_addr_env;
unsigned long int bind_addr_saddr;
unsigned long int inaddr_any_saddr;
struct sockaddr_in local_sockaddr_in[] = { 0 };
void _init (void)
{
	const char *err;
	real_bind = dlsym (RTLD_NEXT, "bind");
	if ((err = dlerror ()) != NULL) {
		fprintf (stderr, "dlsym (bind): %s\n", err);
	}
	real_connect = dlsym (RTLD_NEXT, "connect");
	if ((err = dlerror ()) != NULL) {
		fprintf (stderr, "dlsym (connect): %s\n", err);
	}
	inaddr_any_saddr = htonl (INADDR_ANY);
	if (bind_addr_env = getenv ("BIND_ADDR")) {
		bind_addr_saddr = inet_addr (bind_addr_env);
		local_sockaddr_in->sin_family = AF_INET;
		local_sockaddr_in->sin_addr.s_addr = bind_addr_saddr;
		local_sockaddr_in->sin_port = htons (0);
	}
}
int bind (int fd, const struct sockaddr *sk, socklen_t sl)
{
	static struct sockaddr_in *lsk_in;
	lsk_in = (struct sockaddr_in *)sk;
/*	printf("bind: %d %s:%d\n", fd, inet_ntoa (lsk_in->sin_addr.s_addr),
		ntohs (lsk_in->sin_port));*/
if ((lsk_in->sin_family == AF_INET)
		&& (lsk_in->sin_addr.s_addr == inaddr_any_saddr)
		&& (bind_addr_env)) {
		lsk_in->sin_addr.s_addr = bind_addr_saddr;
	}
	return real_bind (fd, sk, sl);
}
int connect (int fd, const struct sockaddr *sk, socklen_t sl)
{
	static struct sockaddr_in *rsk_in;
 
	rsk_in = (struct sockaddr_in *)sk;
/*	printf("connect: %d %s:%d\n", fd, inet_ntoa (rsk_in->sin_addr.s_addr),
		ntohs (rsk_in->sin_port));*/
if ((rsk_in->sin_family == AF_INET)
		&& (bind_addr_env)) {
		real_bind (fd, (struct sockaddr *)local_sockaddr_in, sizeof (struct sockaddr));
	}
	return real_connect (fd, sk, sl);
}

安装及使用

gcc -nostartfiles -fpic -shared bind.c -o bind.so -ldl -D_GNU_SOURCE
strip bind.so
cp -i bind.so /usr/lib/
#使用
BIND_ADDR="192.0.2.100" LD_PRELOAD=/usr/lib/bind.so firefox (*)

编译好的bind文件bind_so_compiled.tar.gz
Robert J. McKay写的bindhack.c源码

/*	
	A simple LD_PRELOAD hack to let you specify the source address
	for all outbound connections or if you want to limit a process
to only listening on one IP
	Copyright (C) 2005 Robert J. McKay <robert@mckay.com>
	License: You can do whatever you want with it.
	Compile:
	gcc -fPIC -static -shared -o bindhack.so bindhack.c -lc -ldl
	You can add -DDEBUG to see debug output.
	Usage:
	LD_PRELOAD=/path/to/bindhack.so <command>
 
	eg:
	LD_PRELOAD=/home/rm/bindhack.so telnet example.com
	you can also specify the address to use at runtime like so:
	LD_PRELOAD=/home/rm/bindhack.so BIND_SRC=192.168.0.1 telnet example.com
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <dlfcn.h>
#include <arpa/inet.h>
/*
   This is the address you want to force everything to use. It can be
   overriden at runtime by specifying the BIND_SRC environment
   variable.
*/
#define SRC_ADDR	"192.168.0.1"
/*
   LIBC_NAME should be the name of the library that contains the real
   bind() and connect() library calls. On Linux this is libc, but on
   other OS's such as Solaris this would be the socket library
*/
#define LIBC_NAME	"libc.so.6"
#define YES	1
#define NO	0
int
bind(int sockfd, const struct sockaddr *my_addr, socklen_t addrlen)
{
	struct sockaddr_in src_addr;
	void	*libc;
	int	(*bind_ptr)(int, void *, int);
	int	ret;
	int	passthru;
	char 	*bind_src;
#ifdef DEBUG
	fprintf(stderr, "bind() override called for addr: %s\n", SRC_ADDR);
#endif
	libc = dlopen(LIBC_NAME, RTLD_LAZY);
	if (!libc)
	{
		fprintf(stderr, "Unable to open libc!\n");
		exit(-1);
	}
	*(void **) (&bind_ptr) = dlsym(libc, "bind");
	if (!bind_ptr)
	{
		fprintf(stderr, "Unable to locate bind function in lib\n");
		exit(-1);
	}
 
	passthru = YES;	/* By default, we just call regular bind() */
	if (my_addr==NULL)
	{
		/* If we get a NULL it's because we're being called
		   from the connect() hack */
		passthru = NO;
#ifdef DEBUG
		fprintf(stderr, "bind() Received NULL address.\n");
#endif
	}
	else
	{
		if (my_addr->sa_family == AF_INET)
		{
			struct sockaddr_in	myaddr_in;
			/* If this is an INET socket, then we spring to
			   action! */
			passthru = NO;
			memcpy(&myaddr_in, my_addr, addrlen);
			src_addr.sin_port = myaddr_in.sin_port;
		}
		else
		{
			passthru = YES;
		}
	}
	if (!passthru)
	{
#ifdef DEBUG
		fprintf(stderr, "Proceeding with bind hack\n");
#endif
		src_addr.sin_family = AF_INET;
		bind_src=getenv("BIND_SRC");
		/* If the environment variable BIND_SRC is set, then use
		   that as the source IP to bind instead of the hard-coded
		   SRC_ADDR one.
		*/
		if (bind_src)
		{
			ret = inet_pton(AF_INET, bind_src, &src_addr.sin_addr);
			if (ret<=0)
			{
				/* If the above failed, then try the
				   built in address. */
				inet_pton(AF_INET, SRC_ADDR,
						&src_addr.sin_addr);
			}
		}
		else
		{
			inet_pton(AF_INET, SRC_ADDR, &src_addr.sin_addr);
		}
	/* Call real bind function */
		ret = (int)(*bind_ptr)(sockfd,
					(void *)&src_addr,
					sizeof(src_addr));
	}
	else
	{
#ifdef DEBUG
		fprintf(stderr, "Calling real bind unmolested\n");
#endif
	/* Call real bind function */
		ret = (int)(*bind_ptr)(sockfd,
					(void *)my_addr,
					addrlen);
	}
#ifdef DEBUG
	fprintf(stderr, "The real bind function returned: %d\n", ret);
#endif
	/* Clean up */
	dlclose(libc);
	return ret;
}
/*
	Sometimes (alot of times) programs don't bother to call bind()
	if they're just making an outgoing connection. To take care of
	these cases, we need to call bind when they call connect
	instead. And of course, then call connect as well...
*/
int
connect(int  sockfd, const struct sockaddr *serv_addr, socklen_t addrlen)
{
	int	(*connect_ptr)(int, void *, int);
	void	*libc;
	int	ret;
#ifdef DEBUG
	fprintf(stderr, "connect() override called for addr: %s\n", SRC_ADDR);
#endif
	/* Before we call connect, let's call bind() and make sure we're
	   using our preferred source address.
	*/
	ret = bind(sockfd, NULL, 0); /* Our fake bind doesn't really need
					those params */
	libc = dlopen(LIBC_NAME, RTLD_LAZY);
	if (!libc)
	{
		fprintf(stderr, "Unable to open libc!\n");
		exit(-1);
	}
	*(void **) (&connect_ptr) = dlsym(libc, "connect");
	if (!connect_ptr)
	{
		fprintf(stderr, "Unable to locate connect function in lib\n");
		exit(-1);
	}
	/* Call real connect function */
	ret = (int)(*connect_ptr)(sockfd, (void *)serv_addr, addrlen);
	/* Clean up */
	dlclose(libc);
	return ret;	
}

参考:http://daniel-lange.com/archives/53-Binding-applications-to-a-specific-IP.html

服务器/路由器/n2n.txt · 最后更改: 2020/09/25 21:07 由 caiweizhi