【openwrt】Openwrt系统新增普通用户指南

文章目录

    • [1 如何新增普通用户](#1 如何新增普通用户)
    • [2 如何以普通用户权限运行服务](#2 如何以普通用户权限运行服务)
    • [3 普通用户如何访问root账户的ubus服务](#3 普通用户如何访问root账户的ubus服务)
    • [4 其他权限控制](#4 其他权限控制)
    • [5 参考](#5 参考)

Openwrt系统在默认情况下只提供一个 root账户,所有的服务都是以 root权限运行的,包括 WebUI也是通过root账户访问的,如果你的Openwrt设备支持 WAN口访问WebUI,那么这里就有极大的安全风险,为了尽可能的降低这种风险,新增一个普通用户可能是一个比较合理的方案。

Openwrt系统实际上是支持多用户的,只不过我们需要进行一些必要的配置,本文接下来就会介绍Openwrt系统如何新增普通用户,以及如何控制普通用户访问权限相关知识。

本文所有内容均是基于 Openwrt23.05 + linux 5.15 版本介绍的。

1 如何新增普通用户

新增普通用户需要系统增加如下工具的支持

shell 复制代码
 # 必要工具
su adduser deluser passwd addgroup delgroup

# 可选工具
sudo

如果是手动编译的Openwrt源码,可以使用make menuconfig手动选择编译这些工具,这些工具在menuconfig中的位置如下。当然直接使用opkg直接安装也是可以的,大家按照自己方便的方式安装就行。

shell 复制代码
make menuconfig
> Base system 
	> Login/Password Management Utilities
		su adduser deuser passwd addgroup delgroup	
		
-> Administration 
	sudo

安装好工具后,下一步就可以在控制台(必须是root权限)新增用户了,这里以新增guest用户为例:

shell 复制代码
$ mkdir -p /home/guest
$ addgroup guest_g  # 创建一个guest_g用户组

# 新增guest用户,home目录为/home/guest,默认shell为/bin/ash
# -D 表示默认不分配密码,后续可以使用passwd命令给guest 用户设置密码
# -G guest_g 将guest加入guest_g用户组
$ adduser -h /home/guest -s /bin/sh -D -G guest_g  guest

# 给guest 用户设置密码 
$ passwd guest  # 需要连续输入2次密码

登录/登出guest 用户

shell 复制代码
$ su guest  # 由root账户切换到guest账户
$ exit   # 切换到guest用户后,可以直接使用exit命令返回root账户

这时候guest账户可以在控制台进行登陆了,但是WebUI还不能使用guest账户进行登录,还需要进行如下配置

shell 复制代码
# cat /etc/config/rpcd 
config rpcd
        option socket /var/run/ubus/ubus.sock
        option timeout 30

config login
        option username 'root'
        option password '$p$root'
        list read '*'
        list write '*'
 
 # 增加如下代码  
 config login
        option username 'guest'
        option password '$p$guest'
        list read '*'
        list write '*'

修改完上述配置后,需要执行reload_config让配置生效,之后webUI就可以使用guest账户进行登录了。

至此,openwrt添加普通用户的部分就已经讲完了,接下来继续介绍普通用户的一些权限控制问题。

2 如何以普通用户权限运行服务

当支持多用户之后,我们可能会有一些服务并不想(也没有必要)以root权限运行,所以我们需要以普通用户权限运行这些服务,这也是Openwrt系统支持的。

以普通用户权限运行服务配置方法也比较简单,在服务的启动脚本中新增一条命令即可

shell 复制代码
procd_set_param user guest # run service as user guest

完整示例如下:

shell 复制代码
#!/bin/sh /etc/rc.common
START=12

USE_PROCD=1
NAME=helloworld
PROG=/sbin/helloworld

start_service() {
	procd_open_instance
	procd_set_param command "$PROG" 
	procd_set_param respawn
	procd_set_param stdout 1   
    procd_set_param stderr 1   
    procd_set_param user guest # run service as user guest
	procd_close_instance
}

执行结果:

shell 复制代码
$ ps | grep helloworld
 1048 guest     1700 S    /sbin/helloworld

3 普通用户如何访问root账户的ubus服务

有时候,有些重要的服务程序必须要以root权限运行,而且这些服务可能会对外提供一些ubus method,如果希望以普通权限运行的服务 也能访问这些ubus method,那么就需要使用openwrt 提供的ACL(Access Control List)机制。

拿openwrt自带的系统服务为例,当我们以root账户登录并执行ubus list时,可以看到当前系统中所有的ubus method,示例如下:

shell 复制代码
# ubus list   # root账户执行,可以list出当前系统所有的ubus 对象
dhcp
dnsmasq
dnsmasq.dns
file
hostapd
hotplug.dhcp
hotplug.ieee80211
hotplug.iface
hotplug.neigh
hotplug.net
hotplug.ntp
hotplug.tftp
iwinfo
log
luci
luci-rpc
network
network.device
network.interface
network.interface.lan
network.interface.loopback
network.interface.wan
network.interface.wan6
network.rrdns
network.wireless
rc
service
session
system
uci

如果我们再切换到guest账户再次执行ubus list

shell 复制代码
guest@OpenWrt:~$ ubus list  
dnsmasq.dns

可以看到执行完ubus list后只出现了一个dnsmasq.dns,其他什么信息也没有,这是因为ubusd服务是以root权限运行的,ubusd会检查client是否有权限访问ubus总线,这也称为ACL检查,显然guest用户暂时没有权限访问ubus总线,所以也就看不到注册到ubus总线上面的method了。

那为什么这里会有一个dnsmasq.dns呢?这个放在最后解释。

不过openwrt也给出了相应的解决办法------ACL,我们可以加一条我们自己的ACL规则,让ubusd允许普通用户能够访问特定的ubus对象,示例如下:

json 复制代码
# cat /usr/share/acl.d/system_acl.json 
{
        "user": "guest",
        "access": {
                "system": {
                        "methods": [ "board", "info" ]
                }
        }
}

ACL规则文件统一放在 /usr/share/acl.d/目录下,它们是用json文件描述(需要注意json的语法格式),上述配置的作用是:允许guest用户访问system对象的boardinfo方法。
特别注意 :*.json 文件的权限必须是644,ubusd会检查该文件权限是否符合要求。

增加ACL规则后,可以执行如下命令让ubusd重新加载ACL文件(也可以直接reboot重启)

shell 复制代码
$ ps | grep ubusd
  716 ubus      1368 S    /sbin/ubusd
$ kill -1 716  # 给ubusd发送 SIGHUP(1)信号触发ubusd重启加载ACL文件

ubusd重新加载system_acl.json后,再次执行ubus list

shell 复制代码
$ ubus -v list  # 可以看到system对象的board 和 info 2个method了
'system' @5e41cdee
        "board":{}
        "info":{}
        
$ ubus call system 'board' # 调用 system->board method也是正常的 
{
        "kernel": "5.15.155",
        "hostname": "OpenWrt",
        "system": "ARMv8 Processor rev 4",
        "model": "Bananapi BPI-R64",
        "board_name": "bananapi,bpi-r64",
        "rootfs_type": "squashfs",
        "release": {
                "distribution": "OpenWrt",
                "version": "23.05-SNAPSHOT",
                "revision": "r23861+4-447eef2063",
                "target": "mediatek/mt7622",
                "description": "OpenWrt 23.05-SNAPSHOT r23861+4-447eef2063"
        }
}

如果需要同时添加多个method的访问权限,也可以一次性新增多个:

shell 复制代码
{
        "user": "guest",
        "access": {
                "system": {
                        "methods": [ "board", "info" ]
                },
                "log": {
                        "methods": ["read"]
                },
                "network":{
                        "methods":["restart","reload"]
                },
                "network.device":{
                        "methods":["status"]
                }
        }
}

最后,就回到刚开始dnsmasq.dns的问题了,首先这个dnsmasq.dns并不是一个ubus method,它是一个ubus subscribe,也就是订阅服务,其他client 如果对此事件感兴趣,可以订阅它,当对应的事件发生时,client就会收到通知消息。

为什么guest用户没有添加任何ACL规则,就可以看到它呢?因为所见不一定所得,看到不一定可用。

shell 复制代码
$ ubus list
dnsmasq.dns
$ ubus subscribe dnsmasq.dns   # 尝试订阅这个服务
Error while registering for event 'dnsmasq.dns': Not found  

尝试订阅这个服务,却提示Not found ,其本质原因还是权限问题,解决这个问题的方法还是添加ACL规则,可以继续添加到之前的json中:

json 复制代码
{
        "user": "guest",
        "access": {
                "system": {
                        "methods": [ "board", "info" ]
                },
                "log": {
                        "methods": ["read"]
                },
                "network":{
                        "methods":["restart","reload"]
                },
                "network.device":{
                        "methods":["status"]
                }
        },
        "subscribe":[
                "dnsmasq.dns",
        ]
}

添加subscribe的规则后,触发ubusd重载ACL文件,然后再次订阅,一切正常。

shell 复制代码
$ ubus list
dnsmas
q.dns
log
network
network.device
system
guest@OpenWrt:/root$ ubus subscribe dnsmasq.dns

如果需要添加多个订阅的对象,接着"dnsmasq.dns"后面新增即可。

4 其他权限控制

限制普通用户可执行的命令,例如限制普通用户执行reboot、shutdown、poweroff、mount等指令。

限制普通用户可访问/修改的文件,例如禁止普通用户访问 /etc/config/system配置文件。

这些基本上都可以通过chmod指令来配置,这部分就不再做详细介绍。

5 参考

为 OpenWrt 增加用户且开放访问 WebUI 权限
UBUS ACL
Procd Service Parameters

相关推荐
一叶知秋yyds9 天前
openwrt 系统下通过命令行设置允许wan口进行Luci页面的访问
网络·openwrt·luci 开启wan 口访问
st78020611 天前
Debian 13.1 下编译Openwrt24
运维·debian·openwrt
WTCLLB1 个月前
netgear r6220 路由器,刷openwrt后,系统备份还原
linux·网络·智能路由器·openwrt
郁大锤1 个月前
OpenWrt 的 Overlay 文件系统到底是怎么回事?
openwrt
棒棒的唐3 个月前
winscp 连openwrt 返回127错误码
openwrt·winscp
江西省遂川县常驻深圳大使4 个月前
小米路由器3C刷OpenWrt,更换系统/变砖恢复 指南
智能路由器·openwrt·小米路由器
低温热源5 个月前
Openwrt基本初始化(安装中文包,磁盘扩容)
openwrt
草上爬5 个月前
OpenWrt:使用ALSA实现边录边播
ubuntu·openwrt·record·alsa·play
JASON丶LI5 个月前
家庭路由器改装,搭建openwrt旁路由以及手机存储服务器,实现外网节点转发、内网穿透、远程存储、接入满血DeepSeek方案
服务器·物联网·容器·智能路由器·openwrt
lepton_yang6 个月前
Openwrt下使用ffmpeg配合自建RTSP服务器实现推流
ffmpeg·openwrt·视频服务器