VPS를 실행 중이고 UFW를 사용하여 이를 보호하고 포트 80에 대한 연결만 허용하고 싶습니다. 하지만 원격으로 관리하려면 포트 22를 열어두고 집에서 액세스할 수 있도록 해야 합니다.
나는 특정 IP 주소의 포트로만 연결을 허용하도록 UFW를 구성할 수 있다는 것을 알고 있습니다.
ufw allow proto tcp from 123.123.123.123 to any port 22
하지만 내 IP 주소는 동적이므로 아직 해결 방법이 아닙니다.
질문은: 동적 DNS 확인을 위해 DynDNS를 사용하고 있는데 IP 대신 도메인을 사용하여 규칙을 생성할 수 있습니까?
나는 이것을 시도했습니다 :
ufw allow proto tcp from mydomain.dyndns.org to any port 22
하지만 난 얻었어ERROR: Bad source address
답변1
나는 이것이 가능하다고 믿지 않는다 ufw
. ufw
프런트엔드 iptables
에도 이 기능이 없기 때문에 한 가지 접근 방식은 주기적으로 실행되는 crontab 항목을 만들고 IP 주소가 변경되었는지 확인하는 것입니다. 있다면 업데이트됩니다.
다음을 수행하고 싶을 수도 있습니다.
$ iptables -A INPUT -p tcp --src mydomain.dyndns.org --dport 22 -j ACCEPT
그러나 이는 호스트 이름을 IP로 확인하고 이를 규칙에 사용하므로 나중에 IP가 변경되면 규칙이 적용되지 않습니다.
대안적인 아이디어
이라는 스크립트를 만들 수 있습니다 iptables_update.bash
.
#!/bin/bash
#allow a dyndns name
HOSTNAME=HOST_NAME_HERE
LOGFILE=LOGFILE_NAME_HERE
Current_IP=$(host $HOSTNAME | cut -f4 -d' ')
if [ $LOGFILE = "" ] ; then
iptables -I INPUT -i eth1 -s $Current_IP -j ACCEPT
echo $Current_IP > $LOGFILE
else
Old_IP=$(cat $LOGFILE)
if [ "$Current_IP" = "$Old_IP" ] ; then
echo IP address has not changed
else
iptables -D INPUT -i eth1 -s $Old_IP -j ACCEPT
iptables -I INPUT -i eth1 -s $Current_IP -j ACCEPT
/etc/init.d/iptables save
echo $Current_IP > $LOGFILE
echo iptables have been updated
fi
fi
원천:동적 IP 호스트 이름(예: dyndns.org)과 함께 IPTables 사용
이 스크립트를 저장한 후 다음과 같이 파일에 crontab 항목을 만들 수 있습니다 /etc/crontab
.
*/5 * * * * root /etc/iptables_update.bash > /dev/null 2>&1
그런 다음 항목은 5분마다 스크립트를 실행하여 호스트 이름에 할당된 IP 주소가 변경되었는지 확인합니다. 그렇다면 이를 허용하는 새 규칙을 생성하고 이전 IP 주소에 대한 이전 규칙을 삭제합니다.
답변2
나는 이것이 오래되었다는 것을 알고 있지만 그것을 발견하고 이 솔루션으로 끝났습니다. 로그 파일이 필요하지 않고 필요에 따라 추가 호스트를 쉽게 추가할 수 있기 때문에 더 좋아 보입니다. 기적적으로 작동합니다!
원천: http://rdstash.blogspot.ch/2013/09/allow-host-with-dynamic-ip-through.html
#!/bin/bash
DYNHOST=$1
DYNHOST=${DYNHOST:0:28}
DYNIP=$(host $DYNHOST | grep -iE "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+" |cut -f4 -d' '|head -n 1)
# Exit if invalid IP address is returned
case $DYNIP in
0.0.0.0 )
exit 1 ;;
255.255.255.255 )
exit 1 ;;
esac
# Exit if IP address not in proper format
if ! [[ $DYNIP =~ (([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]) ]]; then
exit 1
fi
# If chain for remote doesn't exist, create it
if ! /sbin/iptables -L $DYNHOST -n >/dev/null 2>&1 ; then
/sbin/iptables -N $DYNHOST >/dev/null 2>&1
fi
# Check IP address to see if the chain matches first; skip rest of script if update is not needed
if ! /sbin/iptables -n -L $DYNHOST | grep -iE " $DYNIP " >/dev/null 2>&1 ; then
# Flush old rules, and add new
/sbin/iptables -F $DYNHOST >/dev/null 2>&1
/sbin/iptables -I $DYNHOST -s $DYNIP -j ACCEPT
# Add chain to INPUT filter if it doesn't exist
if ! /sbin/iptables -C INPUT -t filter -j $DYNHOST >/dev/null 2>&1 ; then
/sbin/iptables -t filter -I INPUT -j $DYNHOST
fi
fi
답변3
이전 답변을 바탕으로 다음을 Debian Jessie의 bash 스크립트로 업데이트했습니다.
#!/bin/bash
HOSTNAME=dynamichost.domain.com
LOGFILE=$HOME/ufw.log
Current_IP=$(host $HOSTNAME | head -n1 | cut -f4 -d ' ')
if [ ! -f $LOGFILE ]; then
/usr/sbin/ufw allow from $Current_IP to any port 22 proto tcp
echo $Current_IP > $LOGFILE
else
Old_IP=$(cat $LOGFILE)
if [ "$Current_IP" = "$Old_IP" ] ; then
echo IP address has not changed
else
/usr/sbin/ufw delete allow from $Old_IP to any port 22 proto tcp
/usr/sbin/ufw allow from $Current_IP to any port 22 proto tcp
echo $Current_IP > $LOGFILE
echo iptables have been updated
fi
fi
답변4
이는 호스트 이름이 여러 엔드포인트(ufw)로 확인되는 경우 ipv4 및 ipv6 규칙을 추가하거나 제거할 수 있는 Python 버전입니다. "모든 항목 허용" 프로필로 시작하므로 내 시나리오는 약간 다릅니다.
Tim Kennedy와 Matthias Pettersson의 버전을 기반으로 함
#!/usr/bin/env python
# Only allow a particular HOSTNAME to access the given port...
# from https://unix.stackexchange.com/a/534117/66983
# and https://unix.stackexchange.com/a/91711/66983
# If the ufw table is empty you might need to execute the script twice (as inserting on top will not work properly)
# crontab -e and add '*/5 * * * * root /path/to/update_ufw.py > /dev/null 2>&1'
HOSTNAME="<hostname>"
PORT=<port>
import os
import subprocess
if os.geteuid() != 0:
print("This script must be run as root")
exit(1)
def run(cmd):
process = subprocess.Popen(['bash', '-c', cmd],
stdout=subprocess.PIPE)
stdout, stderr = process.communicate()
return stdout.decode('utf-8')
new_ip_output = run("getent ahosts \"{}\" | awk '{{ print $1 }}'".format(HOSTNAME))
new_ips=set(new_ip_output.split())
old_ip_output = run("/usr/sbin/ufw status | grep {} | head -n1 | tr -s ' ' | cut -f3 -d ' '".format(HOSTNAME))
old_ips=set(old_ip_output.split())
if old_ips == new_ips:
print ("All IPs still OK.")
else:
# add new IPs
for new_ip in new_ips:
if new_ip not in old_ips:
out = run("/usr/sbin/ufw insert 1 allow from {} to any port {} comment {}".format(new_ip, PORT, HOSTNAME))
print(out)
# remove old IPs
for old_ip in old_ips:
if old_ip not in new_ips:
out = run("/usr/sbin/ufw delete allow from {} to any port {}".format(old_ip, PORT))
print(out)
# add deny rule
out = run("/usr/sbin/ufw deny {}".format(PORT))
print(out)