nc命令实现端口转发
简介
nc命令可以建立一个裸的tcp连接,可以用来测试端口连通性、扫描端口、传递文件、端口转发等,本文介绍其端口转发原理。
实例
首先在本地起一个简单的http服务,监听在8080端口,用curl访问
1 | curl 127.0.0.1:8080 -i |
建立一个管道
1 | mkfifo nc_pipe |
建立端口映射后访问1234端口
1 | nc -l 1234 < nc_pipe | nc 127.0.0.1 8080 > nc_pipe |
可以看到访问1234端口和访问8080端口效果一样,即把8080端口映射道路1234端口。
解释
首先使用mkfifo
建立了一个双向管道,使1234和8080数据可以双向传输。
拆解下管道符|两侧的命令:nc -l 1234
这条命令表示起了一个裸的tcp服务监听在1234端口,假如只运行这一条命令,然后用curl访问1234端口看会发送什么,分别开两个shell窗口运行如下两条命令
1 | nc -l 1234 |
可以看到当curl访问时,curl命令一直阻塞,而nc -l 1234
这条命令的shell窗口返回了如下字段
1 | GET / HTTP/1.1 |
定睛一看,这不就是标准的HTTP请求格式么,然后这段输出会通过管道符|传递给nc 127.0.0.1 8080
命令,这就相当于1234端口给8080端口发送了一个http请求,接着nc 127.0.0.1 8080
带着http请求值请求8080端口,然后这条命令的返回值,也就是http的返回值被重定向到了nc_pipe这个双向管道,然后这个管道里的值通过nc -l 1234 < nc_pipe
这条命令又被送回给了1234端口,然后此时1234端口这个http返回值就返回给了curl请求。总结起来就是1234端口类似于一个中转站,接收curl请求的值,然后请求8080端口再把返回值通过双向管道获取到然后原封不定返回给curl,nc的连接是一个裸的tcp连接,因此对于从curl请求接收的值在nc看来就是一组报文,这个报文就是http格式的,包含了请求Method、路由、Host、User-Agent、Accept等字段,虽然他并不认识这些字段,但是他只管把这些数据发送到8080端口然后再将返回值原封不动返回即可,因此看到的效果是我们仅仅使用nc起了一个裸的tcp服务却可以达到http服务的效果。