Study hard and make progress every day!

2022-02-07
如何在Macos下配置ssh管理多个github账号

介绍在MacOS上管理两个Github账号的ssh key的方法,主要操作就是在ssh的配置文件~/.ssh/config中指定两个不同的Host。

前提介绍

两个github账号,分别为carl.shen和jibing57,对应使用的key如下:

  • carl.shen: id_rsa_carl_github_key
  • jibing57: id_rsa_github

其中,carl.shen是默认账号,jibing57是第二账号。

ssh 配置

两个账号,在~/.ssh/config配置文件中对应的配置如下:

1
2
3
4
5
6
7
8
9
Host "github.com"
HostName "github.com"
User "carl.shen"
IdentityFile ~/.ssh/id_rsa_carl_github_key
Host "jibing57.github.com"
HostName "github.com"
User "jibing57"
IdentityFile ~/.ssh/id_rsa_github

关键点就在于Host "jibing57.github.com"这一几个配置。
该设置的意思是: 当访问Host是jibing57.github.com, 需要使用key ~/.ssh/id_rsa_github来访问,但访问jibing57.github.com时,实际映射到的还是github.com
通过使用Host别名来实现不同的key同时访问github.com

阅读此文

2022-01-07
使用pg_repack回收PostgreSQL磁盘空间

pg_repack介绍

PostgreSQL数据库,因为multiversion concurrency control (MVCC)的原因,在update和delete的事务处理中需要将老数据另行保存一份,会导致占用的磁盘空间会比实际有效空间要大很多。

PostgreSQL自带了autovacuum和vacuum命令, 可以检测这部分旧数据,标记这部分空间为可用,供后续使用,一定程度上可以缓解存储空间肿胀(bloat)的问题,但问题在于autovacuum和vacuum只是在PG范围内标记空间为可用,并不会将空间释放给操作系统进行重新利用。
如果需要将空间释放和操作系统使用,需要使用vacuum full命令,但是该命令会使用排它锁,堵塞对应表的读写操作。在生产环境中是不推荐使用的。

pg_repack这个插件,可以在不阻塞表读写的情况下,进行表数据的清理。
作用机理是:创建一个新表,将数据从旧表移动到新表。为了避免表被独占锁定,创建了一个额外的日志表来记录原始表的改动,还添加了一个把INSERT / UPDATE / DELETE操作记录到日志表的触发器。当原始表中的数据全部导入到新表中,索引重建完毕,日志表的改动全部完成,pg_repack会连同新索引,用新表替换旧表,并将原旧表Drop掉。整个过程非常简单,非常可靠,但是需要注意的是——需要额外剩余足够的磁盘空间(原表大小 + 索引 + 额外的日志表空间)

实操

下面记录一次使用pg_repack来回收AWS RDS for PostgreSQL中磁盘空间的过程。

准备工作

查看RDS的数据库版本和支持的pg_repack版本。

查看数据库版本为PG 10.18

1
2
3
4
5
6
7
ebdb=> select version();
version
----------------------------------------------------------------------------------------------------------
PostgreSQL 10.18 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-11), 64-bit
(1 row)
ebdb=>

阅读此文

2021-12-21
使用growpart热扩展CentOS7的文件系统容量

有台CentOS 7机器磁盘空间不足,扩展了一下,记录下相关步骤。

情况描述

有台虚拟机,CentOS 7.x系统,数据盘空间不足了。给该数据盘添加了100G的空间,需要在LVM和操作系统中识别并使用这100个G空间。

理论准备

  1. 使用growpart将增加的磁盘容量,添加到对应的设备块(block device)中
  2. 使用pvresize,让物理卷(Physical volume)和卷组(Volume group)中识别增加的磁盘容量。
  3. 使用lvextend,将增加的磁盘容量分配到对应的逻辑卷上(logical volume)
  4. 让文件系统识别增加的逻辑卷的容量
    • ext4系统使用resize2fs命令
    • xfs系统使用xfs_growfs命令

操作前系统信息

先查看系统磁盘使用情况,涉及到的命令如下:

  • lsblk: 列出操作系统的块设备
  • df -hT: 列出文件系统的磁盘使用情况
  • pvdisplay: LVM中列出物理卷情况
  • vgdisplay: LVM中列出卷组
  • lvdisplay: LVM中列出逻辑卷
  • fdisk -l: 列出磁盘分区表
阅读此文

2021-10-12
Aliyun Linux上挂载NAS文件系统

摘录阿里云官网在Aliyun Linux上挂载NAS文件系统的各个步骤,汇聚在此。

参考资料

阿里云官方相关的文档链接:

挂载步骤

如下是在系统为Alibaba Cloud Enterprise Linux Server 17.01的ECS上挂载通用型NAS(性能型)的步骤。实际操作中,需要将如下命令中的file-system-id.region换为实际创建的NAS挂载点。

阅读此文

2021-10-09
CentOS7 中更新CA根证书解决Let's Encrypt证书过期问题

起因

签名Let’s Encrypt的证书中的其中一家根证书机构IdenTrust的DST Root X3的证书,在2021-09-30号过期了。
导致了Let’s Encrypt之前签发的证书,被一些系统判定为非法。

关于这事的前因后果,Let’s Encrypt SSL证书失效问题这边有非常清晰详尽的描述。摘录如下:

发生了什么

在 PKI 证书体系中,信任是通过逐级签名以及对这些签名的验证来实现的。 对大部分客户端系统来说,这些系统中会存在一个或多个受信的根证书发证机构的证书, 其公钥是通过这些系统本身的更新机制派发的。

根证书发证机构的证书通常是自签名的,更新相对来说比较麻烦(它通常依赖于操作系统的在线或离线更新机制), 因此这些证书的私钥事关重大,因此人们通常不希望经常更新它们,因而证书发证机构在绝大多数时候并不会使用这些私钥来签署证书。 取而代之的是,他们会创建一些称为中级发证机构的证书用来签署日常的证书,这样根证书的私钥可以采用更为严密的方法来保护, 例如可以把它们从网络上彻底断开,而中级发证机构的证书则可以以较高的频率进行密钥轮换,借此来避免其私钥暴露导致的风险。

一个新的发证机构进入市场时,其自签名的根证书往往不会被已经在市场上的客户端系统认可, 因此这样一来新的发证机构想要获得用户就必须想办法解决能被用户承认这个问题。 一旦获得了一定的知名度并证明了自己的可靠性, 这些发证机构便可以遵循一定的流程获得主流浏览器或操作系统的认可, 并将自己的根证书也加入到它们的受信根证书列表中了。 所以,在起步阶段,新的发证机构往往会要求一些已经存在的根证书去对其根证书进行交叉签署, 在客户端验证证书有效性时,由于这些根证书在他们看来是一个经过了受信根证书签名的中级证书而不是一个普通的不受信自签名根证书, 因此也就不会给出无法验证证书是否有效的提示,而是能够正确地对其有效性进行验证了。

Let’s Encrypt 在起步阶段正是采用了这种做法。通俗地说,它的中级发证机构的证书被两家根证书机构同时签名, 其一是它自己的 ISRG Root,另一个是另一家根证书机构 IdenTrust 的 DST Root X3。初期,由于 DST Root X3 已经被许多操作系统和浏览器认证过,因此为其普及起到了非常重要的作用。

UTC 时间 2021年9月29日 19:21:40,DST Root X3 的根证书过期了。这样一来,这一边的信任链便不再成立。

DST Root X3 的过期时间是早已公布了的,过去几年, Let’s Encrypt 也大力推广了自己的 ISRG Root, 因此对比较新的操作系统来说,DST Root X3 的根证书过期这件事并不是什么太大的问题,毕竟另外一条信任链仍然可以用来验证证书的有效性。

然而我们都知道凡事都是有代价的。早先版本的 OpenSSL 中存在一个 bug,简而言之,在验证证书时, 它会捋出一条潜在的信任链,然后再逐个确认链条上的每一个环节的过期时间。

这样一来,如果本地的根证书存储中包含了已经过期的 DST Root X3 证书,OpenSSL 就有可能找到这条信任链, 并在稍后发现该根证书已经过期并不再信任之。这会导致证书无法验证,并导致对应的服务无法访问。

应对方案

首先,更新到最新版本的SSL库是可以完全避免这个问题的。OpenSSL在 2016 年的 1.1.0 版本中已经修正了这个问题。 当然这个行业你懂的,不出点惊天的问题你永远不知道谁在游泳的时候光着腚,这不今天就退潮了吗?

OpenSSL 官方给出了三种替代的应对方案。

第一条是删掉已经过期的 DST Root X3 证书。这个方法比较简单,但部署成本却比较高,因为它需要修改根证书数据库, 对于已经在役的系统特别是学名 万物互联 (Internet of Things) 的 万粪互联 (Internet of Shit) 来说,您这个要求就可能太高了。

第二条是让调用者启用 X509_V_FLAG_TRUSTED_FIRST。这需要修改应用程序;对于第三方应用程序作者来说, 这个要求可能也有点高,不过 OpenSSL 官方已经准备出一个新版本的 OpenSSL 1.0.2 系列来允许发行商把该选项写死在库里。

第三条则是服务器端可以做的事情:不要提供采用 DST Root X3 签名的那个中级证书。这个对于自己控制服务器的同学来说更容易实现一些, 只需要用 openssl x509 -in chain.pem -noout -text 查看一下证书链,并根据需要删除其中那个交叉签名的证书就可以了。

我猜最终整个行业将采取的措施应该是第一条或第二条,如果你是那个受害的运行服务器的倒霉蛋儿,现在采取第三条应对方案也许也不晚。

阅读此文

2021-09-18
Shell Tips

简单的log和err_log

shell函数如下:

1
2
3
4
5
6
7
8
9
10
11
function log()
{
timer=`date "+%Y-%m-%d %H:%M:%S"`
echo "$timer -- $1"
}
function err_log()
{
log "[Error]: $1"
}

用法:

1
2
log "hello world."
err_log "hello error."

输出:

1
2
2021-09-20 11:47:49 -- hello world.
2021-09-20 11:47:49 -- [Error]: hello error.

阅读此文

2021-08-17
给AWS Lambda node 12x环境添加Layer

起因

收到AWS侧的通告:
因为Nodejs官方对Node.js 10的支持于2021 年 4 月 30 日结束了,AWS侧于 2021 年 7 月 30 日终止在 Amazon Lambda 中对 Node.js 10 的支持。

  • 自 2021 年 7 月 30 日起
    • Lambda 将不再对 Lambda 函数使用的 Node.js 10 运行时应用安全修补程序和其他更新,并且使用 Node.js 10 的函数将不再符合获得技术支持的条件。
    • 此外,您将无法再使用 Node.js 10 运行时创建新的 Lambda 函数。
  • 从 2021 年 8 月 30 日开始
    • 您将无法再更新使用 Node.js 10 运行时的现有 Lambda 函数

Lambda的Nodejs 10.x平台在8月底就要不能更改了, AWS官方建议升级到最新的Node.js 14。
有个很老的用来处理图片resize的Lambda Function是10.x版本的,需要升级,稳妥起见,决定先升级到12.x版本。

升级过程

Console上升级版本

直接Console上操作,置换到12.x平台后,运行函数提示有Error: write EPIPE的错误。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
ERROR Error: write EPIPE
at afterWriteDispatched (internal/stream_base_commons.js:156:25)
at writeGeneric (internal/stream_base_commons.js:147:3)
at Socket._writeGeneric (net.js:787:11)
at Socket._write (net.js:799:8)
at doWrite (_stream_writable.js:403:12)
at writeOrBuffer (_stream_writable.js:387:5)
at Socket.Writable.write (_stream_writable.js:318:11)
at gm._spawn (/var/task/node_modules/gm/lib/command.js:253:18)
at /var/task/node_modules/gm/lib/command.js:140:19
at series (/var/task/node_modules/gm/node_modules/array-series/index.js:11:36) {
errno: 'EPIPE',
code: 'EPIPE',
syscall: 'write'
}

调查了一下,12.x上面官方node环境,不再默认提供ImageMagic的命令组件了。我们函数中使用到了ImageMagic的组件来resize图片,在12.x上面就报错了。

阅读此文

2021-07-18
蜂窝版Apple Watch一卡双终端和家人共享独立eSIM的设置方法

前阵子购买了两个带蜂窝的Apple Watch,一个Apple Watch Series 6,一个Apple Watch SE。开通设置蜂窝的时候折腾了好一阵,最终搞好了,记录在此,给大家一个参考。
本文内容来自于2021-07-18之前apple和各运营商的网页说明,后续apple和运营商所提供的服务可能会更新。

预备知识

首先了解一下Apple Watch蜂窝绑定相关的一些知识点

Apple Watch两种类型

Apple Watch联网模式上分为两种

  • GPS版(不能连接运营商网络,通信要靠WIFI或者蓝牙连接iPhone)
  • GPS + cellular, 即我们所称的蜂窝版(除了GPS版的连接方式外,配置后还可以直接使用运营商网络)

Apple Watch绑定模式

Apple Watch的绑定需要在iPhone上操作,绑定支持两种模式

  • 给自己绑定Apple Watch(为自己的iPhone绑定Apple Watch)
  • 给家人共享(用自己的iPhone给没有iPhone的家人绑定Apple Watch)

其中,”给家人共享”模式,必须要是蜂窝版的Apple Watch才可以使用。

运营商蜂窝模式

Apple Watch蜂窝版要上网,目前运营商提供了两种方式

  • 一号双终端(需要有一个iPhone手机在使用实体sim卡,手表和iPhone共享同一个号码)
  • 独立eSIM业务(手表开通使用一个独立的号码。自己可以没有iPhone,使用家人共享模式绑定Apple Watch)

三大运营商对蜂窝模式的支持

运营商 一号双终端 独立eSIM业务 运营商说明网页
中国移动 支持 不支持 点这
中国电信 支持 支持 点这
中国联通 支持 支持 点这

其中:

  • 中国移动不支持独立eSIM业务, 也就不支持家人共享模式。意味着如果你是移动的号码,就无法使用家人共享模式,给孩子设置Apple Watch来使用一个独立的号码。
  • 不是所有地区的运营商都支持开通eSIM业务。详情请咨询各地运营商。
阅读此文

2021-07-12
搭建MongoDB集群

搭建一个简单的MongoDB副本集的过程

准备过程

服务器信息

三台服务器信息如下:

  • 系统版本: CentOS 7 7.6.1810
  • IP和主机信息:
    • mongodb_1 : 192.168.187.209
    • mongodb_2 : 192.168.187.210
    • mongodb_3 : 192.168.187.211
  • 安装MongoDB版本: 4.2

设置主机名

设置主机名, 根据预先的规划,分别登陆机器设置主机名字。

1
2
3
sudo hostnamectl set-hostname mongodb_1
sudo hostnamectl set-hostname mongodb_2
sudo hostnamectl set-hostname mongodb_3

设置主机名,添加如下信息到三台机器的/etc/hosts中。

1
2
3
4
5
sudo cat >> /etc/hosts << EOF
192.168.187.209 mongodb_1
192.168.187.210 mongodb_2
192.168.187.211 mongodb_3
EOF

阅读此文

2021-06-29
AWS cli命令tips

显示不分页

使用AWS_PAGER="" aws ....来执行cli命令时,就可以前端显示不分页了。

Reference:

删除EKS的步骤

官方文档参考: https://docs.aws.amazon.com/eks/latest/userguide/delete-cluster.html
大概步骤

  1. 删除kubenetes中type为LoadBalancer的service,此时会删除aws侧对应的load balancer
  2. 删node groups和Fargate profile
  3. 删除EKS cluster

如果资源不是由CloudFormation创建的,那么逐次删除资源时可能会有一些依赖,删除时会报错。
报错的话就一个一个找出来依赖资源删除即可。

阅读此文