Nicksxs's Blog

What hurts more, the pain of hard work or the pain of regret?

我们日常开发包括我自用的小工具也在用git管理
在使用git的过程中经常有个场景是我在A分支上开发了一部分,临时需要切换到B分支,又不想先把这部分代码提交,因为还没开发完,
这是用git stash命令就能很好的解决这个问题,但是这里在使用git stash的时候我认为有两个阶段
第一阶段就是简单使用



比如我有这个进行中的变更,在有未提交的代码的时候可以先用

1
git add 1.txt

添加到暂存区,但不提交,然后使用

1
git stash

保存工作进度,git stash之后再用 git status 就看不到刚才的更改了

然后就是弹出刚才stash的变更了
可以使用 git stash pop 就可以把刚才藏起来的临时变更就弹出来了

这里其实在真正使用时我们如果是深度使用就可能会出现四个问题或者是诉求

问题一

我不止stash了一次变更,怎么找到stash的多少次呢,因为直接用 pop 就是把栈顶的那次隐藏的变更弹出来了
这个问题就可以通过 git stash list 来解决

问题二

如果使用的pop我们这个stash相当于栈顶弹出,已经pop出来的就没有了,如果我只是想看一下改了哪些,当然我们可以先pop出来,在stash回去,
但更好的办法就是用git stash apply,这样是不会清栈的

问题三

如何指定弹出,比如我在list里能看到多次stash,那么我想弹出其中某一次
可以用
git stash pop stash@{1} 注意这个 stash@{1} 是指stash list 的第二个,因为是从0开始的
弹出倒数第二次stash

问题四

我想知道我这个stash里内容是啥,在不用pop和apply的情况下有没有办法
也是有的
可以使用 git stash show 1 或者 git stash show stash@{1} 来查看这次变更了哪些文件
甚至我们可以用 git stash show 1 -p 来查看具体变更的内容

之前在使用headscale的自建derper中转的时候,因为使用了acme管理的证书,虽然acme会自动续期,但是由于证书要做转换,没办法很方便的自动更新derper中映射的证书,因为最近在尝试迁移服务器,就在寻找是否有新的方法,正好就结合前面使用的caddy,只需要做好域名解析,caddy 就会自动加上https,那么在docker层面就可以不用额外增加证书啥的,各干各的事
docker还是一样的方式,差别就在于不用映射证书目录了

1
docker run --restart always   --name derper -p 12345:12345 -p 3478:3478/udp -v /run/tailscale/tailscaled.sock:/var/run/tailscale/tailscaled.sock  -e DERP_ADDR=:12345   -e DERP_DOMAIN=derper.domain.com   -e DERP_VERIFY_CLIENTS=true   -d dockerproxy.cn/yangchuansheng/derper:latest

derper.domain.com 需要换成自己的域名,端口也可以自己按需,只是还要注意下 /run/tailscale/tailscaled.sock 这个映射是为了让derper能够识别到这是同一个headscale下的客户端链接,防止被滥用,

1
curl -fsSL https://tailscale.com/install.sh | sh

本机通过这个安装下,然后再登录headscale

1
tailscale up --login-server=http://headscaleip:headscaleport --accept-routes=true --accept-dns=false

然后找到进程对应的sock文件,把它映射进去
接下去就是做反向代理,第一步先把域名解析做好,不然caddy没法做证书的,感觉caddy真的是懒人福音

1
2
3
4
derper.domain.com {
# 反向代理的地址
reverse_proxy 127.0.0.1:12345
}

就这几行,是不是超方便,这样就省去了隔段时间要去转换下证书,重启derper的麻烦了,虽然也可以自动化,但是作为一个shell不那么熟练的,又怕权限控制不好,重要目录被删掉的,还是这样比较省力

docker镜像拉取目前是个大问题,前阵子出现了比较大规模的封禁,导致很多原有的方案无法使用,其中包括阿里云的私有镜像地址,导致我折腾了半天
本来是可以在 https://cr.console.aliyun.com/cn-beijing/instances/mirrors 上打开,阿里云用户都有各自的私有地址

1
https://xxxxxxxx.mirror.aliyuncs.com

然后可以通过这个方式修改

1
2
3
4
5
6
7
8
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://xxxxxxxx.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

这样修改以后查看下日志

1
journalctl -xe --no-pager -u docker

但还是拉不下来,后来发现还是拉不下来
应该也是之前被封的原因,
后面重要找到了一个
配置使用这个就可以了

1
2
3
4
5
{
"registry-mirrors": [
"https://dockerproxy.cn"
]
}

或者拉取镜像的前缀加上这个地址
docker pull dockerproxy.cn/yangchuansheng/derper:latest
也可以这么拉取,说实话docker镜像现在真的很必要,据说这次是因为传了某些敏感的AI语音
参考下面的图

首先是安装Caddy,

1
2
3
4
5
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install caddy

安装完成就会自动启动Caddy,
这时我们就可以来实践反向代理,并且自带https,

1
caddy reverse-proxy --from :2080 --to :9000

这样就可以构建一个2080到9000的反向代理
如果需要做域名的反向代理
可以这样

1
caddy reverse-proxy --from example.com --to :9000

可以在本地开启一个9000端口的http服务

1
php -S localhost:9000

然后请求本地

1
curl -v https://localhost

就能看到响应

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
*   Trying 127.0.0.1:443...
* Connected to localhost (127.0.0.1) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* CAfile: /etc/ssl/certs/ca-certificates.crt
* CApath: /etc/ssl/certs
* TLSv1.0 (OUT), TLS header, Certificate Status (22):
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS header, Certificate Status (22):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS header, Finished (20):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.2 (OUT), TLS header, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_128_GCM_SHA256
* ALPN, server accepted to use h2
* Server certificate:
* subject: [NONE]
* start date: Oct 6 12:54:37 2024 GMT
* expire date: Oct 7 00:54:37 2024 GMT
* subjectAltName: host "localhost" matched cert's "localhost"
* issuer: CN=Caddy Local Authority - ECC Intermediate
* SSL certificate verify ok.
* Using HTTP2, server supports multiplexing
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* Using Stream ID: 1 (easy handle 0x55b8f32f5eb0)
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
> GET / HTTP/2
> Host: localhost
> user-agent: curl/7.81.0
> accept: */*
>
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* Connection state changed (MAX_CONCURRENT_STREAMS == 250)!
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
< HTTP/2 404
< alt-svc: h3=":443"; ma=2592000
< content-type: text/html; charset=UTF-8
< date: Sun, 06 Oct 2024 13:37:43 GMT
< host: localhost
< server: Caddy
< content-length: 533
<
* TLSv1.2 (IN), TLS header, Supplemental data (23):
<!doctype html><html><head><title>404 Not Found</title><style>
body { background-color: #fcfcfc; color: #333333; margin: 0; padding:0; }
h1 { font-size: 1.5em; font-weight: normal; background-color: #9999cc; min-height:2em; line-height:2em; border-bottom: 1px inset black; margin: 0; }
h1, p { padding-left: 10px; }
code.url { background-color: #eeeeee; font-family:monospace; padding:0 2px;}
</style>
* Connection #0 to host localhost left intact
</head><body><h1>Not Found</h1><p>The requested resource <code class="url">/</code> was not found on this server.</p></body></html>

然后在php侧服务器就能看到

1
2
3
4
[Sun Oct  6 21:34:29 2024] PHP 8.1.2-1ubuntu2.19 Development Server (http://localhost:9000) started
[Sun Oct 6 21:37:43 2024] 127.0.0.1:38708 Accepted
[Sun Oct 6 21:37:43 2024] 127.0.0.1:38708 [404]: GET / - No such file or directory
[Sun Oct 6 21:37:43 2024] 127.0.0.1:38708 Closing

还能用配置的形式

1
2
3
4
5

demo.domain.com {
# 反向代理的地址
reverse_proxy 127.0.0.1:xxxx
}

再运行caddy reload就能启动,还是很方便的

目前我在家里用的路由器是个装了ImmortalWrt的NX30 Pro路由器,由于内存只有256兆,默认没带网速统计和限制网速的插件,对于网络速度限制就有点困难,刚好这次网上找到了一个可以用iptables统计网速的脚本,简单记录下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

#!/bin/sh
echo "Collecting data..."
echo ""
cat /proc/net/arp | grep : | grep ^192 | grep -v 00:00:00:00:00:00| awk '{print $1}'> mac-arp
iptables -N UPLOAD
iptables -N DOWNLOAD
while read line;do iptables -I FORWARD 1 -s $line -j UPLOAD;done < mac-arp
while read line;do iptables -I FORWARD 1 -d $line -j DOWNLOAD;done < mac-arp
sleep 1
echo "Download speed:"
echo ""
iptables -nvx -L FORWARD | grep DOWNLOAD | awk '{print $2/1024/1" KB/s ",$1/10" packets/s", $9}' | sort -n -r
echo ""
echo "Upload speed:"
echo ""
iptables -nvx -L FORWARD | grep UPLOAD | awk '{print $2/1024/1" KB/s ",$1/10" packets/s", $8}' | sort -n -r
while read line;do iptables -D FORWARD -s $line -j UPLOAD;done < mac-arp
while read line;do iptables -D FORWARD -d $line -j DOWNLOAD;done < mac-arp
iptables -X UPLOAD
iptables -X DOWNLOAD

首先是通过arp记录内网ip地址,然后添加UPLOADDOWNLOAD链,
然后为mac-arp文件中每个ip地址添加FORWARD规则,将流量导到UPLOADDOWNLOAD
等待1秒,统计下载和上传速度,计算KB/s,packets/s,再清理规则
然后对于上传占用高的,我们可以用

1
2
iptables -t mangle -I FORWARD 1 -s 192.168.x.x -m limit --limit 800/s --limit-burst 1000 -j ACCEPT
iptables -t mangle -I FORWARD 2 -s 192.168.x.x -j DROP

限制通过包的数量为800,不过这个不绝对精确

0%