はじめに

電気通信大学のLANにはセキュリティのためにプロキシサーバが設けられており、学外にアクセスするにはここを経由する必要があります。学校のVPNに接続しているときもネットワーク的に学内扱いなのでプロキシを設定する必要があります。

学校から提供されているプロキシサーバは次のとおりです。学外あての全ての通信はここを経由する必要があります。

プロトコル ホスト:ポート
HTTP proxy.uec.ac.jp:8080
Socks 5 socks.cc.uec.ac.jp:1080

準備

SSIDの名前でUECWirelessか判別するやり方

1. まずSSIDの名前を取得します

1
2
# OSX
export SSID=$(/System/Library/PrivateFrameworks/Apple80211.framework/Resources/airport -I | grep -E '^\s+SSID: ' | sed -E 's/SSID://' | xargs echo)
1
2
# Linux
export SSID=$(iwgetid -r)

2. 判別します

1
[[ $SSID == UECWireless ]]

VPNに接続しているか判別するやり方

UECという名前でVPNが構成されているものとします。

1
2
# OSX
[[ $(scutil --nc status UEC | head -1) == Connected ]]
1
2
# Linux
[[ $(nmcli connection show UEC | grep GENERAL.STATE) != '' ]]

シェルのプロキシ設定

以上で判別方法が分かったので、シェル用のプロキシを設定していきます。Linux端末を学校に持ってくるような人はシェルスクリプトは朝飯前だと思うのでOSX用の設定を載せます。

.bash_profile

1
source $HOME/.bashrc

と書き、.bashrcには次のスクリプトを書きます。

1
2
3
4
5
6
7
8
9
10
11
12
13
# .bashrc
export SSID=$(/System/Library/PrivateFrameworks/Apple80211.framework/Resources/airport -I | grep -E '\sSSID: ' | sed -E 's/SSID://' | xargs echo)
if [[ $SSID == UECWireless ]];then
export http_proxy="http://proxy.uec.ac.jp:8080/"
export https_proxy="http://proxy.uec.ac.jp:8080/"
export no_proxy="localhost,127.0.0.1,172.21.17.1,130.153.*.*,172.21.*.*,192.168.*.*,*uec.ac.jp"
export proxy="http://proxy.uec.ac.jp:8080/"
else
unset http_proxy
unset https_proxy
unset no_proxy
unset proxy
fi

SSHのプロキシ設定

学外にSSHするときにはSSHもプロキシが必要です。大方のプログラムは上で設定した環境変数で対応できますが、SSHは個別に設定が必要です。学内にいるときだけMatchProxyCommandを追加すればいいので、OSXのときはこうします。

1
2
3
4
5
6
7
8
9
# OSX
Match Host vps exec "[[ $(/System/Library/PrivateFrameworks/Apple80211.framework/Resources/airport -I | grep -E '\sSSID: ' | sed -E 's/SSID://' | xargs echo) == 'UECWireless' ]]"
ProxyCommand nc -X 5 -x socks.cc.uec.ac.jp:1080 %h %p

Host vps
HostName example.com
Port 22
User hoge
IdentityFile ~/.ssh/id_rsa_vps

Gnomeのプロキシ設定

先日学内でUbuntuを使っている時にZoomに入れなくなりました。

zoomをstraceしてみると、GUIでconnectingとなっている最中、このような接続をしていることが分かりました。130.153.8.24proxy.uec.ac.jpなので、その80番ポートにアクセスしていることになります。もちろん、このプロキシサーバで使えるポートは8080だけなので本来であれば8080にアクセスするはずです。

1
2
3
4
5
6
connect(72, {sa_family=AF_INET, sin_port=htons(80), sin_addr=inet_addr("130.153.8.24")}, 16) = -1 EINPROGRESS (現在処理中の操作です)
connect(72, {sa_family=AF_INET, sin_port=htons(80), sin_addr=inet_addr("130.153.8.24")}, 16) = 0
connect(72, {sa_family=AF_INET, sin_port=htons(80), sin_addr=inet_addr("130.153.8.24")}, 16) = -1 EINPROGRESS (現在処理中の操作です)
connect(72, {sa_family=AF_INET, sin_port=htons(80), sin_addr=inet_addr("130.153.8.24")}, 16) = 0
connect(72, {sa_family=AF_INET, sin_port=htons(80), sin_addr=inet_addr("130.153.8.24")}, 16) = -1 EINPROGRESS (現在処理中の操作です)
connect(72, {sa_family=AF_INET, sin_port=htons(80), sin_addr=inet_addr("130.153.8.24")}, 16) = 0

ZoomはおそらくGnomeのプロキシ設定を参照しているので、設定を確認すると自動設定になっていました。

学内限定サイトなのでかなり省いていますが、http://proxy.uec.ac.jp/に書いてある通り、学内にいるとDIRECTになっていることが分かります。

1
2
3
4
if (学内)
return "DIRECT";
else
return "プロキシ使う";

つまり、Gnomeの設定でプロキシをautoにして、http://proxy.uec.ac.jp/のスクリプトを使うと、学内にいるときはプロキシを使わないようになります。

ならば手動で設定し、学内にいるときもプロキシを使うようにすればいいので、このようにしたところ無事Zoomに入ることができました。

自動化

networkd-dispatcherでWifiにつないだときやVPNにつないだときのプロキシ設定処理を自動化します。これはNetworkManagerの一機能です。次のコマンドで有効化されているか確認します。

1
sudo systemctl status networkd-dispatcher.service

inactiveのときは有効化と起動をしておきます。

1
2
sudo systemctl enable networkd-dispatcher.service
sudo systemctl start networkd-dispatcher.service

/etc/NetworkManager/dispatcher.d/10-uec.shに次のスクリプトを書きます。Gnomeの設定はユーザーごとなのでログインしているユーザー全員に設定して回ります。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#!/bin/bash

function uec_proxy(){
USER=$1
echo $USER
RUN_AS_USER="sudo -Hu $USER DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$(id $USER -u)/bus"

if [ "$CONNECTION_ID" = 'UEC' -a "$NM_DISPATCHER_ACTION" = 'vpn-up' ] \
|| [ "$CONNECTION_ID" = 'UECWireless' -a "$NM_DISPATCHER_ACTION" = 'up' ];then
$RUN_AS_USER gsettings set org.gnome.system.proxy mode 'manual'
$RUN_AS_USER gsettings set org.gnome.system.proxy.http host 'proxy.uec.ac.jp'
$RUN_AS_USER gsettings set org.gnome.system.proxy.http port 8080
$RUN_AS_USER gsettings set org.gnome.system.proxy.https host 'proxy.uec.ac.jp'
$RUN_AS_USER gsettings set org.gnome.system.proxy.http port 8080
$RUN_AS_USER gsettings set org.gnome.system.proxy.socks host 'localhost'
$RUN_AS_USER gsettings set org.gnome.system.proxy ignore-hosts "['localhost', '127.0.0.0/8', '::1']"
else
$RUN_AS_USER gsettings set org.gnome.system.proxy mode 'none'
fi
}

export -f uec_proxy
who | awk '{print $1}' | xargs -l -P 16 [email protected] bash -c 'uec_proxy @'