阅读视图

发现新文章,点击刷新页面。
🔲 ⭐

介绍一个生产力工具:ntfy

之前为了监控家里的IP地址的变化,写了一个循环任务,每隔几秒钟访问一次ifconfig.io,获取大网IP,当发现IP地址变化时,通过mailgun发邮件到自己邮箱,用这种方式感知到IP地址变化,同时也使用域名提供商的域名解析接口刷新IP地址。这个邮箱通知的方式有点偏重,并且mailgun随时有被墙的风险。最近开始接触虚拟币投资,发现虚拟币的波动大,适合短线交易。合约支持看空和看涨,因此只要有交易量,价格有波动则适合买卖,当然能否踩准加仓和平仓的波峰波谷才是关键。对于我这样每天并不能随时看盘的上班族而言,希望有个后台监控任务,识别已经仓位变化,变化幅度大时通知到手机。全网搜刮,找到了ntfy这个应用,支持自托管,有域名即可。用docker部署了,然后也下载了官方提供的android app,设置app后台常驻,使用方法也相当简单。直接上代码:

class Notify:
    def __init__(self, endpoint, user, password):
        self.auth_header = "Basic " + base64.b64encode(
            (user + ":" + password).encode("ascii")
        ).decode("ascii")
        # Remove trailing slashes
        while endpoint.endswith('/'):
            endpoint = endpoint[:-1]
        self.endpoint = endpoint

    def notify(self, title, msg, subject):
        if len(self.endpoint) == 0:
            return

        hostname = socket.gethostname()
        msg += f" (from {hostname})"
        res = requests.post(self.get_endpoint(subject),
                            data=msg,
                            headers={
                                "Title": title,
                                "Authorization": self.auth_header
                            })
        if not res or res.status_code != 200:
            logging.error(title)
            logging.error(msg)
            logging.error(str(res.status_code) + ":" + str(res.content))

    def get_endpoint(self, subject):
        if subject.startswith('/'):
            return self.endpoint + subject
        else:
            return self.endpoint + "/" + subject

然后就是调用币安的API SDK代码,请求账号的仓位信息,发现仓位变化量达到一定幅度时发通知。区分盈利和亏损,手机app上面分别订阅盈利和亏损的topic,设置不同的提示铃声,随时感知仓位变化信息,必要时进行平仓和加仓。

Screenshot_20241224_215317_ntfy Screenshot_20241224_215323_ntfy

后面基于这个代码继续丰富这个后台任务的逻辑,走上虚拟币量化之路。

🔲 ☆

困扰了快1个月的家用宽带网络卡顿问题-Linux病毒实战手记

最近一段时间家里领导反馈网络经常慢,之前还没太在意,上周反馈给电信,电信小哥直接给换了光猫。观察了几天,仍然间歇性的卡顿。尝试换路由器,换光猫拨号,都没有彻底解决。今天发现homenas流量异常,经常跑出大于电信宽带规格的带宽,家里宽带规格是300Mb的,上行更是只有50Mb的,怎么能跑出1000Mb带宽的数据量,很像是局域网的访问行为,这个带宽看起来很像家用磁盘的规格。压根没往外网流量上面想。查各种监控,都只有带宽和流出数据量的统计,找不到哪个进程或者业务。尝试atop,ntop,iftop,netdata,nethogs各种监控,都看不到流量哪里来的,更别说netstat了。最后只能tcpdump持续抓包,找到了一些线索。

​大量从本机发出去的syn包,syn flood攻击,只是我的nas是攻击方,被拿来做“肉鸡”了。只发出了syn包,netstat看不到连接,还是我敲命令的时候,攻击已经停了,应该是前者,攻击的时候,登录在控制台界面也看不到连接。发现所有的网络统计工具都不显示只发了syn包的连接。syn攻击在工作中经常听到,但是很少有机会去实地解决,前端的防护设备帮挡住了,没想到在家用设备上面遇到了。

​进一步找系统日志,有提示被攻击,应该是对端回应syn的包被系统识别为攻击请求直接拒绝了。
mmexport1713540039729

mmexport1713540042770

mmexport1713540047007

mmexport1713540048592
​第一天就先查到这里了,担心NAS上面的数据被破坏,也先保家里的网络,关机收工。留下了几个疑点:
​1,能跑出80MB上行带宽,远大于5MB,说明电信在这种攻击报文的带宽统计有缺陷,拦不住。当然syn包是否都出了光猫,发到了目标端,还是存疑的;
​2,操作系统能拦截外面进来的攻击行为,不知道有没有拦截本机外发攻击包的行为;
​3,根因应该是nas上面docker滥装,没有考证安全性,被留了后门,或者某个软件有已知的漏洞,被利用了。空了再找吧。

​第二天上午,小心翼翼的开启NAS,继续分析头一天的抓包和系统日志。

试图从日志搜索攻击目标端的IP地址是什么时候注入的,无果。然后逐行分析日志,将重复的UFW日志过滤掉。可以发现有两条Cron的日志一直在打印:

image

这条 /.mod的日志特别显眼,之前就看到过这个日志,没有联想到系统的异常流量,因此觉得就是系统的例行任务。现在仔细看这个文件,是放在根目录的,之前没去分析过这条记录的含义,没注意放在根目录。一般可执行的命令怎么会放在根目录?赶紧去根目录找这个文件,使用ls命令,居然是返回的空,没见过这种,大概率是修改了文件属性之类的,继续使用stat命令,就发现异常了。文件是3月30号创建的。考虑这个文件每分钟都在执行,那我手动执行一次也无妨。使用strace跟踪执行过程,发现这个可执行文件会去打开/usr/lib/libgdi.so.0.8.2这个文件,然后看起来是直接执行这个文件。这是so文件,怎么会可执行呢?病毒无疑了。后面去打开这个文件,才发现是一个脚本。比我想象的简单多了,相当于分析了一下shell脚本执行时的strace,:-(

看到这里震惊了,Linux系统出现病毒文件,并且还能对外发起syn flood攻击。一下子就明了了。这个so文件也是3月30号创建的,然后也尝试执行了一下,strace日志比较复杂,有大量的网络操作。剩下的就没细看了,直接Google,找到了非常接近的介绍:Linux.Siggen.5802,按照这里给的列表,逐一确认是否病毒文件,逐一删除,并清理掉病毒生成的Cron任务。

最后还想找到3月30号系统是如何安装上这个病毒的,找了系统日志,没有发现太大的异常,不知道跟下面这个是否有关系,好像早先折腾过UI界面的桌面环境,不知道是不是当时下载了非标的安装包带入的:

image

不管了,这个也一并卸载了。

最后网络终于恢复宁静了。总结一下,就是syn flood包把光猫或者路由器的带宽和连接资源耗尽,然后NAS自己的网络也占满,最终导致终端上网异常。我是在NAS上面部署了dnsmasq作为局域网的解析,因此有时候还表现为终端能用聊天软件,而不能打开网页。

其实中途,一度怀疑新买的Wifi6路由器不稳定,考虑弄一个二手的企业路由器拨号看看,找到了tplink r473g,还打开了调试模式,登录到路由器的shell里面,尝试用top+nc,把实时的top命令结果传出来,最终也确实有所发现,就是当网络异常时,路由器的CPU是满的,然后CPU用在soft irq上面,就是在不停的响应网络中断,看到这里也没什么头绪。当时就想在路由器上面抓包,但是busybox系统没有默认带这个,也没有curl等命令能把抓包数据传出去,难度有点大,就先放弃了,直到这周五发现HomeNAS经常有流量尖峰,才朝着HomeNAS上面去定位流量异常的这个方向走。最早是考虑局域网内的终端访问NAS带来的,逐个排查是哪个终端导致的,甚至二分法逐一关闭容器,都无果。最终还是抓包+系统日志找到了问题。HomeNAS上面,一般是用docker,很少安装不明二进制包,偶尔安装不明的来源的docker镜像。docker里面搞破坏应该很少能破坏宿主机。目前看来,这个病毒做得还不算绝,没有动系统文件,估计也怕jc抓。计算机世界的病毒跟自然界一样,都是希望跟宿主和谐共处,薅一点资源生存。以前只听说黑客利用系统漏洞,做一些攻击,也一直认为Linux很安全,没什么病毒。第一次经历Linux系统被植入病毒木马,上了重要的一课。

附:一些定位过程中的命令
接收远端日志:(nc -l 12599 -k >> router_log.txt &)
路由器跟踪top:(top –n 1 –d 3 |nc –v 22.22.22.3 12599 &),具体的循环任务忘记了,路由器的top没有打印时间,需要定时增加时间信息输出。
持续抓包:(tcpdump -i eno1  ‘not port 6870 and not port 22 and not port 443’ -s 96 -w all.cap -C 300 &)
iftop持续跟踪系统连接:(while :; do echo `date`>>iftop_all.txt; iftop -t -BNPn -s 10 -o 10s -i eno1 2>/dev/null >> iftop_all.txt; done &)
使用ntopng监控系统网络事件,使用iftop命令监控,跟Prometheus+Grafana的结果差不多,仅仅多了基于连接的统计结果。但是这种半连接过程的数据没有统计。

🔲 ⭐

jAlbum升级JDK、Jetty和支持HTTP2

利用这个周六休息时间,将jAlbum代码升级了下。主要是想支持HTTP2,提升浏览器加载性能。升级过程中遇到一些问题,记录下:

1、alpn库的问题,jetty在配套不同的jdk版本时,有一些策略:见官网链接的说明:Jetty 9 and ALPN,jdk8使用一个单独的包,jdk9及以后的版本使用使用alpn的api,需要另外一个包。在不同的jdk环境下,依赖包有差异,不能混淆。

2、jar-with-dependencies 和 META-INF/services 冲突的问题。大概是jetty-http和jetty-http2包内都实现了同一个接口,而jvm只加载到了其中一个:
org.eclipse.jetty.http.Http1FieldPreEncoder
org.eclipse.jetty.http2.hpack.HpackFieldPreEncode
两个类都实现了同一个接口,使用了META-INF/servcies目录的机制。由于之前打包时,使用了将所有依赖包都抽取到一个独立jar包的做法,导致这个servcies目录下的同名文件只保留一个,最终http2的类无法加载成功。改用依赖包放在单独目录的方式,解决问题。

3、升级jdk到11之后,有几个原本是jdk自带的工具包(jaxb和anonations)被新版本jdk删除了,只能一一重新在pom.xml中添加回来。

本来支持http2是个比较简单的事情,由于这些库之间的互相依赖,折腾了比较久。具体修改:Commit记录。也编译了0.3.2版本放在版本下载表中。升级改造之后jAlbum、本站以及相关的子站点都全面支持HTTP2。

❌