Open anfragment opened 7 months ago
Hello, just a quick headsup, I just ran the Zen executable on Archlinux with Hyprland and NetworkManager, and it seems to be working just fine. I'm wondering if the necessary package isn't just NetworkManager ?
Hi! Does your setup happen to have the gsettings
command line tool?
How about working with /etc/environment
?
Its a file that stores the system-wide variables initialized upon boot:
http_proxy="http://127.0.0.1:<port>"
https_proxy="http://127.0.0.1:<port>"
You could have shell commands change this file either adding or removing lines from it ? Only problem is that the user needs to logout and login again for changes to take effect.
How about working with
/etc/environment
? Its a file that stores the system-wide variables initialized upon boot:http_proxy="http://127.0.0.1:<port>" https_proxy="http://127.0.0.1:<port>"
You could have shell commands change this file either adding or removing lines from it ? Only problem is that the user needs to logout and login again for changes to take effect.
this is a bad idea in general because it depends on zen being active at all times and will cause all sorts of issues if it's not active. maybe it'd be better to replace it with instructions to set this up manually if someone doesn't use gnome, maybe even within the browser only? either way, i will update the arch linux package to depend on glib2 and networkmanager, since those gsettings flags depend on both.
on the other hand, @anfragment anecdotally i did notice that proxy settings were persistent upon quitting zen so maybe this should change if zen is stopped? or is it a bug? not sure.
What if Zen is setup to toggle off
the proxy setting on exit ? Wouldn't it mittigate the issue ?
@anfragment @myyc
And what if you use NetworkManager's nmcli :
nmcli connection modify <connection_name> proxy yes
nmcli connection modify <connection_name> proxy.method manual
nmcli connection modify <connection_name> proxy.http http://127.0.0.1:<port>
nmcli connection modify <connection_name> proxy.https http://127.0.0.1:<port>
This would mean that the settings could be changed without having to login again. Then you only depend on networkmanager.
The issue with this potential solution, is that you depend on NetworkManager, and that you'd need to loop through all connection names to set the proxy settings.
You can also set proxy settings per device types : wlan, wwan, etc, using nmcli device status
and loop through thoses:
nmcli connection modify "$device" proxy yes
nmcli connection modify "$device" proxy.method manual
nmcli connection modify "$device" proxy.http "$proxy"
nmcli connection modify "$device" proxy.https "$proxy"
or by type maybe
on the other hand, @anfragment anecdotally i did notice that proxy settings were persistent upon quitting zen so maybe this should change if zen is stopped? or is it a bug? not sure.
Yes, it's a bug, the proxy doesn't properly shut down when the app gets closed on Linux. Should get fixed in a release later this week.
@hollisticated-horse @myyc
nmcli
looks promising. NetworkManager is desktop environment agnostic, right? Does every NetworkManager installation come with nmcli
?
@anfragment
From my research, NetworkManager seems desktop environment agnostic and comes with nmcli
.
See compiled list of links:
nmcli
) and a curses‐based interface (nmtui
).nmtui
or also nmcli
nmcli
.And what if you use NetworkManager's nmcli :
have you tried it? the above suggestion doesn't work, maybe it refers to an older version of networkmanager. i still think that the most reliable way would be to stick to supporting gnome and kde only, and showing instructions for other setups.
@myyc I'm also struggling to make those commands work reliably. I'll do some testing and get back to you guys @myyc @anfragment
EDIT 1:
proxy.method
is indeed wrong.
still maintain that if you don't use gnome or kde you should probably configure proxy settings yourself as opposed to having an external piece of software messing with networkmanager or wiping environment variable configs by accident.
still maintain that if you don't use gnome or kde you should probably configure proxy settings yourself as opposed to having an external piece of software messing with networkmanager or wiping environment variable configs by accident.
Good point. Non-technical users should have an easy way to reset their proxy settings in case something goes wrong with the app. I've done some searching and it seems like even on KDE there is no alternative to gsettings
, which means that we would have to stick to only setting the system proxy automatically on GNOME. Currently the app fails to launch if we didn't find the gsettings
binary. I'll work on fixing that and adding a notification for users to manually configure their proxy settings. @myyc @hollisticated-horse really appreciate your help in figuring this out, thank you guys.
potentially you could even do it programmatically in go instead of using gsettings? chatgpt suggest the following
package main
import (
"fmt"
"github.com/godbus/dbus"
)
func main() {
conn, err := dbus.SessionBus()
if err != nil {
fmt.Println("Failed to connect to the D-Bus session bus:", err)
return
}
defer conn.Close()
proxySettings := conn.Object("org.gnome.SettingsDaemon", "/org/gnome/SettingsDaemon/Proxy")
err = proxySettings.Call("org.freedesktop.DBus.Properties.Set", 0, "org.gnome.system.proxy", "mode", dbus.MakeVariant("manual")).Err
if err != nil {
fmt.Println("Failed to set proxy mode:", err)
return
}
fmt.Println("Proxy mode set to manual")
}
but i'm not sure using godbus is better than spawning gsettings.
I had a quick look at the mullvad electron app, thinking that they must also work with proxys but am unsure of what I found.
Otherwise, I was looking through the archlinux wiki page proxy server
page and found this:
Some programs, such as wget and (used by pacman) CURL, use environment variables of the form
*protocol*_proxy
to determine the proxy for a given protocol (e.g. HTTP, FTP, ...).Below is an example on how to set these variables in a shell:
export http_proxy=<a rel="nofollow" class="external free" href="http://10.203.0.1:5187/">http://10.203.0.1:5187/</a> export https_proxy=$http_proxy export ftp_proxy=$http_proxy export rsync_proxy=$http_proxy export no_proxy="localhost,127.0.0.1,localaddress,.localdomain.com"
Some programs look for the all caps version of the environment variables.
Also:
Alternatively, there is a tool named proxyman-gitAUR which claims to configure system-wide proxy settings easily.
and :
Automation with network managers
NetworkManager cannot change the environment variables. netctl could set-up these environment variables but they would not be seen by other applications as they are not child of netctl.
Which makes me think that the nmcli
route might be dead.
https://github.com/himanshub16/ProxyMan/blob/master/shellrc.sh has shell functions to set and unset proxy server.
Which could be interesting to explore.
Hi there,
Using NM could be one road ahead. It's proxy vars env agnostic which is a good thing. Trying to capture any and all env vars ever used and to be used is whack-a-mole for proxy settings.
As not everyone is using NM, additionally setting known proxy env vars wouldn't hurt.
Feature: if proxy settings are set per connection/device there is no circumventing it by malicious programs or misconfigurations. At least, they're not rooted, that is.
BUT: IIUC, it's just about redirection of HTTP[S] for ad filtering purposes. So the correct route would be setting up iptables/netfilter for the Linux and PF for BSD folks, resp., to redirect the relevant ports.
cheers
@corbolais thanks for the suggestion, setting some iptables rules might indeed be the solution I was looking for.
So when looking up how to use iptables, I end up with this function to set iptables
rules:
as an example:
func setIpRule() {
cmd := exec.Command("iptables", "-t", "nat", "-A", "PREROUTING", "-p", "tcp", "--dport", "80", "-j", "REDIRECT", "--to-port", "8080")
err := cmd.Run()
if err != nil {
log.Fatal(err)
}
}
and this function to delete the previous rule.
func delIpRule() {
cmd := exec.Command("iptables", "-t", "nat", "-D", "PREROUTING", "-p", "tcp", "--dport", "80", "-j", "REDIRECT", "--to-port", "8080")
err := cmd.Run()
if err != nil {
log.Fatal(err)
}
}
Is this what you envisioned @corbolais ?
To be noted, it seems that iptables is not persistent across reboots from the get go. There is a package,iptables-persistent
. This packages makes it so that any erected iptables rules will be saved to the corresponding IPv4 and IPv6 files:
/etc/iptables/rules.v4
/etc/iptables/rules.v6
Btw, there is a go package that provides an API for iptables : https://github.com/coreos/go-iptables
Not sure if it's needed, but it's there.
For pf, I assume it is similar ?
@hollisticated-horse those rules look about right. You probably want to use -I 1
instead of -A
. Users might have custom rules or default ufw rules on Ubuntu/Fedora/.. active and appended rules might get ignored if the previous last rule i.e. is a DROP
.
Persistency is another chapter in it's own right. It'd be probably best to create a systemd service using a one-shot rule install/removal upon boot/shutdown. Best to check beforehand whether the rule is already installed.
Not sure of the best way to handle this for a multitude of distributions. And there's also a plethora of tools to run custom rulesets. I'd most likely start with injecting and removing the rule oob, like you suggested. Then see where this is leading. OTOH, this issue is no new thing, the net might offer a better solution.
PF, I'm not familiar with. It's a verbose filter language even more so than ufw cmdline syntax is.
Also, I think we'd need to set the rule using the OUTPUT
chain instead of the PREROUTING
chain, since it only affects incoming instead of outgoing packets (see: https://manpages.debian.org/unstable/iptables/iptables.8.en.html#nat). From my limited understanding of iptables, this would also mean that requests originating from Zen itself will get routed back to it, creating an infinite loop. This can be solved by adding the -m owner ! --uid-owner zenuser
option to the rule, but this would mean that we'd have to run Zen via a separate user, which sounds like a whole another headache in itself.
@anfragment Correct. For locally generated packets nat OUTPUT
is the right choice.
iptables -t nat -A OUTPUT --match owner --uid-owner $ZEN_USR -p tcp --dport 80 -j ACCEPT
iptables -t nat -A OUTPUT -p tcp --dport 80 -j DNAT --to-destination $ZEN_IP:8080
Running ZEN with it's own user id is good practice anyway.
There's a treasure trove to be ingested at https://wiki.squid-cache.org/ConfigExamples/Intercept . The squid-cache wiki is invaluable in this regard. This should keep you busy for the next days.. ;-)
Happy holidays
C
Thanks for the valuable input @corbolais. Best of luck to you in the coming year!
Hello, stumbled upon this tool written in go, to manage forwards with iptables. Might be a lead ?
The only thing stopping Zen from working in other desktop environments is that it can't set the system proxy settings. On GNOME it is done via couple gsettings commands, but I couldn't find any documentation on similar ways to do this programmatically on other desktop environments. Feel free to add a comment if you think you can help.