超简明小教程:如何为你的 Github 源码提交添加绿色(数字签名)验证小图标

Github Signed Verified Mark
Github Signed Verified Mark

今天 Github 添加了一个新功能:如果你的源码提交(commit)或者 tag 添加了 GPG 数字签名,则 Github 会在旁边显示一个绿色的钩钩小图标表示该数字签名通过验证。Git 的数字签名由来已久,通过它可以多一层验证以保障源码的提交确为作者本人,所以如果你之前使用 Git 时就已经习惯了为 commit 或者 tag 添加 GPG 数字签名,现在转到 Github 网站看看你的源码仓库(repository),把你的 GPG 公钥填上,说不定已经能看到绿色小图标已经躺在哪儿了(题图是我的一个源码库于 2014 年的一次 tag 更新)。

本文假设你对 GPG 数字签名一无所知,通过下面几个简单步骤可以为你的源码库的更新添加酷酷的绿色验证小图标。

1、准备 GPG 工具

GPG 是一个开源免费的加密及数字签名程序。没猜错!它又是一个命令行工具,虽然也有一些图形化的前端,不过其实都用不着,因为它跟 Git 的情况类似,常用的命令就那么几个而已。GPG 在大部分 Linux 发行版都已经内置,因为 Linux 正是使用 GPG 数字签名来验证从网上(各个镜像服务器)下载回来的软件包的数字签名以保证没经过别人篡改(所以国内的 Linux Mirror是可以十二分放心使用的,注意这里说的是镜像而不是源 repo 噢,非发行方的官方 repo 是不能随便用嘀,除非是类似 EPEL 这种比较靠谱的)。至于 OS X,则可以通过 Homebrew 来安装:

$ brew install gpg

2、生成你自己的 GPG 密钥对

无论是加密还是数字签名,都需要你事先创建属于你自己的 GPG 密钥对,方法跟使用 SSH 创建密钥对的过程很类似,命令如下:

$ gpg --gen-key

到询问你的名字和 email 地址时,名字建议使用你比较常用的网名或者 id,反正是别人可以联想到或者一看便知道是你的名字,比如我的是 @ivarptr当然类似工作等正式场合还得正式一点啦,咳咳。email 地址比较重要,要填写真实的。然后它会要求你输入一个密码用于保护你的密钥(注意,以后使用你的密钥时,程序都会要求你输入这个密码方能继续)。完成后使用下面命令可以罗列当前本机所拥有的密钥:

$ gpg --list-secret-keys
List GPG secret keys
List GPG secret keys

不出意外的话应该能看到类似上图所示的结果,这时你已经拥有属于自己的 GPG 密钥对了。

3、签名你的 Git Commit 和 Tag

方法很简单,在你本地 Commit 更新时,添加一个 -S 参数(注意是大写英文字母 S)就可以了,命令如下:

$ git commit -a -S

然后在显示 log 时可以添加参数 –show-signature 让数字签名显示出来,命令如下:

$ git log --show-signature

如果你能看到 “gpg: Good signature from …” 等字样,说明已经签名成功了。

签名 Tag 的情况类似,但参数是小写英文字母 s,命令如下:

$ git tag -s v1.0.2

然后你在 show 这个 tag 时会看到数字签名,或者使用 -v 参数可以验证这个签名,命令如下:

$ git tag -v v1.0.2

完成后,就用 git push 提交到 Github 吧!

4、告诉 Github 你的 GPG 公钥

Github 需要知道你的 GPG 公钥(所谓公钥就是指密钥对里面的可公开部分,另外那个不可公开的部分叫做私钥),才能验证你的数字签名,然后才能加上绿色钩钩小图标。所以首先导出你的 GPG 公钥:

$ gpg --armor --export your_email@example.com

把上面命令的 email 地址替换成你自己的,命令执行后就会以字符的形式显示你的公钥,选中输出的所有字符(即从 —–BEGIN PGP PUBLIC KEY BLOCK—– 这行开始到 —–END PGP PUBLIC KEY BLOCK—– 这行为止,包括这两行)然后复制,然后粘贴到你 Github 账号设置里面的 SSH and GPG key 里头就可以了。

然后刷新一下你的 Commits 和 Release 页面吧,是不是已经看到绿色验证小图标了?好吧,有时有缓存,需要耐心等待一段时间。

如果想了解更多关于 GPG 和 Git 数字签名技术以便日后熟练掌握运用,比如导出导入 GPG 密钥对、加密文件、共享交流公钥等等,我这里挑选了一些简单易懂的文章:

使用 ffmpeg 缩放、裁剪、剪辑视频

我们平时使用手机拍摄的视频一般都在1080p及以上,在实际应用中,比如共享给朋友等,可能需要处理一下会比较方便。下面列出几个 ffmpeg 常用的处理视频方法(如果只需要格式转换,可以参考我之前的一篇文章《使用H264编码转换视频》

缩小视频

假设原始视频尺寸是 1080p(即 1920×1080 px,16:9),使用下面命令可以缩小到 480p:

$ ffmpeg -i a.mov -vf scale=853:480 -acodec aac -vcodec h264 out.mp4

各个参数的含义:

  • -i a.mov 指定待处理视频的文件名
  • -vf scale=853:480 vf 参数用于指定视频滤镜,其中 scale 表示缩放,后面的数字表示缩放至 853×480 px,其中的 853px 是计算而得,因为原始视频的宽高比为 16:9,所以为了让目标视频的高度为 480px,则宽度 = 480 x 9 / 16 = 853
  • -acodec aac 指定音频使用 aac 编码。注:因为 ffmpeg 的内置 aac 编码目前(写这篇文章时)还是试验阶段,故会提示添加参数 “-strict -2” 才能继续,尽管添加即可。又或者使用外部的 libfaac(需要重新编译 ffmpeg)。
  • -vcodec h264 指定视频使用 h264 编码。注:目前手机一般视频拍摄的格式(封装格式、文件格式)为 mov 或者 mp4,这两者的音频编码都是 aac,视频都是 h264。
  • out.mp4 指定输出文件名

上面的参数 scale=853:480 当中的宽度和高度实际应用场景中通常只需指定一个,比如指定高度为 480 或者 720,至于宽度则可以传入 “-1” 表示由原始视频的宽高比自动计算而得。即参数可以写为:scale=-1:480,当然也可以 scale=480:-1

 裁剪视频

有时可能只需要视频的正中一块,而两头的内容不需要,这时可以对视频进行裁剪(crop),比如有一个竖向的视频 1080 x 1920,如果指向保留中间 1080×1080 部分,可以使用下面的命令:

$ ffmpeg -i a.mov -strict -2 -vf crop=1080:1080:0:420 out.mp4

其中的 crop=1080:1080:0:420 才裁剪参数,具体含义是 crop=width:height:x:y,其中 width 和 height 表示裁剪后的尺寸,x:y 表示裁剪区域的左上角坐标。比如当前这个示例,我们只需要保留竖向视频的中间部分,所以 x 不用偏移,故传入0,而 y 则需要向下偏移:(1920 – 1080) / 2 = 420

视频缩放和裁剪是可以同时进行的,如下命令则为将视频缩小至 853×480,然后裁剪保留横向中间部分:

$ ffmpeg -i IMG_4940.MOV -strict -2 -vf scale=853:480,crop=480:480:186:0 out.mp4

剪辑视频

如果有一段很长的视频只需保留其中的一段,可以使用下面命令对视频进行剪辑。

$ ffmpeg -i a.mov -ss 00:00:21 -t 00:00:10 -acodec aac -vcodec h264 -strict -2 out.mp4

其中 -ss 00:00:21 表示开始剪辑的位置(时间点),-t 00:00:10 表示剪辑的长度,即 10 秒钟。

当然一段视频是可以在一个命令里同时进行剪辑、缩放、裁剪的,只需把相关的参数合在一起即可。

简单搭建 https proxy 服务器

在各种上网的方法当中,https proxy 可能是最简单、方便、快速的,它免去了 vpn 各种拨号连接的麻烦,也免去了安装各种客户端的麻烦,同时搭建所用的软件也是历史悠久的非常稳定。

吐槽:如果问为什么这么好的方式却很少人用,答案可能是因为它需要较多的¥money,而且可能需要一张双币/多币种信用卡来购买这些东西:一个虚拟服务器 vps,一个域名,一个 SSL 证书。vps 我比较推荐 linode,并不是因为你戳一下这个链接并成功购买后能返回一点零钱给我,而是 linode 相当厚道,它会跟随主流免费为你升级 CPU、内存、硬盘、带宽等等。域名和 SSL 证书大家可以参考我的前一篇《如何购买廉价 SSL 证书》。全部扔上购物车一年大概 $150 以上,捉襟见肘的可以考虑多人合购。

好了说回正题,用于实现 https proxy 的服务端软件很多,可以用老掉牙但很稳定的 squid,也可以随便用一个轻量级的 http proxy 程序搭配老掉牙的 stunnel,或者试试新秀 node-spdyproxy 也可以。

下面介绍一下比较简单的方案:轻量级 http proxy 程序 tinyproxy + stunnel 。

1、安装 tinyproxy 和 stunnel

首先使用各个 Linux 发行版的包管理器安装 tinyproxy 和 stunnel,比如:

$ sudo yum install tinyproxy stunnel // 对于 centos linux

$ sudo pacman -S tinyproxy stunnel // 对于 arch linux

 

安装完成后顺便设置它们随开机启动(可选)。

2、设置 stunnel

把你证书私钥和购买的证书扔到 /etc/stunnel 里,然后编辑文件 stunnel.conf,先指定私钥和证书文件名:

cert = /etc/stunnel/mycert.pem
key = /etc/stunnel/mykey.pem

需要注意的是从证书服务商购买回来的证书通常是几个小文件,大概有是:一个你的域名证书,一个证书链证书,一个root证书。把它们用文本编辑器打开,然后按照上述的顺序复制粘贴成一个文件,这个文件就是上面 ”cert=“ 这行所需的文件。

然后指定端口转换,比如将端口 443 (https 的默认端口)绑定并转换到 tinyproxy 的默认端口 8888:

[https]
accept = 443
connect = 127.0.0.1:8888

其中 https 这个一项绑定的名称,可以随便起,accept 表示本机监听的端口,connect 表示转换到哪里。完整的意思就是为 127.0.0.1:8888 添加 SSL 加密层,然后通过 443 端口对外服务。

 

3、客户端设置

目前默认支持 https/spdy 代理的只有 google chrome 浏览器(其他浏览器需要在客户端运行 stunnel 把 https 翻译为 http 才能使用)。而且很诡异的是 chrome 没有自己独立设置 proxy 的地方,使用系统全局的那个 https 设置是不行的(因为系统那个 https 代理指的是当你访问 https 的网站时所走的 http 代理通道,跟我们这篇说的 https proxy 是两码事),所以你还得在 chrome 浏览器里安装插件  TunnelSwitch,然后在这个插件里设置 https 代理为:“你的网站域名:443”,这样所有工作都完成可以直接上网了。

4、一个给爱折腾的人的省钱方案

如果想节省购买 SSL 证书的花费,那么自己生成一个“自签名”的证书也是可以的,不过如果你的 proxy 想共享给其他人使用的话,要慎重考虑这种方式,因为它会让不爱折腾的人觉得很折腾。

用下面命令即可生成一个自签名证书:

openssl genrsa -out key.pem 1024
openssl req -new -key key.pem -subj "/CN=localhost" -out req.pem
openssl x509 -req -days 365 -in req.pem -signkey key.pem -out cert.pem

注意要将上面的 localhost 更改为你的域名,最终有用的分别是私钥文件 key.pem 和证书文件 cert.pem,把这两个文件替换上面第二步所提到的位置即可。

然后在客户端需要导入这个 cert.pem 才能顺利使用你所搭建的 https proxy 服务。各个操作系统的导入证书方法都不太相同。

  • 在 linux 里比较麻烦,需要用 libnss3 工具 certutil 来完成,命令如下:
$ certutil -d "sql:$HOME/.pki/nssdb" -A -n dummy -i cert.pem -t C
  • 在 mac osx 里使用 keychain 工具,把证书拖进”证书“一栏里。
  • 在 windows 里双击证书文件,在选择“导入到位置”那一步选择”根信任“。

然后重启你的 chrome 浏览器就可以了。

 

如何购买廉价 SSL 证书

之前的一篇《添加 GoDaddy SSL 证书到你的网站》提到如何从 GoDaddy 购买 SSL 证书并添加到 Tomcat Web Server,这里补充一下购买廉价 SSL 的过程。

网上有不少廉价甚至免费的 SSL 证书服务商,而比较方便快捷的应该是通过 namecheap.com 购买 Comodo Positive SSL 和 RapidSSL,两者都是 $10 左右一年,一般在 10 来分钟之内就能完成。下面是购买的详细步骤:

1、首先确定你 Web Server 的类型

一般来说,除了 Java Tomcat Web Server 之外的其他 Web Server(比如 Apache Httpd)都是使用 OpenSSL 实现其加密层的,所以在购买证书时先选定你的 Web Server 加密程序为 OpenSSL。(注:Tomcat 结合 APR 使用的话也是用 OpenSSL 的哦,如果你需要为 Tomcat 购买 SSL 证书,则转到本文第一段提到的那篇旧文。)

2、生成私钥和签名请求文件

使用如下命令可以产生一个私钥以及一个签名请求文件

$ openssl req -nodes -newkey rsa:2048 -keyout my.key -out my-request.csr

这条命令的 rsa:2048 用于指定加密算法的名称以及密钥的长度,最终生成的 my.key 为私钥(要保管好)和一个签名请求文件。

运行这个命令时会询问关你的网站的信息,如果是个人网站,那么大部分资料都是可以随便填的,只要 “Common Name” 这一项准确填写你的域名即可,比如 abc.com,xyz.org,注意不用加 www 前缀,namecheap 代理销售的 SSL 证书会自动额外签名你的 www 二级域名,即付一份价钱,可以同时认证 abc.com 和 www.abc.com。

3、检查一下你域名登记的 email 地址

因为证书服务商会验证你的域名,而验证方法则是发送一封 email 到你域名注册时所填写的联系 email 地址,如果你注册域名时是乱填的,记得现在要更正过来了。

4、把签名请求文件发送给证书服务商

根据购买流程当中的指引,把第 2 步产生的 my-request.csr 发送给证书服务商。大概等十几分钟(也有时要几个小时)服务商会发送一封 email 给你,一般来说里面包含一个验证码,把这个验证码输入购买流程的页面当中就完成域名验证了。

5、获取签名证书

上一步完成之后,大概再等几分钟,你就会收到一封邮件(或者出现在购买流程当中),里面包含有你的证书和证书链。具体来说可能会有这 3 个证书文件:

  • yourDomainName.crt
  • PositiveSSLCA2.crt
  • AddTrustExternalCARoot.crt

一般来说我们要把后两者合并为一个文件,用记事本打开然后复制粘贴形成一个新文件即可,需要注意 *Root.crt 这个文件的内容要放在最后,对于 linux 系统用户,用这行搞定:

$ cat PositiveSSLCA2.crt AddTrustExternalCARoot.crt > yourDomainName.ca-bundle.crt

6、使用证书

这里以 Apache Httpd 为例,一般的设置如下:

SSLEngine on
SSLCertificateKeyFile /etc/ssl/ssl.key/my.key
SSLCertificateFile /etc/ssl/ssl.crt/yourDomainName.crt
SSLCertificateChainFile /etc/ssl/ssl.crt/yourDomainName.ca-bundle

如果你的 apache 配置了多个虚拟主机,则配置如下:

# make sure add these lines in somewhere else
#NameVirtualHost *:80
#NameVirtualHost *:443

<VirtualHost *:80>
  ServerName www.your-domain.com
  DocumentRoot /var/www/your-domain
  ServerAlias your-domain.com
<VirtualHost>
<VirtualHost *:443>
  SSLEngine on
  SSLCertificateKeyFile /etc/ssl/ssl.key/my.key
  SSLCertificateFile /etc/ssl/ssl.crt/yourDomainName.crt
  SSLCertificateChainFile /etc/ssl/ssl.crt/yourDomainName.ca-bundle
  ServerName www.your-domain.com  
  DocumentRoot /var/www/your-domain
  ServerName your-domain.com
<VirtualHost>

对于使用了 APR 的 Tomcat 服务器,配置如下:

<Connector port="443" protocol="HTTP/1.1"
address="198.74.59.36"
SSLEnabled="true"
scheme="https" secure="true"
enableLookups="false"
SSLCertificateFile="/etc/ssl/my/yourDomainName.crt"
SSLCertificateChainFile="/etc/ssl/my/yourDomainName.ca-bundle.crt"
SSLCertificateKeyFile="/etc/ssl/my/my.key"/>

证书设置完毕。

7、补:SSL 证书的格式转换

如果你已经根据上面的流程购买了一个 SSL 证书,而碰巧使用的时候要求是 Java Keystore 格式,那么需要将 OpenSSL 的证书转换一下:

首先将密钥和证书转为 pkcs12 格式:

$ openssl pkcs12 -export -in yourDomainName.crt -inkey my.key > my.p12

然后将 pkcs12 格式转换为 Java keystore 格式:

$ keytool -importkeystore -srckeystore my.p12 -destkeystore my.jks -srcstoretype pkcs12

.

 

刷刷存在感

正如首页的帖子列表显示所示,这里已经快一年没有更新了。因为最近实在是太忙了,原先有几篇文章提到的后续文章,现在看来遥遥无期的样子,所以就不写后续了(其实也因为时间隔太久,之前在脑海里组织的文字都忘记了)。

最近我回忆起早6,7年我喜欢的是网络通信(tcp/udp之上的应用层)、数据处理(加密、分布储存)、分布计算这些领域,记得当时折腾起这些东西时不亦乐乎,可能由于当时是出于兴趣而不是工作任务。后来就开始主要做 web 应用开发了,那么之前学的东西,包括经验呀代码呀什么的还没来得及分享就已经荒废了。

所以下半年要想办法挤一点时间出来,然后把之前玩得最开心的那些经验和积累写成一篇篇简简单单的教程,这样也算是没有枉费之前的辛苦所得。