利用 OpenWRT 的 Hotplug 事件解决 Zerotier 启动时添加自定义路由的难题

利用 ip monitor 工具实现路由观察分析,并利用 OpenWRT 的 hotplug 事件解决 Zerotier 启动时添加自定义路由的难题。 背景 公司有多个办公地点,使用zerotier组网 不是所有办公地点都开放实现互访 每个办公地点都会定期变动公网ip,每日执行 ifup wan 对电信网络执行重新拨号,因此会导致自己手动添加的 ip route 路由被清除 如何获得真正加入 zerotier 网络并可用变成了必须解决的问题,因此本文探讨的问题即为此 Zerotier本身依赖UDP打洞技术,属于P2P V*N,没有明确的中心化概念,所以什么时候明确连接上网络是个不可预知的问题 Zerotier本身有所有节点的自定义路由,可以在控制器添加,但本次仅为了单台节点自身添加自定义路由而不希望网络中其他节点也有此路由,因此只能在节点本身动手脚 解决方案 解决方案大体有这么两种 方案1:可以全部通过zerotier custom route实现,全路由转发,再配合iptables ACCEPT来实现访问控制 方案2:仅在需要访问其他子网的路由节点本地添加自定义路由 分析步骤 打开监控 ip monitor all 之后执行 service zerotier stop 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 [NEIGH]172.16.200.1 dev ztjqgyage2 lladdr d2:10:71:16:e9:16 STALE [ROUTE]Deleted 172.……

阅读全文

Linux 动态切换路由表

背景 我们总共有13台服务器,1个24口交换机(没有路由器),仅购买了两个公网IP,也就是说仅有两台服务器可以直接连通公网(全配置为全转发路由器),而其他机器得通过NAT来访问公网。 问题 存在的问题:托管在机房的服务器由于是二手硬件,难免会偶尔直接崩溃无法开机。。。而我们没有实际上的路由器,若网关服务器炸了,作为网络内需要通过NAT来上网的机器,该如何自动切换到备用网关呢? 解决思路 由于我们并不是一台服务器上面多条物理网线,所以没办法使用单台服务器内的网口上下线事件来作为切换通知 所以解决方案是:那部分需要做NAT的机器,通过自身定时检测是否能通过网关访问公网,若不能则切换为备用网关 前提条件 两台能分配到公网的机器开启全路由模式 内核允许转发 iptables允许转发 公司主路由(openwrt 系统)和托管机房服务器通过 Zerotier 组网,并且两台公网服务器分别分配到 zerotier ip 172.16.200.1 和 172.16.200.2 解决步骤 增加ping包的目标路由表、ping指定网络接口,可以在不影响现有网络运行的情况下达到定向检测网络接口可用性 ping -I $NIC -c 2 -W $PING_TIMEOUT $REMOTE_IP > /dev/null # 通过$NIC网络接口发出对$REMOTE_IP的ping包,数量2个,若超过超时时间$PING_TIMEOUT(seconds)则认为是失败,> /dev/null 不输出ping命令的结果到控制台 PING_RESULT=$? # 通过获取上一次命令执行成功的结果,成功为0,失败为1 检测主网关和备用网关可用性,若主网关可用则优先使用主网关 添加crontab任务,每分钟执行一次判断以达到动态切换作用 xxx.sh > /tmp/route_failover.log 实现切换的脚本参考(适用于Linux服务器) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 #!……

阅读全文

机房托管的血与泪

前言 为了解决日益增长的计算、存储、测试环境的需求,结合我们办公室小机房优异的散热、电量、网络条件(详情如下),因此在2021年3月份决定将公司的13台Dell R720服务器搬迁到机房进行托管,以期获得稳定的使用条件。 散热:开了16度然而还能热出汗的空调 供电:物业预期下午5点断电早上11点先进行预演,时不时跳一下闸什么的 机房布线管理:网线乱飞、电源线乱飞、随时踩一脚断电or断网 潘多拉的域名玩法:电信专线并不封堵TCP/443,当年(2017)使用TCP/443并配合DNS-01 challenge验证域名所有权,然后使用Let's Encrypt来签发证书,最终提供给测试环境HTTPS证书,并且在公网环境提供免备案的服务 极其漫长的踩坑之路 从过年后3月初决定要搞事,开始采购新机器到最终上架“萝岗加速器”机房的时间是5月7号,整整跨了两个月。 硬件玄学 二手硬件不稳定什么的,对于我们这种垃圾佬当然不是什么问题啦!插电,开机~~~ 服务器采购(花费一周) 购买6台新的Dell R720 XD 2U服务器,每台机器配置 CPU: E5 2650V2 * 2 H710P mini 硬盘阵列卡 内存:8GB/16GB * 16 = 144GB/288GB 迁移原有服务器(Dell R420)内硬盘到新的机器 顺利的:基本能够直接开机,只要硬件自检通过,然后重新配置阵列卡,开机完成硬件升级 失败的:硬盘阵列卡故障、硬盘背板失败不通电、内存没装好….. PVE集群之坑 从已有用于测试环境的3台1U服务器,升级成4台2U的服务器(由于IP经过了变更,所以需要重新组件集群而不是使用现有的集群) 旧的集群:2台1U服务器原本已经安装了PVE并且有虚拟机提供测试环境数据,正在服役 新的集群:2台新机器直接安装PVE操作系统,组建集群 集群管理的坑 对pve集群node节点管理不熟悉 官方文档是最好的解决方案 对pve虚拟机磁盘管理不熟悉导致的坑 误删两个虚拟机硬盘,直接导致测试环境需要重建 remove/purge的时候要认真阅读警告信息。。。 域名备案问题 这是个迷之问题,只有在神奇的东方才有这种需求,这个过程花了一些时间去了解政策,才算是明确了再次备案不影响原先接入备案的问题。 遵循接入方备案原则:同一个域名,接入阿里云需要做一次备案,接入另外一家服务商需要再做一次备案。 当年绕过电信专线不封堵TCP/443用来提供HTTPS,然后间接提供相对标准(只使用80/443端口)的公网HTTP服务的方案,在经过了几年的发展,积累了一大批域名,还好基本都是属于同一个顶级域名的二级、三级域名,没造成太大的修改难题 文网文问题 这是一个更迷的问题,同样只存在于大局域网国家,多次申诉、联系客服折腾无果,只能按照某福报厂要求对网站内容进行大幅度修改,去掉游戏相关字眼(只要网站内容有游戏,必须要求文网文证件)的内容。 一个国家有关部门已经不签发的证书,却在审核备案的的初审部分需要审核,投诉无门,喝喝 网络架构调整 原网络拓扑:公司和服务器之间是局域网(192.168.0.0/21),服务器局域网连接是通过连接同一个交换机并uplink到公司主路由来实现访问的,几个提供对外访问的具有公网的服务器则是另外一个专线交换机连接 新网络拓扑:为了方便公司同事在开发的时候,直接使用局域网地址+端口号来访问测试服务,而不是一切访问都经过网关做端口转发 通过 SD-WAN 技术,使用P2P VPN软件Zerotier建立局域网 172.16.200.0/24 托管机房网关 Zerotier 网口 IP 172.16.200.1 配置防火墙允许流量 iptables -t raw -A INPUT -i zt+ -j ACCEPT 配置 NAT iptables -t nat -A POSTROUTING -o zt+ -j MASQUERADE 配置入站数据转发 iptables -A FORWARD -i zt+ -j ACCEPT 配置 Linux 内核开启 ipv4 转发,修改 /etc/sysctl.……

阅读全文

通过 DHCP Options 下发路由解决同局域网内服务器互访的效率问题

背景 局域网 Kubernetes 测试服务器的具有公网(1.2.3.4)、局域网(10.0.0.10)双网卡 日常需求较多需要从局域网内/公网环境通过域名访问测试服务器(同时还有部分正式环境的大数据服务) 旧方案 公网环境 DNS 配置gw.sukikaka.com A 1.2.3.4 局域网环境 DNS Server 10.0.0.1 配置劫持成 gw.sukikaka.com A 10.0.0.10 局域网环境通过 DHCP Server 配置 DHCP Options 6,10.0.0.1,223.5.5.5 来达到下发 DNS Server 的目的 而以前用内网DNS服务器添加劫持,将gw.sukikaka.com A 10.0.0.10从而解决解析的问题,但是其他测试环境域名通过CNAME将解析指向gw.sukikaka.com时,并不能将CNAME再次顺利解析到10.0.0.10 存在的问题 需要将DNS Server设置成内网指定的DNS Server 10.0.0.10,否则无法劫持 增减域名需要在公网DNS Server设置解析,也需要在局域网DNS Server设置解析 另外,由于公司不少同事是使用科学上网,而这些科学上网很难要求他们会自己将DNS Server设置成内网的Server,所以最终导致占用 Kubernetes 公网带宽,测试环境体验不好 访问测试环境的数据会经过主路由器 NAT 成 default route 的公网地址,然后再访问Kubernetes的公网地址NAT回来,然后处理完成之后再反向回来局域网内的请求客户端,ip packet 增加了多余的NAT 新方案 公网环境 DNS 配置gw.sukikaka.com A 1.2.3.4 局域网环境通过 DHCP Server(网关) 配置 DHCP Options 6,10.0.0.1,223.5.5.5 来达到下发 DNS Server的目的(此时内网DNS Server仅通过使用SmartDNS服务,用于优化DNS查询,不做测试环境解析记录劫持) 利用 DHCP Server 将 DHCP Options 121, 1.……

阅读全文

Migrate to Hugo

2017年搭建的hexo博客,因腾讯云学生机即将过期,这几年用下来也觉得:似乎没什么必要续费云服务器 另外,人老了对npm这种一大坨恶心东西没什么好感,因此决定换用hugo,以此记录。 hexo迁移到hugo 腾讯云迁移到github pages 启用disqus评论 UPDATE 2020-09-10 由于实在忍受不了github pages速度。。。。 于是: 又迁移到了腾讯云对象存储+CDN+免费HTTPS证书,按访问量收费,估计就。。。几块钱一个月吧,可以忽略不计- -# 使用腾讯云对象存储coscmd工具上传public文件夹,和之前github pages上传到github一样,也问题不大。。 ……

阅读全文

Vue项目使用Nginx部署并发布到子目录

Vue项目使用Nginx部署并发布到子目录 默认Vue项目是以根目录来发布的,但是我们要有时候希望以子目录来做发布,那么就需要做一些修改,Vue项目本身的配置,包括Nginx也需要做一些配置修改。 对Vue项目源码的修改 以下路径以vue-cli常见项目的文件结构来说明。 修改路由:router/index.js,添加base部分的代码。 1 2 3 4 5 6 7 8 9 10 function getAbsolutePath () { let path = location.pathname return path.substring(0, path.lastIndexOf('/') + 1) } export default new Router({ mode: 'hash', base: getAbsolutePath(), routes: [...] }) 修改配置:config/index.js 文件,对于打包路径的定义,只处理build,将assetsPublicPath: '/'修改为assetsPublicPath: './' 1 2 3 4 5 6 7 8 9 10 11 12 module.exports = { build: { // Template for index.html index: path.resolve(__dirname, '../dist/index.html'), // Paths assetsRoot: path.……

阅读全文

记一次celery worker hang debug

记一次celery worker hang debug 【写在前面】: 本文最终并没有debug出为什么卡住,虽然换了种方案解决了问题。 引入celery是为了调用京东api来做发货行为,以便提供给电商业务下快递单,然而在这个过程中,踩了一些坑(此文大概是2018年底的记录) 最初的配置,使用supervisor来管理celery进程,并且在代码更新之后,使用supervisorctl restart {$APP_NAME}来更新代码(celery并不支持gracefully reload,也暂时没有用其他更优雅的方案,待更深入的测试) 发现问题 线上的celery总是一段时间之后,就没有接受新的请求,celery beat还在发消息,python代码也在发消息存到broker(redis)里面,但消息一直没被消费 debug过程 找出celery worker的pid, www-data 6329 0.0 0.6 157228 50640 ? S 2018 0:03 /home/ubuntu/.pyenv/versions/3.7.1/envs/ems-admin-api/bin/python /home/ubuntu/.pyenv/versions/ems-admin-api/bin/celery -A settings beat -s /tmp/celerybeat-schedule --pidfile= -l info www-data 10004 0.1 0.6 162456 53804 ? S Jan02 4:12 /home/ubuntu/.pyenv/versions/3.7.1/envs/ems-admin-api/bin/python /home/ubuntu/.pyenv/versions/ems-admin-api/bin/celery -A settings worker --autoscale=8,4 -l info www-data 18317 0.0 0.6 173032 56280 ? S Jan03 0:04 /home/ubuntu/.pyenv/versions/3.7.1/envs/ems-admin-api/bin/python /home/ubuntu/.pyenv/versions/ems-admin-api/bin/celery -A settings worker --autoscale=8,4 -l info www-data 18318 0.……

阅读全文

pipenv使用指南

pipenv使用指南 厌倦了使用virtualenv pyenv的时候,总是先要创建一个虚拟环境,然后激活虚拟环境再写代码 有时候就单纯想要写点scripts,那么pipenv这个开箱即用的虚拟环境显然更适合 确保当期不在任何虚拟环境中,或者说在系统的解释器中 pip install pipenv 然后其他安装命令,以pipenv代替pip 比如pipenv install -r requirements.txt会将pip的依赖文件requirements.txt转换成pipenv的版本管理格式文件Pipfile和Pipfile.lock 如果是空项目,那么直接pipenv install {third-party-lib} 默认将会为你创建当前目录加随机字母组成的虚拟环境,后续直接管理 位于 ~/.local/share/virtualenvs/{pwd_basename}-{random_stuff} 如果需要在vscode中支持pipenv的话,新增支持pipenv的虚拟目录位置 然后就可以愉快地选择pipenv的虚拟环境了……

阅读全文

pyenv使用指南

背景 之前使用venv,大部分情况下并没有什么不好,配合virtualenvwrapper,用起来倒也顺手,如果没有Python版本切换需求的话。 日常开发机器使用的python是最新版,logging的时候,使用了f’i am a {var}‘这种format语法,而这个特性是Python 3.6之后才有的,于是上线之后凉凉= = (生产环境的机器是Ubuntu 16.04,仅使用apt管理Python版本,于是装的版本实际上是3.5.2) 既然吃了一回亏,那么就赶紧解决问题。。。 题外话:貌似在Python的benchmark中,3.5、3.6、3.7中性能最差也是3.5,于是,抽空将生产机器改成用pyenv来管理版本 食用步骤 参考pyenv-installer进行安装和配置 直接装需要的Python版本啦,比如pyenv install 3.7.1 如果安装过程中有任何问题,参考common build problems 如果安装也成功了,那么希望更改当前shell环境的Python版本来替换掉系统的版本,可以使用pyenv global 3.7.1 virtualenv使用 使用指定的Python版本创建虚拟环境pyenv virtualenv 3.7.1 myenv 启用虚拟环境 pyenv activate myenv 退出虚拟环境 source deactivate 进入项目目录自动启用虚拟环境,离开项目目录退出虚拟环境,需要在项目目录内 pyenv local myenv,会创建一个.python-version的文件,内容为虚拟环境的名字,则为myenv done, 希望食用快乐~……

阅读全文

Python日期相关知识及处理

Python的日期实现/Linux发行版一般使用(tz database/Olson database)1 Python中的日期 一般使用pytz库来操作日期 django中的时区使用问题 https://docs.djangoproject.com/en/2.1/topics/i18n/timezones/ Time zone support is disabled by default. To enable it, set USE_TZ = True in your settings file. Time zone support uses pytz, which is installed when you install Django. When support for time zones is enabled, Django stores datetime information in UTC in the database, uses time-zone-aware datetime objects internally, and translates them to the end user’s time zone in templates and forms.……

阅读全文