Зміст

Встановлення та налаштування Accel-ppp на прикладі Debian 9

https://accel-ppp.org/wiki/doku.php?id=ru:start Офіційна документація

Збірка та встановлення

# apt-get update
# apt-get upgrade
# apt-get install -y build-essential git cmake gcc linux-headers-`uname -r` git libpcre3-dev libssl-dev liblua5.1-0-dev htop mc tcpdump vlan ethtool sudo
# git clone https://github.com/accel-ppp/accel-ppp /opt/accel-ppp-code
# mkdir /opt/accel-ppp-code/build
# cd /opt/accel-ppp-code/build/
# cmake -DBUILD_IPOE_DRIVER=TRUE -DBUILD_VLAN_MON_DRIVER=TRUE -DLUA=TRUE -DRADIUS=TRUE -DSHAPER=TRUE -DCMAKE_INSTALL_PREFIX=/usr -DKDIR=/usr/src/linux-headers-`uname -r` -DCPACK_TYPE=Debian9 ..
# make
# cpack -G DEB
# dpkg -i accel-ppp.deb
# mv /etc/accel-ppp.conf.dist /etc/accel-ppp.conf
# echo "ipoe" >> /etc/modules
# echo "vlan_mon" >> /etc/modules
# chmod +x /etc/init.d/accel-ppp
# systemctl enable accel-ppp.service
# echo "\$INCLUDE dictionary.accel-ppp" >> /usr/share/accel-ppp/radius/dictionary

Налаштування

Lua скрипт для формування username-мів (/etc/accel-ppp.lua):

/etc/accel-ppp.lua
#!lua
function macuser(pkt)
        return pkt:hdr('chaddr')
end
 
function opt82_v1(pkt)
        v,b1,b2,b3,b4,b5,b6=string.unpack(pkt:agent_remote_id(),'bbbbbb')
        return string.format("%02x:%02x:%02x:%02x:%02x:%02x", b1,b2,b3,b4,b5,b6)
end
 
function opt82_v2(pkt)
        if pkt:agent_circuit_id() ~= nil then
                if string.len(pkt:agent_remote_id()) ~= 0 then
                        v,b1,b2,b3,b4,b5,b6=string.unpack(pkt:agent_remote_id(),'bbbbbb')
                        return string.format("%02x:%02x:%02x:%02x:%02x:%02x", b1,b2,b3,b4,b5,b6)
                elseif (string.len(pkt:agent_remote_id()) == 0 and string.len(pkt:agent_circuit_id()) ~= 0) then
                        m1=string.sub(pkt:agent_circuit_id(),'-15','-14')
                        m2=string.sub(pkt:agent_circuit_id(),'-13','-12')
                        m3=string.sub(pkt:agent_circuit_id(),'-11','-10')
                        m4=string.sub(pkt:agent_circuit_id(),'-9','-8')
                        m5=string.sub(pkt:agent_circuit_id(),'-7','-6')
                        m6=string.sub(pkt:agent_circuit_id(),'-5','-4')
                        local username=m1..':'..m2..':'..m3..':'..m4..':'..m5..':'..m6
	                return username
                end
	else
        	return pkt:hdr('chaddr')
        end
end
 
function username(pkt)
	local username = string.sub(pkt:ifname(), string.find(pkt:ifname(), ".", 1, true)+1, 32)
		return username
end

Logrotate

Створимо конфігурацію для ротації логів (/etc/logrotate.d/accel-ppp):

/etc/logrotate.d/accel-ppp
/var/log/accel-ppp/*.log {
daily
rotate 3
missingok
sharedscripts
postrotate
test -r /var/run/accel-pppd.pid && kill -HUP `cat /var/run/accel-pppd.pid`
endscript
}

Firewall

Перевірте, що всі команди зі скрипта (vconfig, ifconfig, ethtool, iptables, ipset, dig, sysctl) у вас доступні. У разі відсутності будь-яких бінарників потрібно встановити їх самостійно.
Скрипт для запуску на автостарті. Наприклад у кронтаб:

@reboot /etc/firewall_start.sh
firewall_start.sh
#!/bin/bash
#
# firewall
#
# chkconfig: - 97 20
#
### BEGIN INIT INFO
# Provides:          firewall
# Required-Start:    $network
# Required-Stop:
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Description:       firewall builder
### END INIT INFO
 
lock_path=/var/lock/firewall.lock
 
# Список IPSETів
ipset_list=(
disabled
)
 
VC=`which vconfig`
IFC=`which ifconfig`
ETT=`which ethtool`
IPT=`which iptables`
IPS=`which ipset`
DIG=`which dig`
CTL=`which sysctl`
 
DNS_lookup="1.1.1.1"
 
# OUT інтерфейс (інтернет)
out_interface1="eth1"
 
# IP SRC-NAT для користувачів
out_ext_ip1="public_ip_for_nat"
 
# IP для редиректу на сторінку заглушки
REDIRECT_IP="10.100.1.2"
 
# назва IPSETа для дозволених IP
allowed_ipset="allowed"
 
# Список дозволених сайтів та IP
allowed_list=(
ubilling.isp
8.8.8.8
8.8.4.4
www.liqpay.com
liqpay.com
static.liqpay.com
ecommerce.liqpay.com
api.privatbank.ua
login.privatbank.ua
privat24.privatbank.ua
www.privat24.ua
privat24.ua
liqpay.com
www.liqpay.com
static.liqpay.com
ecommerce.liqpay.com
fonts.googleapis.com
ajax.googleapis.com
my-payments-p24.privatbank.ua
themes.googleusercontent.com
www.google-analytics.com
google-analytics.com
ssl.google-analytics.com
widget.siteheart.com
static.siteheart.com
www.googleadservices.com
stats.g.doubleclick.net
googleads.g.doubleclick.net
qrapi.privatbank.ua
js.honeybadger.io
socauth.privatbank.ua
www.googletagmanager.com
st.privatbank.ua
services.privatbank.ua
mypayments.privatbank.ua
client.siteheart.com
fonts.gstatic.com
esapi.siteheart.com
crm.privatbank.ua
)
 
postrouting() {
	# Очищаем NAT
	$IPT -t nat -F POSTROUTING
 
	# NAT для користувачів
	$IPT -t nat -A POSTROUTING -s 100.64.0.0/22 -o $out_interface1 -j SNAT --to-source $out_ext_ip1 --persisten
	echo "POSTROUTING done"
}
 
input() {
        $IPT -F INPUT
 
        # Якщо використовуєте Fail2ban SSH
        $IPT -N fail2ban-ssh
        $IPT -A INPUT -p tcp -m multiport --dports 22 -j fail2ban-ssh
        $IPT -A INPUT -i eth1 -s "mgmt_net" -j ACCEPT
        $IPT -A INPUT -p TCP -m state --state ESTABLISHED,RELATED -j ACCEPT
        $IPT -A INPUT -p UDP -m state --state ESTABLISHED,RELATED -j ACCEPT
        $IPT -A INPUT -p TCP -m multiport --dports 6881:6889 -m state --state NEW -j DROP
        $IPT -A INPUT -p UDP -m multiport --dports 6881:6889 -j DROP
        $IPT -A INPUT -p TCP -m multiport --dports 49001 -m state --state NEW -j DROP
        $IPT -A INPUT -p UDP -m multiport --dports 49001 -j DROP
        $IPT -A INPUT -p TCP -m multiport --dports 135,137,138,139,445 -j DROP
        echo "INPUT done"
}
 
raw_rules() {
	# очищуємо RAW таблиці
	$IPT -t raw -F PREROUTING
	$IPT -t raw -F OUTPUT
 
	echo "RAW rules done"
}
 
forward() {
	# Очищаем FORWARD
	$IPT -F FORWARD
 
	# Пропускаємо трафік до дозволених IP
  	$IPT -A FORWARD -m set --match-set $allowed_ipset dst -j ACCEPT
 
	# Блокуємо трафік користувачів у IPSETах
	for ipset_name in ${ipset_list[*]}
	do
		$IPT -A FORWARD -m set --match-set $ipset_name src -j REJECT --reject-with icmp-proto-unreach
	done
 
	echo "FORWARD done"
}
 
prerouting() {
	# Очищаємо PREROUTING
	$IPT -t nat -F PREROUTING
 
	# Пропускаємо трафік до дозволених IP
	$IPT -t nat -A PREROUTING -m set --match-set $allowed_ipset dst -j ACCEPT
 
	# Перенаправляємо користувачів з IPSETів на сторінки заглушки
	$IPT -t nat -A PREROUTING -m set --match-set disabled src -p tcp --dport 80 -j DNAT --to-destination $REDIRECT_IP:80
 
	echo "PREROUTING done"
}
 
allow() {
	# Очищаємо IPSET дозволених IP
	$IPS -F $allowed_ipset
 
	for row in ${allowed_list[*]}
	do
		# перевіряємо запис зі списку дозволених, чи є він IP адресою
		if [[ $row =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]];
		then
			# додаємо цей IP до списку дозволених
			$IPS add $allowed_ipset $row > /dev/null 2>&1
		else
			# запис виявився доменом, резолвимо його IP через dig
  			for ip in `$DIG $row +short @$DNS_lookup`
			do
				# додаємо отримані через dns IP-адреси до списку дозволених
				$IPS add $allowed_ipset $ip > /dev/null 2>&1
			done
		fi
	done
 
	echo "ALLOWED done"
}
 
start() {
	if [ -f $lock_path ]; then
	  echo "Firewall is running"
	  exit 0
	else
	  touch $lock_path
	fi
 
	echo "Start building firewall"
 
	for ipset_name in ${ipset_list[*]}
	do
	  $IPS -N $ipset_name iphash > /dev/null 2>&1
	done
 
	$IPS -N active iphash > /dev/null 2>&1
	$IPS -N $allowed_ipset iphash > /dev/null 2>&1
 
	allow
        input
	forward
	prerouting
	postrouting
	raw_rules
 
	$CTL -p > /dev/null 2>&1
 
	echo "Firewall rules created"
}
 
stop() {
	if [ ! -f $lock_path ]; then
	  echo "Firewall is stoped"
	  exit 0
	else
	  rm -f $lock_path
	fi
 
        $IPT -F INPUT
	$IPT -F FORWARD
	$IPT -t nat -F
	$IPT -t mangle -F
	$IPT -t raw -F PREROUTING
	$IPT -t raw -F OUTPUT
 
	$IPT -P FORWARD ACCEPT
 
	echo "FORWARD/NAT/RAW flushed"
 
	$CTL -p > /dev/null 2>&1
}
 
show() {
        $IPT -L INPUT -v -n --line-numbers
	$IPT -L FORWARD -v -n --line-numbers
	$IPT -t nat -L PREROUTING -v -n --line-numbers
	$IPT -t nat -L POSTROUTING -v -n --line-numbers
	$IPT -t raw -L -v -n --line-numbers
	$IPS list $allowed_ipset
}
 
case "$1" in
  start)
    start
    ;;
  stop)
    stop
    ;;
  restart)
    stop
    start
    ;;
  allow)
    allow
    ;;
  input)
    input
    ;;
  forward)
    forward
    ;;
  pre)
    prerouting
    ;;
  post)
    postrouting
    ;;
  raw)
    raw_rules
    ;;
  show)
    show
    ;;
  *)
    echo "Usage: $0 {start|stop|restart|allow|input|forward|pre|post|raw|show}"
esac

Рекомендації

→ MTU
Піднімати MTU необхідно тільки на qinq-інтерфейсі (bond і eth, що входять до нього), оскільки використовується зайвий тег. На саб-інтерфейсах з однією міткою можна не піднімати, оскільки поле vlan id і так у фреймі є і за рахунок тега не зростає.


→ Таблиця ARP
При кількостях сесій понад 700 і при режимі DHCP v4 необхідно правити sysctl, а саме розширювати таблицю ARP, так як нові ядра не пишуть лайку в dmesg і відбувається аномалія при параметрах за замовчуванням.

/etc/sysctl.conf
net.ipv4.neigh.default.gc_thresh1 = 4096
net.ipv4.neigh.default.gc_thresh2 = 8192
net.ipv4.neigh.default.gc_thresh3 = 12288

→ Для роботи шейпера\полісера на прикладі eth1

# cat /etc/network/interfaces.d/eth1
auto eth1
iface eth1 inet manual
    pre-up /sbin/ifconfig eth1 txqueuelen 10000
    pre-up /sbin/ifconfig eth1 mtu 9000
    pre-up /sbin/ethtool --offload eth1 rx off tx off 
    pre-up /sbin/ethtool -G eth1 tx 4096 rx 4096
    pre-up /sbin/ethtool -K eth1 tso off gso off gro off lro off
    pre-up /sbin/ethtool -K eth1 rxvlan off txvlan off
    pre-up /sbin/ethtool --set-priv-flags eth1 vlan-stag-rx on

→ Розподіл мережевих переривань для QINQ трафіку
Потрібно поставити драйвера з гіта

Підготовка FreeRADIUS

Не забуваємо про словник для нашого NAS. Правимо файл (на білінговому сервері!) /usr/local/etc/raddb/dictionary.
Розкоментуємо рядок із подальшим перезапуском freeradius.

$INCLUDE       /usr/local/etc/raddb/dictionary_preset/accel-ppp.dictionary

Так само, не забуваємо, що додавання нових серверів доступу вимагає перезапуску FreeRADIUS:

# service radiusd restart