Описание работы с ng_nat

Проблемы установки, настройки и работы Правильной Операционной Системы

Модератор: terminus

Правила форума
Убедительная просьба юзать теги [cоde] при оформлении листингов.
Сообщения не оформленные должным образом имеют все шансы быть незамеченными.
Аватара пользователя
terminus
майор
Сообщения: 2305
Зарегистрирован: 2007-10-29 11:27:35
Откуда: Рига

Описание работы с ng_nat

Непрочитанное сообщение terminus » 2011-03-13 22:35:55

Последний раз редактировалось f_andrey 2011-03-25 17:01:45, всего редактировалось 1 раз.
Причина: Автору, выбирайте пожалуйста раздел соответствуюший тематике вашего сообщения.
Модель: AST-PM-105/0044; Тип: Универсальный, ремонтный; Название: Терминус; Род повреждения: Распад функций; Выводы: Сдать на слом.

Хостинговая компания Host-Food.ru
Хостинг HostFood.ru
 

Услуги хостинговой компании Host-Food.ru

Хостинг HostFood.ru

Тарифы на хостинг в России, от 12 рублей: https://www.host-food.ru/tariffs/hosting/
Тарифы на виртуальные сервера (VPS/VDS/KVM) в РФ, от 189 руб.: https://www.host-food.ru/tariffs/virtualny-server-vps/
Выделенные сервера, Россия, Москва, от 2000 рублей (HP Proliant G5, Intel Xeon E5430 (2.66GHz, Quad-Core, 12Mb), 8Gb RAM, 2x300Gb SAS HDD, P400i, 512Mb, BBU):
https://www.host-food.ru/tariffs/vydelennyi-server-ds/
Недорогие домены в популярных зонах: https://www.host-food.ru/domains/

Аватара пользователя
Alex Keda
стреляли...
Сообщения: 35477
Зарегистрирован: 2004-10-18 14:25:19
Откуда: Made in USSR
Контактная информация:

Re: Описание работы с ng_nat

Непрочитанное сообщение Alex Keda » 2011-03-25 12:51:18

намана

публиукем?
Убей их всех! Бог потом рассортирует...

Аватара пользователя
Zemskov
рядовой
Сообщения: 29
Зарегистрирован: 2009-07-29 14:02:16

Re: Описание работы с ng_nat

Непрочитанное сообщение Zemskov » 2011-03-25 14:44:58

Каждое из этих хначений в бинарном виде выражается с помощью установки одного разряда.
*значений
Вами тестировалась реализация LSNAT?

Аватара пользователя
terminus
майор
Сообщения: 2305
Зарегистрирован: 2007-10-29 11:27:35
Откуда: Рига

Re: Описание работы с ng_nat

Непрочитанное сообщение terminus » 2011-03-30 20:40:08

Не - специально не тестировал. Из описания ng_nat понятно, что после создания кокого-либо одиночного правила редирекции redirect_addr, redirect_port или redirect_proto мы можем прицепить к нему дополнительные адреса для LSNAT через этот самый

Код: Выделить всё

ngctl msg nat1: addserver { id=1 addr=1.2.3.4 port=8080}
где id=1 это соттв номер правила редирекции с которым мы манипулируем. Да и там где-то еще говорилось, что после добавления первого элемента пула, оригинальная настройка редирекции пропадает - старый адрес надо добавить еще разок, но уже через addserver.
Модель: AST-PM-105/0044; Тип: Универсальный, ремонтный; Название: Терминус; Род повреждения: Распад функций; Выводы: Сдать на слом.

terminus_
проходил мимо

Re: Описание работы с ng_nat

Непрочитанное сообщение terminus_ » 2013-08-31 23:59:40

похерил пароль на админку статей...

закину сюда исходник ng_nat.sh
на сайте nuclight'a он больше не доступен

Код: Выделить всё


#!/bin/sh
#
# $FreeBSD$
#

# PROVIDE: ng_nat
# REQUIRE: ipfw
# KEYWORD: nojail

. /etc/rc.subr
. /etc/network.subr

name="ng_nat"
rcvar=`set_rcvar`
start_precmd="ng_nat_precmd"
start_cmd="ng_nat_start"
stop_cmd="ng_nat_stop"
extra_commands="set_mode redirect_port redirect_proto redirect_address list_redirects delete_redirect"
set_mode_cmd="ng_nat_set_mode"
redirect_proto_cmd="ng_nat_redirect_proto"
redirect_port_cmd="ng_nat_redirect_port"
redirect_address_cmd="ng_nat_redirect_address"
list_redirects_cmd="ng_nat_list_redirects"
delete_redirect_cmd="ng_nat_delete_redirect"
required_modules="ng_nat ng_ipfw"
: ${ng_nat_enable:=NO}

_ngc=/usr/sbin/ngctl
_IPADDR_EXPR_REGEXP='[0-9]\{1,3\}.[0-9]\{1,3\}.[0-9]\{1,3\}.[0-9]\{1,3\}$'

ng_nat_precmd()
{
	local alias_addr cookies iface ipfw_rules node_name 

	if [ -z "${ng_nat_nodes}" ]; then
		warn '$ng_nat_nodes is not set'
		return 1
	fi

	for node_name in ${ng_nat_nodes}
	do
		eval iface=\"\$ng_nat_${node_name}_interface\"
		if [ -z "${iface}" ]; then
			eval warn \'\$ng_nat_${node_name}_interface is not set\'
			return 1
		fi

		eval cookies=\"\$ng_nat_${node_name}_cookies\"
		if [ -z "${cookies}" ]; then
			eval warn \'\$ng_nat_${node_name}_cookies is not set\'
			return 1
		fi

		eval ipfw_rules=\"\$ng_nat_${node_name}_ipfw_rules\"
		if [ -z "${ipfw_rules}" ]; then
			eval warn \'\$ng_nat_${node_name}_ipfw_rules is not set\'
			return 1
		fi
		
		if [ `expr "${iface}" : $_IPADDR_EXPR_REGEXP` -ne 0 ]; then
			alias_addr=${iface}
			eval ng_nat_${node_name}_alias_addr=${iface}
		else
			# if interface has several aliases, take first address
			alias_addr=$(ifconfig ${iface} | sed -Ene \
				'/^[[:space:]]*inet ([0-9.]*) .*$/{s//\1/;p;q' -e '}')
			eval ng_nat_${node_name}_alias_addr=${alias_addr}
		fi
	
		if [ `expr "${alias_addr}" : $_IPADDR_EXPR_REGEXP` -eq 0 ]; then
			warn "could not determine alias address for node ${node_name}"
			return 1
		fi
	done
	return 0
}

ng_nat_StrToAddrPortRange()
{
	local _argument _addr _port _port2 name_addr name_port name_port2 _wantaddr

	_argument=$1
	name_addr=$2
	name_port=$3
	name_port2=$4
	_wantaddr=$5
	_addr=
	_port=
	_port2=

	case $_argument in
	*:*-*)
		_addr=${_argument%%:*}
		_argument=${_argument##*:}
		_port=${_argument%%-*}
		_port2=${_argument##*-}
		;;
	*-*)
		_port=${_argument%%-*}
		_port2=${_argument##*-}
		;;
	*:*)
		_addr=${_argument%%:*}
		_port=${_argument##*:}
		;;
	*)
		if [ -n "$_wantaddr" ]; then
			_addr=$_argument
		else
			_port=$_argument
		fi
		;;
	esac
	if [ -n "$_port" ]; then
		if [ `expr "$_port" : "[0-9]\{1,5\}$"` -eq 0 ]; then
			warn "invalid $name_port"
			return 1
		fi
	fi
	if [ -n "$_port2" ]; then
		if [ `expr "$_port2" : "[0-9]\{1,5\}$"` -eq 0 ]; then
			warn "invalid $name_port interval"
			return 1
		fi
		if [ "$_port2" -le "$_port" ]; then
			warn "invalid $name_port interval"
			return 1
		fi
	fi
	if [ -n "$_addr" ]; then
		if [ `expr "$_addr" : $_IPADDR_EXPR_REGEXP` -eq 0 ]; then
			warn "invalid $name_addr"
			return 1
		fi
	fi

	setvar $name_addr $_addr
	setvar $name_port $_port
	setvar $name_port2 $_port2
	return 0
}

ng_nat_redirect_port()
{
	local name proto target _alias remote
	local _proto local_addr local_port alias_addr alias_port remote_addr remote_port
	local local_port2 alias_port2 lsnat id _target _remote_port

	name=$1
	proto=$2
	target=$3
	_alias=$4
	remote=$5

	if [ "udp" != "$proto" -a "tcp" != "$proto" ]; then
		warn "redirect_port: invalid protocol"
	fi

	_proto=`awk '{if ($1=="'"$proto"'") print $2}' /etc/protocols`
	if [ -z "$_proto" ]; then
		if [ `expr "$proto" : "[0-9]\{1,3\}$"` -eq 0 ]; then
			warn "redirect_port: invalid protocol"
			return 1
		fi
		_proto=$proto
	fi


	# Clear vars from previous context - user must specify addresses
	# explicitly if he wants
	alias_addr=
	lsnat=0
	_remote_port=

	# Parse aliasing address/port and possible port range
	ng_nat_StrToAddrPortRange "$_alias" alias_addr alias_port alias_port2 || return 1
	if [ -n "$alias_addr" ]; then
		alias_addr="alias_addr=$alias_addr"
	fi
	if [ -z "$alias_port" ]; then
		warn "redirect_port: missing alias port"
		return 1
	fi

	# Optional remote restriction
	ng_nat_StrToAddrPortRange "$remote" remote_addr remote_port remote_port2 yes || return 1
	if [ -n "$remote_addr" ]; then
		remote_addr="remote_addr=$remote_addr"
	fi
	if [ -n "$alias_port2" -a -n "$remote_port" ]; then
		if [ $((${remote_port2} - ${remote_port})) -ne $((${alias_port2} - ${alias_port}))  ]; then
			warn "redirect_port: remote port range of not equal size to alias port range"
			return 1
		fi
	fi

	# Now handle local addresses and possible LSNAT case
	case $target in
	*,*)
		local_addr=0.0.0.0
		local_port=65535
		lsnat=1
		target=`echo $target | sed 's/,/ /g'`
		;;
	*)
		ng_nat_StrToAddrPortRange "$target" local_addr local_port local_port2 || return 1
		;;
	esac
	if [ "$lsnat" -eq 1 -a -n "$alias_port2" ]; then
		warn "redirect_port: can't use port ranges with LSNAT"
		return 1
	fi
	if [ -z "$local_addr" ]; then
		warn "redirect_port: missing target address"
		return 1
	fi
	if [ -n "$local_port2" -a -z "$alias_port2" -o -z "$local_port2" -a -n "$alias_port2" ]; then
		warn "redirect_port: need two ranges, but only one specified"
		return 1
	fi
	if [ -n "$local_port2" -a "$alias_port2" ]; then
		if [ $((${local_port2} - ${local_port})) -ne $((${alias_port2} - ${alias_port})) ]; then
			warn "redirect_port: port ranges of not equal size"
			return 1
		fi
	fi

	# Add redirection and obtain it's ID, possibly for entire interval
	[ -z "$alias_port2" ] && alias_port2=$alias_port
	while [ "$alias_port" -le "$alias_port2" ]; do
		[ -n "$remote_port" ] && _remote_port="remote_port=$remote_port"
		id=`$_ngc msg ${name}: redirectport \{ proto=$_proto	\
			local_addr=$local_addr local_port=$local_port	\
			$alias_addr alias_port=$alias_port 		\
			$remote_addr $_remote_port			\
			description=\"$description\" \} | grep Args | awk '{print $2}'`
		if [ -z "$id" ]; then
			warn "redirect_port: $_ngc failure"
			return 1
		fi
		alias_port=$((${alias_port} + 1))
		local_port=$((${local_port} + 1))
		[ -n "$remote_port2" ] && remote_port=$((${remote_port} + 1))
	done

	if [ "$lsnat" -eq 1 ]; then
		for _target in $target; do
			ng_nat_StrToAddrPortRange "$_target" local_addr local_port local_port2
			if [ -z "$local_port" -o -z "$local_addr" ]; then
				warn "redirect_port: invalid LSNAT address/port pair"
				return 1
			fi
			$_ngc msg ${name}: addserver \{ id=$id addr=$local_addr port=$local_port \}
		done
	fi
}

ng_nat_redirect_proto()
{
	local name proto target _alias remote _proto _alias_a remote_a

	name=$1
	proto=$2
	target=$3
	_alias=$4
	remote=$5

	_proto=`awk '{if ($1=="'"$proto"'") print $2}' /etc/protocols`
	if [ -z "$_proto" ]; then
		if [ `expr "$proto" : "[0-9]\{1,3\}$"` -eq 0 ]; then
			warn "redirect_proto: invalid protocol"
			return 1
		fi
		_proto=$proto
	fi

	if [ -z "$target" ]; then
		warn "redirect_proto: missing target address"
		return 1
	fi
	if [ `expr "$target" : $_IPADDR_EXPR_REGEXP` -eq 0 ]; then
		warn "redirect_proto: invalid target address"
		return 1
	fi

	_alias_a=
	if [ -n "$_alias" ]; then
		if [ `expr "$_alias" : $_IPADDR_EXPR_REGEXP` -eq 0 ]; then
			warn "redirect_proto: invalid alias address"
			return 1
		fi
		_alias_a="alias_address=$_alias"
	fi

	remote_a=
	if [ -n "$remote" ]; then
		if [ `expr "$remote" : $_IPADDR_EXPR_REGEXP` -eq 0 ]; then
			warn "redirect_proto: invalid remote address"
			return 1
		fi
		remote_a="remote_address=$remote"
	fi

	$_ngc msg ${name}: redirectproto \{ proto=$_proto local_addr=$target \
		$_alias_a $remote_a description=\"$description\" \}
}

ng_nat_redirect_address()
{
	local name target local_addr alias_addr lsnat

	name=$1
	target=$2
	alias_addr=$3

	if [ `expr "$alias_addr" : $_IPADDR_EXPR_REGEXP` -eq 0 ]; then
		warn "redirect_address: invalid alias address"
		return 1
	fi

	lsnat=0
	case $target in
	*,*)
		local_addr=0.0.0.0
		lsnat=1
		target=`echo $target | sed 's/,/ /g'`
		;;
	*)
		local_addr=$target
		if [ `expr "$local_addr" : $_IPADDR_EXPR_REGEXP` -eq 0 ]; then
			warn "redirect_address: invalid local address"
			return 1
		fi
		;;
	esac

	id=`$_ngc msg ${name}: redirectaddr \{ local_addr=$local_addr	\
		alias_addr=$alias_addr					\
		description=\"$description\" \} | grep Args | awk '{print $2}'`
	if [ -z "$id" ]; then
		warn "redirect_address: $_ngc failure"
		return 1
	fi

	if [ "$lsnat" -eq 1 ]; then
		for local_addr in $target; do
			if [ `expr "$local_addr" : $_IPADDR_EXPR_REGEXP` -eq 0 ]; then
				warn "redirect_address: invalid local address"
				return 1
			fi
			$_ngc msg ${name}: addserver \{ id=$id addr=$local_addr port=65535 \}
		done
	fi
}

ng_nat_set_mode()
{
	local name flags args log deny_incoming same_ports unregistered_only
	local proxy_only reverse reset_on_addr_change

	name=$1
	log=0
	deny_incoming=0
	same_ports=0
	unregistered_only=0
	proxy_only=0
	reverse=0
	reset_on_addr_change=0

	shift
	args="$@"

	for _flag in $args; do
		case $_flag in
		log)
			log=1
			;;
		deny_incoming)
			deny_incoming=2
			;;
		same_ports)
			same_ports=4
			;;
		unregistered_only)
			unregistered_only=16
			;;
		reset_on_addr_change)
			reset_on_addr_change=32
			;;
		proxy_only)
			proxy_only=64
			;;
		reverse)
			reverse=128
			;;
		*)
			warn "set_mode: invalid flag $_flag"
			return 1
		esac
	done

	flags=$((${log} + ${deny_incoming} + ${same_ports} + ${unregistered_only} +
		${proxy_only} + ${reverse} + ${reset_on_addr_change}))
	$_ngc msg ${name}: setmode \{ flags=$flags mask=0xffffffff \}
}

ng_nat_list_redirects()
{
	local local_addr local_port alias_addr alias_port lsnat
	local id proto remote_addr remote_port description
	local total_count _total_count _line FMT_STR printf

	_total_count=0
	printf=/usr/bin/printf
	FMT_STR='%5s %5s %15s:%-5s %15s:%-5s %15s:%-5s %5s %-s\n'

	$_ngc msg $1: listredirects | tr -s '{}[]' ' \n\n ' | \
	sed -E '1,2d;s/Args(.*)(total_count=.*)[ ]+.*/\2/g' | \
	while read _line; do
		[ -z "$_line" ] && continue	# suppress empty lines
		id=0
		local_addr='*'
		local_port='*'
		alias_addr='*'
		alias_port='*'
		remote_addr='*'
		remote_port='*'
		proto='*'
		lsnat=0
		description=
		total_count=

		if [ `expr "$_line" : "Args"` -gt 0 ]; then
			# Empty list, sed regexp not matched
			echo No static redirects configured.
			break
		fi

		eval "`echo $_line | sed -E 's/=[0-9]+ /&\
/g'`"
		if [ -n "$total_count" ]; then
			# Have some list, remember count to output after all
			# and print header
			echo "List of static redirects for node $1 ($total_count total):"
			$printf "$FMT_STR" "ID" "PROTO" "LOCAL ADDR" "PORT"	\
				"ALIAS ADDR" "PORT" "REMOTE ADDR" "PORT"	\
				"LSNAT" "DESCRIPTION"
			total_count=
		else
			_proto=`awk '{if ($2=="'"$proto"'") print $1}' /etc/protocols`
			[ "$proto" -eq 259 ] && proto="!ADDR"	# redirect_address
			[ -n "$_proto" ] && [ "${#_proto}" -lt 6 ] && proto=$_proto
			$printf "$FMT_STR" "$id" "$proto" "$local_addr" "$local_port"	\
				"$alias_addr" "$alias_port" "$remote_addr" "$remote_port" \
				"$lsnat" "$description"
		fi
	done
}

ng_nat_delete_redirect()
{
	local node_name id

	node_name=$1
	id=$2

	$_ngc msg $node_name: redirectdelete $id >/dev/null 2>&1
}

ng_nat_start()
{
	local cookie_in cookie_out fwcmd ipfw_rule_in ipfw_rule_out node_name
	local _rule _varnum _redirect description target_address set_mode

	case ${firewall_quiet} in                                
	[Yy][Ee][Ss])
	        fwcmd="/sbin/ipfw -q"
	        ;;
	*)
        	fwcmd="/sbin/ipfw"
	        ;;
	esac

	for node_name in ${ng_nat_nodes}
	do
		eval set \$ng_nat_${node_name}_cookies
		if [ -z "$1" -o -z "$2" ]; then
			eval warn \"\$ng_nat_${node_name}_cookies set improperly\"
			return 1
		fi
		cookie_in=$1
		cookie_out=$2

		eval set \$ng_nat_${node_name}_ipfw_rules
		if [ -z "$1" -o -z "$2" ]; then
			eval warn \"\$ng_nat_${node_name}_ipfw_rules set improperly\"
			return 1
		fi
		
		ipfw_rule_in=$1
		ipfw_rule_out=$2

		eval iface=\$ng_nat_${node_name}_interface
		eval alias_addr=\$ng_nat_${node_name}_alias_addr

		$_ngc -f - <<EOT
mkpeer ipfw: nat ${cookie_out} out
name ipfw:${cookie_out} ${node_name}
connect ipfw: ${node_name}: ${cookie_in} in
msg ${node_name}: setaliasaddr ${alias_addr}
EOT

		_varnum=0
		while : ; do
			eval _rule=\$ng_nat_${node_name}_ipfw_rule${_varnum}
			if [ -n "${_rule}" ]; then
				${fwcmd} add ${_rule}
				_varnum=$((${_varnum} + 1))
			else
				break
			fi
		done

		if [ "${_varnum}" -eq 0 ]; then
			${fwcmd} add ${ipfw_rule_in} netgraph ${cookie_in} \
				all from any to any in recv ${iface}
			${fwcmd} add ${ipfw_rule_out} netgraph ${cookie_out} \
				all from any to any out xmit ${iface}
		fi

		# 
		# Optional settings - errors here do not interrupt script
		#

		# Set mode
		eval set_mode=\$ng_nat_${node_name}_set_mode
		[ -n "$set_mode" ] && ng_nat_set_mode ${node_name} ${set_mode}

		# Target address
		eval target_address=\$ng_nat_${node_name}_target_address
		if [ -n "$target_address" ]; then
			if [ `expr "$target_address" : $_IPADDR_EXPR_REGEXP` -eq 0 ]; then
				warn "invalid target address"
			else
				$_ngc msg ${node_name}: settarget $target_address
			fi
		fi

		# Port redirects
		_varnum=0
		while : ; do
			eval _redirect=\$ng_nat_${node_name}_redirect_port${_varnum}
			if [ -n "${_redirect}" ]; then
				eval description=\$ng_nat_${node_name}_redirect_port${_varnum}_description
				ng_nat_redirect_port ${node_name} ${_redirect} 
				_varnum=$((${_varnum} + 1))
			else
				break
			fi
		done

		# Proto redirects
		_varnum=0
		while : ; do
			eval _redirect=\$ng_nat_${node_name}_redirect_proto${_varnum}
			if [ -n "${_redirect}" ]; then
				eval description=\$ng_nat_${node_name}_redirect_proto${_varnum}_description
				ng_nat_redirect_proto ${node_name} ${_redirect} 
				_varnum=$((${_varnum} + 1))
			else
				break
			fi
		done

		# Address redirects
		_varnum=0
		while : ; do
			eval _redirect=\$ng_nat_${node_name}_redirect_address${_varnum}
			if [ -n "${_redirect}" ]; then
				eval description=\$ng_nat_${node_name}_redirect_address${_varnum}_description
				ng_nat_redirect_address ${node_name} ${_redirect} 
				_varnum=$((${_varnum} + 1))
			else
				break
			fi
		done

		# Proxy rules
		_varnum=0
		while : ; do
			eval _rule=\$ng_nat_${node_name}_proxy_rule${_varnum}
			if [ -n "${_rule}" ]; then
				$_ngc msg ${node_name}: proxyrule \"${_rule}\"
				_varnum=$((${_varnum} + 1))
			else
				break
			fi
		done
	done
}

ng_nat_stop()
{
	local fwcmd node_name _rules _prevnum rulenum

	case ${firewall_quiet} in                                
	[Yy][Ee][Ss])
	        fwcmd="/sbin/ipfw -q"
	        ;;
	*)
        	fwcmd="/sbin/ipfw"
	        ;;
	esac

	for node_name in ${ng_nat_nodes}
	do
		_prevnum=NO_RULE_YET
		eval _rules=\$ng_nat_${node_name}_ipfw_rules
		for rulenum in ${_rules}; do
			if [ "$rulenum" != "${_prevnum}" ]; then
				${fwcmd} delete "$rulenum"
			fi
			_prevnum=$rulenum
		done
	
		$_ngc shutdown ${node_name}:
	done
}

load_rc_config $name
run_rc_command $*



Аватара пользователя
vintovkin
ВДВ
Сообщения: 1291
Зарегистрирован: 2007-05-11 9:39:11
Откуда: CSKA

Re: Описание работы с ng_nat

Непрочитанное сообщение vintovkin » 2013-09-01 22:25:43

+1 за статью!
JunOS kernel based on FreeBSD UNIX.