2017年8月

本文撰写参考了以下文章,并引用了该文章部分内容:专利告诉你,为何 Apache 禁用 FB + PL 代码,作者:付钦伟。

哪里有压迫,哪里就有反抗

身为知识产权圈里的专利人,笔者钦佩开源情怀,并曾写道:即使专利人也有专利情怀,现实世界中开源与专利的碰撞依然难免丑陋。现在看来,这话有点轻描淡写了。

笔者未能认真发掘开源运动史,只好拍拍脑袋认定:开源软件运动是针对知识产权制度,尤其是专利制度,对软件产业之压迫的暴动。

“哪里有压迫,哪里就有反抗。”

这场轰轰烈烈的暴动在发展过程中,于 2017 年 7 月,“Apache Software Foundation 主管兼法律事务副主席 Chris Mattmann 正式发表声明称:Facebook BSD+Patents license(以下简称 FB+PL)已经正式被列入 “CategoryX” 列表,因此 Apache 项目中将不能够包含或依赖于 Facebook Patents license 的代码;而已经发布的代码,涉及 FB+PL 许可证的,需要在 8 月 31 号前完成替换。”

简而言之,Apache 一脚将 FB+PL 踢出了。这是不是 Apache 在开源暴动中的激进声明?为什么这么说?

专利情怀

故事要从头讲起:

专利制度产生了,那时候大家并不认为这是一个万恶的吃人的制度。专利制度的根本目的还是促进技术进步,从而推动产业和经济发展。为了达成此目的,则需要合理保护发明人的积极性,具体而言,就是给予他们一定时期的专有保护为回报,在这种利益驱动下,他们会积极的做出发明,并通过申请专利,在向社会公布技术促进技术进步的同时,兑现专有保护。

"Before then [the adoption of the United States Constitution], any man might instantly use what another had invented; so that the inventor had no special advantage from his own invention. The patent system changed this; secured to the inventor, for a limited time, the exclusive use of his invention; and thereby added the fuel of interest to the fire of genius, in the discovery and production of new and useful things. "

-- Abraham Lincoln, Second lecture on discoveries and inventions, February 11, 1859

以上这段诠释了专利情怀的话出自美国总统林肯的演讲。只需要读懂这个短句就好了:专利制度为天才之火添上利益之油。

开源与专利的碰撞

到上世纪 90 年代,专利海盗开始大行其道,软件产业受害最深。在软件行业里,程序员和开发者需要开放、自由地交流和利用彼此的成果才利于行业发展。这一特性先天与专利制度八字不合。这个死结是一百多年的林肯总统绝对意料不到的。

从根本上,开源情怀在于:对于自己的智力劳动成果,放弃可取得收益的专有权利,给软件松绑,从而利于成果的流通、利用,以及行业发展。

绑在软件身上的主要知识产权绳索有两条:版权,专利。商标不起核心作用。解开版权这条绳索的方式比较成熟:版权开源许可证。而专利很微妙,最主要的原因是它的无形,主动权常常不在开源作者自己手里。版权是属于作者的,所以作者有主动权;而专利属于申请人,申请人有主动权,申请人可以是任何第三方。这是开源与专利之矛盾的根源。

对开源情怀的最大伤害在于:不知道是谁用专利这根无形绳索悄悄捆绑了自己的作品。这是开源人对专利的敏感和敌视的由来。开源人常常感到愤怒和难以理解的是:为什么自己的智力成果,别人可以用专利来捆上?

对不起,这一个很让人遗憾的回答:任何人都可以对包括已公开的开源技术在内的任何现有技术做出改进,并就改进获得专利权。而当有别人在某项开源技术比较可行的主要改进方向上都申请了专利,就相当于把主要出路都卡上了,那么这项开源技术也就被别人的专利绑上了。这种专利申请技术,在圈内有一个好听的名字:专利布局。防御性的专利布局可以用来对自己的技术成果形成严密保护。进攻性的专利布局可以用来摘别人的桃子的,包括摘开源的桃子。专利海盗就属于充分、高超地利用专利手段和法律程序,激进地玩进攻性专利布局来摘别人桃子的。有时,手法可以高超到骗过专利审查员的法眼,将与现有技术很接近的内容纳入自己的保护范围。软件行业是重灾区。

应当说,在专利方面,对开源最大的威胁来自第三方,而不是开源的作者、后续开发者、用户。在社区内,大家尝试在版权开源许可之外附加专利开源许可,但是因为这种附加许可的效力仅能延伸到后续开发者、用户,不能规制第三方或专利海盗,实质能达到的效果较为有限。

Facebook 被踢的委屈

现在,我们重新梳理一下 Apache 踢 FB+PL 这件事。Apache 主要是对 Facebook Patents license,即对专利许可的条件不满意才开踢的。

Apache 的表态很干脆地捍卫了开源情怀,但是不是有些偏强硬激进了呢?

对于发展开源事业,首要的问题是什么呢?当然应当是分清谁是朋友,谁是敌人。然后,团结一切可以团结的进步力量,形成对敌统一战线。

笔者猜想,开源的敌人是第三方专利海盗,以及供专利海盗滋生的土壤。Facebook 看起来更像可以团结的朋友:Facebook 对开源有很积极的贡献和推动,其在专利许可方面的动作应当也没有越线。Facebook 如果真想以专利捆绑开源,另安排一个白手套作为第三方来布局专利,岂不干脆彻底?哪里还需要如此费事的搞 Facebook Patents license?至少应当说,Facebook 还是出于基本善意的立场提出的专利许可。

扒扒 Facebook 专利许可

再深入剖析这个问题,就要梳理 Facebook Patents license 的主要条款对开源的影响了。

Facebook Patents license 的主要条款

Additional Grant of Patent Rights Version 2

"Software" means the React software distributed by Facebook, Inc.

Facebook, Inc. ("Facebook") hereby grants to each recipient of the Software
("you") a perpetual, worldwide, royalty-free, non-exclusive, irrevocable
(subject to the termination provision below) license under any Necessary
Claims, to make, have made, use, sell, offer to sell, import, and otherwise
transfer the Software. For avoidance of doubt, no license is granted under
Facebook's rights in any patent claims that are infringed by (i) modifications
to the Software made by you or any third party or (ii) the Software in
combination with any software or other technology.

The license granted hereunder will terminate, automatically and without notice,
if you (or any of your subsidiaries, corporate affiliates or agents) initiate
directly or indirectly, or take a direct financial interest in, any Patent
Assertion: (i) against Facebook or any of its subsidiaries or corporate
affiliates, (ii) against any party if such Patent Assertion arises in whole or
in part from any software, technology, product or service of Facebook or any of
its subsidiaries or corporate affiliates, or (iii) against any party relating
to the Software. Notwithstanding the foregoing, if Facebook or any of its
subsidiaries or corporate affiliates files a lawsuit alleging patent
infringement against you in the first instance, and you respond by filing a
patent infringement counterclaim in that lawsuit against that party that is
unrelated to the Software, the license granted hereunder will not terminate
under section (i) of this paragraph due to such counterclaim.

A "Necessary Claim" is a claim of a patent owned by Facebook that is
necessarily infringed by the Software standing alone.

A "Patent Assertion" is any lawsuit or other action alleging direct, indirect,
or contributory infringement or inducement to infringe any patent, including a
cross-claim or counterclaim.

简要而言,关键点有两个:

  • Facebook 对免费专利许可设了限制条件:你不可以诉我知识产权侵权;
  • 专利许可所涉及的专利,仅限于所涉及的开源软件本身,对于软件修改后或与其他技术共同使用而可能侵犯的专利,不在许可之列。

法律背景扑朔迷离

即使分析以上两个要点,也要仔细衡量,须考虑现实背景中的重要因素:

  • 如果无专利许可,会如何?
  • 许可不涉及实质性的对价。
  • 许可涉及复杂的国际司法环境。

笔者认为,许可条款之外的上述背景中的三条因素才真正使许可的效力变得扑朔迷离。

就背景因素 1 而言,现实情况中,普遍存在开源许可证仅涉及版权而回避了专利的情况。这是社区当中大家普遍可以接受的条件。未提及专利,并不等于没有给予专利许可,尤其在许可证中没有明示“专利要另收钱”的情况下。有一个奇妙的东西,可以叫作基于诚实信用或善意公平原则的“默认许可”。

何为“默认许可”?简单讲,当你给人家什么东西去用,没有明示这个东西要收钱,人家用了之后,你向人家去收钱,这么做不太厚道吧?基于诚实信用或善意公平原则,通常法院不会支持这种像是给人下了套,然后去收钱的行为的,而会认为当你给人家东西去用,没有明示这个东西要收钱时,已经“默认许可”人家免费用了。

开源软件的作者或提供者,同时又作为相关专利的专利权人时,在提供了明确免除版权费用的许可证的情况下,如果在向用户交付产品的同时,没有明示要收取专利费,“默认许可”应当成立。从学术讨论的角度,也有将之称为“专利权权利用尽”的。但是由于未收钱,“专利权权利用尽”的成立更有困难些。笔者还是坚持“默认许可”路线。

但还是很遗憾,法律世界不同于软件世界。在软件世界里,每一段算法程序,在给定条件后,都会给你执行出一个清楚的结果。法律世界里很难如此。“默认许可”是否会得到司法完全支持?真的很难讲,各个国家,甚至一个国家在不同时期,都可能对相似的情况采取不同的思路并给出不同的分寸和方向的判决。在美国、英国、澳大利亚等海洋法系的国家,前后判例的一致性会比较高。而中国、德国等大陆法系国家,变化可能较大。以下将要讨论的诸多问题均受各国司法差异因素影响,以下不再赘述。

总之,不确定性较大。尽管笔者对各国实际判例缺少一手研究,但从法理和情理上倾向于在专利“默认许可”成立,即利于开源免费。

就背景因素 2 而言,许可是否涉及实质性的对价是很重要的因素。实际上,我们现在讨论的是许可证,性质又不同于协议,但一些相关因素可以类比来考虑。没有实质性对价,指没有因交易性的收获进行实质支付,比如,支付价款。在这种情形下,许可证或协议在性质上更类似于赠与,对有关方的权利义务要求未必牢固。比如,Facebook 将自己开发的软件拿出来开源,自己付出了开发成本,却没有向使用者收取费用;使用者可以较随意地拿 Facebook 的开源软件免费使用。如果由于这种免费的行为中暗藏玄机,而导致 Facebook 或使用者要承受重大的义务、付出重大代价,则是有失基本公平的,除非有特别原因。所以,各国从司法的角度,会考虑“是否涉及实质性的对价”这一因素,但仍然是会采取不同的思路并给出不同的分寸和方向的判决。简而言之,Facebook Patents license 并不涉及实质性的对价,所以司法层面不会随便基于这种许可而使有关方承担与对价不相匹配的重大义务。

总之,还是不确定性较大,尽管笔者还是对各国实际判例缺少一手研究,但从法理和情理上仍倾向于 Facebook Patents license 因不存在实质性对价,相关方带来重大义务或损失的可能性较低,即利于开源免费。

背景因素 3 已经融合在以上讨论之中了。

综合以上背景因素的讨论,可知 Facebook Patents license 对开源还是比较友好的,至少不会造成重大损害。

Facebook,面子大于里子

再审视 Facebook Patents license 的两个关键点,其对“默认许可”是否仍能成立各有微妙影响。笔者的观点是,很可能使情形确实反而不如没有这个 Facebook Patents license,不过负面影响有限。

就关键点 1,Facebook 对免费专利许可设了限制条件:你不可以诉我知识产权侵权。

明示的效力当然优于默认的效力,所以笔者倾向认为默认许可的效力被破坏了。但以下三个因素将对开源有利:

  • 用户对 Facebook 发起诉讼时,许可终止,但用户此前的使用仍享受免费许可。所以,主动权还是在用户手里,可以选择有利形势。当用户认为自己更多的知识产权为 Facebook 所使用,份量重于自己所使用的 Facebook 开源软件的知识产权时,才发起诉讼,并在诉讼前做好调整和准备;如果自己用的 Facebook 的知识产权比较多,而被 Facebook 使用的知识产权少,自己还是在赚便宜,何必去找 Facebook 麻烦呢?更应当指出,Facebook 所设的这个条件较容易做被规避:可以将专利转移给第三人,也就是白手套,由白手套去诉 Facebook。这样,即可以继续享受免费许可,又可以搞 Facebook。这在法理上是成立的。
  • 对单一用户来讲,出现要诉 Facebook 而会破坏免费许可这一情况的现实可能性较低。
  • Facebook 此条件有构成滥用知识产权的风险。

以上第 1 条实际上已经能够让 Facebook 的关键点 1 形同虚设,达不成实际意义了。以上第 3 条,不确定性很大。

就关键点 2,专利许可所涉及的专利,仅限于所涉及的软件本身,对于软件修改后或与其他技术共同使用而可能侵犯的专利,不在许可之列。

关键点 2 实际上暗藏杀机,比形同虚设的关键点 1 凶险些,但实际威力也还有限。重点在于:

  • Facebook 明示不予许可的专利:软件修改后或与其他技术共同使用而可能侵犯的专利,实际上照样可能将开源软件捆死。这是其心机最凶险之处。
  • 尽管 Facebook 明示排除了软件修改后或与其他技术共同使用而可能侵犯的专利,但只是泛泛而论。实际上,用户修改软件或将之与其他技术共同使用是必然普遍发生的情况,如果 Facebook 没有及时向用户提示这些具体专利的存在,并对收费有明确具体要求,笔者倾向于默认许可的效力仍应成立。当然,不确定性仍然较大。“及时向用户提示”指对于软件交付之前已经持有的专利,应在软件交付前明确提示;对于软件交付之后获得的专利,应在专利获得后马上提示。

综上,尽管复杂的不确定性仍较多,笔者倾向于认为 Facebook Patents license 总体上对开源较为友善,与不涉及专利的许可证相比较,没有带来实质性变劣。对 Facebook 而言,可能象征意义更大于实质意义,即面子大于里子。

Apache 潜在风险

另外,还有一个潜在风险因素,使 Apache 踢掉 FB+PL 之后使自己处在更为不利的境地。

Apache的风险控制措施是:“Apache 项目中将不能够包含或依赖于 Facebook Patents license 的代码;而已经发布的代码,涉 及FB+PL 许可证的,需要在 8 月 31 号前完成替换。”这一措施理论上说说还好,但在可操作性上问题很多。笔者认为,剔除 FB+PL 版权许可证所涉及的内容比较好操作:只要剔除相关的代码,替之以其他来源或自编的代码就好了。因为其他来源或自编的代码,基本就能确保在表达方式上的不同,从而规避版权侵权。这是现实的操作方式。

而规避侵犯 Facebook 专利权,上述方式很可能并不奏效。简单而言,版权保护表达形式,专利保护构想。规避表达形式,也就是从表述方式上加以实质调整就可以做到了。而规避构想,确实很难。实际上,Facebook 到底有哪些专利与之相关恐怕也很不清晰,还要加以规避,就更是难上加难了。分析工作和代码的重新设计对专利的专业性要求非常高,工作很复杂,工作量也很大。

这种情况下,Apache 可能面对的最坏情况是:放弃了 FB+PL 的开源代码,仍存在侵犯 Facebook 专利的高风险,又不会得到 Facebook 明示、默认许可。

Apache 的激进开源

所以,笔者认为,Apache 的表态很干脆地捍卫了开源情怀,踢掉 FB+PL 的行事方式有可能略偏强硬激进,尽管从规避不确定的风险而言,也不是完全没有道理。

(题图:HuffPost)


作者简介:

李可

集慧智佳知识产权咨询公司,李可。江湖人称“可哥”,老牌专利代理人,知识产权高级咨询师。70 后文艺理工男,属牛,性子慢但踏实稳妥。

OpenStack 部署完就是一个 “ 僵栈 StuckStack ”,一般出于技术原因,但有时是商业上的原因,它是无法在没有明显中断,也不花费时间和成本的情况下升级的。在关于这个话题的最后一篇文章中,我们讨论了这些云中有多少陷入僵局,以及当时是怎么决定的与如今的大部分常识相符。现在 OpenStack 已经有 7 年了,最近随着容器编排系统的增长以及更多企业开始利用公共和私有的云平台,OpenStack 正面临着压力。

没有魔法解决方案

如果你仍在寻找一个可以没有任何问题地升级你现有的 僵栈 StuckStack 的解决方案,那么我有坏消息给你:没有魔法解决方案,你最好集中精力建立一个标准化的平台,它可以有效地运营和轻松地升级。

廉价航空业已经表明,虽然乘客可能渴望最好的体验,可以坐在头等舱或者商务舱喝香槟,有足够的空间放松,但是大多数人会选择乘坐最便宜的,最终价值等式不要让他们付出更多的代价。工作负载是相同的。长期而言,工作负载将运行在最经济的平台上,因为在高价硬件或软件上运行的业务实际上并没有受益。

Amazon、Microsoft、Google 等大型公共云企业都知道,这就是为什么他们建立了高效的数据中心,并使用模型来构建、操作和扩展基础设施。长期以来,企业一直奉行以设计、制造、市场、定价、销售、实施为一体的最优秀的硬件和软件基础设施。现实可能并不总是符合承诺,但它现在还不重要,因为 成本模式 cost model 在当今世界无法生存。一些组织试图通过改用免费软件替代,而不改变自己的行为来解决这一问题。因此,他们发现,他们只是将成本从获取软件变到运营软件上。好消息是,那些高效运营的大型运营商使用的技术,现在可用于所有类型的组织。

什么是软件模型?

虽然许多年来,软件程序由许多对象、进程和服务而组成,但近年来,程序是普遍由许多单独的服务组成,它们高度分布在数据中心的不同服务器以及跨越数据中心的服务器上。

OpenStack 服务的简单演示

许多服务意味着许多软件需要配置、管理并跟踪许多物理机器。以成本效益的方式规模化地进行这一工作需要一个模型,即所有组件如何连接以及它们如何映射到物理资源。为了构建模型,我们需要有一个软件组件库,这是一种定义它们如何彼此连接以及将其部署到平台上的方法,无论是物理的还是虚拟的。在 Canonical 公司,我们几年前就认识到这一点,并建立了一个通用的软件建模工具 Juju,使得运营商能够从 100 个通用软件服务目录中组合灵活的拓扑结构、架构和部署目标。

Juju 建模 OpenStack 服务

在 Juju 中,软件服务被定义为一种叫做 Charm 的东西。 Charms 是代码片段,它通常用 python 或 bash 编写,其中提供有关服务的信息 - 声明的接口、服务的安装方式、可连接的其他服务等。

Charms 可以简单或者复杂,具体取决于你想要赋予的功能。对于 OpenStack,Canonical 在上游 OpenStack 社区的帮助下,为主要 OpenStack 服务开发了一套完整的 Charms。Charms 代表了模型的说明,使其可以轻松地部署、操作扩展和复制。Charms 还定义了如何升级自身,包括在需要时执行升级的顺序以及如何在需要时优雅地暂停和恢复服务。通过将 Juju 连接到诸如 裸机即服务(MAAS) 这样的裸机配置系统,其中 OpenStack 的逻辑模型可以部署到物理硬件上。默认情况下,Charms 将在 LXC 容器中部署服务,从而根据云行为的需要,提供更大的灵活性来重新定位服务。配置在 Charms 中定义,或者在部署时由第三方工具(如 Puppet 或 Chef)注入。

这种方法有两个不同的好处:1 - 通过创建一个模型,我们从底层硬件抽象出每个云服务。2 - 使用已知来源的标准化组件,通过迭代组合新的架构。这种一致性使我们能够使用相同的工具部署非常不同的云架构,运行和升级这些工具是安全的。

通过全面自动化的配置工具和软件程序来管理硬件库存,运营商可以比使用传统企业技术或构建偏离核心的定制系统更有效地扩展基础架构。有价值的开发资源可以集中在创新应用领域,使新的软件服务更快上线,而不是改变标准的商品基础设施,这将会导致进一步的兼容性问题。

在下一篇文章中,我将介绍部署完全建模的 OpenStack 的一些最佳实践,以及如何快速地进行操作。如果你有一个现有的 僵栈 StuckStack ,那么虽然我们不能很容易地拯救它,但是与公有云相比,我们将能够让你走上一条完全支持的、高效的基础架构以及运营成本的道路。

即将举行的网络研讨会

如果你在旧版本的 OpenStack 中遇到问题,并且想要轻松升级 OpenStack 云并且无需停机,请观看我们的在线点播研讨会,从 Newton 升级到 Ocata 的现场演示。

联系我们

如果你想了解有关迁移到 Canonical OpenStack 云的更多信息,请联系这里

(题图:乐高的空客 A380-800模型。空客运行 OpenStack)


作者简介:

专注于 Ubuntu OpenStack 的云产品经理。以前在 MySQL 和 Red Hat 工作。喜欢摩托车,遇见使用 Ubuntu 和 Openstack 做有趣事的人。


via: https://insights.ubuntu.com/2017/07/18/stuckstack-how-modelling-helps-you-avoid-getting-a-stuck-openstack/

作者:Mark Baker 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

Package_Management_tw_mostov.png-307.8kB

介绍

大多数现代的类 Unix 操作系统都提供了一种中心化的机制用来搜索和安装软件。软件通常都是存放在存储库中,并通过包的形式进行分发。处理包的工作被称为包管理。包提供了操作系统的基本组件,以及共享的库、应用程序、服务和文档。

包管理系统除了安装软件外,它还提供了工具来更新已经安装的包。包存储库有助于确保你的系统中使用的代码是经过审查的,并且软件的安装版本已经得到了开发人员和包维护人员的认可。

在配置服务器或开发环境时,我们最好了解下包在官方存储库之外的情况。某个发行版的稳定版本中的包有可能已经过时了,尤其是那些新的或者快速迭代的软件。然而,包管理无论对于系统管理员还是开发人员来说都是至关重要的技能,而已打包的软件对于主流 Linux 发行版来说也是一笔巨大的财富。

本指南旨在快速地介绍下在多种 Linux 发行版中查找、安装和升级软件包的基础知识,并帮助您将这些内容在多个系统之间进行交叉对比。

包管理系统:简要概述

大多数包系统都是围绕包文件的集合构建的。包文件通常是一个存档文件,它包含已编译的二进制文件和软件的其他资源,以及安装脚本。包文件同时也包含有价值的元数据,包括它们的依赖项,以及安装和运行它们所需的其他包的列表。

虽然这些包管理系统的功能和优点大致相同,但打包格式和工具却因平台而异:

操作系统格式工具
Debian.debapt, apt-cache, apt-get, dpkg
Ubuntu.debapt, apt-cache, apt-get, dpkg
CentOS.rpmyum
Fedora.rpmdnf
FreeBSDPorts, .txzmake, pkg

Debian 及其衍生版,如 Ubuntu、Linux Mint 和 Raspbian,它们的包格式是 .deb。APT 这款先进的包管理工具提供了大多数常见的操作命令:搜索存储库、安装软件包及其依赖项,并管理升级。在本地系统中,我们还可以使用 dpkg 程序来安装单个的 deb 文件,APT 命令作为底层 dpkg 的前端,有时也会直接调用它。

最近发布的 debian 衍生版大多数都包含了 apt 命令,它提供了一个简洁统一的接口,可用于通常由 apt-getapt-cache 命令处理的常见操作。这个命令是可选的,但使用它可以简化一些任务。

CentOS、Fedora 和其它 Red Hat 家族成员使用 RPM 文件。在 CentOS 中,通过 yum 来与单独的包文件和存储库进行交互。

在最近的 Fedora 版本中,yum 已经被 dnf 取代,dnf 是它的一个现代化的分支,它保留了大部分 yum 的接口。

FreeBSD 的二进制包系统由 pkg 命令管理。FreeBSD 还提供了 Ports 集合,这是一个存在于本地的目录结构和工具,它允许用户获取源码后使用 Makefile 直接从源码编译和安装包。

更新包列表

大多数系统在本地都会有一个和远程存储库对应的包数据库,在安装或升级包之前最好更新一下这个数据库。另外,yumdnf 在执行一些操作之前也会自动检查更新。当然你可以在任何时候对系统进行更新。

系统命令
Debian / Ubuntusudo apt-get update
sudo apt update
CentOSyum check-update
Fedoradnf check-update
FreeBSD Packagessudo pkg update
FreeBSD Portssudo portsnap fetch update

更新已安装的包

在没有包系统的情况下,想确保机器上所有已安装的软件都保持在最新的状态是一个很艰巨的任务。你将不得不跟踪数百个不同包的上游更改和安全警报。虽然包管理器并不能解决升级软件时遇到的所有问题,但它确实使你能够使用一些命令来维护大多数系统组件。

在 FreeBSD 上,升级已安装的 ports 可能会引入破坏性的改变,有些步骤还需要进行手动配置,所以在通过 portmaster 更新之前最好阅读下 /usr/ports/UPDATING 的内容。

系统命令说明
Debian / Ubuntusudo apt-get upgrade只更新已安装的包
sudo apt-get dist-upgrade可能会增加或删除包以满足新的依赖项
sudo apt upgradeapt-get upgrade 类似
sudo apt full-upgradeapt-get dist-upgrade 类似
CentOSsudo yum update
Fedorasudo dnf upgrade
FreeBSD Packagessudo pkg upgrade
FreeBSD Portsless /usr/ports/UPDATING使用 less 来查看 ports 的更新提示(使用上下光标键滚动,按 q 退出)。
cd /usr/ports/ports-mgmt/portmaster && sudo make install && sudo portmaster -a安装 portmaster 然后使用它更新已安装的 ports

搜索某个包

大多数发行版都提供针对包集合的图形化或菜单驱动的工具,我们可以分类浏览软件,这也是一个发现新软件的好方法。然而,查找包最快和最有效的方法是使用命令行工具进行搜索。

系统命令说明
Debian / Ubuntuapt-cache search search_string
apt search search_string
CentOSyum search search_string
yum search all search_string搜索所有的字段,包括描述
Fedoradnf search search_string
dnf search all search_string搜索所有的字段,包括描述
FreeBSD Packagespkg search search_string通过名字进行搜索
pkg search -f search_string通过名字进行搜索并返回完整的描述
pkg search -D search_string搜索描述
FreeBSD Portscd /usr/ports && make search name=package通过名字进行搜索
cd /usr/ports && make search key=search_string搜索评论、描述和依赖

查看某个软件包的信息

在安装软件包之前,我们可以通过仔细阅读包的描述来获得很多有用的信息。除了人类可读的文本之外,这些内容通常包括像版本号这样的元数据和包的依赖项列表。

系统命令说明
Debian / Ubuntuapt-cache show package显示有关包的本地缓存信息
apt show package
dpkg -s package显示包的当前安装状态
CentOSyum info package
yum deplist package列出包的依赖
Fedoradnf info package
dnf repoquery --requires package列出包的依赖
FreeBSD Packagespkg info package显示已安装的包的信息
FreeBSD Portscd /usr/ports/category/port && cat pkg-descr

从存储库安装包

知道包名后,通常可以用一个命令来安装它及其依赖。你也可以一次性安装多个包,只需将它们全部列出来即可。

系统命令说明
Debian / Ubuntusudo apt-get install package
sudo apt-get install package1 package2 ...安装所有列出来的包
sudo apt-get install -y packageapt 提示是否继续的地方直接默认 yes
sudo apt install package显示一个彩色的进度条
CentOSsudo yum install package
sudo yum install package1 package2 ...安装所有列出来的包
sudo yum install -y packageyum 提示是否继续的地方直接默认 yes
Fedorasudo dnf install package
sudo dnf install package1 package2 ...安装所有列出来的包
sudo dnf install -y packagednf 提示是否继续的地方直接默认 yes
FreeBSD Packagessudo pkg install package
sudo pkg install package1 package2 ...安装所有列出来的包
FreeBSD Portscd /usr/ports/category/port && sudo make install从源码构建安装一个 port

从本地文件系统安装一个包

对于一个给定的操作系统,有时有些软件官方并没有提供相应的包,那么开发人员或供应商将需要提供包文件的下载。你通常可以通过 web 浏览器检索这些包,或者通过命令行 curl 来检索这些信息。将包下载到目标系统后,我们通常可以通过单个命令来安装它。

在 Debian 派生的系统上,dpkg 用来处理单个的包文件。如果一个包有未满足的依赖项,那么我们可以使用 gdebi 从官方存储库中检索它们。

在 CentOS 和 Fedora 系统上,yumdnf 用于安装单个的文件,并且会处理需要的依赖。

系统命令说明
Debian / Ubuntusudo dpkg -i package.deb
sudo apt-get install -y gdebi && sudo gdebi package.deb安装 gdebi,然后使用 gdebi 安装 package.deb 并处理缺失的依赖
CentOSsudo yum install package.rpm
Fedorasudo dnf install package.rpm
FreeBSD Packagessudo pkg add package.txz
sudo pkg add -f package.txz即使已经安装的包也会重新安装

删除一个或多个已安装的包

由于包管理器知道给定的软件包提供了哪些文件,因此如果某个软件不再需要了,它通常可以干净利落地从系统中清除这些文件。

系统命令说明
Debian / Ubuntusudo apt-get remove package
sudo apt remove package
sudo apt-get autoremove删除不需要的包
CentOSsudo yum remove package
Fedorasudo dnf erase package
FreeBSD Packagessudo pkg delete package
sudo pkg autoremove删除不需要的包
FreeBSD Portssudo pkg delete package
cd /usr/ports/path_to_port && make deinstall卸载 port

apt 命令

Debian 家族发行版的管理员通常熟悉 apt-getapt-cache。较少为人所知的是简化的 apt 接口,它是专为交互式使用而设计的。

传统命令等价的 apt 命令
apt-get updateapt update
apt-get dist-upgradeapt full-upgrade
apt-cache search stringapt search string
apt-get install packageapt install package
apt-get remove packageapt remove package
apt-get purge packageapt purge package

虽然 apt 通常是一个特定操作的快捷方式,但它并不能完全替代传统的工具,它的接口可能会随着版本的不同而发生变化,以提高可用性。如果你在脚本或 shell 管道中使用包管理命令,那么最好还是坚持使用 apt-getapt-cache

获取帮助

除了基于 web 的文档,请记住我们可以通过 shell 从 Unix 手册页(通常称为 man 页面)中获得大多数的命令。比如要阅读某页,可以使用 man

man page

man 中,你可以用箭头键导航。按 / 搜索页面内的文本,使用 q 退出。

系统命令说明
Debian / Ubuntuman apt-get更新本地包数据库以及与包一起工作
man apt-cache在本地的包数据库中搜索
man dpkg和单独的包文件一起工作以及能查询已安装的包
man apt通过更简洁,用户友好的接口进行最基本的操作
CentOSman yum
Fedoraman dnf
FreeBSD Packagesman pkg和预先编译的二进制包一起工作
FreeBSD Portsman ports和 Ports 集合一起工作

结论和进一步的阅读

本指南通过对多个系统间进行交叉对比概述了一下包管理系统的基本操作,但只涉及了这个复杂主题的表面。对于特定系统更详细的信息,可以参考以下资源:


via: https://www.digitalocean.com/community/tutorials/package-management-basics-apt-yum-dnf-pkg

译者后记:

从经典的 configure && make && make install 三部曲到 dpkg,从需要手处理依赖关系的 dpkg 到全自动化的 apt-get,恩~,你有没有想过接下来会是什么?译者只能说可能会是 Snaps,如果你还没有听过这个东东,你也许需要关注下这个公众号了:Snapcraft

作者:Brennen Bearnes 译者:Snapcrafter 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

这些错误会造成很麻烦的问题,需要数小时才能解决。

当你做错事时,承认错误并不是一件容易的事,但是犯错是任何学习过程中的一部分,无论是学习走路,还是学习一种新的编程语言都是这样,比如学习 Python。

为了让初学 Python 的程序员避免犯同样的错误,以下列出了我学习 Python 时犯的三种错误。这些错误要么是我长期以来经常犯的,要么是造成了需要几个小时解决的麻烦。

年轻的程序员们可要注意了,这些错误是会浪费一下午的!

1、 可变数据类型作为函数定义中的默认参数

这似乎是对的?你写了一个小函数,比如,搜索当前页面上的链接,并可选将其附加到另一个提供的列表中。

def search_for_links(page, add_to=[]):
    new_links = page.search_for_links()
    add_to.extend(new_links)
    return add_to

从表面看,这像是十分正常的 Python 代码,事实上它也是,而且是可以运行的。但是,这里有个问题。如果我们给 add_to 参数提供了一个列表,它将按照我们预期的那样工作。但是,如果我们让它使用默认值,就会出现一些神奇的事情。

试试下面的代码:

def fn(var1, var2=[]):
    var2.append(var1)
    print var2

fn(3)
fn(4)
fn(5)

可能你认为我们将看到:

[3]
[4]
[5]

但实际上,我们看到的却是:

[3]
[3, 4]
[3, 4, 5]

为什么呢?如你所见,每次都使用的是同一个列表,输出为什么会是这样?在 Python 中,当我们编写这样的函数时,这个列表被实例化为函数定义的一部分。当函数运行时,它并不是每次都被实例化。这意味着,这个函数会一直使用完全一样的列表对象,除非我们提供一个新的对象:

fn(3, [4])
[4, 3]

答案正如我们所想的那样。要想得到这种结果,正确的方法是:

def fn(var1, var2=None):
    if not var2:
        var2 = []
    var2.append(var1)

或是在第一个例子中:

def search_for_links(page, add_to=None):
    if not add_to:
        add_to = []
    new_links = page.search_for_links()
    add_to.extend(new_links)
    return add_to

这将在模块加载的时候移走实例化的内容,以便每次运行函数时都会发生列表实例化。请注意,对于不可变数据类型,比如元组字符串整型,是不需要考虑这种情况的。这意味着,像下面这样的代码是非常可行的:

def func(message="my message"):
    print message

2、 可变数据类型作为类变量

这和上面提到的最后一个错误很相像。思考以下代码:

class URLCatcher(object):
    urls = []

    def add_url(self, url):
        self.urls.append(url)

这段代码看起来非常正常。我们有一个储存 URL 的对象。当我们调用 add\_url 方法时,它会添加一个给定的 URL 到存储中。看起来非常正确吧?让我们看看实际是怎样的:

a = URLCatcher()
a.add_url('http://www.google.com')
b = URLCatcher()
b.add_url('http://www.bbc.co.hk')

b.urls:

['http://www.google.com', 'http://www.bbc.co.uk']

a.urls:

['http://www.google.com', 'http://www.bbc.co.uk']

等等,怎么回事?!我们想的不是这样啊。我们实例化了两个单独的对象 ab。把一个 URL 给了 a,另一个给了 b。这两个对象怎么会都有这两个 URL 呢?

这和第一个错例是同样的问题。创建类定义时,URL 列表将被实例化。该类所有的实例使用相同的列表。在有些时候这种情况是有用的,但大多数时候你并不想这样做。你希望每个对象有一个单独的储存。为此,我们修改代码为:

class URLCatcher(object):
    def __init__(self):
        self.urls = []

    def add_url(self, url):
        self.urls.append(url)

现在,当创建对象时,URL 列表被实例化。当我们实例化两个单独的对象时,它们将分别使用两个单独的列表。

3、 可变的分配错误

这个问题困扰了我一段时间。让我们做出一些改变,并使用另一种可变数据类型 - 字典

a = {'1': "one", '2': 'two'}

现在,假设我们想把这个字典用在别的地方,且保持它的初始数据完整。

b = a

b['3'] = 'three'

简单吧?

现在,让我们看看原来那个我们不想改变的字典 a

{'1': "one", '2': 'two', '3': 'three'}

哇等一下,我们再看看 b

{'1': "one", '2': 'two', '3': 'three'}

等等,什么?有点乱……让我们回想一下,看看其它不可变类型在这种情况下会发生什么,例如一个元组

c = (2, 3)
d = c
d = (4, 5)

现在 c(2, 3),而 d(4, 5)

这个函数结果如我们所料。那么,在之前的例子中到底发生了什么?当使用可变类型时,其行为有点像 C 语言的一个指针。在上面的代码中,我们令 b = a,我们真正表达的意思是:b 成为 a 的一个引用。它们都指向 Python 内存中的同一个对象。听起来有些熟悉?那是因为这个问题与先前的相似。其实,这篇文章应该被称为「可变引发的麻烦」。

列表也会发生同样的事吗?是的。那么我们如何解决呢?这必须非常小心。如果我们真的需要复制一个列表进行处理,我们可以这样做:

b = a[:]

这将遍历并复制列表中的每个对象的引用,并且把它放在一个新的列表中。但是要注意:如果列表中的每个对象都是可变的,我们将再次获得它们的引用,而不是完整的副本。

假设在一张纸上列清单。在原来的例子中相当于,A 某和 B 某正在看着同一张纸。如果有个人修改了这个清单,两个人都将看到相同的变化。当我们复制引用时,每个人现在有了他们自己的清单。但是,我们假设这个清单包括寻找食物的地方。如果“冰箱”是列表中的第一个,即使它被复制,两个列表中的条目也都指向同一个冰箱。所以,如果冰箱被 A 修改,吃掉了里面的大蛋糕,B 也将看到这个蛋糕的消失。这里没有简单的方法解决它。只要你记住它,并编写代码的时候,使用不会造成这个问题的方式。

字典以相同的方式工作,并且你可以通过以下方式创建一个昂贵副本:

b = a.copy()

再次说明,这只会创建一个新的字典,指向原来存在的相同的条目。因此,如果我们有两个相同的列表,并且我们修改字典 a 的一个键指向的可变对象,那么在字典 b 中也将看到这些变化。

可变数据类型的麻烦也是它们强大的地方。以上都不是实际中的问题;它们是一些要注意防止出现的问题。在第三个项目中使用昂贵复制操作作为解决方案在 99% 的时候是没有必要的。你的程序或许应该被改改,所以在第一个例子中,这些副本甚至是不需要的。

编程快乐!在评论中可以随时提问。


作者简介:

Pete Savage - Peter 是一位充满激情的开源爱好者,在过去十年里一直在推广和使用开源产品。他从 Ubuntu 社区开始,在许多不同的领域自愿参与音频制作领域的研究工作。在职业经历方面,他起初作为公司的系统管理员,大部分时间在管理和建立数据中心,之后在 Red Hat 担任 CloudForms 产品的主要测试工程师。


via: https://opensource.com/article/17/6/3-things-i-did-wrong-learning-python

作者:Pete Savage 译者:polebug 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

7 月 19 日是 开放容器计划 Open Container Initiative (OCI)的一个重要里程碑,OCI 发布了容器运行时和镜像规范的 1.0 版本,而 Docker 在这过去两年中一直充当着推动和引领的核心角色。我们的目标是为社区、客户以及更广泛的容器行业提供底层的标准。要了解这一里程碑的意义,我们先来看看 Docker 在开发容器技术行业标准方面的成长和发展历史。

Docker 将运行时和镜像捐赠给 OCI 的历史回顾

Docker 的镜像格式和容器运行时在 2013 年作为开源项目发布后,迅速成为事实上的标准。我们认识到将其转交给中立管理机构管理,以加强创新和防止行业碎片化的重要性。我们与广泛的容器技术人员和行业领导者合作,成立了 开放容器项目 Open Container Project 来制定了一套容器标准,并在 Linux 基金会的支持下,于 2015 年 6 月在 Docker 大会 DockerCon 上推出。最终在那个夏天演变成为 开放容器计划 Open Container Initiative (OCI)。

Docker 贡献了 runc ,这是从 Docker 员工 Michael Crosby 的 libcontainer 项目中发展而来的容器运行时参考实现。 runc 是描述容器生命周期和运行时行为的运行时规范的基础。runc 被用在数千万个节点的生产环境中,这比任何其它代码库都要大一个数量级。runc 已经成为运行时规范的参考实现,并且随着项目的进展而不断发展。

在运行时规范制定工作开始近一年后,我们组建了一个新的工作组来制定镜像格式的规范。 Docker 将 Docker V2 镜像格式捐赠给 OCI 作为镜像规范的基础。通过这次捐赠,OCI 定义了构成容器镜像的数据结构(原始镜像)。定义容器镜像格式是一个至关重要的步骤,但它需要一个像 Docker 这样的平台通过定义和提供构建、管理和发布镜像的工具来实现它的价值。 例如,Dockerfile 等内容并不包括在 OCI 规范中。

Docker 为 OCI 贡献的历史

开放容器标准化之旅

这个规范已经持续开发了两年。随着代码的重构,更小型的项目已经从 runc 参考实现中脱颖而出,并支持即将发布的认证测试工具。

有关 Docker 参与塑造 OCI 的详细信息,请参阅上面的时间轴,其中包括:创建 runc ,和社区一起更新、迭代运行时规范,创建 containerd 以便于将 runc 集成到 Docker 1.11 中,将 Docker V2 镜像格式贡献给 OCI 作为镜像格式规范的基础,并在 containerd 中实现该规范,使得该核心容器运行时同时涵盖了运行时和镜像格式标准,最后将 containerd 捐赠给了 云计算基金会 Cloud Native Computing Foundation (CNCF),并于本月发布了更新的 1.0 alpha 版本。

维护者 Michael CrosbyStephen Day 引导了这些规范的发展,并且为 v1.0 版本的实现提供了极大的帮助,另外 Alexander Morozov,Josh Hawn,Derek McGown 和 Aaron Lehmann 也贡献了代码,以及 Stephen Walli 参加了认证工作组。

Docker 仍然致力于推动容器标准化进程,在每个人都认可的层面建立起坚实的基础,使整个容器行业能够在依旧十分差异化的层面上进行创新。

开放标准只是一小块拼图

Docker 是一个完整的平台,用于创建、管理、保护和编排容器以及镜像。该项目的愿景始终是致力于成为支持开源组件的行业规范的基石,或着是容器解决方案的校准铅锤。Docker 平台正位于此层之上 -- 为客户提供从开发到生产的安全的容器管理解决方案。

OCI 运行时和镜像规范成为一个可靠的标准基础,允许和鼓励多样化的容器解决方案,同时它们不限制产品创新或遏制主要开发者。打一个比方,TCP/IP、HTTP 和 HTML 成为过去 25 年来建立万维网的可靠标准,其他公司可以继续通过这些标准的新工具、技术和浏览器进行创新。 OCI 规范也为容器解决方案提供了类似的规范基础。

开源项目也在为产品开发提供组件方面发挥着作用。containerd 项目就使用了 OCI 的 runc 参考实现,它负责镜像的传输和存储,容器运行和监控,以及支持存储和网络附件的等底层功能。containerd 项目已经被 Docker 捐赠给了 CNCF ,与其他重要项目一起支持云计算解决方案。

Docker 使用了 containerd 和其它自己的核心开源基础设施组件,如 LinuxKit,InfraKit 和 Notary 等项目来构建和保护 Docker 社区版容器解决方案。正在寻找一个能提供容器管理、安全性、编排、网络和更多功能的完整容器平台的用户和组织可以了解下 Docker Enterprise Edition 。

Docker 栈

这张图强调了 OCI 规范提供了一个由容器运行时实现的标准层:containerd 和 runc。 要组装一个完整的像 Docker 这样具有完整容器生命周期和工作流程的容器平台,需要和许多其他的组件集成在一起:管理基础架构的 InfraKit,提供操作系统的 LinuxKit,交付编排的 SwarmKit,确保安全性的 Notary。

OCI 下一步该干什么

随着运行时和镜像规范的发布,我们应该庆祝开发者的努力。开放容器计划的下一个关键工作是提供认证计划,以验证实现者的产品和项目确实符合运行时和镜像规范。认证工作组 已经组织了一个程序,结合了 开发套件 developing suite 运行时镜像规范测试工具将展示产品应该如何参照标准进行实现。

同时,当前规范的开发者们正在考虑下一个最重要的容器技术领域。云计算基金会的通用容器网络接口开发工作已经正在进行中,支持镜像签署和分发的工作正也在 OCI 的考虑之中。

除了 OCI 及其成员,Docker 仍然致力于推进容器技术的标准化。 OCI 的使命是为用户和公司提供在开发者工具、镜像分发、容器编排、安全、监控和管理等方面进行创新的基准。Docker 将继续引领创新,不仅提供提高生产力和效率的工具,而且还通过授权用户,合作伙伴和客户进行创新。

在 Docker 学习更过关于 OCI 和开源的信息:

(题图:vox-cdn.com)


作者简介:

Patrick Chanezon 是 Docker Inc. 技术人员。他的工作是帮助构建 Docker 。一个程序员和讲故事的人 (storyller),他在 Netscape 和 Sun 工作了10年的时间,又在Google,VMware 和微软工作了10年。他的主要职业兴趣是为这些奇特的双边市场“平台”建立和推动网络效应。他曾在门户网站,广告,电商,社交,Web,分布式应用和云平台上工作过。有关更多信息,请访问 linkedin.com/in/chanezon 和他的推特 @chanezon。


via: https://blog.docker.com/2017/07/oci-release-of-v1-0-runtime-and-image-format-specifications/

作者:Patrick Chanezon 译者:rieonke 校对:校对者ID

本文由 LCTT 原创编译,Linux中国 荣誉推出

本指南将向你介绍如何使用 Authconfig 在命令行中将无图形界面的 CentOS 7 服务器集成到 Samba4 AD 域控制器中。

这类设置提供了由 Samba 持有的单一集中式帐户数据库,允许 AD 用户通过网络基础设施对 CentOS 服务器进行身份验证。

要求

  1. 在 Ubuntu 上使用 Samba4 创建 AD 基础架构
  2. CentOS 7.3 安装指南

步骤 1:为 Samba4 AD DC 配置 CentOS

1、 在开始将 CentOS 7 服务器加入 Samba4 DC 之前,你需要确保网络接口被正确配置为通过 DNS 服务查询域。

运行 ip address 命令列出你机器网络接口,选择要编辑的特定网卡,通过针对接口名称运行 nmtui-edit 命令(如本例中的 ens33),如下所示。

# ip address
# nmtui-edit ens33

List Network Interfaces

列出网络接口

2、 打开网络接口进行编辑后,添加最适合 LAN 的静态 IPv4 配置,并确保为 DNS 服务器设置 Samba AD 域控制器 IP 地址。

另外,在搜索域中追加你的域的名称,并使用 [TAB] 键跳到确定按钮来应用更改。

当你仅对域 dns 记录使用短名称时, 已提交的搜索域保证域对应项会自动追加到 dns 解析 (FQDN) 中。

Configure Network Interface

配置网络接口

3、最后,重启网络守护进程以应用更改,并通过对域名和域控制器 ping 来测试 DNS 解析是否正确配置,如下所示。

# systemctl restart network.service
# ping -c2 tecmint.lan
# ping -c2 adc1
# ping -c2 adc2

Verify DNS Resolution on Domain

验证域上的 DNS 解析

4、 另外,使用下面的命令配置你的计算机主机名并重启机器应用更改。

# hostnamectl set-hostname your_hostname
# init 6

使用以下命令验证主机名是否正确配置。

# cat /etc/hostname
# hostname

5、 最后,使用 root 权限运行以下命令,与 Samba4 AD DC 同步本地时间。

# yum install ntpdate
# ntpdate domain.tld

Sync Time with Samba4 AD DC

与 Samba4 AD DC 同步时间

步骤 2:将 CentOS 7 服务器加入到 Samba4 AD DC

6、 要将 CentOS 7 服务器加入到 Samba4 AD 中,请先用具有 root 权限的帐户在计算机上安装以下软件包。

# yum install authconfig samba-winbind samba-client samba-winbind-clients

7、 为了将 CentOS 7 服务器与域控制器集成,可以使用 root 权限运行 authconfig-tui,并使用下面的配置。

# authconfig-tui

首屏选择:

  • 在 User Information 中:

    • Use Winbind
  • 在 Authentication 中使用[空格键]选择:

    • Use Shadow Password
    • Use Winbind Authentication
    • Local authorization is sufficient

Authentication Configuration

验证配置

8、 点击 Next 进入 Winbind 设置界面并配置如下:

  • Security Model: ads
  • Domain = YOUR\_DOMAIN (use upper case)
  • Domain Controllers = domain machines FQDN (comma separated if more than one)
  • ADS Realm = YOUR\_DOMAIN.TLD
  • Template Shell = /bin/bash

Winbind Settings

Winbind 设置

9、 要加入域,使用 [tab] 键跳到 “Join Domain” 按钮,然后按[回车]键加入域。

在下一个页面,添加具有提升权限的 Samba4 AD 帐户的凭据,以将计算机帐户加入 AD,然后单击 “OK” 应用设置并关闭提示。

请注意,当你输入用户密码时,凭据将不会显示在屏幕中。在下面再次点击 OK,完成 CentOS 7 的域集成。

Join Domain to Samba4 AD DC

加入域到 Samba4 AD DC

Confirm Winbind Settings

确认 Winbind 设置

要强制将机器添加到特定的 Samba AD OU 中,请使用 hostname 命令获取计算机的完整名称,并使用机器名称在该 OU 中创建一个新的计算机对象。

将新对象添加到 Samba4 AD 中的最佳方法是已经集成到安装了 RSAT 工具的域的 Windows 机器上使用 ADUC 工具。

重要:加入域的另一种方法是使用 authconfig 命令行,它可以对集成过程进行广泛的控制。

但是,这种方法很容易因为其众多参数造成错误,如下所示。该命令必须输入一条长命令行。

# authconfig --enablewinbind --enablewinbindauth --smbsecurity ads --smbworkgroup=YOUR_DOMAIN --smbrealm YOUR_DOMAIN.TLD --smbservers=adc1.yourdomain.tld --krb5realm=YOUR_DOMAIN.TLD --enablewinbindoffline --enablewinbindkrb5 --winbindtemplateshell=/bin/bash--winbindjoin=domain_admin_user --update  --enablelocauthorize   --savebackup=/backups

10、 机器加入域后,通过使用以下命令验证 winbind 服务是否正常运行。

# systemctl status winbind.service

11、 接着检查是否在 Samba4 AD 中成功创建了 CentOS 机器对象。从安装了 RSAT 工具的 Windows 机器使用 AD 用户和计算机工具,并进入到你的域计算机容器。一个名为 CentOS 7 Server 的新 AD 计算机帐户对象应该在右边的列表中。

12、 最后,使用文本编辑器打开 samba 主配置文件(/etc/samba/smb.conf)来调整配置,并在 [global] 配置块的末尾附加以下行,如下所示:

winbind use default domain = true
winbind offline logon = true

Configure Samba

配置 Samba

13、 为了在 AD 帐户首次登录时在机器上创建本地家目录,请运行以下命令:

# authconfig --enablemkhomedir --update

14、 最后,重启 Samba 守护进程使更改生效,并使用一个 AD 账户登陆验证域加入。AD 帐户的家目录应该会自动创建。

# systemctl restart winbind
# su - domain_account

Verify Domain Joining

验证域加入

15、 通过以下命令之一列出域用户或域组。

# wbinfo -u
# wbinfo -g

List Domain Users and Groups

列出域用户和组

16、 要获取有关域用户的信息,请运行以下命令。

# wbinfo -i domain_user

List Domain User Info

列出域用户信息

17、 要显示域摘要信息,请使用以下命令。

# net ads info

List Domain Summary

列出域摘要

步骤 3:使用 Samba4 AD DC 帐号登录CentOS

18、 要在 CentOS 中与域用户进行身份验证,请使用以下命令语法之一。

# su - ‘domain\domain_user’
# su - domain\\domain_user

或者在 samba 配置文件中设置了 winbind use default domain = true 参数的情况下,使用下面的语法。

# su - domain_user
# su - [email protected]

19、 要为域用户或组添加 root 权限,请使用 visudocommand 编辑 sudoers 文件,并添加以下截图所示的行。

YOUR_DOMAIN\\domain_username             ALL=(ALL:ALL) ALL      #For domain users
%YOUR_DOMAIN\\your_domain\  group            ALL=(ALL:ALL) ALL  #For domain groups

或者在 samba 配置文件中设置了 winbind use default domain = true 参数的情况下,使用下面的语法。

domain_username                  ALL=(ALL:ALL) ALL      #For domain users
%your_domain\  group             ALL=(ALL:ALL) ALL  #For domain groups

Grant Root Privileges on Domain Users

授予域用户 root 权限

20、 针对 Samba4 AD DC 的以下一系列命令也可用于故障排除:

# wbinfo -p #Ping domain
# wbinfo -n domain_account #Get the SID of a domain account
# wbinfo -t  #Check trust relationship

21、 要离开该域, 请使用具有提升权限的域帐户对你的域名运行以下命令。从 AD 中删除计算机帐户后, 重启计算机以在集成进程之前还原更改。

# net ads leave -w DOMAIN -U domain_admin
# init 6

就是这样了!尽管此过程主要集中在将 CentOS 7 服务器加入到 Samba4 AD DC 中,但这里描述的相同步骤也适用于将 CentOS 服务器集成到 Microsoft Windows Server 2012 AD 中。


作者简介:

Matei Cezar - 我是一个电脑上瘾的家伙,开源和基于 linux 的系统软件的粉丝,在 Linux 发行版桌面、服务器和 bash 脚本方面拥有大约 4 年的经验。


via: https://www.tecmint.com/integrate-centos-7-to-samba4-active-directory/

作者:Matei Cezar 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出