感谢meiyouqian学长笔记
要记得改 postgres 的密码不然容易被攻击来着(
基础环境搭建
cat /etc/os-releaseuname -auname -rdocker --version lsb_release -a systemctl list-units --type =service
which dockersystemctl status docker ps aux | grep docker
安装docker
sudo apt install -y \ vim \ git \ curl \ wget \ htop \ net-tools \ ufw \ nginx \ docker.io \ docker-compose
防火墙配置
sudo ufw allow 50071/tcp comment 'SSH' sudo ufw allow 80/tcp comment 'HTTP' sudo ufw allow 443/tcp comment 'HTTPS' sudo ufw allow 8080/tcp comment 'CTF' sudo ufw status numberedsudo ufw enable sudo ufw status verbose
Node.js 22+配置
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash - sudo apt install -y nodejsnode -v
Go 1.24+配置
wget https://go.dev/dl/go1.24.11.linux-amd64.tar.gz sudo rm -rf /usr/local/gosudo tar -C /usr/local -xzf go1.24.11.linux-amd64.tar.gzecho 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bashrcsource ~/.bashrcgo version
PostgreSQL 15+配置
sudo sed -i 's/http:\/\/cn.archive.ubuntu.com/https:\/\/mirrors.aliyun.com/g' /etc/apt/sources.listsudo sh -c 'echo "deb https://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list' wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add - sudo apt-get updatesudo apt-get -y install postgresql-15psql --version
Redis 7+配置
wget https://github.com/redis/redis/archive/7.2.5.tar.gz tar -xzvf 7.2.5.tar.gz cd redis-7.2.5sudo apt updatesudo apt install build-essentialmake
sudo apt updatesudo apt install -y pkg-config build-essential tcl libssl-devmake distclean make make test sudo make install sudo mkdir -p /etc/redis /var/lib/redissudo cp redis.conf /etc/redis/redis-server /etc/redis/redis.conf --daemonize yes sudo sysctl vm.overcommit_memory=1
单节点Kubernetes配置
https://zhuanlan.zhihu.com/p/1932852088334951626
环境准备
sudo systemctl disable ufwsudo swapoff -asudo sed -i '/swap/d' /etc/fstabcat /etc/fstabfree -h
内核参数配置
sudo tee /etc/sysctl.d/k8s.conf <<EOF net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 net.ipv4.ip_forward = 1 vm.swappiness = 0 EOF sudo modprobe br_netfiltersudo sysctl --system
安装依赖工具
sudo apt updatesudo apt install -y apt-transport-https ca-certificates curl
安装 Kubernetes 组件
sudo tee /etc/apt/sources.list.d/kubernetes.list <<EOF deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main EOF curl -s https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | sudo gpg --dearmor -o /etc/apt/trusted.gpg.d/kubernetes-aliyun.gpg sudo apt updatesudo apt install -y kubelet kubeadm kubectlsudo apt-mark hold kubelet kubeadm kubectl
初始化控制面板
sudo systemctl status cri-dockerd
wget https://github.com/Mirantis/cri-dockerd/releases/download/v0.3.4/cri-dockerd-0.3.4.amd64.tgz tar -xvf cri-dockerd-0.3.4.amd64.tgz sudo mv cri-dockerd/cri-dockerd /usr/local/bin/sudo chmod +x /usr/local/bin/cri-dockerdcri-dockerd --version sudo tee /etc/systemd/system/cri-docker.service > /dev/null <<EOF [Unit] Description=CRI Docker Daemon Documentation=https://github.com/Mirantis/cri-dockerd Requires=docker.service After=network.target docker.service [Service] ExecStart=/usr/local/bin/cri-dockerd --container-runtime-endpoint unix:///var/run/cri-dockerd.sock --docker-endpoint unix:///var/run/docker.sock Restart=always RestartSec=5 [Install] WantedBy=multi-user.target EOF sudo tee /etc/systemd/system/cri-docker.socket > /dev/null <<EOF [Unit] Description=CRI Docker Socket [Socket] ListenStream=/var/run/cri-dockerd.sock SocketMode=0660 SocketUser=root SocketGroup=docker [Install] WantedBy=sockets.target EOF sudo systemctl daemon-reloadsudo systemctl start cri-docker.servicesudo systemctl enable cri-docker.servicesudo systemctl status cri-docker.servicels -la /var/run/cri-dockerd.sock
sudo kubeadm init \ --image-repository registry.aliyuncs.com/google_containers \ --cri-socket unix:///var/run/cri-dockerd.sock export KUBECONFIG=/etc/kubernetes/admin.confkubectl get nodes
安装 Calico 网络插件
kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml kubectl get pods -n kube-system
移除污点
kubectl describe node | grep Taints kubectl taint nodes --all node-role.kubernetes.io/control-plane:NoSchedule- kubectl describe node | grep Taints
安装Dashboard
wget https://get.helm.sh/helm-v3.18.4-linux-amd64.tar.gz tar zxvf helm-v3.18.4-linux-amd64.tar.gz mv linux-amd64/helm /usr/local/bin/helm repo add kubernetes-dashboard https://kubernetes.github.io/dashboard/
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml kubectl get pods -n kubernetes-dashboard
访问Dashboard
注意这边我们是云服务器啊,不是本地的,不要搞本地的,要用公网IP进行端口转发
pkill -f "kubectl port-forward" kubectl -n kubernetes-dashboard patch svc kubernetes-dashboard -p '{"spec":{"type":"NodePort"}}' kubectl get svc -n kubernetes-dashboard kubectl apply -f - <<EOF apiVersion: v1 kind: ServiceAccount metadata: name: admin-user namespace: kubernetes-dashboard --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: admin-user roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-admin subjects: - kind: ServiceAccount name: admin-user namespace: kubernetes-dashboard EOF kubectl -n kubernetes-dashboard create token admin-user sudo ufw allow XXX/tcp
常用命令备忘录
pkill -f "kubectl port-forward" kubectl -n kubernetes-dashboard patch svc kubernetes-dashboard -p '{"spec":{"type":"NodePort"}}' kubectl get svc -n kubernetes-dashboard kubectl -n kubernetes-dashboard create token admin-user kubectl get all --all-namespaces kubectl get componentstatuses kubectl get events --sort-by='.lastTimestamp' kubectl logs <pod-name> -n <namespace> kubectl exec -it <pod-name> -- sh
搭建A1CTF
wget https://github.com/carbofish/A1CTF/archive/refs/heads/main.zip apt install unzip unzip main.zip
配置环境
cp config.example.yaml config.yaml
启动Docker
git init git add . git commit -m "A1CTF Initial commit" docker-compose up -d
修改配置
docker-compose.yml
version: '3.8' services: app: build: . image: test-a1ctf:latest ports: - "0.0.0.0:7777:7777" - "0.0.0.0:5173:5173" - "0.0.0.0:8081:8081" environment: - GIN_MODE=release volumes: - ./appdata:/app/data - ./config.yaml:/app/config.yaml:ro - ./k8sconfig.yaml:/app/k8sconfig.yaml:ro depends_on: - postgres - redis restart: unless-stopped networks: - a1ctf-network postgres: image: postgres:17-alpine environment: POSTGRES_DB: a1ctf POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres POSTGRES_INITDB_ARGS: "--encoding=UTF8" volumes: - ./postgres_data:/var/lib/postgresql/data ports: - "0.0.0.0:5433:5432" restart: unless-stopped networks: - a1ctf-network healthcheck: test: ["CMD-SHELL" , "pg_isready -U postgres -d a1ctf" ] interval: 10s timeout: 5s retries: 10 start_period: 20s redis: image: redis:alpine ports: - "0.0.0.0:63790:6379" restart: unless-stopped networks: - a1ctf-network networks: a1ctf-network: driver: bridge
前人踩坑
sudo chown -R 1000:1000 appdatasudo chmod -R 755 appdata
报错:k8sconfig.yaml是一个目录而不是文件
sudo cp /etc/kubernetes/admin.conf ~/A1CTF-main/k8sconfig.yamlsudo chown $USER :$USER ~/A1CTF-main/k8sconfig.yaml
docker-compose up -d docker-compose restart app
root@hkwdjaION31UcV:~/A1CTF-main# rm -rf ~/A1CTF-main/k8sconfig.yaml root@hkwdjaION31UcV:~/A1CTF-main# ls -la ~/A1CTF-main/k8sconfig.yaml ls : cannot access '/root/A1CTF-main/k8sconfig.yaml' : No such file or directoryroot@hkwdjaION31UcV:~/A1CTF-main# sudo cp /etc/kubernetes/admin.conf ~/A1CTF-main/k8sconfig.yaml root@hkwdjaION31UcV:~/A1CTF-main# sudo chown $USER :$USER ~/A1CTF-main/k8sconfig.yaml root@hkwdjaION31UcV:~/A1CTF-main# ls -la ~/A1CTF-main/k8sconfig.yaml -rw------- 1 root root 5642 Feb 7 15:10 /root/A1CTF-main/k8sconfig.yaml root@hkwdjaION31UcV:~/A1CTF-main#
可能原因是本来就存在该目录,复制不会覆盖,所以要先删除
docker-compose build docker-compose up -d
docker logs --tail 50 a1ctf-main_app_1
权限问题,容器内的应用无法读取 k8sconfig.yaml 文件
chmod 644 ~/A1CTF-main/k8sconfig.yamlls -l k8sconfig.yamldocker-compose down docker-compose up -d --force-recreate docker-compose ps
无法连接
尝试修改配置,使用 Docker 网关地址
还是失败。。交给ai
自己踩坑
用户问题
首先,postgres用户是超级用户,比较不安全,如果要创建用户
使用 Docker 环境变量 (推荐,最简单)
在 docker-compose.yml 的 postgres 服务下直接定义环境变量。这是最标准的做法。
services: postgres: image: postgres:15-alpine environment: POSTGRES_USER: a1ctf POSTGRES_PASSWORD: postgres POSTGRES_DB: a1ctf
k8sconfig.yaml
推荐方案 :使用宿主机的局域网静态 IP。
apiVersion: v1 clusters: - cluster: server: https://10.0.124.2:6443
ip a ps aux | grep kube-apiserver
网络与防火墙设置
在启动容器前,必须确保 Docker 容器网段可以访问宿主机的 K8s API 端口 (默认6443)。
ps aux | grep kube-apiserver
docker network inspect a1ctf-main_a1ctf-network | grep Subnet iptables -I INPUT -s 172.18.0.0/16 -p tcp --dport 6443 -j ACCEPT
注意:此规则重启后可能会失效,建议写入持久化防火墙配置中。
美滋滋,ai还是把我养得太好了
配置域名
apt update apt install -y nginx curl ifconfig.me
nano /etc/nginx/sites-available/a1ctf.conf server { listen 80; server_name luoyinhui.xyz www.luoyinhui,xyz; location / { proxy_pass http://127.0.0.1:7777; proxy_http_version 1.1; proxy_set_header Host $host ; proxy_set_header X-Real-IP $remote_addr ; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for ; proxy_set_header X-Forwarded-Proto $scheme ; proxy_read_timeout 300; proxy_send_timeout 300; client_max_body_size 200m; } } ln -s /etc/nginx/sites-available/a1ctf.conf /etc/nginx/sites-enabled/a1ctf.confnginx -t systemctl reload nginx apt install -y certbot python3-certbot-nginx dig @223.5.5.5 luoyinhui.xyz A +short certbot --nginx -d luoyinhui.xyz -d www.luoyinhui.xyz
总结
数据库连接
postgres: image: postgres:17-alpine # ... ports: - "5433:5432" # 左边是外部端口(5433),右边是内部端口(5432)
存档配置文件
config.yml
Prometheus 监控端口 ( 8081 ) 仅监听在容器内部/本地回环接口,不再对外部网络(包括宿主机局域网)开放,避免危险
configVersion: v1 system: gin-port: 7777 gin-host: 0.0 .0 .0 prometheus-port: 8081 prometheus-host: 127.0 .0 .1 favicon: ./data/favicon.ico baseURL: http://localhost:5173 forwarded-by-client-ip: true remote-ip-headers: - X-Forwarded-For - X-Real-IP trusted-proxies: - 0.0 .0 .0 /0 pprof-enable: false redis: address: redis:6379 password: "postgres" db: 0 k8s: k8s-config-file: "k8sconfig.yaml" node-ip-map: - { name: "vm-4-3-ubuntu" , "address": "example.com/1.1.1.1" } manual-port-assignments: enabled: false port-range-map: pull-secret-names: custom-dns-server: enabled: false nameservers: - 8.8 .8 .8 postgres: host: postgres port: 5432 user: a1ctf password: "postgres" dbname: a1ctf sslmode: disable cache-time: user-list: 500ms upload-list: 500ms solved-challenges-for-game: 500ms game-info: 500ms all-teams-for-game: 500ms game-scoreboard: 500ms challenges-for-game: 1s challenge-detail: 500ms container-status: 100ms team-flag: 100ms team-solve-status: 100ms judge-result: 100ms redis-cache-time: user-list: 500ms upload-list: 500ms solved-challenges-for-game: 500ms game-info: 500ms all-teams-for-game: 500ms monitoring: enabled: true system-monitor-interval: 1s gorm-slow-query-threshold: 100ms job-intervals: update-activate-game-score: 500ms update-active-game-score-board: 5s flag-judge: 1s update-game-scoreboard-cache: 1s container-updating: 1s compress-and-delete-old-logs: 2h cap-settings: defaultChallengeTokenSize: 25 defaultChallengeCount: 80 defaultChallengeSize: 32 defaultChallengeDifficulty: 4 defaultChallengeExpires: 10m defaultTokenSize: 64 defaultTokenIdSize: 16 defaultTokenExpires: 20m defaultTokenVerifyOnce: true defaultHttpHandleLimitRPS: 10 defaultHttpHandleLimitBurst: 50 game-settings: container-cooldown-time: 60s
version: '3.8' services: app: build: . image: test-a1ctf:latest ports: - "7777:7777" - "5173:5173" - "8681:8681" environment: - GIN_MODE=release volumes: - ./appdata:/app/data - ./config.yaml:/app/config.yaml:ro - ./k8sconfig.yaml:/app/k8sconfig.yaml:ro depends_on: postgres: condition: service_healthy redis: condition: service_started restart: unless-stopped networks: - a1ctf-network postgres: image: postgres:17-alpine environment: POSTGRES_DB: a1ctf POSTGRES_USER: a1ctf POSTGRES_PASSWORD: postgres POSTGRES_INITDB_ARGS: "--encoding=UTF8" volumes: - ./postgres_data:/var/lib/postgresql/data ports: - "5433:5432" restart: unless-stopped networks: - a1ctf-network healthcheck: test: ["CMD-SHELL" , "pg_isready -U postgres -d a1ctf" ] interval: 10s timeout: 5s retries: 10 start_period: 20s redis: image: redis:alpine ports: - "63790:6379" restart: unless-stopped networks: - a1ctf-network networks: a1ctf-network: driver: bridge