网络 VPS 安全 Linux服务器新装系统,为了安全必做的事情 Longans 2026-05-15 2026-05-31 1.前言
前端时间主力服务器被黑客入侵,见本站文章主力服务器遭遇黑客入侵勒索 。
由此服务器网络安全引起本人极度重视。甚至PTSD
本文主要更新服务器安装后,需要做的一些事情,仅仅适用于debian 12系统。
2. 安装 2.1永久开启BBR拥堵算法。
BBR(Bottleneck Bandwidth and Round-trip propagation time)是由Google 于2016年发布的TCP拥塞控制 (不适用于UDP)算法。它通过持续测量网络路径的瓶颈带宽和往返延迟,动态优化数据传输速率,能显著提升网络吞吐量并大幅降低连接延迟。
1 2 3 grep -qxF "net.core.default_qdisc=fq" /etc/sysctl.conf || echo "net.core.default_qdisc=fq" | sudo tee -a /etc/sysctl.conf > /dev/null grep -qxF "net.ipv4.tcp_congestion_control=bbr" /etc/sysctl.conf || echo "net.ipv4.tcp_congestion_control=bbr" | sudo tee -a /etc/sysctl.conf > /dev/null sysctl -p
2.2安装必要依赖 1 2 3 4 5 apt update && apt upgrade -y apt install -y sudo vim wget curl jq unzip net-tools socat cron vnstat bsdextrautils lsof timedatectl set-timezone Asia/Singapore
2.3安装Docker和Docker Compose 1 2 3 4 wget -qO- get.docker.com | bash systemctl enable docker curl -L https://github.com/docker/compose/releases/latest/download/docker-compose-Linux-x86_64 > /usr/local/bin/docker-compose chmod +x /usr/local/bin/docker-compose
验证Docker和Docker Compose的安装
1 2 docker -v docker-compose --version
1 2 3 4 5 6 7 8 9 10 11 12 cat > /etc/docker/daemon.json <<EOF { "log-driver": "json-file", "log-opts": { "max-size": "20m", "max-file": "3" }, "experimental": true, "ipv6": false, "ip6tables": false } EOF
对于大陆的服务器,用下面这个限制docker日志写盘容量,同时配置了镜像加速。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 cat > /etc/docker/daemon.json <<EOF { "log-driver": "json-file", "log-opts": { "max-size": "20m", "max-file": "3" }, "ipv6": false, "experimental": true, "ip6tables": false, "registry-mirrors": [ "https://docker.m.daocloud.io", "https://mirror.ccs.tencentyun.com", "https://hub-mirror.c.163.com", "https://registry.docker-cn.com" ] } EOF
2.4关闭密码登录,仅启用密钥登录
密钥基于非对称加密 技术,几乎免疫针对密码的“暴力破解”攻击;而密码容易因泄露或被“撞库”而失窃。
密钥登录:本地生成一对密钥,即公钥(放在服务器)和私钥(保存在个人电脑)。登录时,服务器用公钥加密一段信息,只有匹配的私钥才能解密通过。
1 ssh-keygen -t ed25519 -C "your_email@example.com"
Windows提示下面内容,输入保存密钥对的路径。
1 Enter file in which to save the key (C:\Users\XXX/.ssh/id_ed25519):
输入路径后,Windows会提示输入一个密码,用于客户端解密私钥用。
1 2 Enter passphrase (empty for no passphrase): Enter same passphrase again:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 C:\Users\abc>ssh-keygen -t ed25519 -C "your_email@example.co Generating public/private ed25519 key pair. Enter file in which to save the key (C:\Users\abc/.ssh/id_ed25519): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in C:\Users\abc/.ssh/id_ed25519 Your public key has been saved in C:\Users\abc/.ssh/id_ed25519.pub The key fingerprint is: SHA256:4cgS0Iw6nJxnOfr7XUYCMDQ6snUeT+TAOPDKN650K8M your_email@example.co The key's randomart image is: +--[ED25519 256]--+ |..o@. . | | .=.B+ | |++=.=.o . | |=O.B *.o . | |oo+o+ +.S. | | .o .. o | |...o o | |.Eo.. . o | | .ooo. . | +----[SHA256]-----+ C:\Users\abc>
将公钥 public key上传到服务器/root/.ssh路径,公钥后缀一般是.pub,假如公钥名字是id_rsa.pub。
不要把私钥上传到服务器!不要把私钥上传到服务器!不要把私钥上传到服务器!
将公钥内容追加到授权文件(替换下面的公钥内容)
1 2 cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys
设置正确的权限,600表示只有root用户能改该文件,防止被程序乱加公钥进去。
1 2 3 chmod 700 /root/.sshchmod 600 /root/.ssh/authorized_keyschmod 600 /root/.ssh/id_rsa.pub
1 2 ls -ld /root /root/.sshls -l /root/.ssh
1 2 3 4 5 6 7 8 root@localhost:~# ls -ld /root /root/.ssh ls -l /root/.ssh drwx------ 3 root root 4096 May 31 16:33 /root drwx------ 2 root root 4096 May 31 16:36 /root/.ssh total 8 -rw------- 1 root root 105 May 31 16:36 authorized_keys -rw------- 1 root root 105 May 31 16:36 id_rsa.pub root@localhost:~#
1 2 3 4 5 6 7 8 9 10 11 12 13 14 r:允许查看目录内容(ls) w:允许创建、删除文件 x:允许进入目录和访问目录中的文件 Linux 中的 600、700、755 等都是权限的八进制表示法。 权限分为: 所有者(Owner) 组(Group) 其他人(Others) 6 = 4 + 2 = rw- 0 = --- 0 = --- 7 = 4 + 2 + 1 = rwx 0 = --- 0 = ---
1 nano /etc/ssh/sshd_config
找到配置文件里面的Include /etc/ssh/sshd_config.d/*.conf,将他注释掉。
Debian 12和Ubuntu 24.04都在/etc/ssh/sshd_config的顶部包含了Include /etc/ssh/sshd_config.d/.conf。OpenSSH对大多数指令使用它找到的第一个值。/etc/ssh/sshd_config.d/ .conf文件优先于主配置文件 中的设置。注释掉/etc/ssh/sshd_config.d/*.conf是为了防止他自己的自定义设置覆盖。
1 2 3 4 5 6 7 Port 6666 PermitRootLogin prohibit-password PubkeyAuthentication yes PermitEmptyPasswords no KbdInteractiveAuthentication no ChallengeResponseAuthentication no PasswordAuthentication no
修改完后在英文输入法下,按ctl+x,输入y回车进行保存并退出。
在修改完SSH后,一定新开一个窗口测试SSH连接成功后,再关SSH登录,防止把自己锁在外面。
重启SSH
妥善保存私钥,这是大门的”钥匙”。
服务器SSH只允许特定ip登录。
1 nano /etc/ssh/sshd_config
1 AllowUsers ubuntu@1.1.1.1 root@8.8.8.8
2.5禁止ping
禁PING的意思是:不允许电脑、设备或服务器使用PING功能。一般情况下电脑、防火墙、服务器都是允许PING功能的,不需要特别设置不禁止PING,但是远程的服务器(比如某个网站会禁止PING功能也是根据自己业务的属性来去选择) 服务器禁ping的好处与坏处。
好处:一定程度上在互联网上隐藏自己防止一些批量扫描软件探测主机,减少被入侵的几率。
坏处:无法使用常用的ping或者监控软件来检测站点是否正常或服务器是否在线。当别人PING用户的时候会耗费用户的连接资源。
永久 禁Ping:
1 net.ipv4.icmp_echo_ignore_all = 1
2.6安装fail2ban
fail2ban是一款入侵防御软件,启动后会通过检测系统行为日志识别暴力破解行为。对于在短时间内多次未能通过身份验证的请求,fail2ban会自动调用系统自带的防火墙或包管理框架(如iptables或tcp wrapper等)进行封禁。
查看SSH被爆破记录:(日志刷屏警告 )
1 2 3 4 5 6 sudo apt-get updateapt install fail2ban nftables systemctl enable fail2ban systemctl enable nftables systemctl status fail2ban systemctl status nftables
用任意文本编辑器打开 /etc/fail2ban/jail.local
1 cp /etc/fail2ban/jail.{conf,local }
1 vim /etc/fail2ban/jail.local
1 2 3 4 5 6 7 8 9 10 11 12 13 [INCLUDES] banaction = nftables-multiport [DEFAULT] [sshd] enabled = true port = 6902 filter = sshd logpath = /var/log/auth.log backend = systemd maxretry = 2 findtime = 60d bantime = -1 ignoreip = 1
1 2 sudo systemctl restart fail2bansudo systemctl status fail2ban
1 sudo fail2ban-client status sshd
1 sudo fail2ban-client set sshd unbanip 1.1.1.1
1 sudo fail2ban-client set sshd banip 66.42.99.107
添加服务依赖,重新启动nftables时, 确保也重新启动fail2ban服务, 以便其添加防火墙规则, 为此需要在两者之间添加服务依赖关系, 创建一个新文件/etc/systemd/system/fail2ban.service.d/override.conf并填入以下内容:
1 mkdir -p /etc/systemd/system/fail2ban.service.d
1 vim /etc/systemd/system/fail2ban.service.d/override.conf
1 2 3 4 5 6 [Unit] Requires=nftables.service PartOf=nftables.service [Install] WantedBy=multi-user.target nftables.service
1 2 3 4 systemctl daemon-reload systemctl restart fail2ban systemctl restart nftables systemctl restart docker
1 2 systemctl cat fail2ban nft list ruleset
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 root@localhost:~# systemctl cat fail2ban [Unit] Description=Fail2Ban Service Documentation=man:fail2ban(1) After=network.target iptables.service firewalld.service ip6tables.service ipset.service nftables.service PartOf=firewalld.service [Service] Type=simple Environment="PYTHONNOUSERSITE=1" ExecStart=/usr/bin/fail2ban-server -xf start ExecStop=/usr/bin/fail2ban-client stop ExecReload=/usr/bin/fail2ban-client reload RuntimeDirectory=fail2ban PIDFile=/run/fail2ban/fail2ban.pid Restart=on-failure RestartPreventExitStatus=0 255 Environment="PYTHONNOUSERSITE=yes" [Install] WantedBy=multi-user.target [Unit] Requires=nftables.service PartOf=nftables.service [Install] WantedBy=multi-user.target nftables.service root@localhost:~#
2.7安装防火墙,按需开启端口
参考这个文章如何在Linux VPS上使用UFW和nftables配置防火墙?
新开通的VPS没有任何防火墙规则。所有端口都是开放的。自动化扫描器会在你的服务器上线几分钟内发现它,然后开始探测SSH、测试默认凭据、寻找暴露的服务。默认拒绝防火墙是第一道防线。
对于Linux,防火墙主要有UFW和nftables两个可以选择。
UFW是一个简化的前端,通过ufw allow 22等简短命令生成iptables/nftables规则。
nftables是Linux原生防火墙框架,替代iptables,使用表、链和规则,语法更清晰。UFW适合想要快速默认配置的初学者。nftables适合需要使用meter进行速率限制、命名集合或Docker兼容规则的运维人员。
特性
UFW
nftables
学习曲线
低。单行命令。
中等。表/链/规则结构。
默认安装于
Ubuntu(已安装,未激活)
Debian 12(已安装,最小配置)
IPv6支持
自动(双栈)
需要手动规则(inet族)
速率限制
ufw limit(按规则)
Meter,按IP跟踪
Docker兼容
否。Docker绕过UFW规则。
是。nftables与Docker的DOCKER-USER链配合工作。
配置持久化
ufw enable时自动
/etc/nftables.conf + systemd
推荐场景
单应用VPS、第一台服务器
多服务、Docker主机、生产环境
1 apt update && apt install -y nftables
1 2 ufw disable systemctl disable --now ufw
1 2 systemctl enable nftables systemctl start nftables
1 2 sudo systemctl stop nftablessudo systemctl disable nftables
1 cp /etc/nftables.conf /etc/nftables.conf.bak
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 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 #!/usr/sbin/nft -f flush ruleset table inet firewall { set ssh_ratelimit { type ipv4_addr flags dynamic timeout 60s } set ssh_ratelimit6 { type ipv6_addr flags dynamic timeout 60s } chain inbound_ipv4 { icmp type echo-request limit rate 5/second accept } chain inbound_ipv6 { icmpv6 type { nd-neighbor-solicit, nd-router-advert, nd-neighbor-advert } accept icmpv6 type echo-request limit rate 5/second accept } chain inbound { type filter hook input priority 0; policy drop; ct state established,related accept ct state invalid drop iifname "lo" accept meta protocol vmap { ip : jump inbound_ipv4, ip6 : jump inbound_ipv6 } tcp dport 6902 ct state new add @ssh_ratelimit { ip saddr limit rate 3/minute burst 5 packets } accept tcp dport 6902 ct state new add @ssh_ratelimit6 { ip6 saddr limit rate 3/minute burst 5 packets } accept tcp dport { 80, 443 } accept limit rate 5/second log prefix "[nftables] Dropped: " counter drop } chain forward { type filter hook forward priority 0; policy drop; ct state established,related accept iifname "docker0" accept oifname "docker0" accept iifname "br-*" accept oifname "br-*" accept } chain outbound { type filter hook output priority 0; policy accept; } }
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 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 cat > /etc/nftables.conf << 'NFTEOF' flush ruleset table inet firewall { set ssh_ratelimit { type ipv4_addr flags dynamic timeout 60s } set ssh_ratelimit6 { type ipv6_addr flags dynamic timeout 60s } chain inbound_ipv4 { icmp type echo-request limit rate 5/second accept } chain inbound_ipv6 { icmpv6 type { nd-neighbor-solicit, nd-router-advert, nd-neighbor-advert } accept icmpv6 type echo-request limit rate 5/second accept } chain inbound { type filter hook input priority 0; policy drop; ct state established,related accept ct state invalid drop iifname "lo" accept meta protocol vmap { ip : jump inbound_ipv4, ip6 : jump inbound_ipv6 } tcp dport 6902 ct state new add @ssh_ratelimit { ip saddr limit rate 3/minute burst 5 packets } accept tcp dport 6902 ct state new add @ssh_ratelimit6 { ip6 saddr limit rate 3/minute burst 5 packets } accept tcp dport { 80, 443 } accept limit rate 5/second log prefix "[nftables] Dropped: " counter drop } chain forward { type filter hook forward priority 0; policy drop; ct state established,related accept iifname "docker0" accept oifname "docker0" accept iifname "br-*" accept oifname "br-*" accept } chain outbound { type filter hook output priority 0; policy accept; } } NFTEOF
1 2 nft -f /etc/nftables.conf systemctl restart docker
需要注意的是,在本配置中,入站通过iifname "lo" accept开启了本地回环。由于本地默认就能访问所有端口,即使没有进行tcp dport {XX端口} accept放行,本地127.0.0.1:port也能访问,但是公网ip:port无法访问。利用这个特性用域名 反代127.0.0.1:port,防止ddos攻击直接攻击公网ip。
在修改完防火墙规则后,一定新开一个窗口测试SSH连接成功后,再关SSH登录,防止把自己锁在外面。
Nftable开启内核端口转发:(选做,用于本地端口跳跃)
开启端口跳跃,把30000-31000端口的UDP入站转发到本地监听端口8443。
编辑防火墙 inbound 链,在chain inbound 段加入udp的2083端口:
新增 NAT 表。在flush ruleset后添加:(本地端口跳跃,没有经过公网,不需要masquerade 伪装)
1 2 3 4 5 6 7 8 table ip mynat { chain prerouting { type nat hook prerouting priority 0; policy accept; udp dport 30000-31000 dnat to :8443 } }
1 2 nft -f /etc/nftables.conf systemctl restart docker
3.DD服务器(选做)
由于大厂自带的系统有一大堆自定义的监控(点名甲骨文),可以用下面脚本一键安装纯净debian 12,重启后需要等15分钟:
1 2 3 4 curl -O https://raw.githubusercontent.com/bin456789/reinstall/main/reinstall.sh || wget -O ${_##*/} $_ sudo chmod +x ./reinstall.shsudo bash reinstall.sh debian 12reboot
1 2 3 4 curl -O https://raw.githubusercontent.com/bin456789/reinstall/main/reinstall.sh || wget -O ${_##*/} $_ sudo chmod +x ./reinstall.shsudo bash reinstall.sh ubuntu 22.04reboot
1 2 curl -O https://raw.githubusercontent.com/bin456789/reinstall/main/reinstall.sh || wget -O ${_##*/} $_ sudo chmod +x ./reinstall.sh
4.关闭ipv6(选做) 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 #!/bin/bash set -eecho "关闭 IPv6 中..." cat >> /etc/sysctl.conf <<EOF net.ipv6.conf.all.disable_ipv6=1 net.ipv6.conf.default.disable_ipv6=1 net.ipv6.conf.lo.disable_ipv6=1 EOF sysctl-p cat > /etc/systemd/system/sysctl-p.service <<EOF [Unit] Description=Apply sysctl settings at boot DefaultDependencies=no Before=local-fs.target [Service] Type=oneshot ExecStart=/sbin/sysctl -p [Install] WantedBy=sysinit.target EOF systemctl daemon-reload systemctl enable sysctl-p.service systemctl start sysctl-p.service echo "IPv6 已关闭并应用配置。"
4.安装1panel用于反代
1 curl -sSL https://resource.fit2cloud.com/1panel/package/quick_start.sh -o quick_start.sh && bash quick_start.sh
5.添加本地Socks5
注意:原生的 SOCKS5 协议本身是明文的。它不仅不加密传输的实际内容(Payload),在进行账号密码认证时,用户名和密码同样是以明文(Base64 或纯文本)发送的 ,这使得它容易受到抓包和中间人攻击。
如果您通过 SOCKS5 代理访问的是 HTTPS 网站,那么您的网络通信本身已经由网站的 SSL/TLS 进行了端到端加密。代理服务器只能看到您在访问哪个网站,但无法窃取或篡改您传输的具体数据
不适合在大陆直接使用。
创建SOCKS5用户,用户名为socksuser:
1 2 sudo useradd -M -s /usr/sbin/nologin socksusersudo passwd socksuser
输入密码即可。(后续连接也是这个密码)
安装Dante:
1 2 sudo apt updatesudo apt install dante-server -y
如下例子,地址为eth0,其中lo为本地回环地址,不用理会:
1 2 3 4 5 6 7 8 9 10 11 12 root@Netherlands:~# ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link /loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq state UP group default qlen 1000 link /ether 00:4f:e2:d8:fc :f4 brd ff:ff:ff:ff:ff:ff altname enp0s3 altname ens3 inet XXXXX scope global eth0 valid_lft forever preferred_lft forever root@Netherlands:~#
1 sudo mv /etc/danted.conf /etc/danted.conf.bak
1 sudo nano /etc/danted.conf
粘贴写入:
注意下方配置的external: eth0改为自己的物理网卡名字,其他不用改。端口默认为1080 。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 logoutput: syslog internal: 0.0.0.0 port = 1080 external: eth0 socksmethod: username user.privileged: root user.unprivileged: nobody user.libwrap: nobody client pass { from: 0.0.0.0/0 to: 0.0.0.0/0 } socks pass { from: 0.0.0.0/0 to: 0.0.0.0/0 protocol: tcp udp }
1 2 3 sudo systemctl restart dantedsudo systemctl enable dantedsudo systemctl status danted