几种需要内网穿透情况下Windows远程桌面的方案

要解决一个比较典型的需求:在家里的时候需要远程桌面到办公室的电脑做一些操作,最大问题是办公室的机器在局域网内没有公网IP,所以不能直接使用远程桌面工具连接。想要完成这个任务核心是需要进行所谓的内网穿透,之后就可以选择自己熟悉的远程桌面工具操作了。这里介绍几种我使用过的办法,供有需要的朋友参考。

* 如果你需要操作的是一台内网Linux机器,也可以参考之前的这篇《从Internet访问没有外网ip的NAS服务器的解决办法》。

 

方案一 TeamViewer

TeamViewer是一款简单好用的工具,不仅允许个人用户免费使用,还支持多平台下机器相互连接,比如可以从Android手机或macOS电脑远程到Windows电脑。只要两台电脑都安装了该软件,便可直接相互远程桌面,内网问题完全透明,操作速度也完全可以接受。不过使用一段时间后,被提示有可能是商业用途使用,也考虑过付费购买,但单个用户49刀/月的价格对于偶尔使用来说确实比较贵。于是就转到了第二个方案。

 

方案二 ZeroTier

ZeroTier也是一款可以直接安装使用的工具,相比TeamViewer的好处是,第一提供免费套餐,不区分个人和商业用途,并且免费套餐允许同时100台设备组网,第二它是更完整的内网穿透方案,安装了ZeroTier软件的所有设备都会加入到一个自己指定的虚拟局域网内,这样这些设备之间相当于都是局域网访问,所以不仅能远程桌面,还能进行其他任何操作。ZeroTier的使用也很简单,每台设备上安装软件后加入到自己创建的网络内即可,具体可参考相关帮助。

唯一可惜的是在远程操作时,速度有些慢,这是因为同TeamViewer一样,设备之间的连接都是通过他们的服务器转发的,而ZeroTier的服务器,在国内的访问速度显然不如TeamViewer的好,如果TeamViewer的连接速度比作1的话,ZeroTier不经过额外配置的情况下,对于我的网络状况下差不多是0.6。

所谓的额外配置,是ZeroTier允许你自己加入中转服务器(通常是自己所有设备都能访问到的具有公网IP的VPS),这样两台设备连接时会自动利用ZeroTier自身服务器(称作planet)和你指定的中转服务器(称作moons)之间连接速度更好的一个。在按照官方文档Creating Your Own Roots (a.k.a. Moons)和相关参考文章《ZeroTier moon 设置教程》 设置好以后,发现速度确实有所提升,感觉可以达到TeamViewer的1-1.3倍的速度。

 

方案三 frp

frp是国内大牛开发的一个开源方案(A fast reverse proxy to help you expose a local server behind a NAT or firewall to the internet.,目前仍处在开发状态,不推荐用于生产环境),相比于TeamViewer客户端/服务器端都闭源,ZeroTier客户端开源/服务器端闭源来说,frp的客户端和服务器端都在GitHub上开源。主要思路是通过自己指定中转服务器,实现两台不同内网设备之间的点对点链接。它的好处是和ZeroTier一样能够暴露某个机器上的所有指定端口,而且服务器端完全走指定的中转服务器(ZeroTier是自动选择)。具体配置步骤如下:

1. 在中转服务器VPS上配置服务器端。

wget https://github.com/fatedier/frp/releases/download/v0.23.3/frp_0.23.3_linux_amd64.tar.gz

tar -zxvf frp_0.23.3_linux_amd64.tar.gz

//编辑服务器端配置文件frps.ini

[common]
bind_port = 7000  # VPS监听的端口,用于和frp客户端连接 。需防火墙开放

//启动服务器端(可自己配置系统服务)

nohup ./frps -c frps.ini & &> /dev/null

 

2. 在需要远程桌面的机器上配置客户端

//从github release获取同样的release文件(服务器端和客户端的所有文件都在里面)

//编辑客户端配置文件frpc.ini

[common]
server_addr = xxx.xxx.xxx.xxx  #中转VPS的Ip
server_port = 7000                #同服务器端配置的端口
[rdp]
type = tcp
local_ip = 127.0.0.1
local_port = 3389                 # 当用户连接 frps的以下3443端口时,会被转发到frp client的此端口
remote_port = 3443              # frps监听的端口,任何机器通过此端口与frps连接。需防火墙开放

custom_domains = xxx.xxxxxxxxxxx.com              #可选,如此可通过域名访问3443端口

 

3. 客户端通过frpc -c frpc.ini即可启动。办公室的电脑是Windows机器,可通过如下方法开机自动启动frp。

//创建一个frp_autostart.bat文件如下

@echo off
cd C:\frp_0.23.3_windows_amd64
frpc -c frpc.ini
exit

//创建Windows服务

C:>sc create frp binPath=  C:\frp_0.23.3_windows_amd64\frp_autostart.bat start= auto

 

最后即可通过[中转VPS的IP]:3443进行远程桌面连接了。家里的是macOS,推荐使用微软官方的Microsoft Remote Desktop的软件(目前beta)。最后frp这个方案速度最快,如果TeamViewer是1的话,感觉连接速度可达2以上。值得一提的是,这三个方案都是跨操作系统的,并且后两种方案,不局限于远程桌面,其他应用都可以支持。

北京联通烽火HG220G-U光猫升级+路由改桥接

  去年家里宽带升到200M之后,因为原先的光猫是百兆LAN口,网速受限,所以打联通客服要求换一个千兆LAN口的光猫。当时说我们这片只有烽火HG220G-U个型号的二手光猫支持千兆了,于是就先用着,还算稳定,但发现光猫的工作模式被锁死在路由模式下,不像原来的百兆光猫是桥接模式,这样光猫后面的路由器就没法拨号,导致路由后的NAS没法从外网直接访问,又用回了之前的SSH反向端口转发的办法

  后来又联系过两次联通客服,总说新猫没有到货,于是想看看有没有什么办法自己解决。找到了老周部落贴吧里的《烽火HG220G-U E00L2.03M2000光猫改桥接教程》,修改完成后发现光猫确实按桥接模式工作了,路由器也能正常拨号上网,但网速从200M降到了不到100M,发现是因为光猫的固件版本掉坑里了,2.02版本的光猫确实会出现改桥接后掉速的问题。当时也没找到升级光猫固件的办法,无奈又改回了路由模式。

  昨天恰好看到老周部落贴吧里的又出了新文章《北京联通烽火HG220G-U/HG221G/HG260G-U/HG261G互通型HGU升级指导》,先看了下跟贴,发现有一人情况和我一样,原来是2.02版本,想通过升级再改桥接。但他升级到最新2.04版本后,改完桥接依然掉速。

image 

  本想希望不大,抱着试试看的心态也升级了家里的光猫固件版本,但没有直接升到最新的2.04,而是到之前教程里改桥接肯定没问题2.03版本,然后改桥接,路由拨号,测试,200M–>200M。又可以从外网愉快的访问NAS啦~

image

 

image

 

image

家用(影像)存储及备份方案选择

  随着家庭成员和移动设备的增多,我们日常生活中越来越频繁地产生着各种照片和视频文件,日积月累,这些数字资料的保存,读取,备份或早或迟都会成为困扰你的一个问题。

 

  先来说说存储。我们移动设备存储空间满额的时候,最先想到的是把照片和视频导出保存到电脑硬盘上;而你肯定经历或者听说过硬盘坏掉这件事情,所以你可能觉得电脑硬盘靠不住了,买个移动硬盘来寸照片和其他重要资料吧,一来不用天天通电读取,看起来寿命似乎要更长,二来可以当作备份使用。但仔细想想,移动硬盘只不过是一个体积更大,容量更大的u盘(而且抗震性能还不如u盘),把你认为重要的资料存在u盘里可靠吗?你听说周围朋友移动硬盘坏了,丢了的情况多还是他说我家里台式机硬盘坏了的情况多?既然台式机硬盘无法保障我的照片和视频,更好的方案是什么呢?答案就是NAS。关于NAS的介绍大家可以自己google一下,品牌一般就是Synology(群晖)和QNAP(威联通)二选一。而当你使用NAS超过一段时间后,会发现对NAS硬盘里的资料进行备份又变成一个不可避免的话题。虽然比台式机硬盘坏掉概率要小很多,但只要发生,对于你的资料就是100%的丢失。

 

  再来说说备份。如何对NAS上的资料进行备份呢?通常NAS里不仅有比较珍贵的照片和视频,可能还有不太重要的一堆高清电影。最先想到的办法是多块硬盘做RAID1或者RAID5。前者硬盘空间浪费多,后者对NAS硬件级别又有要求(最少3块硬盘)。自己手上的QNAP 212P是比较低端的NAS,虽然有两个盘位,但发现做RAID1的话需要自己把现有资料备份,然后塞两块硬盘进行重新格式化,之后再把备份的数据倒回去;想做热备份的话就得换更好的NAS。前者需要多加一块硬盘,外加数据导入导出,成本1000元左右;后者换NAS,加硬盘,成本更高。

 

  最后目光又落回了云存储上面。之前也看到NAS里有应用可以备份本地数据到云存储上面,一般都支持增量备份及本地/云端双向同步备份,足够满足需求了。但感觉有额外的费用,没有细想。这回重新计算一下成本发现,云存储的备份办法确实比较划得来。目前需要备份的照片和视频差不多有100G,按照AWS S3最贵的Standard存储级别0.03美元/GB/月来算,就算200G数据,每月成本6美元,2年的成本大约1000人民币,相比加硬盘,换NAS来说更有优势。因为目前家用NAS正在快速普及,两年后NAS功能,硬盘容量,成本几何都是未知数。

 

   下来就比较一下可选的云存储方案。能考虑的也就是三家,亚马逊的AWS S3,谷歌的Google Cloud Storage和微软的Azure Storage。从信誉度来说国内的各种所谓云计算直接pass,从持久性来说微软的Azure也pass,不是说Azure的durability不行,而是怕微软的Azure哪天就不行了。。。S3中的Glacier响应速度4小时,就不用考虑了;S3还有一个Reduced Redundancy Storage(RRS)的durability是99.99%,相比其他剩余选项的99.999999999%来说,在成本差别不大的情况下也可以淘汰掉。剩余的选项对比如下:

 

  AWS S3 Standard AWS S3 Standard – Infrequent Access GCD Standard GCD Durable Reduced Availability GCD Nearline Storage
Durability 99.999999999% 99.999999999% >= 99.9% >= 99.0% >= 99.0%
Availability 99.99% 99.99% “High availability” “Lower availability than Standard” “Lower availability than Standard”
Storage Pricing (per Month) $0.03 per GB $0.0125 per GB $0.026 per GB $0.02 per GB $0.01 per GB
 

Data Transfer Pricing

$0.09 per GB $0.09 per GB $0.012 per GB $0.012 per GB $0.012 per GB
Retrieval Fee $0.01 per GB $0.01 per GB

 

  其中,S3的价格以us-east为准;Data Transfer即是数据下载到本地的价格(存储收费,下载消耗网络带宽也要收费),而Google Cloud Storage还要区分下载到哪,大部分地区是$0.012/GB,而下载到中国(可能吗?)和澳大利亚地区费用更高;Retrieval Fee是价格保护策略的收费,对于价格更低的AWS S3 – IA和Google的Nearline Storage来说,本身存储成本低,划算,所以设置了额外的费用增加使用成本,也就下载是除了Data Transfer的费用外还要额外收取$0.01 per GB的费用;此外的Request Pricing(请求次数的费用)很低,可以忽略不计。

 

  Google Cloud Storage和S3的设计理念完全一致,IAM管理,bucket,object,storage class等,但控制台界面的友好性,即使用策略的灵活性来说(S3允许单向切换Storage Class,Google不行;S3的Life Cycle策略的应用粒度可以到bucket内的某个/某些文件夹,google不行),AWS完胜Google。另外,虽然家里已经有能翻墙的路由器,但在其他网络上访问Google的数据的不便利性,也是需要考虑的一个因素。

 

 基于上面的数据,和大约200GB左右的数据量,几乎完全是单向备份,极少机会会下载到本地(除非NAS硬盘坏掉)的使用场景来看,AWS S3 Standard – Infrequent Access是最好的选择。最后从安全性上来说即使RAID1,硬盘加再多也有可能出事故,比如搬家时摔坏了,丢掉了;云存储可以防止此类隐患,理论上来说即使地震也不怕了。。。当然地震后你本人仍要有能够访问云端数据的机会:)

 

参考:

1. Amazon S3 Storage Classes

2. Amazon S3 Pricing

3. Google Cloud Storage Storage Class

4. Google Cloud Storage Pricing

5. Google Cloud Storage SLA

在CodeDeploy脚本中使用nvm

  nvm是一个nodejs版本管理工具,它能够方便地帮助你管理多个共存的nodejs版本,并在其中进行自由切换。

  这回在AWS的CodeDeploy脚本中调用nvm自动安装和使用指定版本的nodejs,遇到了问题。如下的脚本,

image

  执行后发现,最终部署结果里并没有使用5.3.0的nodejs,而使用的仍然是系统原来安装的老版本。ssh登录机器,查看nvm ls和nvm current,却已然是5.3.0版本的nodejs了:

image

  原来nvm的所有命令,如nvm install,nvm ls都是写在~/.nvm/nvm.sh脚本里的,系统之所以能识别这些命令,是因为在当前shell里运行过source ~/.nvm/nvm.sh。而正因为已经在~/.bashrc文件中添加了该语句,所以每次ssh登录时,shell相当于已经source过了该脚本。

  而以”su -c”方式执行命令时,命令是在一个non-login,non-interactive的shell执行的,所以不会读取~/.bashrc文件,因此nvm的命令就无效了。解决办法是在CodeDeploy脚本中调用nvm命令的语句前,先使~/.nvm/nvm.sh文件source一下。比如:

image

  参考:

Windows下删除过长路径下文件(夹)的办法

  有时候在Windows下删除文件或文件夹会碰到如下错误:

The source file name(s) are larger than is supported by the file system. Try moving to a location which has a shorter path name, or try renaming to shorter name(s) before attempting this operation.

文件名对目标文件夹可能过长。您可以缩短文件名并重试,或者尝试路径较短的位置。

image

  解决的办法是在命令行输入:

robocopy /MIR c:\a d:\xxx

  其中c:\a是c盘新建的一个空目录,d:\xxx是路径过长的文件(夹)的根目录。执行后,你会发现d:\xxx目录已经被清空了。

使用AWS CodeDeploy的几点注意事项

  AWS CodeDeploy是亚马逊云计算提供的服务之一,用来将代码更容易地部署到EC2实例或私有云实例中。

image

  它能够根据用户配置,从S3或Github上获取最新代码,并按照用户提供的appspec.yml配置文件,在不同的hook事件阶段执行不同的脚本文件,从而使代码部署过程自动化。

image

  比如你可将多个EC2实例分为Dev,QA,PRD三组,通过结合CodeDeploy和其他CI工具(如Jenkins),自动化完成持续交付(部署到Dev/QA实例上),持续部署(部署到PRD实例上)的任务。

  在使用CodeDeploy的过程中,有以下几点事项需要注意:

  • 所有EC2实例上必须安装CodeDeploy Agent服务,EC2实例之所以会响应CodeDeploy服务,都是由CodeDeploy Agent来完成工作的。
  • 默认CodeDeploy Agent是通过root用户安装的,所以appspec.yml中执行脚本时,默认是以root用户身份执行。而我们的代码中用到了PM2,执行PM2命令(如pm2 start)时,需要在appspec.yml中指定以ec2-user用户执行脚本,否则相关命令执行时,会导致EC2实例cpu持续占用100%,最终导致超时而部署失败。
  • sudo: sorry, you must have a tty to run sudo问题。在sh脚本中,如有需要sudo执行的命令,则需在所有EC2实例的/etc/sudoers文件中,注释掉“Default requiretty”一行。
  • /bin/bash^M: bad interpreter: No such file or directory问题。这是因为在windows操作系统上修改了.sh文件,导致文件末行编码不同,而在linux机器上无法执行。解决办法是在linux机器上重新保存该文件,或在windows上用sublime打开该文件,View->Line Endings->选择Unix,保存即可。

Amazon EC2上通过NFS共享目录的注意事项

  背景:拟在Amazon EC2上部署nodejs应用集群。假设nodejs部署在A和B两台机器上,通过前端的ELB(Elastic Load Balancer)分发请求到A和B机器上,两台机器分别对请求做无状态响应,这样就要求A和B机器存取完全相同的数据。由于nodejs应用需要读写本地硬盘目录(对响应速度要求高,无法采用S3存储),而Amazon目前提供的存储方案中,只有EBS(Elastic Block Storage)存储可以挂载到具体机器上以提供本地路径,所以只能选取EBS作为应用集群的存储位置。但EBS类似SAN,只能挂载到一个EC2实例机器中,如果直接挂到A或B上的话,另一台机器就无法读取其中数据。所以采用的方案是启动第三个EC2实例机器C,将EBS挂载到C机器上后,该机作为NFS服务器共享EBS的挂载目录,A和B机器作为NFS客户端,分别加载共享出来的EBS路径到各自对应目录,从而保证nodejs集群能够实时读写相同的数据。如下图所示:

image

  问题:在C机器上挂在EBS存储卷后,修改/etc/exports文件设置了NFS共享,并且有rw, no_root_squash选项。但在A机器和B机器上通过修改/etc/fstab文件并mount -a后,发现能够加载C机器上的EBS存储到指定目录,但写入文件时提示无权限。

  解决办法:确保C机器(NFS服务器)上,EBS挂载路径的所有者,与A和B机器(NFS客户端)上准备写入数据的用户要拥有相同的UID和GID。具体来说,这三台机器都是从Amazon Linux的AMI启动的,所以默认用户都是ec2-user(非root用户)。C机器上EBS挂载点是/data,一开始该目录的所有者和组均为root(因为在根目录下建立目录需要root权限),所以导致在A和B机器上加载该共享目录后,加载目录的所有者和组也均为root用户。这样A和B机器上运行nodejs的ec2-user用户就无法写入数据了。解决的具体办法是在C机器上运行”sudo chmod –R ec2-suer:ec2-user /data”命令后,在A,B机器上重新加载NFS共享目录即可。

  参考:How to properly set permissions for NFS folder? Permission denied on mounting end.

  目前Amazon EC2上推出了公测版的EFS(Elastic File System)存储,类似NAS,在可以提供本地存储路径的前提下,还可以挂载到多台EC2实例上。但目前只有US West(Oregon)一个区域可用。在EFS全面推出前,采用上述方案,可保证应用集群横向扩展的情况下,依然能存取相同的数据。缺点是C机器是单故障点;但数据存储在单独的EBS上,至少保证数据的生命周期不依赖具体的EC2实例机器。

北京联通,DigitalOcean和Shadowsocks

  最近家里宽带换成了北京联通20M,相比之前的宽带通,质量确实高了不少,国外网站和公司vpn的速度明显快了很多。但比较奇怪的是自己搭在DigitalOcean上的Shadowsocks速度没有太大提升,有时反而还不如以前。

  首先公司网络里测试Shadowsocks的时候速度比较理想,也非常稳定,说明不是DigitalOcean的问题;自己家里上国外网站速度明显快了不少,而且只要能访问的网站速度都比较快,说明北京联通也没有问题。那问题只可能是北京联通与DigitalOcean之间水土不服了。

  之前自己的vps一直放在DigitalOcean的旧金山机房,因为国内这个机房的口碑普遍比较好。但在家里打开newnaw.com和自己博客的时候也能感觉到速度不如以前了,难道是联通到这个机房度的问题?ping了一下DigitalOcean在旧金山的测速页面:

Screen Shot 2015-05-24 at 17.06.36  11%丢包率,平均响应也都在310ms以上……感觉联通到旧金山机房确实有问题,看看其他的机房吧。DigitalOcean去年在亚洲开通了新加坡机房,但之前就看到过,据说到国内的速度不稳定,还不如其他机房。抱着试试看的心态,也ping了一下新加坡的测速页面:

Screen Shot 2015-05-24 at 17.11.16  平均响应时间172ms,快了几乎一倍。立刻去新建了一个vps,机房选择新加坡,之后上面部署了Shadowsocks测试了一下速度,youtube的4k视频都可以流畅观看了,有点小感动…

Screen Shot 2015-05-24 at 13.08.12  测试后发现Shadowsocks的速度比较稳定,于是就在DigitalOcean上创建snapshot,转移之到新加坡机房,重建vps…整个操作很简单,DigitalOcean便利性还是很好的。

  后来又用traceroute试了一下新加坡机房的测试页面,发现并不像网上所说,会先绕去北美一圈,然后才到新加坡,而是直接从日本到了新加坡:

Screen Shot 2015-05-24 at 18.34.17

  那单从传输距离来说,新加坡明显还是比旧金山近很多,也就解释了为什么新加坡机房速度会比较快了。

  Shadowsocks是国内的clowwindy写的工具,在goagent沦陷,ssh速度偏慢的情况下确实给大家带来了非常大的便利。前两天中文维基百科也不能愉快地从国内访问了,借网络上一张图看看,世界前30的网站我们还能上几个……希望这已经是最坏的时候了。

Screen Shot 2015-05-24 at 17.44.04

从Internet访问没有外网ip的NAS服务器的解决办法

  最近家里买了一台NAS服务器,用来完成多项任务,比如存储和管理大量的照片,用做24小时离线下载机器等。但其中NAS比较吸引我的一个功能是,能够随时随地从外网访问家里NAS机器上的数据,并且能够在外地游玩的时候,把照片通过互联网随时传到家里的NAS机器上备份并腾出设备空间继续拍照。
  这样做的前提是你的路由器得有一个外网ip。有了外网ip后,可通过设置路由器的端口转发,再设置一个DDNS域名就可随时访问家里的NAS了。但恰好自己使用的网络是鹏博士集团下的一家公司(宽带通,长城宽带都是),恰好他们以转卖二手带宽,不给拨号用户外网ip而著称。他们给你的拨号ip实际是经过多层NAT转发的一个大局域网ip。为了实现目的,必须解决所谓的NAT穿透/NAT打洞/内网穿透问题。
  一开始搜到了花生壳,最近刚好除了内网版,号称可以实现没有公网ip的情况下访问你的内网设备。测试了一下果然可以,但需要交年费,并且限制流量,要想用更多的流量就得交更多的钱,弃用之。
  最后找到了ssh的反向端口转发(reverse port forwarding)功能,这是常被忽略但是非常强大的一个用途。原理是在本地机器的端口和远程机器的端口建立映射关系,这样访问远程机器指定端口时,所有请求都会被加密并传输到本地机器的端口上,本地机器响应后将结果在转发回远程机器的端口,整个过程看起来就像远程机器做出响应一样,强大之处是远程机器可以直接绕过防火墙和各种NAT转发,准确找到你的内网机器。
  具体做法很简单,只需要一个命令:
  ssh -NfR <remote port>:localhost:<local port> remoteuser@remoteserver
  其中remote port是要接受请求的远程机器端口,local port是要做出响应的本地机器的端口, remoteserver是远程机器的地址,remoteuser是负责转发的具体用户。比如家里的NAS端口是8080,你的vps外网地址1.2.3.4,那么可以通过在你的NAS上执行ssh –NfR 8888:localhost:8080 user1@1.2.3.4命令后,访问vps的8888端口来访问家里的NAS机器了。
  几个需要注意的问题:1. 需要设置远程机器ssh配置文件中的GatewayPorts参数来达到允许任意地址机器来使用这个转发规则的目的,  否则上述命令只允许在远程机器本机上的请求通过,centos上操作见此;2. 该命令执行后,如果一段时间内没有请求被转发,则ssh反向连接会自动断开,这时候就需要autossh之类的工具来维持这个连接(实时监测,断开后自动重连),具体使用方法可以搜到很多例子;3. ssh通过autossh自动重连时不可能每次都手动输入用户密码,所以需要改用key authentication的方式连接(将本地机器的用户公钥添加到远程机器用户的~/.ssh/authorized_keys文件中)。
  虽然鹏博士的实际出口网速很慢,但在大局域网下迅雷下载能满10M/s,可在线看1080p视频,性价比还是挺高的,明年不用换高价的宽带了。。。
  PS: 此方法可用于其他场景,比如回家后远程访问公司机器上的资料,给外网客户演示公司内网机器上的demo等。

  参考资料:

Nexus 7电池充电慢耗电快的解决办法

最近发现前两年买的Nexus 7一代出现了充电非常慢(充满电整个需要10个小时以上),并且充满后使用耗电超快的问题,以为是电池寿命到了,想看看别人是怎么解决的,最后在youtube上找到一个解决办法,测试后确实解决了电池问题,电池又和新的差不多了。
解决办法就是:在充电的时候,把充电器一头的usb线(usb线两头中大头的那一边)反复插拔若干次。看起来很奇怪,但确实解决了此问题。