树洞剪藏#剪藏#树洞剪藏

VPS基本安全措施 - 开发调优 - LINUX DO

2024 年 12 月 10 日1 分钟
分享Twitter / XTelegram微博

同步来源:树洞剪藏 源站剪藏 ID:327 原文地址:https://linux.do/t/topic/267502

打开原文 · 打开源站剪藏快照


VPS基本安全措施 - 开发调优 - LINUX DO

set 限制解除

跳到主要内容

20

话题

我的帖子

关于

友链

即将到来的活动

文档

更多

外部链接

Status

Connect

Channel

Telegram

类别

开发调优

资源荟萃

文档共建

跳蚤市场

前沿快讯

福利羊毛

搞七捻三

运营反馈

深海幽域

所有类别

标签

抽奖

公告

精华神帖

快问快答

人工智能

所有标签

消息

收件箱

频道

常规频道

直接消息

聊天

Default

真诚 、 友善 、 团结 、 专业 ,共建你我引以为荣之社区。 《常见问题解答》

VPS基本安全措施

开发调优

网络安全 精华神帖

5.4k

浏览量

1.1k

20

链接

79

用户

9

6

5

2

2

阅读时间

14 分钟

热门回复

总结

前言

安全管理系统

创建非 root 账户

禁用 root SSH 密码登陆

修改 SSH 端口号

Fail2ban 防暴力破解 SSH

通知服务器SSH登录

【严格】使用绝对路径运行命令

使用密钥登录

启用 UFW 防火墙

禁止ping服务器

限定SSH登录IP

保证软件更新

日常更新系统

开启 Ubuntu Pro

隐藏公网 IP

防止 SSL 证书泄露 IP

申请并下载证书

配置证书并且设置禁止 IP 80/433 的 HTTP 访问

Nginx 1.19.4 之后的新方法

真的安全了吗

于是我们打个补丁

真的安全了……吗?

迈向全面容器化

Docker基本使用

UFW管不了Docker的解决方案(推荐)

UFW管不了Docker的解决方案(不太推荐)

长亭雷池WAF+Cloudflare单节点部署

部署

使用域名访问雷池控制台的问题

重定向问题

引用

跳至结尾

时间线

渡鸦95676 Raven95676 Regular

40 17 天

前言

当我们拿到 VPS 之后,我们都需要做些什么呢?

如果选择将网站 / 服务放在知名厂商虚拟主机上,虚拟主机的厂商会负责基本的服务器安全措施。但如果放在 VPS 上,那么你就是服务器的安全负责人了。更多的权限代表着更多的义务,VPS 在具有更高的自由度的情况下自然有更高的风险。 而我们要做到的不是绝对安全,而是比大多数人安全。 只要做到没那么容易被攻破那就是胜利。

本文使用的环境为 Ubuntu 24.04 LTS,其他发行版可大致参照思路。

在继续阅读本文之前,建议提前阅读由 LUG@USTC 编写的: https://101.lug.ustc.edu.cn/

本文与 GitHub - ustclug/Linux101-docs: Linux 101 学生课程教材与讲义 项目无关

佬友们可以看看本文有没有什么需要补充的(

安全管理系统

有些 VPS 厂商默认提供的是 root 账户。众所周知,root 账户拥有整个系统最高的权限,这么高的权限自然是不安全的。正确的做法是创建一个非 root 账户,在必须使用 root 权限时使用 sudo 提权。

创建非 root 账户

使用以下命令创建一个具有提权能力的账户:

useradd -m -G sudo -s /bin/bash 用户名

然后我们给这个用户设置一个至少为 16 位的随机大小写字母 + 数字的密码(个人建议的最低安全性需求):

passwd 用户名

wordpure:

建议把 root 用户的密码也改掉,云服务器的默认密码强度还是差点,而且有些服务商会通过邮件来发送默认密码,不太安全。

禁用 root SSH 密码登陆

先不提 root 登录本身就是危险的行为,root 账户的用户名固定为”root”,如果允许其通过密码登录,攻击者只需进行密码穷举即可尝试攻破系统。之前我们已经创建了非 root 账户,在这里我们只需要禁用非 root 账户的 SSH 登录即可。

执行以下命令编辑 SSH 配置文件:

sudo vim /etc/ssh/sshd_config

进行如下设置:

Oganneson:

禁止 Root 用户通过密码远程登录

PermitRootLogin prohibit-password

之后重启 SSH 服务生效:

sudo systemctl restart ssh

为什么不设置成no:

庄sir:

另,直接禁掉root登录 PermitRootLogin no 我也不常用,更习惯和其他sudoer一样配密钥然后禁止密码登录仅允许密钥登录。我是一般能操做线下集群的机子才会这么配,不然出个故障没root用不了了,比如存储满了远程ssh session都建立不了。

Oganneson:

理论上PermitRootLogin是好的,但在服务器寄掉需要救援时就会变麻烦,我其实更推荐只关闭远程密码登录,保留本地密码登录,出问题时可以通过vnc或者ipmi本地登录root进行救援。

修改 SSH 端口号

章北海:

首先就要把22端口改了。

中文网络寻呼机🔰:

这是参照原帖里的基础上补充~

实际端口一般登上去就会改掉

Lao Qian:

登上去第一件事就是改SSHD的 端口并修改防火墙,22全是猜密码的请求。

有个小技巧,就是改端口并重启 sshd后当前的连接并没有断,向新端口发请求,能连上就是修改正确,要是不能建立新连接,还可以改回来,或查下防火墙的配置。

正常情况下,直接通过 sudo vim /etc/ssh/sshd_config 修改SSH端口,然后再使用 sudo systemctl restart ssh.service 重启SSH服务应用更改是可行的:

Oganneson:

设置 SSH端口

Port 自拟

但是在 Ubuntu 22.10 或更高版本 中各位可能发现这是 无效 的,各位会发现SSH服务在重启后依然监听原端口。

因为在Ubuntu 22.10 或更高版本中,ssh 默认通过套接字激活。

在 Ubuntu 22.10、Ubuntu 23.04 和 Ubuntu 23.10 中进行修改的方法是:

sudo mkdir -p /etc/systemd/system/ssh.socket.d sudo vim /etc/systemd/system/ssh.socket.d/listen.conf sudo systemctl daemon-reload sudo systemctl restart ssh.socket sudo systemctl restart ssh.service

listen.conf的参考配置为:

[Socket] ListenStream = ListenStream = 2233

在 Ubuntu 24.04 中进行修改的方法是:

sudo vim /etc/ssh/sshd_config sudo systemctl daemon-reload sudo systemctl restart ssh.service

如果不在乎通过套接字激活节省的内存,可以通过以下命令恢复到非套接字激活:

sudo systemctl disable --now ssh.socket sudo systemctl daemon-reload sudo systemctl enable --now ssh.service

wordpure:

建议在 /etc/ssh/sshd_config.d/ 创建一个 conf 文件来自定义 sshd 配置,而不是直接编辑 /etc/ssh/sshd_config ,防止 OpenSSH 更新后配置冲突。

参考: ssh - PasswordAuthentication no, but I can still login by password - Unix & Linux Stack Exchange

图片 1454×1325 193 KB

有些云服务商为了启用远程密码登录(sshd 默认禁用 ),会在 /etc/ssh/sshd_config.d/ 自定义一个 conf 文件,修改 sshd 配置前先要排除它们的干扰。

查看 sshd_config.d 是否存在其他 conf 文件

sudo ls /etc/ssh/sshd_config.d/*.conf

如果存在,重命名,防止后续自定义配置被覆盖

sudo mv /etc/ssh/sshd_config.d/xxx.conf /etc/ssh/sshd_config.d/xxx.conf.bak

比如 CloudCone 就有一个 /etc/ssh/sshd_config.d/50-cloud-init.conf

图片 1028×305 11.3 KB

sshd 配置修改完,先用 sudo sshd -T 看一下有效配置,免得被覆盖了都不知道 。

Root 用户登录方式

sudo sshd -T | grep -i "PermitRootLogin"

密码认证

sudo sshd -T | grep -i "PasswordAuthentication"

ssh 端口

sudo sshd -T | grep -i "Port"

值得一提的是, prohibit-password 是 without-password 的别名,所以看到下面的输出是正常现象。

图片 1111×91 8.94 KB

参考:

Permit root to login via ssh only with key-based authentication - Unix & Linux Stack Exchange

OpenSSH 7.0 更新日志

Fail2ban 防暴力破解 SSH

执行以下命令安装 Fail2ban:

sudo apt install fail2ban

官方推荐的做法是利用 jail.local 来进行自定义设置:

sudo vim /etc/fail2ban/jail.local

可以参照以下配置文件来进行自己的配置(记得删注释):

[sshd] ignoreip = 127.0 . 0.1 / 8 # 白名单 enabled = true filter = sshd port = 22 # 端口,改了的话这里也要改 maxretry = 5 # 最大尝试次数 findtime = 300 # 多少秒以内最大尝试次数规则生效 bantime = 600 # 封禁多少秒,-1是永久封禁(不建议永久封禁) action = %(action_)s[port= "%(port)s" , protocol= "%(protocol)s" , logpath= "%(logpath)s" , chain= "%(chain)s" ] # 不需要发邮件通知就这样设置 banaction = iptables-multiport # 禁用方式 logpath = /var/log/auth.log # SSH 登陆日志位置

通知服务器SSH登录

kendo:

很有用,我还加了一个在登录 ssh 时候自动发通知到企业微信机器人,以防偷家不知道

可以通过 PAM 模块在每次ssh登录时触发脚本来实现。

编辑 /etc/pam.d/sshd ,在文件末尾添加:

session optional pam_exec.so 脚本路径

对于提到的用例,脚本大致如下:

参照: 群机器人配置说明 - 文档 - 企业微信开发者中心

2024年11月26日注:修复了示例脚本的一些问题。

#!/bin/bash

if [ " $PAM_TYPE " != "open_session" ]; then exit 0 fi

ip= $PAM_RHOST date =$( date + "%e %b %Y, %a %r" ) name= $PAM_USER

webhook_url= "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxxxxxxxxxxxxxx"

curl -s -X POST " $webhook_url "
-H "Content-Type: application/json"
-d "{ "msgtype": "markdown", "markdown": { "content": "登录提醒\

登录用户: $name
客户端IP: $ip
登录时间: $date " } }"

请根据自己的用例替换api及调用方式。

【严格】使用绝对路径运行命令

使用绝对路径可以精准指定要运行的程序或文件,可避免因环境变量被篡改等原因误执行潜在的恶意程序。

libook:

使用 su 的完整路径可以避免运行潜在的攻击者植入的 su。

使用密钥登录

如果 VPS 厂商提供了 SSH 密钥绑定功能,可以忽略本节内容并按照 VPS 厂商提供的方法绑定。

在 powershell 中运行:

ssh-keygen -t ed25519

直接使用默认的密钥路径即可。密码可以留空,也可以设置。

Generating public / private ed25519 key pair. Enter file in which to save the key ( C :\Users<user>/.ssh/id_ed25519): # 直接回车 Enter passphrase ( empty for no passphrase): # 可以留空,也可以设置 Enter same passphrase again: # 和上一个一样

然后我们在 VPS 上编辑 SSH 授权密钥文件:

vim ~/.ssh/authorized_keys

之后打开 C:\Users/.ssh/id_ed25519.pub,复制其内容并粘贴过去。

执行以下命令编辑 SSH 配置文件:

sudo vim /etc/ssh/sshd_config

进行如下设置:

PubkeyAuthentication yes AuthorizedKeysFile .ssh/authorized_keys PasswordAuthentication no

之后重启 SSH 服务生效:

sudo systemctl restart ssh

启用 UFW 防火墙

如果 VPS 厂商提供了防火墙功能,且没有复杂的需求,可以忽略本节内容并使用 VPS 厂商提供的防火墙。

在正式启用 UFW 之前,我们需要先设置规则。我们首先来设置 UFW 的默认行为:

sudo ufw default allow outgoing # 默认允许所有数据出站 sudo ufw default deny incoming # 默认禁止所有数据入站

我们可以通过以下命令查看 UFW 当前生效的规则:

sudo ufw status sudo ufw status numbered # 加上数字编号

我们可以通过以下命令允许或拒绝某端口的传入 / 传出流量(部分以 22、80、443 端口为例):

允许22端口的proto协议的流量入站

sudo ufw allow in 22/proto

#允许22端口的proto协议的流量出站 sudo ufw allow out 22/proto

在未指定in/out的情况下,默认为in

sudo ufw allow 22/proto

在未指定proto的情况下,默认为tcp和udp

sudo ufw allow 22

拒绝的话就把allow改成deny

sudo ufw deny 22

允许从start_port到end_port的端口

sudo ufw allow start_port:end_port

允许复数个端口,以英文逗号分隔

sudo ufw allow port1,port2

允许来自于特定ip或cidr段的流量

sudo ufw allow from ip/cidr

允许来自于特定ip或cidr段端口22的流量

sudo ufw allow from ip/cidr to any port 22

允许来自于特定ip或cidr段端口22的tcp协议的流量

sudo ufw allow from ip/cidr to any proto tcp port 22

如果指定复数个端口,则必须指定协议

sudo ufw allow from ip to any proto tcp port 80,443

comment用于注释

sudo ufw allow from ip to any proto tcp port 80,443 comment "hello"

我们可以通过以下命令删除生效的规则:

sudo ufw delete allow 22 # 在规则前面加个delete sudo ufw delete 1 # 按照numbered的编号删除也行

在确定所有规则均成功设置后,通过以下命令启动 \ 关闭 \ 重启 UFW

启动防火墙前务必保证 22 端口(或者其他 SSH 端口)被放行。

sudo ufw enable | disable |reload

如果需要重置规则,请使用:

重置规则前务必保证 UFW 处于关闭状态。

sudo ufw reset

本人建议仅放行正在使用的端口,比如22、80、443。

默认情况下,UFW仅记录不符合规则的被拒绝的数据包。如果需要记录与该服务相关的每个详细信息,可以在allow后加上log以进行记录。

中文网络寻呼机🔰:

成功连接 ssh 的也记一下日志备查比较好

ufw allow log 22/tcp

禁止ping服务器

Se:

我之前还会进行禁止ping的设置。

1 . 使用 iptables 禁止ping

  • 查看当前iptables规则:

  • iptables -L -n

  • 这条命令可以列出当前iptables的规则,-L表示列出规则,-n表示以数字形式显示 IP 地址和端口号,而不是解析为主机名和服务名。

  • 禁止 ping(入站 ICMP Echo Request):

  • iptables - A INPUT - p icmp --icmp - type 8 -j DROP

  • 这里- A INPUT 表示在 INPUT 链(用于处理进入本机的数据包)的末尾添加一条规则。- p icmp指定协议为 ICMP, --icmp - type 8 表示 ICMP 类型为 8 (即 Echo Request),-j DROP表示将匹配的数据包丢弃。

  • 保存iptables规则(如果需要永久生效):

  • 对于不同的 Linux 发行版,保存iptables规则的方式不同。

  • 在 CentOS 等基于 RHEL 的系统中,可以使用service iptables save命令来保存规则。这条命令会将当前的iptables规则保存到/etc/sysconfig/iptables文件中,这样在系统重启后规则依然生效。

  • 在 Ubuntu 等 Debian 系系统中,需要安装iptables - persistent软件包。安装后可以使用iptables - save > /etc/iptables/rules .v4 (对于 IPv4 规则)来保存规则,这样在系统重启后也能恢复规则。

  • 恢复 ping 功能 如果要恢复 ping 功能,可以删除刚才添加的禁止 ping 的规则。使用iptables -D INPUT - p icmp --icmp - type 8 -j DROP命令。其中-D INPUT 表示从 INPUT 链中删除规则,其他参数和添加规则时相同。

渡鸦95676:

ufw本身没有直接支持阻止icmp协议的命令。ufw在/etc/ufw/before.rules中定义了针对ping的允许规则,我们可以修改ACCEPT为DROP来达成禁止ping的目的:

ok icmp codes for INPUT

  • A ufw-before- input - p icmp --icmp-type destination-unreachable -j DROP
  • A ufw-before- input - p icmp --icmp-type time -exceeded -j DROP
  • A ufw-before- input - p icmp --icmp-type parameter-problem -j DROP
  • A ufw-before- input - p icmp --icmp-type echo-request -j DROP

ok icmp code for FORWARD

  • A ufw-before-forward - p icmp --icmp-type destination-unreachable -j DROP
  • A ufw-before-forward - p icmp --icmp-type time -exceeded -j DROP
  • A ufw-before-forward - p icmp --icmp-type parameter-problem -j DROP
  • A ufw-before-forward - p icmp --icmp-type echo-request -j DROP

限定SSH登录IP

Staleness:

我办公室的网络是固定 ip,VPS 运营商的防火墙开 22 端口然后指定 IP 地址,这样以后需要别的 IP 访问的话,直接添加 IP 即可

如果拥有动态公网IP且厂商支持通过接口修改防火墙规则,可以直接使用厂商的接口。

若没有公网IP,可忽略此条。

保证软件更新

日常更新系统

个人建议定期登录 VPS 运行 sudo apt update && sudo apt upgrade 来保证 VPS 内所有软件包均为最新。

不过 Ubuntu 默认会每天自动安装系统的安全更新,所以说这个频率没必要太勤。

开启 Ubuntu Pro

同样出色的操作系统,更多的安全更新

将平均 CVE(通用漏洞披露)暴露时间从 98 天减少到 1 天

具备扩展的 CVE 补丁、十年的安全维护、可选的支持和对整个开源应用程序堆栈的维护。

上面是 Ubuntu 官方的广告词。到底多有用我不知道,有修复总比没修复好,而且个人免费 5 台机器,开了不亏。

我们先来创建一个 Ubuntu One 帐户: https://ubuntu.com/login

注册结束之后,转到 https://ubuntu.com/pro/dashboard 查看 Token。

1024×647 44.9 KB

得到了Token之后,前往我们的VPS,运行 sudo pro attach [YOUR_TOKEN] 。等待一段时间,我们的VPS就成功开启Ubuntu Pro了。建议在开启之后再运行一次 sudo apt update && sudo apt upgrade 以确保系统安装了最新的安全更新。

隐藏公网 IP

庄sir:

隐藏公网IP并不是所有VPS使用者的共同安全需求,有一个胡诌的针对未来(指ipv6广泛使用)的方案就是只暴露源站v6地址给CDN用,这样Censys这样强扫的工具耗时会很长,不过也还是要配白名单。

防止 SSL 证书泄露 IP

本节 “防止 SSL 证书泄露 IP” 引自 “如何避免证书泄露源站 IP”,作者为秋未萌,根据 CC BY-SA 4.0 授权协议发布。本文其他部分根据 CC BY-NC-SA 4.0 授权协议发布,但本节内容使用 CC BY-SA 4.0 授权协议。

申请并下载证书

注册并且登录 ZeroSSL

到 Dashboard 找到 Create SSL Certificate,点击 New Certificate 蓝色按钮

在 Enter Domains 处输入源站 IP

其实过期也无妨,总之不让 censys 扫描到真正的域名证书就可以。因此选择 90 天证书

CSR & Contat 保持不变

验证域名的办法选择 HTTP File Upload

使用 NGINX 的话,如果你保持原先设置不变,即 /etc/nginx/sites-available/default 不变就没问题。当然,如果你改变了,记得保留 server {listen 80; root /var/www/html;} 就可以

然后下载 Auth File,并且把它上传到 /var/www/html/.well-known/pki-validation 。如果没有文件夹,就新建,记得让 NGINX 有权访问这些文件,否则还是会失败

按照提示,点击一下 .txt 文件是不是可以访问。成功的话,就验证好了

配置证书并且设置禁止 IP 80/433 的 HTTP 访问

下载 *.zip 文件,解压它。解压好的文件夹里面有好申请到的证书

将 ca_bundle.crt 和 certificate.crt 合并,方法是用 notepad3 或者 vsode 等可靠的编辑器打开 certificate.crt 。然后把 ca_bundle.crt 内容复制进去。格式是:

--- --BEGIN CERTIFICATE----- certificate .crt 内容 --- --END CERTIFICATE----- --- --BEGIN CERTIFICATE----- ca_bundle .crt 内容 --- --END CERTIFICATE-----

上传合并好的文件和 private.key

上传证书到一个 Nginx 有权限的文件夹,咱放在 /etc/nginx/ip-certificate/

设置 /etc/nginx/sites-available/default 文件。参考设置如下:

server { #HTTP Server Default Set listen 80 ; listen 443 ssl http2 default_server; server_name ip;

#HTTP_TO_HTTPS_END ssl_certificate /etc/nginx/ip-certificate/certificate.crt; ssl_certificate_key /etc/nginx/ip-certificate/private.key; ssl_protocols TLSv1. 1 TLSv1. 2 TLSv1. 3 ; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE; ssl_prefer_server_ciphers on; ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m;

#Server ROOT index index.html; root /var/www/html/; index index.html;

return 444 ; #NGINX HTPP Code 444

}

服务器后台输入 nginx -t 检查是否有误,正确即可 sudo systemctl restart nginx 重启。

直接输入 IP 作为网址检查是不是连接后立刻变成空白页

Nginx 1.19.4 之后的新方法

如果各位的 Nginx 版本大于等于 1.19.4,可以直接使用 ssl_reject_handshake 配置项,通过简单的配置就能拒绝所有未匹配到域名的 TLS 握手:

server { listen 443 ssl default_server; server_name _; ssl_reject_handshake on ; }

如果出现如 nginx: [emerg] unknown directive “ssl_reject_handshake” 的报错,首先请检查nginx版本是否大于等于1.19.4。 ssl_reject_handshake on; 在nginx 1.19.4 主线版加入。

如果是通过源代码编译安装的,请确认ngx_http_ssl_module模块是否启用。 该模块不是默认构建的,需要通过 --with-http_ssl_module 配置参数来启用。

真的安全了吗

前文中,我们只能确保攻击者无法通过直接访问 ip 获取默认证书来推断域名信息。然而又没有规定说攻击者只能用这种方式获取 IP 与域名的对应关系。可以看出,前文的规则依赖于 server_name 的匹配。攻击者完全可以携带正确的 server_name 握遍所有可能的非已知 CDN 的 IP 段,记录正确响应的目标。下面是判断(不包含遍历)的简单实现:

https://gist.github.com/Raven95676/39ffdba22144e39d7155ad9dc1bcca55

import ssl import socket def check ( ip, domain ): try : context = ssl.create_default_context() with socket.create_connection((ip, 443 )) as sock: with context.wrap_socket(sock, server_hostname=domain) as ssl_sock: request = f"GET / HTTP/1.1 Host: {domain} Connection: close

" ssl_sock.sendall(request.encode()) ssl_sock.recv( 4096 ) return True except Exception: return False

print (check( "192.168.0.256" , "example.com" ))

于是我们打个补丁

如果 VPS 厂商提供了防火墙功能,可以直接使用 VPS 厂商提供的防火墙。

各位可以直接用这个方法

我们可以仅允许 CDN 的 CIDR 段访问服务器的 80/443 端口。先来添加允许的规则:

sudo ufw allow from "cidr段" to any proto tcp port 80 , 443 comment "CDN服务商"

comment 不是必须的,只是为了方便日后能认出来这规则是干什么的才加上的。

CDN 的 CIDR 段去找 cdn 服务商要,有的在官网也有公示。比如 Cloudflare 的CIDR 段可以从这个网页获取: https://www.cloudflare.com/ips-v4

上面那个是 ipv4 的,ipv6 的可以从这个网页获取: https://www.cloudflare.com/ips-v6

对于 Cloudflare ,还有佬友编写的脚本可以在执行后更新 CF IP 到 ufw 443。

避免网站被攻击的低成本想法

RULES=$( sudo ufw status numbered | grep 'Cloudflare IP' | awk -F "[][]" '{print $2}' | sort -nr) for RULE in $RULES ; do echo "Deleting rule $RULE " echo "y" | sudo ufw delete $RULE done

for cfip in curl -sw ' ' https://www.cloudflare.com/ips-v{4,6}; do ufw allow proto tcp from $cfip to any port 443 comment 'Cloudflare IP' ; done

ufw reload > /dev/null

由于特殊情况的存在,本人建议在部署该脚本之前先执行以下命令查看是否正确输出。

for cfip in curl -sw ' ' https://www.cloudflare.com/ips-v{4,6}; do echo $cfip ; done

如果输出正常(如下),则可以部署:

173.245 . 48.0 / 20 103.21 . 244.0 / 22 …略 2400 :cb00 : :/ 32 2606 : 4700 : :/ 32 …略

添加完了之后我们使用以下命令查看防火墙现有规则列表:

sudo ufw status numbered

使用以下命令删除之前可能存在的针对 80 和 443 端口允许所有流量的规则:

sudo ufw delete 序号

为什么不直接使用 Nginx 的 deny 配置项呢?因为 deny 会返回 403 Forbidden 状态码,而在此之前必须完成 TLS 握手。只有在 TLS 握手成功后,客户端才能发送 HTTP 请求并接收到响应。如果直接使用 deny,我们相当于在做无用功。

真的安全了……吗?

居然还能再出一期

这其实算是 Cloudflare 特辑,不过如果使用其他 CDN 提供商,为了增强安全性也可以参考。众所周知,Cloudflare 不仅提供 CDN 服务,还有一系列其他产品,比如 Workers 和 WARP。而这些服务有一些需要注意的特点:

能对外发出请求

用的是 Cloudflare 的 IP 段

虽然 Cloudflare 对于滥用肯定是限制的,但是为了以防万一,我们还可以再做点安全措施 —— 经过身份验证的源服务器拉取。

必须确保SSL/TLS加密模式为完全或者完全(严格)

我们首先来到 SSL/TLS→源服务器这里签发源证书,日期选 15 年就好。将证书上传到服务器后,更新 nginx server 段配置:

ssl_client_certificate 证书地址; ssl_verify_client on ;

然后在 SSL/TLS→源服务器这里开启经过身份验证的源服务器拉取。

雷池WAF社区版目前暂时无法稳定使用此方法,除非乐意在雷池前面再叠一层反代。

迈向全面容器化

Oganneson:

我的建议是善用容器化技术进行隔离

本节暂不涉及1panel等运维面板或portainer等docker面板。

Docker基本使用

发现成熟的文档,不再重复造轮子。

本文与 GitHub - yeasy/docker_practice: Learn and understand Docker&Container technologies, with real DevOps practice! 项目无关

小小的偷个懒

附注:如果 docker-compose 提示找不到命令,试试 docker compose 。docker compose现已弃用 version 字段,现有的compose配置文件中 version 字段将被忽略并显示一条警告。

yeasy.gitbook.io

前言 | Docker — 从入门到实践

更新:添加Docker官中文档。

docs.docker.net.cn – 28 Nov 24

手册 | Docker 文档

UFW管不了Docker的解决方案(推荐)

Oganneson:

再写一点关于docker的问题吧,其实没必要用ufw来管理docker的端口开放,docker会自己写入iptables规则用以管控端口,以docker compose为例:

  1. 对于数据库或者redis之类仅在应用内使用的服务:

仅在容器内部网络内开放,compose拉起时会创建一个名为 第一个服务名_default 的bridge,可以用 docker network ls 查看。

容器默认对该内部网络开放所有端口。

同一网络内的其他容器可以通过容器名和端口访问该服务。

没有加入该网络的容器无法访问任何端口。

对于仅在内部网络中暴露端口的服务, 无需 在 ports 下指定任何映射

  1. 对于需要进行反代的服务:

仅在127.0.0.1监听即可防止外部端口访问,在对应容器处使用

ports:

  • 127.0.0.1:端口:端口
  1. 对于需要外部直接访问端口的服务:

直接使用

ports:

  • 端口:端口

同样的,贴一个示例compose.yml

services: rsshub: image: diygod/rsshub:latest restart: always ports:

  • 127.0.0.1:1200:1200 environment: NODE_ENV: production CACHE_TYPE: redis REDIS_URL: "redis://redis:6379/" PUPPETEER_WS_ENDPOINT: "ws://browserless:3000" env_file:
  • .env healthcheck: test: ["CMD", "curl", "-f", "http://localhost:1200/healthz"] interval: 30s timeout: 10s retries: 3 depends_on:
  • redis
  • browserless

browserless: image: browserless/chrome restart: always ulimits: core: hard: 0 soft: 0 healthcheck: test: ["CMD", "curl", "-f", "http://localhost:3000/pressure"] interval: 30s timeout: 10s retries: 3

redis: image: redis:alpine restart: always volumes:

  • ./data:/data healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 30s timeout: 10s retries: 5 start_period: 5s

sb: image: ghcr.io/sagernet/sing-box container_name: sb restart: always volumes:

  • ./sing-box:/etc/sing-box/ command: -D /var/lib/sing-box -C /etc/sing-box/ run

此外,如果需要阻止外部端口访问,除去仅在127.0.0.1监听外还可以:

有容:

需要Nginx/Caddy等反代的服务,在Compose文件里可以配置一个Docker专用的172开头的内网ip,且不配置端口。这样Docker就不会暴露公共端口,反代地址写 内网ip:默认端口即可。

比如MySQL的Compose文件配置,指定了使用内网IP为 172.20.0.15 ,注释了端口映射,在配置反向代理时 直接反代 172.20.0.15:3306 即可。

networks: default: external: true name: ${DOCKER_MY_NETWORK} services: mysql: container_name: mysql8 image: mysql:8

ports:

- "3306:3306"

environment: TZ: Asia/Shanghai networks: default: ipv4_address: 172.20 .0 .15 restart: unless-stopped

UFW管不了Docker的解决方案(不太推荐)

本节 “UFW管不了Docker的解决方案(不太推荐)” 引自项目 ufw-docker 的README,作者为 chaifeng ,根据 GPL-3.0 license 授权协议发布。本文其他部分根据 CC BY-NC-SA 4.0 授权协议发布,但本节内容使用 GPL-3.0 license 授权协议。

目前新的解决方案只需要修改一个 UFW 配置文件即可,Docker 的所有配置和选项都保持默认。

修改 UFW 的配置文件 /etc/ufw/after.rules ,在最后添加上如下规则:

BEGIN UFW AND DOCKER

*filter :ufw-user-forward - [0:0] :ufw-docker-logging-deny - [0:0] :DOCKER-USER - [0:0] -A DOCKER-USER -j ufw-user-forward

-A DOCKER-USER -j RETURN -s 10.0.0.0/8 -A DOCKER-USER -j RETURN -s 172.16.0.0/12 -A DOCKER-USER -j RETURN -s 192.168.0.0/16

-A DOCKER-USER -p udp -m udp --sport 53 --dport 1024:65535 -j RETURN

-A DOCKER-USER -j ufw-docker-logging-deny -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 192.168.0.0/16 -A DOCKER-USER -j ufw-docker-logging-deny -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 10.0.0.0/8 -A DOCKER-USER -j ufw-docker-logging-deny -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 172.16.0.0/12 -A DOCKER-USER -j ufw-docker-logging-deny -p udp -m udp --dport 0:32767 -d 192.168.0.0/16 -A DOCKER-USER -j ufw-docker-logging-deny -p udp -m udp --dport 0:32767 -d 10.0.0.0/8 -A DOCKER-USER -j ufw-docker-logging-deny -p udp -m udp --dport 0:32767 -d 172.16.0.0/12

-A DOCKER-USER -j RETURN

-A ufw-docker-logging-deny -m limit --limit 3/min --limit-burst 10 -j LOG --log-prefix "[UFW DOCKER BLOCK] " -A ufw-docker-logging-deny -j DROP

COMMIT

END UFW AND DOCKER

然后重启 UFW, sudo systemctl restart ufw 。现在外部就已经无法访问 Docker 发布出来的任何端口了,但是容器内部以及私有网络地址上可以正常互相访问,而且容器也可以正常访问外部的网络。 可能由于某些未知原因,重启 UFW 之后规则也无法生效,请重启服务器。

如果希望允许外部网络访问 Docker 容器提供的服务,比如有一个容器的服务端口是 80 。那就可以用以下命令来允许外部网络访问这个服务:

ufw route allow proto tcp from any to any port 80

这个命令会允许外部网络访问所有用 Docker 发布出来的并且内部服务端口为 80 的所有服务。

请注意,这个端口 80 是容器的端口,而非使用 -p 0.0.0.0:8080:80 选项发布在服务器上的 8080 端口。

如果有多个容器的服务端口为 80,但只希望外部网络访问某个特定的容器。比如该容器的私有地址为 172.17.0.2 ,就用类似下面的命令:

ufw route allow proto tcp from any to 172.17 . 0.2 port 80

如果一个容器的服务是 UDP 协议,假如是 DNS 服务,可以用下面的命令来允许外部网络访问所有发布出来的 DNS 服务:

ufw route allow proto udp from any to any port 53

同样的,如果只针对一个特定的容器,比如 IP 地址为 172.17.0.2 :

ufw route allow proto udp from any to 172.17 . 0.2 port 53

长亭雷池WAF+Cloudflare单节点部署

思来想去没啥可写的

Oganneson:

对安全要求更高的话可以像我一样再套上WAF+蜜罐。

部署

有一键部署命令:

bash -c " $(curl -fsSLk https://waf-ce.chaitin.cn/release/latest/setup.sh) "

或部署LTS版本:

RELEASE =lts bash -c "$(curl -fsSLk https://waf-ce.chaitin.cn/release/latest/setup.sh)"

由于本用例在雷池WAF前套了一层Cloudflare,所以说需要将防护站点→全局配置→源 IP 获取方式设置为“取 X-Forwarded-For 中上一级代理的地址”

如果出现其他问题,可前往官方文档 常见问题排查 | 雷池 SafeLine 查询。

使用域名访问雷池控制台的问题

最佳解决方案:不用域名

如果我们需要通过域名访问雷池控制台,会发现启用 Cloudflare 小黄云后,域名访问无法实现。这是因为 Cloudflare 的端口转发仅支持其指定的几个端口:

【已解决】部署在cloudflare的域名开启代理之后就无法连接到vps

Cloudflare 支持的 HTTP 端口: 80,8080,8880,2052,2082,2086,2095

Cloudflare 支持的 HTTPS 端口: 443,2053,2083,2087,2096,8443

解决方案也很简单,打开 规则→Origin Rules,然后创建规则。传入请求匹配表达式大致如下:

(starts_with(http.request.full_uri, "https://域名" ))

目标端口设置重写到9443即可

为了隐藏公网IP,请设定限定仅cloudflare cdn cidr段访问9443端口的防火墙规则。

重定向问题

如果重定向时 URL 中意外出现端口号,可通过防护站点→站点详情→自定义 NGINX 配置添加以下内容进行解决:

proxy_redirect https: // $host :[port] https: // $host ;

引用

开始使用 Ubuntu Pro 来自 Ubuntu 官网

如何避免证书泄露源站 IP 作者:秋未萌

Ufw 使用指南 来自 Ubuntu 中文

Key-based authentication in OpenSSH for Windows 来自 Microsoft Learn

Install Docker Engine on Ubuntu 来自docker官网

VPS基本安全措施 - #2,来自 edwardzcn

VPS基本安全措施 - #3,来自 Oganneson

【已解决】部署在cloudflare的域名开启代理之后就无法连接到vps - #11,来自 MatsuzakaSato

VPS基本安全措施 - #18,来自 OICQ

GitHub - chaifeng/ufw-docker: To fix the Docker and UFW security flaw without disabling iptables

VPS基本安全措施 - #23,来自 Oganneson

VPS基本安全措施 - #42,来自 libook

VPS基本安全措施 - #44,来自 Staleness

VPS基本安全措施 - #20,来自 kendo

群机器人配置说明 - 文档 - 企业微信开发者中心

VPS基本安全措施 - #21,来自 alertsc

VPS基本安全措施 - #22,来自 OICQ

VPS基本安全措施 - #57,来自 waqian

Bug #2069041 “Changing Port in sshd_config requires calling syst...” : Bugs : openssh package : Ubuntu

避免网站被攻击的低成本想法 - #29,来自 Bee

VPS基本安全措施 - #71,来自 pama

VPS基本安全措施 - #87,来自 sevendays

VPS基本安全措施 - #97,来自 wordpure

VPS基本安全措施 - #99,来自 wordpure

本文在本人博客首发, 除特别声明外均采用 CC BY-NC-SA 4.0 许可协议。

此副本已去除所有可能涉及引流的站外链接。

如需转载,请您在非商业使用的情况下标明转载自本帖并附上本贴链接。

如本文采纳诸位佬友的意见,相关帖子链接将会放在引用部分。

6 个回复

heart

+1

confetti_ball

585

回复

【长期帖】来推荐你心目中的精华神帖吧 关于通过1panel部署lobechat遇到的问题分享 请教docker端口不受ufw限制怎样解决?

5.4k

浏览量

1.1k

20

链接

79

用户

9

6

5

2

2

阅读时间

14 分钟

热门回复

总结

庄sir edwardzcn

17 天

很好的帖子。隐藏公网IP并不是所有VPS使用者的共同安全需求,有一个胡诌的针对未来(指ipv6广泛使用)的方案就是只暴露源站v6地址给CDN用,这样Censys这样强扫的工具耗时会很长,不过也还是要配白名单。

另,直接禁掉root登录 PermitRootLogin no 我也不常用,更习惯和其他sudoer一样配密钥然后禁止密码登录仅允许密钥登录。我是一般能操做线下集群的机子才会这么配,不然出个故障没root用不了了,比如存储满了远程ssh session都建立不了。 1 个回复

14 回复

Oganneson 大预言家

17 天

理论上PermitRootLogin是好的,但在服务器寄掉需要救援时就会变麻烦,我其实更推荐只关闭远程密码登录,保留本地密码登录,出问题时可以通过vnc或者ipmi本地登录root进行救援。贴一个我自用的sshd_config。

禁止 Root 用户通过密码远程登录

PermitRootLogin prohibit-password

关闭远程密码登录,允许密钥登录

PasswordAuthentication no PubkeyAuthentication yes AuthorizedKeysFile .ssh/authorized_keys

允许本地密码登录

UsePAM yes

禁用键盘交互认证

KbdInteractiveAuthentication no

允许 X11 转发

X11Forwarding yes

禁止显示登录消息

PrintMotd no

允许环境变量传递

AcceptEnv LANG LC_*

启用 SFTP 子系统

Subsystem sftp /usr/lib/openssh/sftp-server

防止超时断开

ClientAliveInterval 60 ClientAliveCountMax 3

禁用 DNS 反向解析,加快登录速度

UseDNS no

设置 SSH端口

Port 自拟

至于web服务的安全问题,我再补充一点,我的建议是善用容器化技术进行隔离,尽可能把应用放进docker。如非必要,容器只在本地监听,直接断绝ip+端口访问的可能。nginx拒绝ip访问,对安全要求更高的话可以像我一样再套上WAF+蜜罐。WAF可以挡住大部分自动化脚本的扫描,有预谋的入侵也更容易先触动蜜饵,给防御留出时间。

image 1667×815 91 KB

无论如何,不要在公网裸奔!!

4 个回复

heart

+1

45

回复

智子 sophon Regular

17 天

感谢分享。!!!

7 回复

MiniStep

17 天

谢谢分享,一直在琢磨安全问题

4 回复

Mira

17 天

感谢大佬科普

12 回复

fx fx318

17 天

感谢 分享 点赞

6 回复

jingyao jy06 大预言家

17 天

感谢佬友分享

37 回复

Aitilos

17 天

感谢大佬科普

10 回复

sureai Regular

17 天

感谢分享,vps安全很重要

19 回复

大帅哥 handsome 种子用户

17 天

感谢大佬教程

15 回复

tyoa

17 天

感谢 ,现已加入我的收藏,太有用了

12 回复

真诚、友善、团结、专业 jonntd 浴火重生

17 天

感谢分享大佬厉害啊

6 回复

章北海 alertsc 文化宣导员

17 天

渡鸦95676:

ssl_reject_handshake on;

试了一下报错。nginx: [emerg] unknown directive “ssl_reject_handshake” 1 个回复

8 回复

渡鸦95676 Raven95676 Regular 章北海 17 天

首先请检查nginx版本是否大于等于1.19.4。 ssl_reject_handshake on; 在nginx 1.19.4 主线版加入(参见: https://www.oschina.net/news/119594/nginx-1-9-4-released)

如果是通过源代码编译安装的,请确认ngx_http_ssl_module模块是否启用。 该模块不是默认构建的,需要通过 --with-http_ssl_module 配置参数来启用。 1 个回复

4 回复

章北海 alertsc 文化宣导员 渡鸦95676 17 天

谢谢。才注意到ubuntu默认的源Nginx版本很老,停留在1.18了。直接添加官方源还不能upgrade,还有依赖需要处理。

11 回复

britny dewiop22

17 天

感觉把自己的ip藏好很重要

13 回复

中文网络寻呼机🔰 OICQ 文化宣导员

17 天

渡鸦95676:

UFW 防火墙

成功连接 ssh 的也记一下日志备查比较好

ufw allow log 22/tcp 2 个回复

7 回复

mycbxzd Regular

17 天

感谢大佬分享,很有用,收藏了

20 回复

kendo Regular

17 天

很有用,我还加了一个在登录ssh时候自动发通知到企业微信机器人,以防偷家不知道 2 个回复

10 回复

章北海 alertsc 文化宣导员 中文网络寻呼机🔰 17 天

首先就要把22端口改了。 2 个回复

4 回复

中文网络寻呼机🔰 OICQ 文化宣导员

章北海 17 天

这是参照原帖里的基础上补充~

实际端口一般登上去就会改掉 1 个回复

4 回复

Oganneson 大预言家

17 天

再写一点关于docker的问题吧,其实没必要用ufw来管理docker的端口开放,docker会自己写入iptables规则用以管控端口,以docker compose为例:

  1. 对于数据库或者redis之类仅在应用内使用的服务:

仅在容器内部网络内开放,compose拉起时会创建一个名为 第一个服务名_default 的bridge,可以用 docker network ls 查看。

容器默认对该内部网络开放所有端口。

同一网络内的其他容器可以通过容器名和端口访问该服务。

没有加入该网络的容器无法访问任何端口。

对于仅在内部网络中暴露端口的服务, 无需 在 ports 下指定任何映射

  1. 对于需要进行反代的服务:

仅在127.0.0.1监听即可防止外部端口访问,在对应容器处使用

ports:

  • 127.0.0.1:端口:端口
  1. 对于需要外部直接访问端口的服务:

直接使用

ports:

  • 端口:端口

同样的,贴一个示例compose.yml

services: rsshub: image: diygod/rsshub:latest restart: always ports:

  • 127.0 .0 .1 :1200:1200 environment: NODE_ENV: production CACHE_TYPE: redis REDIS_URL: "redis://redis:6379/" PUPPETEER_WS_ENDPOINT: "ws://browserless:3000" env_file:
  • .env healthcheck: test: [ "CMD" , "curl" , "-f" , "http://localhost:1200/healthz" ] interval: 30s timeout: 10s retries: 3 depends_on:
  • redis
  • browserless

browserless: image: browserless/chrome restart: always ulimits: core: hard: 0 soft: 0 healthcheck: test: [ "CMD" , "curl" , "-f" , "http://localhost:3000/pressure" ] interval: 30s timeout: 10s retries: 3

redis: image: redis:alpine restart: always volumes:

  • ./data:/data healthcheck: test: [ "CMD" , "redis-cli" , "ping" ] interval: 30s timeout: 10s retries: 5 start_period: 5s

sb: image: ghcr.io/sagernet/sing-box container_name: sb restart: always volumes:

  • ./sing-box:/etc/sing-box/ command: -D /var/lib/sing-box -C /etc/sing-box/ run

1 个回复

14 回复

onezerotwofourzero 10240 海纳百川

17 天

mark一下 感谢大佬分享,很有用!!

4 回复

标签 11月 23 日 更新

#精华神帖添加

litchi MrliuXing520 圆圆满满

17 天

感谢分享。佬友

20 回复

sam_s 海纳百川

17 天

感谢大佬的分享~

7 回复

ODXUNIL ODXUNI1

17 天

感谢大佬分享

2 回复

jackpot0

16 天

学到了

5 回复

Proletarian

16 天

渡鸦95676:

1panel

十分详细,感谢!

4 回复

vodja zomco

16 天

感谢大佬分享

4 回复

Klaus

16 天

感谢大佬风险

11 回复

CHEN EDWINCHENC 种子用户

16 天

精华神帖!。

5 回复

nightmare

16 天

实用好贴,感谢大佬分享

1 回复

beary

15 天

感谢佬的分享,收藏了

2 回复

CNM 大预言家

1 15 天

太长不看之快速解决版:

入站关闭除 443 外所有端口

配置入站 ip 和出站 ip 白名单为 cf 的 ipv4,限制出站 ip 是为了防反弹 shell(但你似乎必须使用 cf 的 dns)

配置 ssl证书 并打开 cf 小黄云,ssl 完全

完事 甚至顺便防了 ddos

18 回复

jimmyrogue liangtao92 种子用户

15 天

感谢楼主分享,很有收获

5 回复

lxwh 大预言家

15 天

建议楼主排版加一下目录,这样子会更加清晰明了 1 个回复

5 回复

渡鸦95676 Raven95676 Regular lxwh 15 天

已添加目录功能 1 个回复

8 回复

lxwh 大预言家

渡鸦95676 15 天

nice, good !!

3 回复

二进制 xzc

15 天

建议很不错,有些我在Debian也可以使用

4 回复

libook 银笔杆

15 天

另外建议也不要将普通用户加入sudoer,而是/usr/bin/su root,然后用root密码切换到root用户进行管理操作。

sudo会使用当前用户自己的密码,如果当前用户的密码泄漏了,就可以用于提权到root。

使用su的完整路径可以避免运行潜在的攻击者植入的su。 1 个回复

5 回复

Milo povvoq

15 天

写的真好。我看还有直接上来就把SSH端口干成非22再把对应的22端口火墙改了的。

6 回复

Staleness Regular

15 天

学习下大佬的思路

我办公室的网络是固定ip,VPS运营商的防火墙开22端口然后指定IP地址,这样以后需要别的IP访问的话,直接添加IP即可 1 个回复

3 回复

章北海 alertsc 文化宣导员 kendo 14 天

这个怎么设置。很有用。 1 个回复

9 回复

beyonca

14 天

渡鸦95676:

Fail2ban

很好的贴子,但我有2个疑问。

既然配置了密匙登录就没必要再上 Fail2ban了吧。

另外如何使用ufw来仅允许某个省的IP段访问呢,这样设置对单IP用户极为友好,苦于找不到办法和符合的IP段 1 个回复

5 回复

FrancisLiu Regular Oganneson 14 天

呐,这个就叫专业,感谢大佬分享

7 回复

You are fired yonxinli Regular

14 天

很好很专业,感谢佬友分享

3 回复

渡鸦95676 Raven95676 Regular beyonca 14 天

不排除有不设置密钥登陆仅需要使用Fail2ban的用户。

可以通过 sudo ufw allow from cidr to any proto tcp port 22 允许来自于特定cidr段端口22的流量,改成别的端口记得换。

需要某个省的cidr段可以看看 GitHub - metowolf/iplist: 📖 IP CIDRs List / IP 地址列表 但本人未验证其有效性,谨慎使用。 1 个回复

1 回复

XiaoLin Lin_Xiao 大预言家

14 天

感谢大佬分享

回复

fugui

14 天

找了很久的方法,谢谢

4 回复

kendo Regular

章北海 14 天

我也忘记怎么设置了,当时问gpt的,我是发送给企业微信机器人的,所以调用很简单,你可以根据你的通知渠道,然后问问gpt,比如

我需要设置监听,在用户登录ssh时候发送通知,curl 'https : //qyapi.weixin.qq.com/cgi-bin/webhook/send?key=123456789' \ -H 'Content -Type: application/json'
-d ' { "msgtype" : "text" , "text" : { "content" : "hello world" } }'

1 个回复

1 回复

SG TH9

14 天

感谢分享,学习了,先赞后看

2 回复

章北海 alertsc 文化宣导员 kendo 14 天

没用过企业微信机器人。可以配置个人微信机器人吗? 2 个回复

2 回复

Mr.C CossX

14 天

多谢科普~ 紫薯布丁.exe

1 回复

beyonca 渡鸦95676 14 天

如果有很多cidr段,需要一行行的重复书写吗,比如

1.0.1.0/24

1.0.2.0/23

1.0.8.0/21

1.0.32.0/19

1.1.0.0/24

1.1.2.0/23

1.1.4.0/22

1.1.8.0/21

1.1.16.0/20

1.1.32.0/19

1.2.0.0/23

1.2.2.0/24

1.2.5.0/24

1.2.6.0/23

1.2.8.0/21

1.2.16.0/20

1.2.32.0/19

1.2.64.0/18

1.3.0.0/16

1.4.1.0/24

1.4.2.0/23 2 个回复

2 回复

Lao Qian waqian

14 天

登上去第一件事就是改SSHD的 端口并修改防火墙,22全是猜密码的请求。

有个小技巧,就是改端口并重启 sshd后当前的连接并没有断,向新端口发请求,能连上就是修改正确,要是不能建立新连接,还可以改回来,或查下防火墙的配置。

有的VPS有两层防火墙的(主机是通过NAT对外服务),有个web网页管理对外的防火墙,楼主讲的都是本机的防火墙,只改本机的不生效。 2 个回复

4 回复

kendo Regular

章北海 14 天

额,不知道还有个人微信机器人这东东。可以开通个企微,挺简单的。或者看看server酱有没有合适你的 1 个回复

1 回复

kendo Regular

章北海 14 天

我看楼主有写了我这通知的教程了,可以看看

2 回复

渡鸦95676 Raven95676 Regular beyonca 14 天

每一个cidr段都要写一行命令

回复

废品 feipinxiang

14 天

问个问题,root配12位以上复杂密码+Fail2ban错3次封60分钟,还有必要开其他用户禁root登录么? 1 个回复

回复

渡鸦95676 Raven95676 Regular 废品 14 天

如果佬友认为需要开,就可以开

1 回复

Eliot.H 大预言家

14 天

太全了,感谢分享,Mark好找

回复

youtobe youto 文化宣导员

14 天

这就是专业!感谢佬友分享!

回复

zhouzhou爸 grassroadsZ

14 天

留痕有用留痕

3 回复

Dr.X 圆圆满满

14 天

懒人可以用 1Panel,这些操作都是一键搞定

1 回复

Wink

14 天

学到了 学到了

2 回复

lida

14 天

感谢分享~ ~ 点赞

4 回复

quant Seatable

14 天

非常好的新手入门server篇

7 回复

这是 cat 首次发帖 - 让我们欢迎他/她加入社区吧!

cat api Oganneson 14 天

插眼马克马克

3 回复

有容 pama 大预言家

1 14 天

看了一下,总结的很到位,也是我目前玩机的方案。补充个Docker端口相关的,

需要Nginx/Caddy等反代的服务,在Compose文件里可以配置一个Docker专用的172开头的内网ip,且不配置端口。这样Docker就不会暴露公共端口,反代地址写 内网ip:默认端口即可。

比如MySQL的Compose文件配置,指定了使用内网IP为 172.20.0.15 ,注释了端口映射,在配置反向代理时 直接反代 172.20.0.15:3306 即可。

networks: default: external: true name: ${DOCKER_MY_NETWORK} services: mysql: container_name: mysql8 image: mysql:8

ports:

- "3306:3306"

environment: TZ: Asia/Shanghai networks: default: ipv4_address: 172.20 .0 .15 restart: unless-stopped

1 个回复

4 回复

( ⩌ ˰ ⩌) Bee 种子用户

beyonca 14 天

像 cf 有 api 可以取得,就可以写脚本自动每天执行一次:

避免网站被攻击的低成本想法 开发调优

分享一个 shell 脚本,执行后更新 CF IP 到 ufw 443。 (前提当然是你的鸡能存取 cloudflare.com) 脚本在添加时会带有 Cloudflare IP 注解,删除时条件判断也是注解,所以不会影响其他自己设定的规则 RULES=$(sudo ufw status numbered | grep 'Cloudflare IP' | awk -F"[][]" '{pri…

没 api 确实自己一行一行加,或者先在文字编辑器里面复制贴上好,用 &&

ufw allow from 1.1 . 51.0 / 24 to any port 3322 && ufw allow from 1.1 . 52.0 / 24 to any port 3322

6 回复

flyaway

14 天

感谢分享,nginx 的 ssl_reject_handshake 刚刚学到了,试看看去~

回复

model

14 天

感谢大神 有没有一键脚本

4 回复

gowinder

14 天

真是不错,收藏了, 已经把fail2ban应用了. 谢谢

4 回复

渡鸦95676 Raven95676 Regular Lao Qian 14 天

渡鸦95676:

如果 VPS 厂商提供了防火墙功能,且没有复杂的需求,可以忽略本节内容并使用 VPS 厂商提供的防火墙。

VPS厂商提供的防火墙用法及功能各有不同,故本帖仅指出可以使用。

Lao Qian:

有的VPS有两层防火墙的(主机是通过NAT对外服务),有个web网页管理对外的防火墙,楼主讲的都是本机的防火墙,只改本机的不生效。

请首先检查防火墙是否处于启用状态。如果是UFW,请检查是否已执行 sudo ufw enable 。

在正确配置的情况下,即使外层防火墙存在,操作系统的防火墙仍然能控制本机流量。如果无法控制,可能是 VPS 厂商进行了特殊设置。

4 回复

Undefined_Lee 圆圆满满

14 天

感谢技术分享!

8 回复

章北海 alertsc 文化宣导员 kendo 14 天

我的疑问是为啥必须是微信群机器人。这种只有我需要接受通知的场景不能像TG bot一样就是一个通知机器人吗?为了收消息我还得建一个两人的群,还要遵守各种群管理规则? 3 个回复

2 回复

0x26e7d 圆圆满满

14 天

学习了, 感谢分享

1 回复

渡鸦95676 Raven95676 Regular 章北海 14 天

没有必须是哪个平台,只要有api能够调用就行。

3 回复

kendo Regular

章北海 14 天

额,我只是说我用的是企业微信机器人而已,作用是举例,不代表你一定要用这个的。你可以用任意一个通知渠道都行的,完全可以用 TG bot

4 回复

培哥 plnl

13 天

感谢分享。佬友

6 回复

萧亦行 xiaoyixing

13 天

谢谢大佬,学到了很多,我这就去加强一下防御

3 回复

weijordan Oganneson 13 天

感谢分享,vps安全 插眼

15 回复

Thomas Kay Thomas 种子用户

12 天

server { listen 443 ssl default_server; server_name _; ssl_reject_handshake on ; }

非常有用,避免还要给ssl default_server套一个证书,如果不套的话,cf这边直接525.

回复

niko zqingdut

11 天

运维狂喜,Mark

回复

Se sevendays

10 天

我之前还会进行禁止ping的设置。

  1. 使用 iptables 禁止ping
  • 查看当前iptables规则:

  • iptables -L -n

  • 这条命令可以列出当前iptables的规则,-L表示列出规则,-n表示以数字形式显示 IP 地址和端口号,而不是解析为主机名和服务名。

  • 禁止 ping(入站 ICMP Echo Request):

  • iptables -A INPUT -p icmp --icmp - type 8 -j DROP

  • 这里-A INPUT表示在INPUT链(用于处理进入本机的数据包)的末尾添加一条规则。-p icmp指定协议为 ICMP,--icmp - type 8表示 ICMP 类型为 8(即 Echo Request),-j DROP表示将匹配的数据包丢弃。

  • 保存iptables规则(如果需要永久生效):

  • 对于不同的 Linux 发行版,保存iptables规则的方式不同。

  • 在 CentOS 等基于 RHEL 的系统中,可以使用service iptables save命令来保存规则。这条命令会将当前的iptables规则保存到/etc/sysconfig/iptables文件中,这样在系统重启后规则依然生效。

  • 在 Ubuntu 等 Debian 系系统中,需要安装iptables - persistent软件包。安装后可以使用iptables - save > /etc/iptables/rules.v4(对于 IPv4 规则)来保存规则,这样在系统重启后也能恢复规则。

  • 恢复 ping 功能 如果要恢复 ping 功能,可以删除刚才添加的禁止 ping 的规则。使用iptables -D INPUT -p icmp --icmp - type 8 -j DROP命令。其中-D INPUT表示从INPUT链中删除规则,其他参数和添加规则时相同。

  1. 使用 firewalld 禁止 ping
  • 查看firewalld状态:

  • systemctl status firewalld

  • 这条命令可以查看firewalld防火墙的状态,包括是否正在运行等信息。

  • 禁止 ping:

  • 对于firewalld,可以通过设置区域规则来禁止 ping。例如,对于默认的public区域,可以使用firewalld - cmd --permanent --zone = public --add - rich - rule='rule family="ipv4" protocol="icmp" drop'

  • 这里--permanent表示永久设置(需要重新加载firewalld才能生效),--zone = public指定操作的区域为public,--add - rich - rule用于添加一条复杂的规则,在这个规则中rule family="ipv4" protocol="icmp" drop表示对于 IPv4 协议的 ICMP 流量进行丢弃操作。

  • 重新加载firewalld使规则生效:

  • firewalld - cmd --reload

恢复 ping 功能 要恢复 ping 功能,可以删除刚才添加的禁止 ping 的规则。使用firewalld - cmd --permanent --zone = public --remove - rich - rule='rule family="ipv4" protocol="icmp" drop',然后重新加载firewalld(firewalld - cmd --reload)。

  1. 使用UFW禁止ping
  • 要禁止 ping,需要阻止 ICMP 的 Echo Request 数据包。可以使用以下 UFW 命令:

  • sudo ufw deny in icmp

  • 这条命令会拒绝所有入站(in)的 ICMP 数据包,从而禁止其他主机 ping 本机。

  • 如果要恢复 ping 功能,可以使用以下命令:

  • sudo ufw delete deny in icmp

  • 这条命令会删除之前设置的拒绝入站 ICMP 数据包的规则,这样其他主机就可以再次 ping 本机了。

在网上摘抄了一下,希望有用。 2 个回复

1 回复

Minecraft 种子用户

10 天

谢谢整理分享,非常实用

回复

渡鸦95676 Raven95676 Regular

1 Se 10 天

ufw本身没有直接支持阻止icmp协议的命令。ufw在/etc/ufw/before.rules中定义了针对ping的允许规则,我们可以修改ACCEPT为DROP来达成禁止ping的目的:

ok icmp codes for INPUT

  • A ufw-before- input - p icmp --icmp-type destination-unreachable -j DROP
  • A ufw-before- input - p icmp --icmp-type time -exceeded -j DROP
  • A ufw-before- input - p icmp --icmp-type parameter-problem -j DROP
  • A ufw-before- input - p icmp --icmp-type echo-request -j DROP

ok icmp code for FORWARD

  • A ufw-before-forward - p icmp --icmp-type destination-unreachable -j DROP
  • A ufw-before-forward - p icmp --icmp-type time -exceeded -j DROP
  • A ufw-before-forward - p icmp --icmp-type parameter-problem -j DROP
  • A ufw-before-forward - p icmp --icmp-type echo-request -j DROP

2 个回复

1 回复

Se sevendays 渡鸦95676 10 天

感谢改正在网上搜到的ufw 禁止ping还没有进行验证

回复

alisa elisa

10 天

感谢热心的大佬,小白的VPS终于安全了

回复

有容 pama 大预言家 章北海 6 天

因为微信不开放,不提供TG bot这样的功能/接口。而企微群机器人在一定程度上能实现需求

回复

海贼·王师傅 SilversRayleigh

3 天

感谢大佬分享

回复

luosan 圆圆满满

2 天

感谢分享~~

回复

turei

2 天

其实可以都走 cloudflare tunnel 出去

这样不用担心被扫

回复

flyespace

2 天

讲的很全面啊,学习学习

回复

wordpure

1 天

建议在 /etc/ssh/sshd_config.d/ 创建一个 conf 文件来自定义 sshd 配置,而不是直接编辑 /etc/ssh/sshd_config ,防止 OpenSSH 更新后配置冲突。

参考: ssh - PasswordAuthentication no, but I can still login by password - Unix & Linux Stack Exchange

图片 1454×1325 193 KB

有些云服务商为了启用远程密码登录(sshd 默认禁用 ),会在 /etc/ssh/sshd_config.d/ 自定义一个 conf 文件,修改 sshd 配置前先要排除它们的干扰。

查看 sshd_config.d 是否存在其他 conf 文件

sudo ls /etc/ssh/sshd_config.d/*.conf

如果存在,重命名,防止后续自定义配置被覆盖

sudo mv /etc/ssh/sshd_config.d/xxx.conf /etc/ssh/sshd_config.d/xxx.conf.bak

比如 CloudCone 就有一个 /etc/ssh/sshd_config.d/50-cloud-init.conf

图片 1028×305 11.3 KB

sshd 配置修改完,先用 sudo sshd -T 看一下有效配置,免得被覆盖了都不知道 。

Root 用户登录方式

sudo sshd -T | grep -i "PermitRootLogin"

密码认证

sudo sshd -T | grep -i "PasswordAuthentication"

ssh 端口

sudo sshd -T | grep -i "Port"

值得一提的是, prohibit-password 是 without-password 的别名,所以看到下面的输出是正常现象。

图片 1111×91 8.94 KB

参考:

Permit root to login via ssh only with key-based authentication - Unix & Linux Stack Exchange

OpenSSH 7.0 更新日志

1 个回复

1 回复

玛奇玛 Aopex Regular

1 天

满满的干货啊,最近正在学习用VPS,先mk了,感谢佬友的教程

回复

wordpure

1 天

渡鸦95676:

Enter passphrase (empty for no passphrase): # 可以留空,也可以设置

本地不一定安全,最好设置一个高强度的随机密码,这样电脑被黑别人用不了私钥。

渡鸦95676:

然后我们给这个用户设置一个至少为 16 位的随机大小写字母 + 数字的密码(个人建议的最低安全性需求):

建议把 root 用户的密码也改掉,云服务器的默认密码强度还是差点,而且有些服务商会通过邮件来发送默认密码,不太安全。 2 个回复

1 回复

yvesyc

20 小时

好贴,跟着好好学习主机安全。

回复

wang12345

18 小时

感谢大佬分享,很有用,收藏了

回复

西红柿 huangyzzz

6 小时

感谢分享!学到了

回复

NgMfkS wordpure 5 小时

我用的那个直接工单给你明文密码

回复

分享

加入书签

举报

回复

已取消置顶

常规

您会在别人 @ 您或回复您时收到通知。

推荐

相关

新话题和未读话题

话题列表,带有按钮的列标题可以排序。

话题

回复

浏览量

活动

基于Cloudflare Worker部署的在线剪切板,支持markdown和文件分享(优化更新9) 151

开发调优

配置优化 Cloudflare

160

5.0k

18 小时

【配置优化】我拿到VPS服务器必做的那些事 13

开发调优

325

11.1k

7 天

教育邮箱申请 52

开发调优

快问快答

136

5.3k

11月 5 日

域名注册交流 1

开发调优

28

2.2k

10月 29 日

佬们,有没有坚果云的平替 1

开发调优

快问快答

30

992

10月 19 日

有 116 个未读 话题 和 156 个新 话题,

或浏览 开发调优 中的其他话题

'>

相关文章