ngrok反向隧道--获取内网IP
ngrok反向隧道
前情提要:小明与小白各有一台主机,两台主机在同一内网,小明想直接通过内网ssh到小白的主机上。但是小白的ip地址会不断的变化,而小明不想每次都要麻烦小白查看ip。于是小明催生了一个想法:写个脚本在自己的主机运行输出小白的ip。
01 获取本机ip地址
> cat ip-server.c
#include <stdio.h>
#include <sys/socket.h>
#include <unistd.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <arpa/inet.h>
#define SERVER_PORT 20000 // define the defualt connect port id
#define LENGTH_OF_LISTEN_QUEUE 10 // length of listen queue in server
#define BUFFER_SIZE 255
unsigned long getNumIP(char* dev){//eth0
int fd;
struct ifreq ifr;
fd = socket(AF_INET, SOCK_DGRAM, 0);
/* I want to get an IPv4 IP address */
ifr.ifr_addr.sa_family = AF_INET;
/* I want IP address attached to "eth0" */
strncpy(ifr.ifr_name, dev, IFNAMSIZ-1);
int rtn=ioctl(fd, SIOCGIFADDR, &ifr);
close(fd);
if(rtn==-1) return rtn;
/* display result */
unsigned long numIP=((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;
return numIP;
}
int main(int argc, char** argv)
{
int servfd,clifd;
struct sockaddr_in servaddr,cliaddr;
if ((servfd = socket(AF_INET,SOCK_STREAM, 0 )) < 0 )
{
printf( " create socket error!\n " );
exit( 1 );
}
bzero( & servaddr, sizeof (servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERVER_PORT);
servaddr.sin_addr.s_addr = htons(INADDR_ANY);
if (bind(servfd,( struct sockaddr * ) & servaddr, sizeof (servaddr)) < 0 )
{
printf( " bind to port %d failure!\n " ,SERVER_PORT);
exit( 1 );
}
if (listen(servfd,LENGTH_OF_LISTEN_QUEUE) < 0 )
{
printf( " call listen failure!\n " );
exit( 1 );
}
while ( 1 )
{ // server loop will nerver exit unless any body kill the process
char buf[BUFFER_SIZE];
long timestamp;
socklen_t length = sizeof (cliaddr);
clifd = accept(servfd,( struct sockaddr * ) & cliaddr, & length);
if (clifd < 0 )
{
printf( " error comes when call accept!\n " );
break ;
}
// inet_ntop(INET_ADDRSTRLEN,cliaddr.sin_addr,buf,BUFFER_SIZE);
//////////
unsigned long numIP=getNumIP("ppp0");
if(numIP==-1)//-1 error
numIP=getNumIP("eth0");
//printf("eth0:%lld\n",numIP);
if(numIP==-1) numIP=getNumIP("wlan0");
if(numIP==-1) numIP=0;
struct in_addr iaddr;
iaddr.s_addr=numIP;
char* ip = inet_ntoa(iaddr);
////////
strcpy(buf, ip );
send(clifd,buf,strlen(buf), 0 );
close(clifd);
} // exit
close(servfd);
return 0 ;
}
编译
> gcc ip-server.c -o ip-server
02 启动ngrok客户端
这里使用的是1.7版本,官方的2.0及之后非开源。
> cat start_ngrok.sh
#可以加入开机自启动脚本,如/etc/rc.local中
PRE=$HOME/bin/ngrok
NGROK_DIR=$PRE/ngrok1.7
$PRE/ip-server &
$NGROK_DIR/ngrok -log=stdout -config=$NGROK_DIR/ngrok.cfg -subdomain theUniqName 20000 > /dev/null 2>&1 &
其中ngrok.cfg中指定如下的内容:
server_addr: "xxxHostName:4443"
trust_host_root_certs: false
启动ngrok后,服务器xxxHostName上会开通一个子域名theUniqName,通过访问theUniqName.xxxHostName:80可以获取到ngrok客户端机器上的20000端口的内容。
在不添加-subdomain参数时服务端会选择一个未使用的端口,建立到你的本地的隧道。每次你重新建立隧道时给你分配的端口很可能不同。
另外还可以使用sunny博客博主提供的ngrok服务(www.ngrok.cc),用户注册后可以创建固定端口的隧道,并分配一个clientID,ngrok启动时指定这个clientID即可。
03 测试使用
在其他机器上通过curl来获取(因为ip-server程序中仅仅输出一行ip地址,而没有http头部信息,所以curl会检测出来并直接输出原内容)
> curl 隧道地址
另外,随手附上终止ngrok程序的脚本(ngrok在连接不到服务器时可能会不断尝试连接而不是自行退出)
> cat stop.sh
pid_1=$(ps ax|grep [i]p-server|awk '{print $1}')
pid_2=$(ps ax|grep [n]grok1.7/ngrok|awk '{print $1}')
if [ -z $pid_1 ];then
echo 'ip_server not running'
else
kill $pid_1
fi
if [ -z $pid_2 ];then
echo 'ngrok not running'
else
kill -9 $pid_2
fi
echo 'stopped ip-server and ngrok!'
04 END
反向隧道通常用来打通内网主机与公网主机的连接,可以方便web开发等。那么它与ssh反向隧道相比有什么优势呢?除了可以创建子域名的方式比较方便外,暂时也不太清楚,但是比ssh功能上要纯粹的多。
ngrok反向隧道--获取内网IP的更多相关文章
- 通过js获取内网ip和外网ip的简单方法 ...
今天遇到了一个需求,需要获取用户当前的内网ip, 找了半天终于找到了方法,遂将找到的方法记录下来,留给需要的人. 1,获取内网ip function getIP(callback) { let rec ...
- xss实现获取内网ip
前提得浏览器支持webRTC,测试的时候google浏览器测试成功,火狐浏览器不支持webRTC, 再在xss平台直接复制如下js代码: function form_ip(ip,port){ var ...
- JAVA 优先获取外网Ip,再获取内网Ip
1.获取内网Ip private String getLocalhostIp(){ String hostAddress = ""; try { InetAddress addre ...
- Python获取内网IP
Python 获取本机内网IP 本文记录使用Python获取本机IP的两种方法. 通过hostname来获取本机IP import socket print(socket.gethostbyname( ...
- (转)js获取内网ip地址,操作系统,浏览器版本等信息
这次呢,说一下使用js获取用户电脑的ip信息,刚开始只是想获取用户ip,后来就顺带着获取了操作系统和浏览器信息. 先说下获取用户ip地址,包括像ipv4,ipv6,掩码等内容,但是大部分都要根据浏览器 ...
- 获取本机外网ip和内网ip
获取本机外网ip //获取本机的公网IP public static string GetIP() { string tempip = ""; try { WebRequest r ...
- js获取设备内网ip
可以直接使用,不需要导入其他配置 看代码 1 <script> 2 //获取内网ip 3 var RTCPeerConnection = window.RTCPeerConnection ...
- 根据Request获取客户端IP 内网IP及外网IP
在JSP里,获取客户端的IP地址的方法是:request.getRemoteAddr() ,这种方法在大部分情况下都是有效的.但是在通过了Apache,Squid等反向代理软件就不能获取到客户端的真实 ...
- C#获取内网和外网IP
写了个小客户端,里面用到了获取内网和外网的IP地址,代码如下: // InnerIP var ipHost = Dns.Resolve(Dns.GetHostName()); ]; innerIP = ...
随机推荐
- Java设计模式 -- 基本原则
这两个星期开始系统地学习设计模式相关的知识,对每一个原则或者设计模式主要从下面几点分析学习: 定义:简单地描述其作用 解决问题:说明该原则或设计模式解决什么限制条件下的问题. 结构图:绘制相关例子的U ...
- EL表达式的算术运算
一个例子--乘法运算 ${book.bookCount * book.bookPrice } 两个不同对象的EL表达式的算术运算同理 ${student.studentNum * book.bookP ...
- Angular的自定义指令以及实例
本文章已收录于: AngularJS知识库 分类: javascript(55) http://www.cnblogs.com/xiaoxie53/p/5058198.html 前面的文章介 ...
- Android 5.X新特性之为RecyclerView添加下拉刷新和上拉加载及SwipeRefreshLayout实现原理
RecyclerView已经写过两篇文章了,分别是Android 5.X新特性之RecyclerView基本解析及无限复用 和 Android 5.X新特性之为RecyclerView添加Header ...
- APP级别处理未捕获异常
前言: 项目APP有时候会出现Crash,然后就是弹出系统强制退出的对话框,点击关闭APP. 有的APP进行了处理,会发现,当程序出现异常的时候,会Toast一个提示"程序出现异常,3秒后将 ...
- WKWebView浅析
原文链接:supermokey WKWebView 一个WKWebView对象展示交互的web内容,例如应用于app内的浏览器.你可以在你的App中使用WKWebView. 综述 Important: ...
- (十一)Maven远程仓库的各种配置
1.远程仓库的配置 在平时的开发中,我们往往不会使用默认的中央仓库,默认的中央仓库访问的速度比较慢,访问的人或许很多,有时候也无法满足我们项目的需求,可能项目需要的某些构件中央仓库中是没有的,而在其他 ...
- LintCode389.判断数独是否合法
LintCode简单题:判断数独是否合法 问题描述: 请判定一个数独是否有效. 该数独可能只填充了部分数字,其中缺少的数字用 . 表示. 注意事项: 一个合法的数独(仅部分填充)并不一定是可解的.我们 ...
- 转载 NPOI Excel 单元格背景颜色对照表
NPOI Excel 单元格颜色对照表,在引用了 NPOI.dll 后可通过 ICellStyle 接口的 FillForegroundColor 属性实现 Excel 单元格的背景色设置,FillP ...
- Sublime Text 3 快捷键总结
以下是个人总结不完全的快捷键总汇,祝愿各位顺利解放自己的鼠标. 选择类 Ctrl+D 选中光标所占的文本,继续操作则会选中下一个相同的文本. Alt+F3 选中文本按下快捷键,即可一次性选择全部的相同 ...