mirror of
https://github.com/LCTT/TranslateProject.git
synced 2025-03-09 01:30:10 +08:00
Merge remote-tracking branch 'LCTT/master'
This commit is contained in:
commit
4f5b299d5f
@ -1,8 +1,8 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10375-1.html)
|
||||
[#]: subject: (11 Uses for a Raspberry Pi Around the Office)
|
||||
[#]: via: (https://blog.dxmtechsupport.com.au/11-uses-for-a-raspberry-pi-around-the-office/)
|
||||
[#]: author: (James Mawson https://blog.dxmtechsupport.com.au/author/james-mawson/)
|
||||
@ -12,9 +12,9 @@
|
||||
|
||||
我知道你在想什么:树莓派只能用在修修补补、原型设计和个人爱好中。它实际不能用在业务中。
|
||||
|
||||
毫无疑问,这台电脑的处理能力相对较低、易损坏的 SD 卡、缺乏电池备份以及支持的 DIY 性质,这意味着它不会是一个能在任何时候执行最关键的操作的[专业的已安装和已配置的商业服务器][1]的可行替代,。
|
||||
毫无疑问,这台电脑的处理能力相对较低、易损坏的 SD 卡、缺乏电池备份以及支持的 DIY 性质,这意味着它不会是一个能在任何时候执行最关键的操作的[专业的、已安装好、配置好的商业服务器][1]的可行替代品。
|
||||
|
||||
但是它电路板便宜、功耗很小、很小几乎适合任何地方、无限灵活 - 这实际上是处理办公室一些基本任务的好方法。
|
||||
但是它电路板便宜、功耗很小、小到几乎适合任何地方、无限灵活 —— 这实际上是处理办公室一些基本任务的好方法。
|
||||
|
||||
而且,更好的是,已经有一些人完成了这些项目并很乐意分享他们是如何做到的。
|
||||
|
||||
@ -22,11 +22,11 @@
|
||||
|
||||
每次在浏览器中输入网站地址或者点击链接时,都需要将域名转换为数字 IP 地址,然后才能显示内容。
|
||||
|
||||
通常这意味着向互联网上某处 DNS 服务器发出请求 - 但你可以通过本地处理来加快浏览速度。
|
||||
通常这意味着向互联网上某处 DNS 服务器发出请求 —— 但你可以通过本地处理来加快浏览速度。
|
||||
|
||||
你还可以分配自己的子域,以便本地访问办公室中的计算机。
|
||||
|
||||
[这里是如何让这它工作。][2]
|
||||
[这里了解它是如何工作的。][2]
|
||||
|
||||
### 厕所占用标志
|
||||
|
||||
@ -34,37 +34,37 @@
|
||||
|
||||
这对于那些等待的人来说很烦人,花在处理它上面的时间会耗费你在办公室的工作效率。
|
||||
|
||||
我想你希望在办公室里也悬挂飞机上有的标志。
|
||||
我想你希望在办公室里也悬挂飞机上那个厕所有人的标志。
|
||||
|
||||
[Occu-pi][3] 是一个更简单的解决方案,使用磁性开关和树莓派来判断螺栓何时关闭并在 Slack 频道中更新厕所在使用中 - 这意味着整个办公室的人都可以看一眼电脑或者移动设备知道是否有空闲的隔间。
|
||||
[Occu-pi][3] 是一个非常简单的解决方案,使用磁性开关和树莓派来判断螺栓何时关闭,并在 Slack 频道中更新“厕所在使用中” —— 这意味着整个办公室的人都可以看一眼电脑或者移动设备知道是否有空闲的隔间。
|
||||
|
||||
### 针对黑客的蜜罐陷阱
|
||||
|
||||
黑客破坏了网络的第一个线索是一些事情变得糟糕,这应该会吓到大多数企业主。
|
||||
|
||||
这就是可以用到蜜罐的地方:一台没有任何服务的计算机位于你的网络,将特定端口打开伪装成黑客喜欢的目标。
|
||||
这就是可以用到蜜罐的地方:一台没有任何服务的计算机位于你的网络,将特定端口打开,伪装成黑客喜欢的目标。
|
||||
|
||||
安全研究人员经常在网络外部部署蜜罐,以收集攻击者正在做的事情的数据。
|
||||
|
||||
但对于普通的小型企业来说,这些作为一种绊脚石部署在内部更有用。因为普通用户没有真正的理由想要连接到蜜罐,所以任何发生的登录尝试都是正在进行捣乱的非常好的指示。
|
||||
|
||||
这可以提供对外部人员入侵的预警,并且可信赖的内部人员也没有任何好处。
|
||||
这可以提供对外部人员入侵的预警,并且也可以提供对值得信赖的内部人员的预警。
|
||||
|
||||
在较大的客户端/服务器网络中,将它作为虚拟机运行可能更为实际。但是在无线路由器上运行的点对点的小型办公室/家庭办公网络中,[HoneyPi][4] 之类的东西是一个很小的防盗报警器。
|
||||
在较大的客户端/服务器网络中,将它作为虚拟机运行可能更为实用。但是在无线路由器上运行的点对点的小型办公室/家庭办公网络中,[HoneyPi][4] 之类的东西是一个很小的防盗报警器。
|
||||
|
||||
### 打印服务器
|
||||
|
||||
网络连接的打印机更方便。
|
||||
联网打印机更方便。
|
||||
|
||||
但更换所有打印机可能会很昂贵 - 特别是如果你对它们感到满意的话。
|
||||
但更换所有打印机可能会很昂贵 —— 特别是如果你对现有的打印机感到满意的话。
|
||||
|
||||
[将树莓派设置为打印服务器][5]可能会更有意义。
|
||||
|
||||
### 网络附加存储 (NAS)
|
||||
### 网络附加存储(NAS)
|
||||
|
||||
将硬盘变为 NAS 是树莓派最早的实际应用之一,并且它仍然是最好的之一。
|
||||
|
||||
[这是如何使用树莓派创建NAS。][6]
|
||||
[这是如何使用树莓派创建 NAS。][6]
|
||||
|
||||
### 工单服务器
|
||||
|
||||
@ -74,13 +74,13 @@
|
||||
|
||||
### 数字标牌
|
||||
|
||||
无论是用于活动、广告、菜单还是其他任何东西,许多企业都需要一种显示数字标牌的方式 - 而树莓派的廉价和省电使其成为一个非常有吸引力的选择。
|
||||
无论是用于活动、广告、菜单还是其他任何东西,许多企业都需要一种显示数字标牌的方式 —— 而树莓派的廉价和省电使其成为一个非常有吸引力的选择。
|
||||
|
||||
[这有很多可供选择的选项。] [8]
|
||||
|
||||
### 目录和信息亭
|
||||
|
||||
[FullPageOS][9] 是一个基于 Raspbian 的 Linux 发行版,它直接引导到 Chromium 的全屏版本 - 这非常适合导购、图书馆目录等。
|
||||
[FullPageOS][9] 是一个基于 Raspbian 的 Linux 发行版,它直接引导到 Chromium 的全屏版本 —— 这非常适合导购、图书馆目录等。
|
||||
|
||||
### 基本的内联网 Web 服务器
|
||||
|
||||
@ -96,7 +96,7 @@ Kali Linux 是专为探测网络安全漏洞而构建的操作系统。通过将
|
||||
|
||||
[你可以在这里找到树莓派镜像的种子链接。][11]
|
||||
|
||||
绝对小心只在你自己的网络或你有权对它安全审计的网络中使用它 - 使用此方法来破解其他网络是严重的犯罪行为。
|
||||
绝对要小心只在你自己的网络或你有权对它安全审计的网络中使用它 —— 使用此方法来破解其他网络是严重的犯罪行为。
|
||||
|
||||
### VPN 服务器
|
||||
|
||||
@ -104,15 +104,15 @@ Kali Linux 是专为探测网络安全漏洞而构建的操作系统。通过将
|
||||
|
||||
你可以订阅任意数量的商业 VPN 服务,并且你可以在云中安装自己的服务,但是在办公室运行一个 VPN,这样你也可以从任何地方访问本地网络。
|
||||
|
||||
对于轻度使用 - 比如偶尔的商务旅行 - 树莓派是一种强大的,节约能源的设置 VPN 服务器的方式。(首先要检查一下你的路由器是不是不支持这个功能,许多路由器是支持的。)
|
||||
对于轻度使用 —— 比如偶尔的商务旅行 —— 树莓派是一种强大的,节约能源的设置 VPN 服务器的方式。(首先要检查一下你的路由器是不是不支持这个功能,许多路由器是支持的。)
|
||||
|
||||
[这是如何在树莓派上安装 OpenVPN。][12]
|
||||
|
||||
### 无线咖啡机
|
||||
|
||||
啊,美味:美味的饮料还是公司内工作效率的支柱。
|
||||
啊,美味:好喝的饮料是神赐之物,也是公司内工作效率的支柱。
|
||||
|
||||
那么, 为什么不[将办公室的咖啡机变成可以精确控制温度和无线连接的智能咖啡机呢?][13]
|
||||
那么,为什么不[将办公室的咖啡机变成可以精确控制温度和无线连接的智能咖啡机呢?][13]
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
@ -121,7 +121,7 @@ via: https://blog.dxmtechsupport.com.au/11-uses-for-a-raspberry-pi-around-the-of
|
||||
作者:[James Mawson][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
@ -139,4 +139,4 @@ via: https://blog.dxmtechsupport.com.au/11-uses-for-a-raspberry-pi-around-the-of
|
||||
[10]: https://maker.pro/raspberry-pi/projects/raspberry-pi-web-server
|
||||
[11]: https://www.offensive-security.com/kali-linux-arm-images/
|
||||
[12]: https://medium.freecodecamp.org/running-your-own-openvpn-server-on-a-raspberry-pi-8b78043ccdea
|
||||
[13]: https://www.techradar.com/au/how-to/how-to-build-your-own-smart-coffee-machine
|
||||
[13]: https://www.techradar.com/au/how-to/how-to-build-your-own-smart-coffee-machine
|
@ -1,28 +1,30 @@
|
||||
Bash 环境变量的那些事
|
||||
======
|
||||
> 初学者可以在此教程中了解环境变量。
|
||||
|
||||

|
||||
|
||||
bash 变量,尤其是讨厌的环境变量,已经是一个老生常谈的话题了。我们也更应该对它有一个详细的了解,让它为我们所用。
|
||||
bash 变量,尤其是讨厌的*环境变量*,已经是一个老生常谈的话题了。我们也更应该对它有一个详细的了解,让它为我们所用。
|
||||
|
||||
下面就打开终端,开始吧。
|
||||
|
||||
### 环境变量
|
||||
|
||||
`HOME` 除了是你脱下帽子惬意休息的地方,同时也是 Linux 中的一个变量,它是当前用户主目录的路径:
|
||||
`HOME` (LCTT 译注:双关语)除了是你脱下帽子惬意休息的地方,同时也是 Linux 中的一个变量,它是当前用户主目录的路径:
|
||||
|
||||
```
|
||||
echo $HOME
|
||||
```
|
||||
|
||||
以上这个命令会显示当前用户的主目录路径,通常都在 `/home/` 下。
|
||||
以上这个命令会显示当前用户的主目录路径,通常都在 `/home/<your username>` 下。
|
||||
|
||||
顾名思义,一个变量的值并不是固定的。实际上,Linux 系统中每一个用户的 `HOME` 变量都是不一样的,当然你也可以这样自行更改 `HOME` 变量的值:
|
||||
顾名思义,变量的值是可以根据上下文变化的。实际上,Linux 系统中每一个用户的 `HOME` 变量都是不一样的,当然你也可以这样自行更改 `HOME` 变量的值:
|
||||
|
||||
```
|
||||
HOME=/home/<your username>/Documents
|
||||
```
|
||||
|
||||
以上这个命令将会把 `HOME` 变量设置为 `/home/<your username>/Documents` 目录。
|
||||
以上这个命令将会把 `HOME` 变量设置为你的 `Documents` 目录。
|
||||
|
||||
其中有三点需要留意:
|
||||
|
||||
@ -45,7 +47,7 @@ $ echo $PATH
|
||||
/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/sbin:/bin:/sbin
|
||||
```
|
||||
|
||||
每两个目录之间使用冒号(`:`)分隔。如果某个应用程序的所在目录不在 `PATH` 变量中,那么运行的时候就需要声明应用程序的目录让 shell 能够找到。
|
||||
每两个目录之间使用冒号 `:` 分隔。如果某个应用程序的所在目录不在 `PATH` 变量中,那么运行的时候就需要声明应用程序的目录让 shell 能够找到。
|
||||
|
||||
```
|
||||
/home/<user name>/bin/my_program.sh
|
||||
@ -67,9 +69,9 @@ PATH=$PATH:$HOME/bin
|
||||
|
||||
然后 `/home/<user name>/bin/` 目录就会出现在 `PATH` 变量中了。但正如之前所说,这个变更只会在当前的 shell 生效,当前的 shell 一旦关闭,环境变量的值就又恢复原状了。
|
||||
|
||||
如果要让变更对当前用户持续生效,就不能在 shell 中直接执行对应的变更,而是应该将这些变更操作卸载每次启动 shell 时都会运行的文件当中。这个文件就是当前用户主目录中的 `.bashrc` 文件。文件名前面的点号表明这是一个隐藏文件,执行普通的 `ls` 命令是不会将这个文件显示出来的,但只要在 `ls` 命令中加入 `-a` 参数就可以看到这个文件了。
|
||||
如果要让变更对当前用户持续生效,就不能在 shell 中直接执行对应的变更,而是应该将这些变更操作写在每次启动 shell 时都会运行的文件当中。这个文件就是当前用户主目录中的 `.bashrc` 文件。文件名前面的点号表明这是一个隐藏文件,执行普通的 `ls` 命令是不会将这个文件显示出来的,但只要在 `ls` 命令中加入 `-a` 参数就可以看到这个文件了。
|
||||
|
||||
你可以使用诸如 [kate][1]、[gedit][2]、[nano][3] 或者 [vim][4] 这些文本编辑器来打开 `.bashrc` 文件(但不要用 LibreOffice Writer,它是一个文字处理软件,跟前面几个文字编辑器并不一个量级的东西)。打开 `.bashrc` 文件之后,你会看见里面放置了一些 shell 命令,是用于为当前用户设置环境的。
|
||||
你可以使用诸如 [kate][1]、[gedit][2]、[nano][3] 或者 [vim][4] 这些文本编辑器来打开 `.bashrc` 文件(但不要用 LibreOffice Writer,它是一个文字处理软件,跟前面几个文字编辑器完全不同)。打开 `.bashrc` 文件之后,你会看见里面放置了一些 shell 命令,是用于为当前用户设置环境的。
|
||||
|
||||
在文件的末尾添加新行并输入以下内容:
|
||||
|
||||
@ -97,13 +99,13 @@ source .bashrc
|
||||
new_variable="Hello"
|
||||
```
|
||||
|
||||
然后可以用一下的方式读取到已定义变量的值:
|
||||
然后可以用以下的方式读取到已定义变量的值:
|
||||
|
||||
```
|
||||
echo $new_variable
|
||||
```
|
||||
|
||||
程序的正常工作离不开各种变量,例如要将某个选项设置为 on,又或者让程序找到所需的代码库,都需要使用变量。在 bash 中运行程序的时候会生成一个子 shell,这个子 shell 和执行原程序的父 shell 并不是完全一样的,只是继承了父 shell 的部分内容,而且默认是不继承父 shell 中的变量的。因为变量默认情况下是局部变量,出于安全原因,一个 shell 中的局部变量不会被另一个 shell 读取到,即使是子 shell 也不可以。
|
||||
程序的正常工作离不开各种变量,例如要将某个选项设置为打开,又或者让程序找到所需的代码库,都需要使用变量。在 bash 中运行程序的时候会生成一个子 shell,这个子 shell 和执行原程序的父 shell 并不是完全一样的,只是继承了父 shell 的部分内容,而且默认是不继承父 shell 中的变量的。因为变量默认情况下是局部变量,出于安全原因,一个 shell 中的局部变量不会被另一个 shell 读取到,即使是子 shell 也不可以。
|
||||
|
||||
下面举一个例子。首先定义一个变量:
|
||||
|
||||
@ -198,7 +200,7 @@ via: https://www.linux.com/blog/learn/2018/12/bash-variables-environmental-and-o
|
||||
作者:[Paul Brown][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[HankChow](https://github.com/HankChow)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
@ -1,8 +1,8 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: (geekpi)
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: reviewer: (wxy)
|
||||
[#]: publisher: (wxy)
|
||||
[#]: url: (https://linux.cn/article-10373-1.html)
|
||||
[#]: subject: (How to Install Putty on Ubuntu and Other Linux Distributions)
|
||||
[#]: via: (https://itsfoss.com/putty-linux/)
|
||||
[#]: author: (Abhishek Prakash https://itsfoss.com/author/abhishek/)
|
||||
@ -10,11 +10,11 @@
|
||||
如何在 Ubuntu 和其他 Linux 发行版上安装 Putty
|
||||
======
|
||||
|
||||
如果我没错,[Putty][1] 可能是 Windows 最受欢迎的 SSH 客户端。
|
||||
如果我没弄错,[Putty][1] 可能是 Windows 最受欢迎的 SSH 客户端。
|
||||
|
||||
I在 IT 公司中,开发环境通常在远程 Linux 系统上,而开发人员则使用 Windows 作为本地系统。Putty 用于从 Windows 机器连接到远程 Linux 系统。
|
||||
在 IT 公司中,开发环境通常在远程 Linux 系统上,而开发人员则使用 Windows 作为本地系统。Putty 用于从 Windows 机器连接到远程 Linux 系统。
|
||||
|
||||
Putty 不仅限于 Windows。你也可以在 Linux 和 macOS 上使用此开源软件。
|
||||
Putty 不是限定于 Windows 的。你也可以在 Linux 和 macOS 上使用此开源软件。
|
||||
|
||||
但是等等!当你已经拥有“真正的” Linux 终端时,为什么要在 Linux 上使用单独的 SSH 客户端?这有几个想在 Linux 上使用 Putty 的原因。
|
||||
|
||||
@ -22,8 +22,6 @@ Putty 不仅限于 Windows。你也可以在 Linux 和 macOS 上使用此开源
|
||||
* 你发现很难手动编辑 SSH 配置文件以保存各种 SSH 会话。你更喜欢 Putty 图形化保存 SSH 连接的方式。
|
||||
* 你想通过连接到原始套接字和串口进行调试。
|
||||
|
||||
|
||||
|
||||
无论是什么原因,如果你想在 Ubuntu 或任何其他 Linux 上使用 Putty,你当然可以这样做。让我告诉你如何做到。
|
||||
|
||||
### 在 Ubuntu Linux 上安装 Putty
|
||||
@ -38,7 +36,7 @@ Putty 不仅限于 Windows。你也可以在 Linux 和 macOS 上使用此开源
|
||||
sudo add-apt-repository universe
|
||||
```
|
||||
|
||||
启用 universe 存储库后,应使用以下命令更新 Ubuntu:
|
||||
启用 universe 仓库后,应使用以下命令更新 Ubuntu:
|
||||
|
||||
```
|
||||
sudo apt update
|
||||
@ -56,13 +54,13 @@ sudo apt install putty
|
||||
|
||||
![Putty in Linux][3]
|
||||
|
||||
当你输入远程系统的[主机名][4]或 IP 地址并连接到它时,Putty 将使用你主目录中已保存的 SSH 密钥。
|
||||
当你输入远程系统的[主机名][4]或 IP 地址并连接到它时,Putty 将使用你已保存在主目录中的 SSH 密钥。
|
||||
|
||||
![Using Putty in Ubuntu Linux][5]
|
||||
|
||||
### 在其他 Linux 发行版上安装 Putty
|
||||
|
||||
[Putty 可用于 Debian][6],所以你只需要使用 apt-get 或 aptitude 来安装它。
|
||||
[Putty 可用于 Debian][6],所以你只需要使用 `apt-get` 或 `aptitude` 来安装它。
|
||||
|
||||
```
|
||||
sudo apt-get install putty
|
||||
@ -82,7 +80,7 @@ sudo pacman -S putty
|
||||
|
||||
请记住,Putty 是一款开源软件。如果你真的想要,你也可以通过源代码安装它。你可以从下面的链接获取 Putty 的源代码。
|
||||
|
||||
[下载 Putty 源代码][8]
|
||||
- [下载 Putty 源代码][8]
|
||||
|
||||
我一直喜欢原生 Linux 终端而不是像 Putty 这样的 SSH 客户端。我觉得 GNOME 终端或 [Terminator][7] 更有家的感觉。但是,在 Linux 中使用默认终端或 Putty 是个人选择。
|
||||
|
||||
@ -95,7 +93,7 @@ via: https://itsfoss.com/putty-linux/
|
||||
作者:[Abhishek Prakash][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[geekpi](https://github.com/geekpi)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
校对:[wxy](https://github.com/wxy)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
@ -108,4 +106,4 @@ via: https://itsfoss.com/putty-linux/
|
||||
[5]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2018/12/putty-interface-ubuntu-1.jpeg?resize=800%2C430&ssl=1
|
||||
[6]: https://packages.debian.org/jessie/putty
|
||||
[7]: https://launchpad.net/terminator
|
||||
[8]: https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html
|
||||
[8]: https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html
|
@ -1,180 +0,0 @@
|
||||
robsean translating
|
||||
Graphics and music tools for game development
|
||||
======
|
||||
|
||||

|
||||
|
||||
In early October, our club, [Geeks and Gadgets][1] from Marshall University, participated in the inaugural [Open Jam][2], a game jam that celebrated the best of open source tools. Game jams are events where participants work as teams to develop computer games for fun. Jams tend to be very short--only three days long--and very exhausting. Opensource.com [announced][3] Open Jam in late August, and more than [three dozen games][4] were entered into the competition.
|
||||
|
||||
Our club likes to create and use open source software in our projects, so Open Jam was naturally the jam we wanted to participate in. Our submission was an experimental game called [Mark My Words][5]. We used a variety of free and open source (FOSS) tools to develop it; in this article we'll discuss some of the tools we used and potential stumbling blocks to be aware of.
|
||||
|
||||
### Audio tools
|
||||
|
||||
#### MilkyTracker
|
||||
|
||||
[MilkyTracker][6] is one of the best software packages available for composing old-style video game music. It is an example of a [music tracker][7], a powerful MOD and XM file creator with a characteristic grid-based pattern editor. We used it to compose most of the musical pieces in our game. One of the great things about this program is that it consumed much less disk space and RAM than most of our other tools. Even so, MilkyTracker is still extremely powerful.
|
||||
|
||||

|
||||
|
||||
The user interface took a while to get used to, so here are some pointers for any musician who wants to try out MilkyTracker:
|
||||
|
||||
* Go to Config > Misc. and set the edit mode control style to "MilkyTracker." This will give you modern keyboard shortcuts for almost everything
|
||||
* Undo with Ctrl+Z
|
||||
* Redo with Ctrl+Y
|
||||
* Toggle pattern-edit mode with the Spacebar
|
||||
* Delete the previous note with the Backspace key
|
||||
* Insert a row with the Insert key
|
||||
* By default, a note will continue playing until it is replaced on that channel. You can end a note explicitly by inserting a KeyOff note with the backquote (`) key
|
||||
* You will have to create or find samples before you can start composing. We recommend finding [Creative Commons][8] licensed samples at websites such as [Freesound][9] or [ccMixter][10]
|
||||
|
||||
|
||||
|
||||
In addition, keep the [MilkyTracker documentation page][11] handy. It contains links to numerous tutorials and manuals. A good starting point is the [MilkyTracker Guide][12] on the project's wiki.
|
||||
|
||||
#### LMMS
|
||||
|
||||
Two of our musicians used the versatile and modern music creation tool [LMMS][13]. It comes with a library of cool samples and effects, plus a variety of flexible plugins for generating unique sounds. The learning curve for LMMS was surprisingly low, in part due to the nice beat/bassline editor.
|
||||
|
||||

|
||||
|
||||
We have one suggestion for musicians trying out LMMS: Use the plugins. For [chiptune][14]-style music, we recommend [sfxr][15], [BitInvader][16], and [FreeBoy][17]. For other styles, [ZynAddSubFX][18] is a good choice. It comes with a wide range of synthesized instruments that can be altered however you see fit.
|
||||
|
||||
### Graphics tools
|
||||
|
||||
#### Tiled
|
||||
|
||||
[Tiled][19] is a popular tilemap editor in open source game development. We used it to assemble consistent, retro-looking backgrounds for our in-game scenes.
|
||||
|
||||

|
||||
|
||||
Tiled can export maps as XML, JSON, or as flattened images. It is stable and cross-platform.
|
||||
|
||||
One of Tiled's features, which we did not use during the jam, allows you to define and place arbitrary game objects, such as coins and powerups, onto the map. All you have to do is load the object's graphics as a tileset, then place them using Insert Tile.
|
||||
|
||||
Overall, Tiled is a stellar piece of software that we recommend for any project that needs a map editor.
|
||||
|
||||
#### Piskel
|
||||
|
||||
[Piskel][20] is a pixel art editor whose source code is licensed under the [Apache License, Version 2.0][21]. We used Piskel for almost all our graphical assets during the jam, and we will certainly be using it in future projects as well.
|
||||
|
||||
Two features of Piskel that helped us immensely during the jam are onion skin and spritesheet exporting.
|
||||
|
||||
##### Onion skin
|
||||
|
||||
The onion skin feature will make Piskel show a ghostly overlay of the previous and next frames of your animation as you edit, like this:
|
||||
|
||||

|
||||
|
||||
Onion skin is handy because it serves as a drawing guide and helps you maintain consistent shapes and volumes on your characters throughout the animation process. To enable it, just click the onion-shaped icon underneath the preview window on the top-right of the screen.
|
||||
|
||||

|
||||
|
||||
##### Spritesheet exporting
|
||||
|
||||
Piskel's ability to export animations as a spritesheet was also very helpful. A spritesheet is a single raster image that contains all the frames of an animation. For example, here is a spritesheet we exported from Piskel:
|
||||
|
||||

|
||||
|
||||
The spritesheet consists of two frames. One frame is in the top half of the image and the other frame is in the bottom half of the image. Spritesheets greatly simplify a game's code by enabling an entire animation to be loaded from a single file. Here is an animated version of the above spritesheet:
|
||||
|
||||

|
||||
|
||||
##### Unpiskel.py
|
||||
|
||||
There were several times during the jam when we wanted to batch convert Piskel files into PNGs. Since the Piskel file format is based on JSON, we wrote a small GPLv3-licensed Python script called [unpiskel.py][22] to do the conversion.
|
||||
|
||||
It is invoked like this:
|
||||
```
|
||||
|
||||
|
||||
python unpiskel.py input.piskel
|
||||
```
|
||||
|
||||
The script will extract the PNG data frames and layers from a Piskel file (here `input.piskel`) and store them in their own files. The files follow the pattern `NAME_XX_YY.png` where `NAME` is the truncated name of the Piskel file, `XX` is the frame number, and `YY` is the layer number.
|
||||
|
||||
Because the script can be invoked from a shell, it can be used on a whole list of files.
|
||||
```
|
||||
for f in *.piskel; do python unpiskel.py "$f"; done
|
||||
```
|
||||
|
||||
### Python, Pygame, and cx_Freeze
|
||||
|
||||
#### Python and Pygame
|
||||
|
||||
We used the [Python][23] language to make our game. It is a scripting language that is commonly used for text processing and desktop app development. It can also be used for game development, as projects like [Angry Drunken Dwarves][24] and [Ren'Py][25] have shown. Both of these projects use a Python library called [Pygame][26] to display graphics and produce sound, so we decided to use this library in Open Jam, too.
|
||||
|
||||
Pygame turned out to be both stable and featureful, and it was great for the arcade-style game we were creating. The library's speed was fast enough at low resolutions, but its CPU-only rendering starts to slow down at higher resolutions. This is because Pygame does not use hardware-accelerated rendering. However, the infrastructure is there for developers to take full advantage of OpenGL.
|
||||
|
||||
If you're looking for a good 2D game programming library, Pygame is one to keep your eye on. Its website has [a good tutorial][27] to get started. Be sure to check it out!
|
||||
|
||||
#### cx_Freeze
|
||||
|
||||
Prepping our game for distribution was interesting. We knew that Windows users were unlikely to have a Python installation, and asking them to install it would have been too much. On top of that, they would have had to also install Pygame, which is not an intuitive task on Windows.
|
||||
|
||||
One thing was clear: We had to put our game into a more convenient form. Many of the other Open Jam participants used the proprietary game engine Unity, which enabled their games to be played in the web browser. This made them extremely convenient to play. Convenience was one thing our game didn't have even a sliver of. But, thanks to a vibrant Python ecosystem, we had options. Tools exist to help Python programmers prepare their programs for distribution on Windows. The two that we considered were [cx_Freeze][28] and [Pygame2exe][29] (which uses [py2exe][30]). We decided on cx_Freeze because it was cross-platform.
|
||||
|
||||
In cx_Freeze, you can pack a single-script game for distribution just by running a command like this in the shell:
|
||||
```
|
||||
cxfreeze main.py --target-dir dist
|
||||
```
|
||||
|
||||
This invocation of `cxfreeze` will take your script (here `main.py`) and the Python interpreter on your system and bundle them up into the `dist` directory. Once this is done, all you have to do is manually copy your game's data files into the `dist` directory. You will find that the `dist` directory contains an executable file that can be run to start your game.
|
||||
|
||||
There is a more involved way to use cx_Freeze that allows you to automate the copying of data files, but we found the straightforward invocation of `cxfreeze` to be good enough for our needs. Thanks to this tool, we made our game a little more convenient to play.
|
||||
|
||||
### Celebrating open source
|
||||
|
||||
Open Jam is important because it celebrates the open source model of software development. This is an opportunity to analyze the current state of open source tools and what we need to work on in the future. Game jams are perhaps the best time for game devs to try to push their tools to the limit, to learn what must be improved for the good of future game devs.
|
||||
|
||||
Open source tools enable people to explore their creativity without compromising their freedom and without investing money upfront. Although we might not become professional game developers, we were still able to get a small taste of it with our short, experimental game called [Mark My Words][5]. It is a linguistically themed game that depicts the evolution of a fictional writing system throughout its history. There were many other delightful submissions to Open Jam, and they are all worth checking out. Really, [go look][31]!
|
||||
|
||||
Before closing, we would like to thank all the [club members who participated][32] and made this experience truly worthwhile. We would also like to thank [Michael Clayton][33], [Jared Sprague][34], and [Opensource.com][35] for hosting Open Jam. It was a blast.
|
||||
|
||||
Now, we have some questions for readers. Are you a FOSS game developer? What are your tools of choice? Be sure to leave a comment below!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/18/1/graphics-music-tools-game-dev
|
||||
|
||||
作者:[Charlie Murphy][a]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://opensource.com/users/rsg167
|
||||
[1]:http://mugeeks.org/
|
||||
[2]:https://itch.io/jam/open-jam-1
|
||||
[3]:https://opensource.com/article/17/8/open-jam-announcement
|
||||
[4]:https://opensource.com/article/17/11/open-jam
|
||||
[5]:https://mugeeksalpha.itch.io/mark-omy-words
|
||||
[6]:http://milkytracker.titandemo.org/
|
||||
[7]:https://en.wikipedia.org/wiki/Music_tracker
|
||||
[8]:https://creativecommons.org/
|
||||
[9]:https://freesound.org/
|
||||
[10]:http://ccmixter.org/view/media/home
|
||||
[11]:http://milkytracker.titandemo.org/documentation/
|
||||
[12]:https://github.com/milkytracker/MilkyTracker/wiki/MilkyTracker-Guide
|
||||
[13]:https://lmms.io/
|
||||
[14]:https://en.wikipedia.org/wiki/Chiptune
|
||||
[15]:https://github.com/grimfang4/sfxr
|
||||
[16]:https://lmms.io/wiki/index.php?title=BitInvader
|
||||
[17]:https://lmms.io/wiki/index.php?title=FreeBoy
|
||||
[18]:http://zynaddsubfx.sourceforge.net/
|
||||
[19]:http://www.mapeditor.org/
|
||||
[20]:https://www.piskelapp.com/
|
||||
[21]:https://github.com/piskelapp/piskel/blob/master/LICENSE
|
||||
[22]:https://raw.githubusercontent.com/MUGeeksandGadgets/MarkMyWords/master/tools/unpiskel.py
|
||||
[23]:https://www.python.org/
|
||||
[24]:https://www.sacredchao.net/~piman/angrydd/
|
||||
[25]:https://renpy.org/
|
||||
[26]:https://www.Pygame.org/
|
||||
[27]:http://Pygame.org/docs/tut/PygameIntro.html
|
||||
[28]:https://anthony-tuininga.github.io/cx_Freeze/
|
||||
[29]:https://Pygame.org/wiki/Pygame2exe
|
||||
[30]:http://www.py2exe.org/
|
||||
[31]:https://itch.io/jam/open-jam-1/entries
|
||||
[32]:https://github.com/MUGeeksandGadgets/MarkMyWords/blob/3e1e8aed12ebe13acccf0d87b06d4f3bd124b9db/README.md#credits
|
||||
[33]:https://twitter.com/mwcz
|
||||
[34]:https://twitter.com/caramelcode
|
||||
[35]:https://opensource.com/
|
@ -1,304 +0,0 @@
|
||||
Translating by qhwdw
|
||||
Protecting Code Integrity with PGP — Part 5: Moving Subkeys to a Hardware Device
|
||||
======
|
||||
|
||||

|
||||
|
||||
In this tutorial series, we're providing practical guidelines for using PGP. If you missed the previous article, you can catch up with the links below. But, in this article, we'll continue our discussion about securing your keys and look at some tips for moving your subkeys to a specialized hardware device.
|
||||
|
||||
[Part 1: Basic Concepts and Tools][1]
|
||||
|
||||
[Part 2: Generating Your Master Key][2]
|
||||
|
||||
[Part 3: Generating PGP Subkeys][3]
|
||||
|
||||
[Part 4: Moving Your Master Key to Offline Storage][4]
|
||||
|
||||
### Checklist
|
||||
|
||||
* Get a GnuPG-compatible hardware device (NICE)
|
||||
|
||||
* Configure the device to work with GnuPG (NICE)
|
||||
|
||||
* Set the user and admin PINs (NICE)
|
||||
|
||||
* Move your subkeys to the device (NICE)
|
||||
|
||||
|
||||
|
||||
|
||||
### Considerations
|
||||
|
||||
Even though the master key is now safe from being leaked or stolen, the subkeys are still in your home directory. Anyone who manages to get their hands on those will be able to decrypt your communication or fake your signatures (if they know the passphrase). Furthermore, each time a GnuPG operation is performed, the keys are loaded into system memory and can be stolen from there by sufficiently advanced malware (think Meltdown and Spectre).
|
||||
|
||||
The best way to completely protect your keys is to move them to a specialized hardware device that is capable of smartcard operations.
|
||||
|
||||
#### The benefits of smartcards
|
||||
|
||||
A smartcard contains a cryptographic chip that is capable of storing private keys and performing crypto operations directly on the card itself. Because the key contents never leave the smartcard, the operating system of the computer into which you plug in the hardware device is not able to retrieve the private keys themselves. This is very different from the encrypted USB storage device we used earlier for backup purposes -- while that USB device is plugged in and decrypted, the operating system is still able to access the private key contents. Using external encrypted USB media is not a substitute to having a smartcard-capable device.
|
||||
|
||||
Some other benefits of smartcards:
|
||||
|
||||
* They are relatively cheap and easy to obtain
|
||||
|
||||
* They are small and easy to carry with you
|
||||
|
||||
* They can be used with multiple devices
|
||||
|
||||
* Many of them are tamper-resistant (depends on manufacturer)
|
||||
|
||||
|
||||
|
||||
|
||||
#### Available smartcard devices
|
||||
|
||||
Smartcards started out embedded into actual wallet-sized cards, which earned them their name. You can still buy and use GnuPG-capable smartcards, and they remain one of the cheapest available devices you can get. However, actual smartcards have one important downside: they require a smartcard reader, and very few laptops come with one.
|
||||
|
||||
For this reason, manufacturers have started providing small USB devices, the size of a USB thumb drive or smaller, that either have the microsim-sized smartcard pre-inserted, or that simply implement the smartcard protocol features on the internal chip. Here are a few recommendations:
|
||||
|
||||
* [Nitrokey Start][5]: Open hardware and Free Software: one of the cheapest options for GnuPG use, but with fewest extra security features
|
||||
|
||||
* [Nitrokey Pro][6]: Similar to the Nitrokey Start, but is tamper-resistant and offers more security features (but not U2F, see the Fido U2F section of the guide)
|
||||
|
||||
* [Yubikey 4][7]: Proprietary hardware and software, but cheaper than Nitrokey Pro and comes available in the USB-C form that is more useful with newer laptops; also offers additional security features such as U2F
|
||||
|
||||
|
||||
|
||||
|
||||
Our recommendation is to pick a device that is capable of both smartcard functionality and U2F, which, at the time of writing, means a Yubikey 4.
|
||||
|
||||
#### Configuring your smartcard device
|
||||
|
||||
Your smartcard device should Just Work (TM) the moment you plug it into any modern Linux or Mac workstation. You can verify it by running:
|
||||
```
|
||||
$ gpg --card-status
|
||||
|
||||
```
|
||||
|
||||
If you didn't get an error, but a full listing of the card details, then you are good to go. Unfortunately, troubleshooting all possible reasons why things may not be working for you is way beyond the scope of this guide. If you are having trouble getting the card to work with GnuPG, please seek support via your operating system's usual support channels.
|
||||
|
||||
##### PINs don't have to be numbers
|
||||
|
||||
Note, that despite having the name "PIN" (and implying that it must be a "number"), neither the user PIN nor the admin PIN on the card need to be numbers.
|
||||
|
||||
Your device will probably have default user and admin PINs set up when it arrives. For Yubikeys, these are 123456 and 12345678, respectively. If those don't work for you, please check any accompanying documentation that came with your device.
|
||||
|
||||
##### Quick setup
|
||||
|
||||
To configure your smartcard, you will need to use the GnuPG menu system, as there are no convenient command-line switches:
|
||||
```
|
||||
$ gpg --card-edit
|
||||
[...omitted...]
|
||||
gpg/card> admin
|
||||
Admin commands are allowed
|
||||
gpg/card> passwd
|
||||
|
||||
```
|
||||
|
||||
You should set the user PIN (1), Admin PIN (3), and the Reset Code (4). Please make sure to record and store these in a safe place -- especially the Admin PIN and the Reset Code (which allows you to completely wipe the smartcard). You so rarely need to use the Admin PIN, that you will inevitably forget what it is if you do not record it.
|
||||
|
||||
Getting back to the main card menu, you can also set other values (such as name, sex, login data, etc), but it's not necessary and will additionally leak information about your smartcard should you lose it.
|
||||
|
||||
#### Moving the subkeys to your smartcard
|
||||
|
||||
Exit the card menu (using "q") and save all changes. Next, let's move your subkeys onto the smartcard. You will need both your PGP key passphrase and the admin PIN of the card for most operations. Remember, that [fpr] stands for the full 40-character fingerprint of your key.
|
||||
```
|
||||
$ gpg --edit-key [fpr]
|
||||
|
||||
Secret subkeys are available.
|
||||
|
||||
pub rsa4096/AAAABBBBCCCCDDDD
|
||||
created: 2017-12-07 expires: 2019-12-07 usage: C
|
||||
trust: ultimate validity: ultimate
|
||||
ssb rsa2048/1111222233334444
|
||||
created: 2017-12-07 expires: never usage: E
|
||||
ssb rsa2048/5555666677778888
|
||||
created: 2017-12-07 expires: never usage: S
|
||||
[ultimate] (1). Alice Engineer <alice@example.org>
|
||||
[ultimate] (2) Alice Engineer <allie@example.net>
|
||||
|
||||
gpg>
|
||||
|
||||
```
|
||||
|
||||
Using --edit-key puts us into the menu mode again, and you will notice that the key listing is a little different. From here on, all commands are done from inside this menu mode, as indicated by gpg>.
|
||||
|
||||
First, let's select the key we'll be putting onto the card -- you do this by typing key 1 (it's the first one in the listing, our [E] subkey):
|
||||
```
|
||||
gpg> key 1
|
||||
|
||||
```
|
||||
|
||||
The output should be subtly different:
|
||||
```
|
||||
pub rsa4096/AAAABBBBCCCCDDDD
|
||||
created: 2017-12-07 expires: 2019-12-07 usage: C
|
||||
trust: ultimate validity: ultimate
|
||||
ssb* rsa2048/1111222233334444
|
||||
created: 2017-12-07 expires: never usage: E
|
||||
ssb rsa2048/5555666677778888
|
||||
created: 2017-12-07 expires: never usage: S
|
||||
[ultimate] (1). Alice Engineer <alice@example.org>
|
||||
[ultimate] (2) Alice Engineer <allie@example.net>
|
||||
|
||||
```
|
||||
|
||||
Notice the * that is next to the ssb line corresponding to the key -- it indicates that the key is currently "selected." It works as a toggle, meaning that if you type key 1 again, the * will disappear and the key will not be selected any more.
|
||||
|
||||
Now, let's move that key onto the smartcard:
|
||||
```
|
||||
gpg> keytocard
|
||||
Please select where to store the key:
|
||||
(2) Encryption key
|
||||
Your selection? 2
|
||||
|
||||
```
|
||||
|
||||
Since it's our [E] key, it makes sense to put it into the Encryption slot. When you submit your selection, you will be prompted first for your PGP key passphrase, and then for the admin PIN. If the command returns without an error, your key has been moved.
|
||||
|
||||
**Important:** Now type key 1 again to unselect the first key, and key 2 to select the [S] key:
|
||||
```
|
||||
gpg> key 1
|
||||
gpg> key 2
|
||||
gpg> keytocard
|
||||
Please select where to store the key:
|
||||
(1) Signature key
|
||||
(3) Authentication key
|
||||
Your selection? 1
|
||||
|
||||
```
|
||||
|
||||
You can use the [S] key both for Signature and Authentication, but we want to make sure it's in the Signature slot, so choose (1). Once again, if your command returns without an error, then the operation was successful.
|
||||
|
||||
Finally, if you created an [A] key, you can move it to the card as well, making sure first to unselect key 2. Once you're done, choose "q":
|
||||
```
|
||||
gpg> q
|
||||
Save changes? (y/N) y
|
||||
|
||||
```
|
||||
|
||||
Saving the changes will delete the keys you moved to the card from your home directory (but it's okay, because we have them in our backups should we need to do this again for a replacement smartcard).
|
||||
|
||||
##### Verifying that the keys were moved
|
||||
|
||||
If you perform --list-secret-keys now, you will see a subtle difference in the output:
|
||||
```
|
||||
$ gpg --list-secret-keys
|
||||
sec# rsa4096 2017-12-06 [C] [expires: 2019-12-06]
|
||||
111122223333444455556666AAAABBBBCCCCDDDD
|
||||
uid [ultimate] Alice Engineer <alice@example.org>
|
||||
uid [ultimate] Alice Engineer <allie@example.net>
|
||||
ssb> rsa2048 2017-12-06 [E]
|
||||
ssb> rsa2048 2017-12-06 [S]
|
||||
|
||||
```
|
||||
|
||||
The > in the ssb> output indicates that the subkey is only available on the smartcard. If you go back into your secret keys directory and look at the contents there, you will notice that the .key files there have been replaced with stubs:
|
||||
```
|
||||
$ cd ~/.gnupg/private-keys-v1.d
|
||||
$ strings *.key
|
||||
|
||||
```
|
||||
|
||||
The output should contain shadowed-private-key to indicate that these files are only stubs and the actual content is on the smartcard.
|
||||
|
||||
#### Verifying that the smartcard is functioning
|
||||
|
||||
To verify that the smartcard is working as intended, you can create a signature:
|
||||
```
|
||||
$ echo "Hello world" | gpg --clearsign > /tmp/test.asc
|
||||
$ gpg --verify /tmp/test.asc
|
||||
|
||||
```
|
||||
|
||||
This should ask for your smartcard PIN on your first command, and then show "Good signature" after you run gpg --verify.
|
||||
|
||||
Congratulations, you have successfully made it extremely difficult to steal your digital developer identity!
|
||||
|
||||
### Other common GnuPG operations
|
||||
|
||||
Here is a quick reference for some common operations you'll need to do with your PGP key.
|
||||
|
||||
In all of the below commands, the [fpr] is your key fingerprint.
|
||||
|
||||
#### Mounting your master key offline storage
|
||||
|
||||
You will need your master key for any of the operations below, so you will first need to mount your backup offline storage and tell GnuPG to use it. First, find out where the media got mounted, for example, by looking at the output of the mount command. Then, locate the directory with the backup of your GnuPG directory and tell GnuPG to use that as its home:
|
||||
```
|
||||
$ export GNUPGHOME=/media/disk/name/gnupg-backup
|
||||
$ gpg --list-secret-keys
|
||||
|
||||
```
|
||||
|
||||
You want to make sure that you see sec and not sec# in the output (the # means the key is not available and you're still using your regular home directory location).
|
||||
|
||||
##### Updating your regular GnuPG working directory
|
||||
|
||||
After you make any changes to your key using the offline storage, you will want to import these changes back into your regular working directory:
|
||||
```
|
||||
$ gpg --export | gpg --homedir ~/.gnupg --import
|
||||
$ unset GNUPGHOME
|
||||
|
||||
```
|
||||
|
||||
#### Extending key expiration date
|
||||
|
||||
The master key we created has the default expiration date of 2 years from the date of creation. This is done both for security reasons and to make obsolete keys eventually disappear from keyservers.
|
||||
|
||||
To extend the expiration on your key by a year from current date, just run:
|
||||
```
|
||||
$ gpg --quick-set-expire [fpr] 1y
|
||||
|
||||
```
|
||||
|
||||
You can also use a specific date if that is easier to remember (e.g. your birthday, January 1st, or Canada Day):
|
||||
```
|
||||
$ gpg --quick-set-expire [fpr] 2020-07-01
|
||||
|
||||
```
|
||||
|
||||
Remember to send the updated key back to keyservers:
|
||||
```
|
||||
$ gpg --send-key [fpr]
|
||||
|
||||
```
|
||||
|
||||
#### Revoking identities
|
||||
|
||||
If you need to revoke an identity (e.g., you changed employers and your old email address is no longer valid), you can use a one-liner:
|
||||
```
|
||||
$ gpg --quick-revoke-uid [fpr] 'Alice Engineer <aengineer@example.net>'
|
||||
|
||||
```
|
||||
|
||||
You can also do the same with the menu mode using gpg --edit-key [fpr].
|
||||
|
||||
Once you are done, remember to send the updated key back to keyservers:
|
||||
```
|
||||
$ gpg --send-key [fpr]
|
||||
|
||||
```
|
||||
|
||||
Next time, we'll look at how Git supports multiple levels of integration with PGP.
|
||||
|
||||
Learn more about Linux through the free ["Introduction to Linux" ][8]course from The Linux Foundation and edX.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.linux.com/blog/learn/pgp/2018/3/protecting-code-integrity-pgp-part-5-moving-subkeys-hardware-device
|
||||
|
||||
作者:[KONSTANTIN RYABITSEV][a]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://www.linux.com/users/mricon
|
||||
[1]:https://www.linux.com/blog/learn/2018/2/protecting-code-integrity-pgp-part-1-basic-pgp-concepts-and-tools
|
||||
[2]:https://www.linux.com/blog/learn/pgp/2018/2/protecting-code-integrity-pgp-part-2-generating-and-protecting-your-master-pgp-key
|
||||
[3]:https://www.linux.com/blog/learn/pgp/2018/2/protecting-code-integrity-pgp-part-3-generating-pgp-subkeys
|
||||
[4]:https://www.linux.com/blog/learn/pgp/2018/3/protecting-code-integrity-pgp-part-4-moving-your-master-key-offline-storage
|
||||
[5]:https://shop.nitrokey.com/shop/product/nitrokey-start-6
|
||||
[6]:https://shop.nitrokey.com/shop/product/nitrokey-pro-3
|
||||
[7]:https://www.yubico.com/product/yubikey-4-series/
|
||||
[8]:https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux
|
@ -1,318 +0,0 @@
|
||||
Protecting Code Integrity with PGP — Part 6: Using PGP with Git
|
||||
======
|
||||
|
||||

|
||||
In this tutorial series, we're providing practical guidelines for using PGP, including basic concepts and generating and protecting your keys. If you missed the previous articles, you can catch up below. In this article, we look at Git's integration with PGP, starting with signed tags, then introducing signed commits, and finally adding support for signed pushes.
|
||||
|
||||
[Part 1: Basic Concepts and Tools][1]
|
||||
|
||||
[Part 2: Generating Your Master Key][2]
|
||||
|
||||
[Part 3: Generating PGP Subkeys][3]
|
||||
|
||||
[Part 4: Moving Your Master Key to Offline Storage][4]
|
||||
|
||||
[Part 5: Moving Subkeys to a Hardware Device][5]
|
||||
|
||||
One of the core features of Git is its decentralized nature -- once a repository is cloned to your system, you have full history of the project, including all of its tags, commits and branches. However, with hundreds of cloned repositories floating around, how does anyone verify that the repository you downloaded has not been tampered with by a malicious third party? You may have cloned it from GitHub or some other official-looking location, but what if someone had managed to trick you?
|
||||
|
||||
Or what happens if a backdoor is discovered in one of the projects you've worked on, and the "Author" line in the commit says it was done by you, while you're pretty sure you had [nothing to do with it][6]?
|
||||
|
||||
To address both of these issues, Git introduced PGP integration. Signed tags prove the repository integrity by assuring that its contents are exactly the same as on the workstation of the developer who created the tag, while signed commits make it nearly impossible for someone to impersonate you without having access to your PGP keys.
|
||||
|
||||
### Checklist
|
||||
|
||||
* Understand signed tags, commits, and pushes (ESSENTIAL)
|
||||
|
||||
* Configure git to use your key (ESSENTIAL)
|
||||
|
||||
* Learn how tag signing and verification works (ESSENTIAL)
|
||||
|
||||
* Configure git to always sign annotated tags (NICE)
|
||||
|
||||
* Learn how commit signing and verification works (ESSENTIAL)
|
||||
|
||||
* Configure git to always sign commits (NICE)
|
||||
|
||||
* Configure gpg-agent options (ESSENTIAL)
|
||||
|
||||
|
||||
|
||||
|
||||
### Considerations
|
||||
|
||||
Git implements multiple levels of integration with PGP, first starting with signed tags, then introducing signed commits, and finally adding support for signed pushes.
|
||||
|
||||
#### Understanding Git Hashes
|
||||
|
||||
Git is a complicated beast, but you need to know what a "hash" is in order to have a good grasp on how PGP integrates with it. We'll narrow it down to two kinds of hashes: tree hashes and commit hashes.
|
||||
|
||||
##### Tree hashes
|
||||
|
||||
Every time you commit a change to a repository, git records checksum hashes of all objects in it -- contents (blobs), directories (trees), file names and permissions, etc, for each subdirectory in the repository. It only does this for trees and blobs that have changed with each commit, so as not to re-checksum the entire tree unnecessarily if only a small part of it was touched.
|
||||
|
||||
Then it calculates and stores the checksum of the toplevel tree, which will inevitably be different if any part of the repository has changed.
|
||||
|
||||
##### Commit hashes
|
||||
|
||||
Once the tree hash has been created, git will calculate the commit hash, which will include the following information about the repository and the change being made:
|
||||
|
||||
* The checksum hash of the tree
|
||||
|
||||
* The checksum hash of the tree before the change (parent)
|
||||
|
||||
* Information about the author (name, email, time of authorship)
|
||||
|
||||
* Information about the committer (name, email, time of commit)
|
||||
|
||||
* The commit message
|
||||
|
||||
|
||||
|
||||
|
||||
##### Hashing function
|
||||
|
||||
At the time of writing, git still uses the SHA1 hashing mechanism to calculate checksums, though work is under way to transition to a stronger algorithm that is more resistant to collisions. Note, that git already includes collision avoidance routines, so it is believed that a successful collision attack against git remains impractical.
|
||||
|
||||
#### Annotated tags and tag signatures
|
||||
|
||||
Git tags allow developers to mark specific commits in the history of each git repository. Tags can be "lightweight" \-- more or less just a pointer at a specific commit, or they can be "annotated," which becomes its own object in the git tree. An annotated tag object contains all of the following information:
|
||||
|
||||
* The checksum hash of the commit being tagged
|
||||
|
||||
* The tag name
|
||||
|
||||
* Information about the tagger (name, email, time of tagging)
|
||||
|
||||
* The tag message
|
||||
|
||||
|
||||
|
||||
|
||||
A PGP-signed tag is simply an annotated tag with all these entries wrapped around in a PGP signature. When a developer signs their git tag, they effectively assure you of the following:
|
||||
|
||||
* Who they are (and why you should trust them)
|
||||
|
||||
* What the state of their repository was at the time of signing:
|
||||
|
||||
* The tag includes the hash of the commit
|
||||
|
||||
* The commit hash includes the hash of the toplevel tree
|
||||
|
||||
* Which includes hashes of all files, contents, and subtrees
|
||||
* It also includes all information about authorship
|
||||
|
||||
* Including exact times when changes were made
|
||||
|
||||
|
||||
|
||||
|
||||
When you clone a git repository and verify a signed tag, that gives you cryptographic assurance that all contents in the repository, including all of its history, are exactly the same as the contents of the repository on the developer's computer at the time of signing.
|
||||
|
||||
#### Signed commits
|
||||
|
||||
Signed commits are very similar to signed tags -- the contents of the commit object are PGP-signed instead of the contents of the tag object. A commit signature also gives you full verifiable information about the state of the developer's tree at the time the signature was made. Tag signatures and commit PGP signatures provide exact same security assurances about the repository and its entire history.
|
||||
|
||||
#### Signed pushes
|
||||
|
||||
This is included here for completeness' sake, since this functionality needs to be enabled on the server receiving the push before it does anything useful. As we saw above, PGP-signing a git object gives verifiable information about the developer's git tree, but not about their intent for that tree.
|
||||
|
||||
For example, you can be working on an experimental branch in your own git fork trying out a promising cool feature, but after you submit your work for review, someone finds a nasty bug in your code. Since your commits are properly signed, someone can take the branch containing your nasty bug and push it into master, introducing a vulnerability that was never intended to go into production. Since the commit is properly signed with your key, everything looks legitimate and your reputation is questioned when the bug is discovered.
|
||||
|
||||
Ability to require PGP-signatures during git push was added in order to certify the intent of the commit, and not merely verify its contents.
|
||||
|
||||
#### Configure git to use your PGP key
|
||||
|
||||
If you only have one secret key in your keyring, then you don't really need to do anything extra, as it becomes your default key.
|
||||
|
||||
However, if you happen to have multiple secret keys, you can tell git which key should be used ([fpr] is the fingerprint of your key):
|
||||
```
|
||||
$ git config --global user.signingKey [fpr]
|
||||
|
||||
```
|
||||
|
||||
NOTE: If you have a distinct gpg2 command, then you should tell git to always use it instead of the legacy gpg from version 1:
|
||||
```
|
||||
$ git config --global gpg.program gpg2
|
||||
|
||||
```
|
||||
|
||||
#### How to work with signed tags
|
||||
|
||||
To create a signed tag, simply pass the -s switch to the tag command:
|
||||
```
|
||||
$ git tag -s [tagname]
|
||||
|
||||
```
|
||||
|
||||
Our recommendation is to always sign git tags, as this allows other developers to ensure that the git repository they are working with has not been maliciously altered (e.g. in order to introduce backdoors).
|
||||
|
||||
##### How to verify signed tags
|
||||
|
||||
To verify a signed tag, simply use the verify-tag command:
|
||||
```
|
||||
$ git verify-tag [tagname]
|
||||
|
||||
```
|
||||
|
||||
If you are verifying someone else's git tag, then you will need to import their PGP key. Please refer to the "Trusted Team communication" document in the same repository for guidance on this topic.
|
||||
|
||||
##### Verifying at pull time
|
||||
|
||||
If you are pulling a tag from another fork of the project repository, git should automatically verify the signature at the tip you're pulling and show you the results during the merge operation:
|
||||
```
|
||||
$ git pull [url] tags/sometag
|
||||
|
||||
```
|
||||
|
||||
The merge message will contain something like this:
|
||||
```
|
||||
Merge tag 'sometag' of [url]
|
||||
|
||||
[Tag message]
|
||||
|
||||
# gpg: Signature made [...]
|
||||
# gpg: Good signature from [...]
|
||||
|
||||
```
|
||||
|
||||
#### Configure git to always sign annotated tags
|
||||
|
||||
Chances are, if you're creating an annotated tag, you'll want to sign it. To force git to always sign annotated tags, you can set a global configuration option:
|
||||
```
|
||||
$ git config --global tag.forceSignAnnotated true
|
||||
|
||||
```
|
||||
|
||||
Alternatively, you can just train your muscle memory to always pass the -s switch:
|
||||
```
|
||||
$ git tag -asm "Tag message" tagname
|
||||
|
||||
```
|
||||
|
||||
#### How to work with signed commits
|
||||
|
||||
It is easy to create signed commits, but it is much more difficult to incorporate them into your workflow. Many projects use signed commits as a sort of "Committed-by:" line equivalent that records code provenance -- the signatures are rarely verified by others except when tracking down project history. In a sense, signed commits are used for "tamper evidence," and not to "tamper-proof" the git workflow.
|
||||
|
||||
To create a signed commit, you just need to pass the -S flag to the git commit command (it's capital -S due to collision with another flag):
|
||||
```
|
||||
$ git commit -S
|
||||
|
||||
```
|
||||
|
||||
Our recommendation is to always sign commits and to require them of all project members, regardless of whether anyone is verifying them (that can always come at a later time).
|
||||
|
||||
##### How to verify signed commits
|
||||
|
||||
To verify a single commit you can use verify-commit:
|
||||
```
|
||||
$ git verify-commit [hash]
|
||||
|
||||
```
|
||||
|
||||
You can also look at repository logs and request that all commit signatures are verified and shown:
|
||||
```
|
||||
$ git log --pretty=short --show-signature
|
||||
|
||||
```
|
||||
|
||||
##### Verifying commits during git merge
|
||||
|
||||
If all members of your project sign their commits, you can enforce signature checking at merge time (and then sign the resulting merge commit itself using the -S flag):
|
||||
```
|
||||
$ git merge --verify-signatures -S merged-branch
|
||||
|
||||
```
|
||||
|
||||
Note, that the merge will fail if there is even one commit that is not signed or does not pass verification. As it is often the case, technology is the easy part -- the human side of the equation is what makes adopting strict commit signing for your project difficult.
|
||||
|
||||
##### If your project uses mailing lists for patch management
|
||||
|
||||
If your project uses a mailing list for submitting and processing patches, then there is little use in signing commits, because all signature information will be lost when sent through that medium. It is still useful to sign your commits, just so others can refer to your publicly hosted git trees for reference, but the upstream project receiving your patches will not be able to verify them directly with git.
|
||||
|
||||
You can still sign the emails containing the patches, though.
|
||||
|
||||
#### Configure git to always sign commits
|
||||
|
||||
You can tell git to always sign commits:
|
||||
```
|
||||
git config --global commit.gpgSign true
|
||||
|
||||
```
|
||||
|
||||
Or you can train your muscle memory to always pass the -S flag to all git commit operations (this includes --amend).
|
||||
|
||||
#### Configure gpg-agent options
|
||||
|
||||
The GnuPG agent is a helper tool that will start automatically whenever you use the gpg command and run in the background with the purpose of caching the private key passphrase. This way you only have to unlock your key once to use it repeatedly (very handy if you need to sign a bunch of git operations in an automated script without having to continuously retype your passphrase).
|
||||
|
||||
There are two options you should know in order to tweak when the passphrase should be expired from cache:
|
||||
|
||||
* default-cache-ttl (seconds): If you use the same key again before the time-to-live expires, the countdown will reset for another period. The default is 600 (10 minutes).
|
||||
|
||||
* max-cache-ttl (seconds): Regardless of how recently you've used the key since initial passphrase entry, if the maximum time-to-live countdown expires, you'll have to enter the passphrase again. The default is 30 minutes.
|
||||
|
||||
|
||||
|
||||
|
||||
If you find either of these defaults too short (or too long), you can edit your ~/.gnupg/gpg-agent.conf file to set your own values:
|
||||
```
|
||||
# set to 30 minutes for regular ttl, and 2 hours for max ttl
|
||||
default-cache-ttl 1800
|
||||
max-cache-ttl 7200
|
||||
|
||||
```
|
||||
|
||||
##### Bonus: Using gpg-agent with ssh
|
||||
|
||||
If you've created an [A] (Authentication) key and moved it to the smartcard, you can use it with ssh for adding 2-factor authentication for your ssh sessions. You just need to tell your environment to use the correct socket file for talking to the agent.
|
||||
|
||||
First, add the following to your ~/.gnupg/gpg-agent.conf:
|
||||
```
|
||||
enable-ssh-support
|
||||
|
||||
```
|
||||
|
||||
Then, add this to your .bashrc:
|
||||
```
|
||||
export SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket)
|
||||
|
||||
```
|
||||
|
||||
You will need to kill the existing gpg-agent process and start a new login session for the changes to take effect:
|
||||
```
|
||||
$ killall gpg-agent
|
||||
$ bash
|
||||
$ ssh-add -L
|
||||
|
||||
```
|
||||
|
||||
The last command should list the SSH representation of your PGP Auth key (the comment should say cardno:XXXXXXXX at the end to indicate it's coming from the smartcard).
|
||||
|
||||
To enable key-based logins with ssh, just add the ssh-add -L output to ~/.ssh/authorized_keys on remote systems you log in to. Congratulations, you've just made your ssh credentials extremely difficult to steal.
|
||||
|
||||
As a bonus, you can get other people's PGP-based ssh keys from public keyservers, should you need to grant them ssh access to anything:
|
||||
```
|
||||
$ gpg --export-ssh-key [keyid]
|
||||
|
||||
```
|
||||
|
||||
This can come in super handy if you need to allow developers access to git repositories over ssh. Next time, we'll provide tips for protecting your email accounts as well as your PGP keys.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.linux.com/blog/learn/pgp/2018/3/protecting-code-integrity-pgp-part-6-using-pgp-git
|
||||
|
||||
作者:[KONSTANTIN RYABITSEV][a]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://www.linux.com/users/mricon
|
||||
[1]:https://www.linux.com/blog/learn/2018/2/protecting-code-integrity-pgp-part-1-basic-pgp-concepts-and-tools
|
||||
[2]:https://www.linux.com/blog/learn/pgp/2018/2/protecting-code-integrity-pgp-part-2-generating-and-protecting-your-master-pgp-key
|
||||
[3]:https://www.linux.com/blog/learn/pgp/2018/2/protecting-code-integrity-pgp-part-3-generating-pgp-subkeys
|
||||
[4]:https://www.linux.com/blog/learn/pgp/2018/3/protecting-code-integrity-pgp-part-4-moving-your-master-key-offline-storage
|
||||
[5]:https://www.linux.com/blog/learn/pgp/2018/3/protecting-code-integrity-pgp-part-5-moving-subkeys-hardware-device
|
||||
[6]:https://github.com/jayphelps/git-blame-someone-else
|
@ -1,3 +1,4 @@
|
||||
Translating by MjSeven
|
||||
Users, Groups and Other Linux Beasts: Part 2
|
||||
======
|
||||

|
||||
|
@ -0,0 +1,177 @@
|
||||
用于游戏开发的图形和音乐工具
|
||||
======
|
||||
|
||||

|
||||
|
||||
在十月初,我们的俱乐部,来自马歇尔大学的 [Geeks and Gadgets][1] , 参加就职 [Open Jam][2], 一个游戏 jam ,庆祝最好的开源工具。游戏 jams 是参与者为娱乐像团队协作的来开发计算机游戏的事件。Jams 倾向于非常简短--仅三天时间长--并非常让人精疲力尽。Opensource.com 在八月下旬 [宣布][3] Open Jam ,更多 [three dozen games][4] 进入到竞赛中。
|
||||
|
||||
我们的俱乐部希望在我们的工程中创建和使用开放源码软件,所以 Open Jam 自然是我们想要参与的 jam 。我们的提交的文件是一个实验性的名称为 [Mark My Words][5] 的游戏。我们使用多种自由和开放源码 (FOSS) 工具来开发它;在这篇文章中,我们将讨论一些我们使用和意识到有潜在的障碍物的工具。
|
||||
|
||||
### 音频工具
|
||||
|
||||
#### MilkyTracker
|
||||
|
||||
[MilkyTracker][6] 是最好的可用于构成旧样式电子游戏音乐的软件包中的一个。它是一个 [music tracker][7] 的一个示例,一个强大的带有特殊的基于网格的图形编辑器的 MOD 和 XM 文件创建器。在我们的游戏中,我们使用它来构成大多数的音乐片段。这个程序最好的特点是,它比我们其它的大多数工具消耗更少的硬盘空间和 RAM 。虽然如此,MilkyTracker 仍然非常强大。
|
||||
|
||||

|
||||
|
||||
用户界面需要一会来习惯,这里有对一些想试用MilkyTracker的音乐家的一些提示:
|
||||
|
||||
* 转到 Config > Misc. ,设置 edit 模式控制样式为 "MilkyTracker." 这将给你几乎所有的现代键盘快捷方式
|
||||
* 撤销 Ctrl+Z
|
||||
* 重做 Ctrl+Y
|
||||
* 切换 pattern-edit 模式 空格键
|
||||
* 删除先前的注释 退格键
|
||||
* 插入一行 Insert键
|
||||
* 默认情况下,一个注释将持续作用,直到它在这频道上被替换。你可以明确地结束一个注释,通过使用一个反引号 (`) 键插入一个 KeyOff 注释
|
||||
* 在你开始谱写乐曲前,你将不得不创建或查找示例。我们建议在网站上查找 [Creative Commons][8] 协议的示例,例如 [Freesound][9] 或 [ccMixter][10]
|
||||
|
||||
|
||||
|
||||
另外,保持 [MilkyTracker 文档页面][11] 在手边。它含有数不清的教程和手册的链接。一个好的开始点是在该项目 wiki 上的 [MilkyTracker 指南][12] 。
|
||||
|
||||
#### LMMS
|
||||
|
||||
我们中的两个音乐家使用多用途和现代音乐创建工具 [LMMS][13] 。它带来一个绝妙的示例和效果库,加一个灵活的多种多样的插件来生成独特的声音。 The learning curve for LMMS 的学习曲线令人吃惊的低,在某种程度上是因为友好的节拍/低音线编辑器。
|
||||
|
||||

|
||||
|
||||
我们对音乐家有一个建议,尝试 LMMS:使用插件。 对于 [chiptune][14]-样式音乐,我们推荐 [sfxr][15] ,[BitInvader][16] ,和 [FreeBoy][17] 。对于其它样式, [ZynAddSubFX][18] 是一个好的选择。它带来一个宽波段的可以被你任意更改的人工合成工具。
|
||||
|
||||
### 图形工具
|
||||
|
||||
#### Tiled
|
||||
|
||||
在开放源码游戏开发中,[Tiled][19] 是一个流行的组件地图类(tilemap)编辑器。我们使用它为来为我们在游戏场景中组合连续的,复古的背景。
|
||||
|
||||

|
||||
|
||||
Tiled 可以导出地图为 XM L,JSON ,或平坦的图像。它是稳定的和跨平台的。
|
||||
|
||||
Tiled 的特征一,在 jam 期间,我们不能使用, 允许你定义和随意的放置游戏对象,例如硬币和永久能力提升道具到地图上。你需要做的全部是加载对象的图像为一个平铺显示集,然后使用插入平铺显示放置它们。
|
||||
|
||||
一般来说,对于一些需要一个地图编辑器的工程,Tiled 是我们建议软件的一个主要的部分。
|
||||
|
||||
#### Piskel
|
||||
|
||||
[Piskel][20] 是一个像素艺术编辑器,它的源文件代码是在 [Apache 协议, 版本 2.0][21] 协议下。在 jam 期间,我们对我们的大多数的图像资源使用 Piskel ,我们当然也将在未来的工程中使用它。
|
||||
|
||||
Piskel 的特征二,在 jam 的 onion skin和Spritesheet导出期间极大地帮助我们。
|
||||
|
||||
##### Onion skin
|
||||
|
||||
onion skin 特征将使 Piskel 显示你编辑的动画的前一帧和后一帧的一个幽灵似的覆盖物,像这样:
|
||||
|
||||

|
||||
|
||||
Onion skin 是便于使用的,因为它适合作为一个绘制指南和在动画进程期间帮助你维护在你的角色上连续的图形和声音。为启用它,只需要在屏幕的右上方预览窗体的下面单击 onion-shaped 图标。
|
||||
|
||||

|
||||
|
||||
##### Spritesheet 导出
|
||||
|
||||
Piskel 的能力是导出动画为一个 spritesheet ,也是非常有用的。一个 spritesheet 是一个单个光栅图象,它包含一个动画的所有的帧。例如,这是一个我们从 Piskel 导出的 spritesheet :
|
||||
|
||||

|
||||
|
||||
spritesheet 包含两幅帧。一幅帧是图像的上半部分,另一帧是图像的下半部分。Spritesheets 通过启用一个完整的动画来从单个文件加载,大大地简化一个游戏的代码。这是上面的 spritesheet 的一个动画版本:
|
||||
|
||||

|
||||
|
||||
##### Unpiskel.py
|
||||
|
||||
在 jam 期间,我们很多次想批量转换 Piskel 文件到 PNG 文件。尽管 Piskel 文件格式基于 JSON ,我们写一个小的 GPLv3 协议的称为 [unpiskel.py][22] 的 Python 脚本来做转换。
|
||||
|
||||
它像这样被引用:
|
||||
```
|
||||
python unpiskel.py input.piskel
|
||||
```
|
||||
|
||||
这个脚本将从一个 Piskel 文件(这里 `input.piskel`)中提取 PNG 数据帧和层,并存储它们在它们拥有的文件中。这些文件采用模式 `NAME_XX_YY.png` ,在这里 `NAME` 是 Piskel 文件的缩减名称,`XX` 是帧的编号,`YY` 是层的编号。
|
||||
|
||||
因为脚本可以从一个 shell 中引用,它可以被使用在文件的整个列表中。
|
||||
```
|
||||
for f in *.piskel; do python unpiskel.py "$f"; done
|
||||
```
|
||||
|
||||
### Python, Pygame, 和 cx_Freeze
|
||||
|
||||
#### Python 和 Pygame
|
||||
|
||||
我们使用 [Python][23] 语言来自制作我们的游戏。它是一个脚本语言,通常被用于文本处理和桌面应用程序开发。它也可以用于游戏开发,例如工程,像 [Angry Drunken Dwarves][24] 和 [Ren'Py][25] 已经显示。这两个工程都使用一个称为 [Pygame][26] 的 Python 库来显示图形和产生声音,所以我们也决定在 Open Jam 中使用这个库。
|
||||
|
||||
Pygame 被证明是既稳定又富有特色,并且它对我们创建的街机游戏来说是优秀的。在低分辨率时,库的速度足够快的,但是在高分辨率时,它的仅 CPU 渲染开始变慢。这是因为 Pygame 不使用硬件加速渲染。然而,开发者可以充分利用 OpenGL 基础设施。
|
||||
|
||||
如果你正在寻找一个好的 2D 游戏编程库,Pygame 是值得密切注意的一个。它的网站有 [一个好的教程][27] 来开始。务必看看它!
|
||||
|
||||
#### cx_Freeze
|
||||
|
||||
准备发行我们的游戏是有趣的。我们知道,Windows 用户不喜欢有一个 Python 安装,并且要求他们来安装它可能很过分。除此之外,他们也可能不得不安装 Pygame ,在 Windows 上,这不是一个简单的工作。
|
||||
|
||||
有一件事很清楚:我们不得不放置我们的游戏到一个更方便的结构中。很多其他的 Open Jam 参与者使用专有的游戏引擎 Unity ,它能够使它们的游戏在网页浏览器中来玩。这使得它们非常方便地来玩。便利性是一个我们的游戏恰巧一丝的都没有的东西。但是,感谢生机勃勃的 Python 生态系统,我们有选择。在 Windows 上现有的工具帮助 Python 程序员准备发行他们的游戏。我们考虑的两个是 [cx_Freeze][28] 和 [Pygame2exe][29] (它使用 [py2exe][30])。我们下决心在 cx_Freeze 上,因为它是跨平台的。
|
||||
|
||||
在 cx_Freeze 中,你可以为发行版打包一个单个脚本游戏,只要在shell运行一个命令,像这样:
|
||||
```
|
||||
cxfreeze main.py --target-dir dist
|
||||
```
|
||||
|
||||
`cxfreeze` 的这个调用将拿你的脚本(这里 `main.py`) 和在你系统上的 Python 解释器,并捆绑定它们到 `dist` 目录。一旦完成它,你需要做的是手动复制你的游戏的数据文件到 `dist` 目录。你将发现,`dist` 目录包含一个可以运行来开始你的游戏的可执行文件。
|
||||
|
||||
这里有更复杂难解的方法来使用 cx_Freeze ,允许你自动地复制数据文件,但是我们发现简单的调用 `cxfreeze` 足够我们的需要。感谢这个工具,我们使我们的游戏稍微便利的运行。
|
||||
|
||||
### 庆祝开放源码
|
||||
|
||||
Open Jam 是重要的,因为它庆祝软件开发的开放源码模式。这是来分析开放源码工具的当前状态和我们在未来工作中需求的一个机会。,对于游戏开发者来设法推动它们的工具的使用范围,学习必需提高未来游戏开发者的益处,游戏 jams 或许是最好的时间。
|
||||
|
||||
开放源码工具使人们能够探索他们的创造性,而不妥协他们的自由和前期的投资。尽管我们可能不能成为专业的游戏开发者,我们仍然能获取它的一段小的体验,使用我们简短的,实验性的称为 [Mark My Words][5] 的游戏。它是一个语言学方面地的有特定主题的游戏,它描述一个小说写作系统在它历史期间的演化。Open Jam 有一些令人愉快的提交,并且它们是值得校核。真的, [去看看][31] !
|
||||
|
||||
在结束前,我们想要感谢所有的 [参加俱乐部的成员][32],使这次经历真正的有价值。我们也想要感谢 [Michael Clayton][33],[Jared Sprague][34] 和 [Opensource.com][35] 主办 open Jam。它是一次欢乐。
|
||||
|
||||
现在,我们对读者有一些问题。你是一个 FOSS 游戏开发者吗?你选择的工具是什么?务必在下面留下一个评论!
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://opensource.com/article/18/1/graphics-music-tools-game-dev
|
||||
|
||||
作者:[Charlie Murphy][a]
|
||||
译者:[robsean](https://github.com/robsean)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://opensource.com/users/rsg167
|
||||
[1]:http://mugeeks.org/
|
||||
[2]:https://itch.io/jam/open-jam-1
|
||||
[3]:https://opensource.com/article/17/8/open-jam-announcement
|
||||
[4]:https://opensource.com/article/17/11/open-jam
|
||||
[5]:https://mugeeksalpha.itch.io/mark-omy-words
|
||||
[6]:http://milkytracker.titandemo.org/
|
||||
[7]:https://en.wikipedia.org/wiki/Music_tracker
|
||||
[8]:https://creativecommons.org/
|
||||
[9]:https://freesound.org/
|
||||
[10]:http://ccmixter.org/view/media/home
|
||||
[11]:http://milkytracker.titandemo.org/documentation/
|
||||
[12]:https://github.com/milkytracker/MilkyTracker/wiki/MilkyTracker-Guide
|
||||
[13]:https://lmms.io/
|
||||
[14]:https://en.wikipedia.org/wiki/Chiptune
|
||||
[15]:https://github.com/grimfang4/sfxr
|
||||
[16]:https://lmms.io/wiki/index.php?title=BitInvader
|
||||
[17]:https://lmms.io/wiki/index.php?title=FreeBoy
|
||||
[18]:http://zynaddsubfx.sourceforge.net/
|
||||
[19]:http://www.mapeditor.org/
|
||||
[20]:https://www.piskelapp.com/
|
||||
[21]:https://github.com/piskelapp/piskel/blob/master/LICENSE
|
||||
[22]:https://raw.githubusercontent.com/MUGeeksandGadgets/MarkMyWords/master/tools/unpiskel.py
|
||||
[23]:https://www.python.org/
|
||||
[24]:https://www.sacredchao.net/~piman/angrydd/
|
||||
[25]:https://renpy.org/
|
||||
[26]:https://www.Pygame.org/
|
||||
[27]:http://Pygame.org/docs/tut/PygameIntro.html
|
||||
[28]:https://anthony-tuininga.github.io/cx_Freeze/
|
||||
[29]:https://Pygame.org/wiki/Pygame2exe
|
||||
[30]:http://www.py2exe.org/
|
||||
[31]:https://itch.io/jam/open-jam-1/entries
|
||||
[32]:https://github.com/MUGeeksandGadgets/MarkMyWords/blob/3e1e8aed12ebe13acccf0d87b06d4f3bd124b9db/README.md#credits
|
||||
[33]:https://twitter.com/mwcz
|
||||
[34]:https://twitter.com/caramelcode
|
||||
[35]:https://opensource.com/
|
@ -0,0 +1,304 @@
|
||||
用 PGP 保护代码完整性(五):将子密钥移到一个硬件设备中
|
||||
======
|
||||
|
||||

|
||||
|
||||
在本系列教程中,我们将提供一个使用 PGP 的实用指南。如果你没有看过前面的文章,你可以通过下面的链接去查看。在这篇文章中,我们将继续讨论如何保护你的密钥,谈一谈将你的子密钥移到一个专门的硬件设备中的一些技巧。
|
||||
|
||||
[第一部分:基本概念和工具][1]
|
||||
|
||||
[第二部分:生成你的主密钥][2]
|
||||
|
||||
[第三部分:生成 PGP 子密钥][3]
|
||||
|
||||
[第四部分:将主密钥移到离线存储中][4]
|
||||
|
||||
### 清单
|
||||
|
||||
* 取得一个 GnuPG 兼容的硬件设备(必要)
|
||||
|
||||
* 配置 GnuPG 在设备上工作(必要)
|
||||
|
||||
* 设置 user 和 admin 的 PIN(必要)
|
||||
|
||||
* 移动子密钥到设备中(必要)
|
||||
|
||||
|
||||
|
||||
|
||||
### 考虑事项
|
||||
|
||||
虽然现在主密钥已经不用担心泄露或失窃了,但子密钥仍然在你的 Home 目录中。任何得到它的人都能够解密你的通讯或假冒你的签名(如果他们知道密钥的密码)。并且,每次执行一个 GnuPG 操作都要将密钥加载到操作系统内存中,这将使一些更高级的恶意软件有机会得到你的密钥(想想 Meltdown 和 Spectre)。
|
||||
|
||||
完全保护密钥的最好方式就是,将它移到一个专门的硬件设备中,这种硬件设备是一个可操作的智能卡。
|
||||
|
||||
#### 智能卡的好处
|
||||
|
||||
一个智能卡包含一个加密芯片,它能够存储私钥,并且直接在智能卡内部执行秘密操作。因为密钥内容从来没有离开过智能卡,计算机操作系统并不能检索你插入的智能卡上的私钥。这与前面用于备份目的的加密 USB 存储是不同的 —— 虽然 USB 设备也是插入并解密的,但操作系统是能够去访问私钥内容的。使用外置的加密 USB 介质并不能代替智能卡设备的功能。
|
||||
|
||||
智能卡的一些其它好处:
|
||||
|
||||
* 它们很便宜且易于获得
|
||||
|
||||
* 它们小巧且易于携带
|
||||
|
||||
* 它们可以用于多种设备上
|
||||
|
||||
* 它们中的很多都具有防篡改功能(取决于制造商)
|
||||
|
||||
|
||||
|
||||
|
||||
#### 可用的智能卡设备
|
||||
|
||||
智能卡最初是嵌入到真实钱包大小的卡中,故而得名智能卡。你总是可以买到并使用 GnuPG 功能的智能卡,并且它们是你能得到的最便宜的可用设备之一。但是,事实上智能卡有一个很重要的缺点:它们需要一个智能卡读卡器,只有极小数的笔记本电脑上有这种读卡器。
|
||||
|
||||
由于这个原因,制造商开始推出小型 USB 设备,它的大小和 U 盘类似,内置有微型智能卡,并且在芯片上简单地实现了智能卡协议特性。下面推荐几个这样的设备:
|
||||
|
||||
* [Nitrokey Start][5]:开源硬件和自由软件,可用于 GnuPG 的最便宜的选择之一,但是额外的安全特性很少。
|
||||
|
||||
* [Nitrokey Pro][6]:类似于 Nitrokey Start,它提供防篡改及更多的安全特性(但没有 U2F,具体查看指南的 U2F 节)。
|
||||
|
||||
* [Yubikey 4][7]:专利硬件和软件,但比 Nitrokey Pro 便宜,并且可以用在最新的笔记本电脑上的 USB-C 接口;也提供像 U2F 这样的额外的安全特性。
|
||||
|
||||
|
||||
|
||||
|
||||
我们推荐选一个同时具备智能卡功能和 U2F 的设备,在写这篇文章时,只能选择 Yubikey 4。
|
||||
|
||||
#### 配置智能卡设备
|
||||
|
||||
你的智能卡设备插入任何一台现代的 Linux 或 Mac 工作站上都应该能正常工作。你可以通过运行如下的命令去验证它:
|
||||
```
|
||||
$ gpg --card-status
|
||||
|
||||
```
|
||||
|
||||
如果你没有收到错误,有一个完整的卡列表,就表示一切正常。不幸的是,排除为什么设备不能正常工作的所有可能原因,已经超出了本指南的范围。如果你的智能卡使用 GnuPG 时有问题,请通过你的操作系统的常见支持通道寻求支持。
|
||||
|
||||
##### PIN 不一定是数字
|
||||
|
||||
注意,尽管名为 “PIN”(暗示你它必须是一个“数字”),不论是 user PIN 还是 admin PIN 都不必非要是数字。
|
||||
|
||||
当你收到一个新设备时,它可能设置有一个默认的 user 和 admin PIN,对于 Yubikeys,它分别是 123456 和 12345678。如果它们的 PIN 不是默认的,请查看设备附带的说明书。
|
||||
|
||||
##### 快速设置
|
||||
|
||||
为配置你的智能卡,你需要使用 GnuPG 菜单系统,因此这里并没有更方便的命令行开关:
|
||||
```
|
||||
$ gpg --card-edit
|
||||
[...omitted...]
|
||||
gpg/card> admin
|
||||
Admin commands are allowed
|
||||
gpg/card> passwd
|
||||
|
||||
```
|
||||
|
||||
你应该去设置 user PIN (1)、admin PIN (3)、和 Reset Code (4)。请确保把它们记录并保存到一个安全的地方 —— 尤其是 Admin PIN 和 Reset Code(它允许你去擦除整个智能卡内容)。你很少使用到 Admin PIN,因此如果你不记录下来,很可能会忘掉它。
|
||||
|
||||
返回到智能卡主菜单,你也可以设置其它值(比如名字、性别、登入日期、等等),但是这些都不是必需的,一旦你的智能卡丢失了,将导致额外的信息泄露。
|
||||
|
||||
#### 将子密钥移到你的智能卡中
|
||||
|
||||
退出卡菜单(使用 “q” 命令)保存所有更改。接下来,我们将你的子密钥移到智能卡中。将需要用到你的 PGP 密钥的密码,在大多数的智能卡操作中都将用到 admin PIN。记住,那个 [fpr] 表示你的密钥的完整的 40 个字符的指纹。
|
||||
```
|
||||
$ gpg --edit-key [fpr]
|
||||
|
||||
Secret subkeys are available.
|
||||
|
||||
pub rsa4096/AAAABBBBCCCCDDDD
|
||||
created: 2017-12-07 expires: 2019-12-07 usage: C
|
||||
trust: ultimate validity: ultimate
|
||||
ssb rsa2048/1111222233334444
|
||||
created: 2017-12-07 expires: never usage: E
|
||||
ssb rsa2048/5555666677778888
|
||||
created: 2017-12-07 expires: never usage: S
|
||||
[ultimate] (1). Alice Engineer <alice@example.org>
|
||||
[ultimate] (2) Alice Engineer <allie@example.net>
|
||||
|
||||
gpg>
|
||||
|
||||
```
|
||||
|
||||
使用 --edit-key 再次进入到菜单模式,你将注意到那个密钥清单有一点小差别。从现在开始,所有的命令都是在这个菜单模式下运行,它用 gpg> 提示符来表示。
|
||||
|
||||
首先,我们来选择移到智能卡中的密钥 —— 你可以通过键入 `key 1`(它表示选择清单中的第一个密钥)来实现:
|
||||
```
|
||||
gpg> key 1
|
||||
|
||||
```
|
||||
|
||||
这个输出会有一点细微的差别:
|
||||
```
|
||||
pub rsa4096/AAAABBBBCCCCDDDD
|
||||
created: 2017-12-07 expires: 2019-12-07 usage: C
|
||||
trust: ultimate validity: ultimate
|
||||
ssb* rsa2048/1111222233334444
|
||||
created: 2017-12-07 expires: never usage: E
|
||||
ssb rsa2048/5555666677778888
|
||||
created: 2017-12-07 expires: never usage: S
|
||||
[ultimate] (1). Alice Engineer <alice@example.org>
|
||||
[ultimate] (2) Alice Engineer <allie@example.net>
|
||||
|
||||
```
|
||||
|
||||
注意与密钥对应的 ssb 行旁边的 `*` —— 它表示这是当前选定的密钥。它是可切换的,意味着如果你再次输入 `key 1`,这个 `*` 将消失,这个密钥将不再被选中。
|
||||
|
||||
现在,我们来将密钥移到智能卡中:
|
||||
```
|
||||
gpg> keytocard
|
||||
Please select where to store the key:
|
||||
(2) Encryption key
|
||||
Your selection? 2
|
||||
|
||||
```
|
||||
|
||||
由于它是我们的 [E] 密钥,把它移到加密区中是有很有意义的。当你提交了你的选择之后,将会被提示输入你的 PGP 密钥的保护密码,接下来输入智能卡的 admin PIN。如果命令没有返回错误,表示你的密钥已经被移到智能卡中了。
|
||||
|
||||
**重要:** 现在再次输入 `key 1` 去取消选中第一个密钥,并输入 `key 2` 去选择 [S] 密钥:
|
||||
|
||||
```
|
||||
gpg> key 1
|
||||
gpg> key 2
|
||||
gpg> keytocard
|
||||
Please select where to store the key:
|
||||
(1) Signature key
|
||||
(3) Authentication key
|
||||
Your selection? 1
|
||||
|
||||
```
|
||||
|
||||
你可以使用 [S] 密钥同时做签名和验证,但是我们希望确保它在签名区,因此,我们选择 (1)。完成后,如果你的命令没有返回错误,表示操作已成功。
|
||||
|
||||
最后,如果你创建了一个 [A] 密钥,你也可以将它移到智能卡中,但是你需要先取消选中 `key 2`。完成后,选择 “q":
|
||||
```
|
||||
gpg> q
|
||||
Save changes? (y/N) y
|
||||
|
||||
```
|
||||
|
||||
保存变更将把你的子密钥移到智能卡后,把你的 Home 目录中的相应子密钥删除(没有关系,因为我们的备份中还有,如果更换了智能卡,你需要再做一遍)。
|
||||
|
||||
##### 验证移动后的密钥
|
||||
|
||||
现在,如果你执行一个` --list-secret-keys` 操作,你将看到一个稍有不同的输出:
|
||||
```
|
||||
$ gpg --list-secret-keys
|
||||
sec# rsa4096 2017-12-06 [C] [expires: 2019-12-06]
|
||||
111122223333444455556666AAAABBBBCCCCDDDD
|
||||
uid [ultimate] Alice Engineer <alice@example.org>
|
||||
uid [ultimate] Alice Engineer <allie@example.net>
|
||||
ssb> rsa2048 2017-12-06 [E]
|
||||
ssb> rsa2048 2017-12-06 [S]
|
||||
|
||||
```
|
||||
|
||||
在 ssb> 的输出中的 `>` 表示子密钥仅在智能卡上有效。如果你进入到你的密钥目录中,查看目录的内容,你将会看到那个 `.key` 文件已经被存根替换:
|
||||
```
|
||||
$ cd ~/.gnupg/private-keys-v1.d
|
||||
$ strings *.key
|
||||
|
||||
```
|
||||
|
||||
这个输出将包含一个影子私钥,它表示那个文件仅是个存根,真正的内容在智能卡中。
|
||||
|
||||
#### 验证智能卡的功能
|
||||
|
||||
验证智能卡能否如期正常运行,你可以通过创建一个签名来验证:
|
||||
```
|
||||
$ echo "Hello world" | gpg --clearsign > /tmp/test.asc
|
||||
$ gpg --verify /tmp/test.asc
|
||||
|
||||
```
|
||||
|
||||
首次运行这个命令时将询问你智能卡的 PIN,在你运行 `gpg —verify` 之后,它将显示 "Good signature”。
|
||||
|
||||
祝贺你,你已经成功将窃取你的开发者数字身份变得更加困难了!
|
||||
|
||||
### 其它常见 GnuPG 操作
|
||||
|
||||
下面是使用你的 PGP 密钥需要做的一些常见操作的快速指南。
|
||||
|
||||
在下面的所有命令中,[fpr] 表示你的密钥指纹。
|
||||
|
||||
#### 挂载主密钥离线存储
|
||||
|
||||
下面的一些操作将需要你的主密钥,因此首先需要去挂载你的主密钥离线存储,并告诉 GnuPG 去使用它。首先,找出介质挂载路径,可以通过查看 mount 命令的输出找到它。接着,设置你的 GnuPG 目录为你的介质上备份的目录,并告诉 GnuPG 将那个目录做为它的 Home:
|
||||
```
|
||||
$ export GNUPGHOME=/media/disk/name/gnupg-backup
|
||||
$ gpg --list-secret-keys
|
||||
|
||||
```
|
||||
|
||||
确保你在输出中看到的是 `sec` 而不是 `sec#`(这个 `#` 表示密钥不可用,仍然使用的是惯常的那个 Home 目录)。
|
||||
|
||||
##### 更新你惯常使用的那个 GnuPG 工作目录
|
||||
|
||||
在你的离线存储上做了任何更改之后,你应该将这些更改同步应用到你惯常使用的工作目录中:
|
||||
```
|
||||
$ gpg --export | gpg --homedir ~/.gnupg --import
|
||||
$ unset GNUPGHOME
|
||||
|
||||
```
|
||||
|
||||
#### 延长密钥过期日期
|
||||
|
||||
我们创建的主密钥的默认过期日期是自创建之日起两年后。这样做都是为安全考虑,这样将使淘汰密钥最终从密钥服务器上消失。
|
||||
|
||||
延长你的密钥过期日期,从当前日期延长一年,只需要运行如下命令:
|
||||
```
|
||||
$ gpg --quick-set-expire [fpr] 1y
|
||||
|
||||
```
|
||||
|
||||
如果为了好记住,你也可以使用一个特定日期(比如,你的生日、1 月 1 日、或加拿大国庆日):
|
||||
```
|
||||
$ gpg --quick-set-expire [fpr] 2020-07-01
|
||||
|
||||
```
|
||||
|
||||
记得将更新后的密钥发送到密钥服务器:
|
||||
```
|
||||
$ gpg --send-key [fpr]
|
||||
|
||||
```
|
||||
|
||||
#### 吊销身份
|
||||
|
||||
如果你需要吊销一个身份(比如,你换了雇主并且旧的邮件地址不再有效了),你可以使用一行命令搞定:
|
||||
```
|
||||
$ gpg --quick-revoke-uid [fpr] 'Alice Engineer <aengineer@example.net>'
|
||||
|
||||
```
|
||||
|
||||
你也可以通过使用 `gpg --edit-key [fpr]` 在菜单模式下完成同样的事情。
|
||||
|
||||
完成后,记得将更新后的密钥发送到密钥服务器上:
|
||||
```
|
||||
$ gpg --send-key [fpr]
|
||||
|
||||
```
|
||||
|
||||
下一篇文章中,我们将谈谈 Git 如何支持 PGP 的多级别集成。
|
||||
|
||||
通过来自 Linux 基金会和 edX 的免费课程 [“Linux 入门" ][8]学习更多 Linux 知识。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.linux.com/blog/learn/pgp/2018/3/protecting-code-integrity-pgp-part-5-moving-subkeys-hardware-device
|
||||
|
||||
作者:[KONSTANTIN RYABITSEV][a]
|
||||
译者:[qhwdw](https://github.com/qhwdw)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://www.linux.com/users/mricon
|
||||
[1]:https://www.linux.com/blog/learn/2018/2/protecting-code-integrity-pgp-part-1-basic-pgp-concepts-and-tools
|
||||
[2]:https://www.linux.com/blog/learn/pgp/2018/2/protecting-code-integrity-pgp-part-2-generating-and-protecting-your-master-pgp-key
|
||||
[3]:https://www.linux.com/blog/learn/pgp/2018/2/protecting-code-integrity-pgp-part-3-generating-pgp-subkeys
|
||||
[4]:https://www.linux.com/blog/learn/pgp/2018/3/protecting-code-integrity-pgp-part-4-moving-your-master-key-offline-storage
|
||||
[5]:https://shop.nitrokey.com/shop/product/nitrokey-start-6
|
||||
[6]:https://shop.nitrokey.com/shop/product/nitrokey-pro-3
|
||||
[7]:https://www.yubico.com/product/yubikey-4-series/
|
||||
[8]:https://training.linuxfoundation.org/linux-courses/system-administration-training/introduction-to-linux
|
@ -0,0 +1,318 @@
|
||||
保护代码完整性(六):在 Git 上使用 PGP
|
||||
======
|
||||
|
||||

|
||||
在本系列教程中,我们提供了一个使用 PGP 的实用指南,包括基本概念和工具、生成和保护你的密钥。如果你错过了前面的文章,你可以查看下面的链接。在这篇文章中,我们谈一谈在 Git 中如何集成 PGP、使用签名的标签,然后介绍签名提交,最后添加签名推送的支持。
|
||||
|
||||
[第一部分:基本概念和工具][1]
|
||||
|
||||
[第二部分:生成你的主密钥][2]
|
||||
|
||||
[第三部分:生成 PGP 子密钥][3]
|
||||
|
||||
[第四部分:将主密钥移到离线存储中][4]
|
||||
|
||||
[第五部分:将子密钥移到硬件设备中][5]
|
||||
|
||||
Git 的核心特性之一就是它的去中心化本质 —— 一旦仓库克隆到你的本地系统,你就拥有了项目的完整历史,包括所有的标签、提交和分支。然而由于存在着成百上千的克隆仓库,如何才能验证你下载的仓库没有被恶意的第三方做过篡改?你可以从 GitHub 或一些貌似官方的位置来克隆它们,但是如果有些人故意欺骗了你怎么办?
|
||||
|
||||
或者在你参与的一些项目上发现了后门,而 "Author" 行显示是你干的,然而你很确定 [不是你干的][6],会发生什么情况?
|
||||
|
||||
为解决上述问题,Git 添加了 PGP 集成。签名的标签通过确认它的内容与创建这个标签的开发者的工作站上的内容完全一致来证明仓库的完整性,而签名的提交几乎是不可能在不访问你的 PGP 密钥的情况下能够假冒你。
|
||||
|
||||
### 清单
|
||||
|
||||
* 了解签名的标签、提交、和推送(必要)
|
||||
|
||||
* 配置 git 使用你的密钥(必要)
|
||||
|
||||
* 学习如何签名标签和验证工作(必要)
|
||||
|
||||
* 配置 git 总是签名注释的标签(推荐)
|
||||
|
||||
* 学习如何签名提交和验证工作(必要)
|
||||
|
||||
* 配置 git 总是签名提交(推荐)
|
||||
|
||||
* 配置 gpg-agent 选项(必要)
|
||||
|
||||
|
||||
|
||||
|
||||
### 考虑事项
|
||||
|
||||
Git 实现了 PGP 的多级集成,首先从签名标签开始,接着介绍签名提交,最后添加签名推送的支持。
|
||||
|
||||
#### 了解 Git 哈希
|
||||
|
||||
Git 是一个复杂的东西,为了你能够更好地掌握它如何集成 PGP,你需要了解什么是”哈希“。我们将它归纳为两种类型的哈希:树哈希和提交哈希。
|
||||
|
||||
##### 树哈希
|
||||
|
||||
每次你向仓库提交一个变更,对于仓库中的每个子目录,git 都会记录它里面所有对象的校验和哈希 —— 内容(blobs)、目录(trees)、文件名和许可等等。它只对每次提交中发生变更的树和内容做此操作,这样在只变更树的一小部分时就不必去重新计算整个树的校验和。
|
||||
|
||||
然后再计算和存储处于顶级的树的校验和,这样如果仓库的任何一部分发生变化,校验和将不可避免地发生变化。
|
||||
|
||||
##### 提交哈希
|
||||
|
||||
一旦创建了树哈希,git 将计算提交哈希,它将包含有关仓库和变更的下列信息:
|
||||
|
||||
* 树哈希的校验和
|
||||
|
||||
* 变更前树哈希的校验和(父级)
|
||||
|
||||
* 有关作者的信息(名字、email、创作时间)
|
||||
|
||||
* 有关提交者的信息(名字、email、提交时间)
|
||||
|
||||
* 提交信息
|
||||
|
||||
|
||||
|
||||
|
||||
##### 哈希函数
|
||||
|
||||
在写这篇文章时,虽然研究一种更强大的、抗碰撞的算法的工作正在进行,但 git 仍然使用的是 SHA1 哈希机制去计算校验和。注意,git 已经包含了碰撞防范程序,因此认为对 git 成功进行碰撞攻击仍然是不可行的。
|
||||
|
||||
#### 注释的标签和标签签名
|
||||
|
||||
在每个 Git 仓库中,标签允许开发者标记特定的提交。标签可以是 “轻量级的” —— 几乎只是一个特定提交上的指针,或者它们可以是 “注释的”,它成为 git 树中自己的项目。一个注释的标签对象包含所有下列的信息:
|
||||
|
||||
* 成为标签的提交哈希的校验和
|
||||
|
||||
* 标签名字
|
||||
|
||||
* 关于打标签的人的信息(名字、email、打标签时间)
|
||||
|
||||
* 标签信息
|
||||
|
||||
|
||||
|
||||
|
||||
一个 PGP 签名的标签是一个带有将所有这些条目封装进一个 PGP 签名的注释标签。当开发者签名他们的 git 标签时,他们实际上是向你保证了如下的信息:
|
||||
|
||||
* 他们是谁(以及他们为什么应该被信任)
|
||||
|
||||
* 他们在签名时的仓库状态是什么样:
|
||||
|
||||
* 标签包含提交的哈希
|
||||
|
||||
* 提交哈希包含了顶级树的哈希
|
||||
|
||||
* 顶级哈希包含了所有文件、内容和子树的哈希
|
||||
* 它也包含有关作者的所有信息
|
||||
|
||||
* 包含变更发生时的精确时间
|
||||
|
||||
|
||||
|
||||
|
||||
当你克隆一个仓库并验证一个签名标签时,就是向你以密码方式保证仓库中的所有内容、包括所有它的历史,与开发者签名时在它的计算机上的仓库完全一致。
|
||||
|
||||
#### 签名的提交
|
||||
|
||||
签名的提交与签名的标签非常类似 —— 提交对象的内容是 PGP 签名过的,而不是标签对象的内容。一个提交签名也给你提供了开发者签名时,开发者树上的全部可验证信息。标签签名和提交 PGP 签名提供了有关仓库和它的完整历史的完全一致的安全保证。
|
||||
|
||||
#### 签名的推送
|
||||
|
||||
为了完整起见,在这里包含了签名的推送这一功能,因为在你使用这个功能之前,需要在接收推送的服务器上先启用它。正如我们在上面所说过的,PGP 签名一个 git 对象就是提供了开发者的 git 树当时的可验证信息,但不提供开发者对那个树意图相关的信息。
|
||||
|
||||
比如,你可以在你自己 fork 的 git 仓库的一个实验分支上尝试一个很酷的特性,为了评估它,你提交了你的工作,但是有人在你的代码中发现了一个恶意的 bug。由于你的提交是经过正确签名的,因此有人可能将包含有恶意 bug 的分支推入到 master 分支中,从而在生产系统中引入一个漏洞。由于提交是经过你的密钥正确签名的,所以一切看起来都是合理合法的,而当 bug 被发现时,你的声誉就会因此而受到影响。
|
||||
|
||||
在 `git push` 时,为了验证提交的意图而不仅仅是验证它的内容,添加了要求 PGP 推送签名的功能。
|
||||
|
||||
#### 配置 git 使用你的 PGP 密钥
|
||||
|
||||
如果在你的钥匙环上只有一个密钥,那么你就不需要再做额外的事了,因为它是你的默认密钥。
|
||||
|
||||
然而,如果你有多个密钥,那么你必须要告诉 git 去使用哪一个密钥。([fpr] 是你的密钥的指纹):
|
||||
```
|
||||
$ git config --global user.signingKey [fpr]
|
||||
|
||||
```
|
||||
|
||||
注意:如果你有一个不同的 gpg2 命令,那么你应该告诉 git 总是去使用它,而不是传统的版本 1 的 gpg:
|
||||
```
|
||||
$ git config --global gpg.program gpg2
|
||||
|
||||
```
|
||||
|
||||
#### 如何使用签名标签
|
||||
|
||||
创建一个签名的标签,只要传递一个简单地 -s 开关给 tag 命令即可:
|
||||
```
|
||||
$ git tag -s [tagname]
|
||||
|
||||
```
|
||||
|
||||
我们建议始终对 git 标签签名,这样让其它的开发者确信他们使用的 git 仓库没有被恶意地修改过(比如,引入后门):
|
||||
|
||||
##### 如何验证签名的标签
|
||||
|
||||
验证一个签名的标签,只需要简单地使用 verify-tag 命令即可:
|
||||
```
|
||||
$ git verify-tag [tagname]
|
||||
|
||||
```
|
||||
|
||||
如果你要验证其他人的 git 标签,那么就需要你导入他的 PGP 公钥。请参考 “可信任的团队沟通” 一文中关于此主题的指导。
|
||||
|
||||
##### 在拉取时验证
|
||||
|
||||
如果你从项目仓库的其它 fork 中拉取一个标签,git 将自动验证签名,并在合并操作时显示结果:
|
||||
```
|
||||
$ git pull [url] tags/sometag
|
||||
|
||||
```
|
||||
|
||||
合并信息将包含类似下面的内容:
|
||||
```
|
||||
Merge tag 'sometag' of [url]
|
||||
|
||||
[Tag message]
|
||||
|
||||
# gpg: Signature made [...]
|
||||
# gpg: Good signature from [...]
|
||||
|
||||
```
|
||||
|
||||
#### 配置 git 始终签名注释的标签
|
||||
|
||||
很可能的是,你正在创建一个带注释的标签,你应该去签名它。强制 git 始终签名带注释的标签,你可以设置一个全局配置选项:
|
||||
```
|
||||
$ git config --global tag.forceSignAnnotated true
|
||||
|
||||
```
|
||||
|
||||
或者,你始终记得每次都传递一个 -s 开关:
|
||||
```
|
||||
$ git tag -asm "Tag message" tagname
|
||||
|
||||
```
|
||||
|
||||
#### 如何使用签名提交
|
||||
|
||||
创建一个签名提交很容易,但是将它纳入到你的工作流中却很困难。许多项目使用签名提交作为一种 "Committed-by:” 的等价行,它记录了代码来源 —— 除了跟踪项目历史外,签名很少有人去验证。在某种意义上,签名的提交用于 ”篡改证据“,而不是 git 工作流的 ”篡改证明“。
|
||||
|
||||
为创建一个签名的提交,你只需要 `git commit` 命令传递一个 -S 标志即可(由于它与另一个标志冲突,所以改为大写的 -S):
|
||||
```
|
||||
$ git commit -S
|
||||
|
||||
```
|
||||
|
||||
我们建议始终使用签名提交,并要求项目所有成员都这样做,这样其它人就可以验证它们(下面就讲到如何验证)。
|
||||
|
||||
##### 如何去验证签名的提交
|
||||
|
||||
验证签名的提交需要使用 verify-commit 命令:
|
||||
```
|
||||
$ git verify-commit [hash]
|
||||
|
||||
```
|
||||
|
||||
你也可以查看仓库日志,要求所有提交签名是被验证和显示的:
|
||||
```
|
||||
$ git log --pretty=short --show-signature
|
||||
|
||||
```
|
||||
|
||||
##### 在 git merge 时验证提交
|
||||
|
||||
如果项目的所有成员都签名了他们的提交,你可以在合并时强制进行签名检查(然后使用 -S 标志对合并操作本身进行签名):
|
||||
```
|
||||
$ git merge --verify-signatures -S merged-branch
|
||||
|
||||
```
|
||||
|
||||
注意,如果有一个提交没有签名或验证失败,将导致合并操作失败。通常情况下,技术是最容易的部分 —— 而人的因素使得项目中很难采用严格的提交验证。
|
||||
|
||||
##### 如果你的项目在补丁管理上采用邮件列表
|
||||
|
||||
如果你的项目在提交和处理补丁时使用一个邮件列表,那么一般很少使用签名提交,因为通过那种方式发送时,签名信息将会丢失。对提交进行签名仍然是非常有用的,这样引用你托管在公开 git 树的其他人就能以它作为参考,但是上游项目接收你的补丁时,仍然不能直接使用 git 去验证它们。
|
||||
|
||||
尽管,你仍然可以签名包含补丁的电子邮件。
|
||||
|
||||
#### 配置 git 始终签名提交
|
||||
|
||||
你可以告诉 git 总是签名提交:
|
||||
```
|
||||
git config --global commit.gpgSign true
|
||||
|
||||
```
|
||||
|
||||
或者你每次都记得给 `git commit` 操作传递一个 -S 标志(包括 —amend)。
|
||||
|
||||
#### 配置 gpg-agent 选项
|
||||
|
||||
GnuPG agent 是一个守护工具,它能在你使用 gpg 命令时随时自动启动,并运行在后台来缓存私钥的密码。这种方式让你只需要解锁一次密钥就可以重复地使用它(如果你需要在一个自动脚本中签署一组 git 操作,而不需要重复输入密钥,这种方式就很方便)。
|
||||
|
||||
为了调整缓存中的密钥过期时间,你应该知道这两个选项:
|
||||
|
||||
* default-cache-ttl(秒):如果在 time-to-live 过期之前再次使用同一个密钥,这个倒计时将重置成另一个倒计时周期。缺省值是 600(10 分钟)。
|
||||
|
||||
* max-cache-ttl(秒):自首次密钥输入以后,不论最近一次使用密钥是什么时间,只要最大值的 time-to-live 倒计时过期,你将被要求再次输入密码。它的缺省值是 30 分钟。
|
||||
|
||||
|
||||
|
||||
|
||||
如果你认为这些缺省值过短(或过长),你可以编辑 ~/.gnupg/gpg-agent.conf 文件去设置你自己的值:
|
||||
```
|
||||
# set to 30 minutes for regular ttl, and 2 hours for max ttl
|
||||
default-cache-ttl 1800
|
||||
max-cache-ttl 7200
|
||||
|
||||
```
|
||||
|
||||
##### 额外好处:与 ssh 一起使用 gpg-agent
|
||||
|
||||
如果你创建了一个 [A](验证)密钥,并将它移到了智能卡,你可以将它用到 ssh 上,为你的 ssh 会话添加一个双因子验证。为了与 agent 沟通你只需要告诉你的环境去使用正确的套接字文件即可。
|
||||
|
||||
首先,添加下列行到你的 ~/.gnupg/gpg-agent.conf 文件中:
|
||||
```
|
||||
enable-ssh-support
|
||||
|
||||
```
|
||||
|
||||
接着,添加下列行到你的 .bashrc 文件中:
|
||||
```
|
||||
export SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket)
|
||||
|
||||
```
|
||||
|
||||
为了让改变生效,你需要 kill 掉正在运行的 gpg-agent 进程,并重新启动一个新的登入会话:
|
||||
```
|
||||
$ killall gpg-agent
|
||||
$ bash
|
||||
$ ssh-add -L
|
||||
|
||||
```
|
||||
|
||||
最后的命令将列出代表你的 PGP Auth 密钥的 SSH(注释应该会在结束的位置显示: cardno:XXXXXXXX,表示它来自智能卡)。
|
||||
|
||||
为了启用 ssh 的基于密钥的登入,只需要在你要登入的远程系统上添加 `ssh-add -L` 的输出到 ~/.ssh/authorized_keys 中。祝贺你,这将使你的 SSH 登入凭据更难以窃取。
|
||||
|
||||
作为一个福利,你可以从公共密钥服务器上下载其它人的基于 PGP 的 ssh 公钥,这样就可以赋予他登入 ssh 的权利:
|
||||
```
|
||||
$ gpg --export-ssh-key [keyid]
|
||||
|
||||
```
|
||||
|
||||
如果你有让开发人员通过 ssh 来访问 git 仓库的需要,这将让你非常方便。下一篇文章,我们将提供像保护你的密钥那样保护电子邮件帐户的小技巧。
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.linux.com/blog/learn/pgp/2018/3/protecting-code-integrity-pgp-part-6-using-pgp-git
|
||||
|
||||
作者:[KONSTANTIN RYABITSEV][a]
|
||||
译者:[qhwdw](https://github.com/qhwdw)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]:https://www.linux.com/users/mricon
|
||||
[1]:https://www.linux.com/blog/learn/2018/2/protecting-code-integrity-pgp-part-1-basic-pgp-concepts-and-tools
|
||||
[2]:https://www.linux.com/blog/learn/pgp/2018/2/protecting-code-integrity-pgp-part-2-generating-and-protecting-your-master-pgp-key
|
||||
[3]:https://www.linux.com/blog/learn/pgp/2018/2/protecting-code-integrity-pgp-part-3-generating-pgp-subkeys
|
||||
[4]:https://www.linux.com/blog/learn/pgp/2018/3/protecting-code-integrity-pgp-part-4-moving-your-master-key-offline-storage
|
||||
[5]:https://www.linux.com/blog/learn/pgp/2018/3/protecting-code-integrity-pgp-part-5-moving-subkeys-hardware-device
|
||||
[6]:https://github.com/jayphelps/git-blame-someone-else
|
Loading…
Reference in New Issue
Block a user