如何组合分片的steam文件权限遗失

&figure&&img src=&/50/v2-68e3a8c4b7ec4a1c2fd9_b.jpg& data-rawwidth=&640& data-rawheight=&512& class=&origin_image zh-lightbox-thumb& width=&640& data-original=&/50/v2-68e3a8c4b7ec4a1c2fd9_r.jpg&&&/figure&&h2&&b&一、uptime命令&/b&&/h2&&figure&&img src=&/50/v2-0aa0dd24ee_b.jpg& data-caption=&& data-rawwidth=&452& data-rawheight=&49& class=&origin_image zh-lightbox-thumb& width=&452& data-original=&/50/v2-0aa0dd24ee_r.jpg&&&/figure&&p&这个命令可以快速查看机器的负载情况。在Linux系统中,这些数据表示等待CPU资源的进程和阻塞在不可中断IO进程(进程状态为D)的数量。这些数据可以让我们对系统资源使用有一个宏观的了解。&/p&&p&命令的输出分别表示1分钟、5分钟、15分钟的平均负载情况。通过这三个数据,可以了解服务器负载是在趋于紧张还是趋于缓解。如果1分钟平均负载很高,而15分钟平均负载很低,说明服务器正在命令高负载情况,需要进一步排查CPU资源都消耗在了哪里。反之,如果15分钟平均负载很高,1分钟平均负载较低,则有可能是CPU资源紧张时刻已经过去。&/p&&p&上面例子中的输出,可以看见最近1分钟的平均负载非常高,且远高于最近15分钟负载,因此我们需要继续排查当前系统中有什么进程消耗了大量的资源。可以通过下文将会介绍的vmstat、mpstat等命令进一步排查。&/p&&h2&&b&二、dmesg命令&/b&&/h2&&figure&&img src=&/50/v2-c3a4a13cd4e5e538a9774b_b.jpg& data-caption=&& data-rawwidth=&640& data-rawheight=&128& class=&origin_image zh-lightbox-thumb& width=&640& data-original=&/50/v2-c3a4a13cd4e5e538a9774b_r.jpg&&&/figure&&p&该命令会输出系统日志的最后10行。示例中的输出,可以看见一次内核的oom kill和一次TCP丢包。这些日志可以帮助排查性能问题。千万不要忘了这一步。 &/p&&h2&&b&三、vmstat命令&/b&&/h2&&figure&&img src=&/50/v2-1bdd_b.jpg& data-caption=&& data-rawwidth=&596& data-rawheight=&205& class=&origin_image zh-lightbox-thumb& width=&596& data-original=&/50/v2-1bdd_r.jpg&&&/figure&&p&vmstat(8) 命令,每行会输出一些系统核心指标,这些指标可以让我们更详细的了解系统状态。后面跟的参数1,表示每秒输出一次统计信息,表头提示了每一列的含义,这几介绍一些和性能调优相关的列: &/p&&ul&&li&r:等待在CPU资源的进程数。这个数据比平均负载更加能够体现CPU负载情况,数据中不包含等待IO的进程。如果这个数值大于机器CPU核数,那么机器的CPU资源已经饱和。&/li&&li&free:系统可用内存数(以千字节为单位),如果剩余内存不足,也会导致系统性能问题。下文介绍到的free命令,可以更详细的了解系统内存的使用情况。&/li&&li&si,so:交换区写入和读取的数量。如果这个数据不为0,说明系统已经在使用交换区(swap),机器物理内存已经不足。&/li&&li&us, sy, id, wa, st:这些都代表了CPU时间的消耗,它们分别表示用户时间(user)、系统(内核)时间(sys)、空闲时间(idle)、IO等待时间(wait)和被偷走的时间(stolen,一般被其他虚拟机消耗)。&/li&&/ul&&p&上述这些CPU时间,可以让我们很快了解CPU是否出于繁忙状态。一般情况下,如果用户时间和系统时间相加非常大,CPU出于忙于执行指令。如果IO等待时间很长,那么系统的瓶颈可能在磁盘IO。&/p&&p&示例命令的输出可以看见,大量CPU时间消耗在用户态,也就是用户应用程序消耗了CPU时间。这不一定是性能问题,需要结合r队列,一起分析。&/p&&h2&&b&四、mpstat命令&/b&&/h2&&figure&&img src=&/50/v2-9ffdea64c0f9d95b1b7016_b.jpg& data-caption=&& data-rawwidth=&640& data-rawheight=&209& class=&origin_image zh-lightbox-thumb& width=&640& data-original=&/50/v2-9ffdea64c0f9d95b1b7016_r.jpg&&&/figure&&p&该命令可以显示每个CPU的占用情况,如果有一个CPU占用率特别高,那么有可能是一个单线程应用程序引起的。 &/p&&h2&&b&五、pidstat命令&/b&&/h2&&figure&&img src=&/50/v2-f79e9dcc739_b.jpg& data-caption=&& data-rawwidth=&586& data-rawheight=&339& class=&origin_image zh-lightbox-thumb& width=&586& data-original=&/50/v2-f79e9dcc739_r.jpg&&&/figure&&p&pidstat命令输出进程的CPU占用率,该命令会持续输出,并且不会覆盖之前的数据,可以方便观察系统动态。如上的输出,可以看见两个JAVA进程占用了将近1600%的CPU时间,既消耗了大约16个CPU核心的运算资源。 &/p&&h2&&b&六、iostat命令&/b&&/h2&&figure&&img src=&/50/v2-95f0e735535fce9f7651_b.jpg& data-caption=&& data-rawwidth=&640& data-rawheight=&222& class=&origin_image zh-lightbox-thumb& width=&640& data-original=&/50/v2-95f0e735535fce9f7651_r.jpg&&&/figure&&ul&&li&r/s, w/s, rkB/s, wkB/s:分别表示每秒读写次数和每秒读写数据量(千字节)。读写量过大,可能会引起性能问题。&/li&&li&await:IO操作的平均等待时间,单位是毫秒。这是应用程序在和磁盘交互时,需要消耗的时间,包括IO等待和实际操作的耗时。如果这个数值过大,可能是硬件设备遇到了瓶颈或者出现故障。&/li&&li&avgqu-sz:向设备发出的请求平均数量。如果这个数值大于1,可能是硬件设备已经饱和(部分前端硬件设备支持并行写入)。&/li&&li&%util:设备利用率。这个数值表示设备的繁忙程度,经验值是如果超过60,可能会影响IO性能(可以参照IO操作平均等待时间)。如果到达100%,说明硬件设备已经饱和。&/li&&/ul&&p&如果显示的是逻辑设备的数据,那么设备利用率不代表后端实际的硬件设备已经饱和。值得注意的是,即使IO性能不理想,也不一定意味这应用程序性能会不好,可以利用诸如预读取、写缓存等策略提升应用性能。&/p&&h2&&b&七、free命令&/b&&/h2&&figure&&img src=&/50/v2-898ce40f720ee5cebe64db_b.jpg& data-caption=&& data-rawwidth=&531& data-rawheight=&120& class=&origin_image zh-lightbox-thumb& width=&531& data-original=&/50/v2-898ce40f720ee5cebe64db_r.jpg&&&/figure&&p&free命令可以查看系统内存的使用情况,-m参数表示按照兆字节展示。最后两列分别表示用于IO缓存的内存数,和用于文件系统页缓存的内存数。需要注意的是,第二行-/+ buffers/cache,看上去缓存占用了大量内存空间。&/p&&p&这是Linux系统的内存使用策略,尽可能的利用内存,如果应用程序需要内存,这部分内存会立即被回收并分配给应用程序。因此,这部分内存一般也被当成是可用内存。&/p&&p&如果可用内存非常少,系统可能会动用交换区(如果配置了的话),这样会增加IO开销(可以在iostat命令中提现),降低系统性能。&/p&&h2&&b&八、sar命令&/b&&/h2&&figure&&img src=&/50/v2-2c2c9bc273e62_b.jpg& data-caption=&& data-rawwidth=&640& data-rawheight=&203& class=&origin_image zh-lightbox-thumb& width=&640& data-original=&/50/v2-2c2c9bc273e62_r.jpg&&&/figure&&p&sar命令在这里可以查看网络设备的吞吐率。在排查性能问题时,可以通过网络设备的吞吐量,判断网络设备是否已经饱和。如示例输出中,eth0网卡设备,吞吐率大概在22 Mbytes/s,既176 Mbits/sec,没有达到1Gbit/sec的硬件上限。&/p&&figure&&img src=&/50/v2-ecc34aecbc979bc_b.jpg& data-caption=&& data-rawwidth=&593& data-rawheight=&265& class=&origin_image zh-lightbox-thumb& width=&593& data-original=&/50/v2-ecc34aecbc979bc_r.jpg&&&/figure&&p&sar命令在这里用于查看TCP连接状态,其中包括: &/p&&ul&&li&active/s:每秒本地发起的TCP连接数,既通过connect调用创建的TCP连接;&/li&&li&passive/s:每秒远程发起的TCP连接数,即通过accept调用创建的TCP连接;&/li&&li&retrans/s:每秒TCP重传数量;&/li&&/ul&&p&TCP连接数可以用来判断性能问题是否由于建立了过多的连接,进一步可以判断是主动发起的连接,还是被动接受的连接。TCP重传可能是因为网络环境恶劣,或者服务器压&/p&&h2&&b&九、top命令&/b&&/h2&&figure&&img src=&/50/v2-a8c9fdcb9a511_b.jpg& data-caption=&& data-rawwidth=&605& data-rawheight=&411& class=&origin_image zh-lightbox-thumb& width=&605& data-original=&/50/v2-a8c9fdcb9a511_r.jpg&&&/figure&&p&top命令包含了前面好几个命令的检查的内容。比如系统负载情况(uptime)、系统内存使用情况(free)、系统CPU使用情况(vmstat)等。因此通过这个命令,可以相对全面的查看系统负载的来源。同时,top命令支持排序,可以按照不同的列排序,方便查找出诸如内存占用最多的进程、CPU占用率最高的进程等。 &/p&&p&但是,top命令相对于前面一些命令,输出是一个瞬间值,如果不持续盯着,可能会错过一些线索。这时可能需要暂停top命令刷新,来记录和比对数据。&/p&&hr&&p&点这里,看更多:&a href=&/?target=http%3A///87104& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&《Linux云计算从入门到精通》&i class=&icon-external&&&/i&&/a&&/p&
一、uptime命令这个命令可以快速查看机器的负载情况。在Linux系统中,这些数据表示等待CPU资源的进程和阻塞在不可中断IO进程(进程状态为D)的数量。这些数据可以让我们对系统资源使用有一个宏观的了解。命令的输出分别表示1分钟、5分钟、15分钟的平均负载…
&figure&&img src=&/50/v2-53bd7b55_b.jpg& data-rawwidth=&900& data-rawheight=&498& class=&origin_image zh-lightbox-thumb& width=&900& data-original=&/50/v2-53bd7b55_r.jpg&&&/figure&&p&&i&用 iftop、Nethogs 和 vnstat 了解更多关于你的网络连接。&/i&&/p&&p&你可以通过这三个 Linux 网络命令,了解有关你网络连接的大量信息。iftop 通过进程号跟踪网络连接,Nethogs 可以快速显示哪个在占用你的带宽,而 vnstat 作为一个很好的轻量级守护进程运行,可以随时随地记录你的使用情况。&/p&&h2&&b&iftop&/b&&/h2&&p&&a href=&/?target=http%3A//www./pdw/iftop/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&iftop&i class=&icon-external&&&/i&&/a& 监听你指定的网络接口,并以 &code&top&/code& 的形式展示连接。&/p&&p&这是一个很好的小工具,用于快速识别占用、测量速度,并保持网络流量的总体运行。看到我们使用了多少带宽是非常令人惊讶的,特别是对于我们这些还记得使用电话线、调制解调器、让人尖叫的 Kbit 速度和真实的实时波特率的老年人来说。我们很久以前就放弃了波特率,转而使用比特率。波特率测量信号变化,有时与比特率相同,但大多数情况下不是。&/p&&p&如果你只有一个网络接口,可以不带选项运行 &code&iftop&/code&。&code&iftop&/code& 需要 root 权限:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&$ sudo iftop
&/code&&/pre&&/div&&p&当你有多个接口时,指定要监控的接口:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&$ sudo iftop -i wlan0
&/code&&/pre&&/div&&p&就像 top 一样,你可以在运行时更改显示选项。&/p&&ul&&li&&code&h&/code& 切换帮助屏幕。&/li&&li&&code&n&/code& 切换名称解析。&/li&&li&&code&s&/code& 切换源主机显示,&code&d&/code& 切换目标主机。&/li&&li&&code&s&/code& 切换端口号。&/li&&li&&code&N&/code& 切换端口解析。要全看到端口号,请关闭解析。&/li&&li&&code&t&/code& 切换文本界面。默认显示需要 ncurses。我认为文本显示更易于阅读和更好的组织(图1)。&/li&&li&&code&p&/code& 暂停显示。&/li&&li&&code&q&/code& 退出程序。&/li&&/ul&&figure&&img src=&/50/v2-57ebb38237aea79b18c2f8dc57f6cd12_b.jpg& data-rawwidth=&800& data-rawheight=&523& class=&origin_image zh-lightbox-thumb& width=&800& data-original=&/50/v2-57ebb38237aea79b18c2f8dc57f6cd12_r.jpg&&&figcaption&图 1:文本显示是可读的和可组织的。&/figcaption&&/figure&&p&当你切换显示选项时,&code&iftop&/code& 会继续测量所有流量。你还可以选择要监控的单个主机。你需要主机的 IP 地址和网络掩码。我很好奇 Pandora 在我那可怜的带宽中占用了多少,所以我先用 &code&dig&/code& 找到它们的 IP 地址:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&$ dig
;; ANSWER SECTION:
208.85.40.. 267
208.85.40.50
&/code&&/pre&&/div&&p&&br&&/p&&p&网络掩码是什么? &a href=&/?target=https%3A///learn/intro-to-linux/2017/8/how-calculate-network-addresses-ipcalc& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&ipcalc&i class=&icon-external&&&/i&&/a& 告诉我们:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&$ ipcalc -b 208.85.40.20
Address: 208.85.40.20
Netmask: 255.255.255.0 = 24
Wildcard: 0.0.0.255
Network: 208.85.40.0/24
&/code&&/pre&&/div&&p&现在将地址和网络掩码提供给 iftop:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&$ sudo iftop -F 208.85.40.20/24 -i wlan0
&/code&&/pre&&/div&&p&这不是真的吗?我很惊讶地发现,我珍贵的带宽对于 Pandora 很宽裕,每小时使用大约使用 500Kb。而且,像大多数流媒体服务一样,Pandora 的流量也有峰值,其依赖于缓存来缓解阻塞。&/p&&p&你可以使用 &code&-G&/code& 选项对 IPv6 地址执行相同操作。请参阅手册页了解 &code&iftop&/code& 的其他功能,包括使用自定义配置文件定制默认选项,并应用自定义过滤器(请参阅 &a href=&/?target=http%3A//www.tcpdump.org/manpages/pcap-filter.7.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&PCAP-FILTER&i class=&icon-external&&&/i&&/a& 作为过滤器参考)。&/p&&h2&&b&Nethogs&/b&&/h2&&p&当你想要快速了解谁占用了你的带宽时,Nethogs 是快速和容易的。以 root 身份运行,并指定要监听的接口。它显示了空闲的应用程序和进程号,以便如果你愿意的话,你可以杀死它:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&$ sudo nethogs wlan0
NetHogs version 0.8.1
7690 carla /usr/lib/firefox
wlan0 12.494 556.580 KB/sec
5648 carla .../chromium-browser wlan0
0.052 0.038 KB/sec
12.546 556.618 KB/sec
&/code&&/pre&&/div&&p&Nethogs 选项很少:在 kb/s、kb、b 和 mb 之间循环;通过接收或发送的数据包进行排序;并调整刷新之间的延迟。请参阅 &code&man nethogs&/code&,或者运行 &code&nethogs -h&/code&。&/p&&h2&&b&vnstat&/b&&/h2&&p&&a href=&/?target=http%3A//humdi.net/vnstat/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&vnstat&i class=&icon-external&&&/i&&/a& 是最容易使用的网络数据收集器。它是轻量级的,不需要 root 权限。它作为守护进程运行,并记录你网络统计信息。&code&vnstat&/code& 命令显示累计的数据:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&$ vnstat -i wlan0
Database updated: Tue Oct 17 08:36:38 2017
wlan0 since 10/17/2017
rx: 45.27 MiB
tx: 3.77 MiB
total: 49.04 MiB
------------------------+-------------+-------------+---------------
45.27 MiB |
3.77 MiB |
49.04 MiB |
0.28 kbit/s
------------------------+-------------+-------------+---------------
------------------------+-------------+-------------+---------------
45.27 MiB |
3.77 MiB |
49.04 MiB |
12.96 kbit/s
------------------------+-------------+-------------+---------------
&/code&&/pre&&/div&&p&它默认显示所有的网络接口。使用 &code&-i&/code& 选项选择单个接口。以这种方式合并多个接口的数据:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&$ vnstat -i wlan0+eth0+eth1
&/code&&/pre&&/div&&p&你可以通过以下几种方式过滤显示:&/p&&ul&&li&&code&-h&/code& 以小时显示统计数据。&/li&&li&&code&-d&/code& 以天数显示统计数据。&/li&&li&&code&-w&/code& 和 &code&-m&/code& 按周和月显示统计数据。&/li&&li&使用 &code&-l&/code& 选项查看实时更新。&/li&&/ul&&p&此命令删除 wlan1 的数据库,并停止监控它:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&$ vnstat -i wlan1 --delete
&/code&&/pre&&/div&&p&此命令为网络接口创建别名。此例使用 Ubuntu 16.04 中的一个奇怪的接口名称:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&$ vnstat -u -i enp0s25 --nick eth0
&/code&&/pre&&/div&&p&默认情况下,vnstat 监视 eth0。你可以在 &code&/etc/vnstat.conf&/code& 中更改此内容,或在主目录中创建自己的个人配置文件。请参见 &code&man vnstat&/code& 以获得完整的参考。&/p&&p&你还可以安装 &code&vnstati&/code& 创建简单的彩色图(图2):&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&$ vnstati -s -i wlx7cdd90a0a1c2 -o vnstat.png
&/code&&/pre&&/div&&p&&br&&/p&&figure&&img src=&/50/v2-d6e94fb3ae120eec80abd_b.jpg& data-rawwidth=&500& data-rawheight=&200& class=&origin_image zh-lightbox-thumb& width=&500& data-original=&/50/v2-d6e94fb3ae120eec80abd_r.jpg&&&figcaption&图 2:你可以使用 vnstati 创建简单的彩色图表。&/figcaption&&/figure&&p&有关完整选项,请参见 &code&man vnstati&/code&。&/p&&hr&&p&via: &a href=&/?target=https%3A///learn/intro-to-linux/-simple-excellent-linux-network-monitors& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&https://www.&/span&&span class=&visible&&/learn/intro-t&/span&&span class=&invisible&&o-linux/-simple-excellent-linux-network-monitors&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&&/p&&p&作者:&a href=&/?target=https%3A///users/cschroder& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&CARLA SCHRODER&i class=&icon-external&&&/i&&/a& 译者:&a href=&/?target=https%3A///geekpi& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&geekpi&i class=&icon-external&&&/i&&/a& 校对:&a href=&/?target=https%3A///wxy& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&wxy&i class=&icon-external&&&/i&&/a&&/p&&p&本文由 &a href=&/?target=https%3A///LCTT/TranslateProject& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&LCTT&i class=&icon-external&&&/i&&/a& 原创编译,&a href=&/?target=https%3A///& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Linux中国&i class=&icon-external&&&/i&&/a& 荣誉推出&/p&
用 iftop、Nethogs 和 vnstat 了解更多关于你的网络连接。你可以通过这三个 Linux 网络命令,了解有关你网络连接的大量信息。iftop 通过进程号跟踪网络连接,Nethogs 可以快速显示哪个在占用你的带宽,而 vnstat 作为一个很好的轻量级守护进程运行,可以随…
&figure&&img src=&/50/v2-17f01beab31eec_b.jpg& data-rawwidth=&1024& data-rawheight=&768& class=&origin_image zh-lightbox-thumb& width=&1024& data-original=&/50/v2-17f01beab31eec_r.jpg&&&/figure&&p&这篇博文将向你展示如何使用 Docker 和 &a href=&/?target=https%3A///alexellis/faas& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&OpenFaaS&i class=&icon-external&&&/i&&/a& 框架构建你自己的 Serverless 树莓派集群。大家常常问我能用他们的集群来做些什么?而这个应用完美匹配卡片尺寸的设备——只需添加更多的树莓派就能获取更强的计算能力。&/p&&blockquote&“Serverless” (无服务器)是事件驱动架构的一种设计模式,与“桥接模式”、“外观模式”、“工厂模式”和“云”这些名词一样,都是一种抽象概念。&/blockquote&&p&&br&&/p&&figure&&img src=&/50/v2-f8a05563becf78eb01be36_b.jpg& data-rawwidth=&714& data-rawheight=&714& class=&origin_image zh-lightbox-thumb& width=&714& data-original=&/50/v2-f8a05563becf78eb01be36_r.jpg&&&figcaption&图片:3 个 Raspberry Pi Zero&/figcaption&&/figure&&p&这是我在本文中描述的集群,用黄铜支架分隔每个设备。&/p&&h2&&b&Serverless 是什么?它为何重要?&/b&&/h2&&p&行业对于 “serverless” 这个术语的含义有几种解释。在这篇博文中,我们就把它理解为一种事件驱动的架构模式,它能让你用自己喜欢的任何语言编写轻量可复用的功能。&a href=&/?target=https%3A//blog.alexellis.io/introducing-functions-as-a-service/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&更多关于 Serverless 的资料&i class=&icon-external&&&/i&&/a&。&/p&&p&&br&&/p&&figure&&img src=&/50/v2-dae5faebad_b.jpg& data-rawwidth=&2278& data-rawheight=&790& class=&origin_image zh-lightbox-thumb& width=&2278& data-original=&/50/v2-dae5faebad_r.jpg&&&figcaption&Serverless 架构也引出了“功能即服务服务”模式,简称 FaaS&/figcaption&&/figure&&p&Serverless 的“功能”可以做任何事,但通常用于处理给定的输入——例如来自 GitHub、Twitter、PayPal、Slack、Jenkins CI pipeline 的事件;或者以树莓派为例,处理像红外运动传感器、激光绊网、温度计等真实世界的传感器的输入。&/p&&p&Serverless 功能能够更好地结合第三方的后端服务,使系统整体的能力大于各部分之和。&/p&&p&了解更多背景信息,可以阅读我最近一偏博文:&a href=&/?target=https%3A//blog.alexellis.io/introducing-functions-as-a-service/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&功能即服务(FaaS)简介&i class=&icon-external&&&/i&&/a&。&/p&&h2&&b&概述&/b&&/h2&&p&我们将使用 &a href=&/?target=https%3A///alexellis/faas& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&OpenFaaS&i class=&icon-external&&&/i&&/a&,它能够让主机或者集群作为支撑 Serverless 功能运行的后端。任何能够使用 Docker 部署的可执行二进制文件、脚本或者编程语言都能在 &a href=&/?target=https%3A///alexellis/faas& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&OpenFaaS&i class=&icon-external&&&/i&&/a& 上运作,你可以根据速度和伸缩性选择部署的规模。另一个优点是,它还内建了用户界面和监控系统。&/p&&p&这是我们要执行的步骤:&/p&&ul&&li&在一个或多个主机上配置 Docker (树莓派 2 或者 3);&/li&&li&利用 Docker Swarm 将它们连接;&/li&&li&部署 &a href=&/?target=https%3A///alexellis/faas& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&OpenFaaS&i class=&icon-external&&&/i&&/a&;&/li&&li&使用 Python 编写我们的第一个功能。&/li&&/ul&&h2&&b&Docker Swarm&/b&&/h2&&p&Docker 是一项打包和部署应用的技术,支持集群上运行,有着安全的默认设置,而且在搭建集群时只需要一条命令。OpenFaaS 使用 Docker 和 Swarm 在你的可用树莓派上传递你的 Serverless 功能。&/p&&p&我推荐你在这个项目中使用带树莓派 2 或者 3,以太网交换机和&a href=&/?target=https%3A//www.amazon.co.uk/Anker-PowerPort-Family-Sized-Technology-Smartphones/dp/B00PK1IIJY& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&强大的 USB 多端口电源适配器&i class=&icon-external&&&/i&&/a&。&/p&&h2&&b&准备 Raspbian&/b&&/h2&&p&把 &a href=&/?target=http%3A//downloads.raspberrypi.org/raspbian/images/raspbian-/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Raspbian Jessie Lite&i class=&icon-external&&&/i&&/a& 写入 SD 卡(8GB 容量就正常工作了,但还是推荐使用 16GB 的 SD 卡)。&/p&&p&&i&注意:不要下载成 Raspbian Stretch 了&/i&&/p&&blockquote&社区在努力让 Docker 支持 Raspbian Stretch,但是还未能做到完美运行。请从&a href=&/?target=http%3A//downloads.raspberrypi.org/raspbian_lite/images/raspbian_lite-/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&树莓派基金会网站&i class=&icon-external&&&/i&&/a&下载 Jessie Lite 镜像。&/blockquote&&p&我推荐使用 &a href=&/?target=https%3A//etcher.io/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Etcher.io&i class=&icon-external&&&/i&&/a& 烧写镜像。&/p&&blockquote&在引导树莓派之前,你需要在引导分区创建名为 &code&ssh&/code& 的空白文件。这样才能允许远程登录。&/blockquote&&h2&&code&接通电源,然后修改主机名&/code&&/h2&&p&现在启动树莓派的电源并且使用 &code&ssh&/code& 连接:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&$ ssh pi@raspberrypi.local
&/code&&/pre&&/div&&p&&br&&/p&&blockquote&默认密码是 &code&raspberry&/code&&/blockquote&&p&使用 &code&raspi-config&/code& 工具把主机名改为 &code&swarm-1&/code& 或者类似的名字,然后重启。&/p&&p&当你到了这一步,你还可以把划分给 GPU (显卡)的内存设置为 16MB。&/p&&h2&&code&现在安装 Docker&/code&&/h2&&p&我们可以使用通用脚本来安装:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&$ curl -sSL
&/code&&/pre&&/div&&blockquote&这个安装方式在将来可能会发生变化。如上文所说,你的系统需要是 Jessie,这样才能得到一个确定的配置。&/blockquote&&p&你可能会看到类似下面的警告,不过你可以安全地忽略它并且成功安装上 Docker CE 17.05:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&WARNING: raspbian is no longer updated @ /
Installing the legacy docker-engine package...
&/code&&/pre&&/div&&p&之后,用下面这个命令确保你的用户帐号可以访问 Docker 客户端:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&$ usermod pi -aG docker
&/code&&/pre&&/div&&blockquote&如果你的用户名不是 &code&pi&/code&,那就把它替换成你的用户名。&/blockquote&&h2&&code&修改默认密码&/code&&/h2&&p&输入 &code&$sudo passwd pi&/code&,然后设置一个新密码,请不要跳过这一步!&/p&&h2&&code&重复以上步骤&/code&&/h2&&p&现在为其它的树莓派重复上述步骤。&/p&&h2&&b&创建你的 Swarm 集群&/b&&/h2&&p&登录你的第一个树莓派,然后输入下面的命令:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&$ docker swarm init
Swarm initialized: current node (3ra7i5ldijsffjnmubmsfh767) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join \
--token SWMTKN-1-496mv9itb7584pzcddzj4zvzzfltgud8k75rvujopw15n3ehzu-af445b08359golnzhncbdj9o3 \
192.168.0.79:2377
&/code&&/pre&&/div&&p&&br&&/p&&p&你会看到它显示了一个口令,以及其它节点加入集群的命令。接下来使用 &code&ssh&/code& 登录每个树莓派,运行这个加入集群的命令。&/p&&p&等待连接完成后,在第一个树莓派上查看集群的节点:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&$ docker node ls
AVAILABILITY
MANAGER STATUS
3ra7i5ldijsffjnmubmsfh767 *
Ready Active Leader
k9mom28s2kqxocfq1fo6ywu63
Ready Active
y2p089bs174vmrlx30gc77h4o
Ready Active
&/code&&/pre&&/div&&p&&br&&/p&&p&恭喜你!你现在拥有一个树莓派集群了!&/p&&h2&&code&更多关于集群的内容&/code&&/h2&&p&你可以看到三个节点启动运行。这时只有一个节点是集群管理者。如果我们的管理节点&i&死机&/i&了,集群就进入了不可修复的状态。我们可以通过添加冗余的管理节点解决这个问题。而且它们依然会运行工作负载,除非你明确设置了让你的服务只运作在工作节点上。&/p&&p&要把一个工作节点升级为管理节点,只需要在其中一个管理节点上运行 &code&docker node promote &node_name&&/code& 命令。&/p&&blockquote&注意: Swarm 命令,例如 &code&docker service ls&/code& 或者 &code&docker node ls&/code& 只能在管理节点上运行。&/blockquote&&p&想深入了解管理节点与工作节点如何保持一致性,可以查阅 &a href=&/?target=https%3A///engine/swarm/admin_guide/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Docker Swarm 管理指南&i class=&icon-external&&&/i&&/a&。&/p&&h2&&b&OpenFaaS&/b&&/h2&&p&现在我们继续部署程序,让我们的集群能够运行 Serverless 功能。&a href=&/?target=https%3A///alexellis/faas& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&OpenFaaS&i class=&icon-external&&&/i&&/a& 是一个利用 Docker 在任何硬件或者云上让任何进程或者容器成为一个 Serverless 功能的框架。因为 Docker 和 Golang 的可移植性,它也能很好地运行在树莓派上。&/p&&p&&br&&/p&&figure&&img src=&/50/v2-9cba2ae45d4f705a2b5d4f31c67c0c8a_b.jpg& data-caption=&& data-rawwidth=&904& data-rawheight=&210& class=&origin_image zh-lightbox-thumb& width=&904& data-original=&/50/v2-9cba2ae45d4f705a2b5d4f31c67c0c8a_r.jpg&&&/figure&&p&&br&&/p&&blockquote&如果你支持 &a href=&/?target=https%3A///alexellis/faas& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&OpenFaaS&i class=&icon-external&&&/i&&/a&,希望你能 &b&星标&/b& &a href=&/?target=https%3A///alexellis/faas& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&OpenFaaS&i class=&icon-external&&&/i&&/a& 的 GitHub 仓库。&/blockquote&&p&登录你的第一个树莓派(你运行 &code&docker swarm init&/code& 的节点),然后部署这个项目:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&$ git clone /alexellis/faas/
$ ./deploy_stack.armhf.sh
Creating network func_functions
Creating service func_gateway
Creating service func_prometheus
Creating service func_alertmanager
Creating service func_nodeinfo
Creating service func_markdown
Creating service func_wordcount
Creating service func_echoit
&/code&&/pre&&/div&&p&你的其它树莓派会收到 Docer Swarm 的指令,开始从网上拉取这个 Docker 镜像,并且解压到 SD 卡上。这些工作会分布到各个节点上,所以没有哪个节点产生过高的负载。&/p&&p&这个过程会持续几分钟,你可以用下面指令查看它的完成状况:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&$ watch 'docker service ls'
57ine9c10xhp
func_wordcount
replicated
functions/alpine:latest-armhf
d979zipx1gld
func_prometheus
replicated
alexellis2/prometheus-armhf:1.5.2 *:/tcp
f9yvm0dddn47
func_echoit
replicated
functions/alpine:latest-armhf
lhbk1fc2lobq
func_markdown
replicated
functions/markdownrender:latest-armhf
pj814yluzyyo
func_alertmanager
replicated
alexellis2/alertmanager-armhf:0.5.1 *:/tcp
q4bet4xs10pk
func_gateway
replicated
functions/gateway-armhf:0.6.0 *:/tcp
v9vsvx73pszz
func_nodeinfo
replicated
functions/nodeinfo:latest-armhf
&/code&&/pre&&/div&&p&我们希望看到每个服务都显示 “1/1”。&/p&&p&你可以根据服务名查看该服务被调度到哪个树莓派上:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&$ docker service ps func_markdown
func_markdown.1
functions/markdownrender:latest-armhf
&/code&&/pre&&/div&&p&状态一项应该显示 &code&Running&/code&,如果它是 &code&Pending&/code&,那么镜像可能还在下载中。&/p&&p&在这时,查看树莓派的 IP 地址,然后在浏览器中访问它的 8080 端口:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&$ ifconfig
&/code&&/pre&&/div&&p&例如,如果你的 IP 地址是 192.168.0.100,那就访问 &a href=&/?target=http%3A//192.168.0.100%3A8080/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&http://192.168.0.100:8080&i class=&icon-external&&&/i&&/a& 。&/p&&p&这是你会看到 FaaS UI(也叫 API 网关)。这是你定义、测试、调用功能的地方。&/p&&p&点击名称为 “func_markdown” 的 Markdown 转换功能,输入一些 Markdown(这是 Wikipedia 用来组织内容的语言)文本。&/p&&p&然后点击 “invoke”。你会看到调用计数增加,屏幕下方显示功能调用的结果。&/p&&p&&br&&/p&&figure&&img src=&/50/v2-e663a26e8b0f0f1aa2c2_b.jpg& data-caption=&& data-rawwidth=&969& data-rawheight=&848& class=&origin_image zh-lightbox-thumb& width=&969& data-original=&/50/v2-e663a26e8b0f0f1aa2c2_r.jpg&&&/figure&&p&&br&&/p&&h2&&b&部署你的第一个 Serverless 功能:&/b&&/h2&&p&这一节的内容已经有相关的教程,但是我们需要几个步骤来配置树莓派。&/p&&h2&&code&获取 FaaS-CLI&/code&&/h2&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&$ curl -sSL
Getting package /alexellis/faas-cli/releases/download/0.4.5-b/faas-cli-armhf
&/code&&/pre&&/div&&h2&&code&下载样例&/code&&/h2&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&$ git clone /alexellis/faas-cli
$ cd faas-cli
&/code&&/pre&&/div&&h2&&code&为树莓派修补样例模版&/code&&/h2&&p&我们临时修改我们的模版,让它们能在树莓派上工作:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&$ cp template/node-armhf/Dockerfile template/node/
$ cp template/python-armhf/Dockerfile template/python/
&/code&&/pre&&/div&&p&这么做是因为树莓派和我们平时关注的大多数计算机使用不一样的处理器架构。&/p&&blockquote&了解 Docker 在树莓派上的最新状况,请查阅: &a href=&/?target=https%3A//blog.alexellis.io/5-things-docker-rpi/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&你需要了解的五件事&i class=&icon-external&&&/i&&/a&。&/blockquote&&p&现在你可以跟着下面为 PC、笔记本和云端所写的教程操作,但我们在树莓派上要先运行一些命令。&/p&&ul&&li&&a href=&/?target=https%3A//blog.alexellis.io/first-faas-python-function& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&使用 OpenFaaS 运行你的第一个 Serverless Python 功能&i class=&icon-external&&&/i&&/a&&/li&&/ul&&p&注意第 3 步:&/p&&ul&&li&把你的功能放到先前从 GitHub 下载的 &code&faas-cli&/code& 文件夹中,而不是 &code&~/functinos/hello-python&/code& 里。&/li&&li&同时,在 &code&stack.yml&/code& 文件中把 &code&localhost&/code& 替换成第一个树莓派的 IP 地址。&/li&&/ul&&p&集群可能会花费几分钟把 Serverless 功能下载到相关的树莓派上。你可以用下面的命令查看你的服务,确保副本一项显示 “1/1”:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&$ watch 'docker service ls'
pv27thj5lftz
hello-python
replicated
alexellis2/faas-hello-python-armhf:latest
&/code&&/pre&&/div&&p&&b&继续阅读教程:&/b& &a href=&/?target=https%3A//blog.alexellis.io/first-faas-python-function& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&使用 OpenFaaS 运行你的第一个 Serverless Python 功能&i class=&icon-external&&&/i&&/a&&/p&&p&关于 Node.js 或者其它语言的更多信息,可以进一步访问 &a href=&/?target=https%3A///alexellis/faas& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&FaaS 仓库&i class=&icon-external&&&/i&&/a&。&/p&&h2&&b&检查功能的指标&/b&&/h2&&p&既然使用 Serverless,你也不想花时间监控你的功能。幸运的是,OpenFaaS 内建了 &a href=&/?target=https%3A//prometheus.io/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Prometheus&i class=&icon-external&&&/i&&/a& 指标检测,这意味着你可以追踪每个功能的运行时长和调用频率。&/p&&h2&&code&指标驱动自动伸缩&/code&&/h2&&p&如果你给一个功能生成足够的负载,OpenFaaS 将自动扩展你的功能;当需求消失时,你又会回到单一副本的状态。&/p&&p&这个请求样例你可以复制到浏览器中:&/p&&p&只要把 IP 地址改成你的即可。&/p&&p&&br&&/p&&figure&&img src=&/50/v2-752fdc5f5ed9b0cf52cd54_b.jpg& data-caption=&& data-rawwidth=&689& data-rawheight=&532& class=&origin_image zh-lightbox-thumb& width=&689& data-original=&/50/v2-752fdc5f5ed9b0cf52cd54_r.jpg&&&/figure&&p&&br&&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&http://192.168.0.25:9090/graph?g0.range_input=15m&g0.stacked=1&g0.expr=rate(gateway_function_invocation_total%5B20s%5D)&g0.tab=0&g1.range_input=1h&g1.expr=gateway_service_count&g1.tab=0
&/code&&/pre&&/div&&p&这些请求使用 PromQL(Prometheus 请求语言)编写。第一个请求返回功能调用的频率:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&rate(gateway_function_invocation_total[20s])
&/code&&/pre&&/div&&p&第二个请求显示每个功能的副本数量,最开始应该是每个功能只有一个副本。&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&gateway_service_count
&/code&&/pre&&/div&&p&如果你想触发自动扩展,你可以在树莓派上尝试下面指令:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&$ while [ true ]; do curl -4 localhost:8080/function/func_echoit --data &hello world& ; done
&/code&&/pre&&/div&&p&查看 Prometheus 的 “alerts” 页面,可以知道你是否产生足够的负载来触发自动扩展。如果没有,你可以尝试在多个终端同时运行上面的指令。&/p&&p&&br&&/p&&figure&&img src=&/50/v2-ed70fef6beed_b.jpg& data-caption=&& data-rawwidth=&736& data-rawheight=&338& class=&origin_image zh-lightbox-thumb& width=&736& data-original=&/50/v2-ed70fef6beed_r.jpg&&&/figure&&p&&br&&/p&&p&当你降低负载,副本数量显示在你的第二个图表中,并且 &code&gateway_service_count&/code& 指标再次降回 1。&/p&&h2&&b&结束演讲&/b&&/h2&&p&我们现在配置好了 Docker、Swarm, 并且让 OpenFaaS 运行代码,把树莓派像大型计算机一样使用。&/p&&blockquote&希望大家支持这个项目,&b&星标&/b& &a href=&/?target=https%3A///alexellis/faas& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&FaaS 的 GitHub 仓库&i class=&icon-external&&&/i&&/a&。&/blockquote&&p&你是如何搭建好了自己的 Docker Swarm 集群并且运行 OpenFaaS 的呢?在 Twitter &a href=&/?target=https%3A///alexellisuk& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&@alexellisuk&i class=&icon-external&&&/i&&/a& 上分享你的照片或推文吧。&/p&&p&&b&观看我在 Dockercon 上关于 OpenFaaS 的视频&/b&&/p&&p&我在 &a href=&/?target=https%3A//blog.alexellis.io/dockercon-2017-captains-log/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Austin 的 Dockercon&i class=&icon-external&&&/i&&/a& 上展示了 OpenFaaS。——观看介绍和互动例子的视频: &a href=&/?target=https%3A///embed/-h2VTE9WnZs& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&https://www.&/span&&span class=&visible&&/embed/-h2VT&/span&&span class=&invisible&&E9WnZs&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&&/p&&p&有问题?在下面的评论中提出,或者给我发邮件,邀请我进入你和志同道合者讨论树莓派、Docker、Serverless 的 Slack channel。&/p&&p&&b&想要学习更多关于树莓派上运行 Docker 的内容?&/b&&/p&&p&我建议从 &a href=&/?target=https%3A//blog.alexellis.io/5-things-docker-rpi/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&你需要了解的五件事&i class=&icon-external&&&/i&&/a& 开始,它包含了安全性、树莓派和普通 PC 间微妙差别等话题。&/p&&ul&&li&&a href=&/?target=https%3A//blog.alexellis.io/dockercon-tips-docker-raspberry-pi/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Dockercon tips: Docker & Raspberry Pi&i class=&icon-external&&&/i&&/a&&/li&&li&&a href=&/?target=https%3A//blog.alexellis.io/gpio-on-swarm/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Control GPIO with Docker Swarm&i class=&icon-external&&&/i&&/a&&/li&&li&&a href=&/?target=https%3A//blog.alexellis.io/docker-engine-in-your-pocket/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Is that a Docker Engine in your pocket??&i class=&icon-external&&&/i&&/a&&/li&&/ul&&hr&&p&via: &a href=&/?target=https%3A//blog.alexellis.io/your-serverless-raspberry-pi-cluster/& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&https://&/span&&span class=&visible&&blog.alexellis.io/your-&/span&&span class=&invisible&&serverless-raspberry-pi-cluster/&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&&/p&&p&作者:&a href=&/?target=https%3A///alexellisuk& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Alex Ellis&i class=&icon-external&&&/i&&/a& 译者:&a href=&/?target=https%3A///haoqixu& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&haoqixu&i class=&icon-external&&&/i&&/a& 校对:&a href=&/?target=https%3A///wxy& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&wxy&i class=&icon-external&&&/i&&/a&&/p&&p&本文由 &a href=&/?target=https%3A///LCTT/TranslateProject& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&LCTT&i class=&icon-external&&&/i&&/a& 原创编译,&a href=&/?target=https%3A///& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Linux中国&i class=&icon-external&&&/i&&/a& 荣誉推出&/p&
这篇博文将向你展示如何使用 Docker 和
框架构建你自己的 Serverless 树莓派集群。大家常常问我能用他们的集群来做些什么?而这个应用完美匹配卡片尺寸的设备——只需添加更多的树莓派就能获取更强的计算能力。“Serverless” (无服务器)是事件…
&figure&&img src=&/50/v2-13eb5e9dfb7cddf5_b.jpg& data-rawwidth=&3264& data-rawheight=&2448& class=&origin_image zh-lightbox-thumb& width=&3264& data-original=&/50/v2-13eb5e9dfb7cddf5_r.jpg&&&/figure&&blockquote&场景需求:家里的几台树莓派通过家用WIFI路由器上网,虽然装了Teamviewer可以远程穿透内网控制图形界面,但远程时屏幕分辨率太小,体验不佳,于是想让树莓派上的SSH也能拥有穿透内网的功能。&/blockquote&&p&原文链接来自我的博客,欢迎访问:&a href=&/?target=https%3A///article/show/raspberry-ngrok& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Windows VPS上部署Ngrok服务器,实现多平台客户端(树莓派)SSH内网穿透&i class=&icon-external&&&/i&&/a&&/p&&h2&前言,关于Ngrok&/h2&&p&查阅了很多资料,发现大多数内网穿透功能的实现都与一款Go语言编写的Ngrok项目相关,Ngrok是一整套的服务器,客户端解决方案。因为其是由Go语言编写的,所以天生具备很强的跨平台能力(但目前基本上所有资料都指向在Linux上部署该服务器端)。博主使用的是阿里云的Windows VPS,并且这段时间正好也在使用Go编程,因此这篇文章将具体介绍如何在Windows上部署Ngrok项目,并且在家用树莓派上部署客户端,实现树莓派的SSH内网穿透。&/p&&p&关于Ngrok,值得注意的有以下几点:&/p&&ul&&li&Ngrok并不仅仅用来22端口的SSH内网穿透,通过简单配置,它可以将遵循TCP/UDP协议的多个端口进行内网穿透。&/li&&li&Ngrok是由一台服务器端和一个或者多个客户端组成的体系。&/li&&li&Ngrok需要一台部署在公网固定IP上的服务器,最好有可正常指向的域名,Ngrok的服务器端就部署在上面,如本次实验的阿里云主机。&/li&&li&Ngrok的客户端装在需要映射的各个没有公网IP的机器上,比如本次实验的树莓派。&/li&&li&Ngrok服务器会在接受到Ngrok客户端请求时分配固定或者随机的端口号,将客户端请求的端口与之映射,从而达到内网穿透的目的。&/li&&li&用户在远程使用SSH客户端进行连接时,不需要任何Ngrok程序,对终端用户来说,Ngrok是透明的。&/li&&li&&a href=&/?target=https%3A///& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Ngrok&i class=&icon-external&&&/i&&/a&自身有一台欧洲的公网服务器,供没有VPS的用户注册使用,该服务器并不是以分配端口的方式映射,而是以分配子域名的方式,随机子域名是免费使用的,固定子域名映射是收费的。&/li&&li&普通玩家可以直接使用&a href=&/?target=https%3A///& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Ngrok的官网&i class=&icon-external&&&/i&&/a&服务器,缺点就是有一点点慢,而且每次客户端重启后子域名会随之变化,无法固定使用。&/li&&li&国内也有一些商家提供了Ngrok服务,比如&a href=&/?target=https%3A//www.ngrok.cc/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Sunny-Ngrok&i class=&icon-external&&&/i&&/a&,同样是收费的,速度可能快一点。&/li&&/ul&&p&Ngrok源代码是开源的,部署在&a href=&/?target=https%3A///mamboer/ngrok& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Git&i class=&icon-external&&&/i&&/a&上,但是博主使用下来略觉繁琐,涉及到很多自认为没必要使用的技术,后期我重新在Git上发布了我重构后的&a href=&/?target=https%3A///newflydd/ngrok& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Ngrok项目&i class=&icon-external&&&/i&&/a&,以供其他朋友直接使用诸如go build或者go install简单命令进行跨平台编译和安装。&/p&&p&为了致敬原作者,我们对这些高端的Golang编程技术做一个简单的了解,对Go语言没有兴致的朋友可以直接跳过下面这段:&/p&&ul&&li&&i&go-bindata&/i& 技术,该技术是一套将任意资源文件转成二进制数据反向生成到Go代码供hash调用的技术,Ngrok的源码利用这一技术将公网证书和密钥,以及站点的HTML生成到go代码中去了,使其变成了一堆byte数组,在程序中hash调用。这么做固然有它的好处,但缺点也显而易见,因为这套技术要提前用一个项目的程序生成另一个项目的Go代码,所以编译起来难免繁琐,于是Ngrok提供了makefile文件以供用户make编译,这就有点尴尬了,本来好好的跨平台Go语言项目,被make和makefile活生生憋成了只能Linux使用的了。博主初期使用时硬着头皮安装了Cygwin,以及其中的make命令,个中的苦逼无以言表,索性后来了解原理后,将官方的Ngrok重构了一遍,避免了使用几乎是专属于Linux的make指令。&/li&&li&&i&build -tags&/i& 技术,通过Ngrok项目,我第一次知道Go的这个特性,可以在代码顶端加上// +build !release等标记,注明编译时的模式,比如前面这种表达方式,就是在非&i&release&/i&编译模式下才会编译这个文件,然后使用go build -tags 'release'或者go build -tags 'debug'来控制是否编译这个代码文件。这个特性确实灵活,可以在项目中编写不同的编译模式下的代码,缺点呢,就是没有详细文档的情况下,第三方用户并不知道有哪些编译模式,加大了源码本地编译的复杂度,所以这也是原版Ngrok项目使用makefile文件的原因之一。&/li&&li&&i&&a href=&/?target=https%3A//www.equinox.io/& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&equinox.io&i class=&icon-external&&&/i&&/a&&/i& 技术,这项技术可以让Go代码在编译和运行期间保持更新,代码作者更新代码后,能够在第三方用户实时更新,具体没有了解,我看原版Ngrok在进行&i&release&/i&编译时增加了很多&i&&a href=&/?target=http%3A//equinox.io& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&equinox.io&/span&&span class=&invisible&&&/span&&i class=&icon-external&&&/i&&/a&&/i&令牌密钥,以连接远程仓库,保证代码更新。&/li&&/ul&&p&总之,上面的这些特性,虽然优点多多,但使用起来难免加大了难度,并且牺牲了Go优良的跨平台特性,这是我不能忍的,于是我重新构造了Ngrok项目,旨在让更多玩家,在众多平台上简单轻松的编译Ngrok项目。&/p&&h2&言归正传,准备工作&/h2&&p&下面我们言归正传,从零开始部署Ngrok,说说准备工作:&/p&&h2&硬件部分&/h2&&ul&&li&一台公网IP服务器,本实验采用Windows系统,拥有域名&a href=&/?target=http%3A//& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&&/span&&span class=&invisible&&&/span&&i class=&icon-external&&&/i&&/a&。&/li&&li&一台装有RASPBIAN操作系统的树莓派,用来部署Ngrok客户端,使其可以SSH内网穿透&/li&&li&一台Windows PC,开发环境&/li&&/ul&&h2&软件部分&/h2&&ul&&li&&a href=&/?target=http%3A///download/Win32OpenSSL_Light-1_1_0f.exe& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Win32 OpenSSL v1.1.0f Light&i class=&icon-external&&&/i&&/a&证书生成程序&/li&&li&&a href=&/?target=https%3A//download.mobatek.net/03227/MobaXterm_Portable_v10.4.zip& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&MobaXterm&i class=&icon-external&&&/i&&/a&几乎是最好的SSH客户端&/li&&li&&a href=&/?target=https%3A///edgedl/go/go1.9.2.windows-amd64.msi& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&go1.9.2.windows-amd64.msi&i class=&icon-external&&&/i&&/a&Go语言编译器,我现在用得最多的语言,一股子的亲切感,交叉编译Linux,ARM,X86等平台的目标程序就跟玩一样&/li&&li&&a href=&/?target=https%3A///newflydd/ngrok& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Ngrok源码&i class=&icon-external&&&/i&&/a&这是我自己重构的Ngrok项目,原版的要想用起来还得安装Cygwin等一堆工具,现在非常纯净,拿到手直接用最简单的命令编译,各平台通吃。这份代码不需要手工download,下面会介绍直接用命令获取。&/li&&li&&a href=&/?target=https%3A///git-for-windows/git/releases/download/v2.14.3.windows.1/Git-2.14.3-64-bit.exe& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Git-windows-amd64&i class=&icon-external&&&/i&&/a&这个就不赘述了,程序猿都知道。&/li&&/ul&&h2&从零开始操作&/h2&&h2&证书生成&/h2&&p&Ngrok需要使用SSL证书确保穿透过程中的通信是加密安全的,因此需要SSL证书,值得庆幸的是并不强制去购买CA认证机构颁发的证书,普通用户直接使用OpenSLL工具就可以自行生成证书。方法如下:&/p&&ul&&li&下载上述准备工作软件部分的SSL证书生成程序,安装后,将安装路径下的bin目录添加到环境变量,方便cmd直接运行openssl.exe。&/li&&li&任意路径打开cmd,执行下面命令:(注意,将两处MY_DOMAIN全部替换成自己的域名,比如我的&a href=&/?target=http%3A//& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&&/span&&span class=&invisible&&&/span&&i class=&icon-external&&&/i&&/a&)openssl genrsa -out rootCA.key 2048&br&openssl req -x509 -new -nodes -key rootCA.key -subj &/CN=%MY_DOMAIN%& -days 5000 -out rootCA.pem&br&openssl genrsa -out device.key 2048&br&openssl req -new -key device.key -subj &/CN=%MY_DOMAIN%& -out device.csr&br&openssl x509 -req -in device.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out device.crt -days 5000&/li&&li&全部执行完毕后,会在当前路径下生成6个文件,我们服务器端会用到其中的 &i&snakeoil.crt&/i& , &i&snakeoil.key&/i& ,客户端会用到 &i&ngrokroot.crt&/i& 文件,先不管它们,留到下面使用。&/li&&/ul&&h2&编译Windows平台下的服务器端程序&/h2&&p&得益于Go的众多优秀的特性,让一份跨平台的代码能够快速地适配不同平台编译和安装。相比其他语言不同的版本,不同的编译方式,编译工具,甚至有些是超级重量级的,比如JAVA,各个平台下的JDK少说也要300M,Go的编译器全平台覆盖,并且只有90M左右,非常轻巧,并且只需要在某一平台下下载一次,就可以轻松靠着两个环境变量编译出全平台覆盖的可执行程序,交叉编译从未如此简单过。&/p&&p&一聊起Go的优点,我就差点收不住。我们来实际体验一下吧,在上方准备工作软件部分下载Go的Windows平台编译器,按照提示安装,设置Windows环境变量PATH路径添加Go安装目录下的bin文件夹,方便cmd中直接使用go命令,为了还能直接使用go get命令,我们需要安装Git,下载地址在上方,下载回来直接根据提示全部以默认选项安装即可。&br&另外需要配置GOPATH,GOROOT两个环境变量,这两个并不是必须的,但为了减少麻烦还是建议设置,其中GOROOT变量指向Go的安装路径,比如C:\GoRoot,GOPATH是我们的工作区路径,随意填写,写完了就在此路径下编写程序就行了,当然如果你仅仅用来完成这个项目,以后不会学习Go也不会编写Go语言的代码,这个路径对你来说仅仅是接下来自动下载源代码的保存路径而已。这里我们简单设置成C:\GoPath。&br&如图所示:&br&&/p&&img src=&/50/v2-0aa682c7ae7d56fca5d8de_b.jpg& data-caption=&& data-rawwidth=&824& data-rawheight=&779& class=&origin_image zh-lightbox-thumb& width=&824& data-original=&/50/v2-0aa682c7ae7d56fca5d8de_r.jpg&&&p&&br&&/p&&p&OK,接下来正式下载,编译,和安装Ngrok的服务器端。&br&你一定会以为这一系列操作很复杂,其实对于Go来说仅仅是一条命令行的指令:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&go /newflydd/ngrok/main/ngrokd
&/code&&/pre&&/div&&p&就这么简单,就这么神奇,简单到你不管在什么路径下执行这行命令都没有问题。这行命令的背后可不简单,go首先会去下载我上传到git上的Ngrok代码,然后试着编译,编译过程中它会发现Ngrok项目还七零八落地依赖了其他各个项目,于是Go用递归的方式再去执行go get命令,直到将所有依赖通通下载回来,最终它成功编译后,将生成的目标程序存放在%GOPATH%\bin目录下,默认情况下它是根据当前机器的环境来生成可执行文件,如果做一些简单的调整,它即可以交叉编译不同平台下的可执行文件。&/p&&p&执行过程可能会有些漫长,跟网络环境相关,建议使用全局科学上网工具。&br&成功编译后,在%GOPATH%\bin目录下会出现ngrokd.exe可执行程序,这就是你要上传到Windows服务器的程序,大小在8M左右,同时你需要上传第一步生成SSL证书中的 &i&snakeoil.crt&/i& , &i&snakeoil.key&/i& 两份文件到同目录。ngrokd.exe双击直接运行是没有意义的,它需要配有参数,因此我们编写bat脚本来方便运行(将下面的MY_DOMAIN替换成自己的域名,比如我的&a href=&/?target=http%3A//& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&&/span&&span class=&invisible&&&/span&&i class=&icon-external&&&/i&&/a&):&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&ngrokd.exe -domain=&MY_DOMAIN& -log ./ngrokd.log &
&/code&&/pre&&/div&&p&将上面脚本保存为run.bat,双击运行是一个命令行界面,同目录下会出现ngrokd.log,打开看一眼,如果出现以下字样,就说明服务器端程序已经正常运行了:&/p&&p&Listening for public http connections on [::]:80&br&Listening for public https connections on [::]:443&br&Listening for control and proxy connections on [::]:4443&/p&&p&运行时的画面如下:&br&&/p&&img src=&/50/v2-f200f91526d1fcb1eabbca5_b.jpg& data-caption=&& data-rawwidth=&693& data-rawheight=&338& class=&origin_image zh-lightbox-thumb& width=&693& data-original=&/50/v2-f200f91526d1fcb1eabbca5_r.jpg&&&p&&br&&/p&&h2&编译Linux ARM平台下的树莓派客户端&/h2&&p&试想一下,如果没有交叉编译,我们该如何在树莓派上安装Ngrok客户端:我们必须同样在树莓派上安装Go的Linux ARM版的编译器;RASPBIAN系统已经安装了git,所以我们不需要独立安装git;我们还得用go get指令下载和编译Ngrok的源码;openssl指令不用装了,因为证书已经生成了。&/p&&p&虽然也不是特别复杂,但还是挺费时间的,而且还会占用树莓派的资源,平白无故地要去安装接近90M的Go编译环境。得益于Go的强大,交叉编译发挥了巨大作用,我们在Windows X86 AMD64上就能编译出能在Linux ARM上跑的可执行文件。&/p&&p&打开一个新的cmd命令行,任意路径,执行下面命令:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&set GOOS=linux
set GOARCH=arm
go /newflydd/ngrok/main/ngrok
&/code&&/pre&&/div&&p&OK,就这么简单,就这么神奇,Windows AMD64上的Go利用简单的两个环境变量,直接构造出了Linux ARM上的可执行文件,多么伟大的语言。。。&br&GOOS GOARCH的组合可以参照:&br&| GOOS | GOARCH |&br&| —————— | —————— |&br&| darwin | 386 |&br&| darwin | amd64 |&br&| freebsd | 386 |&br&| freebsd | amd64 |&br&| linux | 386 |&br&| linux | amd64 |&br&| linux | arm |&br&| windows | 386 |&br&| windows | amd64 |&/p&&h2&在树莓派中运行Ngrok客户端程序&/h2&&p&Go将生成的Linux平台下的程序保存在%GOPATH%\bin\linux_arm目录下,名为ngrok,我们需要将其copy到树莓派中。&br&我们使用超级强大的终端工具MobaXterm来连接树莓派并上传ngrok,MobaXterm的下载地址在本文上方,下载后按照提示就能安装,因为目前树莓派的SSH还不具备内网穿透功能,因此下面操作必须在局域网中完成。&/p&&p&使用MobaXterm建立与树莓派的SSH连接,这里并不是重点,相关操作如果不清楚可以自行百谷。&br&MobaXterm具有强大的文件上传功能,直接将使用下面图例中的按钮将Windows本地的ngrok客户端程序上传到指定目录,同时将我们第一步SSL证书环节生成的 &i&ngrokroot.crt&/i& 文件上传进去。&br&&/p&&img src=&/50/v2-52afae132adafb_b.jpg& data-caption=&& data-rawwidth=&919& data-rawheight=&499& class=&origin_image zh-lightbox-thumb& width=&919& data-original=&/50/v2-52afae132adafb_r.jpg&&&p&&br&&/p&&p&我这里操作的目录为:/home/pi/workspace/go-apps/ngrok/,此时上传上去的ngrok文件不具备执行能力,需要使用下面命令为其添加执行权限:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&chmod a+x ngrok
&/code&&/pre&&/div&&p&同样,ngrok程序不可以直接运行,也需要参数,并且还需要一个配置文件,我们执行下面操作新建配置文件,并编写sh脚本,以便直接运行。&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&nano ngrok.cfg
&/code&&/pre&&/div&&p&新建ngrok.cfg配置文件,并用nano文本编辑器打开,输入以下文本(将MY_DOMAIN替换成自己的域名,比如我的&a href=&/?target=http%3A//& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&&/span&&span class=&invisible&&&/span&&i class=&icon-external&&&/i&&/a&):&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&server_addr: &MY_DOMAIN:4443&
trust_host_root_certs: false
remote_port: 50000
&/code&&/pre&&/div&&p&我这里仅仅需要让SSH的22端口具备穿透能力,因此我只配置了ssh任务,指定了远程端口固定为50000,映射本地的SSH22端口。Ctrl+O并回车保存,Ctrl+X退出文本编辑器。&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&nano run.sh
&/code&&/pre&&/div&&p&新建run.sh脚本文件,并用文本编辑器打开,输入以下文本:&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&nohup ./ngrok -log ./ngrok.ssh.log -config ./ngrok.cfg start ssh &
&/code&&/pre&&/div&&p&Ctrl+O并回车保存,Ctrl+X退出文本编辑器。&/p&&div class=&highlight&&&pre&&code class=&language-text&&&span&&/span&chmod a+x run.sh
&/code&&/pre&&/div&&p&为run.sh添加可执行权限。OK,大功告成,运行./run.sh即可建立树莓派与公网服务器的通信隧道,将其22端口映射到了公网服务器的50000端口,我们接下来就可以在世界任何角落,使用任何SSH工具,连接自己公网服务器的50000端口,访问家中的树莓派了,下图用MobaXterm做一个测试:&br&&/p&&img src=&/50/v2-77862e6affeeb_b.jpg& data-caption=&& data-rawwidth=&1019& data-rawheight=&724& class=&origin_image zh-lightbox-thumb& width=&1019& data-original=&/50/v2-77862e6affeeb_r.jpg&&&p&&br&&/p&&p&&br&&/p&&img src=&/50/v2-dee89fbda5a95464e2da_b.jpg& data-caption=&& data-rawwidth=&1107& data-rawheight=&675& class=&origin_image zh-lightbox-thumb& width=&1107& data-original=&/50/v2-dee89fbda5a95464e2da_r.jpg&&&p&&/p&
场景需求:家里的几台树莓派通过家用WIFI路由器上网,虽然装了Teamviewer可以远程穿透内网控制图形界面,但远程时屏幕分辨率太小,体验不佳,于是想让树莓派上的SSH也能拥有穿透内网的功能。原文链接来自我的博客,欢迎访问:
&figure&&img src=&/50/v2-092ac8ad3a36c0a789c4c1_b.jpg& data-rawwidth=&2288& data-rawheight=&1712& class=&origin_image zh-lightbox-thumb& width=&2288& data-original=&/50/v2-092ac8ad3a36c0a789c4c1_r.jpg&&&/figure&&p&&/p&&blockquote&&b&从熊猫说起&/b&&/blockquote&&p&&br&&/p&&figure&&img src=&/v2-a22e2b88cdece9e9c8358_b.jpg& data-caption=&& data-rawwidth=&1413& data-rawheight=&549& class=&origin_image zh-lightbox-thumb& width=&1413& data-original=&/v2-a22e2b88cdece9e9c8358_r.jpg&&&/figure&&p&熊猫家族经过万年的迁徙与进化,最后主要保存了如下三支:&/p&&ol&&li&大熊猫:主要生活在温室/动物园。 野外生存技能基本退化,就连XXOO都要外界协助完成,没有人工繁殖以及各种保护措施,它们应该早灭绝了(谁叫这么萌呢)。&/li&&li&黑熊/棕熊:主要生活在 森林(这就是大家熟悉的熊大熊二),爱吃蜂蜜,你总得学会爬树吧。&/li&&li&北极熊:主要生活在北极 极寒地区,所以皮糙肉厚,还能下水捕食。&/li&&/ol&&p&不同的生活环境,练就了他们不同的生存本领。&/p&&p&&br&&/p&&blockquote&&b&要知道路由器和三层交换机的区别,就先搞明白他们的应用场景,如图&/b&:&/blockquote&&figure&&img src=&/v2-582a9a0e050ceb85a35ac2df5938387f_b.jpg& data-caption=&& data-rawwidth=&688& data-rawheight=&497& class=&origin_image zh-lightbox-thumb& width=&688& data-original=&/v2-582a9a0e050ceb85a35ac2df5938387f_r.jpg&&&/figure&&p&&br&&/p&&p&常见园区网中,&/p&&p&路由器用于网络出口(几万人的园区,可能只有2台出口路由器)&/p&&p&三层交换机用于汇聚节点和核心(几万人的园区,有几十台 三层交换机做汇聚/核心交换机)&/p&&p&一些基础功能,如OSPF/BGP/MPLS,路由器和三层交换机均能很好支持。&/p&&p&&br&&/p&&p&&br&&/p&&p&正是由于路由器和三层交换机使用位置的不同,塑造他们的差异化:&/p&&ol&&li&接口形态:路由器用于连接运营商,运营商甩给用户的线路可以有ATM、POS、CPOS、以太网等多种线路,路由器都需要支持;而我们平时所说的三层交换机一般只支持以太网接口,接口数量非常多(毕竟用在园区内部)&/li&&li&功能:路由器用于园区出口,承担访问互联网的功能,支持NAT/IPSEC等功能;这些功能90%的三层交换机是不支持的。&/li&&li&性能:三层交换机组建的是内部高速路,到了出口路由器就进入国道了。交换机上10G/40G/100G接口都可以灵活扩展;而一般园区网出口路由器不需要太高性能,够用即可,就算插个100G板卡,也买不起运营商100G链路呀,太贵!&/li&&li&成本:高端路由器比高端交换机价格贵,路由器单接口成本也更高。支持500个接口的交换机很多,但能有500个接口的路由器已经非常贵了。&/li&&li&厂商情况:思科是做路由器起家,后来收购了Catalyst,开始出交换机;华为重点运营商,运营商/金融/公安这类纵向网,都是路由器大户,所以至今华为的路由器也比交换机做得好;新华三数通优势在交换机,毕竟全球第一款交换机就是他的前 前 前 东家3COM公司搞出来的;迈普以前重点行业是金融、运营商低端设备,路由器做得比交换机好;锐捷重点校园网,应该是最大的园区网了吧,也是交换机起家。&/li&&/ol&&p&&/p&&p&&/p&&p&&/p&&p&&/p&&p&&/p&&p&&/p&
从熊猫说起 熊猫家族经过万年的迁徙与进化,最后主要保存了如下三支:大熊猫:主要生活在温室/动物园。 野外生存技能基本退化,就连XXOO都要外界协助完成,没有人工繁殖以及各种保护措施,它们应该早灭绝了(谁叫这么萌呢)。黑熊/棕熊:主要生活在 森林(…
&figure&&img src=&/50/v2-9d3bd06af11260dec7d8_b.jpg& data-rawwidth=&801& data-rawheight=&233& class=&origin_image zh-lightbox-thumb& width=&801& data-original=&/50/v2-9d3bd06af11260dec7d8_r.jpg&&&/figure&&h2&前言&/h2&&p&在我国,由于网民众多,运营商无法保证为每一个宽带用户提供全球唯一的公网IPv4地址。因此很多用户会发现通过路由器端查看到的WAN端IP与百度“IP”关键词所得到的IP不一致,并且前者的IP为一个私有IP。&/p&&p&而还有一些情况下,公网IP比较昂贵,企业虽然本身也持有少量的独立的公网IP,但是由于成本限制无法为企业内每一台主机都提供一个公网IP,或者内网并不是所有服务都需要暴露到公网中进行访问,那么企业有可能就会使用NAT技术将大量的内网IP通过一定规则映射到公网IP上。而最常见的其中一种技术就是NAPT,也叫“网络端口地址转换”。因为一般一个服务都是通过一个端口来提供,因此通过这种方式可以将特定的服务通过特定的规则开放到少量的公网IP上。&/p&&h2&问题&/h2&&p&但是有的时候我们个人宽带用户也想将自己的服务发布到公网IP上。比如说我们做了一个很漂亮的网站想发布到互联网上供大家参观,在没有公网IP的情况下该怎么实现呢?&/p&&p&还有的时候我们在对企业做渗透测试的时候,发现企业某台公网服务器只对公网开放了常见的80端口,而我们提权时需要用到的3389等端口没有对公网开放,这个时候又该怎么办呢?&/p&&p&解决这些问题的方式就是内网穿透了。&/p&&h2&NAPT原理&/h2&&p&简单来说,在NAT网关上会有一张映射表,表上记录了内网向公网哪个IP和端口发起了请求,然后如果内网有主机向公网设备发起了请求,内网主机的请求数据包传输到了NAT网关上,那么NAT网关会修改该数据包的源IP地址和源端口为NAT网关自身的IP地址和任意一个不冲突的自身未使用的端口,并且把这个修改记录到那张映射表上。最后把修改之后的数据包发送到请求的目标主机,等目标主机发回了响应包之后,再根据响应包里面的目的IP地址和目的端口去映射表里面找到该转发给哪个内网主机。这样就实现了内网主机在没有公网IP的情况下,通过NAPT技术借助路由器唯一的一个公网IP来访问公网设备。&/p&&p&具体原理我到网上找了一张图片&/p&&figure&&img src=&/v2-8c765ffbcd_b.jpg& data-caption=&& data-rawwidth=&709& data-rawheight=&443& class=&origin_image zh-lightbox-thumb& width=&709& data-original=&/v2-8c765ffbcd_r.jpg&&&/figure&&p&从这里我们可以看到,NAPT只解决了内网主机在没有公网IP的情况下如何访问公网主机的问题,但是并不能解决公网主机如何主动向内网主机发起请求的问题。&/p&&h2&私有地址&/h2&&p&在较早以前的 RFC 1918 文档中对私有地址有相关的说明。&/p&&p&因特网域名分配组织&a href=&/?target=https%3A///item/IANA/2800158& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&IANA&i class=&icon-external&&&/i&&/a&组织(Internet Assigned Numbers Authority)保留了以下三个&a href=&/?target=https%3A///item/IP%25E5%259C%25B0%25E5%259D%& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&IP地址&i class=&icon-external&&&/i&&/a&块用于私有网络。&/p&&p&10.0.0.0 - 10.255.255.255 (10/8比特前缀)&/p&&p&172.16.0.0 - 172.31.255.255 (172.16/12比特前缀)&/p&&p&192.168.0.0 - 192.168.255.255 (192.168/16比特前缀)&/p&&p&我们可以看到其中有1个A类地址块,32个B类地址块和256个C类地址块。主流的家用路由器使用C类私有地址作为路由器LAN端的IP地址较多,所以我们可以看到路由器设置页面的IP一般都为192.168开头。&/p&&h2&原因&/h2&&p&先说说家庭宽带的情况吧。家庭宽带如果没有公网IP,那么意味着你在本机上监听的任何端口,都只能在本机网卡所在的网络中访问,这个网络一般是路由器LAN端所在的网络。如果没有做特定的映射规则,那么路由器WAN端所连接到的网络将无法正常访问该主机提供的服务。&/p&&p&如果这种情况下想要让WAN端(如果运营商为你分配了公网IP,那么WAN端所连接到的网络通常就是公网),那么需要在路由器上做端口映射。比如说路由器的LAN IP为192.168.1.1,WAN IP为23.23.23.23,我想让内网192.168.1.2主机的80端口提供的HTTP服务器直接能够在公网中通过&a href=&/?target=http%3A//23.23.23.23& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&23.23.23.23&/span&&span class=&invisible&&&/span&&i class=&icon-external&&&/i&&/a&访问,那么就要将192.168.1.2:80映射到23.23.23.23:80上。&/p&&p&但是通常情况下,运营商是不会给普通用户公网IP的。那么用这种方法映射,在公网仍然是无法访问的,因为你的路由器WAN端连接的又是运营商更上一级的路由器LAN端,严重一点,甚至是层层连接最后才到公网,这种行为称作流量穿透。国内某电,某动的宽带就有大量这种行为。通过流量穿透的方式来提供的宽带服务,看似便宜,实则影响很大,由于大家公用一个IP,可能会导致很多网站的反SPAM策略伤及无辜,或者内部为了节省带宽,使用缓存,导致一些不该缓存的敏感安全页面被缓存起来,甚至导致部分网站缓存失效完全打不开。&/p&&p&有的人发现,即使自己有公网IP,但是仍然无法通过常规方法架设服务器,这是怎么回事呢?这是运营商为了防止个人随意开设各种非法服务,也防止黑客通过扫描器进行抓鸡和批量扫描,将一些常用端口进行了封禁,比如说我们这的中国电信就将80,8080等端口封禁了。这样封禁,虽然一定程度上保证了我们的网络安全,比如说前段时间的勒索病毒正因为国内大部分用户没有独立的公网IP,并且操作系统最容易爆发漏洞的一些,135,139等端口被运营商封禁了,使得国内个人家庭电脑中招的概率小了很多;但是导致即使有公网IP,也无法使用常用端口向外网提供服务,只能更换到其他端口。这样有什么不好呢?比较典型的问题就是WEB网站默认使用80端口,那么在输入网址的时候可以不用带上端口号,显得比较美观。&/p&&h2&解决方案&/h2&&p&如果遇到了上述情况,我们该如何解决呢?&/p&&p&如果我们没有一台公网服务器,我们可以使用国内大名鼎鼎的“花生壳”,“nat123”等服务来实现,但是他们背后的原理是什么呢?&/p&&p&我们如果在自己拥有一台具有公网IP服务器的情况下,我们可以借助这台公网IP服务器提供服务。而具体又该怎么操作呢?&/p&&h2&解决方案的实现&/h2&&p&先假设我们自己有一台公网服务器,他的IP为45.45.45.45。我们又有一台内网服务器IP为23.23.23.23.我们现在想把23.23.23.23:80,即内网服务器上的HTTP服务开放到45.45.45.45上。&/p&&p&最简单粗暴的方式就是,我们可以直接将整个内网服务器环境在公网服务器上重新搭建一遍。&/p&&p&但是这样做很麻烦,我们有的时候并不想这样做,我们只是想简单的借助公网服务器的网络来发布一个内网服务。&/p&&p&前面我们通过NAPT原理得知:NAPT实现了内网主机在没有公网IP的情况下访问公网主机。那么我们可以这样做:假设公网IP为23.23.23.23,内网IP为192.168.1.2。公网主机先监听80端口,监听这个端口是用于向外部提供一个HTTP服务,80是WEB服务器的默认端口。同时其他任意一个端口(这里我们假设为7777),监听这个端口是用于让内网服务器主动连接进来打通一个隧道。接着内网再主动向公网主机的7777发起一个请求,这样内网就成功与公网主机建立了一个连接通道。然后当有任何客户端主动连接公网的80端口时,公网接收到连接请求之后马上把这连接请求通过先前建立好的隧道转发到内网主机,内网主机接收到来自隧道的数据包后再主动连接内网主机自身的80端口,连接成功之后将数据包原封不动地转发数据包给80端口,待HTTP服务器程序处理完这个数据包,生成了响应报文之后再原路转发回去,最终到达公网的80端口,然后返回给最开始请求公网服务器80端口的客户端。&/p&&p&看起来是不是比较绕呢?事实上大名鼎鼎的花生壳内网版以及nat123等内网穿透工具的原理基本就是如此,但是并不完全是这样。因为一个运输层端口只能同时提供一种服务,但是我们会发现花生壳这种内网穿透服务是借助一个公网IP同时给很多用户提供了服务,这是因为花生壳在流量转发这一层上并不是像我之前所说的原封不动的将报文进行转发,而是在转发之前加了一些控制协议的内容,用于指明该转发到哪个花生壳客户端所在的内网主机上。前者这种原封不动的转发方式通常叫做透明传输或者透明代理。&/p&&h2&穿透防火墙&/h2&&p&为了安全起见,通常会在网络中加入防火墙,防火墙有入站规则和出站规则。如果不是非常严格的安全管控,通常是不会设置出站规则的,但是入站规则一般都会设置的,比如说外部可以通过80端口传入内网的WEB服务器访问网页,但是不能通过3389端口登陆内网的远程桌面。&/p&&p&而在内网渗透的过程中碰到这种情况,我们也可以借助上面内网传统的方式实现穿透防火墙的入站规则。因为防火墙通常只拦截了入站,没有拦截出站,那么我们可以让内网服务器主动出站(主动连接到黑客的服务器),与黑客自己的服务器打通隧道,最终绕过防火墙连上3389远程桌面。&/p&&p&还有一种情况就是我们已经拿下了内网其中一台并没有做任何防火墙规则的白名单服务器,但是我们想连上内网另一台做了入站规则的目标服务器,那么我们可以让这台白名单服务器作为一个跳板,让他先监听自身任意一个端口,然后在有任何用户连上这个端口之后,白名单服务器就主动连上内网的目标服务器,然后借助这台白名单服务器打通黑客和目标服务器的连接隧道。&/p&&p&而在黑客工具中大名鼎鼎的lcx原理也就是如此,前者的实现是lcx的listen和slave命令,后者的实现是lcx的tran命令。&/p&&h2&代码实现&/h2&&p&知道了原理之后,具体该怎么实现呢?&/p&&p&我这里选择了使用Go语言编程实现了这样一个内网穿透工具。&/p&&p&Golang本身提供了非常多的网络库,并且Golang本身内置的Goroutine能够很方便的处理网络编程中的异步IO,而且最重要的是,Golang开发的程序是可以跨平台运行的,意味着写了一份代码,我们可以在任何一个操作系统上编译并使用。&/p&&p&&a href=&/?target=https%3A///cw1997/NATBypass& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&https://&/span&&span class=&visible&&/cw1997/NATBy&/span&&span class=&invisible&&pass&/span&&span class=&ellipsis&&&/span&&i class=&icon-external&&&/i&&/a&&/p&&p&初始运行时根据情况输出欢迎信息已经语法提示(这里要重点注意printWelcome函数末尾调用了time.Sleep阻塞一秒,这是因为fmt包输出是非线程安全的,而log包下的输出都是线程安全的,因此为了防止后面执行流中打的日志会穿插到提示信息中而使用该函数休息一秒钟)&/p&&figure&&img src=&/v2-bc56bec636b0a1b_b.jpg& data-caption=&& data-rawwidth=&949& data-rawheight=&416& class=&origin_image zh-lightbox-thumb& width=&949& data-original=&/v2-bc56bec636b0a1b_r.jpg&&&/figure&&p&首先通过判断传入参数决定当前使用何种转发策略&/p&&figure&&img src=&/v2-e96d97218effe_b.jpg& data-caption=&& data-rawwidth=&968& data-rawheight=&811& class=&origin_image zh-lightbox-thumb& width=&968& data-original=&/v2-e96d97218effe_r.jpg&&&/figure&&p&然后再判断传入参数是否正确,通过正则表达式等方式验证IP的合法性以及端口范围&/p&&figure&&img src=&/v2-6ed9c211a82da5b7b75c5f_b.jpg& data-caption=&& data-rawwidth=&786& data-rawheight=&348& class=&origin_image zh-lightbox-thumb& width=&786& data-original=&/v2-6ed9c211a82da5b7b75c5f_r.jpg&&&/figure&&p&通过port2port函数实现了两个端口同时监听双向并且转发数据。&/p&&figure&&img src=&/v2-25c1c1f0fb31cbe8c299f61dc67f3b8f_b.jpg& data-caption=&& data-rawwidth=&852& data-rawheight=&277& class=&origin_image zh-lightbox-thumb& width=&852& data-original=&/v2-25c1c1f0fb31cbe8c299f61dc67f3b8f_r.jpg&&&/figure&&p&在port2host操作中实现了跳板中转。&/p&&figure&&img src=&/v2-501ccd4a_b.jpg& data-caption=&& data-rawwidth=&1229& data-rawheight=&441& class=&origin_image zh-lightbox-thumb& width=&1229& data-original=&/v2-501ccd4a_r.jpg&&&/figure&&p&在host2host中实现了主动连接打通隧道的功能。&/p&&figure&&img src=&/v2-3ad6d3b91dbb5cba3f9202d_b.jpg& data-caption=&& data-rawwidth=&1036& data-rawheight=&528& class=&origin_image zh-lightbox-thumb& width=&1036& data-original=&/v2-3ad6d3b91dbb5cba3f9202d_r.jpg&&&/figure&&p&看代码便可以知道,在Golang中进行socket操作的net包要比C语言中的socket.h操作简单很多。&/p&&figure&&img src=&/v2-292b2ff051d193b6d61297_b.jpg& data-caption=&& data-rawwidth=&1237& data-rawheight=&348& class=&origin_image zh-lightbox-thumb& width=&1237& data-original=&/v2-292b2ff051d193b6d61297_r.jpg&&&/figure&&p&转发功能的核心就在于forward函数部分。&/p&&figure&&img src=&/v2-2eddf8d206d8aca6ea51a2_b.jpg& data-caption=&& data-rawwidth=&1173& data-rawheight=&472& class=&origin_image zh-lightbox-thumb& width=&1173& data-original=&/v2-2eddf8d206d8aca6ea51a2_r.jpg&&&}

我要回帖

更多关于 steam移动安装文件夹 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信