Linux网络连接时如何自动更新系统级http_proxy环境变量


阅读 3 次

问题场景描述

在移动开发环境中,我经常需要通过手机热点进行网络共享。但Android系统的DHCP分配机制会随机生成192.168.x.x的私有IP作为网关地址。更麻烦的是,我需要在手机端运行代理服务(如Charles或Fiddler),每次网络切换都需要手动更新代理设置。

现有方案分析

我最初尝试的shell脚本如下:

#!/bin/bash
router=$(route -n | awk '{print $2}' | grep 192.168)
sed "s/\$$PROXY-IP\$$/$router/g" ~/pac/wpad.template > ~/pac/wpad.dat
export http_proxy="http://$router:8080"
export https_proxy="https://$router:8080"
export ftp_proxy="http://$router:8080"

这个脚本存在两个关键问题:

  1. 环境变量修改仅在当前shell会话有效
  2. 无法实现网络连接时的自动触发

系统级环境变量解决方案

在Linux系统中,可以通过以下方式实现持久化配置:

方案1:NetworkManager分发脚本

创建/etc/NetworkManager/dispatcher.d/99proxy脚本:

#!/bin/bash
INTERFACE=$1
STATUS=$2

if [ "$STATUS" = "up" ]; then
    router=$(ip route show default | awk '/default/ {print $3}' | grep '192.168')
    if [ -n "$router" ]; then
        echo "http_proxy=http://$router:8080" >> /etc/environment
        echo "https_proxy=http://$router:8080" >> /etc/environment
        # 通知所有用户进程更新环境
        export $(cat /etc/environment | xargs)
        systemctl --user import-environment http_proxy https_proxy
    fi
fi

方案2:systemd-networkd事件触发

对于使用systemd-networkd的系统,创建/etc/systemd/system/update-proxy.service:

[Unit]
Description=Update proxy settings
After=network.target
BindsTo=sys-subsystem-net-devices-wlp3s0.device

[Service]
Type=oneshot
ExecStart=/usr/local/bin/update-proxy.sh

[Install]
WantedBy=multi-user.target

用户会话级解决方案

对于开发环境,可以在~/.profile中添加动态检测逻辑:

# 动态检测网关IP并设置代理
detect_proxy() {
    local gateway=$(ip route show default | awk '/default/ {print $3}')
    if [[ $gateway =~ ^192\.168 ]]; then
        export http_proxy="http://${gateway}:8080"
        export https_proxy="http://${gateway}:8080"
        echo "Proxy set to $gateway"
    else
        unset http_proxy https_proxy
    fi
}

# 每次打开终端时检测
detect_proxy

# 可选:每分钟自动检测
while true; do
    detect_proxy
    sleep 60
done &

Android端配合方案

在手机端使用Termux创建自动化脚本:

#!/data/data/com.termux/files/usr/bin/bash
# 在热点开启时固定IP
ip link set wlan0 up
ip addr add 192.168.43.1/24 dev wlan0
# 启动代理服务
redsocks -c /data/data/com.termux/files/home/redsocks.conf

测试验证方法

编写测试脚本verify-proxy.sh:

#!/bin/bash
echo "当前代理设置:"
echo "http_proxy=$http_proxy"
echo "https_proxy=$https_proxy"

echo "测试网络连接:"
curl -I http://www.example.com --proxy $http_proxy