Хозяйке на заметку или как фильтровать по AS для cisco, quagga и asterisk

в 11:34, , рубрики: linux, Сетевые технологии, системное администрирование

Начинающие администраторы часто задаются вопросами:
— Как автоматизировать фильтрацию по as или as-set при раздаче BGP, используя cisco и quagga?
— Как отфильтровать абонента asterisk по провайдеру, если у абонента динамический ip?
Нет ничего проще, предлагаю пару простеньких скриптов на shell для этих целей.

Оба скрипта читают простейший конфигурационный файл.

Пример конфигурационного файла

# Комментарий

# Пример: фильтр, включающий в себя только as-set
[filter1]
AS-PROVIDER Необязательное описание as-set

# Пример: фильтр, включающий в себя только as
[filter2]
AS12345 Необязательное описание as
AS67890 Необязательное описание as

# Пример: фильтр, включающий в себя as и as-set
[filter3]
AS-PROVIDER Необязательное описание as-set
AS67890 Необязательное описание as

# Количество as и as-set внутри фильтра может быть любым

Первый скрипт называется cisco-filter.sh и использует конфигурационный файл /etc/cisco-filter.cfg

cisco-filter.sh

#!/bin/sh -e

WHOIS=whois.ripe.net

get_as() {
	echo "! $2"
	WHOIS_OUT=`whois -h $WHOIS -i origin $2`
	echo "${WHOIS_OUT}" | grep route: | sed 's/^.*:s*//' | while read ROUTE; do
		echo ip prefix-list $1 permit $ROUTE
	done
}

get_asset() {
	echo "!"
	echo "! $2"
	echo "!"
	AS_VAR_NAME=$(echo $2 | sed 's/[^a-zA-Z0-9_]//g')
	eval DONE_${AS_VAR_NAME}=$1
	WHOIS_OUT=`whois -h $WHOIS $2`
	echo "${WHOIS_OUT}" | grep members: | sed 's/^.*:s*//' | while read AS; do
		AS_VAR_NAME=$(echo $AS | sed 's/[^a-zA-Z0-9_]//g')
		eval AS_DONE=${DONE_${AS_VAR_NAME}}
		if [ "${AS_DONE}" != "$1" ]; then
			if echo $AS | grep -q '^AS[0-9].*' ; then
				get_as $1 $AS
			else
				get_asset $1 $AS
			fi
		fi
		eval DONE_${AS_VAR_NAME}=1
	done
}

FILTER=default
grep '^[^#].*' /etc/cisco-filter.cfg | while read AS NAME; do
	if echo $AS | grep -q '^[.*]$'; then
		FILTER=$(echo $AS | sed -r 's/^[(.*)]$/1/')
		echo "!"
		echo "! $FILTER"
		echo "!"
		echo "no ip prefix-list $FILTER"
	else
		if echo $AS | grep -q '^AS[0-9].*' ; then
			get_as $FILTER $AS
		else
			get_asset $FILTER $AS
		fi
	fi
done

После вызова необходимо обязательно проверить код возврата, если он нулевой, то вывод скрипта можно отправлять напрямую в quagga или cisco.

Пример вывода

!
! filter1
!
no ip prefix-list filter1
! AS34211
ip prefix-list filter1 permit 81.222.176.0/20
ip prefix-list filter1 permit 81.9.48.0/20
!
! filter2
!
no ip prefix-list filter2
! AS3212
ip prefix-list filter2 permit 178.79.64.0/18
ip prefix-list filter2 permit 194.152.0.0/19
ip prefix-list filter2 permit 213.161.0.0/19
ip prefix-list filter2 permit 82.149.0.0/19
ip prefix-list filter2 permit 86.58.0.0/17
ip prefix-list filter2 permit 86.58.64.0/18
ip prefix-list filter2 permit 91.212.251.0/24

Второй скрипт называется asterisk-filter.sh и использует конфигурационный файл /etc/asterisk-filter.cfg
Я его использую для фильтрации абонентов asterisk с динамическими адресами.

asterisk-filter.sh

#!/bin/sh -e

AST_CFG_PATH=/etc/asterisk
WHOIS=whois.ripe.net

get_as() {
	echo "; $2" >>${AST_CFG_PATH}/sip_permit_$FILTER.conf.tmp
	WHOIS_OUT=`whois -h $WHOIS -i origin $2`
	echo "${WHOIS_OUT}" | grep route: | sed 's/^.*:s*//' | while read ROUTE; do
		echo permit=$ROUTE >>${AST_CFG_PATH}/sip_permit_$FILTER.conf.tmp
	done
}

get_asset() {
	echo ";n; $2n;" >>${AST_CFG_PATH}/sip_permit_$FILTER.conf.tmp
	AS_VAR_NAME=$(echo $2 | sed 's/[^a-zA-Z0-9_]//g')
	eval DONE_${AS_VAR_NAME}=$1
	WHOIS_OUT=`whois -h $WHOIS $2`
	echo "${WHOIS_OUT}" | grep members: | sed 's/^.*:s*//' | while read AS; do
		AS_VAR_NAME=$(echo $AS | sed 's/[^a-zA-Z0-9_]//g')
		eval AS_DONE=${DONE_${AS_VAR_NAME}}
		if [ "${AS_DONE}" != "$1" ]; then
			if echo $AS | grep -q '^AS[0-9].*' ; then
				get_as $1 $AS
			else
				get_asset $1 $AS
			fi
		fi
		eval DONE_${AS_VAR_NAME}=1
	done
}

FILTER=default
grep '^[^#].*' /etc/asterisk-filter.cfg | while read AS NAME; do
	if echo $AS | grep -q '^[.*]$'; then
		FILTER=$(echo $AS | sed -r 's/^[(.*)]$/1/')
		echo ";n; Permission filter [$FILTER]n;n" > ${AST_CFG_PATH}/sip_permit_$FILTER.conf.tmp
	else
		if echo $AS | grep -q '^AS[0-9].*' ; then
			get_as $FILTER $AS
		else
			get_asset $FILTER $AS
		fi
	fi
done
for file in ${AST_CFG_PATH}/*tmp; do
	mv $file `echo $file|sed 's/.tmp$//'`
done

Скрипт создает в каталоге /etc/asterisk файлы вида: sip_permit_filtername.conf.

Пример файла sip_permit_onlime.conf

;
; Permission filter [onlime]
;

; AS42610
permit=109.173.0.0/17
permit=109.173.0.0/18
permit=109.173.64.0/18
permit=178.140.0.0/16
permit=188.255.0.0/17
permit=188.32.0.0/16
permit=37.110.0.0/17
permit=37.110.128.0/19
permit=37.204.0.0/16
permit=46.242.0.0/17
permit=77.37.128.0/17
permit=77.37.128.0/18
permit=77.37.192.0/18
permit=85.30.192.0/18
permit=95.84.128.0/18
permit=95.84.192.0/18

Пример использования внутри /etc/asterisk/sip.conf

[101]
    deny=0.0.0.0/0
    #include sip_permit_provider1.conf
    #include sip_permit_provider2.conf

[102]
    deny=0.0.0.0/0
    #include sip_permit_filter.conf

Как видите, ничего сложного. Надеюсь, кому-нибудь эта небольшая заметка облегчит его системно-администраторские будни. Спасибо за внимание.

Автор: nikbyte

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js