家にDebianサーバーがあります。サーバーは私のルーターであり、外部VPNアクセスを提供します。
静的IPアドレスがありません。 ISPが提供するリース時間は2時間です。
私が住んでいる地域にサービスを提供するこのケーブル装置には、少なくとも顧客に2つの異なるネットワークブロックを提供し、Linuxサーバーの再起動後に別のIPアドレスを取得することは完全に異例ではありませんが、一部のISPメンテナンス作業後にこの問題に関してより重要です。
IPアドレスに依存するいくつかのサービスがあり、パブリックIPアドレスは外部(VPN)アクセスおよび内部参照に使用されます。
一部のサービスでは、複数の場所でIPアドレスを変更する必要がないように、FreeDNSの動的DNS名を使用します。
だから、これまで私が考案した最善のアプローチは、dhclient-exitフックからスクリプトを実行することです。このスクリプトは、DHCPがIPを提供/更新した後に呼び出され、IPが変更されるとサービスを再起動します。
/etc/hosts
また、FreeDNS側の変更が私に影響を与える前に、以前のIPで発生する可能性がある問題を解決するために、動的DNS名のIPを変更しました。
私が書いたスクリプトはdhclient-exit-hooks.d
次のとおりです。exit_status
すべてがうまくいけばゼロになるはずですdhclient
。
#!/bin/bash
PATH=$PATH:/usr/bin
if ! [[ -v exit_status ]]
then
exit 1
fi
if [ $exit_status -eq 0 ]
then
IP=`ip addr show eth0.101 | grep inet | awk ' { print $2 } ' | cut -f1 -d "/"`
OLDIP=`awk ' /xxxx.mooo.com/ { print $1 } ' /etc/hosts`
if [ $reason = "REBOOT" ] || [ $reason = "BOUND" ] || [ $IP != $OLDIP ]
then
sed -i "s/^[0-9\.]* xxxx.mooo.com/$IP xxxx.mooo.com/g" /etc/hosts
timeout 60 /opt/bin/iptables.sh
timeout 60 /etc/init.d/ipsec restart
timeout 60 /etc/init.d/asterisk restart
timeout 120 /etc/init.d/bind9 restart
timeout 60 /usr/bin/wget -O - http://freedns.afraid.org/dynamic/update.php?XXXXXXXXXXXX > /dev/null
fi
fi
他の投稿でこれを提案したことを知っていますdhclient-exit-hooks.d
。しかし、私の質問は、IPアドレスが変更されたときにこれらのサービスを自動的に再起動して設定する方法です。
答え1
懸念事項の分離に応じて、ソリューションをさらに簡素化/分割することをお勧めします。
- スクリプトは
/etc/dhcp/dhclient-exit-hooks.d/trigger_on_ip_change
アクションを実行する必要があるかどうかを判断し、アクションを別のスクリプトに延期する必要があります。/usr/local/bin/act_on_ip_change
- スクリプトは
/usr/local/bin/act_on_ip_change
必要な変更だけを行う必要があります。
これらの質問を区別することは次のとおりです。
dhclient
デバッグ中に、システムが実際に何も変更せずに正しく実行されているかどうかを独立してテストできます。- IPを更新(したがって緩んでいる)なしで「変更」をテストできます。
/usr/local/bin/act_on_ip_change
必要に応じて手動で実行できます。- こんな部分がわかりやすくなりますね
簡単に言えば、次の項目に含めることをお勧めします/etc/dhcp/dhclient-exit-hooks.d/trigger_on_ip_change_action
。
# based on /etc/dhcp/dhclient-exit-hooks.d/debug
if [ "$reason" = "BOUND" -a "$old_ip_address" != "$new_ip_address" ]; then
/usr/local/bin/act_on_ip_change
fi
答え2
答え3
最後に、IPアドレスの変更を処理するためにいくつかの設定を簡素化しました。
iptables
インターネットNATがMASQUERADEに変更されたため、ルールを維持してインストールするdhclient-exit-hooks.d
必要はありませんでしたiptables-persistent
。
iptables -A POSTROUTING -o eth0.101 ! -p esp -j MASQUERADE
apt-get install iptables-persistent
iptables-save > /etc/iptables/rules.v4
BINDはiptablesへの依存関係を認識しているため、起動時に失敗しなくなりました。
今はBINDを再起動しません。また、BINDは現在dnscrypt-proxy
インターネットに残っている暗号化に依存しているため、内部インターフェイスにのみバインドされます(変更されていません)。
exit_status
この変数はドキュメントに記載されていますが、dhclient-exit-hooks.d
明らかに少し混乱があり、終了ステータスを取得するのではなく、終了ステータスをDHCPに渡すためにのみ使用されます。
したがって、最終スクリプトは次のようになります。
#!/bin/bash
PATH=$PATH:/usr/bin
IP=`ip addr show eth0.101 | grep inet | awk ' { print $2 } ' | cut -f1 -d "/"`
OLDIP=`awk ' /xxxx.mooo.com/ { print $1 } ' /etc/hosts`
# if reboot or IP changed
if [ $reason = "REBOOT" ] || [ $reason = "BOUND" ] || [ $IP != $OLDIP ]
then
# put it in hosts
sed -i "s/^[0-9\.]* xxxx.mooo.com/$IP xxxx.mooo.com/g" /etc/hosts
timeout 60 /etc/init.d/ipsec restart
timeout 60 /etc/init.d/asterisk restart
# update FreeDNS service
timeout 60 /usr/bin/wget -O - http://freedns.afraid.org/dynamic/update.php?XXXX > /dev/null
fi
欠けているのは、起動時にexit_status
表示される変数です。dhclient-exit-hooks.d
requested_broadcast_address=1
new_network_number=95.94.xx.0
new_ip_address=95.94.xx.xx
new_dhcp_message_type=5
pid=1100
new_time_offset=0
new_routers=95.94.xx.xx
new_expiry=1462482903
new_subnet_mask=255.255.240.0
interface=eth0.101
requested_time_offset=1
new_domain_name=netcabo.pt
reason=REBOOT
new_time_servers=212.113.176.129 212.113.176.65
requested_routers=1
PATH=/usr/sbin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/bin
requested_subnet_mask=1
new_log_servers=212.113.188.209
new_dhcp_server_identifier=79.169.255.254
new_domain_name_servers=0.0.0.0 8.8.8.8
new_broadcast_address=95.94.xx.255
new_dhcp_renewal_time=7200
new_dhcp_rebinding_time=12600
PWD=/
new_next_server=0.0.0.0
new_dhcp_lease_time=14400