如何升级Kali linux系统?

在 /etc/apt/sources.list 里原来的内容全部删除,改为:

deb https://http.kali.org/kali kali-rolling main non-free contrib
deb-src https://http.kali.org/kali kali-rolling main non-free contrib

# apt update
Hit:1 http://dl.google.com/linux/chrome/deb stable InRelease
Hit:2 https://mirrors.neusoft.edu.cn/kali kali-rolling InRelease
Reading package lists... Done
Building dependency tree
Reading state information... Done
879 packages can be upgraded. Run 'apt list --upgradable' to see them.

以下命令查看可以升级的所有安装包:
apt list --upgradable

现在我们有两个选择,如果安装固定包,执行:apt install PACKAGE-NAME
如果安装所有,执行 apt upgrade
#apt upgrade
这个命令需要执行很长时间,大约需要30分钟后升级完成。
中途有2个问题需要回答,有些服务需要重启,按yes不再提示,直接重启:

There are services installed on your system which need to be restarted when certain libraries, such as libpam, libc, and libssl, are
upgraded. Since these restarts may cause interruptions of service for the system, you will normally be prompted on each upgrade for the list
of services you wish to restart. You can choose this option to avoid being prompted; instead, all necessary restarts will be done for you
automatically so you can avoid being asked questions on each library upgrade.

Restart services during package upgrades without asking? [yes/no]

另外还有一个irc帐号的提示,需要改变用户目录:
Change the home directory of user "irc" from /var/run/ircd to /run/ircd

If you allow this change, a backup of modified files will be made with the extension .org, which you can use if necessary to restore the
current settings. If you do not make this change now, you can make it later with the update-passwd utility.

Do you want to change the home directory of user irc? [yes/no]
敲入yes继续吧。

由于软件包相关性的更改,某些Kali Linux软件包可能会保留下来。
这种情况下,在Kali Linux升级过程结束时,apt upgrade Linux命令将通知您可以使用 apt install PACKAGE-NAME 命令分别升级每个保留的软件包。
也可以一次更新所有保留的软件包:apt dist-upgrade

卸载不再需要的软件包
在初始系统升级期间,某些软件包可能会过时,因此不再需要。要删除所有不再需要的Kali Linux软件包,请执行:
apt autoremove

如何用OkHttp实现WebSocket长连接

如何用OkHttp实现WebSocket长连接

WebSocket介绍

先简单介绍下WebSocket。我们都知道Http是处于应用层的一个通信协议,但是只支持单向主动通信,做不到服务器主动向客户端推送消息。而且Http是无状态的,即每次通信都没有关联性,导致跟服务器关系不紧密。为了解决和服务器长时间通信的痛点,HTML5规范引出了WebSocket协议是一种建立在TCP协议基础上的全双工通信的协议。他跟Http同属于应用层协议,下层还是需要通过TCP建立连接。

但是,WebSocket在TCP连接建立后,还要通过Http进行一次握手,也就是通过Http发送一条GET请求消息给服务器,告诉服务器我要建立WebSocket连接了,你准备好哦,具体做法就是在头部信息中添加相关参数。然后服务器响应我知道了,并且将连接协议改成WebSocket,开始建立长连接。

这里贴上请求头和响应头信息,从网上找了一张图:

如何用OkHttp实现WebSocket长连接
用OkHttp实现WebSocket长连接

简单说明下参数:

URL一般是以 ws或者 wss开头, ws对应 Websocket协议, wss对应在 TLS之上的 WebSocket。类似于 Http和 Https的关系。
请求方法为GET方法。
Connection:Upgrade,表示客户端要连接升级,不用Http协议。
Upgrade:websocket, 表示客户端要升级建立 Websocket连接。
Sec-Websocket-Key:key, 这个key是随机生成的,服务器会通过这个参数验证该请求是否有效。
Sec-WebSocket-Version:13, websocket使用的协议,一般就是13。
Sec-webSocket-Extension:permessage-deflate,客户端指定的一些扩展协议,比如这里 permessage-deflate就是 WebSocket的一种压缩协议。
响应码101,表示响应协议升级,后续的数据交互都按照Upgradet指定的 WebSocket协议来。

OkHttp实现

添加OkHttp依赖
implementation("com.squareup.okhttp3:okhttp:4.7.2")
实现代码
首先是初始化OkHttpClient和WebSocket实例:

/**
* 初始化WebSocket
*/
public void init() {
mWbSocketUrl = "ws://echo.websocket.org";
mClient = new OkHttpClient.Builder()
.pingInterval(10, TimeUnit.SECONDS)
.build();
Request request = new Request.Builder()
.url(mWbSocketUrl)
.build();
mWebSocket = mClient.newWebSocket(request, new WsListener());
}

这里主要是配置了OkHttp的一些参数,以及WebSocket的连接地址。其中newWebSocket方法就是进行WebSocket的初始化和连接。

这里要注意的点是pingInterval方法的配置,这个方法主要是用来设置WebSocket连接的保活。相信做过长连接的同学都知道,一个长连接一般要隔几秒发送一条消息告诉服务器我在线,而服务器也会回复一个消息表示收到了,这样就确认了连接正常,客户端和服务器端都在线。如果服务器没有按时收到这个消息那么服务器可能就会主动关闭这个连接,节约资源。客户端没有正常收到这个返回的消息,也会做一些类似重连的操作,所以这个保活消息非常重要。

我们称这个消息叫作心跳包,一般用PING,PONG表示,像乒乓球一样,一来一回。所以这里的pingInterval就是设置心跳包发送的间隔时间,设置了这个方法之后,OkHttp就会自动帮我们发送心跳包事件,也就是ping包。当间隔时间到了,没有收到pong包的话,监听事件中的onFailure方法就会被调用,此时我们就可以进行重连。

但是由于实际业务需求不一样,以及okhttp中心跳包事件给予我们权限较少,所以我们也可以自己完成心跳包事件,即在WebSocket连接成功之后,开始定时发送ping包,在下一次发送ping包之前检查上一个pong包是否收到,如果没收到,就视为异常,开始重连。感兴趣的同学可以看看文末的相关源码。

建立连接后,我们就可以正常发送和读取消息了,也就是在上文WsListener监听事件中表现:

//监听事件,用于收消息,监听连接的状态
class WsListener extends WebSocketListener {
@Override
public void onClosed(@NotNull WebSocket webSocket, int code, @NotNull String reason) {
super.onClosed(webSocket, code, reason);
}

@Override
public void onClosing(@NotNull WebSocket webSocket, int code, @NotNull String reason) {
super.onClosing(webSocket, code, reason);
}

@Override
public void onFailure(@NotNull WebSocket webSocket, @NotNull Throwable t, @Nullable Response response) {
super.onFailure(webSocket, t, response);
}

@Override
public void onMessage(@NotNull WebSocket webSocket, @NotNull String text) {
super.onMessage(webSocket, text);
Log.e(TAG, "客户端收到消息:" + text);
onWSDataChanged(DATE_NORMAL, text);
//测试发消息
webSocket.send("我是客户端,你好啊");
}

@Override
public void onMessage(@NotNull WebSocket webSocket, @NotNull ByteString bytes) {
super.onMessage(webSocket, bytes);
}

@Override
public void onOpen(@NotNull WebSocket webSocket, @NotNull Response response) {
super.onOpen(webSocket, response);
Log.e(TAG,"连接成功!");
}
}

//发送String消息
public void send(final String message) {
if (mWebSocket != null) {
mWebSocket.send(message);
}
}

/**
* 发送byte消息
* @param message
*/
public void send(final ByteString message) {
if (mWebSocket != null) {
mWebSocket.send(message);
}
}

//主动断开连接
public void disconnect(int code, String reason) {
if (mWebSocket != null)
mWebSocket.close(code, reason);
}

这里要注意,回调的方法都是在子线程回调的,如果需要更新UI,需要切换到主线程。

基本操作就这么多,还是很简单的吧,初始化Websocket——连接——连接成功——收发消息。

其中WebSocket类是一个操作接口,主要提供了以下几个方法'

 

send(text: String)发送一个String类型的消息
send(bytes: ByteString) 发送一个二进制类型的消息
close(code: Int, reason: String?)关闭WebSocket连接

如果有同学想测试下WebSocket的功能但是又没有实际的服务器,怎么办呢?其实OkHttp官方有一个MockWebSocket服务,可以用来模拟服务端,下面我们一起试一下:

模拟服务器
首先集成MockWebSocket服务库:

implementation 'com.squareup.okhttp3:mockwebserver:4.7.2'
然后就可以新建MockWebServer,并加入MockResponse作为接收消息的响应。

MockWebServer mMockWebServer = new MockWebServer();
MockResponse response = new MockResponse()
.withWebSocketUpgrade(new WebSocketListener() {
@Override
public void onOpen(@NotNull WebSocket webSocket, @NotNull Response response) {
super.onOpen(webSocket, response);
//有客户端连接时回调
Log.e(TAG, "服务器收到客户端连接成功回调:");
mWebSocket = webSocket;
mWebSocket.send("我是服务器,你好呀");
}

@Override
public void onMessage(@NotNull WebSocket webSocket, @NotNull String text) {
super.onMessage(webSocket, text);

Log.e(TAG, "服务器收到消息:" + text);
}

@Override
public void onClosed(@NotNull WebSocket webSocket, int code, @NotNull String reason) {
super.onClosed(webSocket, code, reason);
Log.e(TAG, "onClosed:");
}
});

mMockWebServer.enqueue(response);

这里服务器端在收到客户端连接成功消息后,给客户端发送了一条消息。要注意的是这段代码要在子线程执行,因为主线程不能进行网络操作。

然后就可以去初始化Websocket客户端了:

//获取连接url,初始化websocket客户端
String websocketUrl = "ws://" + mMockWebServer.getHostName() + ":" + mMockWebServer.getPort() + "/";
WSManager.getInstance().init(websocketUrl);
ok,运行项目

//运行结果
E/jimu: mWbSocketUrl=ws://localhost:38355/
E/jimu: 服务器收到客户端连接成功回调:
E/jimu: 连接成功!
E/jimu: 客户端收到消息:我是服务器,你好呀
E/jimu: 服务器收到消息:我是客户端,你好啊

 

参考
https://github.com/square/okhttp

如何telnet ipv6端口?

如何telnet ipv6端口

和ping命令一样,加个参数-6 就可以了

# telnet -6 ipv6.google.com 443
Trying 2607:f8b0:4007:803::200e...
Connected to ipv6.google.com.
Escape character is '^]'.
^]
telnet> quit
Connection closed.
[root@zhzl ~]# telnet -6 ipv6.google.com 80
Trying 2607:f8b0:4007:80d::200e...
Connected to ipv6.google.com.
Escape character is '^]'.
^]
telnet> quit
Connection closed.

linux怎么pingipv6地址

ipv6代理测试

首先保证自己已经在ipv6环境里,在Linux下,通过以下命令ping ipv6地址,注意,不是ping,是ping6 了

# ping6 ipv6.google.com
PING ipv6.google.com(lax28s10-in-x0e.1e100.net (2607:f8b0:4007:80d::200e)) 56 data bytes
64 bytes from lax28s10-in-x0e.1e100.net (2607:f8b0:4007:80d::200e): icmp_seq=1 ttl=119 time=0.373 ms
64 bytes from lax28s10-in-x0e.1e100.net (2607:f8b0:4007:80d::200e): icmp_seq=2 ttl=119 time=0.404 ms
64 bytes from lax28s10-in-x0e.1e100.net (2607:f8b0:4007:80d::200e): icmp_seq=3 ttl=119 time=0.403 ms

那么ping不能用了么?当然不是,以下是ping命令,带一个参数-6 就可以了。

# ping -6 ipv6.google.com
PING ipv6.google.com(lax28s10-in-x0e.1e100.net (2607:f8b0:4007:80d::200e)) 56 data bytes
64 bytes from lax28s10-in-x0e.1e100.net (2607:f8b0:4007:80d::200e): icmp_seq=1 ttl=119 time=0.440 ms
64 bytes from lax28s10-in-x0e.1e100.net (2607:f8b0:4007:80d::200e): icmp_seq=2 ttl=119 time=0.409 ms
64 bytes from lax28s10-in-x0e.1e100.net (2607:f8b0:4007:80d::200e): icmp_seq=3 ttl=119 time=0.785 ms
64 bytes from lax28s10-in-x0e.1e100.net (2607:f8b0:4007:80d::200e): icmp_seq=4 ttl=119 time=0.444 ms

网络联通了以后,可以用 https://ipv6proxy.cn 在ipv4环境下测试ipv6网址内容。

Linux下如何mount你的usb硬盘

linux shell学习

首先需要在Linux系统里检测到USB硬盘

将USB设备插入USB端口后,Linux系统将一个新的块设备添加到/dev/目录中。这个阶段还无法使用该设备,因为在获取或存储任何数据之前需要先清除USB文件系统。
查找块设备文件的名称,可以运行fdisk -l命令。

# fdisk -l
OR
$ sudo fdisk -l

执行上述命令后,输出

Disk /dev/sdc: 7.4 GiB, 7948206080 bytes, 15523840 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x00000000
Device Boot Start End Sectors Size Id Type
/dev/sdc1 * 8192 15523839 15515648 7.4G b W95 FAT32

上面的输出很可能会列出连接到系统的多个磁盘。根据其大小和文件系统查找USB驱动器。准备就绪后,记下要安装的分区的块设备名称。例如, FAT32文件系统的/dev/sdc1

建立 mount 的挂载点

在能够使用mount命令挂载USB分区之前,我们需要创建一个挂载点。挂载点可以是主机文件系统中的任何新目录或现有目录。使用mkdir命令创建一个新的挂载点目录来挂载USB设备:

# mkdir /media/usb-drive

挂载USB磁盘

我们准备将USB分区挂载/dev/sdc1到/media/usb-drive挂载点:

# mount /dev/sdc1 /media/usb-drive/

检查USB驱动器是否已正确安装:

# mount | grep sdc1

/dev/sdc1 on /media/usb-drive type vfat (rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=utf8,shortname=mixed,errors=remount-ro
如果以上mount命令未产生任何输出,就代表没有mount好USB分区,肯定哪里出错了。

如何访问USB设备的数据?

如果一切顺利,我们cd到先前创建的安装点即可访问USB数据/media/usb-drive:

# cd /media/usb-drive

如何卸载USB磁盘?

在我们能够卸载USB分区之前,我们需要确保没有进程正在使用或访问我们的挂载点目录,否则将收到类似于以下内容的错误消息:

umount: /media/usb-drive: target is busy
(In some cases useful info about processes that
use the device is found by lsof(8) or fuser(1).)

关闭shell或离开USB挂载点并执行以下linux命令卸载USB驱动器:

# umount /media/usb-drive

如何永久Mount磁盘?

为了在重启后永久安装USB驱动器,请将以下行添加到/etc/fstab配置文件中:
/dev/sdc1 /media/usb-drive vfat defaults 0 0
但是,如果在Linux系统中添加或删除其他驱动器,则上述安装方法可能会失败。因此,建议使用分区UUID而不是原始块设备名称。为此,请首先找到您的USB驱动器的UUID:

# ls -l /dev/disk/by-uuid/*
lrwxrwxrwx 1 root root 10 Mar 27 23:38 /dev/disk/by-uuid/2020-08-30-11-31-31-00 -> ../../sdb1
lrwxrwxrwx 1 root root 10 Mar 27 23:38 /dev/disk/by-uuid/3eccfd4e-bd8b-4b5f-9fd8-4414a32ac289 -> ../../sda1
lrwxrwxrwx 1 root root 10 Mar 27 23:38 /dev/disk/by-uuid/4082248b-809d-4e63-93d2-56b5f13c875f -> ../../sda5
lrwxrwxrwx 1 root root 10 Mar 28 01:09 /dev/disk/by-uuid/8765-4321 -> ../../sdc1
lrwxrwxrwx 1 root root 10 Mar 27 23:38 /dev/disk/by-uuid/E6E3-F2A2 -> ../../sdb2

根据上面的ls命令输出,我们可以看到属于块设备的UUIDsdc1是8765-4321,在文件/etc/fstab加一行:

/dev/disk/by-uuid/8765-4321 /media/usb-drive vfat 0 0

运行mount -a命令安装所有尚未安装的设备。

# mount -a

国内支持ipv6的网站

如何从全球ping一个ipv6地址

国内支持ipv6的网站大部分是教育网内高校的系统,比如清华大学的镜像网址 https://mirrors.tuna.tsinghua.edu.cn 。进入后右侧可以看到有ipv6的网址:https://mirrors6.tuna.tsinghua.edu.cn

因为是IPv6的,所以IPv4下无法访问。如果想在ipv4环境下测试ipv6网址,可通过 IPv6代理测试网址 https://ipv6proxy.cn 进行测试,返回ipv6网址内容。

国内支持ipv6的网站
ipv6代理测试