更新系统
sudo apt updatesudo apt full-upgrade配置防火墙
# 关闭防火墙sudo ufw disable
# 设置默认规则sudo ufw default deny incomingsudo ufw default allow outgoing
# 允许 22、80、443 端口访问sudo ufw allow 22/tcpsudo ufw allow 80/tcpsudo ufw allow 443/tcp
# 开启防火墙sudo ufw enable安装 fail2ban
安装:
sudo apt install fail2ban删除自带配置:
sudo rm /etc/fail2ban/jail.d/defaults-debian.conf添加默认封禁配置:
sudo tee /etc/fail2ban/jail.d/01-defaults.conf <<EOF[DEFAULT]bantime = 12hfindtime = 30mmaxretry = 3
ignoreip = 127.0.0.1/8 ::1/128 172.16.95.102/20
banaction = ufwbanaction_allports = ufwEOF添加 sshd 封禁配置:
sudo tee /etc/fail2ban/jail.d/10-sshd.conf <<EOF[sshd]enabled = trueport = 22filter = sshdbackend = systemdfindtime = 5mmaxretry = 3bantime = 1h
[sshd-slow]enabled = trueport = 22filter = sshdbackend = systemdfindtime = 6hmaxretry = 5bantime = 24hEOF添加“累犯”封禁配置:
sudo tee /etc/fail2ban/jail.d/99-recidive.conf <<EOF[recidive]enabled = truefilter = recidivelogpath = /var/log/fail2ban.logfindtime = 1wmaxretry = 3bantime = -1EOF检查:
sudo fail2ban-client -tsudo fail2ban-client -d启动:
sudo systemctl enable --now fail2ban加固 SSH
配置:
sudo tee /etc/ssh/sshd_config.d/99-hardening.conf <<EOF# 禁用 root 登录PermitRootLogin no
# 禁用密码认证,仅允许密钥PasswordAuthentication noPubkeyAuthentication yes
# 限制算法KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.orgCiphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.comMACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com
# 限制尝试次数MaxAuthTries 3MaxSessions 5ClientAliveInterval 300ClientAliveCountMax 3
# 仅允许特定用户AllowUsers ecs-userEOF检查:
sudo sshd -t && echo "Syntax OK"重载 sshd 配置:
sudo systemctl reload sshd安装 Podman
修改系统配置:
echo "net.ipv4.ip_unprivileged_port_start=80" | sudo tee /etc/sysctl.d/99-unprivileged-ports.confsudo sysctl --system配置 Linger:
sudo loginctl enable-linger $USER安装 podman:
sudo apt install podman配置镜像加速器:
sudo tee /etc/containers/registries.conf <<EOFunqualified-search-registries = ["docker.io"]
[[registry]]prefix = "docker.io"location = "docker.io"blocked = falseinsecure = false
[[registry.mirror]]location = "xxx.mirror.aliyuncs.com"EOF检查用户权限:
grep ecs-user /etc/subuid /etc/subgid
# 预期输出:# /etc/subuid:ecs-user:100000:65536# /etc/subgid:ecs-user:100000:65536## 配置命令:# sudo usermod --add-subuids 100000-165535 ecs-user# sudo usermod --add-subgids 100000-165535 ecs-user安装 Nginx
拉取镜像:
podman pull docker.io/library/nginx:alpine准备目录:
mkdir -p ~/nginx-gateway/logscd ~/nginx-gateway生成 nginx.conf 配置文件:
tee ~/nginx-gateway/nginx.conf <<EOFuser nginx;worker_processes auto; # 自动识别worker_cpu_affinity auto; # 绑定 CPU 核心worker_rlimit_nofile 65535; # 单个 worker 最大文件描述符
pid /var/run/nginx.pid;error_log /var/log/nginx/error.log warn;
events { use epoll; # Linux 最高效事件模型 multi_accept on; # 一次性接受所有新连接 worker_connections 2048; # 单 worker 2048 连接}
http { # 基础设置 include /etc/nginx/mime.types; default_type application/octet-stream;
# 日志格式 log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"' # 设置访问日志 access_log /var/log/nginx/access.log main buffer=32k flush=5s;
# 网络传输优化 sendfile on; # 零拷贝发送静态文件 tcp_nopush on; # 累积数据包再发送 tcp_nodelay on; # 小数据包立即发送
# 连接超时管理 keepalive_timeout 60; # 连接复用 60 秒 keepalive_requests 10000; # 单连接最大请求数 client_header_timeout 10; # 读取请求头超时 client_body_timeout 10; # 读取请求体超时 send_timeout 10; # 发送响应超时 reset_timedout_connection on; # 超时后主动关闭连接
# 客户端缓冲区限制 client_header_buffer_size 4k; large_client_header_buffers 4 8k; client_body_buffer_size 128k; client_max_body_size 50m; # 按需调整上传限制
# 代理缓冲区 proxy_buffering on; proxy_buffer_size 4k; proxy_buffers 8 4k; proxy_busy_buffers_size 8k; proxy_temp_file_write_size 64k;
# 静态文件缓存 open_file_cache max=2000 inactive=180s; open_file_cache_min_uses 2; open_file_cache_valid 300s; open_file_cache_errors off;
# Gzip 压缩 gzip on; gzip_vary on; gzip_proxied any; gzip_buffers 4 16k; gzip_min_length 1024; gzip_comp_level 6; gzip_types text/plain text/css application/javascript application/json text/xml application/xml image/svg+xml;
# 隐藏版本号 server_tokens off;
server { listen 80 default_server; listen [::]:80 default_server; server_name _;
return 444; # 直接关闭连接 }
# 引入站点配置 include /etc/nginx/conf.d/*.conf;}EOF运行容器:
podman run -d --replace \ --name nginx-gateway \ --security-opt=no-new-privileges:true \ --cap-drop=ALL \ --cap-add=CHOWN \ --cap-add=SETUID \ --cap-add=SETGID \ --cap-add=NET_BIND_SERVICE \ -p 80:80 -p 443:443 \ -v ~/nginx-gateway/logs:/var/log/nginx:Z \ -v ~/nginx-gateway/nginx.conf:/etc/nginx/nginx.conf:ro \ --tmpfs /tmp:noexec,nosuid,size=64m \ --tmpfs /var/tmp:noexec,nosuid,size=64m \ --tmpfs /var/run:noexec,nosuid,size=1m \ --tmpfs /var/cache/nginx:noexec,nosuid,size=128m \ --cpus=1.0 \ --cpu-shares=2048 \ --memory=512m \ --memory-swap=512m \ --pids-limit=100 \ --restart=always \ docker.io/library/nginx:alpine配置容器持久化:
tee ~/.config/containers/systemd/nginx-gateway.container <<EOF[Container]Image=docker.io/library/nginx:alpineContainerName=nginx-gatewayNoNewPrivileges=trueDropCapability=ALLAddCapability=CHOWNAddCapability=SETUIDAddCapability=SETGIDAddCapability=NET_BIND_SERVICEPublishPort=80:80PublishPort=443:443Volume=%h/nginx-gateway/logs:/var/log/nginx:ZVolume=%h/nginx-gateway/nginx.conf:/etc/nginx/nginx.conf:roTmpfs=/tmp:noexec,nosuid,size=64mTmpfs=/var/tmp:noexec,nosuid,size=64mTmpfs=/var/run:noexec,nosuid,size=1mTmpfs=/var/cache/nginx:noexec,nosuid,size=128mPodmanArgs=--cpus=1.0PodmanArgs=--cpu-shares=2048PodmanArgs=--memory=512mPodmanArgs=--memory-swap=512mPodmanArgs=--pids-limit=100
[Service]Restart=alwaysRestartSec=10ExecReload=podman kill -s HUP nginx-gateway
[Install]WantedBy=default.targetEOF重载 systemd 配置并启动 nginx-gateway.service 服务:
systemctl --user daemon-reloadsystemctl --user start nginx-gateway.service验证状态:
systemctl --user status nginx-gateway.servicepodman ps | grep nginx-gateway部署个人博客
使用 fnm 管理 node.js
安装依赖:
sudo apt install unzip安装 fnm:
curl -fsSL https://fnm.vercel.app/install | bash安装 node.js:
fnm install --lts安装 pnpm:
npm install -g pnpm构建项目
生成 SSH 密钥:
ssh-keygen -t ed25519 -C "deploy@github" -f ~/.ssh/github将公钥添加到 Github:
cat ~/.ssh/github.pub添加 Github 服务器的公钥指纹:
ssh-keyscan github.com >> ~/.ssh/known_hosts配置 SSH 客户端:
tee ~/.ssh/config <<EOFHost github HostName github.com User git IdentityFile ~/.ssh/github IdentitiesOnly yesEOF拉取项目文件:
git clone git@github:justyycrazy/my-notes.gitgit clone git@github:justyycrazy/my-vault.git将代码仓库和笔记仓库关联:
cd ~/nginx-gateway/my-notes
git switch -c buildrm -rf ~/nginx-gateway/my-notes/src/contentln -s ~/nginx-gateway/my-vault/src-content ~/nginx-gateway/my-notes/src/contentln -s ~/nginx-gateway/my-vault/src-assets-images/etl-workflow-design-with-kettle ~/nginx-gateway/my-notes/src/assets/images/cp -r ~/nginx-gateway/my-vault/public-uploads ~/nginx-gateway/my-notes/public/uploads安装依赖并构建项目:
pnpm installpnpm build获取 SSL 证书
安装 acme.sh 并立即生效:
curl https://get.acme.sh | bashsource ~/.bashrc设置默认证书服务器:
acme.sh --set-default-ca --server letsencrypt获取 SSL 证书:
export Ali_Key=""export Ali_Secret=""acme.sh --issue --dns dns_ali \ -d yycrazy.net \ -d *.yycrazy.net安装 SSL 证书:
mkdir -p ~/.local/share/certsacme.sh --install-cert -d *.yycrazy.net \ --key-file ~/.local/share/certs/yycrazy.net.key \ --fullchain-file ~/.local/share/certs/yycrazy.net.cer \ --reloadcmd "systemctl --user reload nginx-gateway.service"配置 Nginx 站点
tee ~/nginx-gateway/yycrazy.net.conf <<EOFserver { listen 80; server_name yycrazy.net www.yycrazy.net;
return 301 https://\$host\$request_uri;}
server { listen 443 ssl http2; server_name yycrazy.net www.yycrazy.net;
ssl_certificate /etc/nginx/ssl/yycrazy.net.cer; ssl_certificate_key /etc/nginx/ssl/yycrazy.net.key;
ssl_session_timeout 1d; ssl_session_cache shared:SSL:50m; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256; ssl_prefer_server_ciphers off;
root /usr/share/nginx/html; index index.html;
# 静态资源长期缓存 location ~* \.(css|js|ico|svg|png|webp|jpeg|jpg|gif)$ { expires 1y; add_header Cache-Control "public, immutable"; }
location ^~ /uploads/php5-examples/ { types { text/plain php; } charset utf-8; add_header Content-Disposition inline; add_header X-Content-Type-Options nosniff; }}EOF添加挂载点
修改 nginx-gateway 的配置文件:
tee ~/.config/containers/systemd/nginx-gateway.container <<EOF[Container]Image=docker.io/library/nginx:alpineContainerName=nginx-gatewayNoNewPrivileges=trueDropCapability=ALLAddCapability=CHOWNAddCapability=SETUIDAddCapability=SETGIDAddCapability=NET_BIND_SERVICEPublishPort=80:80PublishPort=443:443Volume=%h/nginx-gateway/logs:/var/log/nginx:ZVolume=%h/nginx-gateway/nginx.conf:/etc/nginx/nginx.conf:roVolume=%h/nginx-gateway/yycrazy.net.conf:/etc/nginx/conf.d/yycrazy.net.conf:roVolume=%h/nginx-gateway/my-notes/dist:/usr/share/nginx/html:roVolume=%h/.local/share/certs:/etc/nginx/ssl:roTmpfs=/tmp:noexec,nosuid,size=64mTmpfs=/var/tmp:noexec,nosuid,size=64mTmpfs=/var/run:noexec,nosuid,size=1mTmpfs=/var/cache/nginx:noexec,nosuid,size=128mPodmanArgs=--cpus=1.0PodmanArgs=--cpu-shares=2048PodmanArgs=--memory=512mPodmanArgs=--memory-swap=512mPodmanArgs=--pids-limit=100
[Service]Restart=alwaysRestartSec=10ExecReload=podman kill -s HUP nginx-gateway
[Install]WantedBy=default.targetEOF重载 systemd 配置并重启 nginx-gateway.service 服务:
systemctl --user daemon-reloadsystemctl --user restart nginx-gateway.service验证状态:
systemctl --user status nginx-gateway.servicepodman ps | grep nginx-gateway``