FooHoro.log #20230109 - 服务器搬家记
但是因为 Hetzner 禁止在自家服务器上运行 PoW 或者 PoS 的区块链应用(之前 Solana 不就是被 Hetzner 掐了好多节点嘛),所以咱的验证人节点还在 Linode 上就是。
2022 年 12 月某天, #archlinux-cn 的 Nick Cao 在群里问有没有人要接手他搬完的 Hetzner AX41 服务器(Transfer 可以省下一笔初装费),然后咱就鬼使神差的接了。
但是 Transfer 完没几天咱就被 COVID-19 袭击了 🤧,所以开始的几天一直没有动手,直到 2022 年都快过完了才开工。 😂
装 Proxmox VE
既然 AX41 算作独立服务器,配置比咱之前那个 VPS 大了好几倍,那么很自然的就想在上面分出 N 个虚拟机上去。于是也很自然的想在上面装 Proxmox VE 了。
虽然 Hetzner 没直接提供 PVE 的映像,但是可以先从 Hetzner 的恢复系统启动,装上 Debian ,然后在 Debian 上装 PVE。
然后问题来了,这台服务器上只有一个 IPv4 地址。(随着 IPv4 地址吃紧,追加 IPv4 地址的价钱也越来越贵了,对了还有初装费)于是就得像家里的路由器那样设置一下 NAT 了。
所以 /etc/network/interface
大概像这个样子:(咱好怀念 systemd-networkd 啊……)
# network interface settings; autogenerated # Please do NOT modify this file directly, unless you know what # you're doing. # # If you want to manage parts of the network configuration manually, # please utilize the 'source' or 'source-directory' directives to do # so. # PVE will preserve these directives, but will NOT read its network # configuration from sourced files, so do not attempt to move any of # the PVE managed interfaces into external files! source /etc/network/interfaces.d/* auto lo iface lo inet loopback iface lo inet6 loopback auto enp41s0 iface enp41s0 inet static # 汝自己的 IP 地址和网关可以在 Hetzner Robot 上找到。 address 1.2.3.4/32 gateway 1.2.3.1 up ip -6 route add default via fe80::1 dev enp41s0 auto vmbr0 iface vmbr0 inet static # 划分一个 NAT 用的子网,IP 地址随便选一个内网网段就行。 address 100.64.20.1/24 bridge-ports none bridge-stp off bridge-fd 0 #vm-lan iface vmbr0 inet6 static # 选一个在汝服务器 IPv6 网段里的 IP 地址 address aaaa::bbbb:2/64
接下来,为了实现 NAT ,还要设置 sysctl 和 iptables 规则。
在 /etc/sysctl.d/
目录新建一个配置文件 (例如 99-sysctl.conf
),然后加上这些属性:
# Uncomment the next line to enable packet forwarding for IPv4 net.ipv4.ip_forward=1 # Uncomment the next line to enable packet forwarding for IPv6 # Enabling this option disables Stateless Address Autoconfiguration # based on Router Advertisements for this host net.ipv6.conf.all.forwarding=1 net.ipv6.conf.all.accept_dad = 1 net.ipv6.conf.all.accept_redirects = 1
编辑完成以后可以通过 sysctl --system 命令让修改的配置生效。
而 iptables 规则是这样的 ( /etc/iptables/rules.v4 ):
Generated by iptables-save v1.8.7 on Wed Dec 28 09:56:00 2022 *filter :INPUT ACCEPT [202:24737] :FORWARD ACCEPT [577:308898] :OUTPUT ACCEPT [158:39503] COMMIT # Completed on Wed Dec 28 09:56:00 2022 # Generated by iptables-save v1.8.7 on Wed Dec 28 09:56:00 2022 *raw :PREROUTING ACCEPT [17292813:4458168798] :OUTPUT ACCEPT [62389:14737957] COMMIT # Completed on Wed Dec 28 09:56:00 2022 # Generated by iptables-save v1.8.7 on Wed Dec 28 09:56:00 2022 *nat :PREROUTING ACCEPT [135462:79719080] :INPUT ACCEPT [6851:699941] :OUTPUT ACCEPT [365:22212] :POSTROUTING ACCEPT [378:22968] # 这一条是 NAT 规则,--to-source 后面是汝主机的 IP 地址。 -A POSTROUTING -s 100.64.20.0/24 -o enp41s0 -j SNAT --to-source 1.2.3.4 # 下面两对是端口转发规则,咱这里是把 80 和 443 端口转发到某台虚拟机上了。 # 其它端口可以如法炮制。 -A PREROUTING -i enp41s0 -p tcp -m tcp --dport 80 -j DNAT --to-destination 100.64.20.177 -A POSTROUTING -d 100.64.20.177/32 -o vmbr0 -p tcp -m tcp --dport 80 -j SNAT --to-source 100.64.20.1 -A PREROUTING -i enp41s0 -p tcp -m tcp --dport 443 -j DNAT --to-destination 100.64.20.177 -A POSTROUTING -d 100.64.20.177/32 -o vmbr0 -p tcp -m tcp --dport 443 -j SNAT --to-source 100.64.20.1 COMMIT # Completed on Wed Dec 28 09:56:00 2022 # Generated by iptables-save v1.8.7 on Wed Dec 28 09:56:00 2022 *mangle :PREROUTING ACCEPT [17292814:4458168855] :INPUT ACCEPT [69630:13071644] :FORWARD ACCEPT [17220248:4442770384] :OUTPUT ACCEPT [62389:14737957] :POSTROUTING ACCEPT [17282637:4457508341] -A FORWARD -o enp41s0 -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1460 COMMIT # Completed on Wed Dec 28 09:56:00 2022
然后就是创建一台虚拟机,启动 ArchISO ,分好硬盘,用 rsync 把原来服务器上的系统迁移过来。最后重新配置一下 Bootloader 和网络。
因为咱之前用的是 systemd-networkd ,所以只要修改一些设定就可以了。
[Match] Name=ens18 [Network] # 从汝的子网中挑一个 IPv4 和 IPv6 地址,网关是汝的主机。 Address=100.64.20.177/24 Gateway=100.64.20.1 DNS=1.1.1.1 # 为了不至于因为 MAC 地址不一样而吃到 Hetzner 的警告, # IPv6 地址也是需要网关的。 Address=aaaa:bbbb::100/64 Gateway=aaaa:bbbb::2
以及如果是和 Debian 一样用 interfaces 的系统(像是 Ubuntu 或者 Alpine 之类的),那虚拟机的 /etc/network/interfaces 可以这么写:
auto lo iface lo inet loopback auto eth0 iface eth0 inet static address 100.64.20.48 netmask 255.255.255.0 gateway 100.64.20.1 iface eth0 inet6 static address aaaa::bbbb:48/64 gateway aaaa::bbbb:2
但是后来还是吃了警告……
(可选)和 Hetzner 客服拉锯(误)
旧服务器的系统复制过来没几个小时, Hetzner 就发邮件来抱怨说咱的服务器在扫描网络,疑似被攻击了。但是邮件里的日志记录的目标都是像 192.168.* 或者 172.16.* 之类的私有地址,再一看出口端口,4001。哦,原来是 IPFS Daemon 不知道在干啥。去 GitHub 翻了翻,发现有人遇到过类似的问题。(例如 https://github.com/ipfs/kubo/issues/4343)
上面的 issue 里有提到几种方法,像是让 Swarm.AddrFilters 忽略那些 IP 地址,或者把 IPFS 设置成服务器模式(ipfs config profile apply server)之类的。但是咱设置完一圈下来发现不太管用,于是 Hetzner 的建议是用防火墙规则屏蔽。那咱就顺便把 Proxmox 的防火墙用起来了。
于是 /etc/pve/firewall/cluster.fw 大概是这个样子:(可以参考 Proxmox 关于防火墙的文档: https://pve.proxmox.com/wiki/Firewall)
当然除了解决扫描端口的问题以外还有别的规则。
[OPTIONS] enable: 1 [RULES] # 接受来自内网的入站和出站连接 IN ACCEPT -source 100.64.20.0/24 -log nolog OUT ACCEPT -dest 100.64.20.0/24 -log nolog # 为了修扫描端口的问题拒绝特定目标的出站链接 #(PVE 默认是允许所有出站连接来着) OUT REJECT -dest 192.168.0.0/16 -log nolog OUT REJECT -dest 172.16.0.0/12 -log nolog OUT REJECT -dest 10.0.0.0/8 -log nolog # 接受特定服务的入站连接 IN SPICEproxy(ACCEPT) -log nolog IN Web(ACCEPT) -log nolog IN SSH(ACCEPT) -log nolog IN Ping(ACCEPT) -log nolog # ICMP
把 Docker 容器搬到 Alpine 虚拟机里
(纯粹是偷懒不想把原来 Docker 里的服务从虚拟机里搬出来) 用 Alpine 大概是因为它足够轻?
简单来说的话:
- 新建一个虚拟机。
- 从 Alpine Linux 的网络安装 ISO 启动,然后安装到硬盘。(alpine-setup)
- 编辑 /etc/apk/repositories , 启用 community 仓库。
- 安装需要的软件包。(例如 nano , qemu-guest-agent 和 docker)
- 修改 /etc/conf.d/qemu-guest-agent ,把 GA_PATH 修改到 Proxmox 提供的路径,大概是 /dev/vport1p1 这样的。
playback:~$ cat /etc/conf.d/qemu-guest-agent # Specifies the transport method used to communicate to QEMU on the host side # Default: virtio-serial #GA_METHOD="virtio-serial" # Specifies the device path for the communications back to QEMU on the host # Default: /dev/virtio-ports/org.qemu.guest_agent.0 GA_PATH="/dev/vport1p1"
- 把在 alpine-setup 建立的用户加入到 docker 用户组里,这样就能以那个用户运行 docker 命令了。
- 用 OpenRC 设置 docker 和 qemu-guest-agent 开机启动。
rc-update add docker boot rc-update add qemu-guest-agent boot
- 重启虚拟机,从旧系统上把对应容器的目录复制到新虚拟机里。
- 按照各自服务的 readme 设置和启动。
- 修改 Nginx 配置文件,把反向代理的目标指向新的虚拟机。
反向代理 PVE 管理界面
可以少打开一个端口,以及可以申请和域名匹配的证书拜托不受信任的证书的提示。
如果汝的 Nginx 安装在 PVE 的主机上的话,可以参考 PVE 的文档 : https://pve.proxmox.com/wiki/Web_Interface_Via_Nginx_Proxy 。但是咱这次是用另一台虚拟机里的 Nginx,所以需要改变一下配置文件。
upstream proxmox { # 汝的虚拟机的网关地址(就是主机的内网 IP 地址啦。) server "100.64.20.1"; } server { listen 80 default_server; rewrite ^(.*) https://$host$1 permanent; } server { listen 443 ssl http2; listen [::]:443 ssl http2; ssl_certificate /path/to/your/certificate.pem; ssl_certificate_key /path/to/your/key.pem; add_header Referrer-Policy "same-origin"; server_name your.domain.tld; proxy_redirect off; location / { proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_pass http://proxmox:8006; proxy_buffering off; client_max_body_size 0; proxy_connect_timeout 3600s; proxy_read_timeout 3600s; proxy_send_timeout 3600s; send_timeout 3600s; } }
然后汝就可以通过 https://your.domain.tld 来访问汝的 PVE 管理面板了。
如果汝没用防火墙关闭 pveproxy 默认的 8006 端口的话,也可以修改 pveproxy 的配置文件 (/etc/default/pveproxy) 来关闭。
# 只允许来自特定 IP 地址(这里是本机和内网)的连接。 POLICY="allow" ALLOW_FROM="127.0.0.1,100.64.20.0/24" # 指定 pveproxy 的监听地址。 LISTEN_IP="100.64.20.1"
然后重新启动 pveproxy 服务即可。
于是新服务器就这样将就跑起来了,之前还想过把原来放在一起的其他服务也分开的,但是当下懒了,日后有时间再做吧。
对了,除了在 Matters 拍手和支持以外,汝也可以通过收集这篇文章的 Writing NFT 来支持咱喔。
喜欢我的作品吗?别忘了给予支持与赞赏,让我知道在创作的路上有你陪伴,一起延续这份热忱!
- 来自作者
- 相关推荐