跳转至

博客

OpenWRT 上配置 Gandi DDNS

一直想给自己的 OpenWRT 路由器添加 DDNS 功能,但 Gandi 不在官方的 ddns-scripts 列表中,自己在网上找了一些脚本,发现是 Python 写的,尝试把 Python 安装到路由器上又发现空间不够,虽然可以安装到 USB 上,但总归是麻烦。

最后找到了官方的一个脚本,非常适合我的需求。简单修改一下,然后安装一下支持 HTTPS 的 cURL:

$ opkg update
$ opkg install ca-bundle
$ opkg install curl

然后把脚本添加到 crontab 即可。

ETC 比赛无线网络搭建小记

正好上着李贺武老师的《无线移动网络技术》课,然后今天又给 ETC 比赛搭建无线网络,于是周二的时候找老师咨询了一下意见。我们大概给老师讲了一下场地的样子和尺寸(当时估计的大了),然后老师给我们提供了一个可以供参考的部署方案,包括几个 AP 分别放在哪,这些 AP 的 2.4GHz 都用哪个 channel,然后都用多少功率。并且很友善地在周五的时候让助教来场地帮我们 survey 一下无线网络的状况。我们用 Fluke Networks 的 AirCheck Wi-Fi Tester 看了一下场地的各个频道的 AP 数量和信号强度,发现虽然 AP 挺多的,但是它们的信号都比我们的小不少,而且我们也都开到了 50mW,所以干扰不大。

然后昨天下午一点半钟来到场地,用板车把设备都运到计算机开放实验室,然后开始部署无线网络。我们提前来踩过几次点,这边的网络是没有 DHCP 服务器的,通过一个指定的网关出去。我们发现可以利用已有的这些交换机从地下连到各个电脑上的网线,来连接我们的 AP 和交换机,这样我们就免去了走线的麻烦。于是我们先定下放 AP 的位置,然后用寻线器找到网线插到了交换机的哪一个端口上,标记好后换成连接到我们自己的交换机的网线上,从而可以通过 PoE 把我们的 AP 给启动起来。然后用我自己的路由器,把 LAN 口插到交换机上,给 AP 分发 DHCP 地址,然后把下发的默认网关配置为真实的网关(DHCP Option 3) ,没做但是也可以顺带做的是把 WLC 的地址分发下去(DHCP Option 43 Type 241)。

当然,这个过程也遇到了一点小坑,就是交换机还保留了之前的配置,所以这次把新的几个端口划到了一个 VLAN 下,命令自然是记不住的要现查。然后起来以后还挺稳定的,也没出现什么问题,网络带宽也足够用,离千兆还有蛮多距离,一天也才跑了接近俩 TB 的流量。

Unicode En Dash 小坑

今天有同学问到我这个问题:

$ gcc -o ph ph.c –lpthread

为啥不工作。我怎么看都觉得没啥问题,一开始以为是找不到 pthread,但马上又排除了。想了下会不会是有隐藏的字符,于是让同学 pbpaste | xxd 一下,果然发现这里的 \xe2\x80\x93 ,查了下是 Unicode 里的 En Dash。由于这是从 PDF 里直接拷贝出来的,所以凉了。改成正常的短横杠即可。

软工平台踩坑记

老师要求我们搞 CI/CD,CI 自然是很快就搞好了,不过 CD 还得配一下。今天研究了一下它的 Deployer 架构,发现了若干易用性问题:

  1. 缺乏文档
  2. 只有样例配置没有讲解
  3. 已有的文档 语焉不详
  4. 官方对此回复:功能太多,还没忙过来写文档

于是只好经常戳助教然后尝试理解这个东西。。然后遇到了很多的 BUG:

  1. 容器没有重启功能。。。
  2. 容器死了还是活着看一个图的颜色。。。毫无说明
  3. 容器虽然有 Console,但是输入过长后直接回到行首没有换行。。。
  4. 容器对外的域名里有下划线。。。Django 上来就一句 Invalid HTTP_HOST header: 'xxxx_xxx.app.secoder.net'. The domain name provided is not valid according to RFC 1034/1035. Express 直接就 Invalid Host header 放弃治疗。。。
  5. 助教对上一条的回复是,等我忙完 DDL 有空再做吧。。。也就是说现在要做只能自己再开一个 Nginx 容器然后自己在 proxy_set_header 上做手脚。。。

在荔枝糖(Lichee Tang)上初次体验 FPGA

今天从张宇翔学长那拿到了 荔枝糖(Lichee Tang) 的 FPGA 板子,于是立即开始把前段时间学到的 Verilog 应用上来。不过想到现在我手上没有多少外设,然后又必须远程到 Windows 电脑上去操作,于是先实现了一下 UART 通信。

在网上找到了 ben-marshall/uart 一个简易的实现,很快做到了一直在串口上打印 A 字符。接着我开始尝试实现一个简单的串口回显。一开始,我直接把 UART 读到的数据直接输出,果然可以了,但是一旦传输速率跟不上了,就会丢失数据。于是我添加了 FIFO IP 核,然后把读入的数据存入 FIFO,又从 FIFO 中读取数据写入到 UART 中去。不过发现了一个小 BUG:每次打印的是倒数第二次输入的字符,即丢失了第一个字符。在张宇翔学长的帮助下找到了问题:当 FIFO 的读使能信号为高时,其数据在下一个时钟周期才来,于是解决方案就是等到数据来的时候再向 UART 中写数据:

always @ (posedge clk_in) begin
    uart_tx_en <= uart_fifo_re;
end

这样就解决了这个问题。完整代码在 jiegec/learn_licheetang 中。

使用 veth 实现 IPv6-only 的 Brouter 功能

最近从 @shankerwangmiao 学到了一个方法:通过 veth 把两个 bridge 的 IPv6 桥接起来。方法如下:

$ ip link add veth-v6-in type veth peer name veth-v6-out
$ brctl addif br-in veth-v6-in
$ brctl addif br-out veth-v6-out
$ ebtables -t filter -A FORWARD -p ! IPv6 -o veth-v6-in -j DROP
$ ebtables -t filter -A FORWARD -p ! IPv6 -o veth-v6-out -j DROP

这样就可以看到 veth 上仅有 IPv6 的流量了。

THUCTF 2018 和 Teaser Dragon CTF 2018 小记

终于可以公开 writeup 了,大家也可以去看 twd2 写的 writeup 。这次是我第一次打 CTF,发现题目还挺有意思的,虽然也有一些题目做不出来,有拿钱还是美滋滋。

这次也认识了好些会打 CTF 的人吧,如 0x00, user1, igoodvegetable 等队伍的同学。一开始被蛤力橙叫来打比赛,我觉得心里挺没底的,然后花了很多时间做题目,一点一点还是做出了不少题目来。最精彩的还是结束以后,当知晓没做出来的题目的做法时候,会不自觉感叹题目的巧妙。也学到了一些梗:

#define 1000000007 twd2

接着就参与了一下 Teaser Dragon CTF 2018,是个在线赛,许多人一起做题,只有 24 小时。看了下题目,除了签到题,其它题都比 THUCTF 2018 难多了,我只能围观他们做题。最后看到别人写的 writeup,真是太巧妙了,一环接一环,真的想不到。不过也有很麻烦的题目,特别是有的逆向的题目,太考验人的耐心了。

接下来就等待官方的 writeup 和别人的 writeup,学习一下别人的做法吧。

在 Android 上打开 LTE 的 IPv6

听闻北京移动给 LTE 配置了 SLAAC,但现在需要手动打开,方法如下:

Settings -> Network & Internet -> Mobile Network -> Advanced -> Access Point Names -> 中国移动 GPRS (China Mobile) -> 把 APN procotol 和 APN roaming protocol 两项都改成 IPv4/IPv6

然后在 test-ipv6.com 上可以看到确实分配了 IPv6 地址,不过目前评分只有 1/10。也就是说可用性还不佳。

而在 iOS 上,通过 HE 的 Network Tools 能看到,确实拿到了 IPv6 的地址,但是出不去,怀疑是运营商没有下发相关配置,所以还不能使用,只能继续等。

2018-11-06 更新:现在 iOS 用户也有 LTE 的 v6 了。评分是 9/10。目前可用性已经可以了,就是国内互联还不大好。

绕过 GPGMail 的激活检测

前段时间 GPGMail 宣布不再免费,在三十天的试用期后就不给用了。唉,可能是官方实在没钱维护了,也可能是官方想赚钱了。不过,既然 GPGMail 采用的是自由的许可证,意味着我们可以自己对代码进行更改。和许可证验证相关的代码如下:

- (BOOL)hasActiveContract {
    NSDictionary *contractInformation = [self contractInformation];
    return [contractInformation[@"Active"] boolValue];
}

我们只要改成 return TRUE ,在自己的电脑上手动编译、并复制到 /Library/Application Support/GPGTools/GPGMail 下即可。

另:还有一个直接对二进制打 patch 的方法(仍然符合许可证),利用了最近打 CTF 学到的一些知识。找到以上这个函数,然后把返回值修改成非零即可。这里就不提供方法了。最后的更改:

$ radiff2 -D
--- 0x0000282f  410fbec7
- movsx eax, r15b
+++ 0x0000282f  4c89e090
+ mov rax, r12
+ nop

当然了,还需要额外 codesign --remove-signature 一下。

谨慎对非自由软件采用这个方法。可能有法律风险。

在 macOS 的 VirtualBox 上从 USB 启动

做了一个 Windows 10 安装 U 盘,想测试一下能不能启动,于是想用 VirtualBox 起一个虚拟机。但是发现,一般情况下要从 ISO 或者把 U 盘克隆成一个 vdi/vmdk etc 再启动。不过找到了 Cem Arslan 的 VirtualBox - Booting From USB (MAC) 实验了一下,确实可以用,以 /dev/disk2 为例方法如下:

$ diskutil unmountDisk /dev/disk2
$ sudo chown $(whoami) /dev/disk2
$ VBoxManage internalcommands createrawvmdk -filename PATH_TO_VMDK -rawdisk /dev/disk2
$ # Now boot from VirtualBox

对于其它平台,可以参考 Tu Nguyen 的 How to boot from USB in VirtualBox

研究了一下生成的 vmdk 文件,大概是这样的:

# Disk DescriptorFile
version=1
CID=12345678
parentCID=ffffffff
createType="fullDevice"

# Extent description
RW 12345678 FLAT "/dev/disk2" 0

# The disk Data Base 
#DDB

ddb.virtualHWVersion = "4"
ddb.adapterType="ide"
ddb.geometry.cylinders="1234"
ddb.geometry.heads="1234"
ddb.geometry.sectors="1234"
ddb.uuid.image="12341234-1234-1234-1234-123412341234"
ddb.uuid.parent="00000000-0000-0000-0000-000000000000"
ddb.uuid.modification="00000000-0000-0000-0000-000000000000"
ddb.uuid.parentmodification="00000000-0000-0000-0000-000000000000"
ddb.geometry.biosCylinders="1234"
ddb.geometry.biosHeads="1234"
ddb.geometry.biosSectors="1234"

通过 SSH 隧道连接 ADB 和 Android 设备

由于本机算力不足,想要在远程编译 LineageOS ,其中有一步需要连接到已有的设备,于是突发奇想:

  1. adb 可以通过 网络连接
  2. ssh 可以进行端口转发,这里是把 remote 的端口转发到 Android 设备上的端口。

方法如下:

$ adb shell ip -f inet addr show wlan0
$ # remember the ip address here
$ adb tcpip PORT1
$ ssh -R PORT2:ANDROID_IP:PORT1 REMOTE
(remote)$ adb connect localhost:PORT2 # trust this device on Android

参考文档:

  1. How can I connect to Android with ADB over TCP?
  2. SSH PORT FORWARDING EXAMPLE

在 Ubuntu 上跨版本迁移 MongoDB

由于 MongoDB 只支持当前版本和上一个版本的数据库格式,然后刚刚滚系统升级的时候升级到了 3.6.x,而数据库格式仍然是 3.2.x 的,于是需要先安装回 3.4.x 版本的 MongoDB,输入命令把数据库升级到 3.4.x 版本后,再用 3.6.x 的数据库进行升级。

以 从 Ubuntu 14.04 LTS 升级到 Ubuntu 18.04.1 LTS 为例,方法如下:

$ wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-ubuntu1604-3.4.17.tgz
$ tar xvf mongodb-linux-x86_64-ubuntu1604-3.4.17.tgz
$ cd mongodb-linux-x86_64-ubuntu1604-3.4.17/bin/
$ sudo ./mongod --config /etc/mongodb.conf &
$ mongo
> db.adminCommand( { setFeatureCompatibilityVersion: '3.4' } )
{ "ok" : 1 }
$ fg
^C
$ sudo chown -R mongodb:mongodb /var/lib/mongodb
$ sudo systemctl start mongodb
$ mongo
> db.adminCommand( { getParameter: 1, featureCompatibilityVersion: 1 } )
{ "featureCompatibilityVersion" : { "version" : "3.4" }, "ok" : 1 }
> db.adminCommand( { setFeatureCompatibilityVersion: '3.6' } )
{ "ok" : 1 }
> db.adminCommand( { getParameter: 1, featureCompatibilityVersion: 1 } )
{ "featureCompatibilityVersion" : { "version" : "3.6" }, "ok" : 1 }
$ # Okay now

在 LEDE(OpenWrt)上启用 wpad

WPAD(Web Proxy Auto-Discovery Protocol)是一个可以利用 dhcp 分发 pac 配置的协议。方法如下:

$ # ssh to router first
$ vim /etc/dnsmasq.conf
dhcp-option=252,"http://router_ip/wpad.dat"
$ vim /www/wpad.dat # put pac here
$ service dnsmasq restart
$ # ensure proxy is available to lan
$ # enable wpad on devices

参考文档:

  1. Web Proxy Auto-Discovery Protocol
  2. Automatic Proxy Configuration with WPAD
  3. Deployment Options
  4. Example PAC File

在 Xcode 9 上启用 Vim 模拟(XVim 2)

作为一个不用 vim 编辑会死星人,用 Xcode 总是止不住自己想 Escape 的心。于是找到了 XVimProject/XVim2 进行配置。

大致方法如下:

  1. 按照 Signing Xcode 对 Xcode 进行重签名。套路和对 GDB 进行签名一样。不过这次,签名完成的时间可长多了,毕竟 Xcode 这么大。
  2. 接着按照项目的 README,首先 git clone 然后 make ,第一次打开 Xcode 的时候选择 Load Bundle 即可。

终于可以满足我 Escape Xcode 的欲望了。

在 macOS 上读取移动硬盘的 S.M.A.R.T. 信息

之前想看看自己各个盘的情况,但是发现只能看电脑内置的 SSD 的 S.M.A.R.T 信息,而移动硬盘的都显示:

$ smartctl -a /dev/disk2
smartctl 6.6 2017-11-05 r4594 [Darwin 17.7.0 x86_64] (local build)
Copyright (C) 2002-17, Bruce Allen, Christian Franke, www.smartmontools.org

/dev/disk2: Unable to detect device type
Please specify device type with the -d option.

Use smartctl -h to get a usage summary

一开始我怀疑是个别盘不支持,但换了几个盘都不能工作,问题应该出现在了 USB 上。查了下资料,果然如此。根据 USB devices and smartmontools ,获取 S.M.A.R.T 信息需要直接发送 ATA 命令,但是由于经过了 USB,于是需要进行一个转换,导致无法直接发送 ATA 命令。这个问题自然是有解决方案,大概就是直接把 ATA 命令发送过去(pass-through)。上面这个地址里写到,如果需要在 macOS 上使用,需要安装一个内核驱动。可以找到,源码在 kasbert/OS-X-SAT-SMART-Driver 并且有一个带签名的安装包在 External USB / FireWire drive diagnostics support 中可以下载。丢到 VirusTotal 上没查出问题,用 v0.8 版本安装好后就成功地读取到了移动硬盘的 S.M.A.R.T 信息了。

然后我又简单研究了一下各个 S.M.A.R.T 各个值的含义是什么。 VALUE 代表当前的值, WORST 代表目前检测到的最差的值, THRESH 代表损坏阈值。这些值都是从 RAW_VALUE 进行计算后归一化而来。然后 TYPE 分为两种,一是 Pre-fail ,代表如果这一项的值小于阈值,代表这个机器很危险了,赶紧拷数据丢掉吧。二是 Old_age ,代表如果这一项小于阈值,代表这个机器比较老了,但还没坏。真正要看是否坏了,可以看 When_Failed 一栏。

通过 Ipfilter Extension 实现 RFC8367

前几天无聊闲逛看到了一个很有趣的 RFC8367 - Wrongful Termination of Internet Protocol (IP) Packets ,看到日期大家应该都懂了,这是个粥客,不过里面还是反映了一些事情,咳。

之前看到闪客实现了 shankerwangmiao/xt_PROTO ,想到自己也可以做一个 iptables 扩展,于是就写了 jiegec/xt_EQUALIZE 。它是这样使用的:

$ git clone git@github.com:jiegec/xt_EQUALIZE.git
$ make
$ sudo make install
$ sudo iptables -t filter -A INPUT -j EQUALIZE
$ sudo dmesg -w &
$ # Make some random network requests to see the effect!
$ ping 1.1.1.1
$ ping 8.8.8.8
$ ping ::1

目前还没有把参数都变成可以配置的。如果真的有人需要这个模块的话,我再改吧(逃

在 macOS 上 TAP Interface 上启用 IPv6 自动配置

由于 macOS 对 TAP Interface 不会自动出现一个设置中对应的服务,所以需要手动进行配置。一番测试后,发现可以通过:

$ sudo ipconfig set [tap_if] automatic-v6
$ sudo ipconfig set [tap_if] dhcp

启用系统自带的 dhcp 和 ra 功能。也许有方法可以把这些 tap 搬到系统的设置中去。

UPDATE:

可以把 TAP Interface 加到系统的设置中去。方法参考Virtual network interface in Mac OS X。完成以后可以直接通过系统设置界面进行配置。

在 macOS 下实现 GRETAP

由于没有找到 macOS 下现成的 GRETAP 实现,我就想到自己实现一个。由于tuntaposx提供了一个和 Linux 下基本一样的 TAP Interface,于是自己利用 raw socket 和 TAP Interface 实现了一下,主要方法:

  1. 打开 raw socket,读取收到的 proto 47 的包,判断是否为 GRETAP 包,是,则写入内层包到打开的 TAP Interface 中。
  2. 从 TAP Interface 中读入包,自己加上 GRE 头和 IP 头,然后发送。

主要的难度是在 raw socket 部分,macOS 继承了 BSD,与 Linux 不大一样。于是参考了SOCK_RAW Demystified,成功地实现了这个功能。

代码放在jiegec/gretapmac。写得并不高效,仅仅可用,用了一百多行。

UPDATE: 之后又随手实现了一个类似的协议,L2TPv3 over UDP。代码在jiegc/l2tpv3udptap

在 WireGuard 构建的 Overlay Network 上跑 babel 路由协议

Run Babeld over Wireguard - Fugoes's BlogRoute-based VPN on Linux with WireGuard 启发,自己也想尝试一下,在一个有多个结点的网络中,如何通过 WireGuard 构建一个 overlay network,并通过 babel 自动进行结点发现和路径选择。

首先建立点对点的 WireGuard Tunnel。由于我们用 babel 进行路由,所以我们不能采用 Wiregurad 本身基于目的地址的端口复用,所以每一个 WireGuard interface 都只有一个 Peer。

配置一个点对点的 WireGuard Tunnel:

$ # for wg-quick
$ cat wg0.conf
[Interface]
Address = IPV4/32, fe80::ID/64
PrivateKey = REDACTED
ListenPort = PORT1
Table = off # ask wg-quick not to insert peer address into routing table

[Peer]
PublicKey = REDACTED
AllowedIPs = 0.0.0.0/0, ::/0
Endpoint = REDACTED:PORT2

这里的 IPV4 和 ID 在同一设备上的不同 WireGuard Tunnel 上相同。只是通过 wg interface 编号来区分。

接着配置 babeld:

$ cat babeld.conf

router-id ID
local-port 33123 # for babelweb2

# one line for each wg interface
interface wg0 type tunnel rtt-max 512

redistribute ip PREFIX/LEN ge LEN le 32 local allow # tunnel neighbors
redistribute proto 42 # routes installed by babeld
redistribute local deny
# consult babeld man page for more

然后通过 BabelWeb2(很难用)进行可视化,然后通过手动触发一些网络波动即可达到效果。

更改 macOS 屏幕亮度的按键

由于我打开了「Invert Fn」功能,所以需要调亮度的时候,是采用 Fn+F1/F2 的方法。但是,我的机械键盘则是,不按 Fn 时为 1-9,按着 Fn 时为对应的 F1-F9,但是就无法调整亮度和声音了。

然后捣腾了一下,发现可以用 ScLk 和 Pa/Br(名称在各个键盘上不大一样)调整亮度。不过,还没发现如何更改音量。。。

向 Lenovo y1s 刷入 OpenWRT 17.01.5 固件,并把 IPv6 bridge 到内网中和配置认证脚本

首先参照OpenWRT Wiki - Lenovo Y1 v1找到刷固件教程:

  1. 下载Lenovo y1s 的固件备用
  2. 断开电源,等待一段时间,插入电源同时快速按下重置按钮,如果面板双闪,则说明进入了恢复模式
  3. 电脑连接到四个 LAN 口中任意一个,配置静态地址在 192.168.1.0/24 网段
  4. 打开 192.168.1.1 可以看到刷固件的页面
  5. 上传固件,等待路由器重启
  6. 配置 IP 地址为 DHCP 模式,打开 192.168.1.1 进行配置

然后就是常规的密码设置,opkg 源设置为 tuna 的源,配置 ssh 和 公钥。

接下来,我们为了使用学校的 SLAAC,采用 ebtables 直接把学校的 IPv6 bridge 进来,而 IPv4 由于准入系统,需要 NAT。

参考 Bridge IPv6 connections to WAN,下载 v6brouter_openwrt.sh 到某个地方,然后修改一下里面的一些参数:

# For Lenovo y1s
WAN_DEV=eth0.2
BRIDGE=br-lan
# the rest remain unchanged

然后跑起来之后,自己的电脑可以成功拿到原生的 IPv6 地址了,不需要用难用的 NAT66 技术。

下一步是采用z4yx/GoAuthing

$ go get -u -v github.com/z4yx/GoAuthing
$ cd $GOPATH/src/github.com/z4yx/GoAuthing/cli
$ env GOOS=linux GOARCH=mipsle GOMIPS=softfloat go build main.go
$ mipsel-linux-gnu-strip main
$ scp main root@192.168.1.1:~/GoAuthing
$ ssh root@192.168.1.1
$ opkg install ca-certificates
$ ./GoAuthing

这里参考了解决 GO 语言编译程序在 openwrt(mipsle 架构) 上运行提示 Illegal instruction 问题,配置了 GOMIPS 环境变量。为了访问 HTTPS 网站,参考了OpenWRT Wiki - SSL and Certificates in wget。有毒的是,这个环境变量,在 macOS 上不能正常工作,而在 Linux 机子上是没有问题的。

然后就可以成功地跑起来 GoAuthing,解决了上校园网认证的问题。

感谢宇翔编写的 GoAuthing 小工具。

更新:简化了一下 v6brouter 脚本:

#!/bin/sh
BRIDGE=br-lan
WAN_DEV=$(/sbin/uci get network.wan.ifname)
WHITELIST1="00:11:22:33:44:55"
WHITELIST2="55:44:33:22:11:00"

brctl addbr $BRIDGE 2> /dev/null
brctl addif $BRIDGE $WAN_DEV
ip link set $BRIDGE down
ip link set $BRIDGE up
brctl show

ebtables -F
ebtables -P FORWARD ACCEPT
ebtables -L

uci set dhcp.lan.ra='disabled'
uci set dhcp.lan.dhcpv6='disabled'
uci commit
/etc/init.d/odhcpd restart

echo 2 > /proc/sys/net/ipv6/conf/$BRIDGE/accept_ra
ebtables -t broute -F
ebtables -t broute -A BROUTING -i $WAN_DEV -p ! ipv6 -j DROP
ebtables -t broute -A BROUTING -s $WHITELIST1 -p ipv6 -j ACCEPT
ebtables -t broute -A BROUTING -d $WHITELIST1 -p ipv6 -j ACCEPT
ebtables -t broute -A BROUTING -s $WHITELIST2 -p ipv6 -j ACCEPT
ebtables -t broute -A BROUTING -d $WHITELIST2 -p ipv6 -j ACCEPT
ebtables -t broute -A BROUTING -p ipv6 -j DROP
ebtables -t broute -L

注意,这里添加了两个 WHITELIST 的 MAC 地址,表示只让这两个 MAC 地址的设备访问 v6。一般来说,外面网关的 MAC 地址也要放进来,不然可能接收不到 RA。如果不需要白名单的话,可以去掉 ebtables 的后几行规则。

构建简易的 initramfs

一直对 Linux 的启动很感兴趣,但对 initrd 和 initramfs 等概念不大了解,于是上网找了资料,自己成功地看到了现象。

参考资料:

具体步骤:

$ cat hello.c
#include <stdio.h>
#include <unistd.h>

int main() {
    for (;;) {
        printf("Hello, world!\n");
    }
}
$ gcc -static hello.c -o init
$ echo init | cpio -o -H newc | gzip > initrd
$ qemu-system-x86_64 -kernel /boot/vmlinuz-linux -initrd initrd -nographic -append 'console=ttyS0'
# Use C-a c q u i t <Enter> to exit

可以看到过一会(三四秒?),可以看到满屏的 Hello world 在输出。

用 MuSSH 快速对多台机器进行软件包升级

Debian Stretch 9.5 刚刚更新,自己手上有不少 stretch 的机器,于是顺手把他们都升级了。不过,这个过程比较繁琐,于是我采用了 MuSSH 的方法,让这个效率可以提高,即自动同时 SSH 到多台机器上进行更新。

首先编写 hostlist 文件,一行一个地址,分别对应每台机器。

然后采用 MuSSH 对每台机器执行同样的命令

$ mussh -H hostlist -c 'apt update && apt upgrade -y'

此时要求,ssh 上去以后有相应的权限。这个有许多方法,不再赘述。然后就可以看到一台台机器升级,打上安全补丁,爽啊。

配置 fcitx-fbterm 实现在终端下显示和输入中文

参考网站:

Ubuntu 使用 fbterm 无法打开 fb 设备的解决及 fcitx-fbterm 安装 Fcitx - ArchWiki 完美中文 tty, fbterm+yong(小小输入法) 让 linux console 支持中文显示和 fcitx 输入法

考虑到 lemote yeeloong 机器的 cpu 运算性能,跑一个图形界面会非常卡,于是选择直接用 framebuffer。但是,显示中文又成了问题。于是,采用了 fbterm 和 fcitx 配合,加上 gdm 的方法,完成了终端下的中文输入。

首先,安装相关的包:

$ sudo apt install gpm fcitx-fronend-fbterm dbus-x11 fbterm fonts-wqy-zenhei

接着,基于以上参考网站第一个,编写 zhterm 文件:

$ echo zhterm
#!/bin/bash
eval `dbus-launch --auto-syntax`
fcitx >/dev/null 2>&1
fbterm -i fcitx-fbterm
kill $DBUS_SESSION_BUS_PID
fcitx-remote -e
$ chmod +x zhterm
$ zhterm
# Use C-SPC to switch input source

另:找到一个映射 Caps Lock 到 Escape 的方案

$ sudo bash -c "dumpkeys | sed 's/CtrlL_Lock/Escape/' | loadkeys"