将web服务绑定在 1024 以下的端口上

文章目录

  • [操作系统:Alibaba Cloud Linux 3.2104 LTS 64位](#操作系统:Alibaba Cloud Linux 3.2104 LTS 64位)
    • 问题分析
    • 解决方案
      • [方案 1:使用 sudo 运行(最简单)](#方案 1:使用 sudo 运行(最简单))
        • [实践 1:使用 node 的完整路径](#实践 1:使用 node 的完整路径)
        • [实践 2:保留 PATH 环境变量](#实践 2:保留 PATH 环境变量)
        • [实践 3:创建软链接(一劳永逸)](#实践 3:创建软链接(一劳永逸))
      • [方案 2:使用非特权端口(推荐)](#方案 2:使用非特权端口(推荐))
      • [方案 3:使用 systemd capabilities](#方案 3:使用 systemd capabilities)
      • [方案 4:为当前用户提权](#方案 4:为当前用户提权)
        • [提权方式 1:给 Node.js 授予特权端口绑定能力(推荐)](#提权方式 1:给 Node.js 授予特权端口绑定能力(推荐))
        • [提权方式 2:将用户添加到 sudo 免密码组](#提权方式 2:将用户添加到 sudo 免密码组)
        • [推荐使用方式 1](#推荐使用方式 1)
    • [推荐方案 2](#推荐方案 2)

操作系统:Alibaba Cloud Linux 3.2104 LTS 64位

比如,在443端口上启动服务时,会报错:

bash 复制代码
Error: listen EACCES: permission denied 0.0.0.0:443

问题分析

错误 EACCES: permission denied 0.0.0.0:443 是因为在 Linux 系统上,1024 以下的端口是特权端口,绑定这些端口需要 root 权限。

解决方案

有以下几种方式可以解决这个问题:

方案 1:使用 sudo 运行(最简单)

思路如下:(这只是思路,不能直接运行次命令,思路的详细实践在后文)

bash 复制代码
// 基于node.js的web应用 
sudo node server.js

如果直接运行以上命令会提示:

bash 复制代码
sudo: node: command not found

要特别注意: sudo 会重置环境变量 PATH,导致找不到 node 命令。

实践 1:使用 node 的完整路径

先找到 node 的安装路径:

bash 复制代码
which node

然后使用完整路径运行:

bash 复制代码
sudo $(which node) server.js

或者直接:

bash 复制代码
sudo /usr/bin/node serve.js

(路径根据实际 which node 的输出调整)

实践 2:保留 PATH 环境变量
bash 复制代码
sudo -E env "PATH=$PATH" node server.js
实践 3:创建软链接(一劳永逸)
bash 复制代码
sudo ln -s $(which node) /usr/local/bin/node

之后就可以直接使用:

bash 复制代码
sudo node server_zhaowei.js

推荐方法 2,最简单直接:

bash 复制代码
sudo -E env "PATH=$PATH" node server.js

方案 2:使用非特权端口(推荐)

通过环境变量指定一个大于 1024 的端口:

bash 复制代码
PORT=8443 node server_zhaowei.js

然后通过 Nginx 反向代理将 443 流量转发到 8443。

方案 3:使用 systemd capabilities

创建 systemd 服务并授予绑定特权端口的能力,无需 root 运行:

bash 复制代码
sudo setcap 'cap_net_bind_service=+ep' $(which node)

之后就可以用普通用户运行在 443 端口了。


方案 4:为当前用户提权

可以的,有两种主要方式:

提权方式 1:给 Node.js 授予特权端口绑定能力(推荐)

这是最安全的方式,只授予绑定端口的权限,而不是完整的 root 权限:

bash 复制代码
# 查找 node 路径
which node

# 授予绑定特权端口的能力
sudo setcap 'cap_net_bind_service=+ep' $(which node)

执行后,普通用户就可以直接运行:

bash 复制代码
node server_zhaowei.js

优点

  • 不需要 root 权限运行整个 Node.js 进程
  • 只授予绑定端口的特定权限
  • 安全性更高

提权方式 2:将用户添加到 sudo 免密码组

如果你希望当前用户使用 sudo 时不需要输入密码:

bash 复制代码
# 编辑 sudoers 文件
sudo visudo

# 在文件末尾添加(将 ecs-user 替换为你的用户名)
ecs-user ALL=(ALL) NOPASSWD: ALL

注意:这会给予用户完整的 root 权限,有一定安全风险。


推荐使用方式 1
bash 复制代码
sudo setcap 'cap_net_bind_service=+ep' $(which node)

执行后验证:

bash 复制代码
getcap $(which node)

如果输出类似 cap_net_bind_service+ep,说明设置成功,之后就可以直接用普通用户运行 443 端口的服务了。

#####方式1命令详细解析:

setcap 命令详解

setcap 是 Linux 用于设置**文件能力(Capabilities)**的命令。它允许对程序授予特定的权限,而不是给予完整的 root 权限。

命令结构
bash 复制代码
sudo setcap 'cap_net_bind_service=+ep' /path/to/node
各部分含义
部分 含义
sudo 需要 root 权限执行 setcap
setcap 设置文件能力的命令
cap_net_bind_service 允许绑定 1024 以下特权端口的能力
= 设置操作符
+ep 启用有效和许可标志
标志位说明
  • e (Effective) - 有效标志:程序运行时实际生效的能力
  • p (Permitted) - 许可标志:程序可以启用的能力
  • i (Inheritable) - 可继承标志:子进程可以继承的能力

+ep 表示:添加有效和许可标志,使程序运行时能够使用该能力。

为什么比 sudo 更安全?
方式 权限范围 安全性
sudo node 完整 root 权限(可读写任何文件、修改系统配置等)
setcap 仅授予绑定特权端口这一个能力

使用 setcap 后,Node.js 进程只能绑定特权端口,无法获得其他 root 权限,大大降低了安全风险。

常用能力列表
能力名称 作用
cap_net_bind_service 绑定 1024 以下端口
cap_net_raw 使用原始套接字
cap_sys_admin 系统管理操作
cap_chown 修改文件所有者
cap_dac_override 绕过文件权限检查

推荐方案 2

  • 更安全(不需要 root 权限运行 Node.js)
  • 更灵活(可以配合 Nginx 做负载均衡和 SSL 终止)
相关推荐
To_OC1 小时前
别再串行写 await 了,Promise.all 才是并行请求的正确打开方式
前端·javascript·promise
vipbic2 小时前
中后台越做越乱后,我用插件化把它救回来了
前端·vue.js
Hyyy2 小时前
Computer Use 适合做什么,不适合做什么——一次真实使用后的思考
前端
小和尚同志2 小时前
前端 AI 单元测试思考与落地
前端·人工智能·aigc
invicinble3 小时前
c端系统,其实更像一个信息展示平台
前端
李姆斯4 小时前
管理是否可以被完全量化
前端·产品经理·团队管理
名字还没想好☜5 小时前
Next.js 中间件实战:鉴权、重定向与 A/B 分流
开发语言·前端·javascript·中间件·react·next.js
广州灵眸科技有限公司5 小时前
瑞芯微RV1126B开发板(EASY-EAI-PI2) INI文件操作
java·前端·javascript·网络·人工智能
江华森6 小时前
Web 开发基础:HTTP 与 REST
前端·网络协议·http
IT_陈寒6 小时前
Redis的KEYS命令把我搞崩溃了,改用SCAN才活过来
前端·人工智能·后端