有时候你的SSH因为某些原因, 或者你的VPS的SSH端口被某些无法阻挡的力量被封禁了, 你使用普通的SSH方式无法登录你的服务器, 所以这时候我们需要使用一些方式, 让你的SSH通过代理链接你的服务器, 进而解决这个问题.
如何让你的ssh链接使用socks代理呢, 我们可以使用nc命令, 使用ssh的ProxyCommand配合nc可以让ssh通过你设置的代理访问服务器
$ ssh -o ProxyCommand="nc -X 5 -x 127.0.0.1:1080 %h %p" root@server
其中使用ProxyCommand
命令, 带上具体内容nc -X 5 -x 127.0.0.1:1080 %h %p
, 127.0.0.1:1080
是你的代理实际地址和端口 最后边的root@server
是你需要登录的服务器和用户名
nc
命令的常用参数:
-X
是指定代理协议
4是socks4协议
5是socks5协议
-x
是指定代理服务器和端口[代理服务器:端口]
默认socks
使用1080
HTTPS
使用3128
使用alias
方式也可以:
打开你的.bashrc
或者.zshrc
配置alias
$ vim ~/.bashrc
alias connserver=ssh -o ProxyCommand="nc -X 5 -x 127.0.0.1:1080 %h %p" root@server
保存退出后输入一下:
$ source ~/.bashrc
下次我们访问服务器的时候直接输入connserver就行
$ connserver
我们也可以使用ssh
的config
配置
编辑ssh
的配置文件, 没有这个文件的话, 自己创建一下:
$ vim ~/.ssh/config
然后写入一些命令
Host *
ProxyCommand nc -X 5 -x 127.0.0.1:1080 %h %p
下次使用ssh的时候就不需要配置代理了
有时候你没有socks代理的时候, 我们借助corkscrew
可以让ssh使用HTTP代理
由于我这里是macOS系统, 我就直接用brew安装corkscrew
:
$ brew install corkscrew
安装完成之后我们打开ssh的config文件修改成使用corkscrew的http代理方式:
$ vim ~/.ssh/config
写入:
ProxyCommand /usr/local/bin/corkscrew 127.0.0.1 8080 %h %p
/usr/local/bin/corkscrew
是corkscrew
的可执行文件路径, 如果您和我的不一样, 可以修改成正确的地址
127.0.0.1 8080
是你的HTTP代理端口, 注意中间有空格, 保存退出后这个时候ssh可以通过你设置的http代理进行访问你的服务器了.
注意,这种方式生效是全局的, 可能会影响到你的git 使用ssh的方式clone或者push
[TOC]
这是网上的万能炒菜公式,出处不详,摘抄一下,属于非常基础但不会出错的教程。 别再被程序员做饭指南这种东西坑啦,做菜是没有放「几克盐」、「几克油」这样的说法的,说放一勺,那就是一勺,做菜也是 Responsive Design 的,火大点就多放点,火小点就少放点,炒得久就多放点,炒得快就少放点,你家的厨房要多放点,他家的厨房要少放点……
热油爆香蒜末,再加入蔬菜炒软后放盐
肉切片加入这四样提前腌制 15 分钟
热油爆香蒜末在下腌制的肉,老抽调色
还可以放白糖、鸡精提鲜
辣椒粉热油浇一下再放调料
比例 1:2:3:4:5,即常说的 12345 口决
最后淀粉水勾芡
公司的大部分服务,都部署在公司的内网上,如果需要远程访问需要连接公司提供的 VPN 服务,但是由于搭建的协议是 OpenVPN,而不是 Surge 支持的 WireGuard,因此每次连接内网都需要关闭 Surge,并开启公司的 VPN
再加上偶尔需要访问家里的内网服务,决定着手对此问题进行改造,这里主要围绕 DSM 搭建 Snell 服务进行介绍,公司的通道也是同理的
首先需要明确一下最终期望实现什么效果,无论我人在哪里,无论连什么网络,都可以顺畅的访问家中内网服务,同时要做到,当我人在家里时,不走 Snell,而是直连
既然所有服务都可以通过内网访问,对于安全性上,也需要拒绝一切通过 DDNS 访问的请求
之前使用的 primovist/snell-docker
为snell 的3.0版本的,更新使用 geekdada/snell-server:4.1.1
版本
surge 内配置时改为
Home = snell, 你的域名, 你的端口, psk=Docker环境中的PSK, version = 4
这里我搭建的环境使用的是 primovist/snell-docker 的镜像,其他镜像可能会有细节不一致,但是大体上都是 Snell 的实现
本地端口 | 容器端口 | 类型 |
---|---|---|
xxx | 12543 | tcp |
文件/文件夹 | 装载路径 | 类型 |
---|---|---|
DSM 文件夹 | /etc/snell/ | rw |
键 | 值 |
---|---|
PATH | 保持不变 |
LANG | 保持不变 |
PORT | 123543 |
PSK | 随机生成一串字符 |
OBFS | tls |
[Proxy]
Home = snell, 你的域名, 你的端口, psk=Docker环境中的PSK, obfs=tls
[ProxyGroup]
# 这里配置的意思是,如果当前连接的 WiFi 名为 Home 或者 Home_5G,则直接连接
# 否则切换为 snell
Home Snell = ssid, default = Home, "Home" = DIRECT, "Home_5G" = DIRECT
[Rule]
# 在我的环境中,家里的网段属于 `192.168.31.x`,因此直接在 `Rule` 中这么填即可
IP-CIDR,192.168.31.0/24,Home Snell, no-resolve
我的路由是小米的,如果和你的不同请自行查阅,最开始我为了方便,直接打开了小米的 DMZ 功能,但现在我希望可以手动控制部分服务不提供公网访问
此时需要使用 DSM 动态修改路由的 UPnp 映射表
当然路由中的配置我们并不需要手动添加具体配置,此处只需要打开即可,剩下的在 DSM 中进行配置
比如下图中的 snell 服务,填写对应的端口号保存即可,映射关系 DSM 会自动帮我们同步到路由上
参考 Surge 文档 https://manual.nssurge.com/others/snell.html Surge 论坛 https://community.nssurge.com/d/5
“杠精”里有太多的投机主义者,不要中了他们的圈套,少说话,多做事。你会从本文中对博主有更多的了解吗,不会。这篇文章的内容更多的是对过去的一些经验总结,自省。
一些总是故意找茬,以友好讨论的名义试图挑起争端的人。 经典表现:总是抓住一些无关紧要的细节,或故意把他人表达的观点极端化和扩大化后,模糊对方概念,进行攻击。待对方感到被冒犯,进行反击时,又常作出无辜模样“我只是友善讨论而已,何必如此呢,你反应过度了”。
1.每一个人都有可能成为杠精,且在现如今的网络环境下,这是极易发生的; 2.所有非就事论事的观点(或论点)都是杠精行为; 3.热于对你的主张观点进行二次释意,以混淆概念; 4.对你的观点进行极端化、扩大化; 5.他可能并不在乎你的观点,甚至根本不想听你说什么; 6.善于将相关关系转换成因果关系; 7.让你有被冒犯到;
杠,以船新的角度雕塑事实,避开重要的细节,并辅以极度主观的论据旁敲侧击。也有一些除了杠,甚至有些恶毒。如你所知这是一个吃瓜的时代,也是一个自媒体时代。每一个匿名者都可以在社交网络上言论“自由”,同一件事情在不同的表达手法下亦会造成不一样的观感效果。
人的情绪是极容易被左右的,人始终不是理性动物。
春秋笔法
作者:大闸蟹
链接:https://www.zhihu.com/question/20520007/answer/312551689
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
以气氛烘托、旁敲侧击的手段来暗中影响读者的好恶倾向,比如澎湃新闻写汤兰兰,不明说汤兰兰是坏人,但题目起了个《少女将全家亲人送入监狱》,一眼看去仿佛是少女的错,然后文章中屡屡旁敲侧击,通过质疑一些证据,美化施暴者们的品行,写这些罪犯多么悲惨,多么可怜,让大家产生同情。
“汤兰兰被强奸,她举报了强奸者。”这是事实,但春秋笔法可以写为“汤兰兰举报了xxx,将其送入监狱,xxx在监狱过的十分辛苦,生活和人生被毁了,xxx说‘我这辈子最恨的就是汤兰兰。’”
“特朗普在国务会议结束后,喝了一杯白咖啡。”这是事实,春秋笔法可以写为“美国黑人受歧视形势仍然严峻,特朗普在国务会议上特意只喝白色咖啡。
”他没有明说汤兰兰是坏人,也没有明说特朗普讨厌黑色咖啡,但大家读完以后,都知道他是这个意思,这就是春秋笔法。
南方周末写李鸿章,不写他如何贪污,他如何腐化,而是写张之洞、左宗棠的贪污,写李秉衡的腐化,写慈禧没有本事,从而让读者认为李鸿章优于他们所有人。然后再写李鸿章去外国是多么的替国家撑面子,去日本签条约时是多么忍辱负重,把他写的很可怜,描写成一个年迈无辜的病弱老人,为了国家大局,被迫出来无辜的背黑锅。
这时候读者们就对李鸿章产生了一个非常好的看法。
反之:我恨一个人,我要写臭他,但他没办过什么坏事,我就说警察查嫖娼时遇到了他,实际警察查嫖娼回来的路上遇到了他在吃凉粉,但读者不知道细节,读者只通过了我得知他在警察查嫖娼时被警察遇到了,继而脑补出他嫖娼被抓,我在旁敲侧击几句他曾经追求女性,曾经买了一本《谈恋爱教程》,实际这些也没错,但种种线索连接起来,让读者觉得这个人是臭流氓。
我说的全是事实,你没法告我,但读者确确实实被我影响,对你产生了敌意和鄙视,这就是现在语境下的春秋笔法。即所谓有取向的去将现实重新拼凑起来,夸大一个人的恶,或者夸大他的善。同样的事实,你可以把他写成好人,也可以把他写成坏人。全凭我一根笔,颠倒黑白。
你很难想象的一个别有用心的人(或看你不爽的人)会在你的背后如何描述你。如上一段所言,“人的情绪是极容易被左右的,人始终不是理性动物。”只要会添油加醋,没有什么是他们不能搞臭的。
人跟人之间,就算每日吃饭聊天睡觉,也没办法完全的了解彼此。更何况网络环境下的只言片语。
流言的流通是不可制止的,以及人们并不是那么在乎真相。
流言的流通,谈资、社交货币,不明真相的吃瓜群众(Who care),夹杂私货的事实描写。以及杠精与你来一场风马牛互不相干的各说各话。于事情的有效讨论已无任何实际帮助意义可言。
真理不辨不明,杠精你越理他越来劲。
白羽博客成立以来,访问者众(于我而言),软件使用上的“小白”(有饭来张口的,有只是思路不清晰需要一些引导的,还有明目张胆要饭的)、咨询、反馈;有的我极有耐心的回复了帮助了,有的被我怼了骂了Ban了。这些都是客观的事实。可能有些地方有些做法会让你当时感动不爽。而这些不爽在未来可能会带来一些坏的影响。
只要你足够客观的描述前因后果,你怎么批评,博主都接受。当然,一个人在对另外一个人感到不爽(反感)时没有几个人能如实描述一个事情的。
人对人的片面了解、认知偏见、毫无来由的指责、谩骂,道听途说来的也咀嚼得有声有色。
如序言所言,“这篇文章的内容更多的是对过去的一些经验总结,自省。” 出门在外,少说话,好好说话,多做事。
0.更强大,更专业; 如果你被杠,大多数时候还是业务水平不够,被对方找到可钻的空子,啪啪啪;请及时承认这一点,并尽快弥补起来,与其烂斗,不如翻开起灰的“书本”;我的意思是你该学习了!
1.建议少上“微博”,屁事没有。 如果争辩变成争吵,大可立即退出群聊。你要知道的是,其实并没有人在乎这次争辩/争吵的结果,“围观群众”都在看戏,你懂的,就图一乐。
博主一再提醒大家,多花些时间在现实生活,问你女朋友晚饭吃啥呀?都比这要来得有趣;
2.做错了要认,挨打要立正。 博主的脾气也不见得有多好,热心时热心,暴躁时暴躁;难免会误伤“围观群众”;在博主看来,误会、误解都是可以解决的,做错了就认错,下次还敢。
人非圣贤孰能无过,这不是一道免死金牌,但也无伤大雅。
3.端正态度,论事不论人,以及学会闭嘴。 对线的时候会想骂人吧?WDNMD。用以渲染气氛,给“围观群众”找点乐子。在博主看来,大可不必,你要知道的是杠精是不会跟你就事论事的,他甚至都不想你理你,且等着你人身攻击,等你露更大的破绽;
4.杠精有时候也不知道自己是杠精。害,原谅他们吧。
5.做正确的事,正确的做事,小心充满恶意的投机主义者。
互联网的世界是很复杂的,小心别有用心的投机主义者,断章取义,截图只截一小段,他们是来搞事的。是恶意的。博主也发 #NSFW 图,算得上一个“黑点”,是可以拿来做很多文章的;博主也写了机场推荐推荐文章,想来也是可以被拿来做些文章的;在杠精看来,但凡文章中观点不能保持中立的,非黑即白的描写都有可能被拿来裱起来,即如果你保持中立态度,便万事大吉,避免很多麻烦;
在杠精流行的世界里,谨言慎行;但对付杠精里的投机主义(别有用心)者,一定要打压!
最后的最后,推荐《人性的弱点》一书给各位;
以上。
https://i.imnks.com/2022/11/989809734.png!I
参数设置UI界面
https://i.imnks.com/2022/11/1877059077.png!I
headscale需要的配置文件已建好了,后续套件升级过程会自动备份还原
主配置文件 config.yaml 位于 /var/packages/headscale/target/bin/
db.sqlite private.key 位于 /var/packages/headscale/target/config/
有公网IP,如是动态公网IP还需要有DDNS解析。
重点重点重点!!!:端口映射OK后,例如参数 8181 对外映射为 18181,那么HeadScale参数配置中:server_url: http://0.0.0.0:8181 需要修改为 http://你的公网IP或者域名:18181。参数中的其它0.0.0.0不要修改,只需要改:server_url!!!(旧版本升级后如果如果无法访问,修改其它参数中 127.0.0.1 为 0.0.0.0)
https://i.imnks.com/2023/02/1375760695.png!I
如有域名需ssl连接,请自行修改参数中域名证书的位置,建议放到套件config目录里:
## Use already defined certificates:
tls_cert_path: "/volume1/public/archive/cert.pem"
tls_key_path: "/volume1/public/archive/privkey.pem"
或者使用HeadScale配置中的Let's encrypt自动申请证书:域名提前自行解析到公网IP
# Email to register with ACME provider
acme_email: ""
# Domain name to request a TLS certificate for:
tls_letsencrypt_hostname: ""
举例分组名称 imnks,ssh连接宿主群晖执行:
cd /var/packages/headscale/target/bin
headscale namespaces create imnks
#查看已建的空间
headscale namespaces list
https://i.imnks.com/2022/11/170941698.png!I
群晖安装Tailscale套件后无需登录,ssh连接客户端群晖执行:
http://你的公网IP或者域名:8181,这个按照实际端口映射情况修改,比如内网8181映射为18181,对外就是18181
cd /var/packages/Tailscale/target/bin
tailscale up --login-server=http://你的公网IP或者域名:8181 --accept-dns=false
https://i.imnks.com/2022/11/3922305128.png!I
复制上面执行后得到的网址,修改127.0.0.1为服务端的公网IP或者域名及对外映射端口,在任意的浏览器打开访问
https://i.imnks.com/2023/02/2076759424.png!I
复制上面的代码,修改 USERNAME 为你的 分组空间名称,ssh连接宿主群晖执行:
cd /var/packages/headscale/target/bin
headscale nodes register --user USERNAME --key nodekey:123xxx
#查看已注册的设备
headscale nodes list
https://i.imnks.com/2022/11/3175132911.png!I
PS说明:群晖端如需恢复到连接Tailscale官方:卸载套件,SSH连接群晖执行下面代码,之后重新安装套件即可。
#DSM7 (volume1指套件安装存储空间,自行核对)
sudo rm -rf /volume1/@appdata/Tailscale
#DSM6
sudo rm -rf /usr/syno/etc/packages/Tailscale
Windows客户端所在的电脑访问:http://你的公网IP或者域名:8181/windows
https://i.imnks.com/2023/02/2489961957.png!I
点击 Windows registry file 下载注册表:http://你的公网IP或者域名:8881/windows/tailscale.reg
修改127.0.0.1为服务端的公网IP或者域名,双击运行reg文件,按照提示操作导入Windows系统
https://i.imnks.com/2022/11/2900142939.png!I
安装和运行官方版本的Tailscale客户端,并点击图标打开网页
https://i.imnks.com/2023/02/2076759424.png!I
类似获取到到加入秘钥,在HeadScale服务器上ssh连接执行:修改 USERNAME 为你的 分组空间名称
cd /var/packages/headscale/target/bin
headscale nodes register --user USERNAME --key nodekey:123xxx
#查看已注册的设备
headscale nodes list
https://i.imnks.com/2022/11/536598492.png!I
PS说明:Win端如需恢复到连接Tailscale官方:卸载软件,删除C:/Users/用户名/AppData/Local/Tailscale,重新安装软件即可。
请查看 参考文章,不再一一叙述
参考:http://junyao.tech/posts/a5fad85a.html
如果其它节点设备没法访问群晖IP,在安装了Tailscale的群晖执行:
#启用TUN
/var/packages/Tailscale/target/bin/tailscale configure-host
synosystemctl restart pkgctl-Tailscale.service
电脑端访问HeadScale给群晖分配的IP http://100.64.0.1:5000/
https://i.imnks.com/2022/11/2806179621.png!I
http://junyao.tech/posts/e8e7dd51.html
https://icloudnative.io/posts/how-to-set-up-or-migrate-headscale/
本文由 简悦 SimpRead 转码, 原文地址 icloudnative.io
!https://jsdelivr.icloudnative.io/gh/yangchuansheng/imghosting3@main/uPic/2022-03-21-11-13-q1TRI3.png
目前国家工信部在大力推动三大运营商发展 IPv6,对家用宽带而言,可以使用的 IPv4 公网 IP 会越来越少。有部分地区即使拿到了公网 IPv4 地址,也是个大内网地址,根本不是真正的公网 IP,访问家庭内网的资源将会变得越来越困难。
部分小伙伴可能会选择使用 frp 等针对特定协议和端口的内网穿透方案,但这种方案还是不够酸爽,无法访问家庭内网任意设备的任意端口。更佳的选择还是通过 VPN 来组建大内网。至于该选择哪种 VPN,毫无疑问肯定是 WireGuard,WireGuard 就是 VPN 的未来。我已经不止一次向大家推荐使用 WireGuard 了,我累了,不想再讲了,你爱 JB 用辣鸡 OpenVPN 之类的就用吧,你开心就好。
WireGuard 相比于传统 VPN 的核心优势是没有 VPN 网关,所有节点之间都可以点对点(P2P)连接,也就是我之前提到的 全互联模式(full mesh),效率更高,速度更快,成本更低。
WireGuard 目前最大的痛点就是上层应用的功能不够健全,因为 WireGuard 推崇的是 Unix 的哲学,WireGuard 本身只是一个内核级别的模块,只是一个数据平面,至于上层的更高级的功能(比如秘钥交换机制,UDP 打洞,ACL 等),需要通过用户空间的应用来实现。
所以为了基于 WireGuard 实现更完美的 VPN 工具,现在已经涌现出了很多项目在互相厮杀。笔者前段时间一直在推崇 Netmaker,它通过可视化界面来配置 WireGuard 的全互联模式,它支持 UDP 打洞、多租户等各种高端功能,几乎适配所有平台,非常强大。然而现实世界是复杂的,无法保证所有的 NAT 都能打洞成功,且 Netmaker 目前还没有 fallback 机制,如果打洞失败,无法 fallback 改成走中继节点。Tailscale 在这一点上比 Netmaker 高明许多,它支持 fallback 机制,可以尽最大努力实现全互联模式,部分节点即使打洞不成功,也能通过中继节点在这个虚拟网络中畅通无阻。
没错,我移情别恋了,从 Netmaker 阵营转向了 Tailscale,是渣男没错了。
Tailscale 是一种基于 WireGuard 的虚拟组网工具,和 Netmaker 类似,最大的区别在于 Tailscale 是在用户态实现了 WireGuard 协议,而 Netmaker 直接使用了内核态的 WireGuard。所以 Tailscale 相比于内核态 WireGuard 性能会有所损失,但与 OpenVPN 之流相比还是能甩好几十条街的,Tailscale 虽然在性能上做了些许取舍,但在功能和易用性上绝对是完爆其他工具:
简而言之,我们可以将 Tailscale 看成是更为易用、功能更完善的 WireGuard。
!https://jsdelivr.icloudnative.io/gh/yangchuansheng/imghosting3@main/uPic/2022-03-20-14-50-Q4bWmK.png
光有这些还不够,作为一个白嫖党,咱更关心的是免费与开源。
Tailscale 是一款商业产品,但个人用户是可以白嫖的,个人用户在接入设备不超过 20 台的情况下是可以免费使用的(虽然有一些限制,比如子网网段无法自定义,且无法设置多个子网)。除 Windows 和 macOS 的图形应用程序外,其他 Tailscale 客户端的组件(包含 Android 客户端)是在 BSD 许可下以开源项目的形式开发的,你可以在他们的 GitHub 仓库找到各个操作系统的客户端源码。
对于大部份用户来说,白嫖 Tailscale 已经足够了,如果你有更高的需求,比如自定义网段,可以选择付费。
我就不想付费行不行?行,不过得往下看。
Tailscale 的控制服务器是不开源的,而且对免费用户有诸多限制,这是人家的摇钱树,可以理解。好在目前有一款开源的实现叫 Headscale,这也是唯一的一款,希望能发展壮大。
Headscale 由欧洲航天局的 Juan Font 使用 Go 语言开发,在 BSD 许可下发布,实现了 Tailscale 控制服务器的所有主要功能,可以部署在企业内部,没有任何设备数量的限制,且所有的网络流量都由自己控制。
目前 Headscale 还没有可视化界面,期待后续更新吧。
Headscale 部署很简单,推荐直接在 Linux 主机上安装。
理论上来说只要你的 Headscale 服务可以暴露到公网出口就行,但最好不要有 NAT,所以推荐将 Headscale 部署在有公网 IP 的云主机上。
首先需要到其 GitHub 仓库的 Release 页面下载最新版的二进制文件。
$ wget --output-document=/usr/local/bin/headscale \
https://github.com/juanfont/headscale/releases/download/v<HEADSCALE VERSION>/headscale_<HEADSCALE VERSION>_linux_<ARCH>
$ chmod +x /usr/local/bin/headscale
复制
创建配置目录:
$ mkdir -p /etc/headscale
复制
创建目录用来存储数据与证书:
$ mkdir -p /var/lib/headscale
复制
创建空的 SQLite 数据库文件:
$ touch /var/lib/headscale/db.sqlite
复制
创建 Headscale 配置文件:
$ wget https://github.com/juanfont/headscale/raw/main/config-example.yaml -O /etc/headscale/config.yaml
复制
修改配置文件,将 server_url
改为公网 IP 或域名。如果是国内服务器,域名必须要备案。我的域名无法备案,所以我就直接用公网 IP 了。
如果暂时用不到 DNS 功能,可以先将 magic_dns
设为 false。
server_url
设置为 http://<PUBLIC_IP>:8080
,将 <PUBLIC_IP>
替换为公网 IP 或者域名。
可自定义私有网段,也可同时开启 IPv4 和 IPv6:
ip_prefixes:
# - fd7a:115c:a1e0::/48
- 10.1.0.0/16
复制
创建 SystemD service 配置文件:
# /etc/systemd/system/headscale.service
[Unit]
Description=headscale controller
After=syslog.target
After=network.target
[Service]
Type=simple
User=headscale
Group=headscale
ExecStart=/usr/local/bin/headscale serve
Restart=always
RestartSec=5
# Optional security enhancements
NoNewPrivileges=yes
PrivateTmp=yes
ProtectSystem=strict
ProtectHome=yes
ReadWritePaths=/var/lib/headscale /var/run/headscale
AmbientCapabilities=CAP_NET_BIND_SERVICE
RuntimeDirectory=headscale
[Install]
WantedBy=multi-user.target
复制
创建 headscale 用户:
$ useradd headscale -d /home/headscale -m
复制
修改 /var/lib/headscale 目录的 owner:
$ chown -R headscale:headscale /var/lib/headscale
复制
修改配置文件中的 unix_socket
:
unix_socket: /var/run/headscale/headscale.sock
复制
Reload SystemD 以加载新的配置文件:
$ systemctl daemon-reload
复制
启动 Headscale 服务并设置开机自启:
$ systemctl enable --now headscale
复制
查看运行状态:
$ systemctl status headscale
复制
查看占用端口:
$ ss -tulnp|grep headscale
tcp LISTEN 0 1024 [::]:9090 [::]:* users:(("headscale",pi
d=10899,fd=13))
tcp LISTEN 0 1024 [::]:50443 [::]:* users:(("headscale",pi
d=10899,fd=10))
tcp LISTEN 0 1024 [::]:8080 [::]:* users:(("headscale",pi
d=10899,fd=12))
复制
Tailscale 中有一个概念叫 tailnet,你可以理解成租户,租户与租户之间是相互隔离的,具体看参考 Tailscale 的官方文档: What is a tailnet。Headscale 也有类似的实现叫 namespace,即命名空间。我们需要先创建一个 namespace,以便后续客户端接入,例如:
$ headscale namespaces create default
复制
查看命名空间:
$ headscale namespaces list
ID | Name | Created
1 | default | 2022-03-09 06:12:06
复制
目前除了 iOS 客户端,其他平台的客户端都有办法自定义 Tailscale 的控制服务器。
OS | 是否支持 Headscale |
---|---|
Linux | Yes |
OpenBSD | Yes |
FreeBSD | Yes |
macOS | Yes |
Windows | Yes 参考 https://github.com/juanfont/headscale/blob/main/docs/windows-client.md |
Android | https://github.com/juanfont/headscale/issues/58#issuecomment-950386833 |
iOS | 暂不支持 |
我们先来看下 Linux 平台的接入。
Tailscale 官方提供了各种 Linux 发行版的软件包,但国内的网络你懂得,软件源根本用不了。好在官方还提供了 静态编译的二进制文件,我们可以直接下载。例如:
$ wget https://pkgs.tailscale.com/stable/tailscale_1.22.2_amd64.tgz
复制
解压:
$ tar zxvf tailscale_1.22.2_amd64.tgz
x tailscale_1.22.2_amd64/
x tailscale_1.22.2_amd64/tailscale
x tailscale_1.22.2_amd64/tailscaled
x tailscale_1.22.2_amd64/systemd/
x tailscale_1.22.2_amd64/systemd/tailscaled.defaults
x tailscale_1.22.2_amd64/systemd/tailscaled.service
复制
将二进制文件复制到官方软件包默认的路径下:
$ cp tailscale_1.22.2_amd64/tailscaled /usr/sbin/tailscaled
$ cp tailscale_1.22.2_amd64/tailscale /usr/bin/tailscale
复制
将 systemD service 配置文件复制到系统路径下:
$ cp tailscale_1.22.2_amd64/systemd/tailscaled.service /lib/systemd/system/tailscaled.service
复制
将环境变量配置文件复制到系统路径下:
$ cp tailscale_1.22.2_amd64/systemd/tailscaled.defaults /etc/default/tailscaled
复制
启动 tailscaled.service 并设置开机自启:
$ systemctl enable --now tailscaled
复制
查看服务状态:
$ systemctl status tailscaled
复制
Tailscale 接入 Headscale:
# 将 <HEADSCALE_PUB_IP> 换成你的 Headscale 公网 IP 或域名
$ tailscale up --login-server=http://<HEADSCALE_PUB_IP>:8080 --accept-routes=true --accept-dns=false
复制
这里推荐将 DNS 功能关闭,因为它会覆盖系统的默认 DNS。如果你对 DNS 有需求,可自己研究官方文档,这里不再赘述。
执行完上面的命令后,会出现下面的信息:
To authenticate, visit:
http://xxxxxx:8080/register?key=905cf165204800247fbd33989dbc22be95c987286c45aac303393704
1150d846
复制
在浏览器中打开该链接,就会出现如下的界面:
!https://jsdelivr.icloudnative.io/gh/yangchuansheng/imghosting3@main/uPic/2022-03-20-17-06-08qWbz.png
将其中的命令复制粘贴到 headscale 所在机器的终端中,并将 NAMESPACE 替换为前面所创建的 namespace。
$ headscale -n default nodes register --key 905cf165204800247fbd33989dbc22be95c987286c45aac3033937041150d846
Machine register
复制
注册成功,查看注册的节点:
$ headscale nodes list
ID | Name | NodeKey | Namespace | IP addresses | Ephemeral | Last seen | Onlin
e | Expired
1 | coredns | [Ew3RB] | default | 10.1.0.1 | false | 2022-03-20 09:08:58 | onlin
e | no
复制
回到 Tailscale 客户端所在的 Linux 主机,可以看到 Tailscale 会自动创建相关的路由表和 iptables 规则。路由表可通过以下命令查看:
查看 iptables 规则:
$ ip route show table 52
复制
macOS 客户端的安装相对来说就简单多了,只需要在应用商店安装 APP 即可,前提是你需要一个美区 ID。。。
!https://jsdelivr.icloudnative.io/gh/yangchuansheng/imghosting3@main/uPic/2022-03-20-17-33-3uRFwF.png
安装完成后还需要做一些骚操作,才能让 Tailscale 使用 Headscale 作为控制服务器。当然,Headscale 已经给我们提供了详细的操作步骤,你只需要在浏览器中打开 URL:http://<HEADSCALE_PUB_IP>:8080/apple
,便会出现如下的界面:
!https://jsdelivr.icloudnative.io/gh/yangchuansheng/imghosting3@main/uPic/2022-03-20-17-39-arYdfv.png
你只需要按照图中所述的步骤操作即可,本文就不再赘述了。
修改完成后重启 Tailscale 客户端,在 macOS 顶部状态栏中找到 Tailscale 并点击,然后再点击 Log in
。
!https://jsdelivr.icloudnative.io/gh/yangchuansheng/imghosting3@main/uPic/2022-03-20-17-43-pTW3r7.png
然后立马就会跳转到浏览器并打开一个页面。
!https://jsdelivr.icloudnative.io/gh/yangchuansheng/imghosting3@main/uPic/2022-03-20-17-46-AbzngB.png
接下来与之前 Linux 客户端相同,回到 Headscale 所在的机器执行浏览器中的命令即可,注册成功:
!https://jsdelivr.icloudnative.io/gh/yangchuansheng/imghosting3@main/uPic/2022-03-20-17-51-Gcjcmy.png
回到 Headscale 所在主机,查看注册的节点:
$ iptables -S
-P INPUT DROP
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-N ts-forward
-N ts-input
-A INPUT -j ts-input
-A FORWARD -j ts-forward
-A ts-forward -i tailscale0 -j MARK --set-xmark 0x40000/0xffffffff
-A ts-forward -m mark --mark 0x40000 -j ACCEPT
-A ts-forward -s 100.64.0.0/10 -o tailscale0 -j DROP
-A ts-forward -o tailscale0 -j ACCEPT
-A ts-input -s 10.1.0.5/32 -i lo -j ACCEPT
-A ts-input -s 100.115.92.0/23 ! -i tailscale0 -j RETURN
-A ts-input -s 100.64.0.0/10 ! -i tailscale0 -j DROP
$ iptables -S -t nat
-P PREROUTING ACCEPT
-P INPUT ACCEPT
-P OUTPUT ACCEPT
-P POSTROUTING ACCEPT
-A ts-postrouting -m mark --mark 0x40000 -j MASQUERADE
复制
回到 macOS,测试是否能 ping 通对端节点:
$ headscale nodes list
ID | Name | NodeKey | Namespace | IP addresses | Ephemeral | Last seen | Onlin
e | Expired
1 | coredns | [Ew3RB] | default | 10.1.0.1 | false | 2022-03-20 09:08:58 | onlin
e | no
2 | carsondemacbook-pro | [k7bzX] | default | 10.1.0.2 | false | 2022-03-20 09:48:30 | online | no
复制
也可以使用 Tailscale CLI 来测试:
$ ping -c 2 10.1.0.1
PING 10.1.0.1 (10.1.0.1): 56 data bytes
64 bytes from 10.1.0.1: icmp_seq=0 ttl=64 time=37.025 ms
64 bytes from 10.1.0.1: icmp_seq=1 ttl=64 time=38.181 ms
--- 10.1.0.1 ping statistics ---
2 packets transmitted, 2 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 37.025/37.603/38.181/0.578 ms
复制
如果你没有美区 ID,无法安装 App,可以直接使用命令行版本,通过 Homebrew 安装即可:
Android 客户端就比较麻烦了,需要自己修改源代码编译 App,具体可参考 这个 issue。编译过程还是比较麻烦的,需要先修改源码,然后构建一个包含编译环境的 Docker 镜像,最后在通过该镜像启动容器编译 apk。
我知道很多人一看麻烦就不想搞了,这个问题不大,我送佛送到西,提供了一条龙服务,你只需 fork 我的 GitHub 仓库 tailscale-android:
!https://jsdelivr.icloudnative.io/gh/yangchuansheng/imghosting3@main/uPic/2022-03-20-21-25-utX9zr.png
然后在你的仓库中点击 Settings 标签,找到 Secrets 下拉框中的 Actions 选项:
!https://jsdelivr.icloudnative.io/gh/yangchuansheng/imghosting3@main/uPic/2022-03-20-21-32-OQT9m7.jpg
选择 New repository secret 添加一个 secret 叫 HEADSCALE_URL
,将你的 Headscale 服务公网地址填入其中:
!https://jsdelivr.icloudnative.io/gh/yangchuansheng/imghosting3@main/uPic/2022-03-20-21-35-ep7qXR.png
添加在这里的配置,将只对你可见,不用担心会泄露给他人。
然后点击 Actions 标签,选择 Release Workflow。
!https://jsdelivr.icloudnative.io/gh/yangchuansheng/imghosting3@main/uPic/2022-03-20-21-53-CXAfAl.png
你会看到一个 Run workflow 按钮,点击它,然后在下拉框中点击 Run workflow。
!https://jsdelivr.icloudnative.io/gh/yangchuansheng/imghosting3@main/uPic/2022-03-20-22-02-SaxiiT.png
流水线就会开始执行,执行成功后就会在 Release 页面看到编译好的 apk。
!https://jsdelivr.icloudnative.io/gh/yangchuansheng/imghosting3@main/uPic/2022-03-20-22-05-wxjatP.png
接下来的事情就简单了,下载这个 apk 到你的 Android 手机上安装就好了。安装完成后打开 Tailscale App,选择 Sign in with other。
然后就会跳出这个页面:
将其中的命令粘贴到 Headscale 所在主机的终端,将 NAMESPACE 替换为之前创建的 namespace,然后执行命令即可。注册成功后可将该页面关闭,回到 App 主页,效果如图:
回到之前的 GitHub 仓库,刚才我们是通过手动触发 Workflow 来编译 apk 的,有没有办法自动编译呢?只要 Tailscale 官方仓库有更新,就立即触发 Workflow 开始编译。
那当然是可以实现的,而且我已经实现了,仔细看 GitHub Actions 的编排文件:
!https://jsdelivr.icloudnative.io/gh/yangchuansheng/imghosting3@main/uPic/2022-03-20-22-29-QJvXwt.png
红框圈出来的部分表示只要仓库的 main
分支有更新,便会触发 Workflow。现在的问题是如何让 main 分支和上游官方仓库一致,一直保持在最新状态。
这个问题使用第三方 Github App 就可以解决,这个 App 名字简单粗暴,就叫 Pull,它的作用非也很简单粗暴:保持你的 Fork 在最新状态。
Pull 的使用方法很简单:
!https://jsdelivr.icloudnative.io/gh/yangchuansheng/imghosting3@main/uPic/2022-03-20-22-44-fRwr6j.png
!https://jsdelivr.icloudnative.io/gh/yangchuansheng/imghosting3@main/uPic/2022-03-20-22-46-flOKJW.png
简单三步,Pull App 就安装好了。接下来 Pull App 会每天定时帮你更新代码库,使你 fork 的代码始终是最新版的。
Windows Tailscale 客户端想要使用 Headscale 作为控制服务器,只需在浏览器中打开 URL:http://<HEADSCALE_PUB_IP>:8080/windows
,便会出现如下的界面:
!https://jsdelivr.icloudnative.io/gh/yangchuansheng/imghosting3@main/uPic/2022-03-20-23-30-zcQX3F.png
按照其中的步骤操作即可。
除了常规的 Linux 发行版之外,还有一些特殊场景的 Linux 发行版,比如 OpenWrt、威联通(QNAP)、群晖等,这些发行版的安装方法已经有人写好了,这里就不详细描述了,我只给出相关的 GitHub 仓库,大家如果自己有需求,直接去看相关仓库的文档即可。
Tailscale iOS 客户端源代码没有开源,目前还无法破解使其使用第三方控制服务器,遗憾~~
到目前为止我们只是打造了一个点对点的 Mesh 网络,各个节点之间都可以通过 WireGuard 的私有网络 IP 进行直连。但我们可以更大胆一点,还记得我在文章开头提到的访问家庭内网的资源吗?我们可以通过适当的配置让每个节点都能访问其他节点的局域网 IP。这个使用场景就比较多了,你可以直接访问家庭内网的 NAS,或者内网的任何一个服务,更高级的玩家可以使用这个方法来访问云上 Kubernetes 集群的 Pod IP 和 Service IP。
假设你的家庭内网有一台 Linux 主机(比如 OpenWrt)安装了 Tailscale 客户端,我们希望其他 Tailscale 客户端可以直接通过家中的局域网 IP(例如 192.168.100.0/24) 访问家庭内网的任何一台设备。
配置方法很简单,首先需要设置 IPv4 与 IPv6 路由转发:
$ /Applications/Tailscale.app/Contents/MacOS/Tailscale ping 10.1.0.1
pong from coredns (10.1.0.1) via xxxx:41641 in 36ms
复制
客户端修改注册节点的命令,在原来命令的基础上加上参数 --advertise-routes=192.168.100.0/24
。
$ brew install tailscale
复制
在 Headscale 端查看路由,可以看到相关路由是关闭的。
$ echo 'net.ipv4.ip_forward = 1' | tee /etc/sysctl.d/ipforwarding.conf
$ echo 'net.ipv6.conf.all.forwarding = 1' | tee -a /etc/sysctl.d/ipforwarding.conf
$ sysctl -p /etc/sysctl.d/ipforwarding.conf
复制
开启路由:
$ tailscale up --login-server=http://<HEADSCALE_PUB_IP>:8080 --accept-routes=true --accept-dns=false --advertise-routes=192.168.100.0/24
复制
其他节点查看路由结果:
$ headscale nodes list|grep openwrt
6 | openwrt | [7LdVc] | default | 10.1.0.6 | false | 2022-03-20 15:50:46 | onlin
e | no
$ headscale routes list -i 6
Route | Enabled
192.168.100.0/24 | false
复制
现在你在任何一个 Tailscale 客户端所在的节点都可以 ping 通家庭内网的机器了,你在公司或者星巴克也可以像在家里一样用同样的 IP 随意访问家中的任何一个设备,就问你香不香?
目前从稳定性来看,Tailscale 比 Netmaker 略胜一筹,基本上不会像 Netmaker 一样时不时出现 ping 不通的情况,这取决于 Tailscale 在用户态对 NAT 穿透所做的种种优化,他们还专门写了一篇文章介绍 NAT 穿透的原理, 中文版翻译自国内的 eBPF 大佬赵亚楠,墙裂推荐大家阅读。放一张图给大家感受一下:
!https://jsdelivr.icloudnative.io/gh/yangchuansheng/imghosting3@main/uPic/2022-03-21-10-52-TzXGEZ.png
本文给大家介绍了 Tailscale 和 Headscale,包括 Headscale 的安装部署和各个平台客户端的接入,以及如何打通各个节点所在的局域网。下篇文章将会给大家介绍如何让 Tailscale 使用自定义的 DERP Servers(也就是中继服务器),See you~~
由于安全限制,开发环境与生产环境的网络隔离,只能通过U盘传递文件。
初期部署流程极度麻烦。
暂时没有找到合适的自动化部署方案。本来想通过jenkins实现,但感觉在这个流程下不会有太大优化空间,并且也没有多余机器。
于是抽时间编写了一下脚本,稍微减少了一点敲命令行的时间。
#!/bin/bash
# 定义变量
APP_NAME="项目名"
# 获取时间戳当包版本
DOCKER_IMAGE_TAG=$(date +%s)
DOCKER_IMAGE_NAME="$APP_NAME:$DOCKER_IMAGE_TAG"
DOCKER_IMAGE_FILE="$APP_NAME.tar"
# 打出jar包
if ! mvn clean package -Dmaven.test.skip=true -Pprod; then
# mvn命令执行失败,输出错误信息并退出脚本
echo "mvn command failed"
exit 1
fi
# 如果是win,需要先进入wsl,如果是mac则不做操作
if [[ "$OSTYPE" == "darwin"* ]]; then
echo "This is a Mac system,Do nothing"
# mac下直接用docker命令
docker_command="docker"
elif [[ "$OS" == "Windows_NT" ]]; then
# win的wsl下需要使用wsl docker命令
docker_command="wsl docker"
# 直接使用wsl命令会打开新终端,导致后续脚本命令无法执行(注意!)
wsl docker --version
else
# 系统识别失败,输出错误信息并退出脚本
echo "system recognition failed"
exit 1
fi
# 执行docker build命令
if ! $docker_command build -t $DOCKER_IMAGE_NAME .; then
# docker build命令执行失败,输出错误信息并退出脚本
echo "docker build command failed"
exit 1
fi
# 执行docker save命令
if ! $docker_command save -o "./docker/$DOCKER_IMAGE_FILE" $DOCKER_IMAGE_NAME; then
# docker save命令执行失败,输出错误信息并退出脚本
echo "docker save command failed"
exit 1
fi
# 执行docker rm命令
if ! $docker_command image rm $DOCKER_IMAGE_NAME; then
# docker rm命令执行失败,输出错误信息并退出脚本
echo "docker image rm command failed"
exit 1
fi
# 进入docker目录
cd docker || exit 1
# 生成推送文件
rm pushImage.sh
touch pushImage.sh
chmod +x pushImage.sh
# 生成推送文件
cat << EOF > pushImage.sh
#!/bin/bash
# 加载镜像
if ! docker load -i $DOCKER_IMAGE_FILE; then
echo "docker load command failed"
exit 1
fi
# 获取镜像ID
if ! IMAGE_ID=\$(docker inspect --format='{{.Id}}' $DOCKER_IMAGE_NAME); then
echo "docker inspect command failed"
exit 1
fi
# 打Tag
if ! docker tag "\$IMAGE_ID" 仓库地址/$DOCKER_IMAGE_NAME; then
echo "docker tag command failed"
exit 1
fi
# 推送镜像
if ! docker push 仓库地址/$DOCKER_IMAGE_NAME; then
echo "docker push command failed"
exit 1
fi
docker rmi -f "\$IMAGE_ID"
rm $DOCKER_IMAGE_FILE
EOF
# 如果是win,退出wsl,如果是mac则不做操作
if [[ "$OSTYPE" == "darwin"* ]]; then
echo "This is a Mac system,Do nothing"
elif [[ "$OS" == "Windows_NT" ]]; then
# 退出wsl
exit
else
# 系统识别失败,输出错误信息并退出脚本
echo "system recognition failed"
exit 1
fi