(たぶん)一瞬でできるDS-liteゲートウェイ

2018年10月5日

pppoeのipv4がゴールデンタイム遅かったので、dsliteを利用しようと思ったんですが、どうせやるなら電源入れるだけで勝手にやってくれるスクリプトを作ろうかと。

このスクリプトを作るにあたって、以下を参考にさせていただきました。

https://gato.intaa.net/archives/8431
http://techlog.iij.ad.jp/contents/dslite-raspi

このスクリプトは以下の条件で動作します。(以下を満たせば多分動きます)

  • グローバルipv6が利用可能
  • debian系であること(debian8のraspberry piで操作確認)
  • ipv4が(DNS、ゲートウェイも含め)固定されていること
  • LANネットワーク内にいること(ローカルなipv4が必要 192.168.xx.xxとか)
  • IPv6が2つ以上あることを考慮していなかった(不具合なので気が向いたら治す予定)

このスクリプトが行うことは、

  • ds-liteのトンネル作成
  • 自機に流れ込んできたipv4トラフィックをds-liteにフォワーディング(転送)設定
  • (あとで追加)ipv4のpingが失敗した際、ds-liteの再接続を行う

これによって、ルーターのDHCPのデフォルトゲートウェイを変更することで、ipv4トラフィックをds-liteに転送することが出来ます。また。PCそれぞれに

  • ルーターをデフォルトゲートウェイにする
  • ds-liteをデフォルトゲートウェイにする

を設定することができるので、pppoeのipv4も利用可能です。(ds-liteはポート開放出来ないっぽい)。ipアドレスを固定しておく理由としては、ルーターのDHCPを変更した後に、何らかの理由でds-liteができなかった際にループを発生させないためです。

スクリプトはこちらになります。

cat dslite.sh

#!/bin/sh
#ユーザー設定領域 ここから
#ETH_DEV ipv6グローバルアドレスが振られるインターフェイス
#REMOTE  DSliteの接続先
#NTT東日本エリア 2404:8e00::feed:100 2404:8e00::feed:101
#NTT西日本エリア 2404:8e01::feed:100 2404:8e01::feed:101
#必ず''で囲む
ETH_DEV='eth0'
REMOTE='2404:8e00::feed:101'
PING_IP='8.8.8.8'
#ユーザー設定領域 ここまで

#グローバルなIPv6をLOCALに代入
LOCAL=`ip addr show $ETH_DEV |grep 'inet6'  | grep 'global' |awk '{print $2}'  | awk -F/ '{print $1}'`
#ネットワークが起動しても、ipv6のアドレスが(割当が遅くて)ない場合があるので、取得し続ける
while [ -z $LOCAL ]
do
sleep 0.5s
LOCAL=`ip addr show $ETH_DEV |grep 'inet6'  | grep 'global' |awk '{print $2}'  | awk -F/ '{print $1}'`
done
#echo $LOCAL
#カーネルモジュールの有効化
modprobe ip6_tunnel
#トンネル作成
ip -6 tunnel add dslite mode ip4ip6 remote $REMOTE local $LOCAL dev $ETH_DEV
#トンネルの起動
ip link set dev dslite up
#デフォルトゲートウェイの削除
route delete default
#作成したトンネルをデフォルトゲートウェイに指定
route add default dev dslite
#ipv4のフォワーディングを有効
sysctl -w net.ipv4.ip_forward=1

while true
do
sleep 5s
ping $PING_IP -c 5  >> /dev/null

if [ $? -eq 1 ] ;
then
LOCAL=''
while [ -z $LOCAL ]
do
sleep 0.5s
LOCAL=`ip addr show $ETH_DEV |grep 'inet6'  | grep 'global' |awk '{print $2}'  | awk -F/ '{print $1}'`
done
route delete default
route add default dev $ETH_DEV
ip link set dev dslite down
ip tunnel del dslite
ip -6 tunnel add dslite mode ip4ip6 remote $REMOTE local $LOCAL dev $ETH_DEV
ip link set dev dslite up
route delete default
route add default dev dslite
echo "ds-lite reconnected"
fi
done


cat dslite-auto-start.service

[Unit]
Description=run dslite during boot
After=network.target
[Service]
Type=simple
RemainAfterExit=yes
ExecStart=/usr/local/bin/dslite.sh
[Install]
WantedBy=multi-user.target

cat setup-dslite-scripts.sh

#!/bin/sh
cp ./dslite.sh /usr/local/bin/dslite.sh
chmod +x /usr/local/bin/dslite.sh
cp ./dslite-auto-start.service /etc/systemd/system/dslite-auto-start.service
systemctl enable dslite-auto-start.service

dslite.shには設定すべき箇所があるので注意してください。また、setup-dslite-scripts.shはスクリプトをディレクトリにコピーして、システム起動時のdsliteゲートウェイを有効にする機能があります。コピーさせる場所が既に決まっているのであれば、読み替えてください。