惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

爱范儿
爱范儿
aimingoo的专栏
aimingoo的专栏
Y
Y Combinator Blog
Vercel News
Vercel News
Blog — PlanetScale
Blog — PlanetScale
有赞技术团队
有赞技术团队
P
Proofpoint News Feed
WordPress大学
WordPress大学
V
V2EX
The Register - Security
The Register - Security
博客园 - 聂微东
酷 壳 – CoolShell
酷 壳 – CoolShell
博客园 - Franky
D
DataBreaches.Net
G
Google Developers Blog
O
OpenAI News
S
Schneier on Security
Simon Willison's Weblog
Simon Willison's Weblog
I
Intezer
Engineering at Meta
Engineering at Meta
Recorded Future
Recorded Future
T
Threatpost
The Hacker News
The Hacker News
Cisco Talos Blog
Cisco Talos Blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
B
Blog RSS Feed
Apple Machine Learning Research
Apple Machine Learning Research
T
The Exploit Database - CXSecurity.com
L
LINUX DO - 热门话题
G
GRAHAM CLULEY
博客园 - 叶小钗
V
Vulnerabilities – Threatpost
云风的 BLOG
云风的 BLOG
L
LINUX DO - 最新话题
MyScale Blog
MyScale Blog
L
LangChain Blog
Scott Helme
Scott Helme
大猫的无限游戏
大猫的无限游戏
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
雷峰网
雷峰网
Google Online Security Blog
Google Online Security Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
N
News | PayPal Newsroom
NISL@THU
NISL@THU
M
MIT News - Artificial intelligence
Cloudbric
Cloudbric
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
The Cloudflare Blog
Recent Announcements
Recent Announcements

NickChenyx's Blog

Create_Rubbish Create_Rubbish Create_Rubbish Create_Rubbish Create_Rubbish Create_Rubbish Create_Rubbish Create_Rubbish Create_Rubbish Create_Rubbish Create_Rubbish Create_Rubbish Create_Rubbish Create_Rubbish Create_Rubbish Create_Rubbish Create_Rubbish Create_Rubbish Create_Rubbish Create_Rubbish Create_Rubbish Create_Rubbish Create_Rubbish Create_Rubbish Create_Rubbish Create_Rubbish Create_Rubbish Create_Rubbish Create_Rubbish Create_Rubbish Create_Rubbish Create_Rubbish Create_Rubbish
Create_Rubbish
nickChen · 2018-04-18 · via NickChenyx's Blog

端口扫描工具

工具如其名,主要功能是扫描服务器端口是否开放。常用的方式是扫描服务器(S)在某一段端口(P)范围内,有哪些端口正在被监听。

如:扫描服务器 127.0.0.1,端口 [80, 2000)段内,查看被监听的端口。

实现方案

  • 和对端服务器端口尝试建立 socket 链接,如果链接成功建立,则表明该端口正在被监听。
  • 使用多线程方案,加快端口扫描速度
  • 使用协程方案,降低资源使用,加快扫描速度

以上就是大致的是实现步骤。本次实现了

  • Java 单线程扫描
  • Java 多线程扫描
  • Java 协程扫描
  • Rust 协程扫描

没错,>..< 实际上这是一次学习 Java Quasar Fiber 和 Rust 过程中的小练习。

实现代码

实现已放在 github 仓库,感兴趣的可以下载自行运行。

遇到的问题

Java Fiber 和 Rust 的实现过程中都遇到了关于协程使用上的问题,在此记录一下。

Java Fiber

首先需要在函数上标明 @Suspendable,协程内的阻塞函数需要标记此注解才能让协程正常服务。

其次协程中使用的阻塞函数,需要有自己的封装实现。线程方式中使用 java.net.Socket#connect 函数是调用的 JDK 原生实现 java.net.PlainSocketImpl#socketConnect
这个实现是阻塞的,此阻塞的实现,会影响阻塞住协程,使得协程的性能无法发挥。
Quasar 为此单独提供了 FiberSocketChannel 实现,此实现调用了 co.paralleluniverse.fibers.io.AsyncFiberSocketChannel#connect
底层是异步 IO 实现,使用 Fiber.park 接替了原有的阻塞实现。

使用过程中可以感受到,使用 Fiber 接替现有的代码,还是有需要改造的部分,无法零成本接入。(此处如果我有使用不合理的地方,请邮件我改进,谢谢

Rust

Rust 版本实现中,使用了三方依赖 may 作为 coroutine 的实现依赖。出现了同 Java 版本类似的问题。
原生的 std::net::TcpStream 依然会阻塞住协程,还是需要使用 may 提供的异步 IO 实现 may::net::TcpStream 才能匹配协程提升性能。

另外就是 Rust 的 TcpStream::connect_timeout 使用方式不能按照官方提供的文档使用。

use std::net::TcpStream;

if let Ok(stream) = TcpStream::connect("127.0.0.1:8080") {
    println!("Connected to the server!");
} else {
    println!("Couldn't connect to server...");
}

按照此方法使用 TcpStream::connect_timeout,会导致 if 判断提前进入 else 逻辑,造成逻辑异常。
必须将链接建立的语句提前,才能逻辑正常。

// 正确实现
let stream = TcpStream::connect_timeout(&addrs[0], timeout);
if stream.is_ok() {
    stream.unwrap().shutdown(Shutdown::Both).expect("shutdown tcp stream fail");
    return true;
} else {
    return false;
}

诡异的问题

实现 Rust 版本的测试结果中,出现了诡异的问题。问题描述如下:

使用 rdial --start-port 80 --end-port 9000 --hostname 127.0.0.1 --timeout 200 执行时,
结果返回了 [1080, 4198] 两个接口,实际上 6394 接口也是在被监听,但没有被扫描出来。
修改使用 rdial --start-port 6000 --end-port 9000 --hostname 127.0.0.1 --timeout 200 执行时,
此时结果返回了 6394 接口。

经过 debug 确认了所有端口都有的的确确被扫描到,并没有漏掉 6394 端口。

继续尝试增加 timeout 超时时间,发现还是无法扫描到 6394 端口,但是有个特殊现象——6394 端口在建立链接语句执行后,立马返回了“close”日志,并没有经过设置好的等待时间。

最后发现问题是在操作系统限制的 fd 上,使用 ulimit -n 发现此时设置为 4864,可以看到我们的扫描程序第一次执行的确扫描到了 4198 这个接口监听,而忽略了 6394 这个接口。

答案呼之欲出,执行 ulimit -n 10000 将 fd 限制提升到 10000 之后再次执行,此时返回结果 [1080, 4198, 6394],问题解决。


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 nickchenyx@gmail.com