mirror of
https://github.com/openwrt/packages.git
synced 2025-12-21 21:24:31 +04:00
adguardhome: run as an unprivileged user
Run AdGuard Home without superuser privileges, by granting the binary capabilities through ujail. AdGuard Home writes new config files, so it must have r/w access to the directory where these files live. Which means existing configs must be migrated to a new directory, /etc/adguardhome, by default. CAP_NET_BIND_SERVICE and CAP_NET_RAW capabilities are based on the official documentation linked below. Link: https://github.com/AdguardTeam/AdGuardHome/wiki/Getting-Started#running-without-superuser-linux-only Signed-off-by: George Sapkin <george@sapk.in>
This commit is contained in:
committed by
Tianling Shen
parent
79f78c0e77
commit
754a9908f4
@@ -7,7 +7,7 @@ include $(TOPDIR)/rules.mk
|
|||||||
|
|
||||||
PKG_NAME:=adguardhome
|
PKG_NAME:=adguardhome
|
||||||
PKG_VERSION:=0.107.64
|
PKG_VERSION:=0.107.64
|
||||||
PKG_RELEASE:=1
|
PKG_RELEASE:=2
|
||||||
|
|
||||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||||
PKG_SOURCE_URL:=https://codeload.github.com/AdguardTeam/AdGuardHome/tar.gz/v$(PKG_VERSION)?
|
PKG_SOURCE_URL:=https://codeload.github.com/AdguardTeam/AdGuardHome/tar.gz/v$(PKG_VERSION)?
|
||||||
@@ -46,10 +46,11 @@ define Package/adguardhome
|
|||||||
TITLE:=Network-wide ads and trackers blocking DNS server
|
TITLE:=Network-wide ads and trackers blocking DNS server
|
||||||
URL:=https://github.com/AdguardTeam/AdGuardHome
|
URL:=https://github.com/AdguardTeam/AdGuardHome
|
||||||
DEPENDS:=$(GO_ARCH_DEPENDS) +ca-bundle
|
DEPENDS:=$(GO_ARCH_DEPENDS) +ca-bundle
|
||||||
|
USERID:=adguardhome=853:adguardhome=853
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define Package/adguardhome/conffiles
|
define Package/adguardhome/conffiles
|
||||||
/etc/adguardhome.yaml
|
/etc/adguardhome/adguardhome.yaml
|
||||||
/etc/config/adguardhome
|
/etc/config/adguardhome
|
||||||
endef
|
endef
|
||||||
|
|
||||||
@@ -72,14 +73,20 @@ endef
|
|||||||
|
|
||||||
define Package/adguardhome/install
|
define Package/adguardhome/install
|
||||||
$(call GoPackage/Package/Install/Bin,$(1))
|
$(call GoPackage/Package/Install/Bin,$(1))
|
||||||
|
$(INSTALL_DIR) $(1)/etc/capabilities
|
||||||
|
$(INSTALL_CONF) ./files/adguardhome.json $(1)/etc/capabilities/adguardhome.json
|
||||||
|
|
||||||
|
$(INSTALL_DIR) $(1)/etc/config
|
||||||
|
$(INSTALL_CONF) ./files/adguardhome.config $(1)/etc/config/adguardhome
|
||||||
|
|
||||||
$(INSTALL_DIR) $(1)/etc/init.d
|
$(INSTALL_DIR) $(1)/etc/init.d
|
||||||
$(INSTALL_BIN) ./files/adguardhome.init $(1)/etc/init.d/adguardhome
|
$(INSTALL_BIN) ./files/adguardhome.init $(1)/etc/init.d/adguardhome
|
||||||
|
|
||||||
$(INSTALL_DIR) $(1)/etc/config
|
|
||||||
$(INSTALL_DATA) ./files/adguardhome.config $(1)/etc/config/adguardhome
|
|
||||||
|
|
||||||
$(INSTALL_DIR) $(1)/etc/sysctl.d
|
$(INSTALL_DIR) $(1)/etc/sysctl.d
|
||||||
$(INSTALL_CONF) ./files/adguardhome.sysctl $(1)/etc/sysctl.d/50-adguardhome.conf
|
$(INSTALL_CONF) ./files/adguardhome.sysctl $(1)/etc/sysctl.d/50-adguardhome.conf
|
||||||
|
|
||||||
|
$(INSTALL_DIR) $(1)/etc/uci-defaults
|
||||||
|
$(INSTALL_BIN) ./files/adguardhome.defaults $(1)/etc/uci-defaults/adguardhome
|
||||||
endef
|
endef
|
||||||
|
|
||||||
$(eval $(call Download,adguardhome-frontend))
|
$(eval $(call Download,adguardhome-frontend))
|
||||||
|
|||||||
@@ -1,5 +1,12 @@
|
|||||||
config adguardhome config
|
config adguardhome 'config'
|
||||||
option config /etc/adguardhome.yaml
|
# All paths except for PID must be readable by the configured user
|
||||||
|
option config '/etc/adguardhome/adguardhome.yaml'
|
||||||
# Where to store persistent data by AdGuard Home
|
# Where to store persistent data by AdGuard Home
|
||||||
option workdir /var/lib/adguardhome
|
option workdir '/var/lib/adguardhome'
|
||||||
option pidfile /run/adguardhome.pid
|
option pidfile '/run/adguardhome.pid'
|
||||||
|
option user 'adguardhome'
|
||||||
|
option group 'adguardhome'
|
||||||
|
option verbose '0'
|
||||||
|
# Files and directories that AdGuard Home has read-only access to
|
||||||
|
# list jail_mount '/etc/ssl/adguardhome.crt'
|
||||||
|
# list jail_mount '/etc/ssl/adguardhome.key'
|
||||||
|
|||||||
93
net/adguardhome/files/adguardhome.defaults
Normal file
93
net/adguardhome/files/adguardhome.defaults
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
OLD_CONFIG_FILE=$(uci -q get adguardhome.config.config)
|
||||||
|
OLD_CONFIG_FILE=${OLD_CONFIG_FILE:-/etc/adguardhome.yaml}
|
||||||
|
NEW_CONFIG_DIR=/etc/adguardhome
|
||||||
|
NEW_CONFIG_FILE="$NEW_CONFIG_DIR/adguardhome.yaml"
|
||||||
|
|
||||||
|
start_service() {
|
||||||
|
if ! /etc/init.d/adguardhome running; then
|
||||||
|
/etc/init.d/adguardhome start
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
stop_service() {
|
||||||
|
if /etc/init.d/adguardhome running; then
|
||||||
|
/etc/init.d/adguardhome stop
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ -f "$OLD_CONFIG_FILE" ] && [ "$OLD_CONFIG_FILE" != "$NEW_CONFIG_FILE" ]; then
|
||||||
|
echo "Old AdGuard Home config found in '$OLD_CONFIG_FILE'"
|
||||||
|
OLD_CONFIG_DIR=$(dirname "$OLD_CONFIG_FILE")
|
||||||
|
|
||||||
|
USER=$(uci -q get adguardhome.config.user)
|
||||||
|
USER=${USER:-adguardhome}
|
||||||
|
GROUP=$(uci -q get adguardhome.config.group)
|
||||||
|
GROUP=${GROUP:-adguardhome}
|
||||||
|
|
||||||
|
echo "Using $USER:$GROUP for file ownership."
|
||||||
|
|
||||||
|
CUR_CONFIG_FILE="$OLD_CONFIG_FILE"
|
||||||
|
if [ "$OLD_CONFIG_DIR" = "/etc" ]; then
|
||||||
|
echo "AdGuard Home config must be stored in its own directory. Migrating..."
|
||||||
|
stop_service
|
||||||
|
|
||||||
|
[ -d "$NEW_CONFIG_DIR" ] || mkdir -m 0700 -p "$NEW_CONFIG_DIR"
|
||||||
|
mv "$OLD_CONFIG_FILE" "$NEW_CONFIG_FILE"
|
||||||
|
chown -R "$USER":"$GROUP" "$NEW_CONFIG_DIR"
|
||||||
|
CUR_CONFIG_FILE="$NEW_CONFIG_FILE"
|
||||||
|
uci set adguardhome.config.config="$NEW_CONFIG_FILE"
|
||||||
|
|
||||||
|
echo "Config migrated to '$NEW_CONFIG_FILE'"
|
||||||
|
|
||||||
|
elif [ "$OLD_CONFIG_DIR" != "$NEW_CONFIG_DIR" ]; then
|
||||||
|
echo "AdGuard Home config is stored in a non-default path. " \
|
||||||
|
+ "Ensure configured service user '$USER' can access it."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Use awk to split match on :, remove double quotes and trim leading and
|
||||||
|
# trailing spaces
|
||||||
|
cert_path=$(grep certificate_path: "$CUR_CONFIG_FILE" \
|
||||||
|
| awk -F':' '{gsub(/"/, "", $2); gsub(/^ +| +$/, "", $2); print $2}')
|
||||||
|
if [ -n "$cert_path" ]; then
|
||||||
|
echo "Found custom 'certificate_path' pointing to '$cert_path'." \
|
||||||
|
+ "Ensure configured service user '$USER' can access it."
|
||||||
|
|
||||||
|
stop_service
|
||||||
|
|
||||||
|
if ! uci -q show adguardhome.config.jail_mount | grep -q "$cert_path"; then
|
||||||
|
uci add_list adguardhome.config.jail_mount="$cert_path"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
private_key_path=$(grep private_key_path: "$CUR_CONFIG_FILE" \
|
||||||
|
| awk -F':' '{gsub(/"/, "", $2); gsub(/^ +| +$/, "", $2); print $2}')
|
||||||
|
if [ -n "$private_key_path" ]; then
|
||||||
|
echo "Found custom 'private_key_path' pointing to '$private_key_path'." \
|
||||||
|
+ "Ensure configured service user '$USER' can access it."
|
||||||
|
|
||||||
|
stop_service
|
||||||
|
|
||||||
|
if ! uci -q show adguardhome.config.jail_mount | grep -q "$private_key_path"; then
|
||||||
|
uci add_list adguardhome.config.jail_mount="$private_key_path"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
uci commit adguardhome
|
||||||
|
start_service
|
||||||
|
|
||||||
|
elif [ "$OLD_CONFIG_FILE" != "$NEW_CONFIG_FILE" ]; then
|
||||||
|
echo "Old AdGuard Home config not found in '$OLD_CONFIG_FILE'"
|
||||||
|
stop_service
|
||||||
|
|
||||||
|
# Service script will create the new config directory
|
||||||
|
uci set adguardhome.config.config="$NEW_CONFIG_FILE"
|
||||||
|
echo "Config path changed to '$NEW_CONFIG_FILE'"
|
||||||
|
|
||||||
|
uci commit adguardhome
|
||||||
|
start_service
|
||||||
|
|
||||||
|
else
|
||||||
|
echo "AdGuard Home config is in its default path '$NEW_CONFIG_FILE'. Nothing to do."
|
||||||
|
fi
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
#!/bin/sh /etc/rc.common
|
#!/bin/sh /etc/rc.common
|
||||||
|
# shellcheck disable=SC3043 # ash supports local
|
||||||
|
|
||||||
PROG=/usr/bin/AdGuardHome
|
PROG=/usr/bin/AdGuardHome
|
||||||
|
|
||||||
@@ -10,32 +11,78 @@ START=19
|
|||||||
STOP=89
|
STOP=89
|
||||||
|
|
||||||
boot() {
|
boot() {
|
||||||
adguardhome_boot=1
|
ADGUARDHOME_BOOT=1
|
||||||
start "$@"
|
start "$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
start_service() {
|
start_service() {
|
||||||
if [ -n "$adguardhome_boot" ]; then
|
if [ -n "$ADGUARDHOME_BOOT" ]; then
|
||||||
# Do not start yet, wait for triggers
|
# Do not start yet, wait for triggers
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
config_load adguardhome
|
local config_file
|
||||||
config_get CONFIG_FILE config config "/etc/adguardhome.yaml"
|
local group
|
||||||
config_get PID_FILE config pidfile "/run/adguardhome.pid"
|
local pid_file
|
||||||
config_get WORK_DIR config workdir "/var/lib/adguardhome"
|
local user
|
||||||
|
local verbose
|
||||||
|
local work_dir
|
||||||
|
|
||||||
[ -d "$WORK_DIR" ] || mkdir -m 0755 -p "$WORK_DIR"
|
config_load adguardhome
|
||||||
|
config_get config_file config config "/etc/adguardhome/adguardhome.yaml"
|
||||||
|
config_get work_dir config workdir "/var/lib/adguardhome"
|
||||||
|
config_get pid_file config pidfile "/run/adguardhome.pid"
|
||||||
|
config_get_bool verbose config verbose
|
||||||
|
|
||||||
|
config_get user config user adguardhome
|
||||||
|
config_get group config group adguardhome
|
||||||
|
|
||||||
|
local config_dir
|
||||||
|
config_dir=$(dirname "$config_file")
|
||||||
|
if [ "$config_dir" = '/etc' ]; then
|
||||||
|
echo "AdGuard Home config must be stored in its own directory, and not in /etc" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
mkdir -m 0700 -p "$config_dir"
|
||||||
|
chown -R "$user":"$group" "$config_dir"
|
||||||
|
|
||||||
|
mkdir -m 0700 -p "$work_dir"
|
||||||
|
chown -R "$user":"$group" "$work_dir"
|
||||||
|
|
||||||
procd_open_instance
|
procd_open_instance
|
||||||
procd_set_param command "$PROG" -c "$CONFIG_FILE" -w "$WORK_DIR" --pidfile "$PID_FILE" --no-check-update
|
|
||||||
|
procd_set_param command "$PROG"
|
||||||
|
procd_append_param command --config "$config_file"
|
||||||
|
procd_append_param command --work-dir "$work_dir"
|
||||||
|
procd_append_param command --logfile syslog
|
||||||
|
procd_append_param command --no-check-update
|
||||||
|
[ "$verbose" = 1 ] && procd_append_param command --verbose
|
||||||
|
|
||||||
|
procd_set_param pidfile "$pid_file"
|
||||||
procd_set_param stdout 1
|
procd_set_param stdout 1
|
||||||
procd_set_param stderr 1
|
procd_set_param stderr 1
|
||||||
|
procd_set_param user "$user"
|
||||||
|
procd_set_param group "$group"
|
||||||
|
procd_set_param capabilities /etc/capabilities/adguardhome.json
|
||||||
|
procd_set_param no_new_privs 1
|
||||||
|
|
||||||
|
# log is needed for logging to syslog instead of stdout
|
||||||
|
# procfs is needed to readlink /proc/self/exe
|
||||||
|
procd_add_jail adguardhome log procfs
|
||||||
|
|
||||||
|
# config directory must be writable to write new config files
|
||||||
|
procd_add_jail_mount_rw "$config_dir"
|
||||||
|
procd_add_jail_mount_rw "$work_dir"
|
||||||
|
|
||||||
|
procd_add_jail_mount /etc/hosts
|
||||||
|
procd_add_jail_mount /etc/ssl/certs
|
||||||
|
config_list_foreach config jail_mount procd_add_jail_mount
|
||||||
|
|
||||||
procd_close_instance
|
procd_close_instance
|
||||||
}
|
}
|
||||||
|
|
||||||
service_triggers() {
|
service_triggers() {
|
||||||
if [ -n "$adguardhome_boot" ]; then
|
if [ -n "$ADGUARDHOME_BOOT" ]; then
|
||||||
# Wait for interfaces to be up before starting AdGuard Home for real.
|
# Wait for interfaces to be up before starting AdGuard Home for real.
|
||||||
# Prevents issues like https://github.com/openwrt/packages/issues/21868.
|
# Prevents issues like https://github.com/openwrt/packages/issues/21868.
|
||||||
procd_add_raw_trigger "interface.*.up" 5000 /etc/init.d/adguardhome restart
|
procd_add_raw_trigger "interface.*.up" 5000 /etc/init.d/adguardhome restart
|
||||||
|
|||||||
22
net/adguardhome/files/adguardhome.json
Normal file
22
net/adguardhome/files/adguardhome.json
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"bounding": [
|
||||||
|
"CAP_NET_BIND_SERVICE",
|
||||||
|
"CAP_NET_RAW"
|
||||||
|
],
|
||||||
|
"effective": [
|
||||||
|
"CAP_NET_BIND_SERVICE",
|
||||||
|
"CAP_NET_RAW"
|
||||||
|
],
|
||||||
|
"ambient": [
|
||||||
|
"CAP_NET_BIND_SERVICE",
|
||||||
|
"CAP_NET_RAW"
|
||||||
|
],
|
||||||
|
"permitted": [
|
||||||
|
"CAP_NET_BIND_SERVICE",
|
||||||
|
"CAP_NET_RAW"
|
||||||
|
],
|
||||||
|
"inheritable": [
|
||||||
|
"CAP_NET_BIND_SERVICE",
|
||||||
|
"CAP_NET_RAW"
|
||||||
|
]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user