Page Menu
Home
VyOS Platform
Search
Configure Global Search
Log In
Files
F119063723
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
82 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/data/templates/accel-ppp/ipoe.config.tmpl b/data/templates/accel-ppp/ipoe.config.tmpl
index 84de5bf51..fca520efa 100644
--- a/data/templates/accel-ppp/ipoe.config.tmpl
+++ b/data/templates/accel-ppp/ipoe.config.tmpl
@@ -1,111 +1,111 @@
### generated by ipoe.py ###
[modules]
log_syslog
ipoe
shaper
ipv6pool
ipv6_nd
ipv6_dhcp
ippool
{% if auth_mode == 'radius' %}
radius
{% elif auth_mode == 'local' %}
chap-secrets
{% endif %}
[core]
thread-count={{ thread_cnt }}
[log]
syslog=accel-ipoe,daemon
copy=1
level=5
[ipoe]
verbose=1
{% for interface in interfaces %}
{% if interface.vlan_mon %}
interface=re:{{ interface.name }}\.\d+,{% else %}interface={{ interface.name }},{% endif %}shared={{ interface.shared }},mode={{ interface.mode }},ifcfg={{ interface.ifcfg }},range={{ interface.range }},start={{ interface.sess_start }},ipv6=1
{% endfor %}
{% if auth_mode == 'noauth' %}
noauth=1
{% elif auth_mode == 'local' %}
username=ifname
password=csid
{% endif %}
{%- for interface in interfaces %}
{% if (interface.shared == '0') and (interface.vlan_mon) %}
vlan-mon={{ interface.name }},{{ interface.vlan_mon | join(',') }}
{% endif %}
{% endfor %}
{% if dnsv4 %}
[dns]
{% for dns in dnsv4 -%}
dns{{ loop.index }}={{ dns }}
{% endfor -%}
{% endif %}
{% if dnsv6 %}
[ipv6-dns]
{% for dns in dnsv6 -%}
{{ dns }}
{% endfor -%}
{% endif %}
[ipv6-nd]
verbose=1
[ipv6-dhcp]
verbose=1
{% if client_ipv6_pool %}
[ipv6-pool]
{% for p in client_ipv6_pool %}
{{ p.prefix }},{{ p.mask }}
{% endfor %}
{% for p in client_ipv6_delegate_prefix %}
delegate={{ p.prefix }},{{ p.mask }}
{% endfor %}
{% endif %}
{% if auth_mode == 'local' %}
[chap-secrets]
chap-secrets={{ chap_secrets_file }}
{% elif auth_mode == 'radius' %}
[radius]
verbose=1
{% for r in radius_server %}
-server={{ r.server }},{{ r.key }},auth-port={{ r.port }},req-limit=0,fail-time={{ r.fail_time }}
+server={{ r.server }},{{ r.key }},auth-port={{ r.port }},acct-port={{ r.acct_port }},req-limit=0,fail-time={{ r.fail_time }}
{% endfor -%}
acct-timeout={{ radius_acct_tmo }}
timeout={{ radius_timeout }}
max-try={{ radius_max_try }}
{% if radius_nas_id %}
nas-identifier={{ radius_nas_id }}
{% endif -%}
{% if radius_nas_ip %}
nas-ip-address={{ radius_nas_ip }}
{% endif -%}
{% if radius_source_address %}
bind={{ radius_source_address }}
{% endif -%}
{% if radius_dynamic_author %}
dae-server={{ radius_dynamic_author.server }}:{{ radius_dynamic_author.port }},{{ radius_dynamic_author.key }}
{% endif -%}
{% if radius_shaper_attr %}
[shaper]
verbose=1
attr={{ radius_shaper_attr }}
{% if radius_shaper_vendor %}
vendor={{ radius_shaper_vendor }}
{% endif -%}
{% endif -%}
{% endif %}
[cli]
tcp=127.0.0.1:2002
diff --git a/data/templates/accel-ppp/l2tp.config.tmpl b/data/templates/accel-ppp/l2tp.config.tmpl
index b0ef17525..b9131684d 100644
--- a/data/templates/accel-ppp/l2tp.config.tmpl
+++ b/data/templates/accel-ppp/l2tp.config.tmpl
@@ -1,148 +1,148 @@
### generated by accel_l2tp.py ###
[modules]
log_syslog
l2tp
chap-secrets
{% for proto in auth_proto: %}
{{proto}}
{% endfor%}
{% if auth_mode == 'radius' %}
radius
{% endif -%}
ippool
shaper
ipv6pool
ipv6_nd
ipv6_dhcp
[core]
thread-count={{thread_cnt}}
[log]
syslog=accel-l2tp,daemon
copy=1
level=5
{% if dnsv4 %}
[dns]
{% for dns in dnsv4 -%}
dns{{ loop.index }}={{ dns }}
{% endfor -%}
{% endif %}
{% if dnsv6 %}
[ipv6-dns]
{% for dns in dnsv6 -%}
{{ dns }}
{% endfor -%}
{% endif %}
{% if wins %}
[wins]
{% for server in wins -%}
wins{{ loop.index }}={{ server }}
{% endfor -%}
{% endif %}
[l2tp]
verbose=1
ifname=l2tp%d
ppp-max-mtu={{ mtu }}
mppe={{ ppp_mppe }}
{% if outside_addr %}
bind={{ outside_addr }}
{% endif %}
{% if lns_shared_secret %}
secret={{ lns_shared_secret }}
{% endif %}
[client-ip-range]
0.0.0.0/0
{% if client_ip_pool or client_ip_subnets %}
[ip-pool]
{% if client_ip_pool %}
{{ client_ip_pool }}
{% endif -%}
{% if client_ip_subnets %}
{% for sn in client_ip_subnets %}
{{sn}}
{% endfor -%}
{% endif %}
{% endif %}
{% if gateway_address %}
gw-ip-address={{ gateway_address }}
{% endif %}
{% if auth_mode == 'local' %}
[chap-secrets]
chap-secrets={{ chap_secrets_file }}
{% elif auth_mode == 'radius' %}
[radius]
verbose=1
{% for r in radius_server %}
-server={{ r.server }},{{ r.key }},auth-port={{ r.port }},req-limit=0,fail-time={{ r.fail_time }}
+server={{ r.server }},{{ r.key }},auth-port={{ r.port }},acct-port={{ r.acct_port }},req-limit=0,fail-time={{ r.fail_time }}
{% endfor -%}
acct-timeout={{ radius_acct_tmo }}
timeout={{ radius_timeout }}
max-try={{ radius_max_try }}
{% if radius_nas_id %}
nas-identifier={{ radius_nas_id }}
{% endif -%}
{% if radius_nas_ip %}
nas-ip-address={{ radius_nas_ip }}
{% endif -%}
{% if radius_source_address %}
bind={{ radius_source_address }}
{% endif -%}
{% endif %}
{% if gateway_address %}
gw-ip-address={{ gateway_address }}
{% endif %}
[ppp]
verbose=1
check-ip=1
single-session=replace
lcp-echo-timeout={{ ppp_echo_timeout }}
lcp-echo-interval={{ ppp_echo_interval }}
lcp-echo-failure={{ ppp_echo_failure }}
{% if ccp_disable %}
ccp=0
{% endif %}
{% if client_ipv6_pool %}
ipv6=allow
{% endif %}
{% if client_ipv6_pool %}
[ipv6-pool]
{% for p in client_ipv6_pool %}
{{ p.prefix }},{{ p.mask }}
{% endfor %}
{% for p in client_ipv6_delegate_prefix %}
delegate={{ p.prefix }},{{ p.mask }}
{% endfor %}
{% endif %}
{% if client_ipv6_delegate_prefix %}
[ipv6-dhcp]
verbose=1
{% endif %}
{% if radius_shaper_attr %}
[shaper]
verbose=1
attr={{ radius_shaper_attr }}
{% if radius_shaper_vendor %}
vendor={{ radius_shaper_vendor }}
{% endif -%}
{% endif %}
[cli]
tcp=127.0.0.1:2004
sessions-columns=ifname,username,calling-sid,ip,{{ ip6_column | join(',') }}{{ ',' if ip6_column }}rate-limit,type,comp,state,rx-bytes,tx-bytes,uptime
diff --git a/data/templates/accel-ppp/pppoe.config.tmpl b/data/templates/accel-ppp/pppoe.config.tmpl
index 370ca7946..5ad628fde 100644
--- a/data/templates/accel-ppp/pppoe.config.tmpl
+++ b/data/templates/accel-ppp/pppoe.config.tmpl
@@ -1,204 +1,204 @@
### generated by accel_pppoe.py ###
[modules]
log_syslog
pppoe
{% if auth_mode == 'radius' %}
radius
{% endif %}
chap-secrets
ippool
{% if ppp_ipv6 != 'deny' %}
ipv6pool
ipv6_nd
ipv6_dhcp
{% endif %}
{% for proto in auth_proto: %}
{{proto}}
{% endfor%}
shaper
{% if snmp %}
net-snmp
{% endif %}
{% if limits %}
connlimit
{% endif %}
[core]
thread-count={{ thread_cnt }}
[log]
syslog=accel-pppoe,daemon
copy=1
level=5
{% if snmp == 'enable-ma' %}
[snmp]
master=1
{% endif %}
[client-ip-range]
disable
{% if ppp_gw %}
[ip-pool]
gw-ip-address={{ ppp_gw }}
{% if client_ip_pool %}
{{ client_ip_pool }}
{% endif -%}
{% if client_ip_subnets %}
{% for subnet in client_ip_subnets %}
{{ subnet }}
{% endfor %}
{% endif %}
{% endif %}
{% if client_ipv6_pool %}
[ipv6-nd]
AdvAutonomousFlag=1
[ipv6-pool]
{% for p in client_ipv6_pool %}
{{ p.prefix }},{{ p.mask }}
{% endfor %}
{% for p in client_ipv6_delegate_prefix %}
delegate={{ p.prefix }},{{ p.mask }}
{% endfor %}
{% endif %}
{% if dnsv4 %}
[dns]
{% for dns in dnsv4 -%}
dns{{ loop.index }}={{ dns }}
{% endfor -%}
{% endif %}
{% if dnsv6 %}
[ipv6-dns]
{% for dns in dnsv6 -%}
{{ dns }}
{% endfor -%}
{% endif %}
{% if wins %}
[wins]
{% for server in wins -%}
wins{{ loop.index }}={{ server }}
{% endfor -%}
{% endif %}
{% if auth_mode == 'local' %}
[chap-secrets]
chap-secrets={{ chap_secrets_file }}
{% elif auth_mode == 'radius' %}
[radius]
verbose=1
{% for r in radius_server %}
-server={{ r.server }},{{ r.key }},auth-port={{ r.port }},req-limit=0,fail-time={{ r.fail_time }}
+server={{ r.server }},{{ r.key }},auth-port={{ r.port }},acct-port={{ r.acct_port }},req-limit=0,fail-time={{ r.fail_time }}
{% endfor -%}
acct-timeout={{ radius_acct_tmo }}
timeout={{ radius_timeout }}
max-try={{ radius_max_try }}
{% if radius_nas_id %}
nas-identifier={{ radius_nas_id }}
{% endif -%}
{% if radius_nas_ip %}
nas-ip-address={{ radius_nas_ip }}
{% endif -%}
{% if radius_source_address %}
bind={{ radius_source_address }}
{% endif -%}
{% if radius_dynamic_author %}
dae-server={{ radius_dynamic_author.server }}:{{ radius_dynamic_author.port }},{{ radius_dynamic_author.key }}
{% endif -%}
{% endif %}
{% if ppp_gw %}
gw-ip-address={{ ppp_gw }}
{% endif %}
{% if sesscrtl != 'disable' %}
[common]
single-session={{ sesscrtl }}
{% endif %}
[ppp]
verbose=1
check-ip=1
{% if ppp_ccp %}
ccp=1
{% else %}
ccp=0
{% endif %}
{% if ppp_min_mtu %}
min-mtu={{ ppp_min_mtu }}
{% else %}
min-mtu={{ mtu }}
{% endif %}
{% if ppp_mru %}
mru={{ ppp_mru }}
{% endif %}
mppe={{ ppp_mppe }}
lcp-echo-interval={{ ppp_echo_interval }}
lcp-echo-timeout={{ ppp_echo_timeout }}
lcp-echo-failure={{ ppp_echo_failure }}
{% if ppp_ipv4 %}
ipv4={{ ppp_ipv4 }}
{% endif %}
{% if client_ipv6_pool %}
ipv6=allow
{% endif %}
{% if ppp_ipv6 %}
ipv6={{ ppp_ipv6 }}
{% if ppp_ipv6_intf_id %}
ipv6-intf-id={{ ppp_ipv6_intf_id }}
{% endif %}
{% if ppp_ipv6_peer_intf_id %}
ipv6-peer-intf-id={{ ppp_ipv6_peer_intf_id }}
{% endif %}
{% if ppp_ipv6_accept_peer_intf_id %}
ipv6-accept-peer-intf-id={{ ppp_ipv6_accept_peer_intf_id }}
{% endif %}
{% endif %}
mtu={{ mtu }}
[pppoe]
verbose=1
ac-name={{ concentrator }}
{% if interfaces %}
{% for interface in interfaces %}
interface={{ interface.name }}
{% if interface.vlans %}
vlan-mon={{ interface.name }},{{ interface.vlans | join(',') }}
interface=re:{{ interface.name }}\.\d+
{% endif %}
{% endfor -%}
{% endif -%}
{% if svc_name %}
service-name={{ svc_name|join(',') }}
{% endif -%}
{% if pado_delay %}
pado-delay={{ pado_delay }}
{% endif %}
{% if limits_burst or limits_connections or limits_connections %}
[connlimit]
{% if limits_connections %}
limit={{ limits_connections }}
{% endif %}
{% if limits_burst %}
burst={{ limits_burst }}
{% endif %}
{% if limits_timeout %}
timeout={{ limits_timeout }}
{% endif %}
{% endif %}
[cli]
tcp=127.0.0.1:2001
diff --git a/data/templates/accel-ppp/pptp.config.tmpl b/data/templates/accel-ppp/pptp.config.tmpl
index 0bbfc13c5..e0f2c6da9 100644
--- a/data/templates/accel-ppp/pptp.config.tmpl
+++ b/data/templates/accel-ppp/pptp.config.tmpl
@@ -1,89 +1,89 @@
### generated by accel_pptp.py ###
[modules]
log_syslog
pptp
ippool
{% if auth_mode == 'local' %}
chap-secrets
{% elif auth_mode == 'radius' %}
radius
{% endif -%}
{% for proto in auth_proto %}
{{proto}}
{% endfor %}
[core]
thread-count={{ thread_cnt }}
[log]
syslog=accel-pptp,daemon
copy=1
level=5
{% if dnsv4 %}
[dns]
{% for dns in dnsv4 -%}
dns{{ loop.index }}={{ dns }}
{% endfor -%}
{% endif %}
{% if wins %}
[wins]
{% for server in wins -%}
wins{{ loop.index }}={{ server }}
{% endfor -%}
{% endif %}
[pptp]
ifname=pptp%d
{% if outside_addr %}
bind={{ outside_addr }}
{% endif %}
verbose=1
ppp-max-mtu={{mtu}}
mppe={{ ppp_mppe }}
echo-interval=10
echo-failure=3
[client-ip-range]
0.0.0.0/0
[ip-pool]
tunnel={{ client_ip_pool }}
gw-ip-address={{ gw_ip }}
[ppp]
verbose=5
check-ip=1
single-session=replace
{% if auth_mode == 'local' %}
[chap-secrets]
chap-secrets={{ chap_secrets_file }}
{% elif auth_mode == 'radius' %}
[radius]
verbose=1
{% for r in radius_server %}
-server={{ r.server }},{{ r.key }},auth-port={{ r.port }},req-limit=0,fail-time={{ r.fail_time }}
+server={{ r.server }},{{ r.key }},auth-port={{ r.port }},acct-port={{ r.acct_port }},req-limit=0,fail-time={{ r.fail_time }}
{% endfor -%}
acct-timeout={{ radius_acct_tmo }}
timeout={{ radius_timeout }}
max-try={{ radius_max_try }}
{% if radius_nas_id %}
nas-identifier={{ radius_nas_id }}
{% endif -%}
{% if radius_nas_ip %}
nas-ip-address={{ radius_nas_ip }}
{% endif -%}
{% if radius_source_address %}
bind={{ radius_source_address }}
{% endif -%}
{% endif %}
[cli]
tcp=127.0.0.1:2003
diff --git a/data/templates/accel-ppp/sstp.config.tmpl b/data/templates/accel-ppp/sstp.config.tmpl
index 2c8c00023..c9e4a1d7d 100644
--- a/data/templates/accel-ppp/sstp.config.tmpl
+++ b/data/templates/accel-ppp/sstp.config.tmpl
@@ -1,146 +1,146 @@
### generated by vpn_sstp.py ###
[modules]
log_syslog
sstp
shaper
{% if auth_mode == 'local' %}
chap-secrets
{% elif auth_mode == 'radius' %}
radius
{% endif -%}
ippool
ipv6pool
ipv6_nd
ipv6_dhcp
{% for proto in auth_proto %}
{{proto}}
{% endfor %}
[core]
thread-count={{thread_cnt}}
[common]
single-session=replace
[log]
syslog=accel-sstp,daemon
copy=1
level=5
[client-ip-range]
disable
[sstp]
verbose=1
ifname=sstp%d
accept=ssl
ssl-ca-file={{ ssl_ca }}
ssl-pemfile={{ ssl_cert }}
ssl-keyfile={{ ssl_key }}
{% if client_ip_pool %}
[ip-pool]
gw-ip-address={{ client_gateway }}
{% for subnet in client_ip_pool %}
{{ subnet }}
{% endfor %}
{% endif %}
{% if dnsv4 %}
[dns]
{% for dns in dnsv4 -%}
dns{{ loop.index }}={{ dns }}
{% endfor -%}
{% endif %}
{% if dnsv6 %}
[ipv6-dns]
{% for dns in dnsv6 -%}
{{ dns }}
{% endfor -%}
{% endif %}
{% if auth_mode == 'local' %}
[chap-secrets]
chap-secrets={{ chap_secrets_file }}
{% elif auth_mode == 'radius' %}
[radius]
verbose=1
{% for r in radius_server %}
-server={{ r.server }},{{ r.key }},auth-port={{ r.port }},req-limit=0,fail-time={{ r.fail_time }}
+server={{ r.server }},{{ r.key }},auth-port={{ r.port }},acct-port={{ r.acct_port }},req-limit=0,fail-time={{ r.fail_time }}
{% endfor -%}
acct-timeout={{ radius_acct_tmo }}
timeout={{ radius_timeout }}
max-try={{ radius_max_try }}
{% if radius_nas_id %}
nas-identifier={{ radius_nas_id }}
{% endif -%}
{% if radius_nas_ip %}
nas-ip-address={{ radius_nas_ip }}
{% endif -%}
{% if radius_source_address %}
bind={{ radius_source_address }}
{% endif -%}
{% if radius_dynamic_author %}
dae-server={{ radius_dynamic_author.server }}:{{ radius_dynamic_author.port }},{{ radius_dynamic_author.key }}
{% endif -%}
{% endif %}
{% if client_gateway %}
gw-ip-address={{ client_gateway }}
{% endif %}
[ppp]
verbose=1
check-ip=1
{% if mtu %}
mtu={{ mtu }}
{% endif -%}
{% if client_ipv6_pool %}
ipv6=allow
{% endif %}
{% if ppp_mppe %}
mppe={{ ppp_mppe }}
{% endif -%}
{% if ppp_echo_interval %}
lcp-echo-interval={{ ppp_echo_interval }}
{% endif -%}
{% if ppp_echo_failure %}
lcp-echo-failure={{ ppp_echo_failure }}
{% endif -%}
{% if ppp_echo_timeout %}
lcp-echo-timeout={{ ppp_echo_timeout }}
{% endif %}
{% if client_ipv6_pool %}
[ipv6-pool]
{% for p in client_ipv6_pool %}
{{ p.prefix }},{{ p.mask }}
{% endfor %}
{% for p in client_ipv6_delegate_prefix %}
delegate={{ p.prefix }},{{ p.mask }}
{% endfor %}
{% endif %}
{% if client_ipv6_delegate_prefix %}
[ipv6-dhcp]
verbose=1
{% endif %}
{% if radius_shaper_attr %}
[shaper]
verbose=1
attr={{ radius_shaper_attr }}
{% if radius_shaper_vendor %}
vendor={{ radius_shaper_vendor }}
{% endif -%}
{% endif %}
[cli]
tcp=127.0.0.1:2005
diff --git a/interface-definitions/include/accel-radius-additions.xml.in b/interface-definitions/include/accel-radius-additions.xml.in
index 227a043cd..e37b68514 100644
--- a/interface-definitions/include/accel-radius-additions.xml.in
+++ b/interface-definitions/include/accel-radius-additions.xml.in
@@ -1,113 +1,125 @@
<node name="radius">
<children>
<tagNode name="server">
<children>
+ <leafNode name="acct-port">
+ <properties>
+ <help>Accounting port</help>
+ <valueHelp>
+ <format>1-65535</format>
+ <description>Numeric IP port (default: 1813)</description>
+ </valueHelp>
+ <constraint>
+ <validator name="numeric" argument="--range 1-65535"/>
+ </constraint>
+ </properties>
+ </leafNode>
<leafNode name="fail-time">
<properties>
<help>Mark server unavailable for <n> seconds on failure</help>
<valueHelp>
<format>0-600</format>
<description>Fail time penalty</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 0-600"/>
</constraint>
<constraintErrorMessage>Fail time must be between 0 and 600 seconds</constraintErrorMessage>
</properties>
</leafNode>
</children>
</tagNode>
<leafNode name="timeout">
<properties>
<help>Timeout in seconds to wait response from RADIUS server</help>
<valueHelp>
<format>1-60</format>
<description>Timeout in seconds</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 1-60"/>
</constraint>
<constraintErrorMessage>Timeout must be between 1 and 60 seconds</constraintErrorMessage>
</properties>
</leafNode>
<leafNode name="acct-timeout">
<properties>
<help>Timeout for Interim-Update packets, terminate session afterwards (default 3 seconds)</help>
<valueHelp>
<format>0-60</format>
<description>Timeout in seconds, 0 to keep active</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 0-60"/>
</constraint>
<constraintErrorMessage>Timeout must be between 0 and 60 seconds</constraintErrorMessage>
</properties>
</leafNode>
<leafNode name="max-try">
<properties>
<help>Number of tries to send Access-Request/Accounting-Request queries</help>
<valueHelp>
<format>1-20</format>
<description>Maximum tries</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 1-20"/>
</constraint>
<constraintErrorMessage>Maximum tries must be between 1 and 20</constraintErrorMessage>
</properties>
</leafNode>
<leafNode name="nas-identifier">
<properties>
<help>NAS-Identifier attribute sent to RADIUS</help>
</properties>
</leafNode>
<leafNode name="nas-ip-address">
<properties>
<help>NAS-IP-Address attribute sent to RADIUS</help>
<constraint>
<validator name="ipv4-address"/>
</constraint>
<valueHelp>
<format>ipv4</format>
<description>NAS-IP-Address attribute</description>
</valueHelp>
</properties>
</leafNode>
<node name="dynamic-author">
<properties>
<help>Dynamic Authorization Extension/Change of Authorization server</help>
</properties>
<children>
<leafNode name="server">
<properties>
<help>IP address for Dynamic Authorization Extension server (DM/CoA)</help>
<constraint>
<validator name="ipv4-address"/>
</constraint>
<valueHelp>
<format>ipv4</format>
<description>IPv4 address for aynamic authorization server</description>
</valueHelp>
</properties>
</leafNode>
<leafNode name="port">
<properties>
<help>Port for Dynamic Authorization Extension server (DM/CoA)</help>
<valueHelp>
<format>number</format>
<description>TCP port</description>
</valueHelp>
<constraint>
<validator name="numeric" argument="--range 1-65535"/>
</constraint>
</properties>
</leafNode>
<leafNode name="key">
<properties>
<help>Shared secret for Dynamic Authorization Extension server</help>
</properties>
</leafNode>
</children>
</node>
</children>
</node>
diff --git a/src/conf_mode/service_ipoe-server.py b/src/conf_mode/service_ipoe-server.py
index fbc1000dd..553cc2e97 100755
--- a/src/conf_mode/service_ipoe-server.py
+++ b/src/conf_mode/service_ipoe-server.py
@@ -1,305 +1,309 @@
#!/usr/bin/env python3
#
# Copyright (C) 2018-2020 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
import re
from copy import deepcopy
from stat import S_IRUSR, S_IWUSR, S_IRGRP
from sys import exit
from vyos.config import Config
from vyos.template import render
from vyos.util import call, get_half_cpus
from vyos.validate import is_ipv4
from vyos import ConfigError
from vyos import airbag
airbag.enable()
ipoe_conf = '/run/accel-pppd/ipoe.conf'
ipoe_chap_secrets = '/run/accel-pppd/ipoe.chap-secrets'
default_config_data = {
'auth_mode': 'local',
'auth_interfaces': [],
'chap_secrets_file': ipoe_chap_secrets, # used in Jinja2 template
'interfaces': [],
'dnsv4': [],
'dnsv6': [],
'client_ipv6_pool': [],
'client_ipv6_delegate_prefix': [],
'radius_server': [],
'radius_acct_tmo': '3',
'radius_max_try': '3',
'radius_timeout': '3',
'radius_nas_id': '',
'radius_nas_ip': '',
'radius_source_address': '',
'radius_shaper_attr': '',
'radius_shaper_vendor': '',
'radius_dynamic_author': '',
'thread_cnt': get_half_cpus()
}
def get_config():
conf = Config()
base_path = ['service', 'ipoe-server']
if not conf.exists(base_path):
return None
conf.set_level(base_path)
ipoe = deepcopy(default_config_data)
for interface in conf.list_nodes(['interface']):
tmp = {
'mode': 'L2',
'name': interface,
'shared': '1',
# may need a config option, can be dhcpv4 or up for unclassified pkts
'sess_start': 'dhcpv4',
'range': None,
'ifcfg': '1',
'vlan_mon': []
}
conf.set_level(base_path + ['interface', interface])
if conf.exists(['network-mode']):
tmp['mode'] = conf.return_value(['network-mode'])
if conf.exists(['network']):
mode = conf.return_value(['network'])
if mode == 'vlan':
tmp['shared'] = '0'
if conf.exists(['vlan-id']):
tmp['vlan_mon'] += conf.return_values(['vlan-id'])
if conf.exists(['vlan-range']):
tmp['vlan_mon'] += conf.return_values(['vlan-range'])
if conf.exists(['client-subnet']):
tmp['range'] = conf.return_value(['client-subnet'])
ipoe['interfaces'].append(tmp)
conf.set_level(base_path)
if conf.exists(['name-server']):
for name_server in conf.return_values(['name-server']):
if is_ipv4(name_server):
ipoe['dnsv4'].append(name_server)
else:
ipoe['dnsv6'].append(name_server)
if conf.exists(['authentication', 'mode']):
ipoe['auth_mode'] = conf.return_value(['authentication', 'mode'])
if conf.exists(['authentication', 'interface']):
for interface in conf.list_nodes(['authentication', 'interface']):
tmp = {
'name': interface,
'mac': []
}
for mac in conf.list_nodes(['authentication', 'interface', interface, 'mac-address']):
client = {
'address': mac,
'rate_download': '',
'rate_upload': '',
'vlan_id': ''
}
conf.set_level(base_path + ['authentication', 'interface', interface, 'mac-address', mac])
if conf.exists(['rate-limit', 'download']):
client['rate_download'] = conf.return_value(['rate-limit', 'download'])
if conf.exists(['rate-limit', 'upload']):
client['rate_upload'] = conf.return_value(['rate-limit', 'upload'])
if conf.exists(['vlan-id']):
client['vlan'] = conf.return_value(['vlan-id'])
tmp['mac'].append(client)
ipoe['auth_interfaces'].append(tmp)
conf.set_level(base_path)
#
# authentication mode radius servers and settings
if conf.exists(['authentication', 'mode', 'radius']):
for server in conf.list_nodes(['authentication', 'radius', 'server']):
radius = {
'server' : server,
'key' : '',
'fail_time' : 0,
- 'port' : '1812'
+ 'port' : '1812',
+ 'acct_port' : '1813'
}
conf.set_level(base_path + ['authentication', 'radius', 'server', server])
if conf.exists(['fail-time']):
radius['fail_time'] = conf.return_value(['fail-time'])
if conf.exists(['port']):
radius['port'] = conf.return_value(['port'])
+ if conf.exists(['acct-port']):
+ radius['acct_port'] = conf.return_value(['acct-port'])
+
if conf.exists(['key']):
radius['key'] = conf.return_value(['key'])
if not conf.exists(['disable']):
ipoe['radius_server'].append(radius)
#
# advanced radius-setting
conf.set_level(base_path + ['authentication', 'radius'])
if conf.exists(['acct-timeout']):
ipoe['radius_acct_tmo'] = conf.return_value(['acct-timeout'])
if conf.exists(['max-try']):
ipoe['radius_max_try'] = conf.return_value(['max-try'])
if conf.exists(['timeout']):
ipoe['radius_timeout'] = conf.return_value(['timeout'])
if conf.exists(['nas-identifier']):
ipoe['radius_nas_id'] = conf.return_value(['nas-identifier'])
if conf.exists(['nas-ip-address']):
ipoe['radius_nas_ip'] = conf.return_value(['nas-ip-address'])
if conf.exists(['source-address']):
ipoe['radius_source_address'] = conf.return_value(['source-address'])
# Dynamic Authorization Extensions (DOA)/Change Of Authentication (COA)
if conf.exists(['dynamic-author']):
dae = {
'port' : '',
'server' : '',
'key' : ''
}
if conf.exists(['dynamic-author', 'server']):
dae['server'] = conf.return_value(['dynamic-author', 'server'])
if conf.exists(['dynamic-author', 'port']):
dae['port'] = conf.return_value(['dynamic-author', 'port'])
if conf.exists(['dynamic-author', 'key']):
dae['key'] = conf.return_value(['dynamic-author', 'key'])
ipoe['radius_dynamic_author'] = dae
conf.set_level(base_path)
if conf.exists(['client-ipv6-pool', 'prefix']):
for prefix in conf.list_nodes(['client-ipv6-pool', 'prefix']):
tmp = {
'prefix': prefix,
'mask': '64'
}
if conf.exists(['client-ipv6-pool', 'prefix', prefix, 'mask']):
tmp['mask'] = conf.return_value(['client-ipv6-pool', 'prefix', prefix, 'mask'])
ipoe['client_ipv6_pool'].append(tmp)
if conf.exists(['client-ipv6-pool', 'delegate']):
for prefix in conf.list_nodes(['client-ipv6-pool', 'delegate']):
tmp = {
'prefix': prefix,
'mask': ''
}
if conf.exists(['client-ipv6-pool', 'delegate', prefix, 'delegation-prefix']):
tmp['mask'] = conf.return_value(['client-ipv6-pool', 'delegate', prefix, 'delegation-prefix'])
ipoe['client_ipv6_delegate_prefix'].append(tmp)
return ipoe
def verify(ipoe):
if not ipoe:
return None
if not ipoe['interfaces']:
raise ConfigError('No IPoE interface configured')
for interface in ipoe['interfaces']:
if not interface['range']:
raise ConfigError(f'No IPoE client subnet defined on interface "{ interface }"')
if len(ipoe['dnsv4']) > 2:
raise ConfigError('Not more then two IPv4 DNS name-servers can be configured')
if len(ipoe['dnsv6']) > 3:
raise ConfigError('Not more then three IPv6 DNS name-servers can be configured')
if ipoe['auth_mode'] == 'radius':
if len(ipoe['radius_server']) == 0:
raise ConfigError('RADIUS authentication requires at least one server')
for radius in ipoe['radius_server']:
if not radius['key']:
server = radius['server']
raise ConfigError(f'Missing RADIUS secret key for server "{ server }"')
if ipoe['client_ipv6_delegate_prefix'] and not ipoe['client_ipv6_pool']:
raise ConfigError('IPoE IPv6 deletate-prefix requires IPv6 prefix to be configured!')
return None
def generate(ipoe):
if not ipoe:
return None
render(ipoe_conf, 'accel-ppp/ipoe.config.tmpl', ipoe, trim_blocks=True)
if ipoe['auth_mode'] == 'local':
render(ipoe_chap_secrets, 'accel-ppp/chap-secrets.ipoe.tmpl', ipoe)
os.chmod(ipoe_chap_secrets, S_IRUSR | S_IWUSR | S_IRGRP)
else:
if os.path.exists(ipoe_chap_secrets):
os.unlink(ipoe_chap_secrets)
return None
def apply(ipoe):
if ipoe == None:
call('systemctl stop accel-ppp@ipoe.service')
for file in [ipoe_conf, ipoe_chap_secrets]:
if os.path.exists(file):
os.unlink(file)
return None
call('systemctl restart accel-ppp@ipoe.service')
if __name__ == '__main__':
try:
c = get_config()
verify(c)
generate(c)
apply(c)
except ConfigError as e:
print(e)
exit(1)
diff --git a/src/conf_mode/service_pppoe-server.py b/src/conf_mode/service_pppoe-server.py
index 3149bbb2f..a8357f653 100755
--- a/src/conf_mode/service_pppoe-server.py
+++ b/src/conf_mode/service_pppoe-server.py
@@ -1,466 +1,470 @@
#!/usr/bin/env python3
#
# Copyright (C) 2018-2020 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
import re
from copy import deepcopy
from stat import S_IRUSR, S_IWUSR, S_IRGRP
from sys import exit
from vyos.config import Config
from vyos.template import render
from vyos.util import call, get_half_cpus
from vyos.validate import is_ipv4
from vyos import ConfigError
from vyos import airbag
airbag.enable()
pppoe_conf = r'/run/accel-pppd/pppoe.conf'
pppoe_chap_secrets = r'/run/accel-pppd/pppoe.chap-secrets'
default_config_data = {
'auth_mode': 'local',
'auth_proto': ['auth_mschap_v2', 'auth_mschap_v1', 'auth_chap_md5', 'auth_pap'],
'chap_secrets_file': pppoe_chap_secrets, # used in Jinja2 template
'client_ip_pool': '',
'client_ip_subnets': [],
'client_ipv6_pool': [],
'client_ipv6_delegate_prefix': [],
'concentrator': 'vyos-ac',
'interfaces': [],
'local_users' : [],
'svc_name': [],
'dnsv4': [],
'dnsv6': [],
'wins': [],
'mtu': '1492',
'limits_burst': '',
'limits_connections': '',
'limits_timeout': '',
'pado_delay': '',
'ppp_ccp': False,
'ppp_gw': '',
'ppp_ipv4': '',
'ppp_ipv6': '',
'ppp_ipv6_accept_peer_intf_id': False,
'ppp_ipv6_intf_id': '',
'ppp_ipv6_peer_intf_id': '',
'ppp_echo_failure': '3',
'ppp_echo_interval': '30',
'ppp_echo_timeout': '0',
'ppp_min_mtu': '',
'ppp_mppe': 'prefer',
'ppp_mru': '',
'radius_server': [],
'radius_acct_tmo': '3',
'radius_max_try': '3',
'radius_timeout': '3',
'radius_nas_id': '',
'radius_nas_ip': '',
'radius_source_address': '',
'radius_shaper_attr': '',
'radius_shaper_vendor': '',
'radius_dynamic_author': '',
'sesscrtl': 'replace',
'snmp': False,
'thread_cnt': get_half_cpus()
}
def get_config():
conf = Config()
base_path = ['service', 'pppoe-server']
if not conf.exists(base_path):
return None
conf.set_level(base_path)
pppoe = deepcopy(default_config_data)
# general options
if conf.exists(['access-concentrator']):
pppoe['concentrator'] = conf.return_value(['access-concentrator'])
if conf.exists(['service-name']):
pppoe['svc_name'] = conf.return_values(['service-name'])
if conf.exists(['interface']):
for interface in conf.list_nodes(['interface']):
conf.set_level(base_path + ['interface', interface])
tmp = {
'name': interface,
'vlans': []
}
if conf.exists(['vlan-id']):
tmp['vlans'] += conf.return_values(['vlan-id'])
if conf.exists(['vlan-range']):
tmp['vlans'] += conf.return_values(['vlan-range'])
pppoe['interfaces'].append(tmp)
conf.set_level(base_path)
if conf.exists(['local-ip']):
pppoe['ppp_gw'] = conf.return_value(['local-ip'])
if conf.exists(['name-server']):
for name_server in conf.return_values(['name-server']):
if is_ipv4(name_server):
pppoe['dnsv4'].append(name_server)
else:
pppoe['dnsv6'].append(name_server)
if conf.exists(['wins-server']):
pppoe['wins'] = conf.return_values(['wins-server'])
if conf.exists(['client-ip-pool']):
if conf.exists(['client-ip-pool', 'start']) and conf.exists(['client-ip-pool', 'stop']):
start = conf.return_value(['client-ip-pool', 'start'])
stop = conf.return_value(['client-ip-pool', 'stop'])
pppoe['client_ip_pool'] = start + '-' + re.search('[0-9]+$', stop).group(0)
if conf.exists(['client-ip-pool', 'subnet']):
pppoe['client_ip_subnets'] = conf.return_values(['client-ip-pool', 'subnet'])
if conf.exists(['client-ipv6-pool', 'prefix']):
for prefix in conf.list_nodes(['client-ipv6-pool', 'prefix']):
tmp = {
'prefix': prefix,
'mask': '64'
}
if conf.exists(['client-ipv6-pool', 'prefix', prefix, 'mask']):
tmp['mask'] = conf.return_value(['client-ipv6-pool', 'prefix', prefix, 'mask'])
pppoe['client_ipv6_pool'].append(tmp)
if conf.exists(['client-ipv6-pool', 'delegate']):
for prefix in conf.list_nodes(['client-ipv6-pool', 'delegate']):
tmp = {
'prefix': prefix,
'mask': ''
}
if conf.exists(['client-ipv6-pool', 'delegate', prefix, 'delegation-prefix']):
tmp['mask'] = conf.return_value(['client-ipv6-pool', 'delegate', prefix, 'delegation-prefix'])
pppoe['client_ipv6_delegate_prefix'].append(tmp)
if conf.exists(['limits']):
if conf.exists(['limits', 'burst']):
pppoe['limits_burst'] = conf.return_value(['limits', 'burst'])
if conf.exists(['limits', 'connection-limit']):
pppoe['limits_connections'] = conf.return_value(['limits', 'connection-limit'])
if conf.exists(['limits', 'timeout']):
pppoe['limits_timeout'] = conf.return_value(['limits', 'timeout'])
if conf.exists(['snmp']):
pppoe['snmp'] = True
if conf.exists(['snmp', 'master-agent']):
pppoe['snmp'] = 'enable-ma'
# authentication mode local
if conf.exists(['authentication', 'mode']):
pppoe['auth_mode'] = conf.return_value(['authentication', 'mode'])
if conf.exists(['authentication', 'local-users']):
for username in conf.list_nodes(['authentication', 'local-users', 'username']):
user = {
'name' : username,
'password' : '',
'state' : 'enabled',
'ip' : '*',
'upload' : None,
'download' : None
}
conf.set_level(base_path + ['authentication', 'local-users', 'username', username])
if conf.exists(['password']):
user['password'] = conf.return_value(['password'])
if conf.exists(['disable']):
user['state'] = 'disable'
if conf.exists(['static-ip']):
user['ip'] = conf.return_value(['static-ip'])
if conf.exists(['rate-limit', 'download']):
user['download'] = conf.return_value(['rate-limit', 'download'])
if conf.exists(['rate-limit', 'upload']):
user['upload'] = conf.return_value(['rate-limit', 'upload'])
pppoe['local_users'].append(user)
conf.set_level(base_path)
if conf.exists(['authentication', 'protocols']):
auth_mods = {
'mschap-v2': 'auth_mschap_v2',
'mschap': 'auth_mschap_v1',
'chap': 'auth_chap_md5',
'pap': 'auth_pap'
}
pppoe['auth_proto'] = []
for proto in conf.return_values(['authentication', 'protocols']):
pppoe['auth_proto'].append(auth_mods[proto])
#
# authentication mode radius servers and settings
if conf.exists(['authentication', 'mode', 'radius']):
for server in conf.list_nodes(['authentication', 'radius', 'server']):
radius = {
'server' : server,
'key' : '',
'fail_time' : 0,
- 'port' : '1812'
+ 'port' : '1812',
+ 'acct_port' : '1813'
}
conf.set_level(base_path + ['authentication', 'radius', 'server', server])
if conf.exists(['fail-time']):
radius['fail_time'] = conf.return_value(['fail-time'])
if conf.exists(['port']):
radius['port'] = conf.return_value(['port'])
+ if conf.exists(['acct-port']):
+ radius['acct_port'] = conf.return_value(['acct-port'])
+
if conf.exists(['key']):
radius['key'] = conf.return_value(['key'])
if not conf.exists(['disable']):
pppoe['radius_server'].append(radius)
#
# advanced radius-setting
conf.set_level(base_path + ['authentication', 'radius'])
if conf.exists(['acct-timeout']):
pppoe['radius_acct_tmo'] = conf.return_value(['acct-timeout'])
if conf.exists(['max-try']):
pppoe['radius_max_try'] = conf.return_value(['max-try'])
if conf.exists(['timeout']):
pppoe['radius_timeout'] = conf.return_value(['timeout'])
if conf.exists(['nas-identifier']):
pppoe['radius_nas_id'] = conf.return_value(['nas-identifier'])
if conf.exists(['nas-ip-address']):
pppoe['radius_nas_ip'] = conf.return_value(['nas-ip-address'])
if conf.exists(['source-address']):
pppoe['radius_source_address'] = conf.return_value(['source-address'])
# Dynamic Authorization Extensions (DOA)/Change Of Authentication (COA)
if conf.exists(['dynamic-author']):
dae = {
'port' : '',
'server' : '',
'key' : ''
}
if conf.exists(['dynamic-author', 'server']):
dae['server'] = conf.return_value(['dynamic-author', 'server'])
if conf.exists(['dynamic-author', 'port']):
dae['port'] = conf.return_value(['dynamic-author', 'port'])
if conf.exists(['dynamic-author', 'key']):
dae['key'] = conf.return_value(['dynamic-author', 'key'])
pppoe['radius_dynamic_author'] = dae
# RADIUS based rate-limiter
if conf.exists(['rate-limit', 'enable']):
pppoe['radius_shaper_attr'] = 'Filter-Id'
c_attr = ['rate-limit', 'enable', 'attribute']
if conf.exists(c_attr):
pppoe['radius_shaper_attr'] = conf.return_value(c_attr)
c_vendor = ['rate-limit', 'enable', 'vendor']
if conf.exists(c_vendor):
pppoe['radius_shaper_vendor'] = conf.return_value(c_vendor)
# re-set config level
conf.set_level(base_path)
if conf.exists(['mtu']):
pppoe['mtu'] = conf.return_value(['mtu'])
if conf.exists(['session-control']):
pppoe['sesscrtl'] = conf.return_value(['session-control'])
# ppp_options
if conf.exists(['ppp-options']):
conf.set_level(base_path + ['ppp-options'])
if conf.exists(['ccp']):
pppoe['ppp_ccp'] = True
if conf.exists(['ipv4']):
pppoe['ppp_ipv4'] = conf.return_value(['ipv4'])
if conf.exists(['ipv6']):
pppoe['ppp_ipv6'] = conf.return_value(['ipv6'])
if conf.exists(['ipv6-accept-peer-intf-id']):
pppoe['ppp_ipv6_peer_intf_id'] = True
if conf.exists(['ipv6-intf-id']):
pppoe['ppp_ipv6_intf_id'] = conf.return_value(['ipv6-intf-id'])
if conf.exists(['ipv6-peer-intf-id']):
pppoe['ppp_ipv6_peer_intf_id'] = conf.return_value(['ipv6-peer-intf-id'])
if conf.exists(['lcp-echo-failure']):
pppoe['ppp_echo_failure'] = conf.return_value(['lcp-echo-failure'])
if conf.exists(['lcp-echo-failure']):
pppoe['ppp_echo_interval'] = conf.return_value(['lcp-echo-failure'])
if conf.exists(['lcp-echo-timeout']):
pppoe['ppp_echo_timeout'] = conf.return_value(['lcp-echo-timeout'])
if conf.exists(['min-mtu']):
pppoe['ppp_min_mtu'] = conf.return_value(['min-mtu'])
if conf.exists(['mppe']):
pppoe['ppp_mppe'] = conf.return_value(['mppe'])
if conf.exists(['mru']):
pppoe['ppp_mru'] = conf.return_value(['mru'])
if conf.exists(['pado-delay']):
pppoe['pado_delay'] = '0'
a = {}
for id in conf.list_nodes(['pado-delay']):
if not conf.return_value(['pado-delay', id, 'sessions']):
a[id] = 0
else:
a[id] = conf.return_value(['pado-delay', id, 'sessions'])
for k in sorted(a.keys()):
if k != sorted(a.keys())[-1]:
pppoe['pado_delay'] += ",{0}:{1}".format(k, a[k])
else:
pppoe['pado_delay'] += ",{0}:{1}".format('-1', a[k])
return pppoe
def verify(pppoe):
if not pppoe:
return None
# vertify auth settings
if pppoe['auth_mode'] == 'local':
if not pppoe['local_users']:
raise ConfigError('PPPoE local auth mode requires local users to be configured!')
for user in pppoe['local_users']:
username = user['name']
if not user['password']:
raise ConfigError(f'Password required for local user "{username}"')
# if up/download is set, check that both have a value
if user['upload'] and not user['download']:
raise ConfigError(f'Download speed value required for local user "{username}"')
if user['download'] and not user['upload']:
raise ConfigError(f'Upload speed value required for local user "{username}"')
elif pppoe['auth_mode'] == 'radius':
if len(pppoe['radius_server']) == 0:
raise ConfigError('RADIUS authentication requires at least one server')
for radius in pppoe['radius_server']:
if not radius['key']:
server = radius['server']
raise ConfigError(f'Missing RADIUS secret key for server "{ server }"')
if len(pppoe['wins']) > 2:
raise ConfigError('Not more then two IPv4 WINS name-servers can be configured')
if len(pppoe['dnsv4']) > 2:
raise ConfigError('Not more then two IPv4 DNS name-servers can be configured')
if len(pppoe['dnsv6']) > 3:
raise ConfigError('Not more then three IPv6 DNS name-servers can be configured')
# local ippool and gateway settings config checks
if pppoe['client_ip_subnets'] or pppoe['client_ip_pool']:
if not pppoe['ppp_gw']:
raise ConfigError('PPPoE server requires local IP to be configured')
if pppoe['ppp_gw'] and not pppoe['client_ip_subnets'] and not pppoe['client_ip_pool']:
print("Warning: No PPPoE client pool defined")
return None
def generate(pppoe):
if not pppoe:
return None
render(pppoe_conf, 'accel-ppp/pppoe.config.tmpl', pppoe, trim_blocks=True)
if pppoe['local_users']:
render(pppoe_chap_secrets, 'accel-ppp/chap-secrets.tmpl', pppoe, trim_blocks=True)
os.chmod(pppoe_chap_secrets, S_IRUSR | S_IWUSR | S_IRGRP)
else:
if os.path.exists(pppoe_chap_secrets):
os.unlink(pppoe_chap_secrets)
return None
def apply(pppoe):
if not pppoe:
call('systemctl stop accel-ppp@pppoe.service')
for file in [pppoe_conf, pppoe_chap_secrets]:
if os.path.exists(file):
os.unlink(file)
return None
call('systemctl restart accel-ppp@pppoe.service')
if __name__ == '__main__':
try:
c = get_config()
verify(c)
generate(c)
apply(c)
except ConfigError as e:
print(e)
exit(1)
diff --git a/src/conf_mode/vpn_l2tp.py b/src/conf_mode/vpn_l2tp.py
index 88df2902e..26ad1af84 100755
--- a/src/conf_mode/vpn_l2tp.py
+++ b/src/conf_mode/vpn_l2tp.py
@@ -1,377 +1,381 @@
#!/usr/bin/env python3
#
# Copyright (C) 2019-2020 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
import re
from copy import deepcopy
from stat import S_IRUSR, S_IWUSR, S_IRGRP
from sys import exit
from time import sleep
from ipaddress import ip_network
from vyos.config import Config
from vyos.util import call, get_half_cpus
from vyos.validate import is_ipv4
from vyos import ConfigError
from vyos.template import render
from vyos import airbag
airbag.enable()
l2tp_conf = '/run/accel-pppd/l2tp.conf'
l2tp_chap_secrets = '/run/accel-pppd/l2tp.chap-secrets'
default_config_data = {
'auth_mode': 'local',
'auth_ppp_mppe': 'prefer',
'auth_proto': ['auth_mschap_v2'],
'chap_secrets_file': l2tp_chap_secrets, # used in Jinja2 template
'client_ip_pool': None,
'client_ip_subnets': [],
'client_ipv6_pool': [],
'client_ipv6_delegate_prefix': [],
'dnsv4': [],
'dnsv6': [],
'gateway_address': '10.255.255.0',
'local_users' : [],
'mtu': '1436',
'outside_addr': '',
'ppp_mppe': 'prefer',
'ppp_echo_failure' : '3',
'ppp_echo_interval' : '30',
'ppp_echo_timeout': '0',
'radius_server': [],
'radius_acct_tmo': '3',
'radius_max_try': '3',
'radius_timeout': '3',
'radius_nas_id': '',
'radius_nas_ip': '',
'radius_source_address': '',
'radius_shaper_attr': '',
'radius_shaper_vendor': '',
'radius_dynamic_author': '',
'wins': [],
'ip6_column': [],
'thread_cnt': get_half_cpus()
}
def get_config():
conf = Config()
base_path = ['vpn', 'l2tp', 'remote-access']
if not conf.exists(base_path):
return None
conf.set_level(base_path)
l2tp = deepcopy(default_config_data)
### general options ###
if conf.exists(['name-server']):
for name_server in conf.return_values(['name-server']):
if is_ipv4(name_server):
l2tp['dnsv4'].append(name_server)
else:
l2tp['dnsv6'].append(name_server)
if conf.exists(['wins-server']):
l2tp['wins'] = conf.return_values(['wins-server'])
if conf.exists('outside-address'):
l2tp['outside_addr'] = conf.return_value('outside-address')
if conf.exists(['authentication', 'mode']):
l2tp['auth_mode'] = conf.return_value(['authentication', 'mode'])
if conf.exists(['authentication', 'protocols']):
auth_mods = {
'pap': 'auth_pap',
'chap': 'auth_chap_md5',
'mschap': 'auth_mschap_v1',
'mschap-v2': 'auth_mschap_v2'
}
for proto in conf.return_values(['authentication', 'protocols']):
l2tp['auth_proto'].append(auth_mods[proto])
if conf.exists(['authentication', 'mppe']):
l2tp['auth_ppp_mppe'] = conf.return_value(['authentication', 'mppe'])
#
# local auth
if conf.exists(['authentication', 'local-users']):
for username in conf.list_nodes(['authentication', 'local-users', 'username']):
user = {
'name' : username,
'password' : '',
'state' : 'enabled',
'ip' : '*',
'upload' : None,
'download' : None
}
conf.set_level(base_path + ['authentication', 'local-users', 'username', username])
if conf.exists(['password']):
user['password'] = conf.return_value(['password'])
if conf.exists(['disable']):
user['state'] = 'disable'
if conf.exists(['static-ip']):
user['ip'] = conf.return_value(['static-ip'])
if conf.exists(['rate-limit', 'download']):
user['download'] = conf.return_value(['rate-limit', 'download'])
if conf.exists(['rate-limit', 'upload']):
user['upload'] = conf.return_value(['rate-limit', 'upload'])
l2tp['local_users'].append(user)
#
# RADIUS auth and settings
conf.set_level(base_path + ['authentication', 'radius'])
if conf.exists(['server']):
for server in conf.list_nodes(['server']):
radius = {
'server' : server,
'key' : '',
'fail_time' : 0,
- 'port' : '1812'
+ 'port' : '1812',
+ 'acct_port' : '1813'
}
conf.set_level(base_path + ['authentication', 'radius', 'server', server])
if conf.exists(['fail-time']):
radius['fail_time'] = conf.return_value(['fail-time'])
if conf.exists(['port']):
radius['port'] = conf.return_value(['port'])
+ if conf.exists(['acct-port']):
+ radius['acct_port'] = conf.return_value(['acct-port'])
+
if conf.exists(['key']):
radius['key'] = conf.return_value(['key'])
if not conf.exists(['disable']):
l2tp['radius_server'].append(radius)
#
# advanced radius-setting
conf.set_level(base_path + ['authentication', 'radius'])
if conf.exists(['acct-timeout']):
l2tp['radius_acct_tmo'] = conf.return_value(['acct-timeout'])
if conf.exists(['max-try']):
l2tp['radius_max_try'] = conf.return_value(['max-try'])
if conf.exists(['timeout']):
l2tp['radius_timeout'] = conf.return_value(['timeout'])
if conf.exists(['nas-identifier']):
l2tp['radius_nas_id'] = conf.return_value(['nas-identifier'])
if conf.exists(['nas-ip-address']):
l2tp['radius_nas_ip'] = conf.return_value(['nas-ip-address'])
if conf.exists(['source-address']):
l2tp['radius_source_address'] = conf.return_value(['source-address'])
# Dynamic Authorization Extensions (DOA)/Change Of Authentication (COA)
if conf.exists(['dynamic-author']):
dae = {
'port' : '',
'server' : '',
'key' : ''
}
if conf.exists(['dynamic-author', 'server']):
dae['server'] = conf.return_value(['dynamic-author', 'server'])
if conf.exists(['dynamic-author', 'port']):
dae['port'] = conf.return_value(['dynamic-author', 'port'])
if conf.exists(['dynamic-author', 'key']):
dae['key'] = conf.return_value(['dynamic-author', 'key'])
l2tp['radius_dynamic_author'] = dae
if conf.exists(['rate-limit', 'enable']):
l2tp['radius_shaper_attr'] = 'Filter-Id'
c_attr = ['rate-limit', 'enable', 'attribute']
if conf.exists(c_attr):
l2tp['radius_shaper_attr'] = conf.return_value(c_attr)
c_vendor = ['rate-limit', 'enable', 'vendor']
if conf.exists(c_vendor):
l2tp['radius_shaper_vendor'] = conf.return_value(c_vendor)
conf.set_level(base_path)
if conf.exists(['client-ip-pool']):
if conf.exists(['client-ip-pool', 'start']) and conf.exists(['client-ip-pool', 'stop']):
start = conf.return_value(['client-ip-pool', 'start'])
stop = conf.return_value(['client-ip-pool', 'stop'])
l2tp['client_ip_pool'] = start + '-' + re.search('[0-9]+$', stop).group(0)
if conf.exists(['client-ip-pool', 'subnet']):
l2tp['client_ip_subnets'] = conf.return_values(['client-ip-pool', 'subnet'])
if conf.exists(['client-ipv6-pool', 'prefix']):
l2tp['ip6_column'].append('ip6')
for prefix in conf.list_nodes(['client-ipv6-pool', 'prefix']):
tmp = {
'prefix': prefix,
'mask': '64'
}
if conf.exists(['client-ipv6-pool', 'prefix', prefix, 'mask']):
tmp['mask'] = conf.return_value(['client-ipv6-pool', 'prefix', prefix, 'mask'])
l2tp['client_ipv6_pool'].append(tmp)
if conf.exists(['client-ipv6-pool', 'delegate']):
l2tp['ip6_column'].append('ip6-db')
for prefix in conf.list_nodes(['client-ipv6-pool', 'delegate']):
tmp = {
'prefix': prefix,
'mask': ''
}
if conf.exists(['client-ipv6-pool', 'delegate', prefix, 'delegation-prefix']):
tmp['mask'] = conf.return_value(['client-ipv6-pool', 'delegate', prefix, 'delegation-prefix'])
l2tp['client_ipv6_delegate_prefix'].append(tmp)
if conf.exists(['mtu']):
l2tp['mtu'] = conf.return_value(['mtu'])
# gateway address
if conf.exists(['gateway-address']):
l2tp['gateway_address'] = conf.return_value(['gateway-address'])
else:
# calculate gw-ip-address
if conf.exists(['client-ip-pool', 'start']):
# use start ip as gw-ip-address
l2tp['gateway_address'] = conf.return_value(['client-ip-pool', 'start'])
elif conf.exists(['client-ip-pool', 'subnet']):
# use first ip address from first defined pool
subnet = conf.return_values(['client-ip-pool', 'subnet'])[0]
subnet = ip_network(subnet)
l2tp['gateway_address'] = str(list(subnet.hosts())[0])
# LNS secret
if conf.exists(['lns', 'shared-secret']):
l2tp['lns_shared_secret'] = conf.return_value(['lns', 'shared-secret'])
if conf.exists(['ccp-disable']):
l2tp['ccp_disable'] = True
# PPP options
if conf.exists(['idle']):
l2tp['ppp_echo_timeout'] = conf.return_value(['idle'])
if conf.exists(['ppp-options', 'lcp-echo-failure']):
l2tp['ppp_echo_failure'] = conf.return_value(['ppp-options', 'lcp-echo-failure'])
if conf.exists(['ppp-options', 'lcp-echo-interval']):
l2tp['ppp_echo_interval'] = conf.return_value(['ppp-options', 'lcp-echo-interval'])
return l2tp
def verify(l2tp):
if not l2tp:
return None
if l2tp['auth_mode'] == 'local':
if not l2tp['local_users']:
raise ConfigError('L2TP local auth mode requires local users to be configured!')
for user in l2tp['local_users']:
if not user['password']:
raise ConfigError(f"Password required for user {user['name']}")
elif l2tp['auth_mode'] == 'radius':
if len(l2tp['radius_server']) == 0:
raise ConfigError("RADIUS authentication requires at least one server")
for radius in l2tp['radius_server']:
if not radius['key']:
raise ConfigError(f"Missing RADIUS secret for server { radius['key'] }")
# check for the existence of a client ip pool
if not (l2tp['client_ip_pool'] or l2tp['client_ip_subnets']):
raise ConfigError(
"set vpn l2tp remote-access client-ip-pool requires subnet or start/stop IP pool")
# check ipv6
if l2tp['client_ipv6_delegate_prefix'] and not l2tp['client_ipv6_pool']:
raise ConfigError('IPv6 prefix delegation requires client-ipv6-pool prefix')
for prefix in l2tp['client_ipv6_delegate_prefix']:
if not prefix['mask']:
raise ConfigError('Delegation-prefix required for individual delegated networks')
if len(l2tp['wins']) > 2:
raise ConfigError('Not more then two IPv4 WINS name-servers can be configured')
if len(l2tp['dnsv4']) > 2:
raise ConfigError('Not more then two IPv4 DNS name-servers can be configured')
if len(l2tp['dnsv6']) > 3:
raise ConfigError('Not more then three IPv6 DNS name-servers can be configured')
return None
def generate(l2tp):
if not l2tp:
return None
render(l2tp_conf, 'accel-ppp/l2tp.config.tmpl', l2tp, trim_blocks=True)
if l2tp['auth_mode'] == 'local':
render(l2tp_chap_secrets, 'accel-ppp/chap-secrets.tmpl', l2tp)
os.chmod(l2tp_chap_secrets, S_IRUSR | S_IWUSR | S_IRGRP)
else:
if os.path.exists(l2tp_chap_secrets):
os.unlink(l2tp_chap_secrets)
return None
def apply(l2tp):
if not l2tp:
call('systemctl stop accel-ppp@l2tp.service')
for file in [l2tp_chap_secrets, l2tp_conf]:
if os.path.exists(file):
os.unlink(file)
return None
call('systemctl restart accel-ppp@l2tp.service')
if __name__ == '__main__':
try:
c = get_config()
verify(c)
generate(c)
apply(c)
except ConfigError as e:
print(e)
exit(1)
diff --git a/src/conf_mode/vpn_pptp.py b/src/conf_mode/vpn_pptp.py
index 4536692d2..32cbadd74 100755
--- a/src/conf_mode/vpn_pptp.py
+++ b/src/conf_mode/vpn_pptp.py
@@ -1,282 +1,286 @@
#!/usr/bin/env python3
#
# Copyright (C) 2018-2020 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
import re
from copy import deepcopy
from stat import S_IRUSR, S_IWUSR, S_IRGRP
from sys import exit
from vyos.config import Config
from vyos.template import render
from vyos.util import call, get_half_cpus
from vyos import ConfigError
from vyos import airbag
airbag.enable()
pptp_conf = '/run/accel-pppd/pptp.conf'
pptp_chap_secrets = '/run/accel-pppd/pptp.chap-secrets'
default_pptp = {
'auth_mode' : 'local',
'local_users' : [],
'radius_server' : [],
'radius_acct_tmo' : '30',
'radius_max_try' : '3',
'radius_timeout' : '30',
'radius_nas_id' : '',
'radius_nas_ip' : '',
'radius_source_address' : '',
'radius_shaper_attr' : '',
'radius_shaper_vendor': '',
'radius_dynamic_author' : '',
'chap_secrets_file': pptp_chap_secrets, # used in Jinja2 template
'outside_addr': '',
'dnsv4': [],
'wins': [],
'client_ip_pool': '',
'mtu': '1436',
'auth_proto' : ['auth_mschap_v2'],
'ppp_mppe' : 'prefer',
'thread_cnt': get_half_cpus()
}
def get_config():
conf = Config()
base_path = ['vpn', 'pptp', 'remote-access']
if not conf.exists(base_path):
return None
pptp = deepcopy(default_pptp)
conf.set_level(base_path)
if conf.exists(['name-server']):
pptp['dnsv4'] = conf.return_values(['name-server'])
if conf.exists(['wins-server']):
pptp['wins'] = conf.return_values(['wins-server'])
if conf.exists(['outside-address']):
pptp['outside_addr'] = conf.return_value(['outside-address'])
if conf.exists(['authentication', 'mode']):
pptp['auth_mode'] = conf.return_value(['authentication', 'mode'])
#
# local auth
if conf.exists(['authentication', 'local-users']):
for username in conf.list_nodes(['authentication', 'local-users', 'username']):
user = {
'name': username,
'password' : '',
'state' : 'enabled',
'ip' : '*',
}
conf.set_level(base_path + ['authentication', 'local-users', 'username', username])
if conf.exists(['password']):
user['password'] = conf.return_value(['password'])
if conf.exists(['disable']):
user['state'] = 'disable'
if conf.exists(['static-ip']):
user['ip'] = conf.return_value(['static-ip'])
if not conf.exists(['disable']):
pptp['local_users'].append(user)
#
# RADIUS auth and settings
conf.set_level(base_path + ['authentication', 'radius'])
if conf.exists(['server']):
for server in conf.list_nodes(['server']):
radius = {
'server' : server,
'key' : '',
'fail_time' : 0,
- 'port' : '1812'
+ 'port' : '1812',
+ 'acct_port' : '1813'
}
conf.set_level(base_path + ['authentication', 'radius', 'server', server])
if conf.exists(['fail-time']):
radius['fail_time'] = conf.return_value(['fail-time'])
if conf.exists(['port']):
radius['port'] = conf.return_value(['port'])
+ if conf.exists(['acct-port']):
+ radius['acct_port'] = conf.return_value(['acct-port'])
+
if conf.exists(['key']):
radius['key'] = conf.return_value(['key'])
if not conf.exists(['disable']):
pptp['radius_server'].append(radius)
#
# advanced radius-setting
conf.set_level(base_path + ['authentication', 'radius'])
if conf.exists(['acct-timeout']):
pptp['radius_acct_tmo'] = conf.return_value(['acct-timeout'])
if conf.exists(['max-try']):
pptp['radius_max_try'] = conf.return_value(['max-try'])
if conf.exists(['timeout']):
pptp['radius_timeout'] = conf.return_value(['timeout'])
if conf.exists(['nas-identifier']):
pptp['radius_nas_id'] = conf.return_value(['nas-identifier'])
if conf.exists(['nas-ip-address']):
pptp['radius_nas_ip'] = conf.return_value(['nas-ip-address'])
if conf.exists(['source-address']):
pptp['radius_source_address'] = conf.return_value(['source-address'])
# Dynamic Authorization Extensions (DOA)/Change Of Authentication (COA)
if conf.exists(['dae-server']):
dae = {
'port' : '',
'server' : '',
'key' : ''
}
if conf.exists(['dynamic-author', 'ip-address']):
dae['server'] = conf.return_value(['dynamic-author', 'ip-address'])
if conf.exists(['dynamic-author', 'port']):
dae['port'] = conf.return_value(['dynamic-author', 'port'])
if conf.exists(['dynamic-author', 'key']):
dae['key'] = conf.return_value(['dynamic-author', 'key'])
pptp['radius_dynamic_author'] = dae
if conf.exists(['rate-limit', 'enable']):
pptp['radius_shaper_attr'] = 'Filter-Id'
c_attr = ['rate-limit', 'enable', 'attribute']
if conf.exists(c_attr):
pptp['radius_shaper_attr'] = conf.return_value(c_attr)
c_vendor = ['rate-limit', 'enable', 'vendor']
if conf.exists(c_vendor):
pptp['radius_shaper_vendor'] = conf.return_value(c_vendor)
conf.set_level(base_path)
if conf.exists(['client-ip-pool']):
if conf.exists(['client-ip-pool', 'start']) and conf.exists(['client-ip-pool', 'stop']):
start = conf.return_value(['client-ip-pool', 'start'])
stop = conf.return_value(['client-ip-pool', 'stop'])
pptp['client_ip_pool'] = start + '-' + re.search('[0-9]+$', stop).group(0)
if conf.exists(['mtu']):
pptp['mtu'] = conf.return_value(['mtu'])
# gateway address
if conf.exists(['gateway-address']):
pptp['gw_ip'] = conf.return_value(['gateway-address'])
else:
# calculate gw-ip-address
if conf.exists(['client-ip-pool', 'start']):
# use start ip as gw-ip-address
pptp['gateway_address'] = conf.return_value(['client-ip-pool', 'start'])
if conf.exists(['authentication', 'require']):
# clear default list content, now populate with actual CLI values
pptp['auth_proto'] = []
auth_mods = {
'pap': 'auth_pap',
'chap': 'auth_chap_md5',
'mschap': 'auth_mschap_v1',
'mschap-v2': 'auth_mschap_v2'
}
for proto in conf.return_values(['authentication', 'require']):
pptp['auth_proto'].append(auth_mods[proto])
if conf.exists(['authentication', 'mppe']):
pptp['ppp_mppe'] = conf.return_value(['authentication', 'mppe'])
return pptp
def verify(pptp):
if not pptp:
return None
if pptp['auth_mode'] == 'local':
if not pptp['local_users']:
raise ConfigError('PPTP local auth mode requires local users to be configured!')
for user in pptp['local_users']:
username = user['name']
if not user['password']:
raise ConfigError(f'Password required for local user "{username}"')
elif pptp['auth_mode'] == 'radius':
if len(pptp['radius_server']) == 0:
raise ConfigError('RADIUS authentication requires at least one server')
for radius in pptp['radius_server']:
if not radius['key']:
server = radius['server']
raise ConfigError(f'Missing RADIUS secret key for server "{ server }"')
if len(pptp['dnsv4']) > 2:
raise ConfigError('Not more then two IPv4 DNS name-servers can be configured')
if len(pptp['wins']) > 2:
raise ConfigError('Not more then two IPv4 WINS name-servers can be configured')
def generate(pptp):
if not pptp:
return None
render(pptp_conf, 'accel-ppp/pptp.config.tmpl', pptp, trim_blocks=True)
if pptp['local_users']:
render(pptp_chap_secrets, 'accel-ppp/chap-secrets.tmpl', pptp, trim_blocks=True)
os.chmod(pptp_chap_secrets, S_IRUSR | S_IWUSR | S_IRGRP)
else:
if os.path.exists(pptp_chap_secrets):
os.unlink(pptp_chap_secrets)
def apply(pptp):
if not pptp:
call('systemctl stop accel-ppp@pptp.service')
for file in [pptp_conf, pptp_chap_secrets]:
if os.path.exists(file):
os.unlink(file)
return None
call('systemctl restart accel-ppp@pptp.service')
if __name__ == '__main__':
try:
c = get_config()
verify(c)
generate(c)
apply(c)
except ConfigError as e:
print(e)
exit(1)
diff --git a/src/conf_mode/vpn_sstp.py b/src/conf_mode/vpn_sstp.py
index 4c4d8e403..ddb499bf4 100755
--- a/src/conf_mode/vpn_sstp.py
+++ b/src/conf_mode/vpn_sstp.py
@@ -1,383 +1,387 @@
#!/usr/bin/env python3
#
# Copyright (C) 2018-2020 VyOS maintainers and contributors
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or later as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
from time import sleep
from sys import exit
from copy import deepcopy
from stat import S_IRUSR, S_IWUSR, S_IRGRP
from vyos.config import Config
from vyos.template import render
from vyos.util import call, run, get_half_cpus
from vyos.validate import is_ipv4
from vyos import ConfigError
from vyos import airbag
airbag.enable()
sstp_conf = '/run/accel-pppd/sstp.conf'
sstp_chap_secrets = '/run/accel-pppd/sstp.chap-secrets'
default_config_data = {
'local_users' : [],
'auth_mode' : 'local',
'auth_proto' : ['auth_mschap_v2'],
'chap_secrets_file': sstp_chap_secrets, # used in Jinja2 template
'client_ip_pool' : [],
'client_ipv6_pool': [],
'client_ipv6_delegate_prefix': [],
'client_gateway': '',
'dnsv4' : [],
'dnsv6' : [],
'radius_server' : [],
'radius_acct_tmo' : '3',
'radius_max_try' : '3',
'radius_timeout' : '3',
'radius_nas_id' : '',
'radius_nas_ip' : '',
'radius_source_address' : '',
'radius_shaper_attr' : '',
'radius_shaper_vendor': '',
'radius_dynamic_author' : '',
'ssl_ca' : '',
'ssl_cert' : '',
'ssl_key' : '',
'mtu' : '',
'ppp_mppe' : 'prefer',
'ppp_echo_failure' : '',
'ppp_echo_interval' : '',
'ppp_echo_timeout' : '',
'thread_cnt' : get_half_cpus()
}
def get_config():
sstp = deepcopy(default_config_data)
base_path = ['vpn', 'sstp']
conf = Config()
if not conf.exists(base_path):
return None
conf.set_level(base_path)
if conf.exists(['authentication', 'mode']):
sstp['auth_mode'] = conf.return_value(['authentication', 'mode'])
#
# local auth
if conf.exists(['authentication', 'local-users']):
for username in conf.list_nodes(['authentication', 'local-users', 'username']):
user = {
'name' : username,
'password' : '',
'state' : 'enabled',
'ip' : '*',
'upload' : None,
'download' : None
}
conf.set_level(base_path + ['authentication', 'local-users', 'username', username])
if conf.exists(['password']):
user['password'] = conf.return_value(['password'])
if conf.exists(['disable']):
user['state'] = 'disable'
if conf.exists(['static-ip']):
user['ip'] = conf.return_value(['static-ip'])
if conf.exists(['rate-limit', 'download']):
user['download'] = conf.return_value(['rate-limit', 'download'])
if conf.exists(['rate-limit', 'upload']):
user['upload'] = conf.return_value(['rate-limit', 'upload'])
sstp['local_users'].append(user)
#
# RADIUS auth and settings
conf.set_level(base_path + ['authentication', 'radius'])
if conf.exists(['server']):
for server in conf.list_nodes(['server']):
radius = {
'server' : server,
'key' : '',
'fail_time' : 0,
- 'port' : '1812'
+ 'port' : '1812',
+ 'acct_port' : '1813'
}
conf.set_level(base_path + ['authentication', 'radius', 'server', server])
if conf.exists(['fail-time']):
radius['fail_time'] = conf.return_value(['fail-time'])
if conf.exists(['port']):
radius['port'] = conf.return_value(['port'])
+ if conf.exists(['acct-port']):
+ radius['acct_port'] = conf.return_value(['acct-port'])
+
if conf.exists(['key']):
radius['key'] = conf.return_value(['key'])
if not conf.exists(['disable']):
sstp['radius_server'].append(radius)
#
# advanced radius-setting
conf.set_level(base_path + ['authentication', 'radius'])
if conf.exists(['acct-timeout']):
sstp['radius_acct_tmo'] = conf.return_value(['acct-timeout'])
if conf.exists(['max-try']):
sstp['radius_max_try'] = conf.return_value(['max-try'])
if conf.exists(['timeout']):
sstp['radius_timeout'] = conf.return_value(['timeout'])
if conf.exists(['nas-identifier']):
sstp['radius_nas_id'] = conf.return_value(['nas-identifier'])
if conf.exists(['nas-ip-address']):
sstp['radius_nas_ip'] = conf.return_value(['nas-ip-address'])
if conf.exists(['source-address']):
sstp['radius_source_address'] = conf.return_value(['source-address'])
# Dynamic Authorization Extensions (DOA)/Change Of Authentication (COA)
if conf.exists(['dynamic-author']):
dae = {
'port' : '',
'server' : '',
'key' : ''
}
if conf.exists(['dynamic-author', 'server']):
dae['server'] = conf.return_value(['dynamic-author', 'server'])
if conf.exists(['dynamic-author', 'port']):
dae['port'] = conf.return_value(['dynamic-author', 'port'])
if conf.exists(['dynamic-author', 'key']):
dae['key'] = conf.return_value(['dynamic-author', 'key'])
sstp['radius_dynamic_author'] = dae
if conf.exists(['rate-limit', 'enable']):
sstp['radius_shaper_attr'] = 'Filter-Id'
c_attr = ['rate-limit', 'enable', 'attribute']
if conf.exists(c_attr):
sstp['radius_shaper_attr'] = conf.return_value(c_attr)
c_vendor = ['rate-limit', 'enable', 'vendor']
if conf.exists(c_vendor):
sstp['radius_shaper_vendor'] = conf.return_value(c_vendor)
#
# authentication protocols
conf.set_level(base_path + ['authentication'])
if conf.exists(['protocols']):
# clear default list content, now populate with actual CLI values
sstp['auth_proto'] = []
auth_mods = {
'pap': 'auth_pap',
'chap': 'auth_chap_md5',
'mschap': 'auth_mschap_v1',
'mschap-v2': 'auth_mschap_v2'
}
for proto in conf.return_values(['protocols']):
sstp['auth_proto'].append(auth_mods[proto])
#
# read in SSL certs
conf.set_level(base_path + ['ssl'])
if conf.exists(['ca-cert-file']):
sstp['ssl_ca'] = conf.return_value(['ca-cert-file'])
if conf.exists(['cert-file']):
sstp['ssl_cert'] = conf.return_value(['cert-file'])
if conf.exists(['key-file']):
sstp['ssl_key'] = conf.return_value(['key-file'])
#
# read in client IPv4 pool
conf.set_level(base_path + ['network-settings', 'client-ip-settings'])
if conf.exists(['subnet']):
sstp['client_ip_pool'] = conf.return_values(['subnet'])
if conf.exists(['gateway-address']):
sstp['client_gateway'] = conf.return_value(['gateway-address'])
#
# read in client IPv6 pool
conf.set_level(base_path + ['network-settings', 'client-ipv6-pool'])
if conf.exists(['prefix']):
for prefix in conf.list_nodes(['prefix']):
tmp = {
'prefix': prefix,
'mask': '64'
}
if conf.exists(['prefix', prefix, 'mask']):
tmp['mask'] = conf.return_value(['prefix', prefix, 'mask'])
sstp['client_ipv6_pool'].append(tmp)
if conf.exists(['delegate']):
for prefix in conf.list_nodes(['delegate']):
tmp = {
'prefix': prefix,
'mask': ''
}
if conf.exists(['delegate', prefix, 'delegation-prefix']):
tmp['mask'] = conf.return_value(['delegate', prefix, 'delegation-prefix'])
sstp['client_ipv6_delegate_prefix'].append(tmp)
#
# read in network settings
conf.set_level(base_path + ['network-settings'])
if conf.exists(['name-server']):
for name_server in conf.return_values(['name-server']):
if is_ipv4(name_server):
sstp['dnsv4'].append(name_server)
else:
sstp['dnsv6'].append(name_server)
if conf.exists(['mtu']):
sstp['mtu'] = conf.return_value(['mtu'])
#
# read in PPP stuff
conf.set_level(base_path + ['ppp-settings'])
if conf.exists('mppe'):
sstp['ppp_mppe'] = conf.return_value(['ppp-settings', 'mppe'])
if conf.exists(['lcp-echo-failure']):
sstp['ppp_echo_failure'] = conf.return_value(['lcp-echo-failure'])
if conf.exists(['lcp-echo-interval']):
sstp['ppp_echo_interval'] = conf.return_value(['lcp-echo-interval'])
if conf.exists(['lcp-echo-timeout']):
sstp['ppp_echo_timeout'] = conf.return_value(['lcp-echo-timeout'])
return sstp
def verify(sstp):
if sstp is None:
return None
# vertify auth settings
if sstp['auth_mode'] == 'local':
if not sstp['local_users']:
raise ConfigError('SSTP local auth mode requires local users to be configured!')
for user in sstp['local_users']:
username = user['name']
if not user['password']:
raise ConfigError(f'Password required for local user "{username}"')
# if up/download is set, check that both have a value
if user['upload'] and not user['download']:
raise ConfigError(f'Download speed value required for local user "{username}"')
if user['download'] and not user['upload']:
raise ConfigError(f'Upload speed value required for local user "{username}"')
if not sstp['client_ip_pool']:
raise ConfigError('Client IP subnet required')
if not sstp['client_gateway']:
raise ConfigError('Client gateway IP address required')
if len(sstp['dnsv4']) > 2:
raise ConfigError('Not more then two IPv4 DNS name-servers can be configured')
# check ipv6
if sstp['client_ipv6_delegate_prefix'] and not sstp['client_ipv6_pool']:
raise ConfigError('IPv6 prefix delegation requires client-ipv6-pool prefix')
for prefix in sstp['client_ipv6_delegate_prefix']:
if not prefix['mask']:
raise ConfigError('Delegation-prefix required for individual delegated networks')
if not sstp['ssl_ca'] or not sstp['ssl_cert'] or not sstp['ssl_key']:
raise ConfigError('One or more SSL certificates missing')
if not os.path.exists(sstp['ssl_ca']):
file = sstp['ssl_ca']
raise ConfigError(f'SSL CA certificate file "{file}" does not exist')
if not os.path.exists(sstp['ssl_cert']):
file = sstp['ssl_cert']
raise ConfigError(f'SSL public key file "{file}" does not exist')
if not os.path.exists(sstp['ssl_key']):
file = sstp['ssl_key']
raise ConfigError(f'SSL private key file "{file}" does not exist')
if sstp['auth_mode'] == 'radius':
if len(sstp['radius_server']) == 0:
raise ConfigError('RADIUS authentication requires at least one server')
for radius in sstp['radius_server']:
if not radius['key']:
server = radius['server']
raise ConfigError(f'Missing RADIUS secret key for server "{ server }"')
def generate(sstp):
if not sstp:
return None
# accel-cmd reload doesn't work so any change results in a restart of the daemon
render(sstp_conf, 'accel-ppp/sstp.config.tmpl', sstp, trim_blocks=True)
if sstp['local_users']:
render(sstp_chap_secrets, 'accel-ppp/chap-secrets.tmpl', sstp, trim_blocks=True)
os.chmod(sstp_chap_secrets, S_IRUSR | S_IWUSR | S_IRGRP)
else:
if os.path.exists(sstp_chap_secrets):
os.unlink(sstp_chap_secrets)
return sstp
def apply(sstp):
if not sstp:
call('systemctl stop accel-ppp@sstp.service')
for file in [sstp_chap_secrets, sstp_conf]:
if os.path.exists(file):
os.unlink(file)
return None
call('systemctl restart accel-ppp@sstp.service')
if __name__ == '__main__':
try:
c = get_config()
verify(c)
generate(c)
apply(c)
except ConfigError as e:
print(e)
exit(1)
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Fri, Nov 6, 9:03 AM (1 d, 16 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
4653680
Default Alt Text
(82 KB)
Attached To
Mode
rVYOSONEX vyos-1x
Attached
Detach File
Event Timeline
Log In to Comment