Closed rusty-snake closed 3 years ago
Has anyone found a good solution? Polkit maybe.
Interesting topic. I do indeed think polkit
might be your safest option. Something like the below might work (untested).
$ cat /etc/polkit-1/actions/org.netblue30.fdns.policy
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE policyconfig PUBLIC
"-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
"http://www.freedesktop.org/standards/PolicyKit/1/policyconfig.dtd">
<policyconfig>
<vendor>netblue30</vendor>
<vendor_url>https://github.com/netblue30</vendor_url>
<action id="org.netblue30.fdns.start">
<description>Start fdns</description>
<message>Authentication is required to start fdns</message>
<icon_name>foo</icon_name>
<defaults>
<allow_any>auth_admin</allow_any>
<allow_inactive>auth_admin</allow_inactive>
<allow_active>auth_admin</allow_active>
</defaults>
</action>
</policyconfig>
$ cat /etc/polkit-1/rules.d/30-fdns.rules
/* Allow members of the fdns group to start the daemon
without password authentication, similar to sudo NOPASSWD: */
polkit.addRule(function(action, subject) {
if ((action.id == "org.netblue30.fdns.start")
&& subject.isInGroup("fdns")) {
return polkit.Result.YES;
}
});
I'm need to read more about polkit. Anyway, here is my first attempt.
Actually a rule for pkexec in enough to execute pkexec fdns --proxy-addr=127.70.74.68 --whitelist=github.com
without a password-prompt.
/etc/polkit-1/rules.d/60-fdns.rules
:
polkit.addRule(function(action, subject) {
var re = new RegExp("^/usr/bin/fdns --proxy-addr=127\\.70\\.74\\.[0-9]{1,3}( --whitelist=[A-Za-z0-9._-]+)*$");
if (action.id === "org.freedesktop.policykit.exec" &&
action.lookup("program") === "/usr/bin/fdns" &&
re.test(action.lookup("command_line")) &&
subject.user === "rusty-snake" && subject.local && subject.active) {
return polkit.Result.YES;
}
});
NOTE: This does not work for Debian/Ubuntu because they still ship polkit 0.105 which uses PKLA-rules. Apparently they have some security concerns about using Javascript for that. But I can't understand it, javascript is the first word that comes to my mind when I hear security :clown_face:.
Ok, I go with polkit.
[UPDATE: https://github.com/rusty-snake/fdns4users#example-for-polkit]
polkit.addRule(function(action, subject) {
const USER = "john";
const PROGRAM = "/usr/bin/fdns";
const IP = "127\\.70\\.74\\.[0-9]{1,3}";
const PROXY_ADDR = `--proxy-addr=${IP}`;
const WHITELIST = `--whitelist=[A-Za-z0-9._-]+`;
const ZOM_WHITELIST = `( ${WHITELIST})*`;
const RE = new RegExp(`^${PROGRAM} ${PROXY_ADDR}${ZOM_WHITELIST}$`);
// Debugging: uncomment to see the final RegExp
//polkit.log(RE.toString());
if (action.id === "org.freedesktop.policykit.exec" &&
action.lookup("program") === PROGRAM &&
RE.test(action.lookup("command_line")) &&
subject.user === USER && subject.local && subject.active) {
return polkit.Result.YES;
}
});
#!/bin/bash
PROXY_ADDR=127.70.74.68
FDNS_LOG_FILE="$HOME/fdns-log.txt"
ALLOWED_DOMAINS=(example.com)
whitelist=()
for domain in "${ALLOWED_DOMAINS[@]}"; do
whitelist+=("--whitelist=$domain")
done
echo -e "\n\n===> fdns --proxy-addr=$PROXY_ADDR ${whitelist[@]} <===\n" >> $FDNS_LOG_FILE
pkexec fdns "--proxy-addr=$PROXY_ADDR" "${whitelist[@]}" >> $FDNS_LOG_FILE &
sleep 2s
firejail --dns=$PROXY_ADDR thunderbird
kill $(jobs -p)
kill $(jobs -p)
Wait, I can not kill processes belonging to an other user.
If want to use fdns together with
firejail --dns
, so that a sandbox has it's own resolver. You need to get root to start fdns. That's a bit annoying if you need to enter your PW and bad to script if you use sudo. So what can be done to do this automatically.obvious: add a
NOPASSWD
rule to sudo. However you wound need to create new rules for every used--withelist
argument because sudo has no support for regexp and*
matches everything (including spaces). Example rule:john ALL=(ALL) NOPASSWD: /usr/bin/fdns --proxy-addr=127.70.74.[0-9]
I created a heavy SUID-binary which starts fdns https://github.com/rusty-snake/fdns4users. However, that's still no good solution as you don't want more suids on your system.
Has anyone found a good solution? Polkit maybe.