这里，我们很荣幸地宣布 Fedora 31 的发布。感谢成千上万的 Fedora 社区成员和贡献者的辛勤工作，我们现在正在庆祝又一次的准时发布。这已成为一种惯例！如果你只想立即获取它，请立即访问 https://getfedora.org/。要了解详细信息，请继续阅读！工具箱如果你还没有使用过 Fedora 工具箱，那么现在是尝试一下的好时机。这是用于启动和管理个人工作区容器的简单工具，你可以在一个单独的环境中进行开发或试验。它只需要在命令行运行 toolbox enter 就行。这种容器化的工作流程对于基于 ostree 的 Fedora 变体（如 CoreOS、IoT 和 Silverblue）的用户至关重要，但在任何工作站甚至服务器系统上也非常有用。在接下来的几个月中，希望对该工具及其相关的用户体验进行更多增强，非常欢迎你提供反馈。Fedora 风味版Fedora 的“版本”是针对特定的“展示柜”用途输出的。Fedora 工作站版本专注于台式机，以及希望获得“可以工作的” Linux 操作系统体验的特定软件开发人员。此版本具有 GNOME 3.34，它带来了显著的性能增强，在功耗较低的硬件上尤其明显。Fedora 服务器版本以易于部署的方式为系统管理员带来了最新的、最先进的开源服务器软件。而且，我们还有处于预览状态下的 Fedora CoreOS（一个定义了现代容器世界分类的操作系统）和Fedora IoT（用于“边缘计算”用例）。（敬请期待计划中的给该物联网版本的征集名称的活动！）当然，我们不仅仅提供的是各种版本。还有面向各种受众和用例的 Fedora Spins 和 Labs，包括 Fedora 天文学 版本，为业余和专业的天文学家带来了完整的开源工具链，以及支持各种桌面环境（例如 KDE Plasma 和 Xfce）。而且，请不要忘记我们的替代架构 ARM AArch64、Power 和 S390x。特别要注意的是，我们对包括 Rock960、RockPro64 和 Rock64 在内的 Rockchip 片上系统设备的支持得到了改善，并初步支持了 “panfrost”，这是一种较新的开源 3D 加速图形驱动程序 Arm Mali midgard GPU。不过，如果你使用的是只支持 32 位的 i686 旧系统，那么该找个替代方案了，我们的基本系统告别了 32 位 Intel 架构。常规改进无论你使用哪种 Fedora 版本，你都将获得开源世界所提供的最新版本。遵循 “First” 准则，我们启用了 CgroupsV2（如果你使用的是 Docker，请确保检查一下）。Glibc 2.30 和 NodeJS 12 是 Fedora 31 中许多更新的软件包之一。而且，我们已经将 python 命令切换为 Python 3，请记住，Python 2 在今年年底生命期就终止了。我们很高兴你能试用新版本！转到 https://getfedora.org/ 并立即下载吧。或者，如果你已经在运行 Fedora 操作系统，请遵循简单的升级说明就行。万一出现问题……如果遇到问题，请查看 Fedora 31 常见错误页面，如果有疑问，请访问我们的 Ask Fedora 用户支持平台。谢谢大家感谢在此发行周期中成千上万为 Fedora 项目做出贡献的人们，尤其是那些为使该发行版再次按时发行而付出更多努力的人。而且，如果你本周在波特兰参加 USENIX LISA，请在博览会大厅，在 Red Hat、Fedora 和 CentOS 展位找到我。via: https://fedoramagazine.org/announcing-fedora-31/作者：Matthew Miller 选题：lujun9972 译者：wxy 校对：wxy本文由 LCTT 原创编译，Linux中国 荣誉推出
2019 年最可怕的黑客事件与安全漏洞（下）
是的，这是年终摘要文章之一。这是一篇很长的文章，因为就网络安全新闻来说，2019 年就是一场灾难，每周都会有一个或多个重大事件发生。以下是按月组织的过去 10 个月安全灾难的摘要。七月哈萨克斯坦政府拦截了所有本地 HTTPS 流量：HTTPS 拦截工作针对 Facebook，Google，Twitter 和其他站点。苹果、谷歌和 Mozilla 最终干预并禁止了用于 HTTPS 中间人攻击的证书。黑客窃取了数百万保加利亚人的数据：一名黑客窃取了数百万保加利亚人的个人详细信息，并将窃取的数据的下载链接通过电子邮件发送给了本地新闻出版物。该数据窃取自该国国家税务局，最终在网上泄露。黑客侵入了 FSB 的承包商：黑客侵入了俄罗斯国家情报局 FSB 的承包商 SyTech，他们从那里窃取了该公司代表该机构开展的内部项目的信息，包括将 Tor 流量匿名化的信息。iMessages 可能使你的 iPhone 变砖：该漏洞在被广泛利用之前得到了修补。Urgent/11 安全漏洞：TCP 库中的主要错误影响了路由器、打印机、SCADA、医疗设备和许多 IoT 设备。苹果公司的 AWDL 协议受到安全漏洞的困扰：苹果公司在五月份修补了一个错误，但学者说，其余的漏洞需要重新设计某些苹果服务。错误会启用跟踪和中间人攻击。DHS 警告小型飞机的 CAN 总线漏洞：DHS 网络安全机构 CISA 建议这些小型飞机的所有者“尽其所能”限制对飞机的访问，以防止这个漏洞可能被用来破坏飞机。GE 麻醉机中发现的漏洞：GE 建议设备所有者不要将脆弱的麻醉机连接到医院的主要网络。该公司否认这些漏洞可能导致患者受到伤害，但后来撤回该说法并承认这些问题可能对人类生命构成危险。洛杉矶警方陷入数据泄露：黑客窃取了 2500 多名洛杉矶警察的个人记录。黑客直接通过电子邮件发送给该部门，并提供了一些据称是被盗信息的样本以支持他们的说法。路易斯安那州州长在当地勒索软件爆发后宣布州紧急状态：是的。勒索软件变得非常糟糕。然后它袭击了德克萨斯州、牙医办公室和托管服务提供商。蓝牙漏洞利用可以跟踪和识别 iOS、微软移动设备用户：尽管存在本机操作系统保护但该漏洞可用于监视用户，它影响 Windows 10、iOS 和 macOS 计算机上的蓝牙设备。其中包括 iPhone、iPad、Apple Watch、MacBook 和微软的平板电脑和笔记本电脑。“7-11” 日本的客户由于移动应用漏洞而损失了 50 万美元：7-11 最终关闭了该应用。八月SWAPGSAttack CPU 漏洞：研究人员详细介绍了该硬件漏洞，它绕过了 Windows 系统上针对 Spectre 和 Meltdown CPU 漏洞的缓解措施，并影响了所有使用自 2012 年以来制造的英特尔处理器的系统。新的 Dragonblood 漏洞：今年四月初，两名安全研究人员披露了 WiFi 联盟最近发布的 WPA3 WiFi 安全和身份验证标准中五个漏洞（统称为 Dragonblood）的详细信息。14 个 iOS 零日漏洞：自 2016 年 9 月以来，谷歌发现了针对 14 个 iOS 漏洞的攻击，这些漏洞分为五个漏洞利用链，并已被广泛部署。VPN 安全漏洞：黑客对 Pulse Secure 和 Fortinet VPN 发起攻击。Windows CTF 漏洞：Microsoft CTF 协议中的漏洞可以追溯到 Windows XP。该错误允许黑客劫持任何 Windows 应用，逃脱沙箱并获得管理员权限。WS-Discovery 协议被滥用于 DDoS 攻击：该协议被 DDoS 租用服务所利用，已在实际攻击中使用。Capitol One 黑客事件：一名黑客侵入了 Capitol One，从那里窃取了 1 亿用户的记录。她还入侵了其他 30 家公司。Hy-Vee 卡泄露：超市连锁店 Hy-Vee 承认其某些 PoS 系统存在安全漏洞。该数据最终被在黑客论坛上出售。 员工将核电厂连接到互联网，以便他们可以开采加密货币：乌克兰核电厂的员工为了开采比特币而承担了不必要的安全风险。他们最终被捕。莫斯科的区块链投票系统在大选前一个月就被攻破了：法国研究人员因在基于以太坊的投票系统中发现漏洞而获得 15000 美元的奖金。美国军方购买了价值 3280 万美元的具有已知安全风险的电子产品：国防部购买的易受攻击产品包括 Lexmark 打印机、GoPro相机和联想计算机。AT＆T 员工受贿以在公司网络上植入恶意软件：美国司法部指控巴基斯坦男子贿赂 AT＆T 员工超过 100 万美元，以在该公司网络上安装恶意软件，解锁超过 200 万台设备。Windows 恶意软件会记录用户在成人网站上的访问：新的 Varenyky 木马会记录用户浏览成人网站的桌面视频。当前仅针对法国用户。TrickBot 木马具备协助 SIM 交换攻击的功能：TrickBot 木马可以收集 Sprint、T-Mobile 和 Verizon Wireless 帐户的凭据和 PIN 码。战争技术：黑客可以使用包裹传递服务将黑客设备直接运送到你公司的门口。Instagram 踢掉了广告合作伙伴 Hyp3r：Instagram 发现该广告合作伙伴收集其用户数据。九月Simjacker 攻击：安全研究人员详细介绍了一种基于 SMS 的攻击，该攻击可以通过滥用 SIM 卡上运行的鲜为人知的应用程序，使恶意行为者可以跟踪用户的设备。发现 29 个国家/地区的 SIM 卡受到了影响。 还发现了第二起名为 WIBAttack 的攻击。智能电视间谍活动：两项学术论文发现，智能电视正在收集有关用户的电视观看习惯的数据。Checkm8 iOS 越狱：针对所有运行 A5 至 A11 芯片的 iOS 设备（在 iPhone 4S 以及 iPhone 8 和 X 上）发布的新 Checkm8 越狱。过去九年来，这是第一个在硬件级别起作用的越狱漏洞。数据库泄漏了厄瓜多尔大多数公民的数据：Elasticsearch 服务器泄漏了有关厄瓜多尔公民其家谱和孩子的个人数据，还泄漏了一些用户的财务记录和汽车登记信息。该公司高管随后被捕。Limin PDF 泄露事件：九月中旬，超过 2430 万 Lumin PDF 的用户详细信息在黑客论坛上被分享。该公司在第二天承认这次泄露。Heyyo 约会应用程序泄漏事件：他们泄漏了除私人消息以外的几乎所有内容。vBulletin 零日漏洞和随后的黑客攻击：一位匿名安全研究人员发布了 vBulletin 论坛软件中的零日漏洞。该漏洞立即被黑客用于入侵一系列论坛。大量的帐户劫持事件袭击了 YouTube 创作者：汽车社区的 YouTube 创作者遭受了鱼叉式网络钓鱼攻击，这些攻击可以绕过 2FA，从而使黑客可以接管其 Google 和 YouTube 帐户。Lilocked（Lilu）勒索软件：成千上万的 Linux 服务器感染了新的 Lilocked（Lilu）勒索软件。超过 47,000 台超微服务器正在互联网上暴露了其 BMC 端口：研究人员在超微服务器上发现了一个新的远程攻击方式，发现它在互联网上暴露了其 BMC 端口。勒索软件事件给公司造成了高达 9500 万美元的损失：丹麦制造助听器 Demant 的勒索软件事件造成了近 9500 万美元的损失，这是迄今为止最昂贵的事件之一。Exim 漏洞（CVE-2019-15846）：数百万的 Exim 服务器容易受到一个安全漏洞的攻击，利用该漏洞可以使攻击者能够以 root 特权运行恶意代码。十月Avast 黑客事件：这家捷克的杀毒软件制造商在 2017 年遭受攻击之后，披露了其受到了第二次攻击，旨在破坏 CCleaner 版本。该公司表示，黑客通过受损的 VPN 配置文件破坏了该公司。被广泛利用的 Android 零日漏洞：Google Project Zero 研究人员发现了被广泛利用的 Android 零日漏洞，影响了 Pixel、三星、华为、小米设备。Alexa 和 Google Home 设备再次被利用来网络钓鱼和窃听用户：亚马逊、Google 在首次报告后一年多未能解决 Alexa 和 Home 设备中的安全漏洞。捷克当局拆除了据称是俄罗斯的网络间谍网络：捷克官员说，俄罗斯特工利用当地公司对外国目标发起网络攻击。官员们表示，运营得到了俄罗斯国家情报局 FSB 的支持以及当地大使馆的财政帮助。约翰内斯堡被黑客团伙勒索赎金：一个名为“Shadow Kill Hackers”的组织正在向当地官员索要 4 枚比特币，否则他们将在线发布该城市数据。这是在七月遭到勒索软件攻击之后对约翰内斯堡的第二次重大袭击，当时导致一些当地居民断电。CPDoS 攻击事件：CloudFront、Cloudflare、Fastly、Akamai 等受到新的 CPDoS Web 缓存中毒攻击的影响。被广泛利用的 PHP7 RCE：新的 PHP7 错误 CVE-2019-11043 甚至可以使非技术攻击者接管运行 PHP-FPM 模块的 Nginx 服务器。遭受 DDoS 攻击的 macOS 系统：多达 4 万个 macOS 系统在线暴露了一个特定的端口，该端口可能被滥用于相当大的 DDoS 攻击。
早在 2015 年，Brian Will 撰写了一篇有挑衅性的博客：面向对象编程：一个灾难故事。他随后发布了一个名为面向对象编程很糟糕的视频，该视频更加详细。我建议你花些时间观看视频，下面是我的一段总结：OOP 的柏拉图式理想是一堆相互解耦的对象，它们彼此之间发送无状态消息。没有人真的像这样制作软件，Brian 指出这甚至没有意义：对象需要知道向哪个对象发送消息，这意味着它们需要相互引用。该视频大部分讲述的是这样一个痛点：人们试图将对象耦合以实现控制流，同时假装它们是通过设计解耦的。总的来说，他的想法与我自己的 OOP 经验产生了共鸣：对象没有问题，但是我一直不满意的是面向对象建模程序控制流，并且试图使代码“正确地”面向对象似乎总是在创建不必要的复杂性。有一件事我认为他无法完全解释。他直截了当地说“封装没有作用”，但在脚注后面加上“在细粒度的代码级别”，并继续承认对象有时可以奏效，并且在库和文件级别封装是可以的。但是他没有确切解释为什么有时会奏效，有时却没有奏效，以及如何和在何处划清界限。有人可能会说这使他的 “OOP 不好”的说法有缺陷，但是我认为他的观点是正确的，并且可以在根本状态和偶发状态之间划清界限。如果你以前从未听说过“ 根本 essential ”和“ 偶发 accidental ”这两个术语的使用，那么你应该阅读 Fred Brooks 的经典文章《没有银弹》。（顺便说一句，他写了许多很棒的有关构建软件系统的文章。）我以前曾写过关于根本和偶发的复杂性的文章，这里有一个简短的摘要：软件是复杂的。部分原因是因为我们希望软件能够解决混乱的现实世界问题，因此我们将其称为“根本复杂性”。“偶发复杂性”是所有其它的复杂性，因为我们正尝试使用硅和金属来解决与硅和金属无关的问题。例如，对于大多数程序而言，用于内存管理或在内存与磁盘之间传输数据或解析文本格式的代码都是“偶发的复杂性”。假设你正在构建一个支持多个频道的聊天应用。消息可以随时到达任何频道。有些频道特别有趣，当有新消息传入时，用户希望得到通知。而其他频道静音：消息被存储，但用户不会受到打扰。你需要跟踪每个频道的用户首选设置。一种实现方法是在频道和频道设置之间使用 映射 map （也称为哈希表、字典或关联数组）。注意，映射是 Brian Will 所说的可以用作对象的抽象数据类型（ADT）。如果我们有一个调试器并查看内存中的映射对象，我们将看到什么？我们当然会找到频道 ID 和频道设置数据（或至少指向它们的指针）。但是我们还会找到其它数据。如果该映射是使用红黑树实现的，我们将看到带有红/黑标签和指向其他节点的指针的树节点对象。与频道相关的数据是根本状态，而树节点是偶发状态。不过，请注意以下几点：该映射有效地封装了它的偶发状态 —— 你可以用 AVL 树实现的另一个映射替换该映射，并且你的聊天程序仍然可以使用。另一方面，映射没有封装根本状态（仅使用 get() 和 set() 方法访问数据并不是封装）。事实上，映射与根本状态是尽可能不可知的，你可以使用基本相同的映射数据结构来存储与频道或通知无关的其他映射。这就是映射 ADT 如此成功的原因：它封装了偶发状态，并与根本状态解耦。如果你思考一下，Brian 用封装描述的问题就是尝试封装根本状态。其他描述的好处是封装偶发状态的好处。要使整个软件系统都达到这一理想状况相当困难，但扩展开来，我认为它看起来像这样：没有全局的可变状态封装了偶发状态（在对象或模块或以其他任何形式）无状态偶发复杂性封装在单独函数中，与数据解耦使用诸如依赖注入之类的技巧使输入和输出变得明确组件可由易于识别的位置完全拥有和控制其中有些违反了我很久以来的直觉。例如，如果你有一个数据库查询函数，如果数据库连接处理隐藏在该函数内部，并且唯一的参数是查询参数，那么接口会看起来会更简单。但是，当你使用这样的函数构建软件系统时，协调数据库的使用实际上变得更加复杂。组件不仅以自己的方式做事，而且还试图将自己所做的事情隐藏为“实现细节”。数据库查询需要数据库连接这一事实从来都不是实现细节。如果无法隐藏某些内容，那么显露它是更合理的。我对将面向对象编程和函数式编程放在对立的两极非常警惕，但我认为从函数式编程进入面向对象编程的另一极端是很有趣的：OOP 试图封装事物，包括无法封装的根本复杂性，而纯函数式编程往往会使事情变得明确，包括一些偶发复杂性。在大多数时候，这没什么问题，但有时候（比如在纯函数式语言中构建自我指称的数据结构）设计更多的是为了函数编程，而不是为了简便（这就是为什么 Haskell 包含了一些“ 逃生出口 escape hatches ”）。我之前写过一篇所谓“ 弱纯性 weak purity ”的中间立场。Brian 发现封装对更大规模有效，原因有几个。一个是，由于大小的原因，较大的组件更可能包含偶发状态。另一个是“偶发”与你要解决的问题有关。从聊天程序用户的角度来看，“偶发的复杂性”是与消息、频道和用户等无关的任何事物。但是，当你将问题分解为子问题时，更多的事情就变得“根本”。例如，在解决“构建聊天应用”问题时，可以说频道名称和频道 ID 之间的映射是偶发的复杂性，而在解决“实现 getChannelIdByName() 函数”子问题时，这是根本复杂性。因此，封装对于子组件的作用比对父组件的作用要小。顺便说一句，在视频的结尾，Brian Will 想知道是否有任何语言支持无法访问它们所作用的范围的匿名函数。D 语言可以。 D 中的匿名 Lambda 通常是闭包，但是如果你想要的话，也可以声明匿名无状态函数：import std.stdio; void main() { int x = 41; // Value from immediately executed lambda auto v1 = () { return x + 1; }(); writeln(v1); // Same thing auto v2 = delegate() { return x + 1; }(); writeln(v2); // Plain functions aren't closures auto v3 = function() { // Can't access x // Can't access any mutable global state either if also marked pure return 42; }(); writeln(v3); }via: https://theartofmachinery.com/2019/10/13/oop_and_essential_state.html作者：Simon Arneaud 选题：lujun9972 译者：geekpi 校对：wxy本文由 LCTT 原创编译，Linux中国 荣誉推出
了解如何使用 Ansible 在容器中执行命令。容器和 Ansible 可以很好地融合在一起：从管理和编排到供应和构建。在本文中，我们将重点介绍构建部分。如果你熟悉 Ansible，就会知道你可以编写一系列任务，ansible-playbook 命令将为你执行这些任务。你知道吗，如果你编写 Dockerfile 并运行 podman build，你还可以在容器环境中执行此类命令，并获得相同​​的结果。这是一个例子：- name: Serve our file using httpd hosts: all tasks: - name: Install httpd package: name: httpd state: installed - name: Copy our file to httpd’s webroot copy: src: our-file.txt dest: /var/www/html/你可以在 Web 服务器本地或容器中执行这个剧本，并且只要你记得先创建 our-file.txt，它就可以工作。但是这里缺少了一些东西。你需要启动（并配置）httpd 以便提供文件。这是容器构建和基础架构供应之间的区别：构建镜像时，你只需准备内容；而运行容器是另一项任务。另一方面，你可以将元数据附加到容器镜像，它会默认运行命令。这有个工具可以帮助。试试看 ansible-bender 怎么样？$ ansible-bender build the-playbook.yaml fedora:30 our-httpd该脚本使用 ansible-bender 对 Fedora 30 容器镜像执行该剧本，并将生成的容器镜像命名为 our-httpd。但是，当你运行该容器时，它不会启动 httpd，因为它不知道如何操作。你可以通过向该剧本添加一些元数据来解决此问题：- name: Serve our file using httpd hosts: all vars: ansible_bender: base_image: fedora:30 target_image: name: our-httpd cmd: httpd -DFOREGROUND tasks: - name: Install httpd package: name: httpd state: installed - name: Listen on all network interfaces. lineinfile: path: /etc/httpd/conf/httpd.conf regexp: '^Listen ' line: Listen 0.0.0.0:80 - name: Copy our file to httpd’s webroot copy: src: our-file.txt dest: /var/www/html现在你可以构建镜像（从这里开始，请以 root 用户身份运行所有命令。目前，Buildah 和 Podman 不会为无 root 容器创建专用网络）：# ansible-bender build the-playbook.yaml PLAY [Serve our file using httpd] **************************************************** TASK [Gathering Facts] *************************************************************** ok: [our-httpd-20191004-131941266141-cont] TASK [Install httpd] ***************************************************************** loaded from cache: 'f053578ed2d47581307e9ba3f64f4b4da945579a082c6f99bd797635e62befd0' skipping: [our-httpd-20191004-131941266141-cont] TASK [Listen on all network interfaces.] ********************************************* changed: [our-httpd-20191004-131941266141-cont] TASK [Copy our file to httpd’s webroot] ********************************************** changed: [our-httpd-20191004-131941266141-cont] PLAY RECAP *************************************************************************** our-httpd-20191004-131941266141-cont : ok=3 changed=2 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0 Getting image source signatures Copying blob sha256:4650c04b851c62897e9c02c6041a0e3127f8253fafa3a09642552a8e77c044c8 Copying blob sha256:87b740bba596291af8e9d6d91e30a01d5eba9dd815b55895b8705a2acc3a825e Copying blob sha256:82c21252bd87532e93e77498e3767ac2617aa9e578e32e4de09e87156b9189a0 Copying config sha256:44c6dc6dda1afe28892400c825de1c987c4641fd44fa5919a44cf0a94f58949f Writing manifest to image destination Storing signatures 44c6dc6dda1afe28892400c825de1c987c4641fd44fa5919a44cf0a94f58949f Image 'our-httpd' was built successfully \o/镜像构建完毕，可以运行容器了：# podman run our-httpd AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 10.88.2.106. Set the 'ServerName' directive globally to suppress this message是否提供文件了？首先，找出你容器的 IP：# podman inspect -f '{{ .NetworkSettings.IPAddress }}' 7418570ba5a0 10.88.2.106你现在可以检查了：$ curl http://10.88.2.106/our-file.txt Ansible is ❤你文件内容是什么？这只是使用 Ansible 构建容器镜像的介绍。如果你想了解有关 ansible-bender 可以做什么的更多信息，请查看它的 GitHub 页面。构建快乐！via: https://opensource.com/article/19/10/building-container-images-ansible作者：Tomas Tomecek 选题：lujun9972 译者：geekpi 校对：wxy本文由 LCTT 原创编译，Linux中国 荣誉推出
2019 年最可怕的黑客事件与安全漏洞（上）
是的，这是年终摘要文章之一。这是一篇很长的文章，因为就网络安全新闻来说，2019 年就是一场灾难，每周都会有一个或多个重大事件发生。以下是按月组织的过去 10 个月安全灾难的摘要。一月Apple FaceTime 中的严重漏洞：Apple FaceTime 应用程序中的一个错误使攻击者可以在不与被呼叫者进行任何用户交互的情况下呼叫并自行应答 FaceTime 呼叫，从而为进行秘密监视打开了大门。在通过 Skype 面试后，朝鲜黑客渗透到智利的 ATM 网络：该文章的标题不言而喻，值得你花时间阅读该故事。黑客破坏并窃取了韩国国防部的数据：首尔政府表示，黑客破坏了 30 台计算机并窃取了 10 台计算机中的数据。被黑客入侵的计算机存储了有关武器和弹药采购的数据。 有人入侵了 PHP PEAR 网站：我们仍然不知道发生了什么，但是一些黑客侵入了 PHP PEAR 存储库，并给某个版本的 PHP PEAR 软件包管理器添加了后门。26 种低端加密货币中发现的安全漏洞：该报告显示了一些低端的不著名的加密货币的危险性，以及黑客如何随时窃取大量资金。俄克拉荷马州政府数据泄漏暴露了联邦调查局的调查记录：俄克拉荷马州证券部的服务器允许任何人下载政府文件，例如内部文件，甚至是联邦调查局的调查。被怀疑参与了全球 DNS 劫持活动的伊朗黑客：FireEye 和 Cisco Talos 先后披露了由伊朗黑客发起的全球劫持活动，伊朗黑客通过其伊朗服务器重定向了来自全球各地公司的流量，并记录了公司的凭据以备将来攻击。他们在域名注册商处入侵了 DNS 管理帐户，以执行 DNS 劫持攻击。这些黑客也入侵了希腊的顶级域名注册商。存在了 36 年之久的 SCP 软件安全漏洞：自 1983 年以来，过去 36 年中的所有 SCP（安全复制协议）软件版本均受到了四个安全漏洞的影响，这些漏洞允许恶意的 SCP 服务器对客户（用户）的系统进行未经授权的更改，并在终端隐藏其恶意操作。年度 LTE 安全漏洞：今年发现了两组新的 LTE 安全漏洞。一组影响 3G、4G 和 5G，另一组 36 个漏洞在韩国安全研究人员进行的一项模糊项目之后被发现。网站可以通过浏览器扩展 API 窃取浏览器数据：研究人员发现有将近 200 个 Chrome、Firefox 和 Opera 扩展容易受到恶意站点的攻击。WiFi 固件错误会影响笔记本电脑、智能手机、路由器、游戏设备：Marvell Avastar 芯片组中发现的重大安全漏洞。受影响的设备列表包括 PS4、Xbox One、三星 Chromebook 和微软 Surface 设备。恶意软件被发现预装在 Android 设备上：在 2019 年发生了两次。首先，在一月份，研究人员在预安装在阿尔卡特智能手机上的阿尔卡特应用程序中发现了恶意软件。其次，在六月，德国的网络安全机构在四种中国智能手机型号中发现了后门。二月重大 WinRAR 错误暴露：Check Point 研究人员发现了一个 WinRAR 错误，该错误影响了自 2000 年以来发行的所有 WinRAR 版本。超过 5 亿个 WinRAR 用户面临风险。这些漏洞最终被网络罪犯和国家黑客广泛使用。新的 WinPot 恶意软件可以使 ATM 吐出现金：WinPot 自 2018 年 3 月以来一直在地下论坛上出售。从 Tor 流量检测单个 Android 应用程序的准确性为 97％：新的机器学习算法可以通过 Tor 检测 Tor 用户何时使用了特定的应用程序，例如 YouTube、Instagram、Spotify 等。黑客抹除了电子邮件提供商 VFEmail 的美国服务器：黑客没有要求赎金。VFEmail 将事件描述为“攻击并摧毁”。Thunderclap 漏洞：该安全漏洞影响 Windows、Mac、Linux 处理 Thunderbolt 外围设备的方式。它们允许创建可能从操作系统内存中窃取数据的高度危险的恶意外围设备。PDF 协议攻击：一组德国学者发现了一种在 PDF 文档中伪造签名的方法，并在今年晚些时候找到了一种破解 PDF 加密的方法。使用 CPU 隐藏恶意软件：学者们已经找到了在使用推测执行和英特尔 SGX 安全区系统的计算机上隐藏恶意软件的方法。三月黑客在大风暴发生前将龙卷风警报器离线：是的，就是为了作恶。华硕供应链黑客事件：黑客劫持了华硕 Live Update 实用程序，以便在用户系统上部署恶意软件。黑客攻击发生在 2018 年，但在今年 3 月被披露。据信已经影响了超过一百万台 PC。GitHub 帐户环推广了 300 多个带后门的应用程序：该 GitHub 账户环由 89 个帐户组成，推广了 73 个仓库，其中包含 300 多个带有后门的 Windows、Mac 和 Linux 应用程序。Bithumb 加密货币交易所在两年内第三次被黑客入侵：据信黑客已经赚了近 2000 万美元的 EOS 和瑞波加密货币。在这一点上，Bithumb 似乎放弃挣扎了。Chrome 零日漏洞正受到活跃攻击：CVE-2019-5786（Chrome 的 FileReader API 中的一个错误）被广泛利用以从用户计算机中读取内容。谷歌表示，该漏洞是由一个国家攻击者与 Windows 7 零日漏洞一起使用的。新的英特尔 CPU 错误：研究人员发现了新的 Intel VISA（内部信号架构可视化）调试技术。法国加油站的黑客事件：加油站忘记更换加油站油泵的 PIN 之后，犯罪集团从巴黎附近的道达尔加油站偷走了 12 万升燃油。Citrix 数据泄露：Citrix 从 FBI 获悉了本次黑客攻击。黑客偷走了商业文件。Citrix 的许多客户都是政府机构和财富 500 强公司。智能手机解锁问题：我们今年遇到了一些这样的案例，但第一起案例是在三月份报道的，当时用户发现三星 Galaxy S10 面部识别可能被手机所有者的视频所欺骗。一个月后，用户发现他可以用一包口香糖解锁诺基亚 9 智能手机的指纹扫描仪。然后在十月，用户发现可以在闭着眼睛时解锁 Pixel 4 的面部解锁技术；一对夫妇发现，如果该设备由硅保护套保护，他们可以使用任何用户的手指解锁使用指纹保护的 Samsung S10 设备。实际上，绕过面部识别的问题非常普遍。去年，一家荷兰非营利组织进行的一项研究发现，攻击者可以在测试的 110 部智能手机中的 42 部中绕过面部解锁类的功能。四月美国联合航空公司盖上了座席摄像头：该航空公司坚称这些摄像头尚未投入使用；但是，客户首先仍然对该摄像头的存在感到非常不安和烦恼。由于未修复的 API，研究人员在数百个 GPS 手表的地图上显示 “PWNED!” ：超过 20 种型号的 GPS 手表允许恶意行为者跟踪设备所有者，并修改手表功能。成千上万辆汽车因使用硬编码的密码而暴露于小偷视野之中：二月中以来，MyCar 发布的 Android 和 iOS 应用程序的安全更新已删除了硬编码的密码。被勒索软件感染后，“天气”频道的播出空缺了 90 分钟：10 月对法国电视台 M6 的类似攻击未成功。Facebook 承认存储了数百万个 Instagram 用户的明文密码：该事件发生的一个月前，Facebook 也承认存储了 Facebook 帐户的明文密码。Telegram 上泄露了伊朗网络间谍工具的源代码：每天都有恶意软件开发人员使用这些工具，从而使更多用户受到攻击。五月和六月发生了第二次和第三次伊朗黑客工具泄漏。印度政府机构保留的数百万孕妇的详细信息暴露在线上：超过 1250 万孕妇医学记录被暴露。三个多星期后，泄漏的服务器中删除了记录。超过 13000 个 iSCSI 存储群集暴露在网上而没有密码：新的攻击方式在企业磁盘存储阵列和人们的 NAS 设备内部打开了后门。Gnosticplayers 的黑客事件：几个月之内，一个被称为 Gnosticplayers 的黑客在网上放出了超过 10 亿条用户记录。黑客组织已经在 D-Link 路由器上劫持了 DNS 流量达三个月：他们还针对了其他路由器型号进行了劫持，例如 ARG、DSLink、Secutech 和 TOTOLINK。这些攻击在巴西尤其活跃。五月黑客擦除了 Git 存储库，并要求赎金：成千上万的存储库受到了影响，但几乎所有项目都已恢复。对现代 CPU 的新 MDS 攻击：研究人员和学者详细介绍了新的微体系结构数据采样（MDS）攻击，例如 Zombieload、Fallout 和 RIDL。Thrangrycat 漏洞：Thrangrycat 漏洞使攻击者可以在 Cisco 设备上植入持久的后门。据信大多数 Cisco 设备都会受到影响。没有广泛检测到攻击。BlueKeep 漏洞：五月中旬，微软警告了一个新的 “可用作蠕虫的” RDP 漏洞，该漏洞后来被称为 BlueKeep。后来在八月披露了两个新的类似 BlueKeep 的可用做蠕虫的漏洞（DejaBlue）。经过数月的迫切等待之后，九月公开发布了一种概念验证攻击。不安全的服务器公开了 85％ 巴拿马公民的的数据：该服务器包含患者数据，但没有公开医疗记录，仅公开了个人身份信息（PII）。软件更新导致荷兰警察的脚踝监控器崩溃：有问题的更新阻止了脚踝监控器将数据发送回警察控制室。导致需要找到一些嫌疑人并送回监狱。以色列对空袭哈马斯的黑客首次作出回应：以色列军方称轰炸了住着哈马斯网络部队的房屋。Google 替换了有问题的 Titan 安全密钥：蓝牙配对协议中的漏洞迫使 Google 替换了在美国销售的 Titan 密钥。微软后来被迫发布了一个特殊修复程序以解决该问题。Canva 黑客事件：Gnosticplayers 的受害者之一。该公司被黑客窃取了 1.39 亿条用户记录。StackOverflow 黑客事件：Stack Overflow 表示黑客破坏了生产系统，而黑客发现已经活动了一周以上。Flipboard 黑客事件：黑客入侵的程度尚不得而知，但 Flipboard 表示，黑客已经访问其系统将近九个月的时间。伦敦地铁开始通过 Wi-Fi 热点跟踪乘客：伦敦交通局（TfL）表示，计划在未来几个月内推出一种系统，以利用伦敦地铁上的公共 Wi-Fi 热点跟踪通勤者。安全浏览器的主要错误：移动版 Chrome、Safari 和 Firefox 一年多都未能显示网络钓鱼警告。六月黑客攻击了 10 家电信供应商：Cybereason 的研究人员说，一个由国家支持的情报机构已经破坏了至少 10 家全球电信公司：在某种程度上，攻击者运行着“事实上的影子 IT 部门”。新的 Silex 恶意软件使成千上万的 IoT 设备变砖：攻击持续了数天，但黑客最终停止并撤回了 Silex 恶意软件代码。NASA 因未经授权的树莓派连接到其网络而被黑客入侵：NASA 将该黑客攻击描述为“高级持续威胁（APT）”，该术语通常用于国家黑客组织，但未提供其他详细信息。流行的 Facebook 悲伤支持页面被黑客入侵：Facebok 数周都无视了该黑客攻击。Google Nest 的摄像头可以允许前拥有者监视新拥有者：Google 最终推出了更新解决这个问题。两个 Firefox 零日漏洞：Mozilla 修复了两个 Firefox 零日漏洞[1、2] ，它们被用于攻击 Coinbase 员工。AMCA 数据泄露：去年，美国医疗保健计费供应商被黑客入侵，黑客将患者数据在线出售。该漏洞影响了多家医疗保健提供商，最终数量超过了 2000 万。CBP 说，黑客窃取了车牌和旅行者的照片：CBP 说，分包商未经授权将照片存储在其内部服务器上，然后遭到黑客攻击。HSM 重大漏洞影响着银行、云提供商、政府：两名安全研究人员透露，可以远程利用这些漏洞来检索存储在称为 HSM（硬件安全模块）的特殊计算机组件中的敏感数据。SIM 交换攻击浪潮袭击了美国加密货币用户：六月的一周，数十名美国加密货币用户认为他们是 SIM 交换攻击的受害者。
你可能已经熟悉使用 ssh 命令访问远程系统。ssh 命令背后所使用的协议允许终端的输入和输出流经安全通道。但是你知道也可以使用 ssh 来安全地发送和接收其他数据吗？一种方法是使用“ 端口转发 port forwarding ”，它允许你在进行 ssh 会话时安全地连接网络端口。本文向你展示了它是如何工作的。关于端口标准 Linux 系统已分配了一组网络端口，范围是 0 - 65535。系统会保留 0 - 1023 的端口以供系统使用。在许多系统中，你不能选择使用这些低端口号。通常有几个端口用于运行特定的服务。你可以在系统的 /etc/services 文件中找到这些定义。你可以认为网络端口是类似的物理端口或可以连接到电缆的插孔。端口可以连接到系统上的某种服务，类似物理插孔后面的接线。一个例子是 Apache Web 服务器（也称为 httpd）。对于 HTTP 非安全连接，Web 服务器通常要求在主机系统上使用端口 80，对于 HTTPS 安全连接通常要求使用 443。当你连接到远程系统（例如，使用 Web 浏览器）时，你是将浏览器“连接”到你的主机上的端口。这通常是一个随机的高端口号，例如 54001。你的主机上的端口连接到远程主机上的端口（例如 443）来访问其安全的 Web 服务器。那么，当你有这么多可用端口时，为什么还要使用端口转发呢？这是 Web 开发人员生活中的几种常见情况。本地端口转发想象一下，你正在名为 remote.example.com 的远程系统上进行 Web 开发。通常，你是通过 ssh 进入此系统的，但是它位于防火墙后面，而且该防火墙很少允许其他类型的访问，并且会阻塞大多数其他端口。要尝试你的网络应用，能够使用浏览器访问远程系统会很有帮助。但是，由于使用了讨厌的防火墙，你无法通过在浏览器中输入 URL 的常规方法来访问它。本地转发使你可以通过 ssh 连接来建立可通过远程系统访问的端口。该端口在系统上显示为本地端口（因而称为“本地转发”）。假设你的网络应用在 remote.example.com 的 8000 端口上运行。要将那个系统的 8000 端口本地转发到你系统上的 8000 端口，请在开始会话时将 -L 选项与 ssh 结合使用：$ ssh -L 8000:localhost:8000 remote.example.com等等，为什么我们使用 localhost 作为转发目标？这是因为从 remote.example.com 的角度来看，你是在要求主机使用其自己的端口 8000。（回想一下，任何主机通常可以通过网络连接 localhost 而连接到自身。）现在那个端口连接到你系统的 8000 端口了。ssh 会话准备就绪后，将其保持打开状态，然后可以在浏览器中键入 http://localhost:8000 来查看你的 Web 应用。现在，系统之间的流量可以通过 ssh 隧道安全地传输！如果你有敏锐的眼睛，你可能已经注意到了一些东西。如果我们要 remote.example.com 转发到与 localhost 不同的主机名怎么办？如果它可以访问该网络上另一个系统上的端口，那么通常可以同样轻松地转发该端口。例如，假设你想访问也在该远程网络中的 db.example.com 的 MariaDB 或 MySQL 服务。该服务通常在端口 3306 上运行。因此，即使你无法 ssh 到实际的 db.example.com 主机，你也可以使用此命令将其转发：$ ssh -L 3306:db.example.com:3306 remote.example.com现在，你可以在 localhost 上运行 MariaDB 命令，而实际上是在使用 db.example.com 主机。远程端口转发远程转发让你可以进行相反操作。想象一下，你正在为办公室的朋友设计一个 Web 应用，并想向他们展示你的工作。不过，不幸的是，你在咖啡店里工作，并且由于网络设置，他们无法通过网络连接访问你的笔记本电脑。但是，你同时使用着办公室的 remote.example.com 系统，并且仍然可在这里登录。你的 Web 应用似乎在本地 5000 端口上运行良好。远程端口转发使你可以通过 ssh 连接从本地系统建立端口的隧道，并使该端口在远程系统上可用。在开始 ssh 会话时，只需使用 -R 选项：$ ssh -R 6000:localhost:5000 remote.example.com现在，当在公司防火墙内的朋友打开浏览器时，他们可以进入 http://remote.example.com:6000 查看你的工作。就像在本地端口转发示例中一样，通信通过 ssh 会话安全地进行。默认情况下，sshd 守护进程运行在设置的主机上，因此只有该主机可以连接它的远程转发端口。假设你的朋友希望能够让其他 example.com 公司主机上的人看到你的工作，而他们不在 remote.example.com 上。你需要让 remote.example.com 主机的所有者将以下选项之一添加到 /etc/ssh/sshd_config 中：GatewayPorts yes # 或 GatewayPorts clientspecified第一个选项意味着 remote.example.com 上的所有网络接口都可以使用远程转发的端口。第二个意味着建立隧道的客户端可以选择地址。默认情况下，此选项设置为 no。使用此选项，你作为 ssh 客户端仍必须指定可以共享你这边转发端口的接口。通过在本地端口之前添加网络地址范围来进行此操作。有几种方法可以做到，包括：$ ssh -R *:6000:localhost:5000 # 所有网络 $ ssh -R 0.0.0.0:6000:localhost:5000 # 所有网络 $ ssh -R 192.168.1.15:6000:localhost:5000 # 单个网络 $ ssh -R remote.example.com:6000:localhost:5000 # 单个网络其他注意事项请注意，本地和远程系统上的端口号不必相同。实际上，有时你甚至可能无法使用相同的端口。例如，普通用户可能不会在默认设置中转发到系统端口。另外，可以限制主机上的转发。如果你需要在联网主机上更严格的安全性，那么这你来说可能很重要。 sshd 守护程进程的 PermitOpen 选项控制是否以及哪些端口可用于 TCP 转发。默认设置为 any，这让上面的所有示例都能正常工作。要禁止任何端口转发，请选择 none，或仅允许的特定的“主机:端口”。有关更多信息，请在手册页中搜索 PermitOpen 来配置 sshd 守护进程：$ man sshd_config最后，请记住，只有在 ssh 会话处于打开状态时才会端口转发。如果需要长时间保持转发活动，请尝试使用 -N 选项在后台运行会话。确保控制台已锁定，以防止在你离开控制台时其被篡夺。via: https://fedoramagazine.org/using-ssh-port-forwarding-on-fedora/作者：Paul W. Frields 选题：lujun9972 译者：geekpi 校对：wxy本文由 LCTT 原创编译，Linux中国 荣誉推出
开源世界中的每个主要发行版都在演进，逐渐将 nftables 作为了默认防火墙。换言之，古老的 iptables 现在已经消亡。本文是有关如何构建 nftables 的教程。当前，有一个与 nftables 兼容的 iptables-nft 后端，但是很快，即使是它也不再提供了。另外，正如 Red Hat 开发人员所指出的那样，有时它可能会错误地转换规则。我们需要知道如何构建自己的 nftables，而不是依赖于 iptables 到 nftables 的转换器。在 nftables 中，所有地址族都遵循一个规则。与 iptables 不同，nftables 在用户空间中运行，iptables 中的每个模块都运行在内核（空间）中。它很少需要更新内核，并带有一些新功能，例如映射、地址族和字典。地址族地址族确定要处理的数据包的类型。在 nftables 中有六个地址族，它们是：ipipv6inetarpbridgenetdev在 nftables 中，ipv4 和 ipv6 协议可以被合并为一个称为 inet 的单一地址族。因此，我们不需要指定两个规则：一个用于 ipv4，另一个用于 ipv6。如果未指定地址族，它将默认为 ip 协议，即 ipv4。我们感兴趣的领域是 inet 地址族，因为大多数家庭用户将使用 ipv4 或 ipv6 协议。nftables典型的 nftables 规则包含三个部分：表、链和规则。表是链和规则的容器。它们由其地址族和名称来标识。链包含 inet/arp/bridge/netdev 等协议所需的规则，并具有三种类型：过滤器、NAT 和路由。nftables 规则可以从脚本加载，也可以在终端键入，然后另存为规则集。对于家庭用户，默认链为过滤器。inet 系列包含以下钩子：InputOutputForwardPre-routingPost-routing使用脚本还是不用？最大的问题之一是我们是否可以使用防火墙脚本。答案是：这是你自己的选择。这里有一些建议：如果防火墙中有数百条规则，那么最好使用脚本，但是如果你是典型的家庭用户，则可以在终端中键入命令，然后（保存并在重启时）加载规则集。每种选择都有其自身的优缺点。在本文中，我们将在终端中键入它们以构建防火墙。nftables 使用一个名为 nft 的程序来添加、创建、列出、删除和加载规则。确保使用以下命令将 nftables 与 conntrackd 和 netfilter-persistent 软件包一起安装，并删除 iptables：apt-get install nftables conntrackd netfilter-persistent apt-get purge iptablesnft 需要以 root 身份运行或使用 sudo 运行。使用以下命令分别列出、刷新、删除规则集和加载脚本。nft list ruleset nft flush ruleset nft delete table inet filter /usr/sbin/nft -f /etc/nftables.conf输入策略就像 iptables 一样，防火墙将包含三部分：输入（input）、转发（forward）和输出（output）。在终端中，为输入（input）策略键入以下命令。在开始之前，请确保已刷新规则集。我们的默认策略将会删除所有内容。我们将在防火墙中使用 inet 地址族。将以下规则以 root 身份添加或使用 sudo 运行：nft add table inet filter nft add chain inet filter input { type filter hook input priority 0 \; counter \; policy drop \; }你会注意到有一个名为 priority 0 的东西。这意味着赋予该规则更高的优先级。挂钩通常赋予负整数，这意味着更高的优先级。每个挂钩都有自己的优先级，过滤器链的优先级为 0。你可以检查 nftables Wiki 页面以查看每个挂钩的优先级。要了解你计算机中的网络接口，请运行以下命令：ip link show它将显示已安装的网络接口，一个是本地主机、另一个是以太网端口或无线端口。以太网端口的名称如下所示：enpXsY，其中 X 和 Y 是数字，无线端口也是如此。我们必须允许本地主机的流量，并且仅允许从互联网建立的传入连接。nftables 具有一项称为裁决语句的功能，用于解析规则。裁决语句为 accept、drop、queue、jump、goto、continue 和 return。由于这是一个很简单的防火墙，因此我们将使用 accept 或 drop 处理数据包。nft add rule inet filter input iifname lo accept nft add rule inet filter input iifname enpXsY ct state new, established, related accept接下来，我们必须添加规则以保护我们免受隐秘扫描。并非所有的隐秘扫描都是恶意的，但大多数都是。我们必须保护网络免受此类扫描。第一组规则列出了要测试的 TCP 标志。在这些标志中，第二组列出了要与第一组匹配的标志。nft add rule inet filter input iifname enpXsY tcp flags \& \(syn\|fin\) == \(syn\|fin\) drop nft add rule inet filter input iifname enpXsY tcp flags \& \(syn\|rst\) == \(syn\|rst\) drop nft add rule inet filter input iifname enpXsY tcp flags \& \(fin\|rst\) == \(fin\|rst\) drop nft add rule inet filter input iifname enpXsY tcp flags \& \(ack\|fin\) == fin drop nft add rule inet filter input iifname enpXsY tcp flags \& \(ack\|psh\) == psh drop nft add rule inet filter input iifname enpXsY tcp flags \& \(ack\|urg\) == urg drop记住，我们在终端中键入这些命令。因此，我们必须在一些特殊字符之前添加一个反斜杠，以确保终端能够正确解释该斜杠。如果你使用的是脚本，则不需要这样做。关于 ICMP 的警告互联网控制消息协议（ICMP）是一种诊断工具，因此不应完全丢弃该流量。完全阻止 ICMP 的任何尝试都是不明智的，因为它还会导致停止向我们提供错误消息。仅启用最重要的控制消息，例如回声请求、回声应答、目的地不可达和超时等消息，并拒绝其余消息。回声请求和回声应答是 ping 的一部分。在输入策略中，我们仅允许回声应答、而在输出策略中，我们仅允许回声请求。nft add rule inet filter input iifname enpXsY icmp type { echo-reply, destination-unreachable, time-exceeded } limit rate 1/second accept nft add rule inet filter input iifname enpXsY ip protocol icmp drop最后，我们记录并丢弃所有无效数据包。nft add rule inet filter input iifname enpXsY ct state invalid log flags all level info prefix \”Invalid-Input: \” nft add rule inet filter input iifname enpXsY ct state invalid drop转发和输出策略在转发和输出策略中，默认情况下我们将丢弃数据包，仅接受已建立连接的数据包。nft add chain inet filter forward { type filter hook forward priority 0 \; counter \; policy drop \; } nft add rule inet filter forward ct state established, related accept nft add rule inet filter forward ct state invalid drop nft add chain inet filter output { type filter hook output priority 0 \; counter \; policy drop \; }典型的桌面用户只需要端口 80 和 443 即可访问互联网。最后，允许可接受的 ICMP 协议并在记录无效数据包时丢弃它们。nft add rule inet filter output oifname enpXsY tcp dport { 80, 443 } ct state established accept nft add rule inet filter output oifname enpXsY icmp type { echo-request, destination-unreachable, time-exceeded } limit rate 1/second accept nft add rule inet filter output oifname enpXsY ip protocol icmp drop nft add rule inet filter output oifname enpXsY ct state invalid log flags all level info prefix \”Invalid-Output: \” nft add rule inet filter output oifname enpXsY ct state invalid drop现在我们必须保存我们的规则集，否则重新启动时它将丢失。为此，请运行以下命令：sudo nft list ruleset. > /etc/nftables.conf我们须在引导时加载 nftables，以下将在 systemd 中启用 nftables 服务：sudo systemctl enable nftables接下来，编辑 nftables 单元文件以删除 Execstop 选项，以避免在每次引导时刷新规则集。该文件通常位于 /etc/systemd/system/sysinit.target.wants/nftables.service。现在重新启动nftables：sudo systemctl restart nftables在 rsyslog 中记录日志当你记录丢弃的数据包时，它们直接进入 syslog，这使得读取该日志文件非常困难。最好将防火墙日志重定向到单独的文件。在 /var/log 目录中创建一个名为 nftables 的目录，并在其中创建两个名为 input.log 和 output.log 的文件，分别存储输入和输出日志。确保系统中已安装 rsyslog。现在转到 /etc/rsyslog.d 并创建一个名为 nftables.conf 的文件，其内容如下：:msg,regex,”Invalid-Input: “ -/var/log/nftables/Input.log :msg,regex,”Invalid-Output: “ -/var/log/nftables/Output.log & stop现在，我们必须确保日志是可管理的。为此，使用以下代码在 /etc/logrotate.d 中创建另一个名为 nftables 的文件：/var/log/nftables/* { rotate 5 daily maxsize 50M missingok notifempty delaycompress compress postrotate invoke-rc.d rsyslog rotate > /dev/null endscript }重新启动 nftables。现在，你可以检查你的规则集。如果你觉得在终端中键入每个命令很麻烦，则可以使用脚本来加载 nftables 防火墙。我希望本文对保护你的系统有用。via: https://opensourceforu.com/2019/10/transition-to-nftables/作者：Vijay Marcel D 选题：lujun9972 译者：wxy 校对：wxy本文由 LCTT 原创编译，Linux中国 荣誉推出
上一篇：模式。在这篇帖子中，我们将会通过为应用添加社交登录功能进入后端开发。社交登录的工作方式十分简单：用户点击链接，然后重定向到 GitHub 授权页面。当用户授予我们对他的个人信息的访问权限之后，就会重定向回登录页面。下一次尝试登录时，系统将不会再次请求授权，也就是说，我们的应用已经记住了这个用户。这使得整个登录流程看起来就和你用鼠标单击一样快。如果进一步考虑其内部实现的话，过程就会变得复杂起来。首先，我们需要注册一个新的 GitHub OAuth 应用。这一步中，比较重要的是回调 URL。我们将它设置为 http://localhost:3000/api/oauth/github/callback。这是因为，在开发过程中，我们总是在本地主机上工作。一旦你要将应用交付生产，请使用正确的回调 URL 注册一个新的应用。注册以后，你将会收到“客户端 id”和“安全密钥”。安全起见，请不要与任何人分享他们 ?顺便让我们开始写一些代码吧。现在，创建一个 main.go 文件：package main import ( "database/sql" "fmt" "log" "net/http" "net/url" "os" "strconv" "github.com/gorilla/securecookie" "github.com/joho/godotenv" "github.com/knq/jwt" _ "github.com/lib/pq" "github.com/matryer/way" "golang.org/x/oauth2" "golang.org/x/oauth2/github" ) var origin *url.URL var db *sql.DB var githubOAuthConfig *oauth2.Config var cookieSigner *securecookie.SecureCookie var jwtSigner jwt.Signer func main() { godotenv.Load() port := intEnv("PORT", 3000) originString := env("ORIGIN", fmt.Sprintf("http://localhost:%d/", port)) databaseURL := env("DATABASE_URL", "postgresql://root@127.0.0.1:26257/messenger?sslmode=disable") githubClientID := os.Getenv("GITHUB_CLIENT_ID") githubClientSecret := os.Getenv("GITHUB_CLIENT_SECRET") hashKey := env("HASH_KEY", "secret") jwtKey := env("JWT_KEY", "secret") var err error if origin, err = url.Parse(originString); err != nil || !origin.IsAbs() { log.Fatal("invalid origin") return } if i, err := strconv.Atoi(origin.Port()); err == nil { port = i } if githubClientID == "" || githubClientSecret == "" { log.Fatalf("remember to set both $GITHUB_CLIENT_ID and $GITHUB_CLIENT_SECRET") return } if db, err = sql.Open("postgres", databaseURL); err != nil { log.Fatalf("could not open database connection: %v\n", err) return } defer db.Close() if err = db.Ping(); err != nil { log.Fatalf("could not ping to db: %v\n", err) return } githubRedirectURL := *origin githubRedirectURL.Path = "/api/oauth/github/callback" githubOAuthConfig = &oauth2.Config{ ClientID: githubClientID, ClientSecret: githubClientSecret, Endpoint: github.Endpoint, RedirectURL: githubRedirectURL.String(), Scopes: []string{"read:user"}, } cookieSigner = securecookie.New([]byte(hashKey), nil).MaxAge(0) jwtSigner, err = jwt.HS256.New([]byte(jwtKey)) if err != nil { log.Fatalf("could not create JWT signer: %v\n", err) return } router := way.NewRouter() router.HandleFunc("GET", "/api/oauth/github", githubOAuthStart) router.HandleFunc("GET", "/api/oauth/github/callback", githubOAuthCallback) router.HandleFunc("GET", "/api/auth_user", guard(getAuthUser)) log.Printf("accepting connections on port %d\n", port) log.Printf("starting server at %s\n", origin.String()) addr := fmt.Sprintf(":%d", port) if err = http.ListenAndServe(addr, router); err != nil { log.Fatalf("could not start server: %v\n", err) } } func env(key, fallbackValue string) string { v, ok := os.LookupEnv(key) if !ok { return fallbackValue } return v } func intEnv(key string, fallbackValue int) int { v, ok := os.LookupEnv(key) if !ok { return fallbackValue } i, err := strconv.Atoi(v) if err != nil { return fallbackValue } return i }安装依赖项：go get -u github.com/gorilla/securecookie go get -u github.com/joho/godotenv go get -u github.com/knq/jwt go get -u github.com/lib/pq ge get -u github.com/matoous/go-nanoid go get -u github.com/matryer/way go get -u golang.org/x/oauth2我们将会使用 .env 文件来保存密钥和其他配置。请创建这个文件，并保证里面至少包含以下内容：GITHUB_CLIENT_ID=your_github_client_id GITHUB_CLIENT_SECRET=your_github_client_secret我们还要用到的其他环境变量有：PORT：服务器运行的端口，默认值是 3000。ORIGIN：你的域名，默认值是 http://localhost:3000/。我们也可以在这里指定端口。DATABASE_URL：Cockroach 数据库的地址。默认值是 postgresql://root@127.0.0.1:26257/messenger?sslmode=disable。HASH_KEY：用于为 cookie 签名的密钥。没错，我们会使用已签名的 cookie 来确保安全。JWT_KEY：用于签署 JSON 网络令牌 Web Token 的密钥。因为代码中已经设定了默认值，所以你也不用把它们写到 .env 文件中。在读取配置并连接到数据库之后，我们会创建一个 OAuth 配置。我们会使用 ORIGIN 信息来构建回调 URL（就和我们在 GitHub 页面上注册的一样）。我们的数据范围设置为 “read:user”。这会允许我们读取公开的用户信息，这里我们只需要他的用户名和头像就够了。然后我们会初始化 cookie 和 JWT 签名器。定义一些端点并启动服务器。在实现 HTTP 处理程序之前，让我们编写一些函数来发送 HTTP 响应。func respond(w http.ResponseWriter, v interface{}, statusCode int) { b, err := json.Marshal(v) if err != nil { respondError(w, fmt.Errorf("could not marshal response: %v", err)) return } w.Header().Set("Content-Type", "application/json; charset=utf-8") w.WriteHeader(statusCode) w.Write(b) } func respondError(w http.ResponseWriter, err error) { log.Println(err) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) }第一个函数用来发送 JSON，而第二个将错误记录到控制台并返回一个 500 Internal Server Error 错误信息。OAuth 开始所以，用户点击写着 “Access with GitHub” 的链接。该链接指向 /api/oauth/github，这将会把用户重定向到 github。func githubOAuthStart(w http.ResponseWriter, r *http.Request) { state, err := gonanoid.Nanoid() if err != nil { respondError(w, fmt.Errorf("could not generte state: %v", err)) return } stateCookieValue, err := cookieSigner.Encode("state", state) if err != nil { respondError(w, fmt.Errorf("could not encode state cookie: %v", err)) return } http.SetCookie(w, &http.Cookie{ Name: "state", Value: stateCookieValue, Path: "/api/oauth/github", HttpOnly: true, }) http.Redirect(w, r, githubOAuthConfig.AuthCodeURL(state), http.StatusTemporaryRedirect) }OAuth2 使用一种机制来防止 CSRF 攻击，因此它需要一个“状态”（state）。我们使用 Nanoid() 来创建一个随机字符串，并用这个字符串作为状态。我们也把它保存为一个 cookie。OAuth 回调一旦用户授权我们访问他的个人信息，他将会被重定向到这个端点。这个 URL 的查询字符串上将会包含状态（state）和授权码（code）： /api/oauth/github/callback?state=&code=。const jwtLifetime = time.Hour * 24 * 14 type GithubUser struct { ID int `json:"id"` Login string `json:"login"` AvatarURL *string `json:"avatar_url,omitempty"` } type User struct { ID string `json:"id"` Username string `json:"username"` AvatarURL *string `json:"avatarUrl"` } func githubOAuthCallback(w http.ResponseWriter, r *http.Request) { stateCookie, err := r.Cookie("state") if err != nil { http.Error(w, http.StatusText(http.StatusTeapot), http.StatusTeapot) return } http.SetCookie(w, &http.Cookie{ Name: "state", Value: "", MaxAge: -1, HttpOnly: true, }) var state string if err = cookieSigner.Decode("state", stateCookie.Value, &state); err != nil { http.Error(w, http.StatusText(http.StatusTeapot), http.StatusTeapot) return } q := r.URL.Query() if state != q.Get("state") { http.Error(w, http.StatusText(http.StatusTeapot), http.StatusTeapot) return } ctx := r.Context() t, err := githubOAuthConfig.Exchange(ctx, q.Get("code")) if err != nil { respondError(w, fmt.Errorf("could not fetch github token: %v", err)) return } client := githubOAuthConfig.Client(ctx, t) resp, err := client.Get("https://api.github.com/user") if err != nil { respondError(w, fmt.Errorf("could not fetch github user: %v", err)) return } var githubUser GithubUser if err = json.NewDecoder(resp.Body).Decode(&githubUser); err != nil { respondError(w, fmt.Errorf("could not decode github user: %v", err)) return } defer resp.Body.Close() tx, err := db.BeginTx(ctx, nil) if err != nil { respondError(w, fmt.Errorf("could not begin tx: %v", err)) return } var user User if err = tx.QueryRowContext(ctx, ` SELECT id, username, avatar_url FROM users WHERE github_id = $1 `, githubUser.ID).Scan(&user.ID, &user.Username, &user.AvatarURL); err == sql.ErrNoRows { if err = tx.QueryRowContext(ctx, ` INSERT INTO users (username, avatar_url, github_id) VALUES ($1, $2, $3) RETURNING id `, githubUser.Login, githubUser.AvatarURL, githubUser.ID).Scan(&user.ID); err != nil { respondError(w, fmt.Errorf("could not insert user: %v", err)) return } user.Username = githubUser.Login user.AvatarURL = githubUser.AvatarURL } else if err != nil { respondError(w, fmt.Errorf("could not query user by github ID: %v", err)) return } if err = tx.Commit(); err != nil { respondError(w, fmt.Errorf("could not commit to finish github oauth: %v", err)) return } exp := time.Now().Add(jwtLifetime) token, err := jwtSigner.Encode(jwt.Claims{ Subject: user.ID, Expiration: json.Number(strconv.FormatInt(exp.Unix(), 10)), }) if err != nil { respondError(w, fmt.Errorf("could not create token: %v", err)) return } expiresAt, _ := exp.MarshalText() data := make(url.Values) data.Set("token", string(token)) data.Set("expires_at", string(expiresAt)) http.Redirect(w, r, "/callback?"+data.Encode(), http.StatusTemporaryRedirect) }首先，我们会尝试使用之前保存的状态对 cookie 进行解码。并将其与查询字符串中的状态进行比较。如果它们不匹配，我们会返回一个 418 I'm teapot（未知来源）错误。接着，我们使用授权码生成一个令牌。这个令牌被用于创建 HTTP 客户端来向 GitHub API 发出请求。所以最终我们会向 https://api.github.com/user 发送一个 GET 请求。这个端点将会以 JSON 格式向我们提供当前经过身份验证的用户信息。我们将会解码这些内容，一并获取用户的 ID、登录名（用户名）和头像 URL。然后我们将会尝试在数据库上找到具有该 GitHub ID 的用户。如果没有找到，就使用该数据创建一个新的。之后，对于新创建的用户，我们会发出一个将用户 ID 作为主题（Subject）的 JSON 网络令牌，并使用该令牌重定向到前端，查询字符串中一并包含该令牌的到期日（Expiration）。这一 Web 应用也会被用在其他帖子，但是重定向的链接会是 /callback?token=&expires_at=。在那里，我们将会利用 JavaScript 从 URL 中获取令牌和到期日，并通过 Authorization 标头中的令牌以 Bearer token_here 的形式对 /api/auth_user 进行 GET 请求，来获取已认证的身份用户并将其保存到 localStorage。Guard 中间件为了获取当前已经过身份验证的用户，我们设计了 Guard 中间件。这是因为在接下来的文章中，我们会有很多需要进行身份认证的端点，而中间件将会允许我们共享这一功能。type ContextKey struct { Name string } var keyAuthUserID = ContextKey{"auth_user_id"} func guard(handler http.HandlerFunc) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { var token string if a := r.Header.Get("Authorization"); strings.HasPrefix(a, "Bearer ") { token = a[7:] } else if t := r.URL.Query().Get("token"); t != "" { token = t } else { http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized) return } var claims jwt.Claims if err := jwtSigner.Decode([]byte(token), &claims); err != nil { http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized) return } ctx := r.Context() ctx = context.WithValue(ctx, keyAuthUserID, claims.Subject) handler(w, r.WithContext(ctx)) } }首先，我们尝试从 Authorization 标头或者是 URL 查询字符串中的 token 字段中读取令牌。如果没有找到，我们需要返回 401 Unauthorized（未授权）错误。然后我们将会对令牌中的申明进行解码，并使用该主题作为当前已经过身份验证的用户 ID。现在，我们可以用这一中间件来封装任何需要授权的 http.handlerFunc，并且在处理函数的上下文中保有已经过身份验证的用户 ID。var guarded = guard(func(w http.ResponseWriter, r *http.Request) { authUserID := r.Context().Value(keyAuthUserID).(string) })获取认证用户func getAuthUser(w http.ResponseWriter, r *http.Request) { ctx := r.Context() authUserID := ctx.Value(keyAuthUserID).(string) var user User if err := db.QueryRowContext(ctx, ` SELECT username, avatar_url FROM users WHERE id = $1 `, authUserID).Scan(&user.Username, &user.AvatarURL); err == sql.ErrNoRows { http.Error(w, http.StatusText(http.StatusTeapot), http.StatusTeapot) return } else if err != nil { respondError(w, fmt.Errorf("could not query auth user: %v", err)) return } user.ID = authUserID respond(w, user, http.StatusOK) }我们使用 Guard 中间件来获取当前经过身份认证的用户 ID 并查询数据库。这一部分涵盖了后端的 OAuth 流程。在下一篇帖子中，我们将会看到如何开始与其他用户的对话。源代码via: https://nicolasparada.netlify.com/posts/go-messenger-oauth/作者：Nicolás Parada 选题：lujun9972 译者：PsiACE 校对：wxy本文由 LCTT 原创编译，Linux中国 荣誉推出
随着 Debian 10.1 “Buster” 的发布，MX Linux 19 也发布了
MX Linux 18 是我在最佳 Linux 发行版中的主要推荐的发行版之一，特别是当你在考虑 Ubuntu 以外的发行版时。它基于 Debian 9.6 “Stretch”，具有令人难以置信的快速流畅的体验。现在，作为该发行版的主要升级版本，MX Linux 19 带来了许多重大改进和变更。在这里，我们将看一下主要亮点。MX Linux 19 中的新功能Debian 10 “Buster”这个值得一提，因为 Debian 10 实际上是 MX Linux 18 所基于的 Debian 9.6 “Stretch” 的主要升级。如果你对 Debian 10 “Buster” 的变化感到好奇，建议你阅读有关 Debian 10 “Buster” 的新功能的文章。Xfce 桌面 4.14Xfce 4.14 正是 Xfce 开发团队提供的最新产品。就个人而言，我不是 Xfce 桌面环境的粉丝，但是当你在 Linux 发行版（尤其是 MX Linux 19）上使用它时，它超快的性能会让你惊叹。或许你会感兴趣，我们也有一个快速指南来帮助你自定义 Xfce。升级的软件包及最新的 Debian 内核 4.19除了 GIMP、MESA、Firefox 等的更新软件包之外，它还随附有 Debian “Buster” 可用的最新内核 4.19。升级的 MX 系列应用如果你以前使用过 MX Linux，则可能会知道它已经预装了有用的 MX 系列应用，可以帮助你快速完成更多工作。像 MX-installer 和 MX-packageinstaller 这样的应用程序得到了显著改进。除了这两个以外，所有其他 MX 工具也已不同程度的进行了更新和修复错误、添加了新的翻译（或只是改善了用户体验）。其它改进考虑到这是一次重大升级，很明显，底层的更改要多于表面（包括最新的 antiX live 系统更新）。你可以在他们的官方公告中查看更多详细信息。你还可以从开发人员那里观看以下视频，它介绍了 MX Linux 19 中的所有新功能：获取 MX Linux 19即使是你现在正在使用 MX Linux 18 版本，你也无法升级到 MX Linux 19。你需要像其他人一样进行全新安装。你可以从此页面下载 MX Linux 19：下载 MX Linux 19结语在 MX Linux 18 上，我在使用 WiFi 适配器时遇到了问题，通过论坛解决了该问题，但看来 MX Linux 19 仍未解决该问题。因此，如果你在安装 MX Linux 19 之后遇到了相同的问题，你可能想要查看一下我的论坛帖子。如果你使用的是 MX Linux 18，那么这绝对是一个令人印象深刻的升级。你尝试过了吗？你对新的 MX Linux 19 版本有何想法？让我知道你在以下评论中的想法。via: https://itsfoss.com/mx-linux-19/作者：Ankush Das 选题：lujun9972 译者：wxy 校对：wxy本文由 LCTT 原创编译，Linux中国 荣誉推出
那个你们眼中的硬件厂商，其实已经是云计算的急先锋
从业计算机行业以来，我接触过很多计算机硬件厂商，不知自何时开始，从我们的身边的个人电脑到企业级的服务器和存储设备，越来越多的见到了戴尔的身影。就在我前两天参加的戴尔科技峰会的一个媒体群访会上，戴尔科技集团全球副总裁、大中华区数据中心销售总经理孔大勇先生就笑言，“在座的诸位中有 15 台笔记本电脑，其中 9 台是戴尔的”。更别说如浩如烟海般充斥在数据中心的各式戴尔设备。可能在很多人眼里，戴尔还是那个生产、销售硬件服务器的戴尔，但是很多人不知道的是，戴尔已经在云计算领域布局多年。云计算这个 IT 时髦词虽然已经提出很久了，但是令人有些意外的是，这个时髦词居然历久弥新，在 IT 领域这么变化日新月异的行业中，还能不断焕发新的变化。从早期的分布式计算、虚拟技术，到现在的容器技术，从公有云、私有云，到混合云、多云，不经意间，一篇篇新的技术篇章掀过，我们所面临的已经是一个崭新的云时代。这次有幸参加戴尔科技峰会 2019，让我恍若置身一场云原生大会，除了很多的新技术突破和硬件新品发布，戴尔也在云计算领域取得了长足的发展。由于我们长期以来一直关注云技术的发展，所以我专门着眼于观察戴尔在云计算方面的新变化，下面就让我来给大家介绍一下本次大会中我的感受。戴尔的云端之路自 2010 年戴尔发布 高效企业生态系统 （ Efficient Enterprise Ecosystem ） （E3）的云计算战略以后，就开始不断布局云计算生态，将戴尔从一个传统的计算机硬件企业，转变成为一个软硬件两把抓的云计算强企。得益于多年企业级硬件的产品与设备，戴尔从一开始就为其在企业级场景下的硬件设施打好了基础，而近年来，戴尔也不断并购了一些企业，并以此为契机，增加了自己在云计算领域的能力。近年来，戴尔收购了 EMC，从而掌握了虚拟化领域巨头 VMWare，又在其后收购了Pivotal （后者是顶尖的云计算平台公司，我们所熟悉的 12306 的架构中，就有一大部分在使用 Pivotal 的产品），不断增强自己在云计算领域的能力，并借助于自己在传统硬件领域的强项，去改变企业、政府对于云计算的认识，协助他们完成数字化转型。同时，可能会令很多人意外的是，戴尔也是 Kubernetes 项目代码贡献度全球第二的企业，拥有丰富的 Kubernetes 开发人才。和我们所熟悉的很多公有云厂商不同，他们很多是从开始做云的时候，就决定要做公有云，希望去服务尽可能多的用户，服务更多的中长尾用户。戴尔则是更关注于企业级市场，关注企业用户的需求。当然，这也是源自于戴尔在服务器等企业级市场的深耕，能够精确把握企业对于云计算的需求。源自不同认识的混合云在不断服务企业级客户的过程中，戴尔收集到了大量的用户反馈，企业级用户往往不同于个人用户，将自己的所有业务都集中在一个平台上，企业级客户会同时使用两家甚至是更多的云平台，以确保自己的业务不会因为某一家的云服务出现问题而整体业务崩盘。单一平台所构建的信息孤岛对于企业级用户来说，是一个很大的风险，这也是为什么近些年来，我们看到 Kubernetes 的不断发展。企业面临着信息孤岛的问题而不知如何解决，Kubernetes 是一个标准化的云计算解决方案，帮助他们提升产品和能力的可迁移性，而戴尔则对该问题提供了更进一步的解决方案。前面我们提到，VMWare 目前是属于戴尔公司的，而 VMWare 本身，是目前全球用量最大的云计算虚拟化平台，你所知道或不知道的云计算平台，他们的背后运转的很多都是 VMWare 计算平台。得益于 VMWare 多年的积累，戴尔拥有丰富的私有云建设经验，可以在企业现有的基础设施上快速构建起一套能力强大的私有云体系。同时，因为不少云计算平台使用的也是 VMWare，使得企业自行构建的私有云能够更加轻松的与使用了 VMWare 的公有云结合，构建出一体化体验的云计算平台，让用户可以在一个平台上调度和管理多个不同的云计算平台，在这个平台上做计算、做数据挖掘、做资源调度，帮助企业更加简单的构建私有云。这样构建出的私有云，拥有真正意义上的“混合”云的能力，而不再是仅仅与某一家云计算厂商提供的能力所结合，它可以让你同时和多个不同的云计算平台对接，还可以和你自己企业内部构建的私有云所结合，让不同云计算平台的业务可以通过戴尔所提供的服务和产品无缝对接，让业务正常运转。VCF 如何解决问题由我们所熟悉的一些云计算公司，诸如 AWS、Azure、Google ，以及全球 4000 多家 VCPP（VMware Cloud Provider Program）项目成员所组成的VCF（VMware Cloud Foundation）建立起一套云计算基础设施的标准，都采用统一的 VCF 作为其标准，构建自己的云计算服务。而基于VMware最佳实践来搭建的软件定义的数据中心，其中所有的云都是基于同一个标准、同一个架构，其中的产品也就可以随意的在不同的云计算平台中任意迁移。 对于企业来说，VCF 的存在大大降低了其产品在不同服务商之间切换的成本，企业可以根据自己的需求，随意的在其所使用的几个云服务商之间进行切换，甚至是切换到私有云上！相比于我们熟悉的 Kubernetes，VCF 在易用性上的投入，更是让企业可以简单的实现业务需求，支撑业务的整体运转。SDDC 的未来SDDC 是 VCF 的一个产品组件，想来这个词去描述戴尔的混合云战略真是再准确不过了。什么是 SDDC？和我们所熟悉的 SDN（ 软件定义网络 （ Software-defined Network ） ）类似，SDDC 就是 软件定义的数据中心 （ Software-Defined DataCenter ） ，以软件的方式来定义数据中心。而能够做到这些，源自于戴尔自己多年制作企业级服务器和其所收购的 VMWare 多年来在虚拟化领域的投入。VMware 目前是全球私有云环境里面市场占有率体量也是最大的。和其他云计算厂商相比，戴尔拥有业界体量最大、份额最高、方案最全、价值最高的方案，可以满足用户的不同场景下的需求。在戴尔看来，未来企业级云计算的市场会逐渐归一，所有的公有云也好、私有云也好，终将会回归到混合云的模式，因为企业不可能将所有的核心数据都交付给云计算厂商，他们需要一个私有云，帮助承载和处理企业内部的一些机密数据。而私有云和公有云的对接，就会逐渐成为一个大的问题。做虚拟化出身的 VMWare 帮助戴尔解决了自己的问题，提出了 SDDC 的方式，来完成这个业务需求，并基于 VMWare 多年的积累，为 SDDC 加入大量云计算企业的支持，为客户拉了一针强心剂。在中国，为中国在过去的数年里，戴尔不但在技术研究方面深入到云计算行业，也将自己的云计算产品推向市场，接受市场的考验。比如说，戴尔近几年借助于区域服务商，将其云计算的产品铺设到政府和企业场景中，帮助他们完成信息化、数字化。很多企业和部门内部的基础设施虽然投入昂贵，但是，由于维护和管理不善，从而导致大量的病毒、木马潜伏在服务器内，占用了设备性能，并造成了数据泄露和安全隐患。此外，也因为基础设施维护的不完善，没有办法有效利用基础设施资源，更谈不上数据的共享。同时导致了各部门都需要自行建设基础设施，造成了大量的基础设施和资源的浪费，数据中心建设标准参差不齐，无法保证数据的安全和业务的稳定，为服务埋下了隐患。引入戴尔的混合云方案以后，机构对机房进行统一，建设一个主数据中心，从而完成管理集群、高性能集群、vSAN 集群等，帮助他们构建了一套性能良好、基础设施完备的内部云方案，同时，得益于 VMWare 本身基础设施建设的能力，还引入了 vSAN，借助其拓展能力，实现了双活的副数据中心的构建，以确保数据的安全和业务的运转。借助不断推动企业、政府的数字化、信息化，戴尔实现了自己在几年前定下的诺言，“在中国、为中国”，帮助中国变得越来越好。结语这一次的戴尔科技峰会让我大开眼界，过去那个只做硬件的戴尔，如今不仅做了云，还做取得了长足的发展，站在了云计算技术的前沿，不知道未来，戴尔还能够为我们带来什么更加亮眼的产品？