Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

无网络请求的时候登录失败 #48

Open
bsbds opened this issue Mar 8, 2022 · 15 comments
Open

无网络请求的时候登录失败 #48

bsbds opened this issue Mar 8, 2022 · 15 comments
Labels
bug Something isn't working

Comments

@bsbds
Copy link
Contributor

bsbds commented Mar 8, 2022

在没有其他使用网络的用户软件的情况下运行

# ipgw
using account 'xxxxxxxx'
login failed: 
	unknown reason

任意发一个公网连接请求后就能正常登录

# curl 1.1.1.1        
<script>top.self.location.href='http://202.118.1.87/index_15.html?wlanuserip=xx.xx.xx.xx&wlanacname=NS_Wifi_N18K&ssid=&nasip=202.118.0.11&snmpagentip=&mac=4a806e361ea3&t=wireless-v2-plain&url=http://1.1.1.1/&apmac=&nasid=NS_Wifi_N18K&vid=2008&port=27&nasportid=AggregatePort 1.20080000:2008-0'</script>

# ipgw
using account 'xxxxxxxx'
login successfully
@unbyte
Copy link
Member

unbyte commented Mar 8, 2022

是稳定复现吗

@bsbds
Copy link
Contributor Author

bsbds commented Mar 9, 2022

是, 两台笔记本(arch/freebsd)还有树莓派(debian)上都有这个问题
等待一段时间自动断开后再重新登录就会login failed

@amtoaer
Copy link
Member

amtoaer commented Mar 17, 2022

抱歉,最近在忙春招,没有及时回复。该问题在我 windows 11 上无法复现。😢
当前版本的登录逻辑是请求 ipgw 信息,如果出现网络错误则not in campus network,否则解析IP和用户名信息,IP为空也not in campus network,用户名不为空则"already logged in as '%s'
其它情况,调用登录 api 并重新请求、解析 ipgw 信息,流程内出现错误则返回对应错误。无错误的情况下,查看用户名是否为空,如果用户名为空才返回unknown reason
可见出现unknown reason是要在登录未出错的情况下,获取信息获取不到用户名才行,理论上不太可能出现。
我这边先排查一下是不是登录流程中有些 error 没有返回吧,@bsbds 如果方便的话,可以确认一下 ipgw 是否使用了最新版本与正确架构(因为之前有听说在 arm64 上使用 arm 的 ipgw 会报 unknown reason)。 🤣

@bsbds
Copy link
Contributor Author

bsbds commented Mar 19, 2022

复现方法是在全新安装的系统上(无桌面环境), 使用wpa_supplicant和dhclient连接校园网, 然后用ipgw登录, 确认在 linux(amd64, arm64)和 freebsd(amd64)上都会出现问题, ipgw是编译自最新master分支

试着打印了一下错误, 问题好像是出在这个位置

--- a/pkg/handler/ipgw.go
+++ b/pkg/handler/ipgw.go
@@ -55,6 +55,7 @@ func (h *IpgwHandler) Login(account *model.Account) error {
                        return err
                }
                body, err = h.login(account.Username, password) // 通过用户名、密码登录
+               fmt.Println(body)
        }
 
        if err != nil {
# ipgw
using account 'xxxxxxxx'
{"code":1,"message":"no_response_data_error","Redirect":"","ID":"15"}
login failed: 
	unknown reason

用curl发一个http请求以后就正常了, 猜测是登录认证服务器需要客户端先发送一个http请求后才能登录?

可能有关
https://en.wikipedia.org/wiki/Captive_portal#Implementation

抱歉因为我对网络和go不了解调试能力有限..

@unbyte unbyte added the bug Something isn't working label Mar 19, 2022
@unbyte
Copy link
Member

unbyte commented Mar 19, 2022

那连用两次ipgw,是不是第二次ipgw能成功呢

@bsbds
Copy link
Contributor Author

bsbds commented Mar 19, 2022

那连用两次ipgw,是不是第二次ipgw能成功呢

不能, 重复多次也不行

@unbyte
Copy link
Member

unbyte commented Mar 19, 2022

方便的话可以试一下先curl pass.neu.edu.cn再ipgw能不能成功吗

@bsbds
Copy link
Contributor Author

bsbds commented Mar 19, 2022

不能..
好像这些用于认证的网址都不行, curl其他的url会返回上面发的那个script, 然后就可以登录了

@halozhy
Copy link
Contributor

halozhy commented May 2, 2022

Google了下上面 PR#49 代码里面的 198.18.0.1 ,原来是出自 RFC2544 ,是被分配给基准测试专用的 IP 地址,涨姿势了

前段时间我在一个 ESP8266 单片机上面写了个登录校园网的工具,然后也稳定遇到了第一次登录 ipgw 失败,第二次登录才成功的 bug,当时没太多想,但是第一次登录失败返回的 json 信息确实是 "code":1,"message":"no_response_data_error"

QQ截图20220502171810

这和本 issue 遇到的这个错误信息是一样的,并且我的单片机程序会在 ipgw 认证之后访问一次公网,相当于经过了

ipgw认证 -> 访问公网 -> 失败 -> 重新进行ipgw认证

这样一个流程之后,ipgw 才认证成功,因此我感觉这个 bug 应该可以被稳定复现,在 Windows 上不容易复现可能是因为 Windows 连接网络后就已经发过一些公网请求了,只不过没有被咱们直观感知到

@bsbds
Copy link
Contributor Author

bsbds commented May 3, 2022

Google了下上面 PR#49 代码里面的 198.18.0.1 ,原来是出自 RFC2544 ,是被分配给基准测试专用的 IP 地址,涨姿势了

前段时间我在一个 ESP8266 单片机上面写了个登录校园网的工具,然后也稳定遇到了第一次登录 ipgw 失败,第二次登录才成功的 bug,当时没太多想,但是第一次登录失败返回的 json 信息确实是 "code":1,"message":"no_response_data_error"

QQ截图20220502171810

这和本 issue 遇到的这个错误信息是一样的,并且我的单片机程序会在 ipgw 认证之后访问一次公网,相当于经过了

ipgw认证 -> 访问公网 -> 失败 -> 重新进行ipgw认证

这样一个流程之后,ipgw 才认证成功,因此我感觉这个 bug 应该可以被稳定复现,在 Windows 上不容易复现可能是因为 Windows 连接网络后就已经发过一些公网请求了,只不过没有被咱们直观感知到

嗯,而且必须是http请求,根据维基captive portal的实现里

A common method is to direct all World Wide Web traffic to a web server, which returns an HTTP redirect to a captive portal.

正常的登录流程应该是客户端有一个http请求后重定向到认证网页进行认证

我之前认真看了一下项目代码感觉大概看懂了,所以稍微改了一下,亲测可以正常使用

@unbyte
Copy link
Member

unbyte commented Oct 8, 2022

暂时 revert 了,需要一个更好的解决方案

@halozhy
Copy link
Contributor

halozhy commented Apr 16, 2023

@bsbds 最近又看到这个 issue,结合 unbyte 在 #50 (comment) 里给出的第二个思路

那么发送请求而不等待响应可以解决 #48

我有两个想法

  1. 使用 goroutine 协程发请求 go http.Get("http://198.18.0.1"),这样至少不会阻塞后面正常的认证流程
  2. 使用带 timeout 的 http client 发请求,请求超时就直接结束
c := http.Client{
	Timeout: 100 * time.Millisecond, // 等待100ms就结束请求
}
c.Get("http://198.18.0.1")

我的操作系统是 Windows 10,并不能直接复现这个问题,我尝试过在 Linux 虚拟机环境下复现,但也没能成功,要是你还有复现这个问题的时间和条件的话,可以试一试我的想法

@bsbds
Copy link
Contributor Author

bsbds commented Apr 16, 2023

@bsbds 最近又看到这个 issue,结合 unbyte 在 #50 (comment) 里给出的第二个思路

那么发送请求而不等待响应可以解决 #48

我有两个想法

  1. 使用 goroutine 协程发请求 go http.Get("http://198.18.0.1"),这样至少不会阻塞后面正常的认证流程
  2. 使用带 timeout 的 http client 发请求,请求超时就直接结束
c := http.Client{
	Timeout: 100 * time.Millisecond, // 等待100ms就结束请求
}
c.Get("http://198.18.0.1")

我的操作系统是 Windows 10,并不能直接复现这个问题,我尝试过在 Linux 虚拟机环境下复现,但也没能成功,要是你还有复现这个问题的时间和条件的话,可以试一试我的想法

好的,过段时间没事了再重新来修一下试试

@bsbds
Copy link
Contributor Author

bsbds commented May 1, 2023

今天有时间又测试了一下,用宿舍有线连校园网的captive portal重定向是坏的,不会自动跳转,只有连无线才能正确重定向。同时有线校园网请求 http://198.18.0.1会超时,但是其他ip段不会,可能是校园网内部没有配置对应的路由表。

至于(无线校园网环境)Windows下复现不了的原因是Windows会自动打开浏览器跳转吧,比如Windows识别到网络portal会自动打开浏览器,浏览器(firefox)接下来会请求一个跳转的链接http://detectportal.firefox.com, 之后如果再运行ipgw就无法复现这个问题,如果在裸机Linux环境下肯定是可以复现的。可能无线校园网认证机制是个状态机,通过http请求探测portal才能转移到准备认证的状态,有线校园网可能是没有设置这一步。

将之前的代码改成请求一个url是可行的,这样不会超时,例如c.Get("http://detectportal.firefox.com") , 并且为了更保险可以像 @halozhy 指出的可以加上较短的timeout (goroutine不可以是因为必须先请求再进行后续流程才不会出错)。

你们觉得这样如何 @unbyte @halozhy

@halozhy
Copy link
Contributor

halozhy commented May 2, 2023

我这边确实是缺少一个裸机 Linux 环境来复现问题🙁,如果这个方案在你那边的环境下可以解决问题了,我觉得就 OK

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants