在 ubuntu 18.04 Bionic 上连接 WiFi 网络时自动设置系统代理

在 ubuntu 18.04 Bionic 上连接 WiFi 网络时自动设置系统代理

如何配置 ubuntu 以便在连接到某个 wifi 时自动设置系统代理(用于 apt、shell 命令和 gui 程序)?

使用案例:系统大致分为三类
1) 从不设置代理。2
) 设置代理一次,然后忘记它
3) 每天更改两次代理,每周 6 天。(从工作场所搬到家里的笔记本电脑)

用例 (3) 在 18.04 之前有点烦人,但现在它完全无法使用,因为您必须手动编辑多个设置。

基于 WiFi SSID 实现自动化的最可靠、最简单的方法是什么?
这也隐含地提出了一个问题:“有没有一种简单的方法来设置系统代理?”

答案1

我想到的解决方案分为两部分:

1) 连接到网络时自动执行的脚本:
将其粘贴/etc/NetworkManager/dispatcher.d/05-change_proxy.sh。它应由 root 拥有并可执行。

#!/bin/sh

# Auto Proxy
# Sets the proxy based on the SSID of the wifi network
# place this script in /etc/NetworkManager/dispatcher.d/
# script must be executable and owned by root
# script needs a separate program setproxy to handle setting the proxy

# Parts the user needs to edit have a #EDIT comment next to them

# author:staticd(Sachit) 2018
# this software is released to the public domain

# See man NetworkManager for the parameters passed to a dispatcher script
# $1 is interface that changed; $2 is the specific change that occured; other information is set in the environmental variables of the script

# only run code if the script was called because a new connection was just brought "up"
if [ "$2" != "up" ]; then  
    exit 
fi


#EDIT SSIDS and the proxy settings
#echo "$CONNECTION_ID" >>/tmp/conlog
case "$CONNECTION_ID" in  # the CONNECTION_ID variable is set by the NetworkManager when it calls the script
    "MyHomeWifi")
        setproxy
        ;;
    "WorkWiFi 1" | "WorkWiFi 2")
        setproxy "proxy.company.com" "3128"
        ;;
    "OtherProxiedWifi")
        setproxy "192.168.0.1" "3128"
        ;;
#    *)                                   # any other connection is made
#        [ "$1" = "wlp3s0" ] && setproxy  # default to no proxy only if the new connection is on the wifi
#        ;;
esac

setproxy2)要保存的脚本/usr/local/bin(也是可执行文件并由root拥有),可以在命令行上直接调用此脚本来sudo setproxy proxy port设置代理

#!/bin/sh

# setproxy
# Sets the proxy settings for
#    /etc/environment
#    /etc/bash.bashrc
#    /etc/apt/apt.conf
#    the gnome proxy settings for all logged in users so running programs are notified of the change


# author:staticd(Sachit) 2018
# this software is released to the public domain

setproxy_help() {
    cat << EOS
Usage: setproxy [server] [port]
Sets the system proxy (apt and environment) and updates the proxy settings of running gui programs
This program must be run as root

With -h or --help prints this message
With no arguments it disables proxying
With two arguments it sets the proxy and port

examples:
  setproxy 192.168.0.1 3128        # sets the proxy
  setproxy proxy.company.com 8080  # sets the proxy
  setproxy                         # disables the proxy
EOS
}


#EDIT this if you don't have the default session manager for example if you have a KDE or LXDE desktop
SESSION_MANAGER=gnome-session-b

unset_proxy() {
    #this function clears the proxy settings
    #delete any lines containing "proxy=" 
    sed -i "/proxy\=/d" /etc/environment
    #delete old proxy setting lines and unset any outdated environment variables inherited at login time
    sed -i "/proxy\=/d"       /etc/bash.bashrc
    echo "unset http_proxy" >>/etc/bash.bashrc
    echo "unset https_proxy">>/etc/bash.bashrc
    echo "unset ftp_proxy"  >>/etc/bash.bashrc
    echo "unset no_proxy"   >>/etc/bash.bashrc
    #delete any lines containing "Proxy"
    sed -i "/Proxy/d"   /etc/apt/apt.conf
    # ask the already running programs of logged in users to update their settings
    # programs load the get the settings in /etc/environment only when they just start
    for user in $(users | tr ' ' '\n' | sort --unique) ; do
        unset_proxy_logged_in_user "$user"
    done
}

unset_proxy_logged_in_user(){
    USER=$1
    su "$USER" << EOS
    export $(cat /proc/$(pgrep "$SESSION_MANAGER" -u "$USER")/environ|egrep -z '^DBUS_SESSION_BUS_ADDRESS=')
    gsettings set org.gnome.system.proxy mode 'none'
EOS
}

set_proxy() {
    # this function sets the proxy settings for apt and the environment
    # first argument should be server, second is the port
    unset_proxy
    proxy_url='http://'"$1":"$2"
    echo $proxy_url
    # set the default environment
    echo "http_proxy=\"$proxy_url\"" >>/etc/environment
    echo "https_proxy=\"$proxy_url\"">>/etc/environment
    echo "ftp_proxy=\"$proxy_url\""  >>/etc/environment
    echo "no_proxy=localhost,127.0.0.0/8,::1">>/etc/environment
    # set the proxy for all new terminals that are opened. (without this, new terminals that are opened may continue to inherit outdated environment variables from the state of /etc/environment file at login time)
    echo "export http_proxy=\"$proxy_url\"" >>/etc/bash.bashrc
    echo "export https_proxy=\"$proxy_url\"">>/etc/bash.bashrc
    echo "export ftp_proxy=\"$proxy_url\""  >>/etc/bash.bashrc
    echo "export no_proxy=localhost,127.0.0.0/8,::1">>/etc/bash.bashrc
    # set the apt proxy
    echo "Acquire::Http::Proxy \"$proxy_url\";"  >>/etc/apt/apt.conf
    echo "Acquire::Https::Proxy \"$proxy_url\";" >>/etc/apt/apt.conf
    echo "Acquire::Ftp::Proxy \"$proxy_url\";"   >>/etc/apt/apt.conf
    # ask the already running programs of logged in users to update their settings
    # programs load the settings in /etc/environment only when they just start
    for user in $(users | tr ' ' '\n' | sort --unique) ; do
        set_proxy_logged_in_user "$user" $1 $2
    done
}

set_proxy_logged_in_user(){
    USER=$1
    SERVER=$2
    PORT=$3
    su "$USER" << EOS
    export $(cat /proc/$(pgrep "$SESSION_MANAGER" -u "$USER")/environ|egrep -z '^DBUS_SESSION_BUS_ADDRESS=')
    gsettings set org.gnome.system.proxy mode 'manual'
    gsettings set org.gnome.system.proxy.http host $SERVER
    gsettings set org.gnome.system.proxy.http port $PORT
    gsettings set org.gnome.system.proxy.https host $SERVER
    gsettings set org.gnome.system.proxy.https port $PORT
    gsettings set org.gnome.system.proxy.ftp host $SERVER
    gsettings set org.gnome.system.proxy.ftp port $PORT
    gsettings set org.gnome.system.proxy ignore-hosts "['localhost', '127.0.0.0/8' , '::1' ]"
EOS
}


# print help message
if [ $# -eq 1 ] ; then
    case $1 in
    "-h" | "--help" )
        setproxy_help  
        exit
        ;;
    *)
        echo "Invalid argument" $1
        echo "call " $(basename $0) "-h for help"
        exit 1
        ;;
    esac
fi

# check if running as root
if ! [ $(id -u) = 0 ]; then
   echo "This script needs to be run as root"
   exit 1
fi

if [ $# -eq 0 ] ; then
    unset_proxy
    exit
fi

if [ $# -eq 2 ] ; then
    set_proxy $1 $2
    exit
fi

# If the execution reached here it was called with too many arguments
echo "too many arguments"
echo "call " $(basename $0) "-h for help"
exit 1

相关内容