安装完最小化 RHEL/CentOS 7 后需要做的 30 件事情（五）

Summary: 25. 安装 Linux Malware Detect (LMD) Linux Malware Detect (LMD) 是 GNU GPLv2 协议下发布的开源 Linux 恶意程序扫描器，它是特别为面临威胁的主机环境所设计的。LMD 完整的安装、配置以及使用方法可以查看：  安装 LMD 并和 ClamAV 一起使用作为反病毒引擎  26. 用 Speedtest-cli 测试服务器带宽 speedtest-cli 是用 python 写的用于测试网络下载和上传带宽的工具。关于 speedtest-cli 工具的完整安装和使用请阅读我们的文章用命令行查看 Linux 服务器带宽 27. 配置 Cron 任务 这是最广泛使用的软件工具之一。它是一个任务调度器，比如

man

![](/data/attachment/album/201504/27/151948jz881a61rj66up58.png)

### 25. 安装 Linux Malware Detect (LMD)

Linux Malware Detect (LMD) 是 GNU GPLv2 协议下发布的开源 Linux 恶意程序扫描器，它是特别为面临威胁的主机环境所设计的。LMD 完整的安装、配置以及使用方法可以查看：

* [安装 LMD 并和 ClamAV 一起使用作为反病毒引擎](/article-5156-1.html)

### 26. 用 Speedtest-cli 测试服务器带宽

speedtest-cli 是用 python 写的用于测试网络下载和上传带宽的工具。关于 speedtest-cli 工具的完整安装和使用请阅读我们的文章[用命令行查看 Linux 服务器带宽](/article-3796-1.html)

### 27. 配置 Cron 任务

这是最广泛使用的软件工具之一。它是一个任务调度器，比如，现在安排一个以后可以自动运行的作业。它用于未处理记录的日志和维护，以及其它日常工作，比如常规备份。所有的调度都写在文件 /etc/crontab 中。

crontab 文件包含下面的 6 个域：

```
    分          时                日期                      月份                  星期                  命令
(0-59)           (0-23)       (1-31)                (1/jan-12/dec)       (0-6/sun-sat)          Command/script

```

![Crontab 域](/data/attachment/album/201505/01/213208cde9gyzvi4d2u4bb.jpg)

*Crontab 域*

要在每天 04:30 运行一个 cron 任务（比如运行 /home/$USER/script.sh）。

```
分             时         日期              月份      星期                  命令
30              4             *              *       *            speedtest-cli

```

就把下面的条目增加到 crontab 文件 ‘/etc/crontab/’。

```
30  4  *  *  *  /home/$user/script.sh

```

把上面一行增加到 crontab 之后，它会在每天的 04:30 am 自动运行，输出取决于脚本文件的内容。另外脚本也可以用命令代替。关于更多 cron 任务的例子，可以阅读[Linux 上的 11 个 Cron 任务例子](http://www.tecmint.com/11-cron-scheduling-task-examples-in-linux/)

### 28. 安装 Owncloud

Owncloud 是一个基于 HTTP 的数据同步、文件共享和远程文件存储应用。更多关于安装 owncloud 的内容，你可以阅读这篇文章：[在 Linux 上创建个人/私有云存储](/article-2494-1.html)

### 29. 启用 Virtualbox 虚拟化

虚拟化是创建虚拟操作系统、硬件和网络的过程，是当今最热门的技术之一。我们会详细地讨论如何安装和配置虚拟化。

我们的最小化 CentOS 服务器是一个无用户界面服务器（LCTT 译注：无用户界面[headless]服务器指没有监视器和鼠标键盘等外设的服务器）。我们通过安装下面的软件包，让它可以托管虚拟机，虚拟机可通过 HTTP 访问。

```
# yum groupinstall 'Development Tools' SDL kernel-devel kernel-headers dkms

```

![安装开发工具](/data/attachment/album/201505/01/213209m7099nkjct0nz6e9.jpg)

*安装开发工具*

更改工作目录到 ‘/etc/yum.repos.d/’ 并下载 VirtualBox 库。

```
# wget -q http://download.virtualbox.org/virtualbox/debian/oracle_vbox.asc

```

安装刚下载的密钥。

```
# rpm --import oracle_vbox.asc

```

升级并安装 VirtualBox。

```
# yum update && yum install virtualbox-4.3

```

下一步，下载和安装 VirtualBox 扩展包。

```
# wget http://download.virtualbox.org/virtualbox/4.3.12/Oracle_VM_VirtualBox_Extension_Pack-4.3.12-93733.vbox-extpack
# VBoxManage extpack install Oracle_VM_VirtualBox_Extension_Pack-4.3.12-93733.vbox-extpack

```

![安装 VirtualBox 扩展包](/data/attachment/album/201505/01/213209tyzktii28f6yctf4.jpg)

*安装 VirtualBox 扩展包*

![正在安装 VirtualBox 扩展包](/data/attachment/album/201505/01/213210psah3lndk1aqnqdd.jpg)

*正在安装 VirtualBox 扩展包*

添加用户 ‘vbox’ 用于管理 VirtualBox 并把它添加到组 vboxusers 中。

```
# adduser vbox
# passwd vobx
# usermod -G vboxusers vbox

```

安装 HTTPD 服务器。

```
# yum install httpd

```

安装 PHP （支持 soap 扩展）。

```
# yum install php php-devel php-common php-soap php-gd

```

下载 phpVirtualBox（一个 PHP 写的开源的 VirtualBox 用户界面）。

```
# wget http://sourceforge.net/projects/phpvirtualbox/files/phpvirtualbox-4.3-1.zip

```

解压 zip 文件并把解压后的文件夹复制到 HTTP 工作目录。

```
# unzip phpvirtualbox-4.*.zip
# cp phpvirtualbox-4.3-1 -R /var/www/html

```

下一步，重命名文件 /var/www/html/phpvirtualbox/config.php-example 为 var/www/html/phpvirtualbox/config.php。

```
# mv config.php.example config.php

```

打开配置文件并添加我们上一步创建的 ‘username ’ 和 ‘password’。

```
# vi config.php

```

最后，重启 VirtualBox 和 HTTP 服务器。

```
# service vbox-service restart
# service httpd restart

```

转发端口并从一个有用户界面的服务器上访问它。

```
http://192.168.0.15/phpvirtualbox-4.3-1/

```

![登录 PHP Virtualbox](/data/attachment/album/201505/01/213211j8eezv6d0znsc6e8.png)

*登录 PHP Virtualbox*

![PHP Virtualbox 面板](/data/attachment/album/201505/01/213212jbvsj8kjjahc7sha.png)

*PHP Virtualbox 面板*

---

via: <http://www.tecmint.com/things-to-do-after-minimal-rhel-centos-7-installation/5/>

作者：[Avishek Kumar](http://www.tecmint.com/author/avishek/) 译者：[ictlyh](https://github.com/ictlyh) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译，[Linux中国](http://linux.cn/) 荣誉推出


安装完最小化 RHEL/CentOS 7 后需要做的 30 件事情（六）

Summary: 30. 用密码保护 GRUB 用密码保护你的 boot 引导程序这样你就可以在启动时获得额外的安全保障。同时你也可以在实物层面获得保护。通过在引导时给 GRUB 加锁防止任何无授权访问来保护你的服务器。 首先备份两个文件，这样如果有任何错误出现，你可以有回滚的选择。备份 /etc/grub2/grub.cfg 为 /etc/grub2/grub.cfg.old。 # cp /boot/grub2/grub.cfg /boot/grub2/grub.cfg.old  同样，备份 /etc/grub.d/10_linux 为 /etc/grub.d/10_linux.old。 # cp /etc/grub.d/10_linux /etc/grub.d/10_linux.old  打开文件 /etc/grub.d/10_linux 并在文

不错，为您点赞！：）

![](/data/attachment/album/201504/27/151948jz881a61rj66up58.png)

### 30. 用密码保护 GRUB

用密码保护你的 boot 引导程序这样你就可以在启动时获得额外的安全保障。同时你也可以在实物层面获得保护。通过在引导时给 GRUB 加锁防止任何无授权访问来保护你的服务器。

首先备份两个文件，这样如果有任何错误出现，你可以有回滚的选择。备份 ‘/etc/grub2/grub.cfg’ 为 ‘/etc/grub2/grub.cfg.old’。

```
# cp /boot/grub2/grub.cfg /boot/grub2/grub.cfg.old

```

同样，备份 ‘/etc/grub.d/10\_linux’ 为 ‘/etc/grub.d/10\_linux.old’。

```
# cp /etc/grub.d/10_linux /etc/grub.d/10_linux.old

```

打开文件 ‘/etc/grub.d/10\_linux’ 并在文件末尾添加下列行。

```
cat <<EOF
set superusers="tecmint"
Password tecmint avi@123
EOF

```

![密码保护 Grub](/data/attachment/album/201505/01/214424j1sohzccl1qc0u6c.png)

*密码保护 Grub*

注意在上面的文件中，用你自己的用户名和密码代替 “tecmint” 和 “avi@123”。

现在通过运行下面的命令生成新的 grub.cfg 文件。

```
# grub2-mkconfig --output=/boot/grub2/grub.cfg

```

![生成 Grub 文件](/data/attachment/album/201505/01/214425ibzzdpi8jzi8z6xh.jpg)

*生成 Grub 文件*

创建 grub.cfg 文件之后，重启机器并敲击 ‘e’ 进入编辑。你会发现它会要求你输入 “有效验证” 来编辑 boot 菜单。

![有密码保护的 Boot 菜单](/data/attachment/album/201505/01/214426d5v50aatm52m90a8.jpg)

*有密码保护的 Boot 菜单*

输入登录验证之后，你就可以编辑 grub boot 菜单。

![Grub 菜单文件](/data/attachment/album/201505/01/214426qz7g45m5qbsm545m.jpg)

*Grub 菜单文件*

你也可以用加密的密码代替上一步的明文密码。首先按照下面推荐的生成加密密码。

```
# grub2-mkpasswd-pbkdf2

[两次输入密码]

```

![生成加密的 Grub 密码](/data/attachment/album/201505/01/214426hxzf2xtn5vtcutrj.jpg)

*生成加密的 Grub 密码*

打开 ‘/etc/grub.d/10\_linux’ 文件并在文件末尾添加下列行。

```
cat <<EOF
set superusers=”tecmint”
Password_pbkdf2 tecmint
grub.pbkdf2.sha512...你的加密密码...
EOF

```

![加密 Grub 密码](/data/attachment/album/201505/01/214427yb1eacw6zet7505b.jpg)

*加密 Grub 密码*

用你系统上生成的密码代替原来的密码，别忘了交叉检查密码。

同样注意在这种情况下你也需要像上面那样生成 grub.cfg。重启并敲击 ‘e’ 进入编辑，会提示你输入用户名和密码。

我们已经介绍了大部分工业标准发行版 RHEL 7 和 CentOS 7 安装后必要的操作。如果你发现我们缺少了一些点或者你有新的东西可以扩充这篇文章，你可以和我们一起分享，我们会通过扩充在这篇文章中包括你的分享。

---

via: <http://www.tecmint.com/things-to-do-after-minimal-rhel-centos-7-installation/6/>

作者：[vishek Kumar](http://www.tecmint.com/author/avishek/) 译者：[ictlyh](https://github.com/ictlyh) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译，[Linux中国](http://linux.cn/) 荣誉推出


Linux 的 ‘sort’命令的14个有用的范例（一）

Summary: Sort是用于对单个或多个文本文件内容进行排序的Linux程序。Sort命令以空格作为字段分隔符，将一行分割为多个关键字对文件进行排序。需要注意的是除非你将输出重定向到文件中，否则Sort命令并不对文件内容进行实际的排序(即文件内容没有修改)，只是将文件内容按有序输出。 本文的目标是通过14个实际的范例让你更深刻的理解如何在Linux中使用sort命令。  1、 首先我们将会创建一个用于执行sort命令的文本文件（tecmint.txt）。工作路径是/home/$USER/Desktop/tecmint。 下面命令中的-e选项将启用\转义，将\n解析成换行 $ echo -e "computer\

不错，一步步的跟着学，基本掌握了

这篇总结的很好，感觉很受益

我就想知道他用啥软件做的gif

Sort是用于对单个或多个文本文件内容进行排序的Linux程序。Sort命令以空格作为字段分隔符，将一行分割为多个关键字对文件进行排序。需要注意的是除非你将输出重定向到文件中，否则Sort命令并不对文件内容进行实际的排序(即文件内容没有修改)，只是将文件内容按有序输出。

本文的目标是通过14个实际的范例让你更深刻的理解如何在Linux中使用sort命令。

![](/data/attachment/album/201505/02/102959wecogvuagsouuvke.png)

1、 首先我们将会创建一个用于执行‘sort’命令的文本文件（tecmint.txt）。工作路径是‘/home/$USER/Desktop/tecmint’。

下面命令中的‘-e’选项将启用‘\’转义，将‘\n’解析成换行

```
$ echo -e "computer\nmouse\nLAPTOP\ndata\nRedHat\nlaptop\ndebian\nlaptop" > tecmint.txt

```

![Split String by Lines in Linux](/data/attachment/album/201505/02/103000tnniqv6iacq9idcs.gif)

2、 在开始学习‘sort’命令前，我们先看看文件的内容及其显示方式。

```
$ cat tecmint.txt

```

![Check Content of File](/data/attachment/album/201505/02/103001ixwoe5bxo7c02yd7.gif)

3、 现在，使用如下命令对文件内容进行排序。

```
$ sort tecmint.txt

```

![Sort Content of File linux](/data/attachment/album/201505/02/103001jcvj8wjxr98frrxc.gif)

**注意**：上面的命令并不对文件内容进行实际的排序，仅仅是将其内容按有序方式输出。

4、 对文件‘tecmint.txt’文件内容排序，并将排序后的内容输出到名为sorted.txt的文件中，然后使用[cat](http://www.tecmint.com/13-basic-cat-command-examples-in-linux/)命令查看验证sorted.txt文件的内容。

```
$ sort tecmint.txt > sorted.txt
$ cat sorted.txt

```

![Sort File Content in Linux](/data/attachment/album/201505/02/103002ygup2aa2cf8825s8.gif)

5、 现在使用‘-r’参数对‘tecmint.txt’文件内容进行逆序排序，并将输出内容重定向到‘reversesorted.txt’文件中，并使用cat命令查看文件的内容。

```
$ sort -r tecmint.txt > reversesorted.txt
$ cat reversesorted.txt

```

![Sort Content By Reverse](/data/attachment/album/201505/02/103002qui6h2l5kjv6lt6h.gif)

6、 创建一个新文件（lsl.txt），文件内容为在home目录下执行‘ls -l’命令的输出。

```
$ ls -l /home/$USER > /home/$USER/Desktop/tecmint/lsl.txt
$ cat lsl.txt

```

![Populate Output of Home Directory](/data/attachment/album/201505/02/103003msmc9vddiddd11j8.gif)

我们将会看到对其他字段进行排序的例子，而不是对默认的开始字符进行排序。

7、 基于第二列（符号连接的数量）对文件‘lsl.txt’进行排序。

```
$ sort -nk2 lsl.txt

```

**注意**：上面例子中的‘-n’参数表示对数值内容进行排序。当想基于文件中的数值列对文件进行排序时，必须要使用‘-n’参数。

![Sort Content by Column](/data/attachment/album/201505/02/103004z1w41zi199c14di1.gif)

8、 基于第9列（文件和目录的名称，非数值）对文件‘lsl.txt’进行排序。

```
$ sort -k9 lsl.txt

```

![Sort Content Based on Column](/data/attachment/album/201505/02/103004kmzcc27e2j2t5ebo.gif)

9、 sort命令并非仅能对文件进行排序，我们还可以通过管道将命令的输出内容重定向到sort命令中。

```
$ ls -l /home/$USER | sort -nk5

```

![Sort Content Using Pipe Option](/data/attachment/album/201505/02/103004eyddtpyl1hmxhlyw.gif)

10、 对文件tecmint.txt进行排序，并删除重复的行。然后检查重复的行是否已经删除了。

```
$ cat tecmint.txt
$ sort -u tecmint.txt

```

![Sort and Remove Duplicates](/data/attachment/album/201505/02/103005ycyurzuyv3rd3khv.gif)

目前我们发现的排序规则：

除非指定了‘-r’参数，否则排序的优先级按下面规则排序

* 以数字开头的行优先级最高
* 以小写字母开头的行优先级次之
* 待排序内容按字典序进行排序
* 默认情况下，‘sort’命令将带排序内容的每行关键字当作一个字符串进行字典序排序（数字优先级最高，参看规则 1）

11、 在当前位置创建第三个文件‘lsla.txt’，其内容用‘ls -lA’命令的输出内容填充。

```
$ ls -lA /home/$USER > /home/$USER/Desktop/tecmint/lsla.txt
$ cat lsla.txt

```

![Populate Output With Hidden Files](/data/attachment/album/201505/02/103005hs7dnaduxs7stwbe.gif)

了解ls命令的读者都知道‘ls -lA’ 等于 ‘ls -l’ + 隐藏文件，所以这两个文件的大部分内容都是相同的。

12、 对上面两个文件内容进行排序输出。

```
$ sort lsl.txt lsla.txt

```

![Sort Contents of Two Files](/data/attachment/album/201505/02/103007d6fishsnp6pu63o4.gif)

注意文件和目录的重复

13、 现在我们看看怎样对两个文件进行排序、合并，并且删除重复行。

```
$ sort -u lsl.txt lsla.txt

```

![Sort, Merge and Remove Duplicates from File](/data/attachment/album/201505/02/103010j55g5ngudged89a7.gif)

此时，我们注意到重复的行已经被删除了，我们可以将输出内容重定向到文件中。

14、 我们同样可以基于多列对文件内容进行排序。基于第2,5（数值）和9（非数值）列对‘ls -l’命令的输出进行排序。

```
$ ls -l /home/$USER | sort -t "," -nk2,5 -k9

```

![Sort Content By Field Column](/data/attachment/album/201505/02/103011h787ezzjxvh97eve.gif)

先到此为止了，在接下来的文章中我们将会学习到‘sort’命令更多的详细例子。届时敬请关注我们。保持分享精神。若喜欢本文，敬请将本文分享给你的朋友。

---

via: <http://www.tecmint.com/sort-command-linux/>

作者：[Avishek Kumar](http://www.tecmint.com/author/avishek/) 译者：[cvsher](https://github.com/cvsher) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译，[Linux中国](http://linux.cn/) 荣誉推出


Linux 的 'sort'命令的七个有趣实例（二）

Summary: 在上一篇文章里，我们已经探讨了关于sort命令的多个例子，如果你错过了这篇文章，可以点击下面的链接进行阅读。今天的这篇文章作为上一篇文章的继续，将讨论关于sort命令的剩余用法，与上一篇一起作为Linux sort命令的完整指南。  Linux 的 sort命令的14个有用的范例（一）   在我们继续深入之前，先创建一个文本文档month.txt，并且将上一次给出的数据填进去。 $ echo -e "mar\ndec\noct\nsep\nfeb\naug"  month.txt $ cat month.txt   15、 通过使用M选项，对month.txt文件按照月份顺序进行排序。 $ sort -M month.txt  注意:sort命令需

不错！

请问您的这个 gif 动画使用什么软件制作的?

在[上一篇文章](http://www.tecmint.com/sort-command-linux/)里，我们已经探讨了关于sort命令的多个例子，如果你错过了这篇文章，可以点击下面的链接进行阅读。今天的这篇文章作为上一篇文章的继续，将讨论关于sort命令的剩余用法，与上一篇一起作为Linux ‘sort’命令的完整指南。

* [Linux 的 ‘sort’命令的14个有用的范例（一）](http://www.tecmint.com/sort-command-linux/)

![](/data/attachment/album/201505/02/102959wecogvuagsouuvke.png)

在我们继续深入之前，先创建一个文本文档‘month.txt’，并且将上一次给出的数据填进去。

```
$ echo -e "mar\ndec\noct\nsep\nfeb\naug" > month.txt
$ cat month.txt

```

![Populate Content](/data/attachment/album/201505/02/105700klkfmvv0flbsskf6.gif)

15、 通过使用’M‘选项，对’month.txt‘文件按照月份顺序进行排序。

```
$ sort -M month.txt

```

**注意**:‘sort’命令需要至少3个字符来确认月份名称。

![Sort File Content by Month in Linux](/data/attachment/album/201505/02/105701p2wxy026s0z023to.gif)

16、 把数据整理成方便人们阅读的形式，比如1K、2M、3G、2T，这里面的K、G、M、T代表千、兆、吉、梯。 （LCTT 译注：此处命令有误，ls 命令应该增加 -h 参数，径改之）

```
$ ls -lh /home/$USER | sort -h -k5

```

![Sort Content Human Readable Format](/data/attachment/album/201505/02/105701wxxuatq5zu9qtzmk.gif)

17、 在上一篇文章中，我们在例子4中创建了一个名为‘sorted.txt’的文件，在例子6中创建了一个‘lsl.txt’。‘sorted.txt'已经排好序了而’lsl.txt‘还没有。让我们使用sort命令来检查两个文件是否已经排好序。

```
$ sort -c sorted.txt

```

![Check File is Sorted](/data/attachment/album/201505/02/105702lsqqcyrsncwcffqj.gif)

如果它返回0，则表示文件已经排好序。

```
$ sort -c lsl.txt

```

![Check File Sorted Status](/data/attachment/album/201505/02/105702gyahwzs46p5s21a2.gif)

报告无序。存在矛盾……

18、 如果文字之间的分隔符是空格，sort命令自动地将空格后的东西当做一个新文字单元，如果分隔符不是空格呢？

考虑这样一个文本文件，里面的内容可以由除了空格之外的任何符号分隔，比如‘|’，‘\’，‘+’，‘.’等……

创建一个分隔符为+的文本文件。使用‘cat‘命令查看文件内容。

```
$ echo -e "21+linux+server+production\n11+debian+RedHat+CentOS\n131+Apache+Mysql+PHP\n7+Shell Scripting+python+perl\n111+postfix+exim+sendmail" > delimiter.txt

```

---

```
$ cat delimiter.txt

```

![Check File Content by Delimiter](/data/attachment/album/201505/02/105702uxrgssqxvglzlstn.gif)

现在基于由数字组成的第一个域来进行排序。

```
$ sort -t '+' -nk1 delimiter.txt

```

![Sort File By Fields](/data/attachment/album/201505/02/105703mnrarjnx7nddwnb0.gif)

然后再基于非数字的第四个域排序。

![Sort Content By Non Numeric](/data/attachment/album/201505/02/105703nxjyhizvvx8j5nxk.gif)

如果分隔符是制表符，你需要在’+‘的位置上用$’\t’代替，如上例所示。

19、 对主用户目录下使用‘ls -l’命令得到的结果基于第五列（‘文件大小’）进行一个乱序排列。

```
$ ls -l /home/avi/ | sort -k5 -R

```

![Sort Content by Column in Random Order](/data/attachment/album/201505/02/105704pw69nw6hwhcwavww.gif)

每一次你运行上面的脚本，你得到结果可能都不一样，因为结果是随机生成的。

正如我在上一篇文章中提到的规则2所说——sort命令会将以小写字母开始的行排在大写字母开始的行前面。看一下上一篇文章的例3，字符串‘laptop’在‘LAPTOP’前出现。

20、 如何覆盖默认的排序优先权？在这之前我们需要先将环境变量LC\_ALL的值设置为C。在命令行提示栏中运行下面的代码。

```
$ export LC_ALL=C

```

然后以非默认优先权的方式对‘tecmint.txt’文件重新排序。

```
$ sort tecmint.txt

```

![Override Sorting Preferences](/data/attachment/album/201505/02/105706occ4t7a7h4m999m9.gif)

*覆盖排序优先权*

不要忘记与example 3中得到的输出结果做比较，并且你可以使用‘-f’，又叫‘-ignore-case’（忽略大小写）的选项来获取更有序的输出。

```
$ sort -f tecmint.txt

```

![Compare Sorting Preferences](/data/attachment/album/201505/02/105706sn54r2dspz2nbr2v.gif)

21、 给两个输入文件进行‘sort‘，然后把它们连接成一行！

我们创建两个文本文档’file1.txt‘以及’file2.txt‘，并用数据填充，如下所示，并用’cat‘命令查看文件的内容。

```
$ echo -e “5 Reliable\n2 Fast\n3 Secure\n1 open-source\n4 customizable” > file1.txt
$ cat file1.txt

```

![Populate Content with Numbers](/data/attachment/album/201505/02/105707j38vk01w78yt0g00.gif)

用如下数据填充’file2.txt‘。

```
$ echo -e “3 RedHat\n1 Debian\n5 Ubuntu\n2 Kali\n4 Fedora” > file2.txt
$ cat file2.txt

```

![Populate File with Data](/data/attachment/album/201505/02/105707drz8fbflwl50enze.gif)

现在我们对两个文件进行排序并连接。

```
$ join <(sort -n file1.txt) <(sort file2.txt)

```

![Sort Join Two Files](/data/attachment/album/201505/02/105708uumm00x22i5z2k07.gif)

我所要讲的全部内容就在这里了，希望与各位保持联系，也希望各位经常来逛逛。有反馈就在下面评论吧。

---

via: <http://www.tecmint.com/linux-sort-command-examples/>

作者：[Avishek Kumar](http://www.tecmint.com/author/avishek/) 译者：[DongShuaike](https://github.com/DongShuaike) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译，[Linux中国](http://linux.cn/) 荣誉推出


增强 nginx 的 SSL 安全性

Summary: 本文向你介绍如何在 nginx 服务器上设置健壮的 SSL 安全机制。我们通过禁用 SSL 压缩来降低 CRIME 攻击威胁；禁用协议上存在安全缺陷的 SSLv3 及更低版本，并设置更健壮的加密套件（cipher suite）来尽可能启用前向安全性（Forward Secrecy）；此外，我们还启用了 HSTS 和 HPKP。这样我们就拥有了一个健壮而可经受考验的 SSL 配置，并可以在 Qually Labs 的 SSL 测试中得到 A 级评分。 如果不求甚解的话，可以从 https://cipherli.st 上找到 nginx 、Apache 和 Lighttpd 的安全设置，复制粘帖即可。 本教程在 Digital Ocean 的 VPS 上测试

我在看这篇文章的同时，在Qually Labs 的 SSL 测试了贵站，发现评级为F级，

存在"This server is vulnerable to the OpenSSL Padding Oracle vulnerability (CVE-2016-2107) and insecure. "

And Grade set to F.

额！

谢谢，满血复活！

友情提示：

从 Chrome 68 开始弃用 HPKP，在 Chrome 72 正式移除 HPKP。

所以不用配置这玩意了。

[![](/data/attachment/album/201505/03/180656c9rra95g25gghdg5.png)](https://www.ssllabs.com/ssltest/analyze.html?d=raymii.org)

本文向你介绍如何在 nginx 服务器上设置健壮的 SSL 安全机制。我们通过禁用 SSL 压缩来降低 CRIME 攻击威胁；禁用协议上存在安全缺陷的 SSLv3 及更低版本，并设置更健壮的<ruby> 加密套件 <rp>  （ </rp> <rt>  cipher suite </rt> <rp>  ） </rp></ruby>来尽可能启用<ruby> 前向安全性 <rp>  （ </rp> <rt>  Forward Secrecy </rt> <rp>  ） </rp></ruby>；此外，我们还启用了 HSTS 和 HPKP。这样我们就拥有了一个健壮而可经受考验的 SSL 配置，并可以在 Qually Labs 的 SSL 测试中得到 A 级评分。

如果不求甚解的话，可以从 [https://cipherli.st](https://cipherli.st/) 上找到 nginx 、Apache 和 Lighttpd 的安全设置，复制粘帖即可。

本教程在 Digital Ocean 的 VPS 上测试通过。如果你喜欢这篇教程，想要支持作者的站点的话，购买 Digital Ocean 的 VPS 时请使用如下链接：<https://www.digitalocean.com/?refcode=7435ae6b8212> 。

本教程可以通过[发布于 2014/1/21 的](http://blog.ivanristic.com/2014/01/ssl-labs-stricter-security-requirements-for-2014.html) SSL 实验室测试的严格要求（我之前就通过了测试，如果你按照本文操作就可以得到一个 A+ 评分）。

* [本教程也可用于 Apache](https://raymii.org/s/tutorials/Strong_SSL_Security_On_Apache2.html)
* [本教程也可用于 Lighttpd](https://raymii.org/s/tutorials/Pass_the_SSL_Labs_Test_on_Lighttpd_%28Mitigate_the_CRIME_and_BEAST_attack_-_Disable_SSLv2_-_Enable_PFS%29.html)
* [本教程也可用于 FreeBSD, NetBSD 和 OpenBSD 上的 nginx ，放在 BSD Now 播客上](http://www.bsdnow.tv/episodes/2014_08_20-engineering_nginx): <http://www.bsdnow.tv/tutorials/nginx>

你可以从下列链接中找到这方面的进一步内容：

* [野兽攻击（BEAST）](https://en.wikipedia.org/wiki/Transport_Layer_Security#BEAST_attack)
* [罪恶攻击（CRIME）](https://en.wikipedia.org/wiki/CRIME_%28security_exploit%29)
* [怪物攻击（FREAK ）](http://blog.cryptographyengineering.com/2015/03/attack-of-week-freak-or-factoring-nsa.html)
* [心血漏洞（Heartbleed）](http://heartbleed.com/)
* [完备的前向安全性（Perfect Forward Secrecy）](https://en.wikipedia.org/wiki/Perfect_forward_secrecy)
* [RC4 和 BEAST 的处理](https://en.wikipedia.org/wiki/Transport_Layer_Security#Dealing_with_RC4_and_BEAST)

我们需要编辑 nginx 的配置，在 Ubuntu/Debian 上是 `/etc/nginx/sited-enabled/yoursite.com`，在 RHEL/CentOS 上是 `/etc/nginx/conf.d/nginx.conf`。

本文中，我们需要编辑443端口（SSL）的 `server` 配置中的部分。在文末你可以看到完整的配置例子。

*在编辑之前切记备份一下配置文件！*

### 野兽攻击（BEAST）和 RC4

简单的说，<ruby> 野兽攻击 <rp>  （ </rp> <rt>  BEAST </rt> <rp>  ） </rp></ruby>就是通过篡改一个加密算法的 <ruby> 密码块链 <rp>  （ </rp> <rt>  CBC，cipher block chaining </rt> <rp>  ） </rp></ruby>的模式，从而可以对部分编码流量悄悄解码。更多信息参照上面的链接。

针对<ruby> 野兽攻击 <rp>  （ </rp> <rt>  BEAST </rt> <rp>  ） </rp></ruby>，较新的浏览器已经启用了客户端缓解方案。推荐方案是禁用 TLS 1.0 的所有加密算法，仅允许 RC4 算法。然而，[针对 RC4 算法的攻击也越来越多](http://www.isg.rhul.ac.uk/tls/) ，很多已经从理论上逐步发展为实际可行的攻击方式。此外，有理由相信 NSA 已经实现了他们所谓的“大突破”——攻破 RC4 。

禁用 RC4 会有几个后果。其一，当用户使用老旧的浏览器时，比如 Windows XP 上的 IE 会用 3DES 来替代 RC4。3DES 要比 RC4 更安全，但是它的计算成本更高，你的服务器就需要为这些用户付出更多的处理成本。其二，RC4 算法能减轻<ruby> 野兽攻击 <rp>  （ </rp> <rt>  BEAST </rt> <rp>  ） </rp></ruby>的危害，如果禁用 RC4 会导致 TLS 1.0 用户会换到更容易受攻击的 AES-CBC 算法上（通常服务器端的对<ruby> 野兽攻击 <rp>  （ </rp> <rt>  BEAST </rt> <rp>  ） </rp></ruby>的“修复方法”是让 RC4 优先于其它算法）。我认为 RC4 的风险要高于<ruby> 野兽攻击 <rp>  （ </rp> <rt>  BEAST </rt> <rp>  ） </rp></ruby>的风险。事实上，有了客户端缓解方案（Chrome 和 Firefox 提供了缓解方案），<ruby> 野兽攻击 <rp>  （ </rp> <rt>  BEAST </rt> <rp>  ） </rp></ruby>就不是什么大问题了。而 RC4 的风险却在增长：随着时间推移，对加密算法的破解会越来越多。

### 怪物攻击（FREAK）

<ruby> 怪物攻击 <rp>  （ </rp> <rt>  FREAK </rt> <rp>  ） </rp></ruby>是一种中间人攻击，它是由来自 [INRIA、微软研究院和 IMDEA](https://www.smacktls.com/) 的密码学家们所发现的。<ruby> 怪物攻击 <rp>  （ </rp> <rt>  FREAK </rt> <rp>  ） </rp></ruby>的缩写来自“<ruby> RSA 出口密钥因子分解 <rp>  （ </rp> <rt>  Factoring RSA-EXPORT Keys </rt> <rp>  ） </rp></ruby>”

这个漏洞可上溯到上世纪九十年代，当时美国政府禁止出口加密软件，除非其使用编码密钥长度不超过512位的出口加密套件。

这造成了一些现在的 TLS 客户端存在一个缺陷，这些客户端包括： 苹果的 SecureTransport 、OpenSSL。这个缺陷会导致它们会接受出口降级 RSA 密钥，即便客户端并没有要求使用出口降级 RSA 密钥。这个缺陷带来的影响很讨厌：在客户端存在缺陷，且服务器支持出口降级 RSA 密钥时，会发生中间人攻击，从而导致连接的强度降低。

攻击分为两个组成部分：首先是服务器必须接受“<ruby> 出口降级 RSA 密钥 <rp>  （ </rp> <rt>  export grade RSA </rt> <rp>  ） </rp></ruby>”。

中间人攻击可以按如下流程：

* 在客户端的 Hello 消息中，要求标准的 RSA 加密套件。
* 中间人攻击者修改该消息为<ruby> ‘输出级 RSA 密钥’ <rp>  （ </rp> <rt>  export RSA </rt> <rp>  ） </rp></ruby>。
* 服务器回应一个512位的输出级 RSA 密钥，并以其长期密钥签名。
* 由于 OpenSSL/SecureTransport 的缺陷，客户端会接受这个弱密钥。
* 攻击者根据 RSA 模数分解因子来恢复相应的 RSA 解密密钥。
* 当客户端编码<ruby> ‘预主密码’ <rp>  （ </rp> <rt>  pre-master secret </rt> <rp>  ） </rp></ruby>给服务器时，攻击者现在就可以解码它并恢复 TLS 的<ruby> ‘主密码’ <rp>  （ </rp> <rt>  master secret </rt> <rp>  ） </rp></ruby>。
* 从这里开始，攻击者就能看到了传输的明文并注入任何东西了。

本文所提供的加密套件不启用输出降级加密，请确认你的 OpenSSL 是最新的，也强烈建议你将客户端也升级到新的版本。

### 心血漏洞（Heartbleed）

<ruby> 心血漏洞 <rp>  （ </rp> <rt>  Heartbleed </rt> <rp>  ） </rp></ruby> 是一个于2014年4月公布的 OpenSSL 加密库的漏洞，它是一个被广泛使用的传输层安全（TLS）协议的实现。无论是服务器端还是客户端在 TLS 中使用了有缺陷的 OpenSSL，都可以被利用该缺陷。由于它是因 DTLS 心跳扩展（RFC 6520）中的输入验证不正确（缺少了边界检查）而导致的，所以该漏洞根据“心跳”而命名。这个漏洞是一种缓存区超读漏洞，它可以读取到本不应该读取的数据。

哪个版本的 OpenSSL 受到<ruby> 心血漏洞 <rp>  （ </rp> <rt>  Heartbleed </rt> <rp>  ） </rp></ruby>的影响？

各版本情况如下：

* OpenSSL 1.0.1 直到 1.0.1f （包括）**存在**该缺陷
* OpenSSL 1.0.1g **没有**该缺陷
* OpenSSL 1.0.0 分支**没有**该缺陷
* OpenSSL 0.9.8 分支**没有**该缺陷

这个缺陷是2011年12月引入到 OpenSSL 中的，并随着 2012年3月14日 OpenSSL 发布的 1.0.1 而泛滥。2014年4月7日发布的 OpenSSL 1.0.1g 修复了该漏洞。

升级你的 OpenSSL 就可以避免该缺陷。

### SSL 压缩（罪恶攻击 CRIME）

<ruby> 罪恶攻击 <rp>  （ </rp> <rt>  CRIME </rt> <rp>  ） </rp></ruby>使用 SSL 压缩来完成它的魔法，SSL 压缩在下述版本是默认关闭的： nginx 1.1.6及更高/1.0.9及更高（如果使用了 OpenSSL 1.0.0及更高）， nginx 1.3.2及更高/1.2.2及更高（如果使用较旧版本的 OpenSSL）。

如果你使用一个早期版本的 nginx 或 OpenSSL，而且你的发行版没有向后移植该选项，那么你需要重新编译没有一个 ZLIB 支持的 OpenSSL。这会禁止 OpenSSL 使用 DEFLATE 压缩方式。如果你禁用了这个，你仍然可以使用常规的 HTML DEFLATE 压缩。

### SSLv2 和 SSLv3

SSLv2 是不安全的，所以我们需要禁用它。我们也禁用 SSLv3，因为 TLS 1.0 在遭受到降级攻击时，会允许攻击者强制连接使用 SSLv3，从而禁用了<ruby> 前向安全性 <rp>  （ </rp> <rt>  forward secrecy </rt> <rp>  ） </rp></ruby>。

如下编辑配置文件：

```
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

```

### 卷毛狗攻击（POODLE）和 TLS-FALLBACK-SCSV

SSLv3 会受到[卷毛狗漏洞（POODLE）](https://raymii.org/s/articles/Check_servers_for_the_Poodle_bug.html)的攻击。这是禁用 SSLv3 的主要原因之一。

Google 提出了一个名为 [TLS\_FALLBACK\_SCSV](https://tools.ietf.org/html/draft-ietf-tls-downgrade-scsv-00) 的SSL/TLS 扩展，它用于防止强制 SSL 降级。如果你升级 到下述的 OpenSSL 版本会自动启用它。

* OpenSSL 1.0.1 带有 TLS\_FALLBACK\_SCSV 1.0.1j 及更高。
* OpenSSL 1.0.0 带有 TLS\_FALLBACK\_SCSV 1.0.0o 及更高。
* OpenSSL 0.9.8 带有 TLS\_FALLBACK\_SCSV 0.9.8zc 及更高。

[更多信息请参照 NGINX 文档](http://wiki.nginx.org/HttpSslModule#ssl_protocols)。

### 加密套件（cipher suite）

<ruby> 前向安全性 <rp>  （ </rp> <rt>  Forward Secrecy </rt> <rp>  ） </rp></ruby>用于在长期密钥被破解时确保会话密钥的完整性。<ruby> 完备的前向安全性 <rp>  （ </rp> <rt>  PFS，Perfect Forward Secrecy </rt> <rp>  ） </rp></ruby>是指强制在每个/每次会话中推导新的密钥。

这就是说，泄露的私钥并不能用来解密（之前）记录下来的 SSL 通讯。

提供<ruby> 完备的前向安全性 <rp>  （ </rp> <rt>  PFS，Perfect Forward Secrecy </rt> <rp>  ） </rp></ruby>功能的是那些使用了一种 Diffie-Hellman 密钥交换的短暂形式的加密套件。它们的缺点是系统开销较大，不过可以使用椭圆曲线的变体来改进。

以下两个加密套件是我推荐的，之后[Mozilla 基金会](https://wiki.mozilla.org/Security/Server_Side_TLS)也推荐了。

推荐的加密套件：

```
ssl_ciphers 'AES128+EECDH:AES128+EDH';

```

向后兼容的推荐的加密套件（IE6/WinXP）：

```
ssl_ciphers "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";

```

如果你的 OpenSSL 版本比较旧，不可用的加密算法会自动丢弃。应该一直使用上述的完整套件，让 OpenSSL 选择一个它所支持的。

加密套件的顺序是非常重要的，因为其决定了优先选择哪个算法。上述优先推荐的算法中提供了PFS（完备的前向安全性）。

较旧版本的 OpenSSL 也许不能支持这个算法的完整列表，AES-GCM 和一些 ECDHE 算法是相当新的，在 Ubuntu 和 RHEL 中所带的绝大多数 OpenSSL 版本中不支持。

#### 优先顺序的逻辑

* ECDHE+AESGCM 加密是首选的。它们是 TLS 1.2 加密算法，现在还没有广泛支持。当前还没有对它们的已知攻击。
* PFS 加密套件好一些，首选 ECDHE，然后是 DHE。
* AES 128 要好于 AES 256。有一个关于 AES256 带来的安全提升程度是否值回成本的[讨论](http://www.mail-archive.com/dev-tech-crypto@lists.mozilla.org/msg11247.html)，结果是显而易见的。目前，AES128 要更值一些，因为它提供了不错的安全水准，确实很快，而且看起来对时序攻击更有抵抗力。
* 在向后兼容的加密套件里面，AES 要优于 3DES。在 TLS 1.1及其以上，减轻了针对 AES 的<ruby> 野兽攻击 <rp>  （ </rp> <rt>  BEAST </rt> <rp>  ） </rp></ruby>的威胁，而在 TLS 1.0上则难以实现该攻击。在非向后兼容的加密套件里面，不支持 3DES。
* RC4 整个不支持了。3DES 用于向后兼容。参看 [#RC4\_weaknesses](https://wiki.mozilla.org/Security/Server_Side_TLS#RC4_weaknesses) 中的讨论。

#### 强制丢弃的算法

* aNULL 包含了非验证的 Diffie-Hellman 密钥交换，这会受到<ruby> 中间人 <rp>  （ </rp> <rt>  MITM </rt> <rp>  ） </rp></ruby>攻击
* eNULL 包含了无加密的算法（明文）
* EXPORT 是老旧的弱加密算法，是被美国法律标示为可出口的
* RC4 包含的加密算法使用了已弃用的 ARCFOUR 算法
* DES 包含的加密算法使用了弃用的数据加密标准（DES）
* SSLv2 包含了定义在旧版本 SSL 标准中的所有算法，现已弃用
* MD5 包含了使用已弃用的 MD5 作为哈希算法的所有算法

### 更多设置

确保你也添加了如下行：

```
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;

```

在一个 SSLv3 或 TLSv1 握手过程中选择一个加密算法时，一般使用客户端的首选算法。如果设置了上述配置，则会替代地使用服务器端的首选算法。

* [关于 ssl\_prefer\_server\_ciphers 的更多信息](http://wiki.nginx.org/HttpSslModule#ssl_prefer_server_ciphers)
* [关于 ssl\_ciphers 的更多信息](http://wiki.nginx.org/HttpSslModule#ssl_ciphers)

### 前向安全性和 Diffie Hellman Ephemeral （DHE）参数

<ruby> 前向安全性 <rp>  （ </rp> <rt>  Forward Secrecy </rt> <rp>  ） </rp></ruby>的概念很简单：客户端和服务器协商一个永不重用的密钥，并在会话结束时销毁它。服务器上的 RSA 私钥用于客户端和服务器之间的 Diffie-Hellman 密钥交换签名。从 Diffie-Hellman 握手中获取的预主密钥会用于之后的编码。因为预主密钥是特定于客户端和服务器之间建立的某个连接，并且只用在一个限定的时间内，所以称作<ruby> 短暂模式 <rp>  （ </rp> <rt>  Ephemeral </rt> <rp>  ） </rp></ruby>。

使用了前向安全性，如果一个攻击者取得了一个服务器的私钥，他是不能解码之前的通讯信息的。这个私钥仅用于 Diffie Hellman 握手签名，并不会泄露预主密钥。Diffie Hellman 算法会确保预主密钥绝不会离开客户端和服务器，而且不能被中间人攻击所拦截。

所有版本的 nginx（如1.4.4）都依赖于 OpenSSL 给 Diffie-Hellman （DH）的输入参数。不幸的是，这意味着 Diffie-Hellman Ephemeral（DHE）将使用 OpenSSL 的默认设置，包括一个用于密钥交换的1024位密钥。因为我们正在使用2048位证书，DHE 客户端就会使用一个要比非 DHE 客户端更弱的密钥交换。

我们需要生成一个更强壮的 DHE 参数：

```
cd /etc/ssl/certs
openssl dhparam -out dhparam.pem 4096

```

然后告诉 nginx 将其用作 DHE 密钥交换：

```
ssl_dhparam /etc/ssl/certs/dhparam.pem;

```

### OCSP 装订（Stapling）

当连接到一个服务器时，客户端应该使用<ruby> 证书吊销列表 <rp>  （ </rp> <rt>  CRL，Certificate Revocation List </rt> <rp>  ） </rp></ruby>或<ruby> 在线证书状态协议 <rp>  （ </rp> <rt>  OCSP，Online Certificate Status Protocol </rt> <rp>  ） </rp></ruby>记录来校验服务器证书的有效性。CRL 的问题是它已经增长的太大了，永远也下载不完了。

OCSP 更轻量级一些，因为我们每次只请求一条记录。但是副作用是当连接到一个服务器时必须对第三方 OCSP 响应器发起 OCSP 请求，这就增加了延迟和带来了潜在隐患。事实上，CA 所运营的 OCSP 响应器非常不可靠，浏览器如果不能及时收到答复，就会静默失败。攻击者通过 DoS 攻击一个 OCSP 响应器可以禁用其校验功能，这样就降低了安全性。

解决方法是允许服务器在 TLS 握手中发送缓存的 OCSP 记录，以绕开 OCSP 响应器。这个机制节省了客户端和 OCSP 响应器之间的通讯，称作 OCSP 装订。

客户端会在它的 CLIENT HELLO 中告知其支持 status\_request TLS 扩展，服务器仅在客户端请求它的时候才发送缓存的 OCSP 响应。

大多数服务器最多会缓存 OCSP 响应48小时。服务器会按照常规的间隔连接到 CA 的 OCSP 响应器来获取刷新的 OCSP 记录。OCSP 响应器的位置可以从签名的证书中的<ruby> 授权信息访问 <rp>  （ </rp> <rt>  Authority Information Access </rt> <rp>  ） </rp></ruby>字段中获得。

* [阅读我的教程：在 NGINX 中启用 OCSP 装订](https://raymii.org/s/tutorials/OCSP_Stapling_on_nginx.html)

### HTTP 严格传输安全（HSTS）

如有可能，你应该启用 [HTTP 严格传输安全（HSTS）](https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security)，它会引导浏览器和你的站点之间的通讯仅通过 HTTPS。

* [阅读我关于 HSTS 的文章，了解如何配置它](/article-5266-1.html)

### HTTP 公钥固定扩展（HPKP）

你也应该启用 [HTTP 公钥固定扩展（HPKP）](https://wiki.mozilla.org/SecurityEngineering/Public_Key_Pinning)。

公钥固定的意思是一个证书链必须包括一个白名单中的公钥。它确保仅有白名单中的 CA 才能够为某个域名签署证书，而不是你的浏览器中存储的任何 CA。

我已经写了一篇[关于 HPKP 的背景理论及在 Apache、Lighttpd 和 NGINX 中配置例子的文章](/article-5282-1.html)。

### 配置范例

```
server {

  listen [::]:443 default_server;

  ssl on;
  ssl_certificate_key /etc/ssl/cert/raymii_org.pem;
  ssl_certificate /etc/ssl/cert/ca-bundle.pem;

  ssl_ciphers 'AES128+EECDH:AES128+EDH:!aNULL';

  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  ssl_session_cache shared:SSL:10m;

  ssl_stapling on;
  ssl_stapling_verify on;
  resolver 8.8.4.4 8.8.8.8 valid=300s;
  resolver_timeout 10s;

  ssl_prefer_server_ciphers on;
  ssl_dhparam /etc/ssl/certs/dhparam.pem;

  add_header Strict-Transport-Security max-age=63072000;
  add_header X-Frame-Options DENY;
  add_header X-Content-Type-Options nosniff;

  root /var/www/;
  index index.html index.htm;
  server_name raymii.org;

}

```

### 结尾

如果你使用了上述配置，你需要重启 nginx：

```
# 首先检查配置文件是否正确
/etc/init.d/nginx configtest
# 然后重启
/etc/init.d/nginx restart

```

现在使用 [SSL Labs 测试](https://www.ssllabs.com/ssltest/)来看看你是否能得到一个漂亮的“A”。当然了，你也得到了一个安全的、强壮的、经得起考验的 SSL 配置！

* [参考 Mozilla 关于这方面的内容](https://wiki.mozilla.org/Security/Server_Side_TLS)

---

via: <https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html>

作者：[Remy van Elst](https://raymii.org/) 译者：[wxy](https://github.com/wxy) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译，[Linux中国](http://linux.cn/) 荣誉推出


环境音播放器：让人放松的声音，保持你的创造力

Summary: 对于某些人来说雨声是个令人安心的声音 如果我想变得非常有效率，我不能听正常的音乐。它会使我分心，我会开始跟着唱或者让我想起另一首歌，结局就是我在自己的音乐库里到处戳并且反正，你懂的。 同样我也不能在寂静的环境中工作（虽然和6只猫生活在一起意味着这不太可能）但是无规律的刺耳声音和突然地咔哒声以及猫叫声会打破寂静。 我的解决办法是听环境音。 我发现它能帮助我消除大脑的里的胡思乱想，提供了一个声景覆盖了猫咪玩耍的声音。 环境音就是日常生活中的背景噪音；雨滴在窗户上敲打的声音，咖啡店里人们聊天的嗡嗡声，风中鸟

感觉这类应用更适合开发成一个插件哈，要不然每多装一个音乐类程序，都会在ubuntu的音量菜单下多一项，虽然有方法将其去除，不过终归不是好方法，何不做成系统内现有音乐程序的一种环境音播放模式呢？启动该模式后，就开始播放环境音，并完全屏蔽掉音乐库以及音乐库内的其它音乐。这样同样也可以起到这样的效果呀。话说，这个程序内自带的8个高品质的环境音音频，啊哈，可以不安装这个程序，直接把这8个环境音提取出来，放在那单曲循环听，不过这样好像很没有调调哇

yaourt -S anoise<br />
……

![Rain is a soothing sound for some](/data/attachment/album/201505/03/223347cfqyuqtxtqxmzz3u.jpg)

*对于某些人来说雨声是个令人安心的声音*

**如果我想变得非常有效率，我不能听‘正常’的音乐。它会使我分心，我会开始跟着唱或者让我想起另一首歌，结局就是我在自己的音乐库里到处戳并且……反正，你懂的。**

同样我也不能在寂静的环境中工作（虽然和6只猫生活在一起意味着这不太可能）但是无规律的刺耳声音和突然地咔哒声以及猫叫声会打破寂静。

我的解决办法是听**环境音**。

我发现它能帮助我消除大脑的里的胡思乱想，提供了一个声景覆盖了猫咪玩耍的声音。

环境音就是日常生活中的背景噪音；雨滴在窗户上敲打的声音，咖啡店里人们聊天的嗡嗡声，风中鸟儿们闲聊的声音，等等。

倾听这些声音会强迫一个疯狂运行的大脑减速，重新沉静下来重新把精力聚集到重要的事情上。

### 适用于Ubuntu的环境音应用

![](/data/attachment/album/201505/03/223347rh39ntv9o28vx9n9.jpg)

Google Play和苹果应用商店充满了环境音和白噪声的应用。现在，在Ubuntu里有同样的应用了。

‘[Ambient Noise （环境音）](http://anoise.tuxfamily.org/) ’——人如其名，这是一个专门被设计成播放这种声音的音频播放器。他甚至可以同Ubuntu声音菜单整合到一起，给你‘选择，点击即放松’的体验。

这个应用（又被称为‘ANoise播放器’，由Marcos Costales制作）带有**8个高品质音频**。

这8个预设音频涵盖了多种环境，从下雨时有节奏的声音，到夜晚大自然静谧的旋律，还有下午熙熙攘攘的咖啡店的嗡嗡声。

### 在Ubuntu上安装ANoise播放器

适用于Ubuntu的环境音播放器是个免费的应用而且可以从它专用的PPA里安装。

要这样安装请先打开一个新的终端窗口运行:

```
sudo add-apt-repository ppa:costales/anoise

sudo apt-get update && sudo apt-get install anoise

```

安装好以后只需从Unity Dash（或桌面环境里类同的地方）里打开它，通过声音菜单选择你喜欢的环境音然后……放松吧！这个应用甚至记得你上次用的环境音。

即便如此，你还是要试一试看它是否能满足你的需要。我要说的是让我知道你是怎么想的，但是我将会专心致志到听不到你的声音——你可能也会这样！

---

via: <http://www.omgubuntu.co.uk/2015/04/ambient-noise-player-app-for-ubuntu-linux>

作者：[Joey-Elijah Sneddon](https://plus.google.com/117485690627814051450/?rel=author) 译者：[H-mudcup](https://github.com/H-mudcup) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译，[Linux中国](http://linux.cn/) 荣誉推出


SuperTuxKart 0.9 已发行 —— Linux 中最好的竞速类游戏越来越棒了！

Summary: 热门竞速类游戏 SuperTuxKart 的新版本已经打包发行登陆下载服务器  Super Tux Kart 0.9 发行海报 SuperTuxKart 0.9 相较前一版本做了巨大的升级，内部运行着刚出炉的新引擎（有个炫酷的名字叫Antarctica（南极洲）），目的是要呈现更加炫酷的图形环境，从阴影到场景的纵深，外加卡丁车更好的物理效果。 突出的图形表现也增加了对显卡的要求。SuperTuxKart 开发人员给玩家的建议是，要有图像处理能力比得上（或者，想要完美的话，要超过） Intel HD Graphics 3000, NVIDIA GeForce 8600 或 AMD Radeon HD 3650 的显卡。 其他改变 SuperTux

大四的时候玩得好过瘾呢！

**热门竞速类游戏 SuperTuxKart 的新版本已经[打包发行](http://supertuxkart.blogspot.co.uk/2015/04/supertuxkart-09-released.html)登陆下载服务器**

![](/data/attachment/album/201505/03/223841ke8fjzejwcwzvl7d.jpg)

*Super Tux Kart 0.9 发行海报*

SuperTuxKart 0.9 相较前一版本做了巨大的升级，内部运行着刚出炉的新引擎（有个炫酷的名字叫‘Antarctica（南极洲）’），目的是要呈现更加炫酷的图形环境，从阴影到场景的纵深，外加卡丁车更好的物理效果。

突出的图形表现也增加了对显卡的要求。SuperTuxKart 开发人员给玩家的建议是，要有图像处理能力比得上（或者，想要完美的话，要超过） Intel HD Graphics 3000, NVIDIA GeForce 8600 或 AMD Radeon HD 3650 的显卡。

### 其他改变

SuperTuxKart 0.9 中与图像的改善同样吸引人眼球的是一对**全新赛道**，新的卡丁车，新的在线账户可以记录和分享**全新推出的成就系统**里赢得的徽章，以及大量的改装和涂装的微调。

点击播放下面的官方发行视频，看看基于调色器的 STK 0.9 所散发的光辉吧。（youtube 视频：<https://www.youtube.com/0FEwDH7XU9Q> ）

Ubuntu 用户可以从项目网站上下载新发行版已编译的二进制文件。

* [下载 SuperTuxKart 0.9](http://supertuxkart.sourceforge.net/Downloads)

---

via: <http://www.omgubuntu.co.uk/2015/04/supertuxkart-0-9-released>

作者：[Joey-Elijah Sneddon](https://plus.google.com/117485690627814051450/?rel=author) 译者：[H-mudcup](https://github.com/H-mudcup) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译，[Linux中国](http://linux.cn/) 荣誉推出


搭建一个私有的Docker registry

Summary: 这是系列的第二篇文章，这系列讲述了我的公司如何把基础服务从PaaS迁移到Docker上  第一篇文章: 我谈到了接触Docker之前的经历； 第三篇文章: 我展示如何使创建镜像的过程自动化以及如何用Docker部署一个Rails应用。   为什么需要搭建一个私有的registry呢？嗯，对于新手来说，Docker Hub（一个Docker公共仓库）只允许你拥有一个免费的私有版本库（repo）。其他的公司也开始提供类似服务，但是价格可不便宜。另外，如果你需要用Docker部署一个用于生产环境的应用，恐怕你不希望将这些镜像放在公开的Docker Hub上吧！ 这篇文章提供了一个非

昨晚我创建了一个空的repo,然后看着不知道有啥用

等下一篇~~

![](/data/attachment/album/201505/03/235052rf8iq6i6x1xiz8qo.jpg)

[TL;DR] 这是系列的第二篇文章，这系列讲述了我的公司如何把基础服务从PaaS迁移到Docker上

* [第一篇文章](/article-5339-1.html): 我谈到了接触Docker之前的经历；
* [第三篇文章](/article-5408-1.html): 我展示如何使创建镜像的过程自动化以及如何用Docker部署一个Rails应用。

---

为什么需要搭建一个私有的registry呢？嗯，对于新手来说，Docker Hub（一个Docker公共仓库）只允许你拥有一个免费的私有版本库（repo）。其他的公司也开始提供类似服务，但是价格可不便宜。另外，如果你需要用Docker部署一个用于生产环境的应用，恐怕你不希望将这些镜像放在公开的Docker Hub上吧！

这篇文章提供了一个非常务实的方法来处理搭建私有Docker registry时出现的各种错综复杂的情况。我们将会使用一个运行于DigitalOcean（之后简称为DO）的非常小巧的512MB VPS 实例。并且我会假定你已经了解了Docker的基本概念，因为我必须集中精力在复杂的事情上！

### 本地搭建

首先你需要安装**boot2docker**以及docker CLI。如果你已经搭建好了基本的Docker环境，你可以直接跳过这一步。

从终端运行以下命令（我假设你使用OS X，使用 HomeBrew 来安装相关软件，你可以根据你的环境使用不同的包管理软件来安装）:

```
brew install boot2docker docker

```

如果一切顺利（想要了解搭建docker环境的完整指南，请参阅 <http://boot2docker.io/>） ，你现在就能够通过如下命令启动一个 Docker 运行于其中的虚拟机：

```
boot2docker up

```

按照屏幕显示的说明，复制粘贴book2docker在终端输出的命令。如果你现在运行`docker ps`命令，终端将有以下显示。

```
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

```

好了，Docker已经准备就绪，这就够了，我们回过头去搭建registry。

### 创建服务器

登录进你的DO账号，选择一个预安装了Docker的镜像文件，创建一个新的Drople。（本文写成时选择的是 Image > Applications > Docker 1.4.1 on 14.04）

![](/data/attachment/album/201505/03/235325m6r1k1mom96mqn8m.png)

你将会以邮件的方式收到一个根用户凭证。登录进去，然后运行`docker ps`命令来查看系统状态。

### 搭建AWS S3

我们现在将使用Amazo Simple Storage Service（S3）作为我们registry/repository的存储层。我们将需要创建一个桶(bucket)以及用户凭证（user credentials）来允许我们的docker容器访问它。

登录到我们的AWS账号（如果没有，就申请一个<http://aws.amazon.com/>），在控制台选择S3（Simpole Storage Service）。

![](/data/attachment/album/201505/03/235330nzcuztdvxit4z2ki.png)

点击 **Create Bucket**，为你的桶输入一个名字（把它记下来，我们一会需要用到它），然后点击**Create**。

![](/data/attachment/album/201505/03/235333gph8umin9yc98n9k.png)

OK！我们已经搭建好存储部分了。

### 设置AWS访问凭证

我们现在将要创建一个新的用户。退回到AWS控制台然后选择IAM（Identity & Access Management)。

![](/data/attachment/album/201505/03/235337pht9iif6v2h03uiz.png)

在dashboard的左边，点击Users。然后选择 **Create New Users**。

如图所示：

![](/data/attachment/album/201505/03/235339yy3gv263g2vglvv3.png)

输入一个用户名（例如 docker-registry）然后点击Create。写下（或者下载csv文件）你的Access Key以及Secret Access Key。回到你的用户列表然后选择你刚刚创建的用户。

在Permission section下面，点击Attach User Policy。之后在下一屏，选择Custom Policy。

![](/data/attachment/album/201505/03/235341g7y717cq2447ywfr.png)

custom policy的内容如下：

```
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "SomeStatement",
      "Effect": "Allow",
      "Action": [
        "s3:*"
      ],
      "Resource": [
        "arn:aws:s3:::docker-registry-bucket-name/*",
        "arn:aws:s3:::docker-registry-bucket-name"
      ]
    }
  ]
}

```

这个配置将允许用户（也就是regitstry）来对桶上的内容进行操作（读/写）（确保使用你之前创建AWS S3时使用的桶名）。总结一下：当你想把你的Docker镜像从你的本机推送到仓库中时，服务器就会将他们上传到S3。

### 安装registry

现在回过头来看我们的DO服务器，SSH登录其上。我们将要[使用](https://github.com/docker/docker-registry/)一个[官方Docker registry镜像](https://registry.hub.docker.com/_/registry/)。

输入如下命令，开启registry。

```
docker run \
         -e SETTINGS_FLAVOR=s3 \
         -e AWS_BUCKET=bucket-name \
         -e STORAGE_PATH=/registry \
         -e AWS_KEY=your_aws_key \
         -e AWS_SECRET=your_aws_secret \
         -e SEARCH_BACKEND=sqlalchemy \
         -p 5000:5000 \
         --name registry \
         -d \
         registry

```

Docker将会从Docker Hub上拉取所需的文件系统分层（fs layers）并启动守护容器（daemonised container）。

### 测试registry

如果上述操作奏效，你可以通过ping命令，或者查找它的内容来测试registry（虽然这个时候容器还是空的）。

我们的registry非常基础，而且没有提供任何“验明正身”的方式。因为添加身份验证可不是一件轻松事（至少我认为没有一种部署方法是简单的，像是为了证明你努力过似的），我觉得“查询/拉取/推送”仓库内容的最简单方法就是通过SSH通道的未加密连接（通过HTTP）。

打开SSH通道的操作非常简单：

```
ssh -N -L 5000:localhost:5000 root@your_registry.com

```

这条命令建立了一条从registry服务器（前面执行`docker run`命令的时候我们见过它）的5000号端口到本机的5000号端口之间的 SSH 管道连接。

如果你现在用浏览器访问 <http://localhost:5000/v1/_ping>，将会看到下面这个非常简短的回复。

```
{}

```

这个意味着registry工作正常。你还可以通过登录 <http://localhost:5000/v1/search> 来查看registry内容，内容相似：

```
{
  "num_results": 2,
  "query": "",
  "results": [
    {
      "description": "",
      "name": "username/first-repo"
    },
    {
      "description": "",
      "name": "username/second-repo"
    }
  ]
}

```

### 创建一个镜像

我们现在创建一个非常简单的Docker镜像，来检验我们新弄好的registry。在我们的本机上，用如下内容创建一个Dockerfile（这里只有一点代码，在下一篇文章里我将会展示给你如何将一个Rails应用绑定进Docker容器中。）：

```
#  ruby 2.2.0 的基础镜像
FROM ruby:2.2.0

MAINTAINER Michelangelo Chasseur <michelangelo.chasseur@touchwa.re>

```

并创建它：

```
docker build -t localhost:5000/username/repo-name .

```

`localhost:5000`这个部分非常重要：Docker镜像名的最前面一个部分将告知`docker push`命令我们将要把我们的镜像推送到哪里。在我们这个例子当中，因为我们要通过SSH管道连接远程的私有registry，`localhost:5000`精确地指向了我们的registry。

如果一切顺利，当命令执行完成返回后，你可以输入`docker images`命令来列出新近创建的镜像。执行它看看会出现什么现象？

### 推送到仓库

接下来是更好玩的部分。实现我所描述的东西着实花了我一点时间，所以如果你第一次读的话就耐心一点吧，跟着我一起操作。我知道接下来的东西会非常复杂（如果你不自动化这个过程就一定会这样），但是我保证到最后你一定都能明白。在下一篇文章里我将会使用到一大波shell脚本和Rake任务，通过它们实现自动化并且用简单的命令实现部署Rails应用。

你在终端上运行的docker命令实际上都是使用boot2docker虚拟机来运行容器及各种东西。所以当你执行像`docker push some_repo`这样的命令时，是boot2docker虚拟机在与registry交互，而不是我们自己的机器。

接下来是一个非常重要的点：为了将Docker镜像推送到远端的私有仓库，SSH管道需要在boot2docker虚拟机上配置好，而不是在你的本地机器上配置。

有许多种方法实现它。我给你展示最简短的一种（可能不是最容易理解的，但是能够帮助你实现自动化）

在这之前，我们需要对 SSH 做最后一点工作。

### 设置 SSH

让我们把boot2docker 的 SSH key添加到远端服务器的“已知主机”里面。我们可以使用ssh-copy-id工具完成，通过下面的命令就可以安装上它了：

```
brew install ssh-copy-id

```

然后运行：

```
ssh-copy-id -i /Users/username/.ssh/id_boot2docker root@your-registry.com

```

用你ssh key的真实路径代替`/Users/username/.ssh/id_boot2docker`。

这样做能够让我们免密码登录SSH。

现在我们来测试以下：

```
boot2docker ssh "ssh -o 'StrictHostKeyChecking no' -i /Users/michelangelo/.ssh/id_boot2docker -N -L 5000:localhost:5000 root@registry.touchwa.re &" &

```

分开阐述：

* `boot2docker ssh`允许你以参数的形式传递给boot2docker虚拟机一条执行的命令；
* 最后面那个`&`表明这条命令将在后台执行；
* `ssh -o 'StrictHostKeyChecking no' -i /Users/michelangelo/.ssh/id_boot2docker -N -L 5000:localhost:5000 root@registry.touchwa.re &`是boot2docker虚拟机实际运行的命令；
	+ `-o 'StrictHostKeyChecking no'`——不提示安全问题；
	+ `-i /Users/michelangelo/.ssh/id_boot2docker`指出虚拟机使用哪个SSH key来进行身份验证。（注意这里的key应该是你前面添加到远程仓库的那个）
	+ 最后我们将打开一条端口5000映射到localhost:5000的SSH通道。

### 从其他服务器上拉取

你现在将可以通过下面的简单命令将你的镜像推送到远端仓库：

```
docker push localhost:5000/username/repo_name

```

在下一篇[文章](/article-5408-1.html)中，我们将会了解到如何自动化处理这些事务，并且真正地容器化一个Rails应用。请继续收听！

如有错误，请不吝指出。祝你Docker之路顺利！

---

via: <http://cocoahunter.com/2015/01/23/docker-2/>

作者：[Michelangelo Chasseur](http://cocoahunter.com/author/michelangelo/) 译者：[DongShuaike](https://github.com/DongShuaike) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译，[Linux中国](http://linux.cn/) 荣誉推出


如何在ubuntu14.04上安装轻量级的Budgie桌面(v8)

Summary: Budgie是为Linux发行版定制的旗舰桌面，也是一个定制工程。为思想前卫的用户设计，致力于简单和简洁。它的一个巨大优势是它不是别的项目的fork版本，是从都到尾都独立的。 Budgie桌面与GNOME栈紧密结合，使用先进的技术从而提供一个可选择的桌面体验。出于开源理念，这个桌面之后也能在别的Linux发行版中看到。 现在Budgie能够通过面板的设置达到和GNOME2桌面相似的使用体验。 0.8版的特点  任务栏：支持应用锁定到任务栏 任务栏：使用.desktop文件来配置quicklists菜单 任务栏：使用.desktop文件来配置图标分辨率 任务栏：支持有通知时蓝

Budgie是为Linux发行版定制的旗舰桌面，也是一个定制工程。为思想前卫的用户设计，致力于简单和简洁。它的一个巨大优势是它不是别的项目的fork版本，是从都到尾都独立的。

![Budgie 桌面环境](/data/attachment/album/201505/04/163651ftzrgqtkwvg7jqgf.png)

[Budgie桌面](https://evolve-os.com/budgie/)与GNOME栈紧密结合，使用先进的技术从而提供一个可选择的桌面体验。出于开源理念，这个桌面之后也能在别的Linux发行版中看到。

现在Budgie能够通过面板的设置达到和GNOME2桌面相似的使用体验。

### 0.8版的特点

* 任务栏：支持应用锁定到任务栏
* 任务栏：使用.desktop文件来配置quicklists菜单
* 任务栏：使用.desktop文件来配置图标分辨率
* 任务栏：支持有通知时蓝色闪烁
* 面板：支持默认深色主体
* 添加菜单条的小组件
* 面板：自动隐藏菜单条和工具条(这配置为手动)
* 面板：支持屏幕边缘处阴影
* 面板：动态支持gnome面板主题
* 运行对话框：虚拟刷新
* Budgie菜单: 增加紧凑模式，并默认采用
* Budgie菜单: 按照使用顺序排列菜单项
* Budgie菜单: 移除旧的电源选项
* 编辑器: 在UI中增加所有的菜单选项
* 支持从GNOME 3.10 升级到3.16
* wm: 关闭工作区的动画(v8之后)
* wm: 改变壁纸时更好的动画

### 重要信息

* Budgie [0.8版发行版](https://evolve-os.com/2014/11/16/courageous-budgie-v8-released/)目前只是beta
* 无本地网络管理；可以通过使用ubuntu的小组件解决
* Budgie 是为Evolve OS设计的，因此这个PPA可能会有bug
* GNOME 主题比Ubuntu本地的主题效果更好
* Ubuntu的滚动栏将不在工作
* 如果你想了解的更多可以访问Evolve OS网站

### 安装

现在，我们将在Ubuntu14.04 LTS中安装我们自己的轻量级Budgie桌面。首先，我们要把PPA源添加到我们的Ubuntu中。执行以下命令：

```
$ sudo add-apt-repository ppa:evolve-os/ppa

```

![添加Budgie的ppa源](/data/attachment/album/201505/04/163648yt8ubsgug800n5tc.png)

添加完ppa之后，运行下面的命令更新本地软件仓库。

```
$ sudo apt-get update

```

然后只要执行下面的命令安装

```
$ sudo apt-get install budgie-desktop

```

![安装 Budgie Desktop](/data/attachment/album/201505/04/163648vhlhmza024q2mehm.png)

**注意**

这是一个活跃的开发版本，一些主要的功能可能还不是特别的完善，如：没有网络管理器，没有音量控制组件（可以使用键盘控制），无通知系统并且无法将app锁定到任务栏。

有一个临时解决方案可以禁用叠加滚动栏：设置另外一个默认主题，然后从终端退出当前会话：

```
$ gnome-session-quit

```

![退出 Gnome 会话](/data/attachment/album/201505/04/163649dxybknkhbocoku59.png)

### 登录Budgie会话

安装完成之后，我们能在登录时选择进入budgie桌面。

![选择桌面会话](/data/attachment/album/201505/04/163650a203p81021t39gvp.png)

### 注销当前用户

```
$ budgie-sessioon --logout

```

### 结论

嗨，现在我们已经成功的在 Ubuntu 14.04 LTS 上安装了轻量级 Budgie 桌面环境。Budgie桌面当前正在开发过程中，因此有目前有很多功能的缺失。虽然它是基于Gnome 的 GTK3，但不是完全的复制。Budgie是完全从零开始实现，它的设计是优雅的并且正在不断的完善。如果你有任何问题、评论，请在下面的评论框发表。愿你喜欢 Budgie 桌面 0.8 。

---

via: <http://linoxide.com/ubuntu-how-to/install-lightweight-budgie-v8-desktop-ubuntu/>

作者：[Arun Pyasi](http://linoxide.com/author/arunp/) 译者：[johnhoow](https://github.com/johnhoow) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译，[Linux中国](http://linux.cn/) 荣誉推出


在 Linux 中用 nmcli 命令绑定多块网卡

Summary: 今天，我们来学习一下在 CentOS 7.x 中如何用 nmcli（Network Manager Command Line Interface：网络管理命令行接口）进行网卡绑定。 网卡（接口）绑定是将多块 网卡 逻辑地连接到一起从而允许故障转移或者提高吞吐率的方法。提高服务器网络可用性的一个方式是使用多个网卡。Linux 绑定驱动程序提供了一种将多个网卡聚合到一个逻辑的绑定接口的方法。这是个新的实现绑定的方法，并不影响 linux 内核中旧绑定驱动。  网卡绑定为我们提供了两个主要的好处:  高带宽 冗余/弹性  现在让我们在 CentOS 7 上配置网卡绑定吧。我们需要决定选取哪

https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/Networking_Guide/index.html<br />
看来要学习的还有很多啊！

这个真的很有用！

在TEAM模式下，是否需要在交换机端进行端口汇聚操作呢？？哪位出来详细讲讲TEAM的几种网卡绑定模式和BOND几种绑定模式的区别吧

今天，我们来学习一下在 CentOS 7.x 中如何用 nmcli（Network Manager Command Line Interface：网络管理命令行接口）进行网卡绑定。

网卡（接口）绑定是将多块 **网卡** 逻辑地连接到一起从而允许故障转移或者提高吞吐率的方法。提高服务器网络可用性的一个方式是使用多个网卡。Linux 绑定驱动程序提供了一种将多个网卡聚合到一个逻辑的绑定接口的方法。这是个新的实现绑定的方法，并不影响 linux 内核中旧绑定驱动。

![](/data/attachment/album/201505/04/215715sevw9ec4brcvkcp9.jpg)

**网卡绑定为我们提供了两个主要的好处:**

1. **高带宽**
2. **冗余/弹性**

现在让我们在 CentOS 7 上配置网卡绑定吧。我们需要决定选取哪些接口配置成一个组接口（Team interface）。

运行 **ip link** 命令查看系统中可用的接口。

```
 $ ip link

```

![ip link](/data/attachment/album/201505/04/215804g4zkw6wkg9wjgphg.png)

这里我们使用 **eno16777736** 和 **eno33554960** 网卡在 “主动备份” 模式下创建一个组接口。(译者注：关于不同模式可以参考：[多网卡的7种bond模式原理](http://support.huawei.com/ecommunity/bbs/10155553.html))

按照下面的语法，用 **nmcli** 命令为网络组接口创建一个连接。

```
# nmcli con add type team con-name CNAME ifname INAME [config JSON]

```

**CNAME** 指代连接的名称，**INAME** 是接口名称，**JSON** (JavaScript Object Notation) 指定所使用的处理器(runner)。**JSON** 语法格式如下：

```
'{"runner":{"name":"METHOD"}}'

```

**METHOD** 是以下的其中一个：**broadcast、activebackup、roundrobin、loadbalance** 或者 **lacp**。

### 1. 创建组接口

现在让我们来创建组接口。这是我们创建组接口所使用的命令。

```
 # nmcli con add type team con-name team0 ifname team0 config '{"runner":{"name":"activebackup"}}'

```

![nmcli con create](/data/attachment/album/201505/04/215804bm9kn9md9nh02m9x.png)

运行 **# nmcli con show** 命令验证组接口配置。

```
# nmcli con show

```

![显示组接口](/data/attachment/album/201505/04/215805p8929ybud7b2cupp.png)

### 2. 添加从设备

现在让我们添加从设备到主设备 team0。这是添加从设备的语法：

```
# nmcli con add type team-slave con-name CNAME ifname INAME master TEAM

```

在这里我们添加 **eno16777736** 和 **eno33554960** 作为 **team0** 接口的从设备。

```
# nmcli con add type team-slave con-name team0-port1 ifname eno16777736 master team0

# nmcli con add type team-slave con-name team0-port2 ifname eno33554960 master team0

```

![添加从设备到 team](/data/attachment/album/201505/04/215805kuorf7hoahhorrrj.png)

再次用命令 **#nmcli con show** 验证连接配置。现在我们可以看到从设备配置信息。

```
#nmcli con show

```

![显示从设备配置](/data/attachment/album/201505/04/215806o2rrgoo1ocke1y5g.png)

### 3. 分配 IP 地址

上面的命令会在 **/etc/sysconfig/network-scripts/** 目录下创建需要的配置文件。

现在让我们为 team0 接口分配一个 IP 地址并启用这个连接。这是进行 IP 分配的命令。

```
# nmcli con mod team0 ipv4.addresses "192.168.1.24/24 192.168.1.1"
# nmcli con mod team0 ipv4.method manual
# nmcli con up team0

```

![分配 ip](/data/attachment/album/201505/04/215806trf9nq6chdqufxhr.png)

### 4. 验证绑定

用 **#ip add show team0** 命令验证 IP 地址信息。

```
#ip add show team0

```

![验证 ip 地址](/data/attachment/album/201505/04/215807oy6ycnyfny5zogzg.png)

现在用 **teamdctl** 命令检查 **主动备份** 配置功能。

```
# teamdctl team0 state

```

![teamdctl 检查主动备份](/data/attachment/album/201505/04/215807sm3ll4dln0plpwql.png)

现在让我们把激活的端口断开连接并再次检查状态来确认主动备份配置是否像希望的那样工作。

```
# nmcli dev dis eno33554960

```

![断开激活端口连接](/data/attachment/album/201505/04/215807nvnq089wnset4b0n.png)

断开激活端口后再次用命令 **#teamdctl team0 state** 检查状态。

```
# teamdctl team0 state

```

![teamdctl 检查断开激活端口连接](/data/attachment/album/201505/04/215808hkbo0ypnfxxnb174.png)

是的，它运行良好！！我们会使用下面的命令连接回到 team0 的断开的连接。

```
#nmcli dev con eno33554960

```

![nmcli dev 连接断开的连接](/data/attachment/album/201505/04/215808z0yjlo8j9fjooz99.png)

我们还有一个 **teamnl** 命令可以显示 **teamnl** 命令的一些选项。

用下面的命令检查在 team0 运行的端口。

```
# teamnl team0 ports

```

![teamnl 检查端口](/data/attachment/album/201505/04/215809vlvfgfayvtsbbgfq.png)

显示 **team0** 当前活动的端口。

```
# teamnl team0 getoption activeport

```

![显示 team0 活动端口](/data/attachment/album/201505/04/215809jc52w65bu61qcbqv.png)

好了，我们已经成功地配置了网卡绑定 :-) ，如果有任何反馈，请告诉我们。

---

via: <http://linoxide.com/linux-command/interface-nics-bonding-linux/>

作者：[Arun Pyasi](http://linoxide.com/author/arunp/) 译者：[ictlyh](https://github.com/ictlyh) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译，[Linux中国](http://linux.cn/) 荣誉推出


在 FreeBSD 10.1中安装 Mate 桌面

Summary: FreeBSD是全文本模式的系统，然而有些新用户想要使用GUI桌面环境。这个教程就是帮助你在Freebsd 10.1中安装Mate桌面。 下面是我的系统细节： root@Freebsd-unixmen:~ # uname -a FreeBSD Freebsd-unixmen 10.1-RELEASE FreeBSD 10.1-RELEASE #0 r274401: Tue Nov 11 21:02:49 UTC 2014 root@releng1.nyi.freebsd.org:/usr/obj/usr/src/sys/GENERIC amd64 root@Freebsd-unixmen:~  要在FreeBSD 10.1 中开始安装Mate桌面，按照下面的步骤。 pkg install xf86-video-fbdev mate-desktop mate xorg  在 /etc/rc.conf 中加入下面的行 moused_en

如果要安装中文支持呢？

推荐一款我自己很喜欢的gnome2 的主题 nimbus ，这个是solaris 11默认的主题。样式很喜欢！

同问

来自湖北武汉的 Chrome Mobile 58.0|Android 7.1 用户

![](/data/attachment/album/201505/04/220515m790kl2qp910o5ol.jpg)

FreeBSD是全文本模式的系统，然而有些新用户想要使用GUI桌面环境。这个教程就是帮助你在Freebsd 10.1中安装Mate桌面。

下面是我的系统细节：

```
root@Freebsd-unixmen:~ # uname -a
FreeBSD Freebsd-unixmen 10.1-RELEASE FreeBSD 10.1-RELEASE #0 r274401: Tue Nov 11 21:02:49 UTC 2014     root@releng1.nyi.freebsd.org:/usr/obj/usr/src/sys/GENERIC  amd64
root@Freebsd-unixmen:~

```

要在FreeBSD 10.1 中开始安装Mate桌面，按照下面的步骤。

```
pkg install xf86-video-fbdev mate-desktop mate xorg

```

### 在 /etc/rc.conf 中加入下面的行

```
moused_enable="YES"
dbus_enable="YES"
hald_enable="YES"

```

### 测试安装

```
xinit mate-session

```

![](/data/attachment/album/201505/04/220538dby0rtzzfx0yyegt.png)

Mate本身没有显示管理器。因此我们会使用其他的显示管理器如XDM、GDM、slim等等来作为登录管理器。这里让我们看看如何在Mate桌面中配置Slim DM

### 安装 Slim

```
pkg install slim

```

在**/etc/rc.conf**中加入下面的行：

```
slim_enable="YES"

```

在用户的家目录下的.xinitrc文件加入下面的行。

```
exec mate-session

```

重启电脑。现在在你登录Mate时就会进入Slim登录界面了。

![](/data/attachment/album/201505/04/220639iw1woom3jhpgz3dd.png)

![](/data/attachment/album/201505/04/220655e2fg9p3z3iuimzu7.png)

就是这样。干杯！

---

via: <http://www.unixmen.com/install-mate-desktop-freebsd-10-1/>

作者：[M.el Khamlichi](http://www.unixmen.com/author/pirat9/) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译，[Linux中国](http://linux.cn/) 荣誉推出


EvilAP_Defender：可以警示和攻击 WIFI 热点陷阱的工具

Summary: 开发人员称，EvilAP_Defender甚至可以攻击流氓Wi-Fi接入点  这是一个新的开源工具，可以定期扫描一个区域，以防出现恶意 Wi-Fi 接入点，同时如果发现情况会提醒网络管理员。 这个工具叫做 EvilAP_Defender，是为监测攻击者所配置的恶意接入点而专门设计的，这些接入点冒用合法的名字诱导用户连接上。 这类接入点被称做假面猎手（evil twin），使得黑客们可以从所接入的设备上监听互联网信息流。这可以被用来窃取证书、钓鱼网站等等。 大多数用户设置他们的计算机和设备可以自动连接一些无线网络，比如家里的或者工作地方的网络。通常，当

哈哈，以毒攻毒的工具出现咯，不过这倒是那些提供无线wifi接入的营业场所可以利用来保护其顾客利益的不错工具，未来的商业wifi运营商可以好好利用这款工具。

**开发人员称，EvilAP\_Defender甚至可以攻击流氓Wi-Fi接入点**

**![](/data/attachment/album/201505/08/003841xt0x300roxt16499.gif)**

这是一个新的开源工具，可以定期扫描一个区域，以防出现恶意 Wi-Fi 接入点，同时如果发现情况会提醒网络管理员。

这个工具叫做 EvilAP\_Defender，是为监测攻击者所配置的恶意接入点而专门设计的，这些接入点冒用合法的名字诱导用户连接上。

这类接入点被称做假面猎手（evil twin），使得黑客们可以从所接入的设备上监听互联网信息流。这可以被用来窃取证书、钓鱼网站等等。

大多数用户设置他们的计算机和设备可以自动连接一些无线网络，比如家里的或者工作地方的网络。通常，当面对两个同名的无线网络时，即SSID相同，有时候甚至连MAC地址（BSSID）也相同，这时候大多数设备会自动连接信号较强的一个。

这使得假面猎手攻击容易实现，因为SSID和BSSID都可以伪造。

[EvilAP\_Defender](https://github.com/moha99sa/EvilAP_Defender/blob/master/README.TXT)是一个叫Mohamed Idris的人用Python语言编写，公布在GitHub上面。它可以使用一个计算机的无线网卡来发现流氓接入点，这些坏蛋们复制了一个真实接入点的SSID，BSSID，甚至是其他的参数如通道，密码，隐私协议和认证信息等等。

该工具首先以学习模式运行，以便发现合法的接入点[AP]，并且将其加入白名单。然后可以切换到正常模式，开始扫描未认证的接入点。

如果一个恶意[AP]被发现了，该工具会用电子邮件提醒网络管理员，但是开发者也打算在未来加入短信提醒功能。

该工具还有一个保护模式，在这种模式下，应用会发起一个denial-of-service [DoS]攻击反抗恶意接入点，为管理员采取防卫措施赢得一些时间。

“DoS 将仅仅针对有着相同SSID的而BSSID（AP的MAC地址）不同或者不同信道的流氓 AP，”Idris在这款工具的文档中说道。“这是为了避免攻击到你的正常网络。”

尽管如此，用户应该切记在许多国家，攻击别人的接入点很多时候都是非法的，甚至是一个看起来像是攻击者操控的恶意接入点。

要能够运行这款工具，需要Aircrack-ng无线网套装，一个支持Aircrack-ng的无线网卡，MySQL和Python运行环境。

---

via: <http://www.infoworld.com/article/2905725/security0/this-tool-can-alert-you-about-evil-twin-access-points-in-the-area.html>

作者：[Lucian Constantin](http://www.infoworld.com/author/Lucian-Constantin/) 译者：[wi-cuckoo](https://github.com/wi-cuckoo) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译，[Linux中国](http://linux.cn/) 荣誉推出


自动化部署基于 Docker 的 Rails 应用

Summary: 这是系列文章的第三篇，讲述了我的公司是如何将基础设施从PaaS移植到Docker上的。  第一部分:谈论了我接触Docker之前的经历； 第二部分:一步步搭建一个安全而又私有的registry。   在系列文章的最后一篇里，我们将用一个实例来学习如何自动化整个部署过程。 基本的Rails应用程序 现在让我们启动一个基本的Rails应用。为了更好的展示，我使用Ruby 2.2.0和Rails 4.1.1 在终端运行： $ rvm use 2.2.0 $ rails new  cd docker-test  创建一个基本的控制器： $ rails g controller welcome index  ，然后编辑 routes.rb ，以便让该项目的根指向

good

![](/data/attachment/album/201505/08/011441atgttbjg9yengpbp.jpeg)

[TL;DR] 这是系列文章的第三篇，讲述了我的公司是如何将基础设施从PaaS移植到Docker上的。

* [第一部分](/article-5339-1.html):谈论了我接触Docker之前的经历；
* [第二部分](/article-5379-1.html):一步步搭建一个安全而又私有的registry。

---

在系列文章的最后一篇里，我们将用一个实例来学习如何自动化整个部署过程。

### 基本的Rails应用程序

现在让我们启动一个基本的Rails应用。为了更好的展示，我使用Ruby 2.2.0和Rails 4.1.1

在终端运行：

```
$ rvm use 2.2.0
$ rails new  && cd docker-test

```

创建一个基本的控制器：

```
$ rails g controller welcome index

```

……，然后编辑 `routes.rb` ，以便让该项目的根指向我们新创建的welcome#index方法：

```
root 'welcome#index'

```

在终端运行 `rails s` ，然后打开浏览器，登录[http://localhost:3000](http://localhost:3000/)，你会进入到索引界面当中。我们不准备给应用加上多么神奇的东西，这只是一个基础的实例，当我们将要创建并部署容器的时候，用它来验证一切是否运行正常。

### 安装webserver

我们打算使用Unicorn当做我们的webserver。在Gemfile中添加 `gem 'unicorn'`和 `gem 'foreman'`然后将它bundle起来(运行 `bundle install`命令）。

启动Rails应用时，需要先配置好Unicorn，所以我们将一个**unicorn.rb**文件放在**config**目录下。[这里有一个Unicorn配置文件的例子](https://gist.github.com/chasseurmic/0dad4d692ff499761b20)，你可以直接复制粘贴Gist的内容。

接下来，在项目的根目录下添加一个Procfile，以便可以使用foreman启动应用，内容为下：

```
web: bundle exec unicorn -p $PORT -c ./config/unicorn.rb

```

现在运行**foreman start**命令启动应用，一切都将正常运行，并且你将能够在[http://localhost:5000](http://localhost:5000/)上看到一个正在运行的应用。

### 构建一个Docker镜像

现在我们构建一个镜像来运行我们的应用。在这个Rails项目的根目录下，创建一个名为**Dockerfile**的文件，然后粘贴进以下内容：

```
# 基于镜像 ruby 2.2.0
FROM ruby:2.2.0

# 安装所需的库和依赖
RUN apt-get update && apt-get install -qy nodejs postgresql-client sqlite3 --no-install-recommends && rm -rf /var/lib/apt/lists/*

# 设置 Rails 版本
ENV RAILS_VERSION 4.1.1

# 安装 Rails
RUN gem install rails --version "$RAILS_VERSION"

# 创建代码所运行的目录
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

# 使 webserver 可以在容器外面访问
EXPOSE 3000

# 设置环境变量
ENV PORT=3000

# 启动 web 应用
CMD ["foreman","start"]

# 安装所需的 gems
ADD Gemfile /usr/src/app/Gemfile
ADD Gemfile.lock /usr/src/app/Gemfile.lock
RUN bundle install --without development test

# 将 rails 项目（和 Dockerfile 同一个目录）添加到项目目录
ADD ./ /usr/src/app

# 运行 rake 任务
RUN RAILS_ENV=production rake db:create db:migrate

```

使用上述Dockerfile，执行下列命令创建一个镜像（确保**boot2docker**已经启动并在运行当中）:

```
$ docker build -t localhost:5000/your_username/docker-test .

```

然后，如果一切正常，长长的日志输出的最后一行应该类似于：

```
Successfully built 82e48769506c
$ docker images
REPOSITORY                                       TAG                 IMAGE ID            CREATED              VIRTUAL SIZE
localhost:5000/your_username/docker-test         latest              82e48769506c        About a minute ago   884.2 MB

```

让我们运行一下容器试试！

```
$ docker run -d -p 3000:3000 --name docker-test localhost:5000/your_username/docker-test

```

通过你的boot2docker虚拟机的3000号端口（我的是[http://192.168.59.103:3000](http://192.168.59.103:3000/)），你可以观察你的Rails应用。（如果不清楚你的boot2docker虚拟地址，输入`$ boot2docker ip`命令查看。）

### 使用shell脚本进行自动化部署

前面的文章（指文章1和文章2）已经告诉了你如何将新创建的镜像推送到私有registry中，并将其部署在服务器上，所以我们跳过这一部分直接开始自动化进程。

我们将要定义3个shell脚本，然后最后使用rake将它们捆绑在一起。

### 清除

每当我们创建镜像的时候，

* 停止并重启boot2docker；
* 去除Docker孤儿镜像（那些没有标签，并且不再被容器所使用的镜像们）。

在你的工程根目录下的**clean.sh**文件中输入下列命令。

```
echo Restarting boot2docker...
boot2docker down
boot2docker up

echo Exporting Docker variables...
sleep 1
export DOCKER_HOST=tcp://192.168.59.103:2376
export DOCKER_CERT_PATH=/Users/user/.boot2docker/certs/boot2docker-vm
export DOCKER_TLS_VERIFY=1

sleep 1
echo Removing orphaned images without tags...
docker images | grep "<none>" | awk '{print $3}' | xargs docker rmi

```

给脚本加上执行权限：

```
$ chmod +x clean.sh

```

### 构建

构建的过程基本上和之前我们所做的（docker build）内容相似。在工程的根目录下创建一个**build.sh**脚本，填写如下内容：

```
docker build -t localhost:5000/your_username/docker-test .

```

记得给脚本执行权限。

### 部署

最后，创建一个**deploy.sh**脚本，在里面填进如下内容：

```
# 打开 boot2docker 到私有注册库的 SSH 连接
boot2docker ssh "ssh -o 'StrictHostKeyChecking no' -i /Users/username/.ssh/id_boot2docker -N -L 5000:localhost:5000 root@your-registry.com &" &

# 在推送前先确认该 SSH 通道是开放的。
echo Waiting 5 seconds before pushing image.

echo 5...
sleep 1
echo 4...
sleep 1
echo 3...
sleep 1
echo 2...
sleep 1
echo 1...
sleep 1

# Push image onto remote registry / repo
echo Starting push!
docker push localhost:5000/username/docker-test

```

如果你不理解这其中的含义，请先仔细阅读这部分[第二部分](/article-5379-1.html)。

给脚本加上执行权限。

### 使用rake将以上所有绑定

现在的情况是，每次你想要部署你的应用时，你都需要单独运行这三个脚本。

1. clean
2. build
3. deploy / push

这一点都不费工夫，可是事实上开发者比你想象的要懒得多！那么咱们就索性再懒一点！

我们最后再把工作好好整理一番，我们现在要将三个脚本通过rake捆绑在一起。

为了更简单一点，你可以在工程根目录下已经存在的Rakefile中添加几行代码，打开Rakefile文件，把下列内容粘贴进去。

```
namespace :docker do
  desc "Remove docker container"
  task :clean do
    sh './clean.sh'
  end

  desc "Build Docker image"
  task :build => [:clean] do
    sh './build.sh'
  end

  desc "Deploy Docker image"
  task :deploy => [:build] do
    sh './deploy.sh'
  end
end

```

即使你不清楚rake的语法（其实你真应该去了解一下，这玩意太酷了！），上面的内容也是很显然的吧。我们在一个命名空间（docker）里声明了三个任务。

三个任务是：

* rake docker:clean
* rake docker:build
* rake docker:deploy

Deploy独立于build，build独立于clean。所以每次我们输入命令运行的时候。

```
$ rake docker:deploy

```

所有的脚本都会按照顺序执行。

### 测试

现在我们来看看是否一切正常，你只需要在app的代码里做一个小改动：

```
$ rake docker:deploy

```

接下来就是见证奇迹的时刻了。一旦镜像文件被上传（第一次可能花费较长的时间），你就可以ssh登录产品服务器，并且（通过SSH管道）把docker镜像拉取到服务器并运行了。多么简单！

也许你需要一段时间来习惯，但是一旦成功，它几乎与用Heroku部署一样简单。

备注：像往常一样，请让我了解到你的意见。我不敢保证这种方法是最好，最快，或者最安全的Docker开发的方法，但是这东西对我们确实奏效。

---

via: <http://cocoahunter.com/2015/01/23/docker-3/>

作者：[Michelangelo Chasseur](http://cocoahunter.com/author/michelangelo/) 译者：[DongShuaike](https://github.com/DongShuaike) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译，[Linux中国](http://linux.cn/) 荣誉推出


如何修复 apt-get update 无法添加新的 CD-ROM 的错误

Summary: 这些天我正在体验Elementary OS Freya，在这期间，我遇到了一个非常常见的更新错误：Failed to fetch cdrom Please use apt-cdrom to make this CD-ROM recognized by APT. apt-get update cannot be used to add new CD-ROMs。完整的错误在运行apt-get update后看上去像这样：  W: Failed to fetch cdrom://elementary OS 0.3 Freya  Daily amd64 (20150208)/dists/trusty/main/binary-amd64/Packages Please use apt-cdrom to make this CD-ROM recognized by APT. apt-get update cannot be used to add new CD-ROMs W: Failed to fetc

看了本文，逆向思维，我大概知道了，要是在无法联网情况下，如何配置apt本地源

![](/data/attachment/album/201505/08/102935lutcjkyukbzjb0cl.jpg)

这些天我正在体验Elementary OS Freya，在这期间，我遇到了一个非常常见的更新错误：**Failed to fetch cdrom Please use apt-cdrom to make this CD-ROM recognized by APT. apt-get update cannot be used to add new CD-ROMs**。完整的错误在运行apt-get update后看上去像这样：

>
> W: Failed to fetch cdrom://elementary OS 0.3 *Freya* – Daily amd64 (20150208)/dists/trusty/main/binary-amd64/Packages Please use apt-cdrom to make this CD-ROM recognized by APT. apt-get update cannot be used to add new CD-ROMs
>
>
> W: Failed to fetch cdrom://elementary OS 0.3 *Freya* – Daily amd64 (20150208)/dists/trusty/restricted/binary-amd64/Packages Please use apt-cdrom to make this CD-ROM recognized by APT. apt-get update cannot be used to add new CD-ROMs
>
>
> E: Some index files failed to download. They have been ignored, or old ones used instead.
>
>
>

本篇中，我们会了解如何修复这个错误。

### 修复apt-get update无法添加新的CD-ROM的错误

这个错误的原因是cdrom已经被包含在源之中。要修复这个问题，我们需要将它从软件源中移除。

在Ubuntu中，找到“软件与更新”：

![](/data/attachment/album/201505/08/102935i955dp0ujgtuuu6u.jpg)

在Ubuntu Software的第一个标签中，找到cdrom，如果它是勾选的，那么取消勾选。

![](/data/attachment/album/201505/08/102936kg7s7ktfa7aflkde.jpg)

关闭软件源并再次运行更新。现在应该可以用了。

### 进一步故障排除：

上面描述的方法已经修复了这个**apt-get update cannot be used to add new CD-ROMs**错误。但是这个方法对我无效，因为cdrom的选项这时是灰色的，因为我使用的live版本。

![](/data/attachment/album/201505/08/102936jewm54skws4am4os.png)

现在要修复我们的问题了，我们是要采用命令行路线。打开终端并查看软件源中包含了哪些源：

```
cat /etc/apt/sources.list

```

我的输出是下面这样：

```
deb cdrom:[elementary OS 0.3 _Freya_ – Daily amd64 (20150208)]/ trusty main restricted
deb http://archive.ubuntu.com/ubuntu/ trusty main restricted universe multiverse
deb-src http://archive.ubuntu.com/ubuntu/ trusty main restricted universe multiverse
deb http://security.ubuntu.com/ubuntu/ trusty-security main restricted universe multiverse
deb-src http://security.ubuntu.com/ubuntu/ trusty-security main restricted universe multiverse
deb http://archive.ubuntu.com/ubuntu/ trusty-updates main restricted universe multiverse
deb-src http://archive.ubuntu.com/ubuntu/ trusty-updates main restricted universe multiverse

```

在上面的第一行中。它包含了cdrom。我们需要用‘#’来注释掉这行：

```
#deb cdrom:[elementary OS 0.3 _Freya_ – Daily amd64 (20150208)]/ trusty main restricted

```

要用下面的命令来：

```
sudo gedit /etc/apt/sources.list

```

在你编辑完软件源后，再次运行apt-get update。“apt-get update cannot be used to add new CD-ROMs”这个错误应该已经修复了。如果你还遇到其他的问题，看一下这篇收集了大部分[Ubuntu常见更新错误修复](http://itsfoss.com/fix-update-errors-ubuntu-1404/)的文章。

我希望这篇教程对你有用。如果你还有其他的问题和建议，请在下面留言。

---

via: <http://itsfoss.com/fix-failed-fetch-cdrom-aptget-update-add-cdroms/>

作者：[Abhishek](http://itsfoss.com/author/abhishek/) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译，[Linux中国](http://linux.cn/) 荣誉推出


在 RedHat/CentOS 7.x 中使用 nmcli 命令管理网络

Summary: Red Hat Enterprise Linux 7 与 CentOS 7 中默认的网络服务由 NetworkManager 提供，这是动态控制及配置网络的守护进程，它用于保持当前网络设备及连接处于工作状态，同时也支持传统的 ifcfg 类型的配置文件。 NetworkManager 可以用于以下类型的连接：Ethernet，VLANS，Bridges，Bonds，Teams，Wi-Fi，mobile boradband（如移动3G）以及 IP-over-InfiniBand。针对与这些网络类型，NetworkManager 可以配置他们的网络别名，IP 地址，静态路由，DNS，VPN连接以及很多其它的特殊参数。 可以用命令行工具 nmcli 来控制 NetworkManager。  nmc

好好学习，天天向上！

[**Red Hat Enterprise Linux 7**](https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/7/html/7.0_Release_Notes/) 与 **CentOS 7** 中默认的网络服务由 **NetworkManager** 提供，这是动态控制及配置网络的守护进程，它用于保持当前网络设备及连接处于工作状态，同时也支持传统的 ifcfg 类型的配置文件。

NetworkManager 可以用于以下类型的连接：Ethernet，VLANS，Bridges，Bonds，Teams，Wi-Fi，mobile boradband（如移动3G）以及 IP-over-InfiniBand。针对与这些网络类型，NetworkManager 可以配置他们的网络别名，IP 地址，静态路由，DNS，VPN连接以及很多其它的特殊参数。

可以用命令行工具 nmcli 来控制 NetworkManager。

![](/data/attachment/album/201505/08/104619yi1ioj1xrokaxkrx.png)

### nmcli 用法

```
# nmcli [ OPTIONS ] OBJECT { COMMAND | help }

```

我们可以通过 TAB 键补全命令，当你忘记这个命令的语法时只需要按下 TAB 就可以看到选项列表。

![nmcli tab](/data/attachment/album/201505/08/104640bg3glmtt38uly36t.jpg)

使用 nmcli 的一些例子：

```
# nmcli general status

```

这条命令将 NetworkManager 的所有状态都打印出来。

```
# nmcli connection show

```

显示所有连接。

```
# nmcli connection show -a
```

仅显示当前活动的连接。

```
# nmcli device status

```

列出 NetworkManager 识别出的设备列表及他们的状态。

![nmcli general](/data/attachment/album/201505/08/104641ii7hckji22211144.jpg)

### 启动/停止 网络接口

使用 nmcli 工具启动或停止网络接口，与 ifconfig 的 up/down 是一样的。

使用下列命令停止某个接口：

```
# nmcli device disconnect eno16777736

```

下列命令用来启动接口：

```
# nmcli device connect eno16777736

```

### 添加静态IP的以太网连接

以下命令可以添加一个静态IP地址的以太网连接：

```
# nmcli connection add type ethernet con-name NAME_OF_CONNECTION ifname interface-name ip4 IP_ADDRESS gw4 GW_ADDRESS

```

根据你需要的配置更改 NAME\_OF\_CONNECTION,IP\_ADDRESS, GW\_ADDRESS 参数（如果不需要网关的话可以省略最后一部分）。

```
# nmcli connection add type ethernet con-name NEW ifname eno16777736 ip4 192.168.1.141 gw4 192.168.1.1

```

使用下列命令设置DNS服务器：

```
# nmcli connection modify NEW ipv4.dns "8.8.8.8 8.8.4.4"

```

下列命令启动新的 Ethernet 连接：

```
# nmcli connection up NEW ifname eno16777736

```

查看新连接的配置信息：

```
# nmcli -p connection show NEW

```

![nmcli add static](/data/attachment/album/201505/08/104642xrzr5r49j5o6vv5e.jpg)

### 增加一个使用 DHCP 的新连接

增加新的连接，使用DHCP自动分配IP地址，网关，DNS等，你要做的就是将命令行后 ip/gw 地址部分去掉就行了，DHCP会自动分配这些参数。

例，在 eno 16777736 设备上配置一个 名为 NEW\_DHCP 的 DHCP 连接

```
# nmcli connection add type ethernet con-name NEW_DHCP ifname eno16777736

```

---

via: <http://linoxide.com/linux-command/nmcli-tool-red-hat-centos-7/>

作者：[Adrian Dinu](http://linoxide.com/author/adriand/) 译者：[SPccman](https://github.com/SPccman) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译，[Linux中国](http://linux.cn/) 荣誉推出


Linux有问必答：如何在Linux下禁用IPv6

Summary: 问题：我发现我的一个应用程序在尝试通过IPv6建立连接，但是由于我们本地网络不允许分配IPv6的流量，IPv6连接会超时，应用程序的连接会回退到IPv4，这样就会造成不必要的延迟。由于我目前对IPv6没有任何需求，所以我想在我的Linux主机上禁用IPv6。有什么比较合适的方法呢？  IPv6被认为是IPv4互联网上的传统32位地址空间的替代产品，它用来解决现有IPv4地址空间即将耗尽的问题。然而，由于已经有大量主机、设备用IPv4连接到了互联网上，所以想在一夜之间将它们全部切换到IPv6几乎是不可能的。许多IPv4到IPv6的转换机制(例如：双协议栈、网

学习了，先禁用了，目前根本用不到

我不会告诉你 学校到额网络支持IPV6，所以除了google之外的网站可以进的去 ，qiang 很少

所以，其实国家在普及 IPv6上虽然喊了很多年，但是其实很消极，事实上，也有墙的因素。

>
> **问题**：我发现我的一个应用程序在尝试通过IPv6建立连接，但是由于我们本地网络不允许分配IPv6的流量，IPv6连接会超时，应用程序的连接会回退到IPv4，这样就会造成不必要的延迟。由于我目前对IPv6没有任何需求，所以我想在我的Linux主机上禁用IPv6。有什么比较合适的方法呢？
>
>
>

IPv6被认为是IPv4——互联网上的传统32位地址空间——的替代产品，它用来解决现有IPv4地址空间即将耗尽的问题。然而，由于已经有大量主机、设备用IPv4连接到了互联网上，所以想在一夜之间将它们全部切换到IPv6几乎是不可能的。许多IPv4到IPv6的转换机制(例如：双协议栈、网络隧道、代理) 已经被提出来用来促进IPv6能被采用，并且很多应用也正在进行重写，如我们所提倡的，来增加对IPv6的支持。有一件事情可以确定，就是在可预见的未来里IPv4和IPv6势必将共存。

![](/data/attachment/album/201505/09/203853n903vr6v6revnrun.png)

理想情况下，[向IPv6过渡的进程](http://www.google.com/intl/en/ipv6/statistics.html)不应该被最终的用户所看见，但是IPv4/IPv6混合环境有时会让你碰到各种源于IPv4和IPv6之间不经意间的相互碰撞的问题。举个例子，你会碰到应用程序超时的问题，比如apt-get或ssh尝试通过IPv6连接失败、DNS服务器意外清空了IPv6的AAAA记录、或者你支持IPv6的设备不兼容你的互联网服务提供商遗留下的IPv4网络，等等等等。

当然这不意味着你应该盲目地在你的Linux机器上禁用IPv6。鉴于IPv6许诺的种种好处，作为社会的一份子我们最终还是要充分拥抱它的，但是作为给最终用户进行故障排除过程的一部分，如果IPv6确实是罪魁祸首，那你可以尝试去关闭它。

这里有一些让你在Linux中部分(例如：对于某个特定的网络接口)或全部禁用IPv6的小技巧。这些小贴士应该适用于所有主流的Linux发行版包括Ubuntu、Debian、Linux Mint、CentOS、Fedora、RHEL以及Arch Linux。

### 查看IPv6在Linux中是否被启用

所有现代Linux发行版默认都自动启用IPv6。为了能看到IPv6在你的Linux中是否被激活，可以使用ifconfig或ip命令。如果你在输入这些命令之后看到"inet6"字样的输出，那就意味着你的Linux系统启用了IPv6。

```
$ ifconfig

```

![](/data/attachment/album/201505/09/204020oumokf9ngjmyxxym.jpg)

```
$ ip addr

```

![](/data/attachment/album/201505/09/204028vpehk73c2keivhb8.jpg)

### 临时禁用IPv6

如果你想要在你的Linux系统上临时关闭IPv6，你可以用 /proc 文件系统。"临时"的意思是我们所做的禁用IPv6的更改在系统重启后将不被保存。IPv6会在你的Linux机器重启后再次被启用。

要将一个特定的网络接口禁用IPv6，使用以下命令：

```
$ sudo sh -c 'echo 1 > /proc/sys/net/ipv6/conf/<interface-name>/disable_ipv6'

```

举个例子，将eth0接口禁用IPv6：

```
$ sudo sh -c 'echo 1 > /proc/sys/net/ipv6/conf/eth0/disable_ipv6'

```

![](/data/attachment/album/201505/09/204039epupn33kgp6g1wkz.jpg)

重新启用eth0接口的IPv6：

```
$ sudo sh -c 'echo 0 > /proc/sys/net/ipv6/conf/eth0/disable_ipv6'

```

如果你想要将整个系统所有接口包括回环接口禁用IPv6，使用以下命令：

```
$ sudo sh -c 'echo 1 > /proc/sys/net/ipv6/conf/all/disable_ipv6'

```

### 永久禁用IPv6

以上方法是不能永久禁用IPv6的，你一旦重启系统IPv6还是会被启用。如果你想要永久关闭它，有几个方法你可以试试。

#### 方法一

第一种方法是通过 /etc/sysctl.conf 文件对 /proc 进行永久修改。

换句话说，就是用文本编辑器打开 /etc/sysctl.conf 然后添加以下内容：

```
# 禁用整个系统所有接口的IPv6
net.ipv6.conf.all.disable_ipv6 = 1

# 禁用某一个指定接口的IPv6(例如：eth0, lo)
net.ipv6.conf.lo.disable_ipv6 = 1
net.ipv6.conf.eth0.disable_ipv6 = 1

```

在 /etc/sysctl.conf 使这些更改生效，运行以下命令：

```
$ sudo sysctl -p /etc/sysctl.conf

```

或者直接重启。

#### 方法二

另一个永久禁用IPv6的方法是在开机的时候传递一个必要的内核参数。

用文本编辑器打开 /etc/default/grub 并给GRUB*CMDLINE*LINUX变量添加"ipv6.disable=1"。

```
$ sudo vi /etc/default/grub

```

---

```
GRUB_CMDLINE_LINUX="xxxxx ipv6.disable=1"

```

上面的"xxxxx"代表任何已有的内核参数，在它后面添加"ipv6.disable=1"。

![](/data/attachment/album/201505/09/204054p8jzpjlbfdr1eab8.jpg)

最后，不要忘记用以下方法保存对GRUB/GRUB2的修改：

Debian、Ubuntu或Linux Mint系统：

```
$ sudo update-grub

```

Fedora、CentOS/RHEL系统：

```
$ sudo grub2-mkconfig -o /boot/grub2/grub.cfg

```

现在只要你重启你的Linux系统，IPv6就会完全被禁用。

### 禁用IPv6之后的其它可选步骤

这里有一些在你禁用IPv6后需要考虑的可选步骤，这是因为当你在内核里禁用IPv6后，其它程序也许仍然会尝试使用IPv6。在大多数情况下，应用程序的这种行为不太会影响到什么，但是出于效率或安全方面的原因，你可以为他们禁用IPv6。

#### /etc/hosts

根据你的设置， /etc/hosts 会包含一条或多条IPv6的hosts和它们的地址。用文本编辑器打开 /etc/hosts 并注释掉包含IPv6 hosts的脚本行。

```
$ sudo vi /etc/hosts

```

---

```
# comment these IPv6 hosts
# ::1     ip6-localhost ip6-loopback
# fe00::0 ip6-localnet
# ff00::0 ip6-mcastprefix
# ff02::1 ip6-allnodes
# ff02::2 ip6-allrouters

```

#### Network Manager

如果你在用NetworkManager来管理你的网络设置，你可以在NetworkManager里禁用IPv6。在NetworkManager打开wired connection，点击"IPv6 Settings"选项并在"Method"一栏选择"Ignore"，保存退出。

![](/data/attachment/album/201505/09/204055g1izpc3ix2u2u2cp.png)

#### SSH服务

默认情况下，OpenSSH服务(sshd)会去尝试捆绑IPv4和IPv6的地址。

要强制sshd只捆绑IPv4地址，用文本编辑器打开 /etc/ssh/sshd\_config 并添加以下行。inet只适用于IPv4，而inet6是适用于IPv6的。

```
$ sudo vi /etc/ssh/sshd_config

```

---

```
AddressFamily inet

```

然后重启sshd服务。

---

via: <http://ask.xmodulo.com/disable-ipv6-linux.html>

作者：[Dan Nanni](http://ask.xmodulo.com/author/nanni) 译者：[ZTinoZ](https://github.com/ZTinoZ) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译，[Linux中国](http://linux.cn/) 荣誉推出


25个 Git 进阶技巧

Summary: 我已经使用git差不多18个月了，觉得自己对它应该已经非常了解。然后来自GitHub的Scott Chacon过来给LVS做培训（LVS是一个赌博软件供应商和开发商，从2013年开始的合同），而我在第一天里就学到了很多。 作为一个对git感觉良好的人，我觉得分享从社区里掌握的一些有价值的信息，也许能帮某人解决问题而不用做太深入研究。  基本技巧 1. 安装后的第一步 在安装好git后，你第一件该做的事是设置你的名字和电子邮箱，因为每次提交都要用到这些信息： $ git config --global user.name "Some One" $ git config --global user.email "someone@g

很好的文章，学习了

楼主总结的很实用啊。赞！

我已经使用git差不多18个月了，觉得自己对它应该已经非常了解。然后来自GitHub的[Scott Chacon](http://gitcasts.com/about)过来给LVS做培训（[LVS是一个赌博软件供应商和开发商](http://www.lvs.co.uk/)，从2013年开始的合同），而我在第一天里就学到了很多。

作为一个对git感觉良好的人，我觉得分享从社区里掌握的一些有价值的信息，也许能帮某人解决问题而不用做太深入研究。

![](/data/attachment/album/201505/09/220247v3k9499t5ov03kvv.jpg)

### 基本技巧

#### 1. 安装后的第一步

在安装好git后，你第一件该做的事是设置你的名字和电子邮箱，因为每次提交都要用到这些信息：

```
$ git config --global user.name "Some One"
$ git config --global user.email "someone@gmail.com"

```

#### 2. Git是基于指针的

保存在git里的一切都是文件。当你创建一个提交的时候，会建立一个包含你的提交信息和相关数据（名字，邮件地址，日期/时间，前一个提交，等等）的文件，并把它链接到一个树文件中。这个树文件中包含了对象或其他树的列表。这里的提到的对象（或二进制大对象）是和本次提交相关的实际内容（它也是一个文件，另外，尽管文件名并没有包含在对象里，但是存储在树中）。所有这些文件都使用对象的SHA-1哈希值作为文件名。

用这种方式，分支和标签就是简单的文件（基本上是这样），包含指向该提交的SHA-1哈希值。使用这些索引会带来优秀的灵活性和速度，比如创建一个新分支就是简单地用分支名字和所分出的那个提交的SHA-1索引来创建一个文件。当然，你不需要自己做这些，而只要使用Git命令行工具（或者GUI），但是实际上就是这么简单。

你也许听说过叫HEAD的索引。这只是简单的一个文件，包含了你当前指向的那个提交的SHA-1索引值。如果你正在解决一次合并冲突然后看到了HEAD，这并不是一个特别的分支或分支上的一个必需的特殊位置，只是标明你当前所在位置。

所有的分支指针都保存在.git/refs/heads里，HEAD在.git/HEAD里，而标签保存在.git/refs/tags里 - 自己可以随便进去看看。

#### 3. 两个爸爸（父节点） - 你没看错！

在历史中查看一个合并提交的信息时，你将看到有两个父节点（不同于工作副本上的常规提交的情况）。第一个父节点是你所在的分支，第二个是你合并过来的分支。

#### 4. 合并冲突

目前我相信你碰到过合并冲突并且解决过。通常是编辑一下文件，去掉<<<<，====，>>>>标志，保留需要留下的代码。有时能够看到这两个修改之前的代码会很不错，比如，在这两个现在冲突的分支之前的改动。下面是一种方式：

```
$ git diff --merge
diff --cc dummy.rb
index 5175dde,0c65895..4a00477
--- a/dummy.rb
+++ b/dummy.rb
@@@ -1,5 -1,5 +1,5 @@@
  class MyFoo
    def say
-     puts "Bonjour"
 -    puts "Hello world"
++    puts "Annyong Haseyo"
    end
  end

```

如果是二进制文件，比较差异就没那么简单了...通常你要做的就是测试这个二进制文件的两个版本来决定保留哪个（或者在二进制文件编辑器里手工复制冲突部分）。从一个特定分支获取文件拷贝（比如说你在合并master和feature123两个分支）：

```
$ git checkout master flash/foo.fla # 或者...
$ git checkout feature132 flash/foo.fla
$ # 然后...
$ git add flash/foo.fla

```

另一种方式是通过git输出文件 - 你可以输出到另外的文件名，然后当你决定了要用哪个后，再将选定的正确文件复制为正常的文件名：

```
$ git show master:flash/foo.fla > master-foo.fla
$ git show feature132:flash/foo.fla > feature132-foo.fla
$ # 检出master-foo.fla和feature132-foo.fla
$ # 假如说我们决定来自feature132的文件是正确的
$ rm flash/foo.fla
$ mv feature132-foo.fla flash/foo.fla
$ rm master-foo.fla
$ git add flash/foo.fla

```

更新：感谢Carl在原博客文章上评论里的提醒，你实际上可以用“git checkout —ours flash/foo.fla”和“git checkout —theirs flash/foo.fla”来检出特定版本的文件，而不用记住你在合并的分支名字。就我个人来说喜欢更精确一点，但这也是一种方式...

记着在解决完冲突后要将文件加入提交（像我上面做的那样）。

### 服务器，分支和标签

#### 5. 远端服务器

git的一个超强大的功能就是可以有不止一个远端服务器（实际上你一直都在一个本地仓库上工作）。你并不是一定都要有这些服务器的写权限，你可以有多个可以读取的服务器（用来合并他们的工作）然后写入到另外一个仓库。添加一个新的远端服务器很简单：

```
$ git remote add john git@github.com:johnsomeone/someproject.git

```

如果你想查看远端服务器的信息可以这样做：

```
# 显示每个远端服务器的URL
$ git remote -v

# 提供更多详细信息
$ git remote show name

```

你随时都可以查看本地分支和远端分支的差异：

```
$ git diff master..john/master

```

你也可以查看没有在远端分支上的HEAD的改动：

```
$ git log remote/branch..
# 注意：..后面没有结束的特定引用

```

#### 6. 标签

在git里有两种类型的标签 - 轻量级标签和带注释标签。记住技巧2里说过git是基于指针的，这两者之间的差异也很简单。轻量级标签只是一个简单的指向一次提交的带名字指针。你随时都可以将它指向另一个提交。带注释标签是一个指向标签对象的带名字指针，带有自己的信息和历史。因为有自己的信息，它可以根据需要用GPG签名。

建立这两种类型的标签都很简单（只有一个命令行开关的差异）

```
$ git tag to-be-tested
$ git tag -a v1.1.0 # 会提示输入标签的信息

```

#### 7. 建立分支

在git里建立分支非常简单（而且像闪电一样快，因为它只需要创建一个小于100字节的文件）。用普通方式建立新分支并切换过去：

```
$ git branch feature132
$ git checkout feature132

```

当然，如果你确定自己直接切换到新建的分支，可以用一个命令实现：

```
$ git checkout -b feature132

```

如果你想重命名一个本地分支也很简单（可以显示发生了什么的较长的方式）：

```
$ git checkout -b twitter-experiment feature132
$ git branch -d feature132

```

更新：你也可以（像Brian Palmer在原博客文章的评论里提出的）只用“git branch”的-m开关在一个命令里实现（像Mike提出的，如果你只指定了一个分支参数，就会重命名当前分支）：

```
$ git branch -m twitter-experiment
$ git branch -m feature132 twitter-experiment

```

#### 8. 合并分支

也许在将来的某个时候，你希望将改动合并。有两种方式：

```
$ git checkout master
$ git merge feature83 # 或者...
$ git rebase feature83

```

merge和rebase之间的差别是merge会尝试处理改动并建立一个新的混合了两者的提交。rebase会尝试把你从一个分支最后一次分离后的所有改动，一个个加到该分支的HEAD上。不过，在已经将分支推到远端服务器后不要再rebase了 - 这会引起冲突/问题。

如果你不确定在哪些分支上还有独有的工作 - 所以你也不知道哪些分支需要合并而哪些可以删除，git branch有两个开关可以帮你：

```
# 显示已经全部合并到当前分支的分支
$ git branch --merged

# 显示没有合并到当前分支的分支
$ git branch --no-merged

```

#### 9. 远端分支

如果你在本地有一个分支希望推到远端服务器上，你可以用一行命令推送上去：

```
$ git push origin twitter-experiment:refs/heads/twitter-experiment
# origin是我们服务器的名字，而twitter-experiment是分支名字

```

更新：感谢Erlend在原博客文章上的评论 - 这个实际上和`git push origin twitter-experiment`效果一样，不过使用完整的语法，你可以在两者之间使用不同的分支名（这样本地分支可以是`add-ssl-support`而远端是`issue-1723`）。

如果你想在远端服务器上删除一个分支（注意分支名前面的冒号）：

```
$ git push origin :twitter-experiment

```

如果你想查看所有远端分支的状态可以这样做：

```
$ git remote show origin

```

这个命令可能会列出服务器上一些以前有过但现在已经不在了的分支。如果碰到这种情况你可以用下面的命令从你本地分支里清理掉：

```
$ git remote prune

```

最后，如果你想在本地跟踪一个远端分支，普通的方式是：

```
$ git branch --track myfeature origin/myfeature
$ git checkout myfeature

```

不过，新版的git在使用-b标记检出分支时会自动设定跟踪：

```
$ git checkout -b myfeature origin/myfeature

```

### 在储藏点，索引和文件系统中保存内容

#### 10. 储藏

在git里你可以把当前工作状态放进一个储藏堆栈中，然后可以再取出来。最简单的情形是下面这样：

```
$ git stash
# 做点其他事情...
$ git stash pop

```

许多人建议使用`git stash apply`来代替pop，不过如果这样做的话最后会遗留一个很长的储藏列表。而“pop”会在全部加载后自动从堆栈中移除。如果使用过`git stash apply`，你也可以使用下面的命令从堆栈上移除最后一项：

```
$ git stash drop

```

git会基于当前的提交信息自动创建评论。如果你更希望有自定义信息的话（因为它可能和前一个提交没有任何联系）：

```
$ git stash save "My stash message"

```

如果你希望从列表中取出一个特定的储藏点（不一定非得是最后一个）可以先列出它们然后用下面的方式取出：

```
$ git stash list
  stash@{0}: On master: Changed to German
  stash@{1}: On master: Language is now Italian
$ git stash apply stash@{1}

```

#### 11. 交互式添加

在subversion的世界里你只能修改文件然后提交所有改动。而在git里你有强大得多的方式来提交部分文件或者甚至是部分补丁。提交部分文件或文件中的部分改动你需要进入交互式模式：

```
$ git add -i
           staged     unstaged path

*** Commands ***
  1: status      2: update   3: revert   4: add untracked
  5: patch      6: diff     7: quit     8: help
What now>

```

这会让你进入一个基于菜单的交互式提示。你可以使用命令中的数字或高亮的字母（如果你在终端里打开了高亮的话）来进入相应的模式。然后就只是输入你希望操作的文件的数字了（你可以使用这样的格式，1或者1-4或2,4,7）。

如果你想进入补丁模式（交互式模式下按‘p’或‘5’），你也可以直接进入：

```
$ git add -p
diff --git a/dummy.rb b/dummy.rb
index 4a00477..f856fb0 100644
--- a/dummy.rb
+++ b/dummy.rb
@@ -1,5 +1,5 @@
 class MyFoo
   def say
-    puts "Annyong Haseyo"
+    puts "Guten Tag"
   end
 end
Stage this hunk [y,n,q,a,d,/,e,?]?

```

你可以看到下方会有一些选项供选择用来添加该文件的这个改动、该文件的所有改动，等等。使用‘?’命令可以详细解释这些选项。

#### 12. 从文件系统里保存/取回改动

有些项目（比如Git项目本身）在git文件系统中直接保存额外文件而并没有将它们加入到版本控制中。

让我们从在git中存储一个随机文件开始：

```
$ echo "Foo" | git hash-object -w --stdin
51fc03a9bb365fae74fd2bf66517b30bf48020cb

```

这样这个目标文件就已经保存到数据库中了，但是如果你没有设定一个指向它的指针的话它会被当做垃圾回收。最简单的方式是设定一个标签：

```
$ git tag myfile 51fc03a9bb365fae74fd2bf66517b30bf48020cb

```

注意这里我们使用了标签myfile。当我们需要使用这个文件的时候可以这样做：

```
$ git cat-file blob myfile

```

这个对于一些工具文件很有用，开发者可能会用到（密码，GPG密钥，等等）但是又不希望每次都检出到硬盘（尤其是在实际工作中）。

### 日志以及有哪些改动？

#### 13. 查看日志

长时间使用 Git 的话，不会没用过‘git log’来查看最近的提交。不过，有一些技巧来更好地应用。比如，你可以使用下面的命令来查看每次提交的具体改动：

```
$ git log -p

```

或者你可以仅仅查看有哪些文件改动：

```
$ git log --stat

```

有个很不错的别名你可以试试，会显示简短提交名和一个不错的分支图并在一行里显示提交信息（有点像gitk，但是是在命令行下）：

```
$ git config --global alias.lol "log --pretty=oneline --abbrev-commit --graph --decorate"
$ git lol
* 4d2409a (master) Oops, meant that to be in Korean
* 169b845 Hello world

```

#### 14. 搜索日志

如果你想找特定提交者可以这样做：

```
$ git log --author=Andy

```

更新：感谢Johannes的评论，我已经去掉了之前这里的一些有混淆的地方。

或者你想在提交信息里找一些相关字段：

```
$ git log --grep="Something in the message"

```

也有一个更强大的叫做pickaxe的命令用来查找包含了删除或添加的某个特定内容的提交（比如，该内容第一次出现或被删除）。这可以告诉你什么时候增加了一行（但这一行里的某个字符后面被改动过就不行了）：

```
$ git log -S "TODO: Check for admin status"

```

假如你改动了一个特定的文件，比如`lib/foo.rb`

```
$ git log lib/foo.rb

```

比如说你有一个`feature/132`分支和`feature/145`分支，然后你想看看这两个分支上不在master分支里的提交（注意 符号是不在的意思）：

```
$ git log feature/132 feature/145 ^master

```

你也可以使用ActiveSupport格式的日期来缩小到某个日期范围：

```
$ git log --since=2.months.ago --until=1.day.ago

```

默认情况下会用OR来组合查询，但你可以轻易地改为AND（如果你有超过一条的查询标准）

```
$ git log --since=2.months.ago --until=1.day.ago --author=andy -S "something" --all-match

```

#### 15. 查看/修改版本

有很多方式可以用来引用一个版本，看你记得哪个：

```
$ git show 12a86bc38 # 根据版本
$ git show v1.0.1 # 根据标签
$ git show feature132 # 根据分支名
$ git show 12a86bc38^ # 一次提交的父节点
$ git show 12a86bc38~2 # 一次提交的祖父节点
$ git show feature132@{yesterday} # 时间相关
$ git show feature132@{2.hours.ago} # 时间相关

```

注意和之前部分有些不同，末尾的 的意思是该提交的父节点 - 开始位置的 的意思是不在这个分支。

#### 16. 选择范围

最简单的方式：

```
$ git log origin/master..new
# [old]..[new] - 所有你还没有推送的提交

```

你也可以省略[new]，将使用当前的HEAD。

### 时光回溯和后悔药

#### 17. 重置改动

如果你还没有提交的话可以用下面的命令轻松地取消改动：

```
$ git reset HEAD lib/foo.rb

```

通常会使用‘unstage’的别名，因为上面的看上去有些不直观。

```
$ git config --global alias.unstage "reset HEAD"
$ git unstage lib/foo.rb

```

如果你已经提交了该文件，你可以做两件事 - 如果是最后一次提交你还可以改正：

```
$ git commit --amend

```

这会取消最后一次提交，把工作分支回退到提交前标记了所有改动的状态，而且提交信息也都准备好可以修改或直接提交。

如果你已经提交过多次而且希望全部回退，你可以将分支重置到合适的位置。

```
$ git checkout feature132
$ git reset --hard HEAD~2

```

如果你实际上希望将分支指向一个完全不同的SHA1（也许你要将一个分支的HEAD替换到另一个分支，或者之后的某次提交）你可以使用下面的较长的方式：

```
$ git checkout FOO
$ git reset --hard SHA

```

实际上有一个快速的方式（不需要先把你的工作分支切换到FOO再前进到SHA）：

```
$ git update-ref refs/heads/FOO SHA

```

#### 18. 提交到了错误的分支

好吧，假如说你已经提交到了master，但却应该创建一个叫experimental的主题分支更合适。要移动这些改动，你可以在当前位置创建分支，回退HEAD再检出新分支：

```
$ git branch experimental   # 创建一个指向当前master的位置的指针
$ git reset --hard master~3 # 移动master分支的指针到3个版本之前
$ git checkout experimental

```

如果你的改动是在分支的分支的分支上会更复杂。那样你需要做的是将分支基础切换到其他地方：

```
$ git branch newtopic STARTPOINT
$ git rebase oldtopic --onto newtopic

```

#### 19. 交互式切换基础

这是一个我之前看过展示却没真正理解过的很赞的功能，现在觉得它就很简单了。假如说你提交了3次但是你希望更改顺序或编辑（或者合并）：

```
$ git rebase -i master~3

```

然后这会启动你的编辑器并带有一些指令。你所要做的就是修改这些指令来选择/插入/编辑（或者删除）提交和保存/退出。然后在编辑完后你可以用`git rebase --continue`命令来让每一条指令生效。

如果你有修改，将会切换到你提交时所处的状态，之后你需要使用命令git commit --amend来编辑。

**注意：在rebase的时候千万不要提交 - 只能先添加然后使用参数--continue，--skip或--abort。**

#### 20. 清理

如果你提交了一些内容到你的分支（也许你从SVN导入了一些旧仓库），然后你希望把某个文件从历史记录中全部删掉：

```
$ git filter-branch --tree-filter 'rm -f *.class' HEAD

```

如果你已经推送到origin了，但之后提交了一些垃圾改动，你也可以在推送前在本地系统里这样做：

```
$ git filter-branch --tree-filter 'rm -f *.class' origin/master..HEAD

```

### 其他技巧

#### 21. 你查看过的前一个引用

如果你知道自己之前查看过一个SHA-1，但是随后做了一些重置/回退的操作，你可以使用reflog命令来列出最近查看过的SHA-1记录：

```
$ git reflog
$ git log -g # 和上面一样，但是使用'log'格式输出

```

#### 22. 分支命名

一个可爱的小技巧 - 别忘了分支名并不限于a-z和0-9。名字中可以用/和.将非常方便用来建立伪命名空间或版本，例如：

```
$ # 生成版本132的改动历史
$ git shortlog release/132 ^release/131
$ # 贴上v1.0.1的标签
$ git tag v1.0.1 release/132

```

#### 23. 找出谁是凶手

通常找出来谁改动了某个文件里的某行代码会很有用。实现这个功能的最简单命令是：

```
$ git blame FILE

```

有时候这些改动来自其他文件（如果你合并了两个文件，或者你移动了某个函数）所以你可以使用下面的命令：

```
$ # 显示内容来自哪个文件
$ git blame -C FILE

```

有时候通过点击各个改动然后回到很早很早以前来跟踪改动会很不错。有一个很好的内建GUI命令来做这个：

```
$ git gui blame FILE

```

#### 24. 数据维护

通常git不需要经常维护，它把自己照顾的很好。不过，你可以通过下面的命令查看数据统计：

```
$ git count-objects -v

```

如果占用很多空间的话，你可以选择在你的本地仓库做垃圾回收。这不会影响推送或其他人，却会让一些命令运行更快而且减少空间占用：

```
$ git gc

```

经常运行完整性检查也很有意义：

```
$ git fsck --full

```

你也可以在末尾加上`--auto`参数（如果你在服务器上通过crontab经常/每天都运行这个命令的话），然后它只会在必要的时候才执行fsck动作。

在检查的时候，看到“dangling”或“unreachable”是正常的，通常这是由回退HEAD或切换基础的结果。而看到“missing”或“sha1 mismatch”就不对了...找专业人士帮忙吧！

#### 25. 恢复遗失的分支

如果你使用-D参数删除了experimental分支，可以用下面的命令重新建立：

```
$ git branch experimental SHA1_OF_HASH

```

如果你最近访问过的话，你通常可以用git reflog来找到SHA1哈希值。

另一种方式是使用`git fsck —lost-found`。其中一个dangling的提交就是丢失的HEAD（它只是已删除分支的HEAD，而HEAD 被引用为当前的HEAD所以它并不处于dangling状态）

### 搞定！

哇，这是我写过的最长的一篇博客，我希望有人能觉得有用。如果你这么觉得，或者你有任何疑问请在评论里留言让我知道...

---

via: <https://www.andyjeffries.co.uk/25-tips-for-intermediate-git-users/>

作者：[Andy Jeffries](https://www.andyjeffries.co.uk/author/andy-jeffries/) 译者：[zpl1025](https://github.com/zpl1025) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译，[Linux中国](http://linux.cn/) 荣誉推出


如何修复 Ubuntu 上“...script returned error exit status 1”的错误

Summary: 今天，我在更新VirtualBox新版本的时候遇到了一个问题。  E: /var/cache/apt/archives/ subprocess new pre-removal script returned error exit status 1   解决： 我google了一下并找到了方法。下面是我解决的方法。 sudo apt-get clean sudo apt-get update  sudo apt-get upgrade  这样几乎可以修复这个问题了。 如果你仍然有问题，那就试试下面的命令： sudo dpkg --configure -a sudo apt-get -f install  或者你可以按照下面的方法从Oracle VirtualBox官网下载最新版本并安装。 sudo apt-get update sudo dpkg -i virtualbox-4.3_4

今天，我在更新VirtualBox新版本的时候遇到了一个问题。

>
> E: /var/cache/apt/archives/ subprocess new pre-removal script returned error exit status 1
>
>
>

![](/data/attachment/album/201505/09/220717k9khaaa0k1683q2q.png)

### 解决：

我google了一下并找到了方法。下面是我解决的方法。

```
sudo apt-get clean
sudo apt-get update && sudo apt-get upgrade

```

这样几乎可以修复这个问题了。

如果你仍然有问题，那就试试下面的命令：

```
sudo dpkg --configure -a
sudo apt-get -f install

```

或者你可以按照下面的方法从[Oracle VirtualBox](https://www.virtualbox.org/wiki/Downloads)官网下载最新版本并安装。

```
sudo apt-get update
sudo dpkg -i virtualbox-4.3_4.3.24-98716~Ubuntu~raring_amd64.deb
sudo apt-get -f install
sudo apt-get autoclean && sudo apt-get autoremove

```

干杯！

---

via: <http://www.unixmen.com/linux-basics-how-to-fix-e-varcacheaptarchives-subprocess-new-pre-removal-script-returned-error-exit-status-1-in-ubuntu/>

作者：[SK](https://www.unixmen.com/author/sk/) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译，[Linux中国](http://linux.cn/) 荣誉推出


使用 Prey 定位被盗的 Ubuntu 笔记本与智能电话

Summary: Prey是一款跨平台的开源工具，可以帮助你找回被盗的笔记本，台式机，平板和智能手机。它已经获得了广泛的流行，声称帮助找回了成百上千台丢失的笔记本和智能手机。Prey的使用特别简单，首先安装在你的笔记本或者手机上，当你的设备不见了，用你的账号登入Prey网站，并且标记你的设备为丢失。只要小偷将设备接入网络，Prey就会马上发送设备的地理位置给你。如果你的笔记本有摄像头，它还会拍下该死的贼。 Prey占用很小的系统资源；你不会对你的设备运行有任何影响。你也可以配合其他你已经在设备上安装的防盗软件使用。Prey在你的设备与Pre

首先抹盘.....

先关网卡

个人版，54美元1年<br />
不能免费用？

存储加密 才是真理

存储加密 才是真理

Prey是一款跨平台的开源工具，可以帮助你找回被盗的笔记本，台式机，平板和智能手机。它已经获得了广泛的流行，声称帮助找回了成百上千台丢失的笔记本和智能手机。Prey的使用特别简单，首先安装在你的笔记本或者手机上，当你的设备不见了，用你的账号登入Prey网站，并且标记你的设备为“丢失”。只要小偷将设备接入网络，Prey就会马上发送设备的地理位置给你。如果你的笔记本有摄像头，它还会拍下该死的贼。

Prey占用很小的系统资源；你不会对你的设备运行有任何影响。你也可以配合其他你已经在设备上安装的防盗软件使用。Prey在你的设备与Prey服务器之间采用安全加密的通道进行数据传输。

![](/data/attachment/album/201505/09/222242k1bqi6shsb7zzaix.jpg)

### 在Ubuntu上安装并配置Prey

让我们来看看如何在Ubuntu上安装和配置Prey，需要提醒的是，在配置过程中，我们必须到Prey官网进行账号注册。一旦完成上述工作，Prey将会开始监视你的设备了。免费的账号最多可以监视三个设备，如果你需要添加更多的设备，你就需要购买合适的的套餐了。

可以想象Prey多么流行与被广泛使用，它现在已经被添加到了官方的软件库中了。这意味着你不要往软件包管理器添加任何PPA。很简单，登录你的终端，运行以下的命令来安装它：

```
sudo apt-get install prey

```

![Install Prey](/data/attachment/album/201505/09/222304yng42gnykmn4mpx6.png)

![Install Prey 1](/data/attachment/album/201505/09/222305d1ds61sl444z51dz.png)

Prey是十分轻巧的软件，只使用了系统几兆的空间，安装完成后，从Application >> Prey启动，之后它会询问你进行相关配置。

选择“New User”，如果你是第一次使用的话。

![Prey New User](/data/attachment/album/201505/09/222306i83ackqrxaxbyzkw.png)

第二步实际上就是官网注册的流程。请提供你的用户名，邮箱地址和密码，来申清一个免费的账号。

![Register Prey](/data/attachment/album/201505/09/222306g2a0y0yy9qo7j89o.png)

点击“Apply”完成，所有工作搞定，现在你的计算机被Prey保护了。

![Prey Configuration](/data/attachment/album/201505/09/222307n1181mz1p5pfo3f3.png)

登录你最新建立的[Prey 账号](https://preyproject.com/)，你就应该可以在“Devices”菜单下看见你的设备信息了。

![Prey Web Login](/data/attachment/album/201505/09/222308y05kl9k1cl9k88i4.png)

只要你的笔记本或者任何其他设备丢失了，就登录你的Prey网站账号，然后点击“Set Device to Missing”选项修改设备状态为“missing”。

![Prey Missing Page](/data/attachment/album/201505/09/222309s591i615a9m66d9h.png)

从这里选择定时报告，并点击“Yes，my device is missing”。定时报告选项是指一段时间间隔后，软件会更新并发送给你设备的地理位置。它还会从网页界面那发邮件给你，只要设备的状态改变了。

![Prey Missing Email](/data/attachment/album/201505/09/222309nt7qx4c81q5yb8v6.png)

而一旦被盗的设备接入了互联网，Prey就会马上发送报告给你，包括设备的地理位置和IP地址。

![Prey Found Report](/data/attachment/album/201505/09/222310naohrz3oxhra3r7u.png)

点击报告链接，你应该会看到设备的地理位置和IP地址。

![Prey Final](/data/attachment/album/201505/09/222311lhh3zhyc3jhqulhp.png)

Prey有一个明显的不足。它需要你的设备接入互联网才会发送地理位置给你，如果小偷比较聪明，在接入网络前将你的设备磁盘格式化了，那么你就永远不会收到设备被发现的报告了。但是这里仍然是有一个方法克服这个不足，确保添加一个BIOS密码，并且禁用从可移除的设备里启动系统。

### 结论

这是一款小巧，非常有用的安全保护应用，可以让你在一个地方追踪你所有的设备，尽管不完美，但是仍然提供了找回被盗设备的机会。它在Linux，Windows和Mac平台上无缝运行。以上就是[Prey](https://preyproject.com/plans)完整使用的所有细节。

---

via: <http://linoxide.com/ubuntu-how-to/anti-theft-application-prey-ubuntu/>

作者：[Aun Raza](http://linoxide.com/author/arunrz/) 译者：[wi-cuckoo](https://github.com/wi-cuckoo) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译，[Linux中国](http://linux.cn/) 荣誉推出


在Ubuntu中安装Visual Studio Code

Summary: 微软令人意外地发布了Visual Studio Code，并支持主要的桌面平台，当然包括linux。如果你是一名需要在ubuntu工作的web开发人员，你可以非常轻松的安装Visual Studio Code。 我将要使用Ubuntu Make来安装Visual Studio Code。Ubuntu Make，就是以前的Ubuntu开发者工具中心，是一个命令行工具，帮助用户快速安装各种开发工具、语言和IDE。也可以使用Ubuntu Make轻松安装Android Studio 和其他IDE，如Eclipse。本文将展示如何在Ubuntu中使用Ubuntu Make安装Visual Studio Code。（译注：也可以直接去微软官网下载安装包） 安装微软Visual Stu

make

win xp+linux 32虚拟机，貌似都不适合

下载后 为啥没有出现vs code的图标呢

ERROR: Package requirements can't be met: [Errno 1] Operation not permitted<br />
我在安装的时候出现了这个错误  怎么解决

sudo 试试

web改成ide

我报错umake web: error: argument framework: invalid choice: 'visual-studio-code' (choose from 'firefox-dev', 'phantomjs')

umake web visual-studio-code<br />
web change ide

报错的把web改成ide<br />
umake ide visual-studio-code

![](/data/attachment/album/201505/10/212136v2fq7ob3pp7s723o.jpg)

微软令人意外地[发布了Visual Studio Code](/article-5376-1.html)，并支持主要的桌面平台，当然包括linux。如果你是一名需要在ubuntu工作的web开发人员，你可以**非常轻松的安装Visual Studio Code**。

我将要使用[Ubuntu Make](https://wiki.ubuntu.com/ubuntu-make)来安装Visual Studio Code。Ubuntu Make，就是以前的Ubuntu开发者工具中心，是一个命令行工具，帮助用户快速安装各种开发工具、语言和IDE。也可以使用Ubuntu Make轻松[安装Android Studio](http://itsfoss.com/install-android-studio-ubuntu-linux/) 和其他IDE，如Eclipse。本文将展示**如何在Ubuntu中使用Ubuntu Make安装Visual Studio Code**。（译注：也可以直接去微软官网下载安装包）

### 安装微软Visual Studio Code

开始之前，首先需要安装Ubuntu Make。虽然Ubuntu Make存在Ubuntu15.04官方库中，**但是需要Ubuntu Make 0.7以上版本才能安装Visual Studio**。所以，需要通过官方PPA更新到最新的Ubuntu Make。此PPA支持Ubuntu 14.04, 14.10 和 15.04。

注意，**仅支持64位版本**。

打开终端，使用下列命令，通过官方PPA来安装Ubuntu Make：

```
sudo add-apt-repository ppa:ubuntu-desktop/ubuntu-make
sudo apt-get update
sudo apt-get install ubuntu-make

```

安装Ubuntu Make完后，接着使用下列命令安装Visual Studio Code：

```
umake web visual-studio-code

```

安装过程中，将会询问安装路径，如下图：

![](/data/attachment/album/201505/10/212137ureeadg1c9e3ete6.jpg)

在抛出一堆要求和条件后，它会询问你是否确认安装Visual Studio Code。输入‘a’来确定：

![](/data/attachment/album/201505/10/212138e9j75lja2llwb932.jpg)

确定之后，安装程序会开始下载并安装。安装完成后，你可以发现Visual Studio Code 图标已经出现在了Unity启动器上。点击图标开始运行！下图是Ubuntu 15.04 Unity的截图：

![](/data/attachment/album/201505/10/212139mxxc7gt4vzf6oc6a.jpg)

### 卸载Visual Studio Code

卸载Visual Studio Code，同样使用Ubuntu Make命令。如下：

```
umake web visual-studio-code --remove

```

如果你不打算使用Ubuntu Make，也可以通过微软官方下载安装文件。

* [下载Visual Studio Code Linux版](https://code.visualstudio.com/Download)

怎样！是不是超级简单就可以安装Visual Studio Code，这都归功于Ubuntu Make。我希望这篇文章能帮助到你。如果您有任何问题或建议，欢迎给我留言。

---

via: <http://itsfoss.com/install-visual-studio-code-ubuntu/>

作者：[Abhishek](http://itsfoss.com/author/abhishek/) 译者：[Vic020/VicYu](http://vicyu.net) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译，[Linux中国](http://linux.cn/) 荣誉推出


如何使用Vault安全的存储密码和API密钥

Summary: Vault是用来安全的获取秘密信息的工具，它可以保存密码、API密钥、证书等信息。Vault提供了一个统一的接口来访问秘密信息，其具有健壮的访问控制机制和丰富的事件日志。 对关键信息的授权访问是一个困难的问题，尤其是当有许多用户角色，并且用户请求不同的关键信息时，例如用不同权限登录数据库的登录配置，用于外部服务的API密钥，SOA通信的证书等。当保密信息由不同的平台进行管理，并使用一些自定义的配置时，情况变得更糟，因此，安全的存储、管理审计日志几乎是不可能的。但Vault为这种复杂情况提供了一个解决方案。  突出特点 数据

Vault是用来安全的获取秘密信息的工具，它可以保存密码、API密钥、证书等信息。Vault提供了一个统一的接口来访问秘密信息，其具有健壮的访问控制机制和丰富的事件日志。

对关键信息的授权访问是一个困难的问题，尤其是当有许多用户角色，并且用户请求不同的关键信息时，例如用不同权限登录数据库的登录配置，用于外部服务的API密钥，SOA通信的证书等。当保密信息由不同的平台进行管理，并使用一些自定义的配置时，情况变得更糟，因此，安全的存储、管理审计日志几乎是不可能的。但Vault为这种复杂情况提供了一个解决方案。

![](/data/attachment/album/201505/10/225346geeym2zywo8w22gi.png)

### 突出特点

**数据加密**：Vault能够在不存储数据的情况下对数据进行加密、解密。开发者们便可以存储加密后的数据而无需开发自己的加密技术，Vault还允许安全团队自定义安全参数。

**安全密码存储**：Vault在将秘密信息（API密钥、密码、证书）存储到持久化存储之前对数据进行加密。因此，如果有人偶尔拿到了存储的数据，这也没有任何意义，除非加密后的信息能被解密。

**动态密码**：Vault可以随时为AWS、SQL数据库等类似的系统产生密码。比如，如果应用需要访问AWS S3 桶，它向Vault请求AWS密钥对，Vault将给出带有租期的所需秘密信息。一旦租用期过期，这个秘密信息就不再存储。

**租赁和更新**：Vault给出的秘密信息带有租期，一旦租用期过期，它便立刻收回秘密信息，如果应用仍需要该秘密信息，则可以通过API更新租用期。

**撤销**：在租用期到期之前，Vault可以撤销一个秘密信息或者一个秘密信息树。

### 安装Vault

有两种方式来安装使用Vault。

**1. 预编译的Vault二进制** 能用于所有的Linux发行版，下载地址如下，下载之后，解压并将它放在系统PATH路径下，以方便调用。

* [下载预编译的二进制 Vault (32-bit)](https://dl.bintray.com/mitchellh/vault/vault_0.1.0_linux_386.zip)
* [下载预编译的二进制 Vault (64-bit)](https://dl.bintray.com/mitchellh/vault/vault_0.1.0_linux_amd64.zip)
* [下载预编译的二进制 Vault (ARM)](https://dl.bintray.com/mitchellh/vault/vault_0.1.0_linux_arm.zip)

![wget binary](/data/attachment/album/201505/10/225355yvnjn3n3ornznnjf.png)

*下载相应的预编译的Vault二进制版本。*

![vault](/data/attachment/album/201505/10/225355pgbjjbmbeezyged8.png)

*解压下载到本地的二进制版本。*

祝贺你！您现在可以使用Vault了。

![](/data/attachment/album/201505/10/225356ok42wt4qzpqts20m.png)

**2. 从源代码编译**是另一种在系统中安装Vault的方式。在安装Vault之前需要安装GO和GIT。

在 **Redhat系统中安装GO** 使用下面的指令：

```
sudo yum install go

```

在 **Debin系统中安装GO** 使用下面的指令：

```
sudo apt-get install golang

```

或者

```
sudo add-apt-repository ppa:gophers/go

sudo apt-get update

sudo apt-get install golang-stable

```

在 **Redhat系统中安装GIT** 使用下面的命令：

```
sudo yum install git

```

在 **Debian系统中安装GIT** 使用下面的命令：

```
sudo apt-get install git

```

一旦GO和GIT都已被安装好，我们便可以开始从源码编译安装Vault。

>
> 将下列的Vault仓库拷贝至GOPATH
>
>
>

```
https://github.com/hashicorp/vault

```

>
> 测试下面的文件是否存在，如果它不存在，那么Vault没有被克隆到合适的路径。
>
>
>

```
$GOPATH/src/github.com/hashicorp/vault/main.go

```

>
> 执行下面的指令来编译Vault，并将二进制文件放到系统bin目录下。
>
>
>

```
make dev

```

![path](/data/attachment/album/201505/10/225357r6lrr4vrmdt08m4v.png)

### 一份Vault入门教程

我们已经编制了一份Vault的官方交互式教程，并带有它在SSH上的输出信息。

**概述**

这份教程包括下列步骤：

* 初始化并启封您的Vault
* 在Vault中对您的请求授权
* 读写秘密信息
* 密封您的Vault

#### **初始化您的Vault**

首先，我们需要为您初始化一个Vault的工作实例。在初始化过程中，您可以配置Vault的密封行为。简单起见，现在使用一个启封密钥来初始化Vault，命令如下：

```
vault init -key-shares=1 -key-threshold=1

```

您会注意到Vault在这里输出了几个密钥。不要清除您的终端，这些密钥在后面的步骤中会使用到。

![Initializing SSH](/data/attachment/album/201505/10/225357tpy1dy9dndg5f9fy.png)

#### **启封您的Vault**

当一个Vault服务器启动时，它是密封的状态。在这种状态下，Vault被配置为知道物理存储在哪里及如何存取它，但不知道如何对其进行解密。Vault使用加密密钥来加密数据。这个密钥由"主密钥"加密，主密钥不保存。解密主密钥需要入口密钥。在这个例子中，我们使用了一个入口密钥来解密这个主密钥。

```
vault unseal <key 1>

```

![Unsealing SSH](/data/attachment/album/201505/10/225358jqa50q4a68mq5t3w.png)

#### **为您的请求授权**

在执行任何操作之前，连接的客户端必须是被授权的。授权的过程是检验一个人或者机器是否如其所申明的那样具有正确的身份。这个身份用在向Vault发送请求时。为简单起见，我们将使用在步骤2中生成的root令牌，这个信息可以回滚终端屏幕看到。使用一个客户端令牌进行授权：

```
vault auth <root token>

```

![Authorize SSH](/data/attachment/album/201505/10/225358ht8zattxx6pxkze7.png)

#### **读写保密信息**

现在Vault已经被设置妥当，我们可以开始读写默认挂载的秘密后端里面的秘密信息了。写在Vault中的秘密信息首先被加密，然后被写入后端存储中。后端存储机制绝不会看到未加密的信息，并且也没有在Vault之外解密的需要。

```
vault write secret/hello value=world

```

当然，您接下来便可以读这个保密信息了：

```
vault read secret/hello

```

![RW_SSH](/data/attachment/album/201505/10/225358xln66nd36udmg06e.png)

#### **密封您的Vault**

还有一个用I来密封Vault的API。它将丢掉现在的加密密钥并需要另一个启封过程来恢复它。密封仅需要一个拥有root权限的操作者。这是一种罕见的"打破玻璃过程"的典型部分。

这种方式中，如果检测到一个入侵，Vault数据将会立刻被锁住，以便最小化损失。如果不能访问到主密钥碎片的话，就不能再次获取数据。

```
vault seal

```

![Seal Vault SSH](/data/attachment/album/201505/10/225359xoa6fqc6lojlqzof.png)

这便是入门教程的结尾。

### 总结

Vault是一个非常有用的应用，它提供了一个可靠且安全的存储关键信息的方式。另外，它在存储前加密关键信息、审计日志维护、以租期的方式获取秘密信息，且一旦租用期过期它将立刻收回秘密信息。Vault是平台无关的，并且可以免费下载和安装。要发掘Vault的更多信息，请访问其[官方网站](https://vaultproject.io/)。

---

via: <http://linoxide.com/how-tos/secure-secret-store-vault/>

作者：[Aun Raza](http://linoxide.com/author/arunrz/) 译者：[wwy-hust](https://github.com/wwy-hust) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译，[Linux中国](https://linux.cn/) 荣誉推出


两种方式创建你自己的 Docker 基本映像

Summary: 欢迎大家，今天我们学习一下 docker 基本映像以及如何构建我们自己的 docker 基本映像。Docker 是一个开源项目，提供了一个可以打包、装载和运行任何应用的轻量级容器的开放平台。它没有语言支持、框架和打包系统的限制，从小型的家用电脑到高端服务器，在何时何地都可以运行。这使它们可以不依赖于特定软件栈和供应商，像一块块积木一样部署和扩展网络应用、数据库和后端服务。 Docker 映像是不可更改的只读层。Docker 使用 Union File System 在只读文件系统上增加可读写的文件系统，但所有更改都发生在最顶层的可写层，而其下的只读映

sudo debootstrap trusty trusty > /dev/null<br />
这个指令验证过了么？貌似是特定配置环境下的吧，本地无效啊

想请问一下，要自己把本地的android的iso文件，转换成docker镜像要怎么弄啊。

欢迎大家，今天我们学习一下 docker 基本映像以及如何构建我们自己的 docker 基本映像。[Docker](https://www.docker.com/) 是一个开源项目，提供了一个可以打包、装载和运行任何应用的轻量级容器的开放平台。它没有语言支持、框架和打包系统的限制，从小型的家用电脑到高端服务器，在何时何地都可以运行。这使它们可以不依赖于特定软件栈和供应商，像一块块积木一样部署和扩展网络应用、数据库和后端服务。

Docker 映像是不可更改的只读层。Docker 使用 **Union File System** 在只读文件系统上增加可读写的文件系统，但所有更改都发生在最顶层的可写层，而其下的只读映像上的原始文件仍然不会改变。由于映像不会改变，也就没有状态。基本映像是没有父类的那些映像。Docker 基本映像主要的好处是它允许我们有一个独立运行的 Linux 操作系统。

![](/data/attachment/album/201505/11/144443z73a10fo00aafra0.png)

下面是我们如何可以创建自定义的基本映像的方式。

### 1. 使用 Tar 创建 Docker 基本映像

我们可以使用 tar 构建我们自己的基本映像，我们从一个运行中的 Linux 发行版开始，将其打包为基本映像。这过程可能会有些不同，它取决于我们打算构建的发行版。在 Debian 发行版中，已经预带了 debootstrap。在开始下面的步骤之前，我们需要安装 debootstrap。debootstrap 用来获取构建基本系统需要的包。这里，我们构建基于 Ubuntu 14.04 "Trusty" 的映像。要完成这些，我们需要在终端或者 shell 中运行以下命令。

```
$ sudo debootstrap trusty trusty > /dev/null
$ sudo tar -C trusty -c . | sudo docker import - trusty

```

![使用debootstrap构建docker基本映像](/data/attachment/album/201505/11/144446hugjn8rjm5qz8zkp.png)

上面的命令为当前文件夹创建了一个 tar 文件并输出到标准输出中，"docker import - trusty" 通过管道从标准输入中获取这个 tar 文件并根据它创建一个名为 trusty 的基本映像。然后，如下所示，我们将运行映像内部的一条测试命令。

```
$  docker run trusty cat /etc/lsb-release

```

[Docker GitHub Repo](https://github.com/docker/docker/blob/master/contrib/mkimage-busybox.sh) 中有一些允许我们快速构建基本映像的事例脚本.

### 2. 使用Scratch构建基本映像

在 Docker registry 中，有一个被称为 Scratch 的使用空 tar 文件构建的特殊库：

```
$ tar cv --files-from /dev/null | docker import - scratch

```

![使用scratch构建docker基本映像](/data/attachment/album/201505/11/144447drsrrsar8zrrzhld.png)

我们可以使用这个映像构建新的小容器：

```
FROM scratch
ADD script.sh /usr/local/bin/run.sh
CMD ["/usr/local/bin/run.sh"]

```

上面的 Dockerfile 文件来自一个很小的映像。这里，它首先从一个完全空的文件系统开始，然后它复制新建的 /usr/local/bin/run.sh 为 script.sh ，然后运行脚本 /usr/local/bin/run.sh。

### 结尾

这这个教程中，我们学习了如何构建一个开箱即用的自定义 Docker 基本映像。构建一个 docker 基本映像是一个很简单的任务，因为这里有很多已经可用的包和脚本。如果我们想要在里面安装想要的东西，构建 docker 基本映像非常有用。如果有任何疑问，建议或者反馈，请在下面的评论框中写下来。非常感谢！享受吧 :-)

---

via: <http://linoxide.com/linux-how-to/2-ways-create-docker-base-image/>

作者：[Arun Pyasi](http://linoxide.com/author/arunp/) 译者：[ictlyh](https://github.com/ictlyh) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译，[Linux中国](http://linux.cn/) 荣誉推出


既然float不能表示所有的int，那为什么在类型转换时C++将int转换成float？

Summary: 问题： 代码如下： int i = 23; float f = 3.14; if (i == f) // 执行某段代码  编译器会将i转换成float类型，然后比较这两个float的大小，但是float能够表示所有的int吗？为什么没有将int和float转换成double类型进行比较呢？  回答： 在整型数的演变中，当int变成unsigned时，会丢掉负数部分（有趣的是，这样的话，0u  -1就是对的了）。 和C语言中的大部分机制（在C++中得到继承）一样，就硬件操作而言，常见的算术转换应该简明易懂。C语言的发明者精通他们所使用机器上的汇编语言，他们编写的C语言对他们和像他们一样编写程序的人有直

### 问题：

代码如下：

```
int i = 23;
float f = 3.14;
if (i == f) // 执行某段代码

```

编译器会将i转换成float类型，然后比较这两个float的大小，但是float能够表示所有的int吗？为什么没有将int和float转换成double类型进行比较呢？

![](/data/attachment/album/201505/11/151113i3lzgnfjk8jkxdwe.jpg)

### 回答：

在整型数的演变中，当`int`变成`unsigned`时，会丢掉负数部分（有趣的是，这样的话，`0u < -1`就是对的了）。

和C语言中的大部分机制（在C++中得到继承）一样，就硬件操作而言，常见的算术转换应该简明易懂。C语言的发明者精通他们所使用机器上的汇编语言，他们编写的C语言对他们和像他们一样编写程序的人有直接的意义，直到使用汇编语言编写（诸如UNIX内核）的程序时。

现如今，一般来说，处理器并不具有混合类型的指令系统（如float和double相加、比较int和float，诸如此类），因为如果这样做造成芯片晶圆的巨大浪费——如果你想支持更多不同的类型，你不得不实现更多的操作码。然而，在实际中，你只有实现"add int to int"、"compare float to float"和"multiply unsigned with unsigned"等功能的常见指令，这使得优先进行算术转换变得很有必要——它们是指令系统中两种类型的映射关系，它们中的大部分很有用处。

从习惯编写低级别机器代码的编程人员的角度来说，如果有了混合类型，那么在一般情况下最有可能使用的汇编指令就是那些只需要进行最少类型转换的指令。其中，有一种特殊情况就是浮点数的转换，特别是在20世纪70年代早期，当时C语言正在被开发，计算机运行速度很慢，而浮点数的计算是通过软件完成的，所以进行转换的成本很高。这拖慢了常用算术运算的转换开发——当时只有一种操作数实现了转换（这个例外就是long到unsigned int的转换，这种转换没有任何要求，在大部分机器上都可以进行。当然并不是全部，因为总有例外情况）。

所以，编写常用的算术转换是为了完成汇编程序员在大部分时间需要做的事情：即有两种不匹配的类型，将一种转换成另一种。这也就是汇编代码所做的事情，除非有特别原因需要进行其它类型转换。对于那些习惯编写汇编代码的人来说，除非是特殊需要，才会被迫去编写一种不同的类型转换。显然，这种情况下提出编写转换是很自然的事情。虽然，你可以简单地写成这样

```
if((double) i < (double) f)

```

顺便提一下，在这个问题中有趣的是，`unsigned`的优先级高于`int`，所以把`int`和`unsigned`进行比较时，最终进行的是unsigned类型的比较（开头提到的`0u < -1`就是这个道理）。我猜测这可能是在早些时候（计算机发展初期），当时的人们认为`unsigned`比`int`在所表示的数值范围上受到的限制更小：现在还不需要符号位，所以可以使用额外的位来表示更大的数值范围。如果你觉得`int`可能会溢出，那么就使用unsigned好了——在使用16位表示的ints时这个担心会更明显。

---

via: [stackoverflow](http://stackoverflow.com/questions/28010565/why-does-c-promote-an-int-to-a-float-when-a-float-cannot-represent-all-int-val/28011249#28011249)

作者：[wintermute](http://stackoverflow.com/users/4301306/wintermute) 译者：[KayGuoWhu](https://github.com/KayGuoWhu) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译，[Linux中国](http://linux.cn/) 荣誉推出


监控 Linux 容器性能的命令行神器

Summary: ctop是一个新的基于命令行的工具，它可用于在容器层级监控进程。容器通过利用控制器组（cgroup）的资源管理功能，提供了操作系统层级的虚拟化环境。该工具从cgroup收集与内存、CPU、块输入输出的相关数据，以及拥有者、开机时间等元数据，并以人性化的格式呈现给用户，这样就可以快速对系统健康状况进行评估。基于所获得的数据，它可以尝试推测下层的容器技术。ctop也有助于在低内存环境中检测出谁在消耗大量的内存。 功能 ctop的一些功能如下：  收集CPU、内存和块输入输出的度量值 收集与拥有者、容器技术和任务统计相关的信息 通过任意

容器周边设施正在不断完善中哈

ctop是一个新的基于命令行的工具，它可用于在容器层级监控进程。容器通过利用控制器组（cgroup）的资源管理功能，提供了操作系统层级的虚拟化环境。该工具从cgroup收集与内存、CPU、块输入输出的相关数据，以及拥有者、开机时间等元数据，并以人性化的格式呈现给用户，这样就可以快速对系统健康状况进行评估。基于所获得的数据，它可以尝试推测下层的容器技术。ctop也有助于在低内存环境中检测出谁在消耗大量的内存。

### 功能

ctop的一些功能如下：

* 收集CPU、内存和块输入输出的度量值
* 收集与拥有者、容器技术和任务统计相关的信息
* 通过任意栏对信息排序
* 以树状视图显示信息
* 折叠/展开cgroup树
* 选择并跟踪cgroup/容器
* 选择显示数据刷新的时间窗口
* 暂停刷新数据
* 检测基于systemd、Docker和LXC的容器
* 基于Docker和LXC的容器的高级特性
	+ 打开/连接shell以进行深度诊断
	+ 停止/杀死容器类型

### 安装

**ctop**是由Python写成的，因此，除了需要Python 2.6或其更高版本外（带有内建的光标支持），别无其它外部依赖。推荐使用Python的pip进行安装，如果还没有安装pip，请先安装，然后使用pip安装ctop。

*注意：本文样例来自Ubuntu（14.10）系统*

```
$ sudo apt-get install python-pip

```

使用pip安装ctop：

```
poornima@poornima-Lenovo:~$ sudo pip install ctop

[sudo] password for poornima:

Downloading/unpacking ctop

Downloading ctop-0.4.0.tar.gz

Running setup.py (path:/tmp/pip_build_root/ctop/setup.py) egg_info for package ctop

Installing collected packages: ctop

Running setup.py install for ctop

changing mode of build/scripts-2.7/ctop from 644 to 755

changing mode of /usr/local/bin/ctop to 755

Successfully installed ctop

Cleaning up...

```

如果不选择使用pip安装，你也可以使用wget直接从github安装：

```
poornima@poornima-Lenovo:~$ wget https://raw.githubusercontent.com/yadutaf/ctop/master/cgroup_top.py -O ctop

--2015-04-29 19:32:53-- https://raw.githubusercontent.com/yadutaf/ctop/master/cgroup_top.py

Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 199.27.78.133

Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|199.27.78.133|:443... connected.

HTTP request sent, awaiting response... 200 OK Length: 27314 (27K) [text/plain]

Saving to: ctop

100%[======================================>] 27,314 --.-K/s in 0s

2015-04-29 19:32:59 (61.0 MB/s) - ctop saved [27314/27314]

```

---

```
poornima@poornima-Lenovo:~$ chmod +x ctop

```

如果cgroup-bin包没有安装，你可能会碰到一个错误消息，你可以通过安装需要的包来解决。

```
poornima@poornima-Lenovo:~$ ./ctop

[ERROR] Failed to locate cgroup mountpoints.

poornima@poornima-Lenovo:~$ sudo apt-get install cgroup-bin

```

下面是ctop的输出样例：

![ctop screen](/data/attachment/album/201505/11/155445sj0ir9xdtx3cwfr9.png)

*ctop屏幕*

### 用法选项

```
ctop [--tree] [--refresh=] [--columns=] [--sort-col=] [--follow=] [--fold=, ...] ctop (-h | --help)

```

当你进入ctop屏幕，可使用上（↑）和下（↓）箭头键在容器间导航。点击某个容器就选定了该容器，按q或Ctrl+C退出该容器。

现在，让我们来看看上面列出的那一堆选项究竟是怎么用的吧。

**-h / --help - 显示帮助信息**

```
poornima@poornima-Lenovo:~$ ctop -h
Usage: ctop [options]

Options:
-h, --help show this help message and exit
--tree show tree view by default
--refresh=REFRESH Refresh display every <seconds>
--follow=FOLLOW Follow cgroup path
--columns=COLUMNS List of optional columns to display. Always includes
'name'
--sort-col=SORT_COL Select column to sort by initially. Can be changed
dynamically.

```

**--tree - 显示容器的树形视图**

默认情况下，会显示列表视图

当你进入ctop窗口，你可以使用F5按钮在树状/列表视图间切换。

**--fold= - 在树形视图中折叠名为 <name> 的 cgroup 路径**

该选项需要与 --tree 选项组合使用。

例子: ctop --tree --fold=/user.slice

![Output of 'ctop --fold'](/data/attachment/album/201505/11/155445wibankkerjy2iee2.png)

*'ctop --fold'的输出*

在ctop窗口中，使用+/-键来展开或折叠子cgroup。

注意：在写本文时，pip仓库中还没有最新版的ctop，还不支持命令行的‘--fold’选项

**--follow= - 跟踪/高亮 cgroup 路径**

例子: ctop --follow=/user.slice/user-1000.slice

正如你在下面屏幕中所见到的那样，带有“/user.slice/user-1000.slice”路径的cgroup被高亮显示，这让用户易于跟踪，就算显示位置变了也一样。

![Output of 'ctop --follow'](/data/attachment/album/201505/11/155446sldaxvluru2xbzwl.png)

*'ctop --follow'的输出*

你也可以使用‘f’按钮来让高亮的行跟踪选定的容器。默认情况下，跟踪是关闭的。

**--refresh= - 按指定频率刷新显示，默认1秒**

这对于按每用户需求来显示改变刷新率时很有用。使用‘p’按钮可以暂停刷新并选择文本。

**--columns= - 限定只显示选定的列。'name' 需要是第一个字段，其后跟着其它字段。默认情况下，字段包括：owner, processes,memory, cpu-sys, cpu-user, blkio, cpu-time**

例子: ctop --columns=name,owner,type,memory

![Output of 'ctop --column'](/data/attachment/album/201505/11/155447eljdiaz27t0jt7az.png)

*'ctop --column'的输出*

**-sort-col= - 按指定的列排序。默认使用 cpu-user 排序**

例子: ctop --sort-col=blkio

如果有Docker和LXC支持的额外容器，跟踪选项也是可用的：

```
press 'a' - 接驳到终端输出

press 'e' - 打开容器中的一个 shell

press 's' - 停止容器 (SIGTERM)

press 'k' - 杀死容器 (SIGKILL)

```

目前 Jean-Tiare Le Bigot 还在积极开发 [ctop](https://github.com/yadutaf/ctop) 中，希望我们能在该工具中见到像本地 top 命令一样的特性 :-)

---

via: <http://linoxide.com/how-tos/monitor-linux-containers-performance/>

作者：[B N Poornima](http://linoxide.com/author/bnpoornima/) 译者：[GOLinux](https://github.com/GOLinux) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译，[Linux中国](https://linux.cn/) 荣誉推出