git tag 的理解和版本管理的自动整合

微博中有很多 hash tag,其实来源于 Twitter,部分微信用户也会在自己的朋友圈文章中打 Hash tag,当然只是自己搜索有用,没有其他用处。

开发里有个说法:代码即文章,文章即代码;那当然是要把代码写得非常优雅才可以。 本文旨在通过 git tag 相关命令 ,对版本打标签的做法予以自动化集成到代码的 Web 界面,并能在 SaaS 情形下,让客户自己决定是否更新版本,一个鼠标点击即可完成版本升级。

先来讲一下 git 里面的两种 tag,一个叫 Annotation, 一个叫 Lightweight,我们姑且称为注释标签和轻量标签,前者带有很多 MetaData,后者则没有任何 MetaData,是跟随当前 commit 而来的。 我们先讲这个简单,也在刚开始把我们弄糊涂的轻量标签。

简单而言, 打标签是需要在代码 commit 完, push 之前做的一个步骤。 git tag -a TAGNAME 就是注释标签,没有 -a 就是轻量标签。举例

$ git commit README.md -m "先 commit 再  git tag v2.0.11"
$ git tag v2.0.11  // 添加轻量标签
$ git show v2.0.11  // 验证
commit 9cc9c4a32d581e1aed98b2378104f2d5e29c02bd (HEAD -> edu1.1, tag: v2.0.11)
$ git describe
v2.0.10-1-g9cc9c4a3
$ git show-ref --tags v2.0.11
9cc9c4a32d581e1aed98b2378104f2d5e29c02bd refs/tags/v2.0.11
$ git describe --tags
v2.0.11
$ git push  // push 代码 
$ git push origin tag v2.0.11  // push 标签

这里有一个困惑的地方就是 git describe 的输出, 没有 –tags 参数的时候,输出的其实是 v2.0.10-1-g9cc9c4a3,这是从上一个注释标签开始以来的标签。我们看下 git describe 的解释

The command finds the most recent tag that is reachable from a commit. If the tag points to the commit, then only the tag is shown. Otherwise, it suffixes the tag name with the number of additional commits on top of the tagged object and the abbreviated object name of the most recent commit. The result is a “human-readable” object name which can also be used to identify the commit to other git commands.

By default (without –all or –tags) git describe only shows annotated tags. For more information about creating annotated tags see the -a and -s options to git-tag(1).

有了对以上命令的理解,注释标签就很好解释了, 添加注释标签类似对代码 commit ,就是需要 -m 用来添加对标签的注释。 其他就是 push 的时候需要把标签一起 push 出去。

如果我们在以上一个完整的周期完成后,继续提交代码,但是遗忘了打标签,我们用 git describe 加和不加 --tags 可以看到区别:
$ git describe // 针对注释标签
v2.0.10-2-g54a3d4ca
$ git describe --tags  // 针对任意类型标签
v2.0.11-1-g54a3d4ca

我们可以用 $ git tag -l -n 3 列出所有的标签 ,3 表示输出最多3行注释
在 git 的新版本里,支持 sort
我们可以使用

git tag -l -n --sort="v:refname"

来对 v2.01 之类的版本号标签,根据版本号排序。在 sort 后面的变量前面加一个 减号,我们可以倒排序,这样,我们就可以自动生成 Release Notes 了

git tag -l -n --sort=-"v:refname"

删除远程标签:

$ git push --delete origin tagname

Vuejs 的版本管理, 可以直接用 npm version v1.x.x -m “版本注释” 直接推送, npm 会直接管理 git 版本号,然后用 $ git push origin master –follow-tags 就可以把代码和版本一并推送到代码库,然后在相应的代码文件里,直接调用 config.version 即可读取到 package.json 文件里,自定义的软件包的版本号了。

同样的对于小程序项目,没有 package.json 文件,我们可以手工创建一个:

然后,我们用同样的 npm version v1.2.3 -m “注释” 之类的打标签,然后用 git push origin master –follow-tags 把所有标签都 push 出去

后记, 每次打完标签, 要打很多字,而且 branch 的名字各不相同,写了一个 alias,放到 profile 里, 以后每次 commit 好代码,打完标签,只要敲 .push 就可以推送带标签的代码了:

alias .push='git push $(git remote|tail -1) $(git branch|awk '"'"'/^\*/ {print $NF}'"'"') $(git describe --tags)'
另外如果要查找当前目录下的版本库的顶层目录用:
$ git rev-parse --show-toplevel 

Go 语言动态追踪 git 的版本号,需要在编译时,传入版本号的变量:

ver=$(git describe --tags)
go install -ldflags "-X main.file_v=$ver" myprog.go
这里 file_v 是 main 函数里定义的变量 

定制 curl 支持 –dns-servers 也就是 c-ares 异步 DNS 解析

操作系统默认安装的 curl 是不支持指定自定义的 DNS 服务器的。我们在一台有域名过滤的服务器上, 需要跑 curl ,要绕过系统默认的 DNS 解析器,所以,需要在命令行下指定自己的 DNS 解析服务器,这个需要 c-ares 支持。

# ./configure --enable-ares --enable-https --with-nghttp2  --with-librtmp=/usr/lib/x86_64-linux-gnu --with-gssapi --with-zlib --with-libssh2
如果不想删除原先的 curl 包的话,运行一下:
# ln -s /usr/local/lib/libcurl.so.4.6.0 /usr/lib/x86_64-linux-gnu/libcurl.so.4

跑 configure 之前,当然要先安装相关的 dev 包:
libnghttp2-dev, libc-ares-dev, libssh2-1-dev, librtmp-dev

接下来我们就可以用 curl 来分析网页的 title 来大概知道某个域名是做什么的:

# /usr/local/bin/curl -sS --dns-servers "114.114.114.114" http://www.tuchong.com/|xmllint --html --nowarning --xpath '//title' - 2>/dev/null|tr -d 'a-z<>'

基于 unbound 递归 DNS 服务的广告屏蔽(0)

unbound 的好处就是递归,也就是说,所有的 DNS 请求,都是以 unbound 部署点的 IP 直接从 DNS 根服务器上请求,直到请求到合适的 IP 为止,当然中间不排除被掉包。如果我们走 DNSSEC 的话,就会好很多(回头再说 DNSSEC)。

网络上有篇文章关于 FreeBSD 上跑 unbound + adblock 的脚本,可是我们看了下这个脚本,里面其实使用的是陈旧的4年之前的一个老外的黑名单列表。脚本的核心就是根据那个列表用 awk 转换成 unbound 格式的。 其实也是用 awk 的,我们自己写的就是一行代码:

awk '!/^#/ && !/^$/ {print "local-zone:","\"" $1 "\"","static"}' ${BL} > adb.conf

好吧,如果源清单都是陈旧的,没有在更新的,广告屏蔽也就失去了意义。

实际上以上写出来的 .conf 文件不适合 unbound 1.6.x 版本,低版本的 unbound 每个域名需要写两行,这里有个参考的文章。但是使用的都是那个旧的黑名单。

香橙派 Pi Zero 上的容器操作系统 BalenaOS

香橙派是深圳迅龙公司的产品。该公司旗下有不同种类的基于 AllWinner 芯片的不同的 Pi. Pi Zero 只是其中一个比较低端的产品,H2(ARM Cortex-A7 Quad-core) 的CPU,512M 内存,1x 100M 网口, Wi-Fi 模块, OTG 电源 + 1x USB 2.0 ,最大 32GB TF 卡。当然操作系统要灌在 TF 卡上。

去 balenaCloud 注册一个账号以后,添加设备,选择香橙派 Pi Zero,下载 img,烧写到 TF 卡上,插入到香橙派,上电,插网线,它会自动 DHCP 从网络里取到 IP 地址,然后,过了很长很长时间(1天,2天?)后,在 balena 的云端可以看到“Online”,之前一直 Inactive,不理解是网络那里有问题。

Balena 在他们家网站介绍就是一堆构建,部署,管理 Linux 设备的工具集。下面的这个图基本上能概括他们家的产品列表。这是一家初创公司,看上去充满了很多创新的元素。

部署的前面10个设备是免费的,20个以内每个月 99 美元!50个设备,每个月 299 美元,100 个设备的话要 1299 美元,企业级支持是每月 2999 美元!

先看下,我们已经上线的香橙派吧:

让我们通过命令行进入香橙派看看里面到底是什么东西。我们用 balena scan 看下局域网内的设备:

我们用 balena ssh IP地址,就可以进入香橙派了。 使用 lsof -Pi 命令,我们就可以查看设备侦听的所有网络口:

看下板子的信息:

NEWiFi D2 成都谛听 MT7621 无线路由刷 Breed & OpenWrt

万能某宝,这款 512M 内存 32M Flash 的“大家伙”,带运费 xxx 元。从“占地面积”而言,和之前买的同样 512M内存的香橙派真的是一个天上一个地下。店主有刷好的版本的,为了自己动手,买了崭新的版本,我们自己动手刷 Breed。

按 reset 开机,进入 192.168.1.1 的界面是原生的固件更新界面,不敢造次直接在这个界面刷 Breed。

翻了几篇文档,一个是有一个可执行文件 .exe 直接在 Windows 命令行下执行,应该是 Python 写的,开启路由器上 ssh 成功后,写入什么东西的时候报 404 错误,应该是什么地方下载的目录不对还是怎样,就忽略了这个方法。

既然已经可以 ssh 了, 理论上来说, 我们可以用 mtd 命令直接刷。 root 登录后,看到了潘多拉的界面:

另外一个刷入 Breed 的办法是下载一个 newifi-d2-jail-break.ko 文件,以内核模块的方式刷, 下载完后, 把文件 scp 到路由器 /tmp 目录下, 运行 insmod newifi-d2-jail-break.ko ,过一会儿路由自动重启后,就可以进入原来的潘多拉。这个时候,再按 Reset 重启,就可以进入 Breed 了。 去 Openwrt 官网的 TOH 页面搜索 “Newifi” 就可以找到最新版本的固件,下载完后, Web 端就可以用 Breed 刷入 OpenWrt 了。

关于加强 ssh 安全的15个最佳实践

原文: https://securitytrails.com/blog/mitigating-ssh-based-attacks-top-15-best-security-practices?from=relatedposts 简要翻译如下:

  1. 不要使用默认的 22 端口
  2. 使用 tcp wrapper
  3. 在防火墙上过滤 ssh 端口,安装 CSF
  4. 关闭 root 登录
  5. 关闭口令登录
  6. 加强口令(如果不能关闭口令登录的话)
  7. 设置 Idle Timeout
  8. 关闭空口令(没有人会这么SB,允许空口令的用户)
  9. 定制一个 ssh 登录 Banner
  10. 自动 Block SSH 暴力攻击,有很多工具可以使用: SSHGuard, Fail2ban, 或者 DenyHosts
  11. 不要在笔记本电脑或者桌面电脑上开启 ssh
  12. 关闭 x11 转发
  13. 设置最多尝试次数, MaxAuthTries 3
  14. 每次root 登录都用邮件提醒
  15. 保持 ssh 软件最新版本

用 whoami.ds.akahelp.net 查看递归解析器

2018年5月 Akamai 在他们家博客上发布了这个新域名替代 whoami.akamai.net 的通知。

所有的计算机系统连接互联网的话,都需要一个 DNS 解析器,一般而言,在网络的边缘接入层,当在家庭或者企业用光猫或者路由器拨号或者其他方式接入运营商时,运营商会默认分配 DNS 。然后 DNS 污染就产生了,然后就有了国际求学的需求。

DNS 查询一般是需要一个递归解析器,帮我们的上网电脑作为客户端,把“正确”的 IP 地址返回给我们。运营商给我们的 DNS 服务器就是这样的递归解析器。譬如我们在 PPPoE 拨号路由上,设置自动获取运营商的 DNS ,就得到 116.228.111.118 和 180.168.255.18。

我们修改 Linux 主机上的 /etc/resolv.conf ,指定 nameserver 180.168.255.18 用 dig 命令多次查询 whoami , 就得到如下的结果:

我们可以修改 /etc/resolv.conf ,设置不同的 nameserver 到公共的 DNS 服务器,例如 1.1.1.1, 8.8.8.8,8.8.4.4, 233.5.5.5 等等,来用同样的 dig 命令来检查这些公共 DNS 服务器的递归服务器。

另外,如果要通过 DNS 查找自己的 IP 地址,我们可以用以下的三个 DNS 服务器里的任意一个来查找:

nslookup whoami.akamai.net. ns1-1.akamaitech.net.
nslookup -q=TXT o-o.myaddr.l.google.com. ns2.google.com.
nslookup myip.opendns.com. resolver1.opendns.com.

最后,我们必须提一下,用unbound 这个 DNS 解析软件,在企业局域网内部建设自己的 DNS 递归服务器。也就是说每次局域网内部的电脑请求 DNS 访问时,如果不在缓冲的话,都是向根服务器请求的,绕过了 ISP,也没有使用公共 DNS,这个在被污染的世界里,能保持出淤泥而不染,是绝对值得部署的。刚开始的时候,解析会慢,但是使用多了,就会很快。 配合广告,钓鱼域名的过滤规则,真正实现我命由我不由天!

我们的一台机器上跑了三个 DNS 服务,分别侦听在 53, 5300, 5350 上, 53 上的 dnsmasq 把 DNS Query 转发给 DNSCrypt-Proxy (5300),而 5350 上的 Unbound 是独立的,通过 unbound 查询递归服务器返回的 218.82 的地址,就是公司的公网地址。

KVM Bridge nmcli 修改网卡等等

之前刚研究 KVM 时,记录的一些笔记

删除不要的 Bridge: br1

# ifconfig br1 down
# brctl delbr br1
# brctl show
$ virt-sysprep --list-operations
$ virt-clone -o centos-02 -n centos-03 -f /opt/kvm_disk/centos-03.qcow2
 
# cloud-init clean
# systemctl restart cloud-init-local.service
# netplan apply

# virsh qemu-agent-command <guest-name> '{"execute":"guest-info"}'

linuxtechi@kvm-ubuntu18-04:~$ sudo apt install cpu-checker
linuxtechi@kvm-ubuntu18-04:~$ sudo kvm-ok

virsh net-update add-last ip-dhcp-host \
   --file "<host mac='00:11:22:33:44:55' ip='192.168.122.45'/>" \
   --live --config

$ virsh dumpxml centos-03|grep 'mac address'
# yum provides avahi-resolve --disablerepo=epel

error: Unsafe migration: Migration may lead to data corruption if disks use cache != none or cache != directsync

# nmcli con show
# nmcli con delete uuid
# nmcli con add type ethernet ifname eth0 con-name eth0 \
  autoconnect yes ip4 192.168.1.10 gw4 192.168.1.1
# nmcli con mod eth0 ipv4.method manual 
# nmcli con mod eth0 ipv4.dns "8.8.8.8 8.8.4.4"
# nmcli con down eth0 && nmcli con up eth0