0xFF 引言

最近入手了个路由器,用来接校园网的宽带(神秘校园网只允许一个设备同时接入..)
正当我在想Wifi名的时候,突然想整个活,于是便设置成了Ciallo~ (∠・ω )⌒☆
密码也是喜闻乐见的0d000721

但设置好后突然感觉不对:这不是相当于公开了我花钱办的宽带了吗🤔于是便想改

但最后思来想去还是不想放弃这个Wifi名称,于是便设法实现了使用两个不同密码
连接会有不同响应的Wifi。具体来说,同一个名为Ciallo~ (∠・ω )⌒☆的网络,
使用0d000721连接就只会弹一个带图片的网址,
而使用另外一个密码连接才能正常上网。

0x00 准备工作

想要实现上述效果,需要:

  • 一台已刷OpenWrt的路由器(关于路由器的选购与刷机这里不赘述)
  • 基础Shell操作知识
  • 正常的网络连接

注意:

  • 本教程使用的OpenWrt版本为25.XX,不建议在更早的版本上使用本教程,
    ,因为不同版本间的差异较大,可能会无法使用或造成故障。
  • 搞机有风险,操作需谨慎🥹

0x01 连接网络

如果你的路由器已经连接到网络,可以跳过本节。

打开OpenWrt的管理页面,选择网络>无线。这里便是管理你设备的无线网络的地方。

这里我们使用客户端模式连接到网络并做中继。
点击任意radio扫描按钮打开网络扫描,在弹出的框中
选择要连接的网络点击加入网络,之后在WPA 密钥中输入
密码,点击提交,再点击保存,最后点击最下面的保存并应用
等待设置更新。

这里不同的radio可能分别代表的是2.4GHz和5GHz的天线,具体取决于你自己的设备。
图中以802.11ax/b/g/n结尾的为2.4GHz天线,以802.11ac/ax/n结尾的为5GHz天线。

0x02 创建Wifi

接着我们创建需要使用不同密码连接的Wifi。

点击任意radio添加按钮打开网络扫描,在弹出的框中翻到最下面,
ESSID框中输入要使用的Wifi名称。

切换到无线安全,将加密改为WPA2-PSK,之后在密钥中输入真实的密码(之后能够正常联网的密码)

点击保存,最后点击最下面的保存并应用,等待设置更新。

0x03 升级dnsmasq-full

首先由于我使用的是OpenNDS来做弹出的页面,所以需要将dnsmasq包升级为完整版。

在Shell中输入以下命令:

1
apk update && apk add dnsmasq-full

看到形如OK: XXX MiB in XXX packages的结果即可。

0x04 配置Multi-PSK

使用Shell编辑/etc/config/wireless

关于Shell中的文本编辑器Vim的操作,请详见此文章

以下是一个示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
config wifi-device 'radio0'
......

config wifi-iface 'default_radio0'
......

config wifi-device 'radio1'
......

config wifi-iface 'wifinet3'
option device 'radio1'
option network 'lan'
option mode 'ap'
option ssid 'hyw'
option encryption 'psk2'
option key 'ThisIsTheTruePassword'

config wifi-iface 'wifinet2'
option device 'radio1'
option network 'wwan'
option ssid 'ExampleWifi'
......

可以看到,在config wifi-iface 'default_radio1'配置块中有我们刚刚创建的Wifi,
config wifi-iface 'wifinet2'配置块中有我们刚刚连接的Wifi。

接下来对配置文件做以下更改:

1.启用MultiPSK

在创建的Wifi的配置块中加入option multi_psk '1'
之后你的配置应该像这样:

1
2
3
4
5
6
7
8
config wifi-iface 'wifinet3'
option device 'radio1'
option network 'lan'
option mode 'ap'
option ssid 'hyw'
option encryption 'psk2'
option key 'ThisIsTheTruePassword'
option multi_psk '1'

2.添加wifi-vlan

在文件底部添加以下配置:

1
2
3
4
5
config wifi-vlan
option name 'g_v'
option network 'guest'
option vid '10'
option iface 'wifinet3'

注意:

  • 这里的wifinet3为我们创建的wifi的wifi-iface的名字,见上面的示例配置。
  • 这里的name可以任取但是不能太长,具体限制在不同设备上
    可能不同,但建议只使用3~4个字符。
  • vid10networkguest均可自定义,不过之后需要保证配置能够对的上。

3.添加wifi-station

继续在文件底部添加以下配置:

1
2
3
4
config wifi-station
option key '0d000721'
option vid '10'
option iface 'wifinet3'

注意:

  • 这里的key即为假密码,即无法正常上网的密码。
  • 这里的vidiface要和上面匹配。

编辑完成,保存文件进行下一步。

0x05 添加设备与接口

打开OpenWrt管理面板,进入网络>接口,切换到设备页面,点击最下面的添加设备配置

在弹出的窗口中,将设备类型选为网桥设备,
设备名称设为br-guest(可以自己改),选中允许启动空网桥,然后点击保存

接着切换回接口页面,点击下面的添加新接口
将名称设置为guest(注意和上面的匹配),将协议设置为静态地址,将设备选为br-guest(和上面创建的匹配),然后点击创建接口

接着在弹出的窗口中,将IPv4 地址设置为192.168.72.1(可以任意设置,但要和你正常使用的主网络不同),将IPv4 子网掩码设置为255.255.255.0

然后点击上面的防火墙设置,点击创建/分配防火墙区域,在最下面的自定义框中输入guest_zone(可以自己起名)然后按回车。

最后点击上面的DHCP 服务器,然后点击配置 DHCP 服务器按钮,不用变更配置。

最后点击保存关闭配置窗口,点击最下面的保存并应用,等待设置更新。

0x06 安装OpenNDS

OpenNDS的作用本来一般是提供上网认证界面,但这里我们使用它来做弹出图片的效果。

打开Shell,输入以下命令:

1
apk update && apk add opennds

之后编辑/etc/config/opennds,找到option gatewayinterface
(我设备上是第308行,可以使用查找功能查找),
将其取消注释并把后面的值换成上面配置的设备的名称。

更换之后配置应该如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
...

# GateWayInterface
# Default br-lan
# Use this option to set the device opennds will bind to.
# The value may be an interface section in /etc/config/network or adevice name such as br-lan.
# The selected interface must be allocated an IPv4 address.
# In OpenWrt this is normally br-lan, in generic Linux it might besomething else.
#
option gatewayinterface 'br-guest'
##################################################################

...

保存文件,进行下一步。

0x07 配置弹出页面

编辑/usr/lib/opennds/theme_click-to-continue-basic.sh
将里面的内容全部删除,替换成下面的:

1
2
3
#!/bin/sh
cat /etc/opennds/htdocs/splash.html
exit 0

之后保存文件。

然后编辑/etc/opennds/htdocs/splash.html(即上面配置的文件),将原有内容(如果有)全部删除,替换成你想要的内容。

在使用假密码登录时,OpenNDS会拦截链接并把/etc/opennds/htdocs/splash.html里面的HTML提供给登录者作为登录界面,所以这里可以自由发挥。

值得注意的是,由于使用假密码连接的时候没有网络连接,所以如果想要插入图片的话不能使用图床,因为无法访问。这里我为了方便直接使用了Base64硬编码图片到splash.html里。

另外,由于存在缓冲区大小限制,splash.html不能太长,所以如果要使用Base64添加图片的话需要对图片进行充分压缩。

以下是我的配置:

1
2
3
4
5
6
7
8
9
10
<!DOCTYPE html>
<html>
<head>
<title>Ciallo~ (∠・ω )⌒☆</title>
</head>
<body>
<h1>Ciallo~ (∠・ω )⌒☆</h1><br>
<img width="300px" id="ciallo" alt="ciallo" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAgCAIAAADvz6...(太长了省略)" />
</body>
</html>

保存文件,至此配置已经全部完成。

0x08 重启服务

使用以下命令重启服务:

1
2
3
4
/etc/init.d/network restart
wifi reload
/etc/init.d/dnsmasq restart
/etc/init.d/opennds restart

之后应该就可以看到创建的Ciallo~ (∠・ω )⌒☆Wifi了。

0x09 遇到问题?

由于本人之前也没有接触过OpenWrt,在尝试实现这个效果的过程中也是在摸索,
所以如果各位遇到了一些问题我可能无法进行有效的解答。不过这里有些我
遇到过的问题,供大家参考。

在配置完OpenNDS并重启后无法访问LuCI?

这一般是因为OpenNDS没有被正确配置(即gatewayinterface没有与前面
创建的设备匹配),导致它将所有网络连接全部拦截。

遇到这种情况时,使用Shell登录,并执行/etc/init.d/opennds stop
来停止OpenNDS,之后应该就能恢复LuCI访问。
为了解决问题,请参照上面的步骤正确配置之后,再运行/etc/init.d/opennds start
恢复OpenNDS,看看是否正常工作。

重启服务后找不到添加的Wifi?

这可能是因为你的wifi-vlan块中的name过长,
请参照上面的步骤将其改短后再执行wifi reload看看。

END.

0x00 引言

本部分没有任何干货,可以直接跳过

在我刚学习写代码的时候,经常做一些命令行的小程序玩(因为GUI还不会做()),
虽然能够实现我想要的功能,但这极致简约风格的黑底白字我是实在看得不得劲。
再加上之后跑各种程序的时候又见识到了各种大佬的命令行程序,才知道CLI程序
做的不好看原来触及到的是我的上限而非终端的上限😭

我做的:
有点弱
有点弱
别人做的:
Description 2
!?强强?!

于是我就去了解了一下CLI程序到底该怎么做得美观,自己也写了一些好看一点的小程序,
便于此留下学习经验供各位参考。

本文章作为CLI程序美化系列(可能会存在)的第一篇文章,从最基础的\r开始介绍,
初步实现行刷新功能。在之后的文章中,我会介绍使用ANSI实现彩色、样式输出和
全屏渲染控制,和使用JLine读取键盘输入实现交互的方法。

0x01 \r 是什么

在大部分情况下,\r指的是回车。这里的回车换行不同,前者是将光标移动到行首,后者是将光标移动到下一行。而我们知道,当光标位于一行的行首时,再输出文字,就可以将已经输出的文字覆盖掉。如果根据程序运行情况实时覆盖,就能起到动态进度条、状态栏等的效果。

0x02 \r 的简单使用

要使用\r的话,直接输出即可。下面是一个例子:

1
2
3
4
System.out.print("正在加载中..."); // 不能使用println()
// Doing something ...
Thread.sleep(2000);
System.out.print("\r加载完成! "); // 加空格补齐长度

这里有几点需要注意:

首先部分IDE内置的运行调试窗口可能不支持光标移动的操作,所以可能需要进行
额外设置,或是手动编译运行。

其次在输出待覆盖文字时不能换行,即不能调用println()或者加\n
否则光标就会移动到下一行,而无法覆盖上一行的文字。

最后如果要覆盖的文字的长度比被覆盖的文字短,则不会被完全覆盖,所以必要
时需要使用空格补齐

0x03 使用\r制作带进度条的下载器

以下程序实现了一个命令行下载器,并将下载进度动态更新至进度条。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.Scanner;

public class CLIDownloader {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);

System.out.print("请输入下载地址: ");
String fileURL = scanner.nextLine();
System.out.print("请输入保存的文件名: ");
String saveFileName = scanner.nextLine();
System.out.println("连接中,准备开始下载...");

try {
URL url = new URL(fileURL);
URLConnection conn = url.openConnection();
long totalBytes = conn.getContentLengthLong();

InputStream in = conn.getInputStream();
FileOutputStream out = new FileOutputStream(saveFileName);

byte[] buffer = new byte[64 * 1024];
int bytesRead;
long downloadedBytes = 0;

while ((bytesRead = in.read(buffer)) != -1) {
out.write(buffer, 0, bytesRead);
downloadedBytes += bytesRead;
// 借助 \r 打印动态进度条
if (totalBytes > 0) {
int percent = (int) (downloadedBytes * 100 / totalBytes);
StringBuilder bar = new StringBuilder("[");
for (int i = 0; i < 50; i++) {
bar.append(i < percent / 2 ? "=" : " ");
}
bar.append("]");
// \r 让光标回到行首,实现覆盖刷新
System.out.print("\r" + bar + " " + percent + "%");
}
}

in.close();
out.close();
System.out.println("\n下载完成!文件已保存为: " + saveFileName);
} catch (Exception e) {
System.out.println("\n下载出错: " + e.getMessage());
e.printStackTrace();
} finally {
scanner.close();
}
}
}

虽然本文章使用Java进行演示、但大部分编程语言理论上都支持使用\r进行光标移动操作🤔

运行演示:

demo

0x04 总结

相比于其他美化控制台程序的方法来说,使用\r是最简单直接的一种。
虽然只能实现单行文本的刷新,但已经能够满足大部分轻量程序的要求。
而如果想要进一步美化CLI程序(颜色输出、全屏渲染控制、接收键盘控制等)
则需要使用更高级的一些方法,例如ANSIJLine库(Java),之后可能
会写一些教程qw

其实当程序使用上述技术后,就从CLI(Command Line Interface)
程序进化为TUI(Text User Interface)程序了😋

0%