집에 데비안 서버가 있습니다. 서버는 내 라우터이며 외부 VPN 액세스를 제공합니다.
고정 IP 주소가 없습니다. ISP에서 제공하는 임대 시간은 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
모든 것이 잘 되면 0이 되어야 합니다 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