定制自己的 OpenWrt

每次安装 OpenWrt, root 口令都是空的,然后每次进入都是需要手工设置一把;每次都要修改时区;我们想把 OpenWrt 的“主机名”修改为自己的品牌名称;我们还想修改 ssh 登录的 Banner … …

下载 ImageBuilder 是最快定制自己 Image 的办法。不同的 Target , 这个 ImageBuilder 也会不一样,例如 香橙派 Zero 的文件是:openwrt-imagebuilder-sunxi-cortexa7.Linux-x86_64.tar.xz 所以,我们需要先选择好 Target。所有不同的 profile 其实在 .targetinfo 文件里都有定义。选择到合适的 target profile 后,我们只需要运行
# make -j 4 image PROFILE=”xxx” PACKAGES=”xxx xxx ” FILES=”xxx” 即可安装指定的软件包,并把额外的文件在 FILES 路径下包含进来。另外,要用国内的源:中科大: http://mirrors.ustc.edu.cn/lede/releases/18.06.5/targets/x86/64/ 更新 repositories.conf 把其中的 downloads.openwrt.org 修改为:mirrors.ustc.edu.cn/lede

默认刷的就是 snapshot 版本, 不带 Web 界面的, 要刷 Web 界面,进入 ssh 后运行:
# opkg update; opkg install uhttpd uhttpd-mod-lua luci-i18n-uhttpd-zh-cn luci-theme-bootstrap luci-i18n-base-zh-cn

在想到要修改这些东西的时候,我们需要知道这些东西其实是在一个 /bin/config_generate 里面完成的,就让我们先从这个脚本开始,顺藤摸瓜来解剖 OpenWrt 吧。开头的这几行就是说,如果系统已经初始化过了,就不执行这个脚本了。反过来说,如果我们要初始化板子,直接删除 /etc/config/network 和 /etc/config/system 两个文件,然后执行 config_generate 就好。

在开发过程中,为了每次烧写后有自己网络的 IP 地址,我们把原始的 192.168.1.1 修改了一下。也就是说,如果不想让 OpenWrt 默认 IP 是 192.168.1.1 我们可以修改为其他的 VLAN。

系统名和时区,也可以在脚本里直接修改,注意上海是“UTC-8”哦!(里面的 CST 其实也只是显示为 CST 而已,你可以写任意其他的名字,但是 -8 不能修改)

修改登录的 Banner 当然是 /etc/banner 文件。

那 root 口令怎么初始化呢?我们只能手工生成一个带有 root 口令的 shadow 文件,覆盖初始化时的 /etc/shadow ,这样就完成了以上这些初始化需要注意的步骤。

如果板子是从 SD 卡启动的话,一般 SD 卡是从 img 文件直接用 dd 命令烧写的。烧写完后,挂接 SD 卡的第二个分区(根文件系统分区),用脚本修改 /bin/config_generate ,然后 unmount ,也算一种方法。

另外一种比较正式的方法就是修改包文件 base-files.ipk ,我们现在进阶到 opkg 软件包的解剖了。 ipkg 文件实际上就是一个 .tar.gz 文件。

我们用
# zcat base-*.ipk |tar xvf –

就能得到三个文件:

  • ./debian-binary
  • ./data.tar.gz
  • ./control.tar.gz

其中 data.tar.gz 就是所有这个基本包的文件,包含了这个 /bin/config_generate 脚本。我们把 data.tar.gz 包内的文件解开来,可以看到基本上都是 /etc 下核心的内容。

这里有一个我们认为比较核心的脚本是 ./lib/functions/uci-defaults.sh , 我们可以看到,其实板子启动后会自动往 /tmp/sysinfo 目录里写一些文件的,然后后面的这些启动脚本会读取里面的信息,做对应的处理。

总结:实际上修改包文件其实不符合常规的整体的包的完整性,所以,在实际的操作中,为了烧写定制的 SD卡,我们完全不必定制自己的 ipk 文件,而是用官方的 img 文件烧写完毕后,挂接第二分区,再修改相应的文件,反正烧写完以后,SD 卡是必须扩容的。所以,这个修改文件的动作,也不过是顺水推舟而已。

怎么用脚本自动扩展SD 卡的分区?且听下回分解!

香橙派 Pi Zero Plus 上手记

废话不多说,树莓派玩了几台,之前买的是 Google AIY,还托兄弟从美国买了4台,69美刀一台,送了2台,自己留了2台,号称有 Tensorflow Lite 版本。但是自己没时间玩。后来又买了树莓派 4B,1G 内存的各种操作系统刷。 打算做一款屏蔽广告的产品,先要低成本啊, 搜到了老外用 Aliexpress 买的 Pi Zero,再一搜原来是深圳迅龙的产品,当然是挑 100 RMB 内的产品买,而且是要有有线网口的。所以就选了 Zero Plus。坑的是支持的操作系统版本没几个。 Arch Linux 的下载只有 135M,所以先从 Arch Linux Server 开始干起。

安装软件包,一定很慢, 所以先找国内的镜像, 国内有清华的,中科大的, 我们就把 /etc/pacman.d/mirrorlist 第一行修改为:
Server = https://mirrors.ustc.edu.cn/archlinuxarm/$arch/$repo
然后 pacman Syuw 就可以去掉那个更新时的因为 ca-certificates 的冲突报错的问题。


再返回去,说一下板子的镜像烧写问题,因为有之前树莓派的经验,所以,手册也没看,就下载了其他不相关的镜像,导致以为板子坏了,投诉了售后的黄小姐,在她热情的指点下,终于明白了,这个板子是必须插 SD 卡才能会亮灯的。正常的启动后是 DHCP 拿地址的,然后板子是红灯亮,网口灯黄灯亮(100M?),绿灯闪。
吐槽一下他们家的百度下载,那个百度网盘实在坑爹,从 Google 网盘下载都有 4M每秒,可是百度上就只能是 100多 Kb/秒。

然后就是 pacman -S vim sudo proxychains dnsutils 等各种工具了

且慢! 磁盘空间不够了!根文件系统只有 1.1G,已经 100% 满了!

这个难不倒我们, 把 SD 卡拔出来放到一台 Linux 机器下, 用 fdisk 删分区,建分区,扩展,然后挂接, growfs 就可以。

敲入 shutdown -h now,Zero+ 就自己灭灯了, 只有绿灯还常亮。拔卡!

前面具体删分区,建分区的步骤就是比较简单, 建分区的时候要注意起始扇区要用前面删除之前的那个起始扇区号,其他都是默认就可以。 然后挂接到 /mnt 的时候,可能会遇到超级块错误,也不要慌, 先用 fsck.ext4 -y /dev/sdb2 来做好 fsck 就可以挂接了。 我们看下挂接好之后, resize2fs 前后的磁盘空间

好了, SD 卡已经扩容完毕,我们umount /mnt; eject /dev/sdb 把 SD 卡插回 Pi Zero+

接下来就是安装其他软件的事情了,我们且听下回分解 … …

用Firefox 的 DoH 功能直接测试 ADGuard 的广告屏蔽效果

在火狐浏览器(Firefox) 的网络设置里,我们手工输入 DNS over HTTPS 的解析器名称:adguard-dns-ns1 ,禁用或者删除原先安装的 AD Block 等插件,来看下访问新浪,搜狐等网站的广告效果。

看新浪财经首页,明显的,该有的广告还是在。

点击文章,可以说除了其中一个 Google 的广告因为墙的问题不能展示,其他该有的都有。

去搜狐教育首页,中间资讯部分一大块天窗,是某个 js 的域名被屏蔽了。

点击进入文章详细,左右两侧有两块英文的提示

可以说 Adguard 的效果比较差,而且速度很慢。Adguard 也有各种插件,在 PC 端有直接的客户端,这些额外的软件安装,对于消费者而言充满疑问和疑虑,对于企业级客户而言,更加不可取。

Proxmox VE 6 的 NFS ServerName 不能解析的惨案

在安装系统之前,做好规划绝对是非常重要的,但是总是有漏网之鱼,有些事情会没有提前想到,导致有点灾难性的后果发生。

在把 KVM 下的虚拟机迁移到 Proxmox 的时候,我们先前在设置 Proxmox NFS Pool 的时候,设置的 NFS 服务器采用名字而不是 IP ,这就埋下了雷。也就有了本文。

尽管在迁移之前 KVM 环境下有 dns-01 和 dns-02 两台 dns 解析的机器,甚至 dns-02 已经成功的迁移到了 PVE 下面。但是在迁移 dns-01 的时候,灾难发生了,因为磁盘 Pool 再也不能解析名称了, 所有的 NFS 存储都挂了。

解决办法:
通过 IP 地址分别登录每台 PVE 主机,修改 /etc/pve/storage.cfg,把 NFS 的 server 修改为 IP 地址,重新启动 PVE 主机

PVE 使用了 Corosync Cluster Engine 用于集群通信,并把配置存储在 SQlite 数据库,通过 FUSE 挂接到每个节点的 /etc/pve 目录下。

修改 Proxmox 6 VE 虚拟机的 VM ID

KVM 的虚拟化环境里, 只有 domain name 这一说, domain ID 是会随着每次重启, ID 会改变的。

Proxmox 创建虚拟机如果不指定 ID,这个 ID 会自动递增,而且这个 ID 在一个集群里是唯一的,是一直绑定虚拟机的。为了方便管理,类似网络环境的 DHCP IP Pool 的管理,我们会对某一段 ID 做一个特定的用途,加以区分。例如 100-199 是基础架构类的, 200-299 是模版,300-399 是数据库层, 400-499 是应用层, 500-599 是测试机, 600-699 是Windows 客户机。

如果不小心分配错了 VM ID,没有按照我们自定义的规则,需要修改 VM ID,怎么办呢?

在虚拟机已经关闭的情况下, ssh 登录进入集群内的任意一个节点,例如 pve-01,把 VM ID 111 修改为 211:
# cd /etc/pve/nodes/pve-01/qemu-server
# mv 111.conf 211.conf
# vim 211.conf
把里面的虚拟机磁盘映像路径修改掉,同时去真实的物理路径,把磁盘映像的文件名修改掉
假定磁盘 NFS Pool 的顶层路径为: /mnt/pve/vmpool/images,那么就是:
# mkdir 211
# mv 111/vm-111-disk-0.qcow2 211/vm-211-disk-0.qcow2
就可以

把 KVM qcow2格式虚拟机迁移到 Proxmox VE 6 下的 V2V 脚本

在熟悉 Proxmox VE 之前,我们用 KVM 建了很多虚拟机,了解了这款穷人的 VMware 产品,能做高可用集群,类似 VSphere 的 Live Migration 的时候,我们立刻就喜欢上它,当然最主要的就是免费!

就算要迁移之前的 KVM 虚拟机也十分的方便,其实核心的只有三句话,创建新虚拟机,迁移磁盘,把磁盘挂接到虚拟机上。

十分简单的一个脚本:
#!/bin/bash
id=$1
name=$2
disk=$3
#
pool=”vmpool”
#
[ -z “${disk}” -o ! -r “${disk}” ] && echo “Syntax: $0 id name disk” && exit 1
qm create ${id} –memory 1024 –net0 virtio,bridge=vmbr0 –name ${name} –serial0 socket \
–bootdisk scsi0 –scsihw virtio-scsi-pci –ostype l26
[ $? != 0 ] && echo “Create VM failed!” && exit 2
qm importdisk ${id} ${disk} ${pool} –format qcow2
[ $? != 0 ] && echo “Migrate disk failed!” && exit 3
qm set ${id} –scsi0 ${pool}:${id}/vm-${id}-disk-0.qcow2
[ $? != 0 ] && echo “Attach disk failed!” && exit 4

以上就是一个基本流程。

我们在迁移中遇到几个问题:
1. Ubuntu Guest 的网卡 ens8 被设置成了 ens18,这个需要修改 /etc/netplan 文件里面的网卡名,或者安装 cloud-init , 但是要删除原先 01 开头的 yml 文件
2. 源 qcow2 文件其实不需要在 KVM 环境下关闭 VM 的, 这个几乎等于可以做半在线迁移,能极大的降低 down time.

再聊 DNS 加密以及广告去除以及黑名单

DNS 黑名单其实是一个很重要的话题,很多人往往忽略。曾经在北美某电子商务大厂(不是A)和内部信息安全部门有业务交往,我们被要求管理一个 DNS 黑名单,在公司内部遇到此类域名解析,一律定向到内部的一个域名,在上面有一个 Web 页面,当然是警告了。

如果企业内部的 DNS 都是自己解析,并且能维护一个黑名单的话,基本上 90% 的网络安全事件都是可控的。 甚至还可以做很多类似 GFW 在做的事情,把 Google.com 给你一个某度的地址。

所以说,你可以脑补一下,这个 DNS 是多么神奇的事情,可以把不想给你看的东西去掉,所以,广告以及有病毒的恶意网站域名都是第一批次就被过滤的。

说了那么多,技术上怎么实现呢? 企业内部有 IT 可以做自己的 DNS 服务器,个人家庭网络,要怎么做才能过滤广告,才能安心看片呢?

基本上,你需要一个能安装 Linux 的小盒子,放在光猫旁边,把光猫的 DHCP 功能去掉,把这个 Linux 小盒子通过无线或者有线连接到光猫上,然后 Linux 上启动 DHCP 和 DNS 服务功能。

那么这个 Linux 小盒子,有哪些不同的实现形式呢?最常见的就是能刷机的路由器,例如斐讯的K2 比较常见,华硕的很多也能刷机。这里列出一个能刷 OpenWrt Linux 操作系统的最新版本的一些无线路由器列表,最后两列为 Flash 和内存是购买时要主要考虑的。

我们知道,我们上网时,一般都是要走运营商的 DNS 来解析的,就算我们不使用运营商的,很多人会使用公共 DNS 服务器, 例如 114.114.114.114,但是他们并不能保证我们的 DNS 解析是安全的,而且类似 Google 的域名也是基本被“拐”的,就算有的人知道使用 Google 的 DNS 服务器 8.8.8.8/8.8.4.4 ,但是 DNS 解析本身是不安全的,也就是说,你看过的网站,运营商还是能知道你访问了哪些网站。

那怎么解呢?我们就需要在 Linux 小盒子上安装 Go 语言编写的 DNSCrypt-Proxy 这个免费软件。通过名称就可以知道,它是对 DNS 解析做加密的,能从网络上已知的 DNS 加密服务器上做解析,完全绕过了运营商,而且做了加密。

安装了这个软件,指定了黑名单以后,你就会感觉网页是清爽很多,没有什么狗皮膏药了。

譬如我们看 YouTube,按 F12, 就可以看到很多被屏蔽的域名。

譬如我们看新浪的一则新闻,屏蔽的内容就更多

指定黑名单其实不难, git clone 项目地址,里面有一个公共的黑名单清单, util 目录下还有一个 Python 脚本能自动生成这个黑名单。

企业和个人对这个方案有兴趣的可以关注我们公众号,并留言哦!

DNSCrypt 的黑名单机制,能有效的去除广告以及恶意网站。 不过,对于有些原生的广告图片嵌入, DSNcrypt 确实还是没有效果的,因为此类广告和页面内容的域名是同一个,你总不能因噎废食,把所有正常内容都过滤掉吧。 所以 DNSCrypt 是一个小盒子上的“硬件”解决方案,对于此类特殊的过滤,还是需要浏览器里的广告去除插件来进一步净化环境。

以 Sohu.com 首页下半部娱乐版块内嵌的广告为例,这是使用了 Adblock 以后什么广告都没有的情形:

这是没有使用 Adblock 插件时,小部分广告图片依然有展示。

树莓派4B 上安装最新版本的 Ubuntu 1910 eoan

下载地址: https://ubuntu.com/download/raspberry-pi

下载到 Linux 机器上后解压:
# xz -d ubuntu-19.10.1-preinstalled-server-arm64+raspi3.img.xz
# dd if=ubuntu-19.10.1-preinstalled-server-arm64+raspi3.img of=/dev/sdb bs=32M
# mkdir /mnt/boot; mount /dev/sdb1 /mnt/boot
# touch /mnt/boot/ssh
# umount /mnt/boot; rmdir /mnt/boot
# eject /dev/sdb
拔掉 micro SD 卡,插入到 树莓派, 在 DHCP 网络里, 树莓派会自动取 IP 地址, arp 或者 nmap 或者网关上查看,或者 直接 ping ubuntu 看看上线。如果没有看到树莓派,看看网线问题。 然后
# ssh ubuntu@ubuntu 密码也是 ubuntu , 第一次登录会要求更改密码,并退出。
再次登录就能正常使用 ubuntu 了。

Proxmox VE 6 的集群

上回说到了 Proxmox VE 的单机安装和使用以及手工创建的 qcow2 虚拟机的迁移(V2V)。今天我们来说说集群。

熟悉集群的人都知道,集群系统有个脑裂问题,所以一般最少需要三个节点,Mariadb 的 Galera 集群方案还有另外一个解决偶数节点的仲裁器方案。

因此,我们下面的例子是以一个三节点的集群来讲解集群的创建和自动 Faileover 测试。

关于安装,再多讲一句,默认安装后,要先安装 proxychains,我们后面可以更快的从网上下载东西。 科学上网,你懂的!所以,我们一般先 apt install vim proxychains
然后 vim /etc/proxychains.conf 把 proxy_dns 注释掉,quiet_mode 打开,修改最后一行 socks 服务器为自己内网的代理, 然后 proxychains apt update ; proxychains apt upgrade 就可以快速更新 Proxmox 的 Debian 操作系统了。

我们有 pve-01, pve-02, pve-03 三个节点,域名为 .yj, 内部 DNS 都已经配置好,所以我们不需要去每个节点修改 /etc/hosts 文件。

加入集群有两个办法, Web 界面最简单,进入服务器视图,数据中心下的集群,选择一个节点,点击“加入信息”,选择拷贝信息, 然后去另外一个节点的 Web 登录界面,https://pve-02.yj:8006/ 点击“加入集群”,粘贴后,输入 root 口令,就成功了。

命令行也不算复杂,假定我们要把 pve-03 加入到 pve-01 的集群, ssh 登录到 pve-03 的命令行,敲入 pvecm add 192.168.7.241,我们就有了如下的输出截屏:

重新登录 pve-03 的 Web 登录界面,我们就可以看到三台主机都已经上线。

这个时候我们还没有定义过 HA group,实际上如果强行关闭一个节点,上面的虚拟机是不会自动切换的。 当然到了这一步,你肯定先会玩一下虚拟机的手工迁移了(不展开了)。

我们先定义好 HA Group:


下面我们把一台运行着虚拟机的 pve-02 节点,拔掉网线,看看情况:

以上先前是运行在 pve-02 上 101 虚拟机,我们拔掉网线后在 pve-03 Web界面上看到的集群日志:

刷新页面,我们可以看到 101 虚拟机已经“漂”到了 pve-01 节点上。

总结: Proxmox VE 的操作其实真心不难, 在一个简单的环境里,没有复杂的网络配置,只要用一台中心的 NFS 存储就可以实现所有虚拟机的高可靠。真心是“穷人”的高可靠解决方案。

通过 ssh 的隧道跳板机

绕过跳板机,一步直达目标主机

上次在公众号发了一段话讲了怎样从外部访问公司内服务器:

在办公室机器上打一个隧道到公网服务器上。 回家后登录到公网服务器,从那里直接就连接到公司的服务器了。 公司内服务器运行: user_internal@server_in_office$ ssh -f -N -R 2222:localhost:22 user@host.qcloud.com 腾讯云上服务器,运行 $ ssh -p 2222 user@localhost 就能进入办公室服务器了。 user 可以是办公室搭桥的服务器上任意的用户,不一定是当时搭桥的用户。 搭桥的 ssh 命令可以用 autossh 命令替换。

但是如果要从其他地方进入公司的服务器,每次都要先登录到云端,再在云端的服务器上运行上面的命令,是不是多了一个步骤? 解决方案来了:

ssh -o ProxyCommand=”ssh -W localhost:2222 user@host.qcloud.com” server_in_office

man ssh 对 -W 参数是这么解释的:

这是公司内服务器对外不暴露 ssh 端口的情形下的解决方案,当然,如果公司内服务器直接对外暴露 ssh 端口,就无需以上跳板,连第一步也是多余的了。

至于公司内 IP 地址经常变动,怎样获得相对不变的域名,一般都是 DDNS 的解决方案,我们采用 GoDaddy 的 API,把注册在 GoDaddy 上的二级域名,用定时任务检测到内部 IP 地址变化时,自动更新域名。
该脚本全文已经放在 github, 欢迎 fork and star.