“硅谷的女儿”的成才之路

php是世界上最伟大的语言！

![](/data/attachment/album/201612/27/115216xm4qw3xxchlq4en2.png)

在 2014 年，为了对网上一些关于在科技行业女性稀缺的评论作出回应，我的同事 [Crystal Beasley](http://skinnywhitegirl.com/blog/my-nerd-story/1101/) 倡议在科技/信息安全方面工作的女性在网络上分享自己的“成才之路”。这篇文章就是我的故事。我把我的故事与你们分享是因为我相信榜样的力量，也相信一个人有多种途径，选择一个让自己满意的有挑战性的工作以及可以实现目标的人生。

### 和电脑相伴的童年

我可以说是硅谷的女儿。我的故事不是一个从科技业余爱好转向专业的故事，也不是从小就专注于这份事业的故事。这个故事更多的是关于环境如何塑造你 — 通过它的那种已然存在的文化来改变你，如果你想要被改变的话。这不是从小就开始努力并为一个明确的目标而奋斗的故事，我意识到，这其实是享受了一些特权的成长故事。

我出生在曼哈顿，但是我在新泽西州长大，因为我的爸爸退伍后，在那里的罗格斯大学攻读计算机科学的博士学位。当我四岁时，学校里有人问我爸爸干什么谋生时，我说，“他就是看电视和捕捉小虫子，但是我从没有见过那些小虫子”（LCTT 译注：小虫子，bug）。他在家里有一台哑终端（LCTT 译注：就是那台“电视”），这大概与他在 Bolt Beranek Newman 公司的工作有关，做关于早期互联网人工智能方面的工作。我就在旁边看着。

我没能玩上父亲的会抓小虫子的电视，但是我很早就接触到了技术领域，我很珍惜这个礼物。提早的熏陶对于一个未来的高手是十分必要的 — 所以，请花时间和你的小孩谈谈你在做的事情！

![](/data/attachment/album/201612/27/115217bgeaeg773uup7per.png)

*我父亲的终端和这个很类似 —— 如果不是这个的话 CC BY-SA 4.0*

当我六岁时，我们搬到了加州。父亲在施乐的帕克研究中心（Xerox PARC）找到了一个工作。我记得那时我认为这个城市一定有很多熊，因为在它的旗帜上有一个熊。在1979年，帕洛阿图市还是一个大学城，还有果园和开阔地带。

在 Palo Alto 的公立学校待了一年之后，我的姐姐和我被送到了“半岛学校”，这个“民主典范”学校对我造成了深刻的影响。在那里，好奇心和创新意识是被高度推崇的，教育也是由学生自己分组讨论决定的。在学校，我们很少能看到叫做电脑的东西，但是在家就不同了。

在父亲从施乐辞职之后，他就去了苹果公司，在那里他工作使用并带回家让我玩的第一批电脑就是：Apple II 和 LISA。我的父亲在最初的 LISA 的研发团队。我直到现在还深刻的记得他让我们一次又一次的“玩”鼠标训练的场景，因为他想让我的 3 岁大的妹妹也能对这个东西觉得好用 —— 她也确实那样觉得。

![](/data/attachment/album/201612/27/115218sbloxgs6eo2cxjyh.jpg)

*我们的 LISA 看起来就像这样。谁看到鼠标哪儿去了？CC BY-SA 4.0*

在学校，我的数学的概念学得不错，但是基本计算却惨不忍睹。我的第一个学校的老师告诉我的家长和我，说我的数学很差，还说我很“笨”。虽然我在“常规的”数学项目中表现出色，能理解一个超出 7 岁孩子理解能力的逻辑谜题，但是我不能完成我们每天早上都要做的“练习”。她说我傻，这事我不会忘记。在那之后的十年我都没能相信自己的逻辑能力和算法的水平。**不要低估你对孩子说的话的影响**。

在我玩了几年爸爸的电脑之后，他从 Apple 公司跳槽到了 EA，又跳到了 SGI，我又体验了他带回来的新玩意。这让我们认为我们家的房子是镇里最酷的，因为我们在车库里有一个能玩 Doom 的 SGI 的机器。我不会太多的编程，但是现在看来，从那些年里我学到对尝试新的科技毫不恐惧。同时，我的学文学和教育的母亲，成为了一个科技行业的作家，她向我证实了一个人的职业可以改变，而且一个做母亲的人可能同时驾驭一个科技职位。我不是说这对她来说很简单，但是她让我认为这件事看起来很简单。你可能会想这些早期的熏陶能把我带到科技行业，但是它没有。

### 本科时光

我想我要成为一个小学教师，我就读米尔斯学院就是想要做这个。但是后来我开始研究女性学，后来又研究神学，我这样做仅仅是由于我自己的一个渴求：我希望能理解人类的意志以及为更好的世界而努力。

同时，我也感受到了互联网的巨大力量。在 1991 年，拥有你自己的 UNIX 的账户，能够和全世界的人谈话，是很令人兴奋的事。我仅仅从在互联网中“玩”就学到了不少，从那些愿意回答我提出的问题的人那里学到的就更多了。这些学习对我的职业生涯的影响不亚于我在正规学校教育之中学到的知识。所有的信息都是有用的。我在一个女子学院度过了学习的关键时期，那时是一个杰出的女性在掌管计算机院。在那个宽松氛围的学院，我们不仅被允许，还被鼓励去尝试很多的道路（我们能接触到很多很多的科技，还有聪明人愿意帮助我们），我也确实那样做了。我十分感激当年的教育。在那个学院，我也了解了什么是极客文化。

之后我去了研究生院去学习女性主义神学，但是技术的气息已经渗入我的灵魂。当我意识到我不想成为一个教授或者一个学术伦理家时，我离开了学术圈，带着学校债务和一些想法回到了家。

### 新的开端

在 1995 年，我被互联网连接人们以及分享想法和信息的能力所震惊（直到现在仍是如此）。我想要进入这个行业。看起来我好像要“女承父业”，但是我不知道如何开始。我开始在硅谷做临时工，从 Sun 微系统公司得到我的第一个“真正”技术职位前尝试做了一些事情（为半导体数据公司写最基础的数据库，技术手册印发前的事务，备份工资单的存跟）。这些事很让人激动。（毕竟，我们是“.com”中的那个”点“）。

在 Sun 公司，我努力学习，尽可能多的尝试新事物。我的第一个工作是<ruby> 网页化 <rt>  HTMLing </rt></ruby>（啥？这居然是一个词！）白皮书，以及为 Beta 程序修改一些基础的服务工具（大多数是 Perl 写的）。后来我成为 Solaris beta 项目组中的项目经理，并在 Open Solaris 的 Beta 版运行中感受到了开源的力量。

在那里我做的最重要的事情就是学习。我发现在同样重视工程和教育的地方有一种气氛，在那里我的问题不再显得“傻”。我很庆幸我选对了导师和朋友。在决定休第二个孩子的产假之前，我上每一堂我能上的课程，读每一本我能读的书，尝试自学我在学校没有学习过的技术，商业以及项目管理方面的技能。

### 重回工作

当我准备重新工作时，Sun 公司已经不再是合适的地方了。所以，我整理了我的联系信息（网络帮到了我），利用我的沟通技能，最终获得了一个管理互联网门户的长期合同（2005 年时，一切皆门户），并且开始了解 CRM、发布产品的方式、本地化、网络等知识。我讲这么多背景，主要是我的尝试以及失败的经历，和我成功的经历同等重要，从中学到很多。我也认为我们需要这个方面的榜样。

从很多方面来看，我的职业生涯的第一部分是我的技术教育。时变势移 —— 我在帮助组织中的女性和其他弱势群体，但是并没有看出为一个技术行业的女性有多难。当时无疑我没有看到这个行业的缺陷，但是现在这个行业更加的厌恶女性，一点没有减少。

在这些事情之后，我还没有把自己当作一个标杆，或者一个高级技术人员。当我在父母圈子里认识的一位极客朋友鼓励我申请一个看起来定位十分模糊且技术性很强的开源的非盈利基础设施机构（互联网系统协会 ISC，它是广泛部署的开源 DNS 名称服务器 BIND 的缔造者，也是 13 台根域名服务器之一的运营商）的产品经理时，我很震惊。有很长一段时间，我都不知道他们为什么要雇佣我！我对 DNS、基础设备，以及协议的开发知之甚少，但是我再次遇到了老师，并再度开始飞速发展。我花时间出差，在关键流程攻关，搞清楚如何与高度国际化的团队合作，解决麻烦的问题，最重要的是，拥抱支持我们的开源和充满活力的社区。我几乎重新学了一切，通过试错的方式。我学习如何构思一个产品。如何通过建设开源社区，领导那些有这特定才能，技能和耐心的人，是他们给了产品价值。

### 成为别人的导师

当我在 ISC 工作时，我通过 [TechWomen 项目](https://www.techwomen.org/mentorship/why-i-keep-coming-back-to-mentor-with-techwomen) （一个让来自中东和北非的技术行业的女性到硅谷来接受教育的计划），我开始喜欢教学生以及支持那些技术女性，特别是在开源行业中奋斗的。也正是从这时起我开始相信自己的能力。我还需要学很多。

当我第一次读 TechWomen 关于导师的广告时，我根本不认为他们会约我面试！我有冒名顶替综合症。当他们邀请我成为第一批导师（以及以后六年每年的导师）时，我很震惊，但是现在我学会了相信这些都是我努力得到的待遇。冒名顶替综合症是真实的，但是随着时间过去我就慢慢名副其实了。

### 现在

最后，我不得不离开我在 ISC 的工作。幸运的是，我的工作以及我的价值让我进入了 Mozilla ，在这里我的努力和我的幸运让我在这里承担着重要的角色。现在，我是一名支持多样性与包容的高级项目经理。我致力于构建一个更多样化，更有包容性的 Mozilla ，站在之前的做同样事情的巨人的肩膀上，与最聪明友善的人们一起工作。我用我的激情来让人们找到贡献一个世界需要的互联网的有意义的方式：这让我兴奋了很久。当我爬上山峰，我能极目四望！

通过对组织和个人行为的干预来获取一种改变文化的新方式，这和我的人生轨迹有着不可思议的联系 —— 从我的早期的学术生涯，到职业生涯再到现在。每天都是一个新的挑战，我想这是我喜欢在科技行业工作，尤其是在开放互联网工作的理由。互联网天然的多元性是它最开始吸引我的原因，也是我还在寻求的 —— 所有人都有机会和获取资源的可能性，无论背景如何。榜样、导师、资源，以及最重要的，尊重，是不断发展技术和开源文化的必要组成部分，实现我相信它能实现的所有事 —— 包括给所有人平等的接触机会。

本文作者 Larissa Shapiro 是 Mozilla 的一名支持多样性与包容的高级项目经理。

---

via: <https://opensource.com/life/16/5/my-open-source-story-larissa-shapiro>

作者：[Larissa Shapiro](https://opensource.com/users/larissa-shapiro) 译者：[name1e5s](https://github.com/name1e5s) 校对：[jasminepeng](https://github.com/jasminepeng)

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


哪个编程语言最流行？

Summary: 经常有人问哪个编程语言最流行？这问题很简单，但是回答起来可没那么简单。

php是世界上最伟大的语言！

如果你只想学一门语言，你可以从其中选择一个。我推荐你选择 Java 或 C++，它们可以为你打开进入 C 语言家族的大门

这挖的史诗级大坑~

php是世界上最伟大的语言！

毋庸置疑 肯定是java

走过大坑，然后就发现，真是一马平川啊。不管你用不用 C/C++ ，学过它们对你掌握编程还是有意义的。毕竟现在相当多的编程语言都和 C 语言沾亲带故。

入c坑，恋着c

文章觉得java和C++比C简单？

C#是基于C的么？这个说法有点意思

众多语言中，C#才是非常厉害的；

在性能方面比Java高效，虽然C#和java都是运行在虚拟机上，但在C#中，除了让CLR管理内存，还可以使用非托管模式编程，使用unsafe模式编程，直接用指针操作内存，其性能不会比C差多少，以及优雅的语法、宇宙最强IDE（Visual studio）让程序员开发体验极大提升。

C#能做的事也是Java无法比拟的，C# 擅长C/S的客户端应用程序开发、擅长web应用开发、移动App的Xamarin框架（直接编译成原生的iOS、Andorid代码）、世界著名的游戏引擎（unity3D）脚本语言使用C#、嵌入式开发。

C#才是未来的开发者的首选编程语

来自江西南昌的 Microsoft Edge 14.14393|Windows 10 用户

看到评论，吓得我我不敢说话

高手写代码，傻子秀工具。

所谓基于，其实应该是采取了一些 C 的语法、语言的组织方式、“对象”、内存、实体等的操作方式吧。

php是世界上最伟大的语言！

先学一门语言。

php是世界上最伟大的语言！

php是世界上最伟大的语言！

函数式语言，如erlang也可以学下

经常有人问哪个编程语言最流行？这问题很简单，但是回答起来可没那么简单。

>
> 经常有人问哪个编程语言最流行？这问题很简单，但是回答起来可没那么简单。
>
>
>

![](/data/attachment/album/201612/27/234934i144cvfdc41r6fa1.jpg)

首先，我们要知道，为什么人们会问这样的问题？

一般问这样的问题是人大多是学生，他们想知道这个问题的答案是因为他们想要找份工作，所以寻求一种可以增加面试成功率的技能。对于大多数人来说，进入一个新的领域时了解什么是最流行的，是很有意义的。

而对于其他人来说，比如说已经掌握了一种或几种编程语言的程序员，他可能在想要掌握一门新的编程语言时，会考虑一下当前最流行的编程语言作为参考。而对于要开发一个产品的程序员来说，也希望了解当前最流行的编程语言是因为他们希望所开发的产品能够迎合客户的环境和需求，显然支持流行的语言的 API 会被更多人使用。

甚至，就算是你想启动一个项目时，你也需要考虑是否选择一个流行的编程语言。虽然你首先要考虑的是这种语言能够满足你的需求，比如说如果用一个流行的编程语言你需要花费更多的时间和成本，而不那么流行的编程语言或许会更快捷和轻松，显然你还是会选择那个不太流行的——但是如果各个方面都差不多，不用说你会选择流行的那个，因为这样你可以找到更多的程序员，遇到问题也有更多的解决方案。

### 怎么才算是流行？

那么，哪个语言是最流行的？其实回答这个问题并没有你想象的那么简单。关键是，你该怎么定义这个“**流行**”？

这个问题并没有固定的答案，不过在[维基上有一篇文章提到了如何测量编程语言的流行度](https://en.wikipedia.org/wiki/Measuring_programming_language_popularity)。在这篇文章中，列出了几个测量流行度的因素：

* 该语言在搜索中提及的次数，比如在谷歌趋势中
* 在招聘广告中提及该语言的次数
* 传授和介绍该语言的书籍销售量
* 以该语言编写的现存代码的行数，不流行的语言在公开搜索中可能根本就找不到
* 在 GitHub、Freecode 上使用该语言的项目数量
* 在论坛和新闻组中讨论该语言的帖子数量

此外，你还可以考量如下指标：

* 编程培训班里面该语言的培训课程销售数量
* 编程培训班里面学生的数量
* 视频网站里面关于该语言的视频数量
* Stack Overflow 和 Reddit 里面关于该语言的帖子数量

甚至，你还可以增加一些其它的统计维度，比如根据国家和城市来统计，你知道在北京哪种编程语言最流行么？上海呢？

所以，这个问题的回答并不是一个简单的答案。

### 统计数据来源的不同

即使我们知道了流行度取决于多种因素，但是人们还是希望能够了解到底哪个语言比较流行，以此来指导他们的培训和公司的决策。

有一些网站依据不同的标准，公开发布了一些语言流行度指标。 [IEEE Spectrum](http://spectrum.ieee.org/static/interactive-the-top-programming-languages-2016) 对这些指标做了一个有趣的[整合](http://spectrum.ieee.org/static/interactive-the-top-programming-languages-2016)，它可以让你通过自行设置不同因子的权重来得到你自己的编程语言流行度排行榜。

![](/data/attachment/album/201612/27/222906dphl9aah724hd4lp.jpg)

[Coding Dojo 也有一个图表](http://www.codingdojo.com/blog/9-most-in-demand-programming-languages-of-2016/)，聚合了工作搜索引擎 Indeed.com 的数据；而有名的 [Tiobe](http://www.tiobe.com/tiobe-index/programming-languages-definition/) 排行榜一直使用搜索引擎聚合来计算流行度； [PyPl](http://pypl.github.io/PYPL.html) 则是根据谷歌来查看语言的流行度。

然而，这并没什么大用。如果你想知道你该学习那种语言，或者是你需要支持的语言，最困难的还是你并不知道这里的哪个图表才是适合你的。

### 好吧，我明白了，那么到底那种编程语言是流行的？

为了帮助你找到方向，我组合了上述提及的几种数据源，包括三种 IEEE 分类：“趋势”代表语言的增长度，“工作”代表 Dice.com 和 CareerBuilder 上的招聘量，“开源”代表开源项目数量。

排名结果如下表：

![](/data/attachment/album/201612/27/234950cv5zd00t4bvtvy6b.jpg)

但是问题是，上图并不能告诉我们重点所在。要解决这个问题，我们需要做一点数据分析。我聚合了这六个数据源中的五个（我去掉了 Coding Dojo 是因为它仅显示了前九），然后我根据编程语言出现在图表中的位置和次数进行加权，这样我得到了如下的前十排名。

![](/data/attachment/album/201612/27/234951xaoar0eoc641ke1r.jpg)

如你所见，这些语言分成了三大类。第一梯队包括 Java、C、Python 和 C++，毫无疑问，你肯定经常听到它们的名字。第二梯队包括 JavaScript、C#、PHP 和 Swift。剩下的两个是 Objective-C 和 R。

### 这给我们带来什么启发？

第一梯队的语言 Java、C、Python 和 C++ 都是非常通用的语言，它们并不局限于特定的编程平台或用途。

最值得关注的是第二梯队，它包括 JavaScript、C#、PHP 和 Swift。JavaScript 和 PHP 是主要的 Web 开发语言。C# 是微软的编程语言，而 Swift 是苹果新推出的主力语言。基本上来说，第二梯队是平台相关的。

那么这反映了什么？如果你懂一点现代编程，你就知道编程其实不仅仅是使用这种语言，而更重要的是开发一些什么，比如说嵌入式系统、iPhone 应用、Web 应用或者微软的服务器端应用等等。

对语言的熟悉程度其实只是一小部分。举个例子说，不管你是多么的喜欢 Python 或者古老而常青的 C，但如果你要为 WordPress 开发插件或主题，你只能使用 JavaScript 和 PHP。这无关于哪个语言更流行。

### 字里行间的发现

或者你会注意到一些有趣的地方。

首先，Coding Dojo 的编程语言排行榜的第一名是 SQL，只有它一家是这样。你很少会单独在 SQL 里面编程，通常都是在其它的语言里面使用它来管理数据。所以，学会 SQL 是很有用的，甚至是必要的。然而，去上一门 SQL 的培训课程并不能帮你找到一份工作，也不会多挣多少钱。

其次，苹果特有的语言在排行榜中排名很低，这或许和你的预期不同，因为 iOS 的应用是如此的流行。不过确实是这样的，如果你不是要开发你自己的应用的话，那学它们其实不如学习别的语言，因为其实没有那么多的公司雇佣苹果应用开发人员。这就是 Swift 语言掉到了榜尾的原因，而 Objective-C 正在被 Swift 所替代，在前面也看到了它也处于榜单的后面。

C 家族的语言仍然是主流。Java、C++、C、C#，甚至 Objective-C 都是基于 C 的语言。如果你只想学一门语言，你可以从其中选择一个。我推荐你选择 Java 或 C++，它们可以为你打开进入 C 语言家族的大门。

以我的职业生涯的经验来看，不是特别复杂的场景的话，我大概能用 20 来种语言来编程，通常我只用几天就可以学会一门新的语言。这是因为我在学校的专业就是语言设计，我也教编程超过了 20 年了。掌握这么多的语言对我很有帮助，因为我总是根据我要做的事情选择一种语言，而不是专门去上课学习一种语言。这听起来好像有点难，但是其实你也能做到的。

我的建议就是，如果你要编程，那么就去**学习多种编程语言和各种框架**吧。用编程语言去做点东西出来，编程不仅仅是一种智力锻炼，而且你可以实际用它做点什么出来。

掌握多种语言和框架是重要的，因为计算机行业变得太快了。C 语言[依然历久弥新](http://www.thepeoplehistory.com/1972.html)，而 Swift 虽然出现才几年就登上了排行榜。你今天学习到的或许不够你整个职业生涯挥霍，所以“怎样学习语言”要比“学习语言”更重要，最好的办法就是多学几门。

我的推荐非常简单，无论是 C++ 还是 Java，选一个学习就好了。然后是 JavaScript，越来越多的基于 Web 的应用需要良好的 JavaScript 技能。再然后是 PHP、Swift 或 Python 中选一个，这要看你的工作种类了。当你在这三个梯队中都学会一门后，你就可以根据你的情况学习更多的语言和框架了。

好了，努力吧，学习一些编程语言，做点漂亮的成绩出来。如果你有什么想法，欢迎在下面和我们分享。


Samba 系列（二）：在 Linux 命令行下管理 Samba4 AD 架构

Summary: 这篇文章包括了管理 Samba4 域控制器架构过程中的一些常用命令，比如添加、移除、禁用或者列出用户及用户组等。我们也会关注一下如何配置域安全策略以及如何把 AD 用户绑定到本地的 PAM 认证中，以实现 AD 用户能够在 Linux 域控制器上进行本地登录。

这篇文章包括了管理 Samba4 域控制器架构过程中的一些常用命令，比如添加、移除、禁用或者列出用户及用户组等。

我们也会关注一下如何配置域安全策略以及如何把 AD 用户绑定到本地的 PAM 认证中，以实现 AD 用户能够在 Linux 域控制器上进行本地登录。

![](/data/attachment/album/201612/28/111600kmlm9m3ugqm3spje.jpg)

#### 要求

* [在 Ubuntu 系统上使用 Samba4 来创建活动目录架构](/article-8065-1.html)

### 第一步：在命令行下管理

1、 可以通过 `samba-tool` 命令行工具来进行管理，这个工具为域管理工作提供了一个功能强大的管理接口。

通过 `samba-tool` 命令行接口，你可以直接管理域用户及用户组、域组策略、域站点，DNS 服务、域复制关系和其它重要的域功能。

使用 root 权限的账号，直接输入 `samba-tool` 命令，不要加任何参数选项来查看该工具能实现的所有功能。

```
# samba-tool -h

```

![samba-tool - Manage Samba Administration Tool](/data/attachment/album/201612/28/111608jsqruqozzg086rrs.png)

*samba-tool —— Samba 管理工具*

2、 现在，让我们开始使用 `samba-tool` 工具来管理 Samba4 活动目录中的用户。

使用如下命令来创建 AD 用户：

```
# samba-tool user add your_domain_user

```

添加一个用户，包括 AD 可选的一些重要属性，如下所示：

```
--------- review all options ---------
# samba-tool user add -h
# samba-tool user add your_domain_user --given-name=your_name --surname=your_username --mail-address=your_domain_user@tecmint.lan --login-shell=/bin/bash

```

![Create User on Samba AD](/data/attachment/album/201612/28/111609wlboagivyyeobaob.png)

*在 Samba AD 上创建用户*

3、 可以通过下面的命令来列出所有 Samba AD 域用户：

```
# samba-tool user list

```

![List Samba AD Users](/data/attachment/album/201612/28/111609zprw1rsmv9h8yywr.png)

*列出 Samba AD 用户信息*

4、 使用下面的命令来删除 Samba AD 域用户：

```
# samba-tool user delete your_domain_user

```

5、 重置 Samba 域用户的密码：

```
# samba-tool user setpassword your_domain_user

```

6、 启用或禁用 Samba 域用户账号：

```
# samba-tool user disable your_domain_user
# samba-tool user enable your_domain_user

```

7、 同样地，可以使用下面的方法来管理 Samba 用户组：

```
--------- review all options ---------
# samba-tool group add –h
# samba-tool group add your_domain_group

```

8、 删除 samba 域用户组：

```
# samba-tool group delete your_domain_group

```

9、 显示所有的 Samba 域用户组信息：

```
# samba-tool group list

```

10、 列出指定组下的 Samba 域用户：

```
# samba-tool group listmembers "your_domain group"

```

![List Samba Domain Members of Group](/data/attachment/album/201612/28/111610b0m7cqm600fkvfcn.png)

*列出 Samba 域用户组*

11、 从 Samba 域组中添加或删除某一用户：

```
# samba-tool group addmembers your_domain_group your_domain_user
# samba-tool group remove members your_domain_group your_domain_user

```

12、 如上面所提到的， `samba-tool` 命令行工具也可以用于管理 Samba 域策略及安全。

查看 samba 域密码设置：

```
# samba-tool domain passwordsettings show

```

![Check Samba Domain Password](/data/attachment/album/201612/28/111610x9mdx60f5t3r0xdm.png)

*检查 Samba 域密码*

13、 为了修改 samba 域密码策略，比如密码复杂度，密码失效时长，密码长度，密码重复次数以及其它域控制器要求的安全策略等，可参照如下命令来完成：

```
---------- List all command options ----------
# samba-tool domain passwordsettings -h

```

![Manage Samba Domain Password Settings](/data/attachment/album/201612/28/111611dtaag22to9gr1hrg.png)

*管理 Samba 域密码策略*

不要把上图中的密码策略规则用于生产环境中。上面的策略仅仅是用于演示目的。

### 第二步：使用活动目录账号来完成 Samba 本地认证

14、 默认情况下，离开 Samba AD DC 环境，AD 用户不能从本地登录到 Linux 系统。

为了让活动目录账号也能登录到系统，你必须在 Linux 系统环境中做如下设置，并且要修改 Samba4 AD DC 配置。

首先，打开 Samba 主配置文件，如果以下内容不存在，则添加：

```
$ sudo nano /etc/samba/smb.conf

```

确保以下参数出现在配置文件中：

```
winbind enum users = yes
winbind enum groups = yes

```

![Samba Authentication Using Active Directory User Accounts](/data/attachment/album/201612/28/111611tg8ockdxgyamnkxk.png)

*Samba 通过 AD 用户账号来进行认证*

15、 修改之后，使用 `testparm` 工具来验证配置文件没有错误，然后通过如下命令来重启 Samba 服务：

```
$ testparm
$ sudo systemctl restart samba-ad-dc.service

```

![Check Samba Configuration for Errors](/data/attachment/album/201612/28/111612jkq84e848qyqhhli.png)

*检查 Samba 配置文件是否报错*

16、 下一步，我们需要修改本地 PAM 配置文件，以让 Samba4 活动目录账号能够完成本地认证、开启会话，并且在第一次登录系统时创建一个用户目录。

使用 `pam-auth-update` 命令来打开 PAM 配置提示界面，确保所有的 PAM 选项都已经使用 `[空格]` 键来启用，如下图所示：

完成之后，按 `[Tab]` 键跳转到 OK ，以启用修改。

```
$ sudo pam-auth-update

```

![Configure PAM for Samba4 AD](/data/attachment/album/201612/28/111613pbujqqcr3eeb3fee.png)

*为 Samba4 AD 配置 PAM 认证*

![Enable PAM Authentication Module for Samba4 AD Users](/data/attachment/album/201612/28/111613zlh4ohuov6ll8mhf.png)

为 Samba4 AD 用户启用 PAM认证模块

17、 现在，使用文本编辑器打开 `/etc/nsswitch.conf` 配置文件，在 `passwd` 和 `group` 参数的最后面添加 `winbind` 参数，如下图所示：

```
$ sudo vi /etc/nsswitch.conf

```

![Add Windbind Service Switch for Samba](/data/attachment/album/201612/28/111615aapc0wb0g0gw50cg.png)

*为 Samba 服务添加 Winbind Service Switch 设置*

18、 最后，编辑 `/etc/pam.d/common-password` 文件，查找下图所示行并删除 `user_authtok` 参数。

该设置确保 AD 用户在通过 Linux 系统本地认证后，可以在命令行下修改他们的密码。有这个参数时，本地认证的 AD 用户不能在控制台下修改他们的密码。

```
password       [success=1 default=ignore]      pam_winbind.so try_first_pass

```

![Allow Samba AD Users to Change Passwords](/data/attachment/album/201612/28/111615pv3rzz500vo5v13r.png)

*允许 Samba AD 用户修改密码*

在每次 PAM 更新安装完成并应用到 PAM 模块，或者你每次执行 `pam-auth-update` 命令后，你都需要删除 `use_authtok` 参数。

19、 Samba4 的二进制文件会生成一个内建的 windindd 进程，并且默认是启用的。

因此，你没必要再次去启用并运行 Ubuntu 系统官方自带的 winbind 服务。

为了防止系统里原来已废弃的 winbind 服务被启动，确保执行以下命令来禁用并停止原来的 winbind 服务。

```
$ sudo systemctl disable winbind.service
$ sudo systemctl stop winbind.service

```

虽然我们不再需要运行原有的 winbind 进程，但是为了安装并使用 wbinfo 工具，我们还得从系统软件库中安装 Winbind 包。

wbinfo 工具可以用来从 winbindd 进程侧来查询活动目录用户和组。

以下命令显示了使用 `wbinfo` 命令如何查询 AD 用户及组信息。

```
$ wbinfo -g
$ wbinfo -u
$ wbinfo -i your_domain_user

```

![Check Samba4 AD Information ](/data/attachment/album/201612/28/111616gn6qt6cgqbmxgmmt.png)

*检查 Samba4 AD 信息*

![Check Samba4 AD User Info](/data/attachment/album/201612/28/111616ddk80786qkprkhfa.png)

*检查 Samba4 AD 用户信息*

20、 除了 `wbinfo` 工具外，你也可以使用 `getent` 命令行工具从 Name Service Switch 库中查询活动目录信息库，在 `/etc/nsswitch.conf` 配置文件中有相关描述内容。

通过 grep 命令用管道符从 `getent` 命令过滤结果集，以获取信息库中 AD 域用户及组信息。

```
# getent passwd | grep TECMINT
# getent group | grep TECMINT

```

![Get Samba4 AD Details](/data/attachment/album/201612/28/111617nwh5wovom75445mb.png)

*查看 Samba4 AD 详细信息*

### 第三步：使用活动目录账号登录 Linux 系统

21、 为了使用 Samba4 AD 用户登录系统，使用 `su -` 命令切换到 AD 用户账号即可。

第一次登录系统后，控制台会有信息提示用户的 home 目录已创建完成，系统路径为 `/home/$DOMAIN/` 之下，名字为用户的 AD 账号名。

使用 `id` 命令来查询其它已登录的用户信息。

```
# su - your_ad_user
$ id
$ exit

```

![Check Samba4 AD User Authentication on Linux](/data/attachment/album/201612/28/111617crtky1jrrjnj2cgw.png)

*检查 Linux 下 Samba4 AD 用户认证结果*

22、 当你成功登入系统后，在控制台下输入 `passwd` 命令来修改已登录的 AD 用户密码。

```
$ su - your_ad_user
$ passwd

```

![Change Samba4 AD User Password](/data/attachment/album/201612/28/111618pjic338etiyc5z01.png)

*修改 Samba4 AD 用户密码*

23、 默认情况下，活动目录用户没有可以完成系统管理工作的 root 权限。

要授予 AD 用户 root 权限，你必须把用户名添加到本地 sudo 组中，可使用如下命令完成。

确保你已输入域 、斜杠和 AD 用户名，并且使用英文单引号括起来，如下所示：

```
# usermod -aG sudo 'DOMAIN\your_domain_user'

```

要检查 AD 用户在本地系统上是否有 root 权限，登录后执行一个命令，比如，使用 sudo 权限执行 `apt-get update` 命令。

```
# su - tecmint_user
$ sudo apt-get update

```

![Grant sudo Permission to Samba4 AD User](/data/attachment/album/201612/28/111618dkqhboj2aqjwhw1t.png)

*授予 Samba4 AD 用户 sudo 权限*

24、 如果你想把活动目录组中的所有账号都授予 root 权限，使用 `visudo` 命令来编辑 `/etc/sudoers` 配置文件，在 root 权限那一行添加如下内容：

```
%DOMAIN\\your_domain\  group ALL=(ALL:ALL) ALL

```

注意 `/etc/sudoers` 的格式，不要弄乱。

`/etc/sudoers` 配置文件对于 ASCII 引号字符处理的不是很好，因此务必使用 '%' 来标识用户组，使用反斜杠来转义域名后的第一个斜杠，如果你的组名中包含空格（大多数 AD 内建组默认情况下都包含空格）使用另外一个反斜杠来转义空格。并且域的名称要大写。

![Give Sudo Access to All Samba4 AD Users](/data/attachment/album/201612/28/111618yfqhea2v0pjh0gff.png)

*授予所有 Samba4 用户 sudo 权限*

好了，差不多就这些了！管理 Samba4 AD 架构也可以使用 Windows 环境中的其它几个工具，比如 ADUC、DNS 管理器、 GPM 等等，这些工具可以通过安装从 Microsoft 官网下载的 RSAT 软件包来获得。

要通过 RSAT 工具来管理 Samba4 AD DC ，你必须要把 Windows 系统加入到 Samba4 活动目录。这将是我们下一篇文章的重点，在这之前，请继续关注。

---

via: <http://www.tecmint.com/manage-samba4-active-directory-linux-command-line>

作者：[Matei Cezar](http://www.tecmint.com/author/cezarmatei/) 译者：[rusking](https://github.com/rusking) 校对：[wxy](https://github.com/wxy)

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


如何在 Ubuntu 环境下搭建邮件服务器（一）

非常好！期待下一篇！

要是早几个月发就好了，两个月前做计算机网络的实验，就是用Linux搭建邮件服务器。

看不懂啊！！

![mail server](/data/attachment/album/201612/28/170142s5225bb70hfc0f9c.jpg "mail server")

在这个系列的文章中，我们将通过使用 Postfix、Dovecot 和 openssl 这三款工具来为你展示如何在 ubuntu 系统上搭建一个既可靠又易于配置的邮件服务器。

在这个容器和微服务技术日新月异的时代，值得庆幸的是有些事情并没有改变，例如搭建一个 Linux 下的邮件服务器，仍然需要许多步骤才能间隔各种服务器耦合在一起，而当你将这些配置好，放在一起，却又非常可靠稳定，不会像微服务那样一睁眼有了，一闭眼又没了。 在这个系列教程中我们将通过使用 Postfix、Dovecot 和 openssl 这三款工具在 ubuntu 系统上搭建一个既可靠又易于配置的邮件服务器。

Postfix 是一个古老又可靠的软件，它比原始的 Unix 系统的 MTA 软件 sendmail 更加容易配置和使用（还有人仍然在用sendmail 吗？）。 Exim 是 Debain 系统上的默认 MTA 软件，它比 Postfix 更加轻量而且超级容易配置，因此我们在将来的教程中会推出 Exim 的教程。

Dovecot（LCTT 译注：详情请阅读[维基百科](https://en.wikipedia.org/wiki/Dovecot_(software)）和 Courier 是两个非常受欢迎的优秀的 IMAP/POP3 协议的服务器软件，Dovecot 更加的轻量并且易于配置。

你必须要保证你的邮件通讯是安全的，因此我们就需要使用到 OpenSSL 这个软件，OpenSSL 也提供了一些很好用的工具来测试你的邮件服务器。

为了简单起见，在这一系列的教程中，我们将指导大家安装一个在局域网上的邮件服务器，你应该拥有一个局域网内的域名服务，并确保它是启用且正常工作的，查看这篇“[使用 dnsmasq 为局域网轻松提供 DNS 服务](https://www.linux.com/learn/dnsmasq-easy-lan-name-services )”会有些帮助，然后，你就可以通过注册域名并相应地配置防火墙，来将这台局域网服务器变成互联网可访问邮件服务器。这个过程网上已经有很多很详细的教程了，这里不再赘述，请大家继续跟着教程进行即可。

### 一些术语

让我们先来快速了解一些术语，因为当我们了解了这些术语的时候就能知道这些见鬼的东西到底是什么。 :D

* **MTA**：<ruby> 邮件传输代理 <rp>  （ </rp> <rt>  Mail Transfer Agent </rt> <rp>  ） </rp></ruby>，基于 SMTP 协议（简单邮件传输协议）的服务端，比如 Postfix、Exim、Sendmail 等。SMTP 服务端彼此之间进行相互通信（LCTT 译注 : 详情请阅读[维基百科](https://en.wikipedia.org/wiki/Message_transfer_agent)）。
* **MUA**： <ruby> 邮件用户代理 <rp>  （ </rp> <rt>  Mail User Agent </rt> <rp>  ） </rp></ruby>，你本地的邮件客户端，例如 : Evolution、KMail、Claws Mail 或者 Thunderbird（LCTT 译注 : 例如国内的 Foxmail）。
* **POP3**：<ruby> 邮局协议 <rp>  （ </rp> <rt>  Post-Office Protocol </rt> <rp>  ） </rp></ruby>版本 3，将邮件从 SMTP 服务器传输到你的邮件客户端的的最简单的协议。POP 服务端是非常简单小巧的，单一的一台机器可以为数以千计的用户提供服务。
* **IMAP**： <ruby> 交互式消息访问协议 <rp>  （ </rp> <rt>  Interactive Message Access Protocol </rt> <rp>  ） </rp></ruby>，许多企业使用这个协议因为邮件可以被保存在服务器上，而用户不必担心会丢失消息。IMAP 服务器需要大量的内存和存储空间。
* **TLS**：<ruby> 传输套接层 <rp>  （ </rp> <rt>  Transport socket layer </rt> <rp>  ） </rp></ruby>是 SSL（<ruby> 安全套接层 <rp>  （ </rp> <rt>  Secure Sockets Layer </rt> <rp>  ） </rp></ruby>）的改良版，为 SASL 身份认证提供了加密的传输服务层。
* **SASL**：<ruby> 简单身份认证与安全层 <rp>  （ </rp> <rt>  Simple Authentication and Security Layer </rt> <rp>  ） </rp></ruby>，用于认证用户。SASL进行身份认证，而上面说的 TLS 提供认证数据的加密传输。
* **StartTLS**: 也被称为伺机 TLS 。如果服务器双方都支持 SSL/TLS，StartTLS 就会将纯文本连接升级为加密连接（TLS 或 SSL）。如果有一方不支持加密，则使用明文传输。StartTLS 会使用标准的未加密端口 25 （SMTP）、 110（POP3）和 143 （IMAP）而不是对应的加密端口 465（SMTP）、995（POP3） 和 993 （IMAP）。

### 啊，我们仍然有 sendmail

绝大多数的 Linux 版本仍然还保留着 `/usr/sbin/sendmail` 。 这是在那个 MTA 只有一个 sendmail 的古代遗留下来的痕迹。在大多数 Linux 发行版中，`/usr/sbin/sendmail` 会符号链接到你安装的 MTA 软件上。如果你的 Linux 中有它，不用管它，你的发行版会自己处理好的。

### 安装 Postfix

使用 `apt-get install postfix` 来做基本安装时要注意（图 1），安装程序会打开一个向导，询问你想要搭建的服务器类型，你要选择“Internet Server”，虽然这里是局域网服务器。它会让你输入完全限定的服务器域名（例如： myserver.mydomain.net）。对于局域网服务器，假设你的域名服务已经正确配置，(我多次提到这个是因为经常有人在这里出现错误)，你也可以只使用主机名。

![Postfix](/data/attachment/album/201612/28/170142zczxz01hbwa1ankd.png "Postfix")

*图 1：Postfix 的配置。*

Ubuntu 系统会为 Postfix 创建一个配置文件，并启动三个守护进程 : `master`、`qmgr` 和 `pickup`，这里没用一个叫 Postfix 的命令或守护进程。（LCTT 译注：名为 `postfix` 的命令是管理命令。）

```
$ ps ax
 6494 ? Ss 0:00 /usr/lib/postfix/master
 6497 ? S 0:00 pickup -l -t unix -u -c
 6498 ? S 0:00 qmgr -l -t unix -u

```

你可以使用 Postfix 内置的配置语法检查来测试你的配置文件，如果没用发现语法错误，不会输出任何内容。

```
$ sudo postfix check
[sudo] password for carla:

```

使用 `netstat` 来验证 `postfix` 是否正在监听 25 端口。

```
$ netstat -ant
tcp 0 0 0.0.0.0:25 0.0.0.0:* LISTEN
tcp6 0 0 :::25  :::*  LISTEN

```

现在让我们再操起古老的 `telnet` 来进行测试 :

```
$ telnet myserver 25
Trying 127.0.1.1...
Connected to myserver.
Escape character is '^]'.
220 myserver ESMTP Postfix (Ubuntu)
EHLO myserver
250-myserver
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-STARTTLS
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
^]

telnet>

```

嘿，我们已经验证了我们的服务器名，而且 Postfix 正在监听 SMTP 的 25 端口而且响应了我们键入的命令。

按下 `^]` 终止连接，返回 telnet。输入 `quit` 来退出 telnet。输出的 ESMTP（扩展的 SMTP ） 250 状态码如下。 （LCTT 译注： ESMTP (Extended SMTP)，即扩展 SMTP，就是对标准 SMTP 协议进行的扩展。详情请阅读[维基百科](https://en.wikipedia.org/wiki/Extended_SMTP)）

* **PIPELINING** 允许多个命令流式发出，而不必对每个命令作出响应。
* **SIZE** 表示服务器可接收的最大消息大小。
* **VRFY** 可以告诉客户端某一个特定的邮箱地址是否存在，这通常应该被取消，因为这是一个安全漏洞。
* **ETRN** 适用于非持久互联网连接的服务器。这样的站点可以使用 ETRN 从上游服务器请求邮件投递，Postfix 可以配置成延迟投递邮件到 ETRN 客户端。
* **STARTTLS** （详情见上述说明）。
* **ENHANCEDSTATUSCODES**，服务器支撑增强型的状态码和错误码。
* **8BITMIME**，支持 8 位 MIME，这意味着完整的 ASCII 字符集。最初，原始的 ASCII 是 7 位。
* **DSN**，投递状态通知，用于通知你投递时的错误。

Postfix 的主配置文件是： `/etc/postfix/main.cf`，这个文件是安装程序创建的，可以参考[这个资料](http://www.postfix.org/postconf.5.html)来查看完整的 `main.cf` 参数列表， `/etc/postfix/postfix-files` 这个文件描述了 Postfix 完整的安装文件。

[下一篇教程](/article-8077-1.html)我们会讲解 Dovecot 的安装和测试，然后会给我们自己发送一些邮件。

---

via: <https://www.linux.com/learn/how-build-email-server-ubuntu-linux>

作者：[CARLA SCHRODER](https://www.linux.com/users/cschroder) 译者：[WangYihang](https://github.com/WangYihang) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 组织编译，[Linux中国](https://linux.cn/) 荣誉推出


LXD 2.0 系列（四）：资源控制

这是 LXD 2.0 系列介绍文章的第四篇。

1. [LXD 入门](/article-7618-1.html)
2. [安装与配置](/article-7687-1.html)
3. [你的第一个 LXD 容器](/article-7706-1.html)
4. [资源控制](/article-8072-1.html)
5. [镜像管理](/article-8107-1.html)
6. [远程主机及容器迁移](/article-8169-1.html)
7. [LXD 中的 Docker](/article-8235-1.html)
8. [LXD 中的 LXD](/article-8257-1.html)
9. [实时迁移](/article-8263-1.html)
10. [LXD 和 Juju](/article-8273-1.html)
11. [LXD 和 OpenStack](/article-8274-1.html)
12. [调试，及给 LXD 做贡献](/article-8282-1.html)

![](/data/attachment/album/201612/28/234845wltalollpalno5rl.jpg)

因为 LXD 容器管理有很多命令，因此这篇文章会很长。 如果你想要快速地浏览这些相同的命令，你可以[尝试下我们的在线演示](https://github.com/lxc/lxd/blob/master/doc/configuration.md)！

### 可用资源限制

LXD 提供了各种资源限制。其中一些与容器本身相关，如内存配额、CPU 限制和 I/O 优先级。而另外一些则与特定设备相关，如 I/O 带宽或磁盘用量限制。

与所有 LXD 配置一样，资源限制可以在容器运行时动态更改。某些可能无法启用，例如，如果设置的内存值小于当前内存用量，但 LXD 将会试着设置并且报告失败。

所有的限制也可以通过配置文件继承，在这种情况下每个受影响的容器将受到该限制的约束。也就是说，如果在默认配置文件中设置 `limits.memory=256MB`，则使用默认配置文件（通常是全都使用）的每个容器的内存限制为 256MB。

我们不支持资源限制池，将其中的限制由一组容器共享，因为我们没有什么好的方法通过现有的内核 API 实现这些功能。

#### 磁盘

这或许是最需要和最明显的需求。只需设置容器文件系统的大小限制，并对容器强制执行。

LXD 确实可以让你这样做！

不幸的是，这比它听起来复杂得多。 Linux 没有基于路径的配额，而大多数文件系统只有基于用户和组的配额，这对容器没有什么用处。

如果你正在使用 ZFS 或 btrfs 存储后端，这意味着现在 LXD 只能支持磁盘限制。也有可能为 LVM 实现此功能，但这取决于与它一起使用的文件系统，并且如果结合实时更新那会变得棘手起来，因为并不是所有的文件系统都允许在线增长，而几乎没有一个允许在线收缩。

#### CPU

当涉及到 CPU 的限制，我们支持 4 种不同的东西：

* 只给我 X 个 CPU 核心

在这种模式下，你让 LXD 为你选择一组核心，然后为更多的容器和 CPU 的上线/下线提供负载均衡。

容器只看到这个数量的 CPU 核心。
* 给我一组特定的 CPU 核心（例如，核心1、3 和 5）

类似于第一种模式，但是不会做负载均衡，你会被限制在那些核心上，无论它们有多忙。
* 给我你拥有的 20％ 处理能力

在这种模式下，你可以看到所有的 CPU，但调度程序将限制你使用 20％ 的 CPU 时间，但这只有在负载状态才会这样！所以如果系统不忙，你的容器可以跑得很欢。而当其他的容器也开始使用 CPU 时，它会被限制用量。
* 每测量 200ms，给我 50ms（并且不超过）

此模式与上一个模式类似，你可以看到所有的 CPU，但这一次，无论系统可能是多么空闲，你只能使用你设置的极限时间下的尽可能多的 CPU 时间。在没有过量使用的系统上，这可使你可以非常整齐地分割 CPU，并确保这些容器的持续性能。

另外还可以将前两个中的一个与最后两个之一相结合，即请求一组 CPU，然后进一步限制这些 CPU 的 CPU 时间。

除此之外，我们还有一个通用的优先级调节方式，可以告诉调度器当你处于负载状态时，两个争夺资源的容器谁会取得胜利。

#### 内存

内存听起来很简单，就是给我多少 MB 的内存！

它绝对可以那么简单。 我们支持这种限制以及基于百分比的请求，比如给我 10％ 的主机内存！

另外我们在上层支持一些额外的东西。 例如，你可以选择在每个容器上打开或者关闭 swap，如果打开，还可以设置优先级，以便你可以选择哪些容器先将内存交换到磁盘！

内存限制默认是“hard”。 也就是说，当内存耗尽时，内核将会开始杀掉你的那些进程。

或者，你可以将强制策略设置为“soft”，在这种情况下，只要没有别的进程的情况下，你将被允许使用尽可能多的内存。一旦别的进程想要这块内存，你将无法分配任何内存，直到你低于你的限制或者主机内存再次有空余。

#### 网络 I/O

网络 I/O 可能是我们看起来最简单的限制，但是相信我，实现真的不简单！

我们支持两种限制。 第一个是对网络接口的速率限制。你可以设置入口和出口的限制，或者只是设置“最大”限制然后应用到出口和入口。这个只支持“桥接”和“p2p”类型接口。

第二种是全局网络 I/O 优先级，仅当你的网络接口趋于饱和的时候再使用。

#### 块 I/O

我把最古怪的放在最后。对于用户看起来它可能简单，但有一些情况下，它的结果并不会和你的预期一样。

我们在这里支持的基本上与我在网络 I/O 中描述的相同。

你可以直接设置磁盘的读写 IO 的频率和速率，并且有一个全局的块 I/O 优先级，它会通知 I/O 调度程序更倾向哪个。

古怪的是如何设置以及在哪里应用这些限制。不幸的是，我们用于实现这些功能的底层使用的是完整的块设备。这意味着我们不能为每个路径设置每个分区的 I/O 限制。

这也意味着当使用可以支持多个块设备映射到指定的路径（带或者不带 RAID）的 ZFS 或 btrfs 时，我们并不知道这个路径是哪个块设备提供的。

这意味着，完全有可能，实际上确实有可能，容器使用的多个磁盘挂载点（绑定挂载或直接挂载）可能来自于同一个物理磁盘。

这就使限制变得很奇怪。为了使限制生效，LXD 具有猜测给定路径所对应块设备的逻辑，这其中包括询问 ZFS 和 btrfs 工具，甚至可以在发现一个文件系统中循环挂载的文件时递归地找出它们。

这个逻辑虽然不完美，但通常会找到一组应该应用限制的块设备。LXD 接着记录并移动到下一个路径。当遍历完所有的路径，然后到了非常奇怪的部分。它会平均你为相应块设备设置的限制，然后应用这些。

这意味着你将在容器中“平均”地获得正确的速度，但这也意味着你不能对来自同一个物理磁盘的“/fast”和一个“/slow”目录应用不同的速度限制。 LXD 允许你设置它，但最后，它会给你这两个值的平均值。

### 它怎么工作？

除了网络限制是通过较旧但是良好的“tc”实现的，上述大多数限制是通过 Linux 内核的 cgroup API 来实现的。

LXD 在启动时会检测你在内核中启用了哪些 cgroup，并且将只应用你的内核支持的限制。如果你缺少一些 cgroup，守护进程会输出警告，接着你的 init 系统将会记录这些。

在 Ubuntu 16.04 上，默认情况下除了内存交换审计外将会启用所有限制，内存交换审计需要你通过`swapaccount = 1`这个内核引导参数来启用。

### 应用这些限制

上述所有限制都能够直接或者用某个配置文件应用于容器。容器范围的限制可以使用：

```
lxc config set CONTAINER KEY VALUE

```

或对于配置文件设置：

```
lxc profile set PROFILE KEY VALUE

```

当指定特定设备时：

```
lxc config device set CONTAINER DEVICE KEY VALUE

```

或对于配置文件设置：

```
lxc profile device set PROFILE DEVICE KEY VALUE

```

有效配置键、设备类型和设备键的完整列表可以[看这里](https://github.com/lxc/lxd/blob/master/doc/configuration.md)。

#### CPU

要限制使用任意两个 CPU 核心可以这么做：

```
lxc config set my-container limits.cpu 2

```

要指定特定的 CPU 核心，比如说第二和第四个：

```
lxc config set my-container limits.cpu 1,3

```

更加复杂的情况还可以设置范围：

```
lxc config set my-container limits.cpu 0-3,7-11

```

限制实时生效，你可以看下面的例子：

```
stgraber@dakara:~$ lxc exec zerotier -- cat /proc/cpuinfo | grep ^proces
processor : 0
processor : 1
processor : 2
processor : 3
stgraber@dakara:~$ lxc config set zerotier limits.cpu 2
stgraber@dakara:~$ lxc exec zerotier -- cat /proc/cpuinfo | grep ^proces
processor : 0
processor : 1

```

注意，为了避免完全混淆用户空间，lxcfs 会重排 `/proc/cpuinfo` 中的条目，以便没有错误。

就像 LXD 中的一切，这些设置也可以应用在配置文件中：

```
stgraber@dakara:~$ lxc exec snappy -- cat /proc/cpuinfo | grep ^proces
processor : 0
processor : 1
processor : 2
processor : 3
stgraber@dakara:~$ lxc profile set default limits.cpu 3
stgraber@dakara:~$ lxc exec snappy -- cat /proc/cpuinfo | grep ^proces
processor : 0
processor : 1
processor : 2

```

要限制容器使用 10% 的 CPU 时间，要设置下 CPU allowance：

```
lxc config set my-container limits.cpu.allowance 10%

```

或者给它一个固定的 CPU 时间切片：

```
lxc config set my-container limits.cpu.allowance 25ms/200ms

```

最后，要将容器的 CPU 优先级调到最低：

```
lxc config set my-container limits.cpu.priority 0

```

#### 内存

要直接应用内存限制运行下面的命令：

```
lxc config set my-container limits.memory 256MB

```

（支持的后缀是 KB、MB、GB、TB、PB、EB）

要关闭容器的内存交换（默认启用）：

```
lxc config set my-container limits.memory.swap false

```

告诉内核首先交换指定容器的内存：

```
lxc config set my-container limits.memory.swap.priority 0

```

如果你不想要强制的内存限制：

```
lxc config set my-container limits.memory.enforce soft

```

#### 磁盘和块 I/O

不像 CPU 和内存，磁盘和 I/O 限制是直接作用在实际的设备上的，因此你需要编辑原始设备或者屏蔽某个具体的设备。

要设置磁盘限制（需要 btrfs 或者 ZFS）：

```
lxc config device set my-container root size 20GB

```

比如：

```
stgraber@dakara:~$ lxc exec zerotier -- df -h /
Filesystem                        Size Used Avail Use% Mounted on
encrypted/lxd/containers/zerotier 179G 542M  178G   1% /
stgraber@dakara:~$ lxc config device set zerotier root size 20GB
stgraber@dakara:~$ lxc exec zerotier -- df -h /
Filesystem                       Size  Used Avail Use% Mounted on
encrypted/lxd/containers/zerotier 20G  542M   20G   3% /

```

要限制速度，你可以：

```
lxc config device set my-container root limits.read 30MB
lxc config device set my-container root.limits.write 10MB

```

或者限制 IO 频率：

```
lxc config device set my-container root limits.read 20Iops
lxc config device set my-container root limits.write 10Iops

```

最后你在一个过量使用的繁忙系统上，你或许想要：

```
lxc config set my-container limits.disk.priority 10

```

将那个容器的 I/O 优先级调到最高。

#### 网络 I/O

只要机制可用，网络 I/O 基本等同于块 I/O。

比如：

```
stgraber@dakara:~$ lxc exec zerotier -- wget http://speedtest.newark.linode.com/100MB-newark.bin -O /dev/null
--2016-03-26 22:17:34-- http://speedtest.newark.linode.com/100MB-newark.bin
Resolving speedtest.newark.linode.com (speedtest.newark.linode.com)... 50.116.57.237, 2600:3c03::4b
Connecting to speedtest.newark.linode.com (speedtest.newark.linode.com)|50.116.57.237|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 104857600 (100M) [application/octet-stream]
Saving to: '/dev/null'

/dev/null 100%[===================>] 100.00M 58.7MB/s in 1.7s

2016-03-26 22:17:36 (58.7 MB/s) - '/dev/null' saved [104857600/104857600]

stgraber@dakara:~$ lxc profile device set default eth0 limits.ingress 100Mbit
stgraber@dakara:~$ lxc profile device set default eth0 limits.egress 100Mbit
stgraber@dakara:~$ lxc exec zerotier -- wget http://speedtest.newark.linode.com/100MB-newark.bin -O /dev/null
--2016-03-26 22:17:47-- http://speedtest.newark.linode.com/100MB-newark.bin
Resolving speedtest.newark.linode.com (speedtest.newark.linode.com)... 50.116.57.237, 2600:3c03::4b
Connecting to speedtest.newark.linode.com (speedtest.newark.linode.com)|50.116.57.237|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 104857600 (100M) [application/octet-stream]
Saving to: '/dev/null'

/dev/null 100%[===================>] 100.00M 11.4MB/s in 8.8s

2016-03-26 22:17:56 (11.4 MB/s) - '/dev/null' saved [104857600/104857600]

```

这就是如何将一个千兆网的连接速度限制到仅仅 100Mbit/s 的！

和块 I/O 一样，你可以设置一个总体的网络优先级：

```
lxc config set my-container limits.network.priority 5

```

### 获取当前资源使用率

[LXD API](https://github.com/lxc/lxd/blob/master/doc/rest-api.md) 可以导出目前容器资源使用情况的一点信息，你可以得到：

* 内存：当前、峰值、目前内存交换和峰值内存交换
* 磁盘：当前磁盘使用率
* 网络：每个接口传输的字节和包数。

另外如果你使用的是非常新的 LXD（在写这篇文章时的 git 版本），你还可以在`lxc info`中得到这些信息：

```
stgraber@dakara:~$ lxc info zerotier
Name: zerotier
Architecture: x86_64
Created: 2016/02/20 20:01 UTC
Status: Running
Type: persistent
Profiles: default
Pid: 29258
Ips:
 eth0: inet 172.17.0.101
 eth0: inet6 2607:f2c0:f00f:2700:216:3eff:feec:65a8
 eth0: inet6 fe80::216:3eff:feec:65a8
 lo: inet 127.0.0.1
 lo: inet6 ::1
 lxcbr0: inet 10.0.3.1
 lxcbr0: inet6 fe80::f0bd:55ff:feee:97a2
 zt0: inet 29.17.181.59
 zt0: inet6 fd80:56c2:e21c:0:199:9379:e711:b3e1
 zt0: inet6 fe80::79:e7ff:fe0d:5123
Resources:
 Processes: 33
 Disk usage:
  root: 808.07MB
 Memory usage:
  Memory (current): 106.79MB
  Memory (peak): 195.51MB
  Swap (current): 124.00kB
  Swap (peak): 124.00kB
 Network usage:
  lxcbr0:
   Bytes received: 0 bytes
   Bytes sent: 570 bytes
   Packets received: 0
   Packets sent: 0
  zt0:
   Bytes received: 1.10MB
   Bytes sent: 806 bytes
   Packets received: 10957
   Packets sent: 10957
  eth0:
   Bytes received: 99.35MB
   Bytes sent: 5.88MB
   Packets received: 64481
   Packets sent: 64481
  lo:
   Bytes received: 9.57kB
   Bytes sent: 9.57kB
   Packets received: 81
   Packets sent: 81
Snapshots:
 zerotier/blah (taken at 2016/03/08 23:55 UTC) (stateless)

```

### 总结

LXD 团队花费了几个月的时间来迭代我们使用的这些限制的语言。 它是为了在保持强大和功能明确的基础上同时保持简单。

实时地应用这些限制和通过配置文件继承，使其成为一种非常强大的工具，可以在不影响正在运行的服务的情况下实时管理服务器上的负载。

### 更多信息

LXD 的主站在： <https://linuxcontainers.org/lxd>

LXD 的 GitHub 仓库： <https://github.com/lxc/lxd>

LXD 的邮件列表：<https://lists.linuxcontainers.org>

LXD 的 IRC 频道：#lxcontainers on irc.freenode.net

如果你不想在你的机器上安装LXD，你可以[在线尝试下](https://linuxcontainers.org/lxd/try-it)。

---

作者简介：我是 Stéphane Graber。我是 LXC 和 LXD 项目的领导者，目前在加拿大魁北克蒙特利尔的家所在的Canonical 有限公司担任 LXD 的技术主管。

---

via: <https://www.stgraber.org/2016/03/26/lxd-2-0-resource-control-412/>

作者：[Stéphane Graber](https://www.stgraber.org/author/stgraber/) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

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


把 SQL Server 迁移到 Linux？不如换成 MySQL

所以我选PG，手动滑稽

没有自由开源之心，对于用户来说都很可怕！！！最后一收网，用户的前期投入，维护队伍建设都是问题，只能看着人家做地要价呆若木鸡呐！！！

换数据库也意味着业务系统也要改造。再说了使用sql server数据库的，本身的业务系统想必也用了很多微软的产品，这就不仅仅是换数据库的问题了。

净瞎折腾

来自河南洛阳的 Chrome Mobile 45.0|Android 6.0 用户

linux的漏洞最多。

越是开源，漏洞越多，尤其android和linux的漏洞最多。

再说了，sql server的性能超越oracle了，mySql的性能还很一般。

来自江西南昌的 Chrome Mobile iOS 55.0|iOS 10.2 用户

最近几年，数量庞大的个人和组织放弃 Windows 平台选择 Linux 平台，而且随着人们体验到更多 Linux 的发展，这个数字将会继续增长。在很长的一段时间内， Linux 是网络服务器的领导者，因为大部分的网络服务器都运行在 Linux 之上，这或许是为什么那么多的个人和组织选择迁移的一个原因。

![](/data/attachment/album/201612/29/005244z288682nsm2mwpy8.jpg)

迁移的原因有很多，更强的平台稳定性、可靠性、成本、所有权和安全性等等。随着更多的个人和组织迁移到 Linux 平台，MS SQL 服务器数据库管理系统的迁移也有着同样的趋势，首选的是 MySQL ，这是因为 MySQL 的互用性、平台无关性和购置成本低。

有如此多的个人和组织完成了迁移，这是应业务需求而产生的迁移，而不是为了迁移的乐趣。因此，有必要做一个综合可行性和成本效益分析，以了解迁移对于你的业务上的正面和负面影响。

迁移需要基于以下重要因素：

### 对平台的掌控

不像 Windows 那样，你不能完全控制版本发布和修复，而 Linux 可以让你需要需要修复的时候真正给了你获取修复的灵活性。这一点受到了开发者和安全人员的喜爱，因为他们能在一个安全威胁被确定时立即自行打补丁，不像 Windows ，你只能期望官方尽快发布补丁。

### 跟随大众

目前， 运行在 Linux 平台上的服务器在数量上远超 Windows，几乎是全世界服务器数量的四分之三，而且这种趋势在最近一段时间内不会改变。因此，许多组织正在将他们的服务完全迁移到 Linux 上，而不是同时使用两种平台，同时使用将会增加他们的运营成本。

### 微软没有开放 SQL Server 的源代码

微软宣称他们下一个名为 Denali 的新版 MS SQL Server 将会是一个 [Linux 版本](/article-7967-1.html)，并且不会开放其源代码，这意味着他们仍然使用的是软件授权模式，只是新版本将能在 Linux 上运行而已。这一点将许多乐于接受开源新版本的人拒之门外。

这也没有给那些使用闭源的 Oracle 用户另一个选择，对于使用完全开源的 [MySQL 用户](http://www.scalearc.com/how-it-works/products/scalearc-for-mysql)也是如此。

### 节约授权许可证的花费

授权许可证的潜在成本让许多用户很失望。在 Windows 平台上运行 MS SQL 服务器有太多的授权许可证牵涉其中。你需要这些授权许可证：

* Windows 操作系统
* MS SQL 服务器
* 特定的数据库工具，例如 SQL 分析工具等

不像 Windows 平台，Linux 完全没有高昂的授权花费，因此更能吸引用户。 MySQL 数据库也能免费获取，甚而它提供了像 MS SQL 服务器一样的灵活性，那就更值得选择了。不像那些给 MS SQL 设计的收费工具，大部分的 MySQL 数据库实用程序是免费的。

### 有时候用的是特殊的硬件

因为 Linux 是不同的开发者所开发，并在不断改进中，所以它独立于所运行的硬件之上，并能被广泛使用在不同的硬件平台。然而尽管微软正在努力让 Windows 和 MSSQL 服务器做到硬件无关，但在平台无关上依旧有些限制。

### 支持

有了 Linux、MySQL 和其它的开源软件，获取满足自己特定需求的帮助变得更加简单，因为有不同开发者参与到这些软件的开发过程中。这些开发者或许就在你附近，这样更容易获取帮助。在线论坛也能帮上不少，你能发帖并讨论你所面对的问题。

至于那些商业软件，你只能根据他们的软件协议和时间来获得帮助，有时候他们不能在你的时间范围内给出一个解决方案。

在不同的情况中，迁移到 Linux 都是你最好的选择，加入一个彻底的、稳定可靠的平台来获取优异表现，众所周知，它比 Windows 更健壮。这值得一试。

---

via: <https://www.howtoforge.com/tutorial/moving-with-sql-server-to-linux-move-from-sql-server-to-mysql-as-well/>

作者：[Tony Branson](https://twitter.com/howtoforgecom) 译者：[ypingcn](https://github.com/ypingcn) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 组织编译，[Linux中国](https://linux.cn/) 荣誉推出


PyCharm - Linux 下最好的 Python IDE

Summary: PyCharm 是由 Jetbrains 开发的一个编辑器和调试器，Jetbrains 就是那个开发了 Resharper 的公司。不得不说，Resharper 是一个很优秀的工具，它被 Windows 开发者们用来重构代码，同时，它也使得 Windows 开发者们写 .NET 代码更加轻松。Resharper 的许多原则也被加入到了 PyCharm 专业版中。

怎么在liunx 上支持中文输入

我觉得最出名的intellij idea 吧

来自223.104.63.37的 Sina Weibo 6.12|Android 6.0 用户

不要轻易说“最”

打个酱油。。。

在用 + 1

秀下限？python。再说同一个公司出的IDE，你觉得pycharm会比idea差？

一个模子出来的东西

那个截图怎么跟Android Studio长得那么像！！

嗯，可能比较适合新人吧

### 介绍

![](/data/attachment/album/201612/29/124006mi4yvyz4j6q4l4hz.jpg)

在这篇指南中，我将向你介绍一个集成开发环境 - PyCharm， 你可以在它上面使用 Python 编程语言开发专业应用。

Python 是一门优秀的编程语言，因为它真正实现了跨平台，用它开发的应用程序在 Windows、Linux 以及 Mac 系统上均可运行，无需重新编译任何代码。

PyCharm 是由 [Jetbrains](https://www.jetbrains.com/pycharm/specials/pycharm/pycharm.html?&gclid=CjwKEAjw34i_BRDH9fbylbDJw1gSJAAvIFqU238G56Bd2sKU9EljVHs1bKKJ8f3nV--Q9knXaifD8xoCRyjw_wcB&gclsrc=aw.ds.ds&dclid=CNOy3qGQoc8CFUJ62wodEywCDg) 开发的一个编辑器和调试器，[Jetbrains](https://www.jetbrains.com/pycharm/specials/pycharm/pycharm.html?&gclid=CjwKEAjw34i_BRDH9fbylbDJw1gSJAAvIFqU238G56Bd2sKU9EljVHs1bKKJ8f3nV--Q9knXaifD8xoCRyjw_wcB&gclsrc=aw.ds.ds&dclid=CNOy3qGQoc8CFUJ62wodEywCDg) 就是那个开发了 Resharper 的公司。不得不说，Resharper 是一个很优秀的工具，它被 Windows 开发者们用来重构代码，同时，它也使得 Windows 开发者们写 .NET 代码更加轻松。[Resharper](https://www.jetbrains.com/resharper/) 的许多原则也被加入到了 [PyCharm](https://www.jetbrains.com/pycharm/specials/pycharm/pycharm.html?&gclid=CjwKEAjw34i_BRDH9fbylbDJw1gSJAAvIFqU238G56Bd2sKU9EljVHs1bKKJ8f3nV--Q9knXaifD8xoCRyjw_wcB&gclsrc=aw.ds.ds&dclid=CNOy3qGQoc8CFUJ62wodEywCDg) 专业版中。

### 如何安装 PyCharm

我已经[写了一篇](/article-8080-1.html)关于如何获取 PyCharm 的指南，下载、解压文件，然后运行。

### 欢迎界面

当你第一次运行 PyCharm 或者关闭一个项目的时候，会出现一个屏幕，上面显示一系列近期项目。

你也会看到下面这些菜单选项：

* 创建新项目
* 打开项目
* 从版本控制仓库检出

还有一个配置设置选项，你可以通过它设置默认 Python 版本或者一些其他设置。

### 创建一个新项目

当你选择‘创建一个新项目’以后，它会提供下面这一系列可能的项目类型供你选择：

* Pure Python
* Django
* Flask
* Google App Engine
* Pyramid
* Web2Py
* Angular CLI
* AngularJS
* Foundation
* HTML5 Bolierplate
* React Starter Kit
* Twitter Bootstrap
* Web Starter Kit

这不是一个编程教程，所以我没必要说明这些项目类型是什么。如果你想创建一个可以运行在 Windows、Linux 和 Mac 上的简单桌面运行程序，那么你可以选择 Pure Python 项目，然后使用 Qt 库来开发图形应用程序，这样的图形应用程序无论在何种操作系统上运行，看起来都像是原生的，就像是在该系统上开发的一样。

选择了项目类型以后，你需要输入一个项目名字并且选择一个 Python 版本来进行开发。

### 打开一个项目

你可以通过单击‘最近打开的项目’列表中的项目名称来打开一个项目，或者，你也可以单击‘打开’，然后浏览到你想打开的项目所在的文件夹，找到该项目，然后选择‘确定’。

### 从源码控制进行查看

PyCharm 提供了从各种在线资源查看项目源码的选项，在线资源包括 [GitHub](https://github.com/)、[CVS](http://www.linuxhowtos.org/System/cvs_tutorial.htm)、Git、[Mercurial](https://www.mercurial-scm.org/) 以及 [Subversion](https://subversion.apache.org/)。

### PyCharm IDE（集成开发环境）

PyCharm IDE 中可以打开顶部的菜单，在这个菜单下方你可以看到每个打开的项目的标签。

屏幕右方是调试选项区，可以单步运行代码。

左侧面板有项目文件和外部库的列表。

如果想在项目中新建一个文件，你可以鼠标右击项目的名字，然后选择‘新建’。然后你可以在下面这些文件类型中选择一种添加到项目中：

* 文件
* 目录
* Python 包
* Python 包
* Jupyter 笔记
* HTML 文件
* Stylesheet
* JavaScript
* TypeScript
* CoffeeScript
* Gherkin
* 数据源

当添加了一个文件，比如 Python 文件以后，你可以在右边面板的编辑器中进行编辑。

文本是全彩色编码的，并且有黑体文本。垂直线显示缩进，从而能够确保缩进正确。

编辑器具有智能补全功能，这意味着当你输入库名字或可识别命令的时候，你可以按 'Tab' 键补全命令。

![](/data/attachment/album/201612/29/124048kjpp6pppiuk6iu6i.jpg)

### 调试程序

你可以利用屏幕右上角的’调试选项’调试程序的任何一个地方。

如果你是在开发一个图形应用程序，你可以点击‘绿色按钮’来运行程序，你也可以通过 'shift+F10'　快捷键来运行程序。

为了调试应用程序，你可以点击紧挨着‘绿色按钮’的‘绿色箭头’或者按 ‘shift+F9’ 快捷键。你可以点击一行代码的灰色边缘，从而设置断点，这样当程序运行到这行代码的时候就会停下来。

你可以按 'F8' 单步向前运行代码，这意味着你只是运行代码但无法进入函数内部，如果要进入函数内部，你可以按 'F7'。如果你想从一个函数中返回到调用函数，你可以按 'shift+F8'。

调试过程中，你会在屏幕底部看到许多窗口，比如进程和线程列表，以及你正在监视的变量。

当你运行到一行代码的时候，你可以对这行代码中出现的变量进行监视，这样当变量值改变的时候你能够看到。

另一个不错的选择是使用覆盖检查器运行代码。在过去这些年里，编程界发生了很大的变化，现在，对于开发人员来说，进行测试驱动开发是很常见的，这样他们可以检查对程序所做的每一个改变，确保不会破坏系统的另一部分。

覆盖检查器能够很好的帮助你运行程序，执行一些测试，运行结束以后，它会以百分比的形式告诉你测试运行所覆盖的代码有多少。

还有一个工具可以显示‘类函数’或‘类’的名字，以及一个项目被调用的次数和在一个特定代码片段运行所花费的时间。

### 代码重构

PyCharm 一个很强大的特性是代码重构选项。

当你开始写代码的时候，会在右边缘出现一个小标记。如果你写的代码可能出错或者写的不太好， PyCharm 会标记上一个彩色标记。

点击彩色标记将会告诉你出现的问题并提供一个解决方法。

比如，你通过一个导入语句导入了一个库，但没有使用该库中的任何东西，那么不仅这行代码会变成灰色，彩色标记还会告诉你‘该库未使用’。

对于正确的代码，也可能会出现错误提示，比如在导入语句和函数起始之间只有一个空行。当你创建了一个名称非小写的函数时它也会提示你。

你不必遵循 PyCharm 的所有规则。这些规则大部分只是好的编码准则，与你的代码是否能够正确运行无关。

代码菜单还有其它的重构选项。比如，你可以进行代码清理以及检查文件或项目问题。

### 总结

PyCharm 是 Linux 系统上开发 Python 代码的一个优秀编辑器，并且有两个可用版本。社区版可供临时开发者使用，专业版则提供了开发者开发专业软件可能需要的所有工具。

---

via: <https://www.lifewire.com/pycharm-the-best-linux-python-ide-4091045>

作者：[Gary Newell](https://www.lifewire.com/gary-newell-2180098) 译者：[ucasFL](https://github.com/ucasFL) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 组织编译，[Linux中国](https://linux.cn/) 荣誉推出


Linux 服务器安全简明指南

Summary: 现在让我们强化你的服务器以防止未授权访问。

自动安全更新有风险，一旦某个包有问题，或者和现有环境有冲突，全部同时更新那会就麻烦了。稳妥的是逐批更新。

添加一个受限用户都是老生长谈了。

ssh 用密钥登录，其前提是存放私钥的系统是安全可信的。还有私钥上的密码短语，设置也是需要仔细考虑。

netstat 命令已经过时，RPM 系默认是不安装该命令所属包。

我觉得一般用 ssh 登录的都是承载重要业务的服务器，用 ssh 客户端提供自身公钥给服务器，感觉有些本末倒置，服务器方面难以鉴定该电脑是否处于可信状态。我以为应该采用集中登录，并向明确要登录指定服务器的电脑颁发证书。必要时，追加双重验证。<br />
一旦发现某台电脑存在可疑行为，立即终止对应用户的访问凭据，同时吊销该客户端电脑的证书，双管齐下难阻断可疑访问。

很不错的一篇文章，感谢。

现在让我们强化你的服务器以防止未授权访问。

现在让我们强化你的服务器以防止未授权访问。

![](/data/attachment/album/201612/30/001143d53jv5fzqcpx3338.jpg)

### 经常升级系统

保持最新的软件是你可以在任何操作系统上采取的最大的安全预防措施。软件更新的范围从关键漏洞补丁到小 bug 的修复，许多软件漏洞实际上是在它们被公开的时候得到修补的。

### 自动安全更新

有一些用于服务器上自动更新的参数。[Fedora 的 Wiki](https://fedoraproject.org/wiki/AutoUpdates#Why_use_Automatic_updates.3F) 上有一篇很棒的剖析自动更新的利弊的文章，但是如果你把它限制到安全更新上，自动更新的风险将是最小的。

自动更新的可行性必须你自己判断，因为它归结为**你**在你的服务器上做什么。请记住，自动更新仅适用于来自仓库的包，而不是自行编译的程序。你可能会发现一个复制了生产服务器的测试环境是很有必要的。可以在部署到生产环境之前，在测试环境里面更新来检查问题。

* CentOS 使用 [yum-cron](https://fedoraproject.org/wiki/AutoUpdates#Fedora_21_or_earlier_versions) 进行自动更新。
* Debian 和 Ubuntu 使用 [无人值守升级](https://help.ubuntu.com/lts/serverguide/automatic-updates.html)。
* Fedora 使用 [dnf-automatic](https://dnf.readthedocs.org/en/latest/automatic.html)。

### 添加一个受限用户账户

到目前为止，你已经作为 `root` 用户访问了你的服务器，它有无限制的权限，可以执行**任何**命令 - 甚至可能意外中断你的服务器。 我们建议创建一个受限用户帐户，并始终使用它。 管理任务应该使用 `sudo` 来完成，它可以临时提升受限用户的权限，以便管理你的服务器。

>
> 不是所有的 Linux 发行版都在系统上默认包含 `sudo`，但大多数都在其软件包仓库中有 `sudo`。 如果得到这样的输出 `sudo：command not found`，请在继续之前安装 `sudo`。
>
>
>

要添加新用户，首先通过 SSH 登录到你的服务器。

#### CentOS / Fedora

1、 创建用户，用你想要的名字替换 `example_user`，并分配一个密码：

```
useradd example_user && passwd example_user

```

2、 将用户添加到具有 sudo 权限的 `wheel` 组：

```
usermod -aG wheel example_user

```

#### Ubuntu

1、 创建用户，用你想要的名字替换 `example_user`。你将被要求输入用户密码：

```
adduser example_user

```

2、 添加用户到 `sudo` 组，这样你就有管理员权限了：

```
adduser example_user sudo

```

#### Debian

1、 Debian 默认的包中没有 `sudo`， 使用 `apt-get` 来安装：

```
apt-get install sudo

```

2、 创建用户，用你想要的名字替换 `example_user`。你将被要求输入用户密码：

```
adduser example_user

```

3、 添加用户到 `sudo` 组，这样你就有管理员权限了：

```
adduser example_user sudo

```

创建完有限权限的用户后，断开你的服务器连接：

```
exit

```

重新用你的新用户登录。用你的用户名代替 `example_user`，用你的服务器 IP 地址代替例子中的 IP 地址：

```
ssh example_user@203.0.113.10

```

现在你可以用你的新用户帐户管理你的服务器，而不是 `root`。 几乎所有超级用户命令都可以用 `sudo`（例如：`sudo iptables -L -nv`）来执行，这些命令将被记录到 `/var/log/auth.log` 中。

### 加固 SSH 访问

默认情况下，密码认证用于通过 SSH 连接到您的服务器。加密密钥对更加安全，因为它用私钥代替了密码，这通常更难以暴力破解。在本节中，我们将创建一个密钥对，并将服务器配置为不接受 SSH 密码登录。

#### 创建验证密钥对

1、这是在你本机上完成的，**不是**在你的服务器上，这里将创建一个 4096 位的 RSA 密钥对。在创建过程中，您可以选择使用密码加密私钥。这意味着它不能在没有输入密码的情况下使用，除非将密码保存到本机桌面的密钥管理器中。我们建议您使用带有密码的密钥对，但如果你不想使用密码，则可以将此字段留空。

**Linux / OS X**

>
> 如果你已经创建了 RSA 密钥对，则这个命令将会覆盖它，这可能会导致你不能访问其它的操作系统。如果你已创建过密钥对，请跳过此步骤。要检查现有的密钥，请运行 `ls〜/ .ssh / id_rsa *`。
>
>
>

```
ssh-keygen -b 4096

```

在输入密码之前，按下 **回车**使用 `/home/your_username/.ssh` 中的默认名称 `id_rsa` 和 `id_rsa.pub`。

**Windows**

这可以使用 PuTTY 完成，在我们指南中已有描述：[使用 SSH 公钥验证](https://www.linode.com/docs/security/use-public-key-authentication-with-ssh#windows-operating-system)。

2、将公钥上传到您的服务器上。 将 `example_user` 替换为你用来管理服务器的用户名称，将 `203.0.113.10` 替换为你的服务器的 IP 地址。

**Linux**

在本机上：

```
ssh-copy-id example_user@203.0.113.10

```

**OS X**

在你的服务器上（用你的权限受限用户登录）：

```
mkdir -p ~/.ssh && sudo chmod -R 700 ~/.ssh/

```

在本机上：

```
scp ~/.ssh/id_rsa.pub example_user@203.0.113.10:~/.ssh/authorized_keys

```

>
> 如果相对于 `scp` 你更喜欢 `ssh-copy-id` 的话，那么它也可以在 [Homebrew](http://brew.sh/) 中找到。使用 `brew install ssh-copy-id` 安装。
>
>
>

**Windows**

* **选择 1**：使用 [WinSCP](http://winscp.net/) 来完成。 在登录窗口中，输入你的服务器的 IP 地址作为主机名，以及非 root 的用户名和密码。单击“登录”连接。

一旦 WinSCP 连接后，你会看到两个主要部分。 左边显示本机上的文件，右边显示服务区上的文件。 使用左侧的文件浏览器，导航到你已保存公钥的文件，选择公钥文件，然后点击上面工具栏中的“上传”。

系统会提示你输入要将文件放在服务器上的路径。 将文件上传到 `/home/example_user/.ssh /authorized_keys`，用你的用户名替换 `example_user`。
* **选择 2**：将公钥直接从 PuTTY 键生成器复制到连接到你的服务器中（作为非 root 用户）：

```
mkdir ~/.ssh; nano ~/.ssh/authorized_keys

```

上面命令将在文本编辑器中打开一个名为 `authorized_keys` 的空文件。 将公钥复制到文本文件中，确保复制为一行，与 PuTTY 所生成的完全一样。 按下 `CTRL + X`，然后按下 `Y`，然后回车保存文件。

最后，你需要为公钥目录和密钥文件本身设置权限：

```
sudo chmod 700 -R ~/.ssh && chmod 600 ~/.ssh/authorized_keys

```

这些命令通过阻止其他用户访问公钥目录以及文件本身来提供额外的安全性。有关它如何工作的更多信息，请参阅我们的指南[如何修改文件权限](https://www.linode.com/docs/tools-reference/modify-file-permissions-with-chmod)。

3、 现在退出并重新登录你的服务器。如果你为私钥指定了密码，则需要输入密码。

#### SSH 守护进程选项

1、 **不允许 root 用户通过 SSH 登录。** 这要求所有的 SSH 连接都是通过非 root 用户进行。当以受限用户帐户连接后，可以通过使用 `sudo` 或使用 `su -` 切换为 root shell 来使用管理员权限。

```
# Authentication:
...
PermitRootLogin no

```

2、 **禁用 SSH 密码认证。** 这要求所有通过 SSH 连接的用户使用密钥认证。根据 Linux 发行版的不同，它可能需要添加 `PasswordAuthentication` 这行，或者删除前面的 `#` 来取消注释。

```
# Change to no to disable tunnelled clear text passwords
PasswordAuthentication no

```

>
> 如果你从许多不同的计算机连接到服务器，你可能想要继续启用密码验证。这将允许你使用密码进行身份验证，而不是为每个设备生成和上传密钥对。
>
>
>

3、 **只监听一个互联网协议。** 在默认情况下，SSH 守护进程同时监听 IPv4 和 IPv6 上的传入连接。除非你需要使用这两种协议进入你的服务器，否则就禁用你不需要的。 *这不会禁用系统范围的协议，它只用于 SSH 守护进程。*

使用选项：

* `AddressFamily inet` 只监听 IPv4。
* `AddressFamily inet6` 只监听 IPv6。

默认情况下，`AddressFamily` 选项通常不在 `sshd_config` 文件中。将它添加到文件的末尾：

```
echo 'AddressFamily inet' | sudo tee -a /etc/ssh/sshd_config

```

4、 重新启动 SSH 服务以加载新配置。

如果你使用的 Linux 发行版使用 systemd（CentOS 7、Debian 8、Fedora、Ubuntu 15.10+）

```
sudo systemctl restart sshd

```

如果您的 init 系统是 SystemV 或 Upstart（CentOS 6、Debian 7、Ubuntu 14.04）：

```
sudo service ssh restart

```

#### 使用 Fail2Ban 保护 SSH 登录

[Fail2Ban](http://www.fail2ban.org/wiki/index.php/Main_Page) 是一个应用程序，它会在太多的失败登录尝试后禁止 IP 地址登录到你的服务器。由于合法登录通常不会超过三次尝试（如果使用 SSH 密钥，那不会超过一个），因此如果服务器充满了登录失败的请求那就表示有恶意访问。

Fail2Ban 可以监视各种协议，包括 SSH、HTTP 和 SMTP。默认情况下，Fail2Ban 仅监视 SSH，并且因为 SSH 守护程序通常配置为持续运行并监听来自任何远程 IP 地址的连接，所以对于任何服务器都是一种安全威慑。

有关安装和配置 Fail2Ban 的完整说明，请参阅我们的指南：[使用 Fail2ban 保护服务器](https://www.linode.com/docs/security/using-fail2ban-for-security)。

### 删除未使用的面向网络的服务

大多数 Linux 发行版都安装并运行了网络服务，监听来自互联网、回环接口或两者兼有的传入连接。 将不需要的面向网络的服务从系统中删除，以减少对运行进程和对已安装软件包攻击的概率。

#### 查明运行的服务

要查看服务器中运行的服务：

```
sudo netstat -tulpn

```

>
> 如果默认情况下 `netstat` 没有包含在你的 Linux 发行版中，请安装软件包 `net-tools` 或使用 `ss -tulpn` 命令。
>
>
>

以下是 `netstat` 的输出示例。 请注意，因为默认情况下不同发行版会运行不同的服务，你的输出将有所不同：

```
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:111             0.0.0.0:*               LISTEN      7315/rpcbind
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      3277/sshd
tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      3179/exim4
tcp        0      0 0.0.0.0:42526           0.0.0.0:*               LISTEN      2845/rpc.statd
tcp6       0      0 :::48745                :::*                    LISTEN      2845/rpc.statd
tcp6       0      0 :::111                  :::*                    LISTEN      7315/rpcbind
tcp6       0      0 :::22                   :::*                    LISTEN      3277/sshd
tcp6       0      0 ::1:25                  :::*                    LISTEN      3179/exim4
udp        0      0 127.0.0.1:901           0.0.0.0:*                           2845/rpc.statd
udp        0      0 0.0.0.0:47663           0.0.0.0:*                           2845/rpc.statd
udp        0      0 0.0.0.0:111             0.0.0.0:*                           7315/rpcbind
udp        0      0 192.0.2.1:123           0.0.0.0:*                           3327/ntpd
udp        0      0 127.0.0.1:123           0.0.0.0:*                           3327/ntpd
udp        0      0 0.0.0.0:123             0.0.0.0:*                           3327/ntpd
udp        0      0 0.0.0.0:705             0.0.0.0:*                           7315/rpcbind
udp6       0      0 :::111                  :::*                                7315/rpcbind
udp6       0      0 fe80::f03c:91ff:fec:123 :::*                                3327/ntpd
udp6       0      0 2001:DB8::123           :::*                                3327/ntpd
udp6       0      0 ::1:123                 :::*                                3327/ntpd
udp6       0      0 :::123                  :::*                                3327/ntpd
udp6       0      0 :::705                  :::*                                7315/rpcbind
udp6       0      0 :::60671                :::*                                2845/rpc.statd

```

`netstat` 告诉我们服务正在运行 [RPC](https://en.wikipedia.org/wiki/Open_Network_Computing_Remote_Procedure_Call)（`rpc.statd` 和 `rpcbind`）、SSH（`sshd`）、[NTPdate](http://support.ntp.org/bin/view/Main/SoftwareDownloads)（`ntpd`）和[Exim](http://www.exim.org/)（`exim4`）。

**TCP**

请参阅 `netstat` 输出的 `Local Address` 那一列。进程 `rpcbind` 正在侦听 `0.0.0.0:111` 和 `:::111`，外部地址是 `0.0.0.0:*` 或者 `:::*` 。这意味着它从任何端口和任何网络接口接受来自任何外部地址（IPv4 和 IPv6）上的其它 RPC 客户端的传入 TCP 连接。 我们看到类似的 SSH，Exim 正在侦听来自回环接口的流量，如所示的 `127.0.0.1` 地址。

**UDP**

UDP 套接字是[无状态](https://en.wikipedia.org/wiki/Stateless_protocol)的，这意味着它们只有打开或关闭，并且每个进程的连接是独立于前后发生的连接。这与 TCP 的连接状态（例如 `LISTEN`、`ESTABLISHED`和 `CLOSE_WAIT`）形成对比。

我们的 `netstat`输出说明 NTPdate ：1）接受服务器的公网 IP 地址的传入连接；2）通过本地主机进行通信；3）接受来自外部的连接。这些连接是通过端口 123 进行的，同时支持 IPv4 和 IPv6。我们还看到了 RPC 打开的更多的套接字。

#### 查明该移除哪个服务

如果你在没有启用防火墙的情况下对服务器进行基本的 TCP 和 UDP 的 [nmap](https://nmap.org/) 扫描，那么在打开端口的结果中将出现 SSH、RPC 和 NTPdate 。通过配置防火墙，你可以过滤掉这些端口，但 SSH 除外，因为它必须允许你的传入连接。但是，理想情况下，应该禁用未使用的服务。

* 你可能主要通过 SSH 连接管理你的服务器，所以让这个服务需要保留。如上所述，RSA 密钥和 Fail2Ban 可以帮助你保护 SSH。
* NTP 是服务器计时所必需的，但有个替代 NTPdate 的方法。如果你喜欢不开放网络端口的时间同步方法，并且你不需要纳秒精度，那么你可能有兴趣用 [OpenNTPD](https://en.wikipedia.org/wiki/OpenNTPD) 来代替 NTPdate。
* 然而，Exim 和 RPC 是不必要的，除非你有特定的用途，否则应该删除它们。

>
> 本节针对 Debian 8。默认情况下，不同的 Linux 发行版具有不同的服务。如果你不确定某项服务的功能，请尝试搜索互联网以了解该功能是什么，然后再尝试删除或禁用它。
>
>
>

#### 卸载监听的服务

如何移除包取决于发行版的包管理器：

**Arch**

```
sudo pacman -Rs package_name

```

**CentOS**

```
sudo yum remove package_name

```

**Debian / Ubuntu**

```
sudo apt-get purge package_name

```

**Fedora**

```
sudo dnf remove package_name

```

再次运行 `sudo netstat -tulpn`，你看到监听的服务就只会有 SSH（`sshd`）和 NTP（`ntpdate`，网络时间协议）。

### 配置防火墙

使用防火墙阻止不需要的入站流量能为你的服务器提供一个高效的安全层。 通过指定入站流量，你可以阻止入侵和网络测绘。 最佳做法是只允许你需要的流量，并拒绝一切其他流量。请参阅我们的一些关于最常见的防火墙程序的文档：

* [iptables](https://www.linode.com/docs/security/firewalls/control-network-traffic-with-iptables) 是 netfilter 的控制器，它是 Linux 内核的包过滤框架。 默认情况下，iptables 包含在大多数 Linux 发行版中。
* [firewallD](/article-8098-1.html) 是可用于 CentOS/Fedora 系列发行版的 iptables 控制器。
* [UFW](/article-8087-1.html) 为 Debian 和 Ubuntu 提供了一个 iptables 前端。

### 接下来

这些是加固 Linux 服务器的最基本步骤，但是进一步的安全层将取决于其预期用途。 其他技术可以包括应用程序配置，使用[入侵检测](https://linode.com/docs/security/ossec-ids-debian-7)或者安装某个形式的[访问控制](https://en.wikipedia.org/wiki/Access_control#Access_Control)。

现在你可以按你的需求开始设置你的服务器了。

---

via: <https://www.linode.com/docs/security/securing-your-server/>

作者：[Phil Zona](https://www.linode.com/docs/security/securing-your-server/) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

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


如何在 Ubuntu 环境下搭建邮件服务器（二）

很有用！长见识了！

![Dovecot email](/data/attachment/album/201612/30/163706dtz1d4e4jg4g2i8j.jpg "Dovecot email")

本教程的第 2 部分将介绍如何使用 Dovecot 将邮件从 Postfix 服务器移动到用户的收件箱。

在[第一部分](/article-8071-1.html)中，我们安装并测试了 Postfix SMTP 服务器。Postfix 或任何 SMTP 服务器都不是一个完整的邮件服务器，因为它所做的只是在 SMTP 服务器之间移动邮件。我们需要 Dovecot 将邮件从 Postfix 服务器移动到用户的收件箱中。

Dovecot 支持两种标准邮件协议：IMAP（Internet 邮件访问协议）和 POP3（邮局协议）。 IMAP 服务器会在服务器上保留所有邮件。您的用户可以选择将邮件下载到计算机或仅在服务器上访问它们。 IMAP 对于有多台机器的用户是方便的。但对你而言需要更多的工作，因为你必须确保你的服务器始终可用，而且 IMAP 服务器需要大量的存储和内存。

POP3 是较旧的协议。POP3 服务器可以比 IMAP 服务器服务更多的用户，因为邮件会下载到用户的计算机。大多数邮件客户端可以选择在服务器上保留一定天数的邮件，因此 POP3 的行为有点像 IMAP。但它又不是 IMAP，当你像 IMAP 那样（在多台计算机上使用它时）那么常常会下载多次或意外删除。

### 安装 Dovecot

启动你的 Ubuntu 系统并安装 Dovecot：

```
$ sudo apt-get install dovecot-imapd dovecot-pop3d

```

它会安装可用的配置，并在完成后自动启动，你可以用 `ps ax | grep dovecot` 确认：

```
$ ps ax | grep dovecot
15988 ?  Ss 0:00 /usr/sbin/dovecot
15990 ?  S  0:00 dovecot/anvil
15991 ?  S  0:00 dovecot/log

```

打开你的 Postfix 配置文件 `/etc/postfix/main.cf`，确保配置了maildir 而不是 mbox 的邮件存储方式，mbox 是给每个用户一个单一大文件，而 maildir 是每条消息都存储为一个文件。大量的小文件比一个庞大的文件更稳定且易于管理。添加如下两行，第二行告诉 Postfix 你需要 maildir 格式，并且在每个用户的家目录下创建一个 `.Mail` 目录。你可以取任何名字，不一定要是 `.Mail`：

```
mail_spool_directory = /var/mail
home_mailbox = .Mail/

```

现在调整你的 Dovecot 配置。首先把原始的 `dovecot.conf` 文件重命名放到一边，因为它会调用存放在 `conf.d` 中的文件，在你刚刚开始学习时把配置放一起更简单些：

```
$ sudo mv /etc/dovecot/dovecot.conf /etc/dovecot/dovecot-oldconf

```

现在创建一个新的 `/etc/dovecot/dovecot.conf`：

```
disable_plaintext_auth = no
mail_location = maildir:~/.Mail
namespace inbox {
  inbox = yes
  mailbox Drafts {
    special_use = \Drafts
  }
  mailbox Sent {
    special_use = \Sent
  }
  mailbox Trash {
    special_use = \Trash
  }
}
passdb {
  driver = pam
}
protocols = " imap pop3"
ssl = no
userdb {
  driver = passwd
}

```

注意 `mail_location = maildir` 必须和 `main.cf` 中的 `home_mailbox` 参数匹配。保存你的更改并重新加载 Postfix 和 Dovecot 配置：

```
$ sudo postfix reload
$ sudo dovecot reload

```

### 快速导出配置

使用下面的命令来快速查看你的 Postfix 和 Dovecot 配置：

```
$ postconf -n
$ doveconf -n

```

### 测试 Dovecot

现在再次启动 telnet，并且给自己发送一条测试消息。粗体显示的是你输入的命令。`studio` 是我服务器的主机名，因此你必须用自己的：

```
$ telnet studio 25
Trying 127.0.1.1...
Connected to studio.
Escape character is '^]'.
220 studio.router ESMTP Postfix (Ubuntu)
EHLO studio
250-studio.router
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-STARTTLS
250-ENHANCEDSTATUSCODES
250-8BITMIME
250-DSN
250 SMTPUTF8
mail from: tester@test.net
250 2.1.0 Ok
rcpt to: carla@studio
250 2.1.5 Ok
data
354 End data with .Date: November 25, 2016
From: tester
Message-ID: first-test
Subject: mail server test
Hi carla,
Are you reading this? Let me know if you didn't get this.
.
250 2.0.0 Ok: queued as 0C261A1F0F
quit
221 2.0.0 Bye
Connection closed by foreign host.

```

现在请求 Dovecot 来取回你的新消息，使用你的 Linux 用户名和密码登录：

```
$ telnet studio 110
Trying 127.0.0.1...
Connected to studio.
Escape character is '^]'.
+OK Dovecot ready.
user carla
+OK
pass password
+OK Logged in.
stat
+OK 2 809
list
+OK 2 messages:
1 383
2 426
.
retr 2
+OK 426 octets
Return-Path: <tester@test.net>
X-Original-To: carla@studio
Delivered-To: carla@studio
Received: from studio (localhost [127.0.0.1])
        by studio.router (Postfix) with ESMTP id 0C261A1F0F
        for <carla@studio>; Wed, 30 Nov 2016 17:18:57 -0800 (PST)
Date: November 25, 2016
From: tester@studio.router
Message-ID: first-test
Subject: mail server test

Hi carla,
Are you reading this? Let me know if you didn't get this.
.
quit
+OK Logging out.
Connection closed by foreign host.

```

花一点时间比较第一个例子中输入的消息和第二个例子中接收的消息。 返回地址和日期是很容易伪造的，但 Postfix 不会被愚弄。大多数邮件客户端默认显示一个最小的标头集，但是你需要读取完整的标头才能查看真实的回溯。

你也可以在你的 `~/Mail/cur` 目录中查看你的邮件，它们是普通文本，我已经有两封测试邮件：

```
$ ls .Mail/cur/
1480540325.V806I28e0229M351743.studio:2,S
1480555224.V806I28e000eM41463.studio:2,S

```

### 测试 IMAP

我们 Dovecot 同时启用了 POP3 和 IMAP 服务，因此让我们使用 telnet 测试 IMAP。

```
$ telnet studio imap2
Trying 127.0.1.1...
Connected to studio.
Escape character is '^]'.
* OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS
ID ENABLE IDLE AUTH=PLAIN] Dovecot ready.
A1 LOGIN carla password
A1 OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS
ID ENABLE IDLE SORT SORT=DISPLAY THREAD=REFERENCES THREAD=REFS
THREAD=ORDEREDSUBJECT MULTIAPPEND URL-PARTIAL CATENATE UNSELECT
CHILDREN NAMESPACE UIDPLUS LIST-EXTENDED I18NLEVEL=1 CONDSTORE
QRESYNC ESEARCH ESORT SEARCHRES WITHIN CONTEXT=SEARCH LIST-STATUS
BINARY MOVE SPECIAL-USE] Logged in
A2 LIST "" "*"
* LIST (\HasNoChildren) "." INBOX
A2 OK List completed (0.000 + 0.000 secs).
A3 EXAMINE INBOX
* FLAGS (\Answered \Flagged \Deleted \Seen \Draft)
* OK [PERMANENTFLAGS ()] Read-only mailbox.
* 2 EXISTS
* 0 RECENT
* OK [UIDVALIDITY 1480539462] UIDs valid
* OK [UIDNEXT 3] Predicted next UID
* OK [HIGHESTMODSEQ 1] Highest
A3 OK [READ-ONLY] Examine completed (0.000 + 0.000 secs).
A4 logout
* BYE Logging out
A4 OK Logout completed.
Connection closed by foreign host

```

### Thunderbird 邮件客户端

图 1 中的屏幕截图显示了我局域网上另一台主机上的图形邮件客户端中的邮件。

![thunderbird mail](/data/attachment/album/201612/30/163707tijjuxip7da74bxm.png "thunderbird mail")

*图 1： Thunderbird mail*

此时，你已有一个可以工作的 IMAP 和 POP3 邮件服务器，并且你也知道该如何测试你的服务器。你的用户可以在他们设置邮件客户端时选择要使用的协议。如果您只想支持一个邮件协议，那么只需要在您的 Dovecot 配置中留下你要的协议名字。

然而，这还远远没有完成。这是一个非常简单、没有加密的、大门敞开的安装。它也只适用于与邮件服务器在同一系统上的用户。这是不可扩展的，并具有一些安全风险，例如没有密码保护。 我们会在[下篇](https://www.linux.com/learn/sysadmin/building-email-server-ubuntu-linux-part-3)了解如何创建与系统用户分开的邮件用户，以及如何添加加密。

---

via: <https://www.linux.com/learn/sysadmin/building-email-server-ubuntu-linux-part-2>

作者：[CARLA SCHRODER](https://www.linux.com/users/cschroder) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

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


忘记技术债务 —— 教你如何创造技术财富

Summary: 需要转变思维模式，不是偿还债务，而是创造科技财富，不是要铲除旧代码，而是要逐步修复代码。

电视里正播放着《老屋》节目，[Andrea Goulet](https://www.linkedin.com/in/andreamgoulet) 和她的商业合作伙伴正悠闲地坐在客厅里，商讨着他们的战略计划。那正是大家思想的火花碰撞出创新事物的时刻。他们正在寻求一种能够实现自身价值的方式 —— 为其它公司清理<ruby> 遗留代码 <rt>  legacy code </rt></ruby>及科技债务。他们此刻的情景，像极了电视里的场景。（LCTT 译注：《老屋》电视节目提供专业的家装、家庭改建、重新装饰、创意等等信息，与软件的改造有异曲同工之处）。

“我们意识到我们现在做的工作不仅仅是清理遗留代码，实际上我们是在用重建老屋的方式来重构软件，让系统运行更持久、更稳定、更高效，”Goulet 说。“这让我开始思考公司如何花钱来改善他们的代码，以便让他们的系统运行更高效。就好比为了让屋子变得更有价值，你不得不使用一个全新的屋顶。这并不吸引人，但却是至关重要的，然而很多人都搞错了。“

如今，她是 [Corgibytes](http://corgibytes.com/) 公司的 CEO —— 这是一家提高软件现代化和进行系统重构方面的咨询公司。她曾经见过各种各样糟糕的系统、遗留代码，以及严重的科技债务事件。Goulet 认为**创业公司需要转变思维模式，不是偿还债务，而是创造科技财富，不是要铲除旧代码，而是要逐步修复代码**。她解释了这种新的方法，以及如何完成这些看似不可能完成的事情 —— 实际上是聘用优秀的工程师来完成这些工作。

![](/data/attachment/album/201612/31/000424cic15s5hjhh8vzlv.jpg)

### 反思遗留代码

关于遗留代码最常见的定义是由 Michael Feathers 在他的著作[<ruby> 《高效利用遗留代码》 <rt>  Working Effectively with Legacy Code </rt></ruby>](https://www.amazon.com/Working-Effectively-Legacy-Michael-Feathers/dp/0131177052)一书中提出：遗留代码就是没有被测试所覆盖的代码。这个定义比大多数人所认为的 —— 遗留代码仅指那些古老、陈旧的系统这个说法要妥当得多。但是 Goulet 认为这两种定义都不够明确。“遗留代码与软件的年头儿毫无关系。一个两年的应用程序，其代码可能已经进入遗留状态了，”她说。“**关键要看软件质量提高的难易程度。**”

这意味着写得不够清楚、缺少解释说明的代码，是没有包含任何关于代码构思和决策制定的流程的成果。单元测试就是这样的一种成果，但它并没有包括了写那部分代码的原因以及逻辑推理相关的所有文档。如果想要提升代码，但没办法搞清楚原开发者的意图 —— 那些代码就属于遗留代码了。

>
> **遗留代码不是技术问题，而是沟通上的问题。**
>
>
>

![](/data/attachment/album/201612/30/235819w0yroszn04s243q8.png)

如果你像 Goulet 所说的那样迷失在遗留代码里，你会发现每一次的沟通交流过程都会变得像那条[<ruby> 康威定律 <rt>  Conway’s Law </rt></ruby>](https://en.wikipedia.org/wiki/Conway%27s_law)所描述的一样。

Goulet 说：“这个定律认为你的代码能反映出整个公司的组织沟通结构，如果想修复公司的遗留代码，而没有一个好的组织沟通方式是不可能完成的。那是很多人都没注意到的一个重要环节。”

Goulet 和她的团队成员更像是考古学家一样来研究遗留系统项目。他们根据前开发者写的代码构件相关的线索来推断出他们的思想意图。然后再根据这些构件之间的关系来做出新的决策。

代码构件最重要的什么呢？**良好的代码结构、清晰的思想意图、整洁的代码**。例如，如果使用通用的名称如 “foo” 或 “bar” 来命名一个变量，半年后再返回来看这段代码时，根本就看不出这个变量的用途是什么。

如果代码读起来很困难，可以使用源代码控制系统，这是一个非常有用的工具，因为它可以提供代码的历史修改信息，并允许软件开发者写明他们作出本次修改的原因。

Goulet 说：“我一个朋友认为提交代码时附带的信息，每一个概要部分的内容应该有半条推文那么长（几十个字），如需要的话，代码的描述信息应该有一篇博客那么长。你得用这个方式来为你修改的代码写一个合理的说明。这不会浪费太多额外的时间，并且能给后期的项目开发者提供非常多的有用信息，但是让人惊讶的是很少有人会这么做。我们经常能看到一些开发人员在被一段代码激怒之后，要用 `git blame` 扒代码库找出这些垃圾是谁干的，结果最后发现是他们自己干的。”

使用自动化测试对于理解程序的流程非常有用。Goulet 解释道：“很多人都比较认可 Michael Feathers 提出的关于遗留代码的定义。测试套件对于理解开发者的意图来说是非常有用的工具，尤其当用来与[<ruby> 行为驱动开发模式 <rt>  Behavior Driven Development </rt></ruby>](https://en.wikipedia.org/wiki/Behavior-driven_development)相结合时，比如编写测试场景。”

理由很简单，如果你想将遗留代码限制在一定程度下，注意到这些细节将使代码更易于理解，便于在以后也能工作。编写并运行一个代码单元，接受、认可，并且集成测试。写清楚注释的内容，方便以后你自己或是别人来理解你写的代码。

尽管如此，由于很多已知的和不可意料的原因，遗留代码仍然会出现。

在创业公司刚成立初期，公司经常会急于推出很多新的功能。开发人员在巨大的交付压力下，测试常常半途而废。Corgibytes 团队就遇到过好多公司很多年都懒得对系统做详细的测试了。

确实如此，当你急于开发出系统原型的时候，强制性地去做太多的测试也许意义不大。但是，一旦产品开发完成并投入使用后，你就需要投入时间精力来维护及完善系统了。Goulet 说：“很多人说，‘别在维护上费心思，重要的是功能！’ **如果真这样，当系统规模到一定程序的时候，就很难再扩展了。同时也就失去市场竞争力了。**”

最后才明白过来，原来热力学第二定律对代码也同样适用：**你所面临的一切将向熵增的方向发展。**你需要与混乱无序的技术债务进行一场无休无止的战斗。随着时间的推移，遗留代码也逐渐变成一种债务。

她说：“我们再次拿家来做比喻。你必须坚持每天收拾餐具、打扫卫生、倒垃圾。如果你不这么做，情况将来越来越糟糕，直到有一天你不得不向 HazMat 团队求助。”（LCTT 译注：HazMat 团队，危害物质专队)

就跟这种情况一样，Corgibytes 团队接到很多公司 CEO 的求助电话，比如 Features 公司的 CEO 在电话里抱怨道：“现在我们公司的开发团队工作效率太低了，三年前只需要两个星期就完成的工作，现在却要花费12个星期。”

>
> **技术债务往往反映出公司运作上的问题。**
>
>
>

很多公司的 CTO 明知会发生技术债务的问题，但是他们很难说服其它同事相信花钱来修复那些已经存在的问题是值得的。这看起来像是在走回头路，很乏味，也不是新的产品。有些公司直到系统已经严重影响了日常工作效率时，才着手去处理这些技术债务方面的问题，那时付出的代价就太高了。

### 忘记债务，创造技术财富

如果你想把[<ruby> 重构技术债务 <rt>  reframe your technical debt </rt></ruby>](https://www.agilealliance.org/resources/initiatives/technical-debt/) — [敏捷开发讲师 Declan Whelan 最近造出的一个术语](http://legacycoderocks.libsyn.com/technical-wealth-with-declan-wheelan) — 作为一个积累技术财富的机会，你很可能要先说服你们公司的 CEO、投资者和其它的股东接受并为之共同努力。

“我们没必要把技术债务想像得很可怕。当产品处于开发设计初期，技术债务反而变得非常有用，”Goulet 说。“当你解决一些系统遗留的技术问题时，你会充满成就感。例如，当你在自己家里安装新窗户时，你确实会花费一笔不少的钱，但是之后你每个月就可以节省 100 美元的电费。程序代码亦是如此。虽然暂时没有提高工作效率，但随时时间推移将提高生产力。”

一旦你意识到项目团队工作不再富有成效时，就需要确认下是哪些技术债务在拖后腿了。

“我跟很多不惜一切代价招募英才的初创公司交流过，他们高薪聘请一些工程师来只为了完成更多的工作。”她说。“与此相反，他们应该找出如何让原有的每个工程师能更高效率工作的方法。你需要去解决什么样的技术债务以增加额外的生产率？”

如果你改变自己的观点并且专注于创造技术财富，你将会看到产能过剩的现象，然后重新把多余的产能投入到修复更多的技术债务和遗留代码的良性循环中。你们的产品将会走得更远，发展得更好。

>
> **别把你们公司的软件当作一个项目来看。从现在起，把它想象成一栋自己要长久居住的房子。**
>
>
>

“这是一个极其重要的思想观念的转变，”Goulet 说。“这将带你走出短浅的思维模式，并让你比之前更加关注产品的维护工作。”

这就像对一栋房子，要实现其现代化及维护的方式有两种：小动作，表面上的更改（“我买了一块新的小地毯！”）和大改造，需要很多年才能偿还所有债务（“我想我们应替换掉所有的管道...”)。你必须考虑好两者，才能让你们已有的产品和整个团队顺利地运作起来。

这还需要提前预算好 —— 否则那些较大的花销将会是硬伤。定期维护是最基本的预期费用。让人震惊的是，很多公司都没把维护当成商务成本预算进来。

这就是 Goulet 提出“**<ruby> 软件重构 <rt>  software remodeling </rt></ruby>**”这个术语的原因。当你房子里的一些东西损坏的时候，你并不是铲除整个房子，从头开始重建。同样的，当你们公司出现老的、损坏的代码时，重写代码通常不是最明智的选择。

下面是 Corgibytes 公司在重构客户代码用到的一些方法：

* 把大型的应用系统分解成轻量级的更易于维护的微服务。
* 让功能模块彼此解耦以便于扩展。
* 更新形象和提升用户前端界面体验。
* 集合自动化测试来检查代码可用性。
* 代码库可以让重构或者修改更易于操作。

系统重构也进入到 DevOps 领域。比如，Corgibytes 公司经常推荐新客户使用 [Docker](https://www.docker.com/)，以便简单快速的部署新的开发环境。当你们团队有 30 个工程师的时候，把初始化配置时间从 10 小时减少到 10 分钟对完成更多的工作很有帮助。系统重构不仅仅是应用于软件开发本身，也包括如何进行系统重构。

如果你知道做些什么能让你们的代码管理起来更容易更高效，就应该把这它们写入到每年或季度的项目规划中。别指望它们会自动呈现出来。但是也别给自己太大的压力来马上实施它们。Goulets 看到很多公司从一开始就致力于 100% 测试覆盖率而陷入困境。

**具体来说，每个公司都应该把以下三种类型的重构工作规划到项目建设中来：**

* 自动测试
* 持续交付
* 文化提升

咱们来深入的了解下每一项内容。

#### 自动测试

“有一位客户即将进行第二轮融资，但是他们没办法在短期内招聘到足够的人才。我们帮助他们引进了一种自动化测试框架，这让他们的团队在 3 个月的时间内工作效率翻了一倍，”Goulets 说。“这样他们就可以在他们的投资人面前自豪的说，‘我们一个精英团队完成的任务比两个普通的团队要多。’”

自动化测试从根本上来讲就是单个测试的组合，就是可以再次检查某一行代码的单元测试。可以使用集成测试来确保系统的不同部分都正常运行。还可以使用验收性测试来检验系统的功能特性是否跟你想像的一样。当你把这些测试写成测试脚本后，你只需要简单地用鼠标点一下按钮就可以让系统自行检验了，而不用手工的去梳理并检查每一项功能。

在产品市场尚未打开之前就来制定自动化测试机制有些言之过早。但是一旦你有一款感到满意，并且客户也很依赖的产品，就应该把这件事付诸实施了。

#### 持续交付

这是与自动化交付相关的工作，过去是需要人工完成。目的是当系统部分修改完成时可以迅速进行部署，并且短期内得到反馈。这使公司在其它竞争对手面前有很大的优势，尤其是在客户服务行业。

“比如说你每次部署系统时环境都很复杂。熵值无法有效控制，”Goulets 说。“我们曾经见过花 12 个小时甚至更多的时间来部署一个很大的集群环境。在这种情况下，你不会愿意频繁部署了。因为太折腾人了，你还会推迟系统功能上线的时间。这样，你将落后于其它公司并失去竞争力。”

**在持续性改进的过程中常见的其它自动化任务包括：**

* 在提交完成之后检查构建中断部分。
* 在出现故障时进行回滚操作。
* 自动化审查代码的质量。
* 根据需求增加或减少服务器硬件资源。
* 让开发、测试及生产环境配置简单易懂。

举一个简单的例子，比如说一个客户提交了一个系统 Bug 报告。开发团队越高效解决并修复那个 Bug 越好。对于开发人员来说，修复 Bug 的挑战根本不是个事儿，这本来也是他们的强项，主要是系统设置上不够完善导致他们浪费太多的时间去处理 bug 以外的其它问题。

使用持续改进的方式时，你要严肃地决定决定哪些工作应该让机器去做，哪些交给研发去完成更好。如果机器更擅长，那就使其自动化完成。这样也能让研发愉快地去解决其它有挑战性的问题。同时客户也会很高兴地看到他们报怨的问题被快速处理了。你的待修复的未完成任务数减少了，之后你就可以把更多的时间投入到运用新的方法来提高产品的质量上了。**这是创造科技财富的一种转变。**因为开发人员可以修复 bug 后立即发布新代码，这样他们就有时间和精力做更多事。

“你必须时刻问自己，‘我应该如何为我们的客户改善产品功能？如何做得更好？如何让产品运行更高效？’不过还要不止于此。”Goulets 说。“一旦你回答完这些问题后，你就得询问下自己，如何自动去完成那些需要改善的功能。”

#### 文化提升

Corgibytes 公司每天都会看到同样的问题：一家创业公司建立了一个对开发团队毫无推动的文化环境。公司 CEO 抱着双臂思考着为什么这样的环境对员工没多少改变。然而事实却是公司的企业文化对工作并不利。为了激励工程师，你必须全面地了解他们的工作环境。

为了证明这一点，Goulet 引用了作者 Robert Henry 说过的一段话：

>
> **目的不是创造艺术，而是在最美妙的状态下让艺术应运而生。**
>
>
>

“你们也要开始这样思考一下你们的软件，”她说。“你们的企业文件就类似那个状态。你们的目标就是创造一个让艺术品应运而生的环境，这件艺术品就是你们公司的代码、一流的售后服务、充满幸福感的开发者、良好的市场预期、盈利能力等等。这些都息息相关。”

优先考虑解决公司的技术债务和遗留代码也是一种文化。那是真正为开发团队清除障碍，以制造影响的方法。同时，这也会让你将来有更多的时间精力去完成更重要的工作。如果你不从根本上改变固有的企业文化环境，你就不可能重构公司产品。改变对产品维护及现代化的投资的态度是开始实施变革的第一步，最理想情况是从公司的 CEO 开始自顶向下转变。

以下是 Goulet 关于建立那种流态文化方面提出的建议：

* 反对公司嘉奖那些加班到深夜的“英雄”。提倡高效率的工作方式。
* 了解协同开发技术，比如 Woody Zuill 提出的[<ruby> 合作编程 <rt>  Mob Programming </rt></ruby>](http://mobprogramming.org/)模式。
* 遵从 4 个[现代敏捷开发](https://www.industriallogic.com/blog/modern-agile/)原则：用户至上、实践及快速学习、把安全放在首位、持续交付价值。
* 每周为研发人员提供项目外的职业发展时间。
* 把[日工作记录](http://corgibytes.com/blog/2016/08/02/how-we-use-daily-journals/)作为一种驱动开发团队主动解决问题的方式。
* 把同情心放在第一位。Corgibytes 公司让员工参加 [Brene Brown 勇气工厂](http://www.courageworks.com/)的培训是非常有用的。

“如果公司高管和投资者不支持这种升级方式，你得从客户服务的角度去说服他们，”Goulet 说，“告诉他们通过这次调整后，最终产品将如何给公司的大多数客户提高更好的体验。这是你能做的一个很有力的论点。”

### 寻找最具天才的代码重构者

整个行业都认为顶尖的工程师不愿意干修复遗留代码的工作。他们只想着去开发新的东西。大家都说把他们留在维护部门真是太浪费人才了。

**其实这些都是误解。如果你知道去哪里和如何找工程师，并为他们提供一个愉快的工作环境，你就可以找到技术非常精湛的工程师，来帮你解决那些最棘手的技术债务问题。**

“每次在会议上，我们都会问现场的同事‘谁喜欢去在遗留代码上工作？’每次只有不到 10% 的与会者会举手。”Goulet 说。“但是我跟这些人交流后，我发现这些工程师恰好是喜欢最具挑战性工作的人才。”

有一位客户来寻求她的帮助，他们使用国产的数据库，没有任何相关文档，也没有一种有效的方法来弄清楚他们公司的产品架构。她称修理这种情况的一类工程师为“修正者”。在 Corgibytes 公司，她有一支这样的修正者团队由她支配，热衷于通过研究二进制代码来解决技术问题。

![](/data/attachment/album/201612/30/235853j7xfbt65atiazx6a.png)

那么，如何才能找到这些技术人才呢？ Goulet 尝试过各种各样的方法，其中有一些方法还是富有成效的。

她创办了一个社区网站 [legacycode.rocks](http://legacycode.rocks/) 并且在招聘启示上写道：“长期招聘那些喜欢重构遗留代码的另类开发人员...如果你以从事处理遗留代码的工作为自豪，欢迎加入！”

“我开始收到很多人发来邮件说，‘噢，天呐，我也属于这样的开发人员！’”她说。“只需要发布这条信息，并且告诉他们这份工作是非常有意义的，就吸引了合适的人才。”

在招聘的过程中，她也会使用持续性交付的经验来回答那些另类开发者想知道的信息：包括详细的工作内容以及明确的要求。“我这么做的原因是因为我讨厌重复性工作。如果我收到多封邮件来咨询同一个问题，我会把答案发布在网上，我感觉自己更像是在写说明文档一样。”

但是随着时间的推移，她发现可以重新定义招聘流程来帮助她识别出更出色的候选人。比如说，她在应聘要求中写道，“公司 CEO 将会重新审查你的简历，因此请确保求职信中致意时不用写明性别。所有以‘尊敬的先生’或‘先生’开头的信件将会被当垃圾处理掉”。这些只是她的招聘初期策略。

“我开始这么做是因为很多申请人把我当成男性，因为我是一家软件公司的男性 CEO，我必须是男性！？”Goulet 说。“所以，有一天我想我应该它当作应聘要求放到网上，看有多少人注意到这个问题。令我惊讶的是，这让我过滤掉一些不太严谨的申请人。还突显出了很多擅于从事遗留代码方面工作的人。”

Goulet 想起一个应聘者发邮件给我说，“我查看了你们网站的代码（我喜欢这个网站，这也是我的工作）。你们的网站架构很奇特，好像是用 PHP 写的，但是你们却运行在用 Ruby 语言写的 Jekyll 下。我真的很好奇那是什么呢。”

Goulet 从她的设计师那里得知，原来，在 HTML、CSS 和 JavaScript 文件中有一个未使用的 PHP 类名，她一直想解决这个问题，但是一直没机会。Goulet 的回复是：“你正在找工作吗？”

另外一名候选人注意到她曾经在一篇说明文档中使用 CTO 这个词，但是她的团队里并没有这个头衔（她的合作伙伴是 Chief Code Whisperer）。这些注重细节、充满求知欲、积极主动的候选者更能引起她的注意。

>
> **代码修正者不仅需要注重细节，而且这也是他们必备的品质。**
>
>
>

让人吃惊的是，Goulet 从来没有为招募最优秀的代码修正者而感到厌烦过。“大多数人都是通过我们的网站直接投递简历，但是当我们想扩大招聘范围的时候，我们会通过 [PowerToFly](https://www.powertofly.com/) 和 [WeWorkRemotely](https://weworkremotely.com/) 网站进行招聘。我现在确实不需要招募新人马了。他们需要经历一段很艰难的时期才能理解代码修正者的意义是什么。”

如果他们通过首轮面试，Goulet 将会让候选者阅读一篇 Arlo Belshee 写的文章“[<ruby> 命名是一个过程 <rt>  Naming is a Process </rt></ruby>](http://arlobelshee.com/good-naming-is-a-process-not-a-single-step/)”。它讲的是非常详细的处理遗留代码的的过程。她最经典的指导方法是：“阅读完这段代码并且告诉我，你是怎么理解的。”

她将找出对问题的理解很深刻并且也愿意接受文章里提出的观点的候选者。这对于区分有深刻理解的候选者和仅仅想获得工作的候选者来说，是极其有用的办法。她强烈要求候选者找出一段与他操作相关的代码，来证明他是充满激情的、有主见的及善于分析问题的人。

最后，她会让候选者跟公司里当前的团队成员一起使用 [Exercism.io](http://exercism.io/) 工具进行编程。这是一个开源项目，它允许开发者学习如何在不同的编程语言环境下使用一系列的测试驱动开发的练习进行编程。结对编程课程的第一部分允许候选者选择其中一种语言来使用。下一个练习中，面试官可以选择一种语言进行编程。他们总能看到那些人处理异常的方法、随机应便的能力以及是否愿意承认某些自己不了解的技术。

“当一个人真正的从执业者转变为大师的时候，他会毫不犹豫的承认自己不知道的东西，”Goulet说。

让他们使用自己不熟悉的编程语言来写代码，也能衡量其坚韧不拔的毅力。“我们想听到某个人说，‘我会深入研究这个问题直到彻底解决它。’也许第二天他们仍然会跑过来跟我们说，‘我会一直留着这个问题直到我找到答案为止。’那是作为一个成功的修正者表现出来的一种气质。”

>
> **产品开发人员在我们这个行业很受追捧，因此很多公司也想让他们来做维护工作。这是一个误解。最优秀的维护修正者并不是最好的产品开发工程师。**
>
>
>

如果一个有天赋的修正者在眼前，Goulet 懂得如何让他走向成功。下面是如何让这种类型的开发者感到幸福及高效工作的一些方式：

* 给他们高度的自主权。把问题解释清楚，然后安排他们去完成，但是永不命令他们应该如何去解决问题。
* 如果他们要求升级他们的电脑配置和相关工具，尽管去满足他们。他们明白什么样的需求才能最大限度地提高工作效率。
* 帮助他们[避免分心](http://corgibytes.com/blog/2016/04/15/inception-layers/)。他们喜欢全身心投入到某一个任务直至完成。

总之，这些方法已经帮助 Corgibytes 公司培养出二十几位对遗留代码充满激情的专业开发者。

### 稳定期没什么不好

大多数创业公司都都不想跳过他们的成长期。一些公司甚至认为成长期应该是永无止境的。而且，他们觉得也没这个必要跳过成长期，即便他们已经进入到了下一个阶段：稳定期。**完全进入到稳定期意味着你拥有人力资源及管理方法来创造技术财富，同时根据优先权适当支出。**

“在成长期和稳定期之间有个转折点，就是维护人员必须要足够壮大，并且相对于专注新功能的产品开发人员，你开始更公平的对待维护人员，”Goulet 说。“你们公司的产品开发完成了。现在你得让他们更加稳定地运行。”

这就意味着要把公司更多的预算分配到产品维护及现代化方面。“你不应该把产品维护当作是一个不值得关注的项目，”她说。“这必须成为你们公司固有的一种企业文化 —— 这将帮助你们公司将来取得更大的成功。“

最终，你通过这些努力创建的技术财富，将会为你的团队带来一大批全新的开发者：他们就像侦查兵一样，有充足的时间和资源去探索新的领域，挖掘新客户资源并且给公司创造更多的机遇。当你们在新的市场领域做得更广泛并且不断取得进展 —— 那么你们公司已经真正地进入到繁荣发展的状态了。

---

via: <http://firstround.com/review/forget-technical-debt-heres-how-to-build-technical-wealth/>

作者：<http://firstround.com/> 译者：[rusking](https://github.com/rusking) 校对：[jasminepeng](https://github.com/jasminepeng)

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


Fedora 中使用 Inkscape 起步

Summary: Inkscape 是一个流行的、功能齐全、自由而开源的矢量图形编辑器，它已经在 Fedora 官方仓库中。它特别适合创作 SVG 格式的矢量图形。Inkscape 非常适于创建和操作图片和插图，以及创建图表和用户界面设计。

已get

![inkscape-gettingstarted](/data/attachment/album/201612/31/133127r4nr0r1c4hpf4cgp.png)

Inkscape 是一个流行的、功能齐全、自由而开源的矢量[图形编辑器](https://inkscape.org/)，它已经在 Fedora 官方仓库中。它特别适合创作 [SVG 格式](https://en.wikipedia.org/wiki/Scalable_Vector_Graphics)的矢量图形。Inkscape 非常适于创建和操作图片和插图，以及创建图表和用户界面设计。

![cyberscoty-landscape-800px](/data/attachment/album/201612/31/133127sioxrleepceervix.png)

*使用 inkscape 创建的[风车景色](https://openclipart.org/detail/185885/windmill-in-landscape)的插图*

[其官方网站的截图页](https://inkscape.org/en/about/screenshots/)上有一些很好的例子，说明 Inkscape 可以做些什么。<ruby> Fedora 杂志 <rt>  Fedora Magazine </rt></ruby>上的大多数精选图片也是使用 Inkscape 创建的，包括最近的精选图片：

![communty](/data/attachment/album/201612/31/133128wt62z5g5aramhgei.png)

*Fedora 杂志最近使用 Inkscape 创建的精选图片*

### 在 Fedora 上安装 Inkscape

**Inkscape 已经[在 Fedora 官方仓库中了](https://apps.fedoraproject.org/packages/inkscape)，因此可以非常简单地在 Fedora Workstation 上使用 Software 这个应用来安装它：**

![inkscape-gnome-software](/data/attachment/album/201612/31/133129frrwz1xo1l1vvwrv.png)

另外，如果你习惯用命令行，你可以使用 `dnf` 命令来安装：

```
sudo dnf install inkscape

```

### （开始）深入 Inkscape

当第一次打开程序时，你会看到一个空白页面，并且有一组不同的工具栏。对于初学者，最重要的三个工具栏是：Toolbar、Tools Control Bar、 Colour Palette：

![inkscape_window](/data/attachment/album/201612/31/133129ow8x4dd17kk1wqqq.png)

**Toolbar**提供了创建绘图的所有基本工具，包括以下工具：

* 矩形工具：用于绘制矩形和正方形
* 星形/多边形（形状）工具
* 圆形工具：用于绘制椭圆和圆
* 文本工具：用于添加标签和其他文本
* 路径工具：用于创建或编辑更复杂或自定义的形状
* 选择工具：用于选择图形中的对象

**Colour Palette** 提供了一种设置当前选定对象的颜色的快速方式。 **Tools Control Bar** 提供了工具栏中当前选定工具的所有设置。每次选择新工具时，Tools Control Bar 会变成该工具的相应设置：

![](/data/attachment/album/201612/31/133130ifyhgoiuyl5rglwa.gif)

### 绘图

接下来，让我们使用 Inkscape 绘制一个星星。 首先，从 **Toolbar** 中选择星形工具，**然后在主绘图区域上单击并拖动。**

你可能会注意到你画的星星看起来很像一个三角形。要更改它，请使用 **Tools Control Bar** 中的 **Corners** 选项，再添加几个点。 最后，当你完成后，在星星仍被选中的状态下，从 **Palette**（调色板）中选择一种颜色来改变星星的颜色：

![inkscape-drawastar](/data/attachment/album/201612/31/133130d1313xx6c7n613w6.gif)

接下来，可以在 Toolbar 中实验一些其他形状工具，如矩形工具，螺旋工具和圆形工具。通过不同的设置，每个工具都可以创建一些独特的图形。

### 在绘图中选择并移动对象

现在你有一堆图形了，你可以使用 Select 工具来移动它们。要使用 Select 工具，首先从工具栏中选择它，然后单击要操作的形状，接着将图形拖动到您想要的位置。

选择形状后，你还可以使用尺寸句柄调整图形大小。此外，如果你单击所选的图形，尺寸句柄将转变为旋转模式，并允许你旋转图形：

![inkscape-movingshapes](/data/attachment/album/201612/31/133130rmv1m99m3p6dq6w1.gif)

---

Inkscape是一个很棒的软件，它还包含了更多的工具和功能。在本系列的下一篇文章中，我们将介绍更多可用来创建插图和文档的功能和选项。

---

作者简介：Ryan 是一名 Fedora 设计师。他使用 Fedora Workstation 作为他的主要桌面，还有来自 Libre Graphics 世界的最好的工具，尤其是矢量图形编辑器 Inkscape。

---

via: <https://fedoramagazine.org/getting-started-inkscape-fedora/>

作者：[Ryan Lerch](http://ryanlerch.id.fedoraproject.org/) 译者：[geekpi](https://github.com/geekpi) 校对：[jasminepeng](https://github.com/jasminepeng)

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


如何在 Linux 下安装 PyCharm

专业版是自由开源的吗？两个版本在功能上有木有限制差别

来自陕西西安的 Chrome Mobile 55.0|Android 6.0 用户

专业版是商业版本。

deepin商店,直接点击安装,安装完打开就能用......

可以参考 https://confluence.jetbrains.com/display/PYH/Installing+PyCharm+on+Linux+according+to+FHS?src=search

按照FHS的方式安装pycharm，装在家目录不太符合FHS

arch上就简单多了……

pacman -S pycharm

或者

gnome软件中心（gnome-software）好像也有，点以下就安装

当然有

![](/data/attachment/album/201612/31/173729tiei1c2v31xwdtki.png)

### 简介

Linux 经常被看成是一个远离外部世界，只有极客才会使用的操作系统，虽然这是一个误解，但事实上，如果你想开发软件，那么 Linux 系统能够为你提供一个很好的开发环境。

刚开始学习编程的新手们经常会问这样一个问题：应该使用哪种语言？当涉及到 Linux 系统的时候，通常的选择是 C、C++、Python、Java、PHP、Perl 和 Ruby On Rails。

Linux 系统的许多核心程序都是用 C 语言写的，但是如果离开 Linux 系统的世界， C 语言就不如其它语言比如 Java 和 Python 那么常用。

对于学习编程的人来说， Python 和 Java 都是不错的选择，因为它们是跨平台的，因此，你在 Linux 系统上写的程序在 Windows 系统和 Mac 系统上也能够很好的工作。

虽然你可以使用任何编辑器来开发 Python 程序，但是如果你使用一个同时包含编辑器和调试器的优秀的集成开发环境（IDE）来进行开发，那么你的编程生涯将会变得更加轻松。

PyCharm 是由 Jetbrains 公司开发的一个跨平台编辑器。如果你之前是在 Windows 环境下进行开发，那么你会立刻认出 Jetbrains 公司，它就是那个开发了 Resharper 的公司。 Resharper 是一个用于重构代码的优秀产品，它能够指出代码可能存在的问题以及自动添加声明：比如当你在使用一个类的时候它会自动为你导入。

这篇文章将讨论如何在 Linux 系统上获取、安装和运行 PyCharm 。

### 如何获取 PyCharm

你可以通过访问[这儿](https://www.jetbrains.com/pycharm/)获取 PyCharm 。屏幕中央有一个很大的 'Download' 按钮。

你可以选择下载专业版或者社区版。如果你刚刚接触 Python 编程那么推荐下载社区版。然而，如果你打算发展到专业化的编程，那么专业版的一些优秀特性是不容忽视的。

### 如何安装 PyCharm

下载好的文件的名称可能是 ‘pycharm-professional-2016.2.3.tar.gz’。

以 “tar.gz” 结尾的文件是被 [gzip](https://www.lifewire.com/example-uses-of-the-linux-gzip-command-4078675) 工具压缩过的，并且把文件夹用 [tar](https://www.lifewire.com/uses-of-linux-command-tar-2201086) 工具归档到了一起。你可以阅读关于[提取 tar.gz 文件](https://www.lifewire.com/extract-tar-gz-files-2202057)指南的更多信息。

加快节奏，为了解压文件，你需要做的是首先打开终端，然后通过下面的命令进入下载文件所在的文件夹：

```
cd ~/Downloads

```

现在，通过运行下面的命令找到你下载的文件的名字：

```
ls pycharm*

```

然后运行下面的命令解压文件：

```
tar -xvzf pycharm-professional-2016.2.3.tar.gz -C ~

```

记得把上面命令中的文件名替换成通过 `ls` 命令获知的 pycharm 文件名。（也就是你下载的文件的名字）。上面的命令将会把 PyCharm 软件安装在 `home` 目录中。

### 如何运行 PyCharm

要运行 PyCharm， 首先需要进入 `home` 目录：

```
cd ~

```

运行 `ls` 命令查找文件夹名：

```
ls

```

查找到文件名以后，运行下面的命令进入 PyCharm 目录：

```
cd pycharm-2016.2.3/bin

```

最后，通过运行下面的命令来运行 PyCharm：

```
sh pycharm.sh &

```

如果你是在一个桌面环境比如 GNOME、KDE、Unity、Cinnamon 或者其他现代桌面上运行，那么你也可以通过桌面环境的菜单或者快捷方式来找到 PyCharm 。

### 总结

现在， PyCharm 已经安装好了，你可以开始使用它来开发一个桌面应用、 web 应用和各种工具。

如果你想学习如何使用 Python 编程，那么这儿有很好的[学习资源](https://www.lifewire.com/learn-linux-in-structured-manner-4061368)值得一看。里面的文章更多的是关于 Linux 学习，但也有一些资源比如 Pluralsight 和 Udemy 提供了关于 Python 学习的一些很好的教程。

如果想了解 PyCharm 的更多特性，请点击[这儿](/article-8074-1.html)来查看。它覆盖了从创建项目到描述用户界面、调试以及代码重构的全部内容。

---

via: <https://www.lifewire.com/how-to-install-the-pycharm-python-ide-in-linux-4091033>

作者：[Gary Newell](https://www.lifewire.com/gary-newell-2180098) 译者：[ucasFL](https://github.com/ucasFL) 校对：[wxy](https://github.com/wxy)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 组织编译，[Linux中国](https://linux.cn/) 荣誉推出


如何在 Linux/Unix 系统中验证端口是否打开

很简单，很基础，很实用

打发打发

获取地点，66666

![](/data/attachment/album/201612/31/211726xappkqn7m7kn7lbj.jpg)

在 Linux 或者类 Unix 中，我该如何检查某个端口是否被占用？我又该如何验证 Linux 服务器中有哪些端口处于监听状态？

验证哪些端口在服务器的网络接口上处于监听状态是非常重要的。你需要注意那些开放端口来检测网络入侵。除了网络入侵，为了排除故障，确认服务器上的某个端口是否被其他应用程序占用也是必要的。比方说，你可能会在同一个系统中安装了 Apache 和 Nginx 服务器，所以了解是 Apache 还是 Nginx 占用了 # 80/443 TCP 端口真的很重要。这篇快速教程会介绍使用 `netstat` 、 `nmap` 和 `lsof` 命令来检查端口使用信息并找出哪些程序正在使用这些端口。

### 如何检查 Linux 中的程序和监听的端口

1、 打开一个终端，如 shell 命令窗口。 2、 运行以下任意一行命令：

```
sudo lsof -i -P -n | grep LISTEN
sudo netstat -tulpn | grep LISTEN
sudo nmap -sTU -O IP地址

```

下面我们看看这些命令和它们的详细输出内容：

### 方式 1：lsof 命令

语法如下：

```
$ sudo lsof -i -P -n
$ sudo lsof -i -P -n | grep LISTEN
$ doas lsof -i -P -n | grep LISTEN  ### OpenBSD

```

输出如下：

![](/data/attachment/album/201612/31/211030n26w008vvw5ewfmy.png)

*图 1：使用 lsof 命令检查监听端口和程序*

仔细看上面输出的最后一行：

```
sshd    85379     root    3u  IPv4 0xffff80000039e000      0t0  TCP 10.86.128.138:22 (LISTEN)

```

* `sshd` 是程序的名称
* `10.86.128.138` 是 `sshd` 程序绑定 (LISTEN) 的 IP 地址
* `22` 是被使用 (LISTEN) 的 TCP 端口
* `85379` 是 `sshd` 任务的进程 ID (PID)

### 方式 2：netstat 命令

你可以如下面所示使用 `netstat` 来检查监听的端口和程序。

**Linux 中 netstat 语法**

```
$ netstat -tulpn | grep LISTEN

```

**FreeBSD/MacOS X 中 netstat 语法**

```
$ netstat -anp tcp | grep LISTEN
$ netstat -anp udp | grep LISTEN

```

**OpenBSD 中 netstat 语法**

```
$ netstat -na -f inet | grep LISTEN
$ netstat -nat | grep LISTEN

```

### 方式 3：nmap 命令

语法如下：

```
$ sudo nmap -sT -O localhost
$ sudo nmap -sU -O 192.168.2.13 ### 列出打开的 UDP 端口
$ sudo nmap -sT -O 192.168.2.13 ### 列出打开的 TCP 端口

```

示例输出如下：

![](/data/attachment/album/201612/31/211108za9x94bv5dbyn4va.png)

*图 2：使用 nmap 探测哪些端口监听 TCP 连接*

你可以用一句命令合并 TCP/UDP 扫描：

```
$ sudo nmap -sTU -O 192.168.2.13

```

### 赠品：对于 Windows 用户

在 windows 系统下可以使用下面的命令检查端口使用情况：

```
netstat -bano | more
netstat -bano | grep LISTENING
netstat -bano | findstr /R /C:"[LISTING]"

```

---

via: <https://www.cyberciti.biz/faq/unix-linux-check-if-port-is-in-use-command/>

作者：[VIVEK GITE](https://www.cyberciti.biz/faq/unix-linux-check-if-port-is-in-use-command/) 译者：[GHLandy](https://github.com/GHLandy) 校对：[oska874](https://github.com/oska874)

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


如何在 Apache 中重定向 URL 到另外一台服务器

Summary: 在本文中，我们将解释如何在 Apache 中使用 mod_rewrite 模块重定向对已移动到另外一台服务器上的资源的访问。

linux

学习了，但是为什么不用nginx呢

如我们前面两篇文章（[使用 mod\_rewrite 执行内部重定向](http://www.tecmint.com/redirection-with-mod_rewrite-in-apache/)和[基于浏览器来显示自定义内容](http://www.tecmint.com/mod_rewrite-redirect-requests-based-on-browser/)）中提到的，在本文中，我们将解释如何在 Apache 中使用 mod\_rewrite 模块重定向对已移动到另外一台服务器上的资源的访问。

![](/data/attachment/album/201612/31/213648sonj0hnyo2ij2ydn.png)

假设你正在重新设计公司的网站。你已决定将内容和样式（HTML文件、JavaScript 和 CSS）存储在一个服务器上，将文档存储在另一个服务器上 - 这样可能会更稳健。

>
> **建议阅读：** [5 个提高 Apache Web 服务器性能的提示](http://www.tecmint.com/apache-performance-tuning/) 。
>
>
>

但是，你希望这个更改对用户是透明的，以便他们仍然能够通过之前的网址访问文档。

在下面的例子中，名为 `assets.pdf` 的文件已从 `192.168.0.100`（主机名：`web`）中的 `/var/www/html` 移动到`192.168.0.101`（主机名：`web2`）中的相同位置。

为了让用户在浏览到 `192.168.0.100/assets.pdf` 时可以访问到此文件，请打开 `192.168.0.100` 上的 Apache 配置文件并添加以下重写规则（或者也可以将以下规则添加到 [.htaccess 文件](http://www.tecmint.com/tag/htaccess/)）中：

```
RewriteRule "^(/assets\.pdf$)" "http://192.168.0.101$1"  [R,L]

```

其中 `$1` 占位符，代表与括号中的正则表达式匹配的任何内容。

现在保存更改，不要忘记重新启动 Apache，让我们看看当我们打开 `192.168.0.100/assets.pdf`，尝试访问 `assets.pdf` 时会发生什么：

>
> **建议阅读：** [25 个有用的网站 .htaccess 技巧](http://www.tecmint.com/apache-htaccess-tricks/)
>
>
>

在下面我们就可以看到，为 `192.168.0.100` 上的 `assets.pdf` 所做的请求实际上是由 `192.168.0.101`处理的。

```
# tail -n 1 /var/log/apache2/access.log

```

![Check Apache Logs](/data/attachment/album/201701/02/194302xz7378c3ef6zq6e6.png)

*检查 Apache 日志*

在本文中，我们讨论了如何对已移动到其他服务器的资源进行重定向。 总而言之，我强烈建议你看看 [mod\_rewrite](http://mod-rewrite-cheatsheet.com/) 指南和 [Apache 重定向指南](https://httpd.apache.org/docs/2.4/rewrite/remapping.html)，以供将来参考。

一如既往那样，如果您对本文有任何疑虑，请随时使用下面的评论栏回复。 我们期待你的回音！

---

作者简介：Gabriel Cánepa 是来自阿根廷圣路易斯 Villa Mercedes 的 GNU/Linux 系统管理员和 Web 开发人员。 他在一家全球领先的消费品公司工作，非常高兴使用 FOSS 工具来提高他日常工作领域的生产力。

---

via: <http://www.tecmint.com/redirect-website-url-from-one-server-to-different-server/>

作者：[Gabriel Cánepa](http://www.tecmint.com/author/gacanepa/) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

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


使用 Inkscape：添加颜色

Summary: 虽然 Palette 对于从预定义列表快速更改对象颜色非常有用，但大多数情况下，你需要更好地控制对象的颜色。这时我们使用 Inkscape 中最重要的对话框之一 - 填充和轮廓Fill and Stroke 对话框。

视频播一遍之后就不会显示了

什么视频？

哦。这闹心的 GIF ，居然是显示完了就白屏了。。

很好多出点这些自由软件的教程 还有GIMP 让大家都爱用.最近准备写动画的制作模块

![inkscape-addingcolour](/data/attachment/album/201701/01/193519aksprp9ohzyhocsk.png)

在我们先前的 Inkscape 文章中，[我们介绍了 Inkscape 的基础](/article-8079-1.html) - 安装，以及如何创建基本形状及操作它们。我们还介绍了使用 Palette 更改 inkscape 对象的颜色。 虽然 Palette 对于从预定义列表快速更改对象颜色非常有用，但大多数情况下，你需要更好地控制对象的颜色。这时我们使用 Inkscape 中最重要的对话框之一 - <ruby> 填充和轮廓 <rt>  Fill and Stroke </rt></ruby> 对话框。

**关于文章中的动画的说明：**动画中的一些颜色看起来有条纹。这只是动画创建导致的。当你在 Inkscape 尝试时，你会看到很好的平滑渐变的颜色。

### 使用 Fill/Stroke 对话框

要在 Inkscape 中打开 “Fill and Stroke” 对话框，请从主菜单中选择 `Object`>`Fill and Stroke`。打开后，此对话框中的三个选项卡允许你检查和更改当前选定对象的填充颜色、描边颜色和描边样式。

![open-fillstroke](/data/attachment/album/201701/01/193520dyzh0y4l29qm0lmq.gif)

在 Inkscape 中，Fill 用来给予对象主体颜色。对象的轮廓是你的对象的可选择外框，可在<ruby> 轮廓样式 <rt>  Stroke style </rt></ruby>选项卡中进行配置，它允许您更改轮廓的粗细，创建虚线轮廓或为轮廓添加圆角。 在下面的动画中，我会改变星形的填充颜色，然后改变轮廓颜色，并调整轮廓的粗细：

![using-fillstroke](/data/attachment/album/201701/01/193521c31r1jm926r6a286.gif)

### 添加并编辑渐变效果

对象的填充（或者轮廓）也可以是渐变的。要从 “Fill and Stroke” 对话框快速设置渐变填充，请先选择 “Fill” 选项卡，然后选择<ruby> 线性渐变 <rt>  linear gradient </rt></ruby> 选项：

![create-gradient](/data/attachment/album/201701/01/193521r7xq6sw47rrrhues.gif)

要进一步编辑我们的渐变，我们需要使用专门的<ruby> 渐变工具 <rt>  Gradient Tool </rt></ruby>。 从工具栏中选择“Gradient Tool”，会有一些渐变编辑锚点出现在你选择的形状上。 **移动锚点**将改变渐变的位置。 如果你**单击一个锚点**，您还可以在“Fill and Stroke”对话框中更改该锚点的颜色。 要**在渐变中添加新的锚点**，请双击连接锚点的线，然后会出现一个新的锚点。

![editing-gradient](/data/attachment/album/201701/01/193521zncy9pqs0m5c5lf1.gif)

---

这篇文章介绍了在 Inkscape 图纸中添加一些颜色和渐变的基础知识。 **“Fill and Stroke”** 对话框还有许多其他选项可供探索，如图案填充、不同的渐变样式和许多不同的轮廓样式。另外，查看**<ruby> 工具控制栏 <rt>  Tools control bar </rt></ruby>** 的 **Gradient Tool** 中的其他选项，看看如何以不同的方式调整渐变。

---

作者简介：Ryan 是一名 Fedora 设计师。他使用 Fedora Workstation 作为他的主要桌面，还有来自 Libre Graphics 世界的最好的工具，尤其是矢量图形编辑器 Inkscape。

---

via: <https://fedoramagazine.org/inkscape-adding-colour/>

作者：[Ryan Lerch](http://ryanlerch.id.fedoraproject.org/) 译者：[geekpi](https://github.com/geekpi) 校对：[jasminepeng](https://github.com/jasminepeng)

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


使用 Fedora 和 Inkscape 制作一张简单的壁纸

Summary: 在先前的两篇 Inkscape 的文章中，我们已经介绍了 Inkscape 的基本使用、创建对象以及一些基本操作和如何修改颜色。在接下来的介绍中，我们会集合这些新的技巧，并且创建我们的第一个作品 —— 一张简单的壁纸。

赞一个！

![](/data/attachment/album/201701/01/195104tidznodpibx3codd.png)

在先前的两篇 Inkscape 的文章中，我们已经[介绍了 Inkscape 的基本使用、创建对象](/article-8079-1.html)以及[一些基本操作和如何修改颜色。](/article-8084-1.html)

在接下来的介绍中，我们会集合这些新的技巧，并且创建我们的第一个作品 —— 一张简单的壁纸。

### 更改文档大小

回顾先前的教程时，你可能会注意到主画板上的默认文档尺寸是一个黑色边框的矩形。Inkscape 中默认文档的大小是 A4 纸大小：

![](/data/attachment/album/201701/01/195106rwpxvnkcx26ncs32.png)

对于这张壁纸而言，我们会将尺寸改为 **1024px x 768px**。要改变文档的尺寸，进入`File` > `Document Properties...`。在<ruby> 文档属性 <rt>  Document Properties </rt></ruby>对话框中<ruby> 自定义文档大小 <rt>  Custom Size </rt></ruby>区域中输入宽度为 `1024`，高度为 `768` ，单位是 `px`：

![](/data/attachment/album/201701/01/195106awnnamin9wd1dadi.png)

页面上文档的轮廓大概像这样：

![](/data/attachment/album/201701/01/195107gcqvmcqq800cjwn3.png)

### 绘画背景

接下来，我们会画一个和文档一样大的矩形。因此选择<ruby> 矩形工具 <rt>  rectangle tool </rt></ruby>来画一个矩形，并使用<ruby> 工具控制栏 <rt>  Tools Control bar </rt></ruby>来调整矩形的大小。

![](/data/attachment/album/201701/01/195107z3zozwq23opjzob0.png)

接着在矩形中添加一个<ruby> 渐变填充 <rt>  Gradient Fill </rt></ruby>。如果你需要复习添加渐变，请阅读先前添加色彩的[那篇文章](/article-8084-1.html)。

![](/data/attachment/album/201701/01/195107x7pphasd4u86p7wp.png)

你的矩形也可以设置轮廓颜色。 使用<ruby> 填充和轮廓 <rt>  Fill and Stroke </rt></ruby>对话框将轮廓设置为 `none`。

![](/data/attachment/album/201701/01/195108z6dk6sxduauaz060.png)

### 绘制图样

接下来我们画一个三角形，使用 3 个顶点的星型/多边形工具。你可以按住 `CTRL` 键给三角形一个角度并使之对称。

![](/data/attachment/album/201701/01/195109ayrqflln3mcpyhlx.png)

选中三角形并按下 `CTRL+D` 来复制它（复制的图形会覆盖在原来图形的上面），**因此在复制后确保将它移动到别处。**

![](/data/attachment/album/201701/01/195110qy66qt47usz41q4f.png)

如图选中一个三角形，进入`Object` > `FLIP-HORIZONTAL`（水平翻转）。

![](/data/attachment/album/201701/01/195110l77mfr9zfuf77ee5.png) ![](/data/attachment/album/201701/01/195110whgh2zdazfp2lafa.png)

为这三个三角形重新着色。让它看上去和背景和谐。

![](/data/attachment/album/201701/01/195111gf9zzo03d4ohb643.png)

选中所有的三角形并复制，以填充你的样式：

![](/data/attachment/album/201701/01/195112lfihpin3k32u3zfo.png)

### 导出背景

最后，我们需要将我们的文档导出为 PNG 文件。点击 `File` > `EXPORT PNG`，打开导出对话框，选择文件位置和名字，确保选中的是 `Drawing` 标签，并点击 `EXPORT`。

![](/data/attachment/album/201701/01/195112deasselfs4w9hz22.png)

不要让工具成为你想象力的障碍。来制作美丽的壁纸并提交你的设计到 [FEDORA 25 壁纸](https://fedoramagazine.org/keeping-fedora-beautiful-contribute-wallpaper/)上来吧。你的设计或许会幸运地被选中成为上千万用户的壁纸。下面是用 Inkscape 和上面提到的技术制作的一些壁纸示例：

![](/data/attachment/album/201701/01/195113oqidsqbs25dfbtfd.png) ![](/data/attachment/album/201701/01/195114qnoj4nxl6zllh4co.png)

---

via: <https://fedoramagazine.org/inkscape-design-imagination/>

作者：[a2batic](http://a2batic.id.fedoraproject.org/) 译者：[geekpi](https://github.com/geekpi) 校对：[jasminepeng](https://github.com/jasminepeng)

本文由 [LCTT](https://github.com/LCTT/TranslateProject) 组织编译，[Linux中国](https://linux.cn/) 荣誉推出


sshpass：一个很棒的免交互 SSH 登录工具，但不要用在生产服务器上

Summary: 如果你想自动在 SSH 登录提示符中提供密码和用户名怎么办？这时 sshpass 就可以帮到你了。

colorful的风格，赞

新年新气象~

第一句话少了个字

将sshpass写在shell脚本里，脚本取消普通用户读权限，只能使用root执行，这样会好些

why?

在大多数情况下，Linux 系统管理员使用 SSH 登录到程 Linux 服务器时，要么是通过密码，要么是[无密码 SSH 登录](/article-6901-1.html)或基于密钥的 SSH 身份验证。

如果你想自动在 SSH 登录提示符中提供**密码**和**用户名**怎么办？这时 **sshpass** 就可以帮到你了。

![](/data/attachment/album/201701/03/160301cyn181nn2mf2ur1w.png)

sshpass 是一个简单、轻量级的命令行工具，通过它我们能够向命令提示符本身提供密码（非交互式密码验证），这样就可以通过 [cron 调度器](/article-7513-1.html)执行自动化的 shell 脚本进行备份。

ssh 直接使用 TTY 访问，以确保密码是用户键盘输入的。 sshpass 在专门的 tty 中运行 ssh，以误导 ssh 相信它是从用户接收到的密码。

重要：使用 **sshpass** 是最不安全的，因为所有系统上的用户在命令行中通过简单的 “**ps**” 命令就可看到密码。因此，如果必要，比如说在生产环境，我强烈建议使用 [SSH 无密码身份验证](/article-6901-1.html)。

### 在 Linux 中安装 sshpass

在基于 **RedHat/CentOS** 的系统中，首先需要[启用 EPEL 仓库](/article-2324-1.html)并使用 [yum 命令](/article-2272-1.html)安装它。

```
# yum install sshpass
# dnf install sshpass    [Fedora 22 及以上版本]

```

在 Debian/Ubuntu 和它的衍生版中，你可以使用 [apt-get 命令](/article-4933-1.html)来安装。

```
$ sudo apt-get install sshpass

```

另外，你也可以从最新的源码安装 `sshpass`，首先下载源码并从 tar 文件中解压出内容：

```
$ wget http://sourceforge.net/projects/sshpass/files/latest/download -O sshpass.tar.gz
$ tar -xvf sshpass.tar.gz
$ cd sshpass-1.06
$ ./configure
# sudo make install

```

### 如何在 Linux 中使用 sshpass

**sshpass** 与 **ssh** 一起使用，使用下面的命令可以查看 `sshpass` 的使用选项的完整描述：

```
$ sshpass -h

```

下面为显示的 sshpass 帮助内容：

```
Usage: sshpass [-f|-d|-p|-e] [-hV] command parameters
-f filename   Take password to use from file
-d number     Use number as file descriptor for getting password
-p password   Provide password as argument (security unwise)
-e            Password is passed as env-var "SSHPASS"
With no parameters - password will be taken from stdin
-h            Show help (this screen)
-V            Print version information
At most one of -f, -d, -p or -e should be used

```

正如我之前提到的，**sshpass** 在用于脚本时才更可靠及更有用，请看下面的示例命令。

使用用户名和密码登录到远程 Linux ssh 服务器（10.42.0.1），并[检查文件系统磁盘使用情况](/article-6466-1.html)，如图所示。

```
$ sshpass -p 'my_pass_here' ssh aaronkilik@10.42.0.1 'df -h'

```

**重要提示**：此处，在命令行中提供了密码，这是不安全的，不建议使用此选项。

![sshpass - Linux Remote Login via SSH](/data/attachment/album/201701/03/160315v5apy2anynznaj09.png)

*sshpass – 使用 SSH 远程登录 Linux*

但是，为了防止在屏幕上显示密码，可以使用 `-e` 标志，并将密码作为 `SSHPASS` 环境变量的值输入，如下所示：

```
$ export SSHPASS='my_pass_here'
$ echo $SSHPASS
$ sshpass -e ssh aaronkilik@10.42.0.1 'df -h'

```

![sshpass - Hide Password in Prompt](/data/attachment/album/201701/03/160322gt60xp2pouvg27wp.png)

*sshpass – 在终端中隐藏密码*

**注意：**在上面的示例中，`SSHPASS` 环境变量仅用于临时目的，并将在重新启动后删除。

要永久设置 `SSHPASS` 环境变量，打开 `/etc/profile` 文件，并在文件开头输入 `export` 语句：

```
export SSHPASS='my_pass_here'

```

保存文件并退出，接着运行下面的命令使更改生效：

```
$ source /etc/profile

```

另外，也可以使用 `-f` 标志，并把密码放在一个文件中。 这样，您可以从文件中读取密码，如下所示：

```
$ sshpass -f password_filename ssh aaronkilik@10.42.0.1 'df -h'

```

![sshpass - Supply Password File to Login](/data/attachment/album/201701/03/160323e1twv1r1jpjxoo1r.png)

*sshpass – 在登录时提供密码文件*

你也可以使用 `sshpass` [通过 scp 传输文件](/article-7456-1.html)或者 [rsync 备份/同步文件](/article-4503-1.html)，如下所示：

```
------- Transfer Files Using SCP -------
$ scp -r /var/www/html/example.com --rsh="sshpass -p 'my_pass_here' ssh -l aaronkilik" 10.42.0.1:/var/www/html
------- Backup or Sync Files Using Rsync -------
$ rsync --rsh="sshpass -p 'my_pass_here' ssh -l aaronkilik" 10.42.0.1:/data/backup/ /backup/

```

更多的用法，建议阅读 `sshpass` 的 man 页面，输入：

```
$ man sshpass

```

在本文中，我们解释了 `sshpass` 是一个非交互式密码验证的简单工具。 虽然这个工具可能是有帮助的，但还是强烈建议使用更安全的 ssh 公钥认证机制。

请在下面的评论栏写下任何问题或评论，以便可以进一步讨论。

---

作者简介：Aaron Kili 是一位 Linux 和 F.O.S.S 爱好者，未来的 Linux 系统管理员，web 开发人员， 还是 TecMint 原创作者，热爱电脑工作，并乐于分享知识。

---

via: <http://www.tecmint.com/sshpass-non-interactive-ssh-login-shell-script-ssh-password/>

作者：[Aaron Kili](http://www.tecmint.com/author/aaronkili/) 译者：[geekpi](https://github.com/geekpi) 校对：[jasminepeng](https://github.com/jasminepeng)

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


在 Ubuntu 中用 UFW 配置防火墙

Summary: UFW，即简单防火墙，是一个 Arch Linux、Debian 或 Ubuntu 中管理防火墙规则的前端。 UFW 通过命令行使用（尽管它有可用的 GUI），它的目的是使防火墙配置简单（即不复杂）。

感谢翻译！

UFW，即<ruby> 简单防火墙 <rp>  （ </rp> <rt>  uncomplicated firewall </rt> <rp>  ） </rp></ruby>，是一个 Arch Linux、Debian 或 Ubuntu 中管理防火墙规则的前端。 UFW 通过命令行使用（尽管它有可用的 GUI），它的目的是使防火墙配置简单（即<ruby> 不复杂 <rp>  （ </rp> <rt>  uncomplicated </rt> <rp>  ） </rp></ruby>）。

![](/data/attachment/album/201701/03/171533kyo288kio1s11pa4.jpg)

### 开始之前

1、 熟悉我们的[入门](https://www.linode.com/docs/getting-started)指南，并完成设置服务器主机名和时区的步骤。

2、 本指南将尽可能使用 `sudo`。 在完成[保护你的服务器](/article-8076-1.html)指南的章节，创建一个标准用户帐户，强化 SSH 访问和移除不必要的网络服务。 **但不要**跟着创建防火墙部分 - 本指南是介绍使用 UFW 的，它对于 iptables 而言是另外一种控制防火墙的方法。

3、 更新系统

**Arch Linux**

```
sudo pacman -Syu

```

**Debian / Ubuntu**

```
sudo apt-get update && sudo apt-get upgrade

```

### 安装 UFW

UFW 默认包含在 Ubuntu 中，但在 Arch 和 Debian 中需要安装。 Debian 将自动启用 UFW 的 systemd 单元，并使其在重新启动时启动，但 Arch 不会。 这与告诉 UFW 启用防火墙规则不同，因为使用 systemd 或者 upstart 启用 UFW 仅仅是告知 init 系统打开 UFW 守护程序。

默认情况下，UFW 的规则集为空，因此即使守护程序正在运行，也不会强制执行任何防火墙规则。 强制执行防火墙规则集的部分在下面。

#### Arch Linux

1、 安装 UFW：

```
sudo pacman -S ufw

```

2、 启动并启用 UFW 的 systemd 单元：

```
sudo systemctl start ufw
sudo systemctl enable ufw

```

#### Debian / Ubuntu

1、 安装 UFW

```
sudo apt-get install ufw

```

### 使用 UFW 管理防火墙规则

#### 设置默认规则

大多数系统只需要打开少量的端口接受传入连接，并且关闭所有剩余的端口。 从一个简单的规则基础开始，`ufw default`命令可以用于设置对传入和传出连接的默认响应动作。 要拒绝所有传入并允许所有传出连接，那么运行：

```
sudo ufw default allow outgoing
sudo ufw default deny incoming

```

`ufw default` 也允许使用 `reject` 参数。

>
> 警告：
>
>
> 除非明确设置允许规则，否则配置默认 `deny` 或 `reject` 规则会锁定你的服务器。确保在应用默认 `deny` 或 `reject` 规则之前，已按照下面的部分配置了 SSH 和其他关键服务的允许规则。
>
>
>

#### 添加规则

可以有两种方式添加规则：用**端口号**或者**服务名**表示。

要允许 SSH 的 22 端口的传入和传出连接，你可以运行：

```
sudo ufw allow ssh

```

你也可以运行：

```
sudo ufw allow 22

```

相似的，要在特定端口（比如 111）上 `deny` 流量，你需要运行：

```
sudo ufw deny 111

```

为了更好地调整你的规则，你也可以允许基于 TCP 或者 UDP 的包。下面例子会允许 80 端口的 TCP 包：

```
sudo ufw allow 80/tcp
sudo ufw allow http/tcp

```

这个会允许 1725 端口上的 UDP 包：

```
sudo ufw allow 1725/udp

```

#### 高级规则

除了基于端口的允许或阻止，UFW 还允许您按照 IP 地址、子网和 IP 地址/子网/端口的组合来允许/阻止。

允许从一个 IP 地址连接：

```
sudo ufw allow from 123.45.67.89

```

允许特定子网的连接：

```
sudo ufw allow from 123.45.67.89/24

```

允许特定 IP/ 端口的组合：

```
sudo ufw allow from 123.45.67.89 to any port 22 proto tcp

```

`proto tcp` 可以删除或者根据你的需求改成 `proto udp`，所有例子的 `allow` 都可以根据需要变成 `deny`。

#### 删除规则

要删除一条规则，在规则的前面加上 `delete`。如果你希望不再允许 HTTP 流量，你可以运行：

```
sudo ufw delete allow 80

```

删除规则同样可以使用服务名。

### 编辑 UFW 的配置文件

虽然可以通过命令行添加简单的规则，但仍有可能需要添加或删除更高级或特定的规则。 在运行通过终端输入的规则之前，UFW 将运行一个文件 `before.rules`，它允许回环接口、ping 和 DHCP 等服务。要添加或改变这些规则，编辑 `/etc/ufw/before.rules` 这个文件。 同一目录中的 `before6.rules` 文件用于 IPv6 。

还存在一个 `after.rule` 和 `after6.rule` 文件，用于添加在 UFW 运行你通过命令行输入的规则之后需要添加的任何规则。

还有一个配置文件位于 `/etc/default/ufw`。 从此处可以禁用或启用 IPv6，可以设置默认规则，并可以设置 UFW 以管理内置防火墙链。

### UFW 状态

你可以在任何时候使用命令：`sudo ufw status` 查看 UFW 的状态。这会显示所有规则列表，以及 UFW 是否处于激活状态：

```
Status: active

To                         Action      From
--                         ------      ----
22                         ALLOW       Anywhere
80/tcp                     ALLOW       Anywhere
443                        ALLOW       Anywhere
22 (v6)                    ALLOW       Anywhere (v6)
80/tcp (v6)                ALLOW       Anywhere (v6)
443 (v6)                   ALLOW       Anywhere (v6)

```

### 启用防火墙

随着你选择规则完成，你初始运行 `ufw status` 可能会输出 `Status: inactive`。 启用 UFW 并强制执行防火墙规则：

```
sudo ufw enable

```

相似地，禁用 UFW 规则：

```
sudo ufw disable

```

>
> UFW 会继续运行，并且在下次启动时会再次启动。
>
>
>

### 日志记录

你可以用下面的命令启动日志记录：

```
sudo ufw logging on

```

可以通过运行 `sudo ufw logging low|medium|high` 设计日志级别，可以选择 `low`、 `medium` 或者 `high`。默认级别是 `low`。

常规日志类似于下面这样，位于 `/var/logs/ufw`：

```
Sep 16 15:08:14 <hostname> kernel: [UFW BLOCK] IN=eth0 OUT= MAC=00:00:00:00:00:00:00:00:00:00:00:00:00:00 SRC=123.45.67.89 DST=987.65.43.21 LEN=40 TOS=0x00 PREC=0x00 TTL=249 ID=8475 PROTO=TCP SPT=48247 DPT=22 WINDOW=1024 RES=0x00 SYN URGP=0

```

前面的值列出了你的服务器的日期、时间、主机名。剩下的重要信息包括：

* **[UFW BLOCK]**：这是记录事件的描述开始的位置。在此例中，它表示阻止了连接。
* **IN**：如果它包含一个值，那么代表该事件是传入事件
* **OUT**：如果它包含一个值，那么代表事件是传出事件
* **MAC**：目的地和源 MAC 地址的组合
* **SRC**：包源的 IP
* **DST**：包目的地的 IP
* **LEN**：数据包长度
* **TTL**：数据包 TTL，或称为 time to live。 在找到目的地之前，它将在路由器之间跳跃，直到它过期。
* **PROTO**：数据包的协议
* **SPT**：包的源端口
* **DPT**：包的目标端口
* **WINDOW**：发送方可以接收的数据包的大小
* **SYN URGP**：指示是否需要三次握手。 `0` 表示不需要。

---

via: <https://www.linode.com/docs/security/firewalls/configure-firewall-with-ufw>

作者：[Linode](https://www.linode.com/docs/security/firewalls/configure-firewall-with-ufw) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)

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


如何在 Ubuntu 环境下搭建邮件服务器（三）

Summary: 现在我们将学习设置虚拟用户，以便我们可以管理所有 Dovecot 中的用户。

现在我们将学习设置虚拟用户，以便我们可以管理所有 Dovecot 中的用户。

![Mail server](/data/attachment/album/201701/04/161617lyxvhvt255xmoxh8.jpg "Mail server")

在本系列的最后，我们将详细介绍如何在 Dovecot 和 Postfix 中设置虚拟用户和邮箱。

欢迎回来，热心的 Linux 系统管理员们！ 在本系列的[第一部分](/article-8071-1.html)和[第二部分](/article-8077-1.html)中，我们学习了如何将 Postfix 和 Dovecot 组合在一起，搭建一个不错的 IMAP 和 POP3 邮件服务器。 现在我们将学习设置虚拟用户，以便我们可以管理所有 Dovecot 中的用户。

### 抱歉，还不能配置 SSL

我知道我答应过教你们如何设置一个受 SSL 保护的服务器。 不幸的是，我低估了这个话题的范围。 所以，我会下个月再写一个全面的教程。

今天，在本系列的最后一部分中，我们将详细介绍如何在 Dovecot 和 Postfix 中设置虚拟用户和邮箱。 在你看来这是有点奇怪，所以我尽量让下面的例子简单点。我们将使用纯文本文件和纯文本来进行身份验证。 你也可以选择使用数据库后端和较强的加密认证形式，具体请参阅文末链接了解有关这些的更多信息。

### 虚拟用户

我们希望邮件服务器上用的是虚拟用户而不是 Linux 系统用户。使用 Linux 系统用户不能扩展，并且它们会暴露系统登录账号，给你的服务器带来不必要的风险。 设置虚拟用户需要在 Postfix 和 Dovecot 中编辑配置文件。我们将从 Postfix 开始。首先，我们将从一个干净、简化的 `/etc /postfix/main.cf` 开始。移动你原始的 `main.cf` 到别处做个备份，创建一个新的干净的文件，内容如下：

```
compatibility_level=2
smtpd_banner = $myhostname ESMTP $mail_name (Ubuntu/GNU)
biff = no
append_dot_mydomain = no

myhostname = localhost
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
myorigin = $myhostname
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 192.168.0.0/24
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = all

virtual_mailbox_domains = /etc/postfix/vhosts.txt
virtual_mailbox_base = /home/vmail
virtual_mailbox_maps = hash:/etc/postfix/vmaps.txt
virtual_minimum_uid = 1000
virtual_uid_maps = static:5000
virtual_gid_maps = static:5000
virtual_transport = lmtp:unix:private/dovecot-lmtp0

```

你可以直接拷贝这份文件，除了 `mynetworks` 参数的设置 `192.168.0.0/24`，它应该是你的本地子网掩码。

接下来，创建用户和组 `vmail` 来拥有你的虚拟邮箱。虚拟邮箱保存在 `vmail` 的家目录下。

```
$ sudo groupadd -g 5000 vmail
$ sudo useradd -m -u 5000 -g 5000 -s /bin/bash vmail

```

接下来重新加载 Postfix 配置：

```
$ sudo postfix reload
[sudo] password for carla:
postfix/postfix-script: refreshing the Postfix mail system

```

### Dovecot 虚拟用户

我们会使用 Dovecot 的 `lmtp` 协议来连接到 Postfix。你可以这样安装：

```
$ sudo apt-get install dovecot-lmtpd

```

`main.cf` 的最后一行涉及到 `lmtp`。复制这个 `/etc/dovecot/dovecot.conf` 示例文件来替换已存在的文件。再说一次，我们只使用这一个文件，而不是 `/etc/dovecot/conf.d` 内的所有文件。

```
protocols = imap pop3 lmtp
log_path = /var/log/dovecot.log
info_log_path = /var/log/dovecot-info.log
ssl = no
disable_plaintext_auth = no
mail_location = maildir:~/.Mail
pop3_uidl_format = %g
auth_verbose = yes
auth_mechanisms = plain

passdb {
  driver = passwd-file
  args = /etc/dovecot/passwd
}

userdb {
  driver = static
  args = uid=vmail gid=vmail home=/home/vmail/studio/%u
}

service lmtp {
 unix_listener /var/spool/postfix/private/dovecot-lmtp {
   group = postfix
   mode = 0600
   user = postfix
  }
}

protocol lmtp {
  postmaster_address = postmaster@studio
}
service lmtp {
  user = vmail
}

```

最后，你可以创建一个含有用户和密码的文件 `/etc/dovecot/passwd`。对于纯文本验证，我们只需要用户的完整邮箱地址和密码：

```
alrac@studio:{PLAIN}password
layla@studio:{PLAIN}password
fred@studio:{PLAIN}password
molly@studio:{PLAIN}password
benny@studio:{PLAIN}password

```

Dovecot 虚拟用户独立于 Postfix 虚拟用户，因此你需要管理 Dovecot 中的用户。保存所有的设置并重启 Postfix 和 Dovecot：

```
$ sudo service postfix restart
$ sudo service dovecot restart

```

现在让我们使用老朋友 telnet 来看下 Dovecot 是否设置正确。

```
$ telnet studio 110
Trying 127.0.1.1...
Connected to studio.
Escape character is '^]'.
+OK Dovecot ready.
user molly@studio
+OK
pass password
+OK Logged in.
quit
+OK Logging out.
Connection closed by foreign host.

```

现在一切都好！让我们用 `mail` 命令，发送测试消息给我们的用户。确保使用用户的完整电子邮箱地址而不只是用户名。

```
$ mail benny@studio
Subject: hello and welcome!
Please enjoy your new mail account!
.

```

最后一行的**英文句点**表示发送消息。让我们看下它是否到达了正确的邮箱。

```
$ sudo ls -al /home/vmail/studio/benny@studio/.Mail/new
total 16
drwx------ 2 vmail vmail 4096 Dec 14 12:39 .
drwx------ 5 vmail vmail 4096 Dec 14 12:39 ..
-rw------- 1 vmail vmail  525 Dec 14 12:39 1481747995.M696591P5790.studio,S=525,W=540

```

找到了。这是一封我们可以阅读的纯文本文件：

```
$ less 1481747995.M696591P5790.studio,S=525,W=540
Return-Path: <carla@localhost>
Delivered-To: benny@studio
Received: from localhost
        by studio (Dovecot) with LMTP id V01ZKRuuUVieFgAABiesew
        for <benny@studio>; Wed, 14 Dec 2016 12:39:55 -0800
Received: by localhost (Postfix, from userid 1000)
        id 9FD9CA1F58; Wed, 14 Dec 2016 12:39:55 -0800 (PST)
Date: Wed, 14 Dec 2016 12:39:55 -0800
To: benny@studio
Subject: hello and welcome!
User-Agent: s-nail v14.8.6
Message-Id: <20161214203955.9FD9CA1F58@localhost>
From: carla@localhost (carla)

Please enjoy your new mail account!

```

你还可以使用 telnet 进行测试，如本系列前面部分所述，并在你最喜欢的邮件客户端中设置帐户，如 Thunderbird，Claws-Mail 或 KMail。

### 故障排查

当邮件工作不正常时，请检查日志文件（请参阅配置示例），然后运行 `journalctl -xe`。 这时会提供定位输入错误、未安装包和可以 Google 的短语等所有需要的信息。

### 接下来？

假设你的 LAN 名称服务配置正确，你现在有一台很好用的 LAN 邮件服务器。 显然，以纯文本发送消息不是最佳的，不支持互联网的邮件也是绝对不可以的。 请参阅 [Dovecot SSL 配置](http://wiki.dovecot.org/SSL/DovecotConfiguration)和 [Postfix TLS 支持](http://www.postfix.org/TLS_README.html)，[VirtualUserFlatFilesPostfix](http://wiki2.dovecot.org/HowTo/VirtualUserFlatFilesPostfix) 涵盖了 TLS 和数据库后端。并请期待我之后的 SSL 指南。这次我说的是真的。

---

via: <https://www.linux.com/learn/sysadmin/building-email-server-ubuntu-linux-part-3>

作者：[CARLA SCHRODER](https://www.linux.com/users/cschroder) 译者：[geekpi](https://github.com/geekpi) 校对：[jasminepeng](https://github.com/jasminepeng)

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