From 8998b56a92debb423f8bec19e4953059c585b704 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Tue, 21 Apr 2020 17:55:08 +0200 Subject: vyos.util: migrate all cpu_count() occurances to common get_half_cpus() --- src/conf_mode/service_pppoe-server.py | 8 ++------ src/conf_mode/vpn_l2tp.py | 8 ++------ src/conf_mode/vpn_pptp.py | 15 ++------------- src/conf_mode/vpn_sstp.py | 8 ++------ 4 files changed, 8 insertions(+), 31 deletions(-) (limited to 'src/conf_mode') diff --git a/src/conf_mode/service_pppoe-server.py b/src/conf_mode/service_pppoe-server.py index 94eb675f7..066e997f6 100755 --- a/src/conf_mode/service_pppoe-server.py +++ b/src/conf_mode/service_pppoe-server.py @@ -23,7 +23,7 @@ from sys import exit from vyos.config import Config from vyos.template import render -from vyos.util import call +from vyos.util import call, get_half_cpus() from vyos.validate import is_ipv4 from vyos import ConfigError @@ -78,7 +78,7 @@ default_config_data = { 'radius_dynamic_author': '', 'sesscrtl': 'replace', 'snmp': False, - 'thread_cnt': '1' + 'thread_cnt': get_half_cpus() } def get_config(): @@ -90,10 +90,6 @@ def get_config(): conf.set_level(base_path) pppoe = deepcopy(default_config_data) - cpu = os.cpu_count() - if cpu > 1: - pppoe['thread_cnt'] = int(cpu/2) - # general options if conf.exists(['access-concentrator']): pppoe['concentrator'] = conf.return_value(['access-concentrator']) diff --git a/src/conf_mode/vpn_l2tp.py b/src/conf_mode/vpn_l2tp.py index a640e2a94..d8a1fb115 100755 --- a/src/conf_mode/vpn_l2tp.py +++ b/src/conf_mode/vpn_l2tp.py @@ -25,7 +25,7 @@ from time import sleep from ipaddress import ip_network from vyos.config import Config -from vyos.util import call +from vyos.util import call, get_half_cpus from vyos.validate import is_ipv4 from vyos import ConfigError from vyos.template import render @@ -65,7 +65,7 @@ default_config_data = { 'radius_dynamic_author': '', 'wins': [], 'ip6_column': [], - 'thread_cnt': 1 + 'thread_cnt': get_half_cpus() } def get_config(): @@ -77,10 +77,6 @@ def get_config(): conf.set_level(base_path) l2tp = deepcopy(default_config_data) - cpu = os.cpu_count() - if cpu > 1: - l2tp['thread_cnt'] = int(cpu/2) - ### general options ### if conf.exists(['name-server']): for name_server in conf.return_values(['name-server']): diff --git a/src/conf_mode/vpn_pptp.py b/src/conf_mode/vpn_pptp.py index 15b80f984..8108a9670 100755 --- a/src/conf_mode/vpn_pptp.py +++ b/src/conf_mode/vpn_pptp.py @@ -23,7 +23,7 @@ from time import sleep from vyos.config import Config from vyos import ConfigError -from vyos.util import run +from vyos.util import run, get_half_cpus from vyos.template import render @@ -79,6 +79,7 @@ def get_config(): 'wins': [], 'client_ip_pool': '', 'mtu': '1436', + 'thread_cnt': get_half_cpus() } ### general options ### @@ -206,18 +207,6 @@ def generate(c): if c == None: return None - # accel-cmd reload doesn't work so any change results in a restart of the daemon - try: - if os.cpu_count() == 1: - c['thread_cnt'] = 1 - else: - c['thread_cnt'] = int(os.cpu_count()/2) - except KeyError: - if os.cpu_count() == 1: - c['thread_cnt'] = 1 - else: - c['thread_cnt'] = int(os.cpu_count()/2) - render(pptp_conf, 'pptp/pptp.config.tmpl', c, trim_blocks=True) if c['authentication']['local-users']: diff --git a/src/conf_mode/vpn_sstp.py b/src/conf_mode/vpn_sstp.py index 9ec352290..90b4f1f34 100755 --- a/src/conf_mode/vpn_sstp.py +++ b/src/conf_mode/vpn_sstp.py @@ -23,7 +23,7 @@ from stat import S_IRUSR, S_IWUSR, S_IRGRP from vyos.config import Config from vyos import ConfigError -from vyos.util import call, run +from vyos.util import call, run, get_half_cpus from vyos.template import render @@ -56,7 +56,7 @@ default_config_data = { 'ppp_echo_failure' : '', 'ppp_echo_interval' : '', 'ppp_echo_timeout' : '', - 'thread_cnt' : 1 + 'thread_cnt' : get_half_cpus() } def get_config(): @@ -68,10 +68,6 @@ def get_config(): conf.set_level(base_path) - cpu = os.cpu_count() - if cpu > 1: - sstp['thread_cnt'] = int(cpu/2) - if conf.exists(['authentication', 'mode']): sstp['auth_mode'] = conf.return_value(['authentication', 'mode']) -- cgit v1.2.3 From c29e9344757e36a1bcc422ba49def457268659bf Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Tue, 21 Apr 2020 21:33:41 +0200 Subject: vpn: pptp: T2351: migrate from SysVinit to systemd --- data/templates/pptp/pptp.config.tmpl | 3 +- src/conf_mode/vpn_pptp.py | 175 ++++++++++++++--------------------- 2 files changed, 73 insertions(+), 105 deletions(-) (limited to 'src/conf_mode') diff --git a/data/templates/pptp/pptp.config.tmpl b/data/templates/pptp/pptp.config.tmpl index 2596507af..5f8395f2d 100644 --- a/data/templates/pptp/pptp.config.tmpl +++ b/data/templates/pptp/pptp.config.tmpl @@ -1,4 +1,3 @@ - ### generated by accel_pptp.py ### [modules] log_syslog @@ -63,7 +62,7 @@ gw-ip-address={{gw_ip}} {% if authentication['mode'] == 'local' %} [chap-secrets] -chap-secrets=/etc/accel-ppp/pptp/chap-secrets +chap-secrets={{ chap_secrets_file }} {% endif %} [ppp] diff --git a/src/conf_mode/vpn_pptp.py b/src/conf_mode/vpn_pptp.py index 8108a9670..9e8d1c08b 100755 --- a/src/conf_mode/vpn_pptp.py +++ b/src/conf_mode/vpn_pptp.py @@ -17,47 +17,36 @@ import os import re +from copy import deepcopy from socket import socket, AF_INET, SOCK_STREAM from sys import exit from time import sleep from vyos.config import Config from vyos import ConfigError -from vyos.util import run, get_half_cpus +from vyos.util import call, get_half_cpus from vyos.template import render +pptp_conf = '/run/accel-pppd/pptp.conf' +pptp_chap_secrets = '/run/accel-pppd/pptp.chap-secrets' -pidfile = r'/var/run/accel_pptp.pid' -pptp_cnf_dir = r'/etc/accel-ppp/pptp' -chap_secrets = pptp_cnf_dir + '/chap-secrets' -pptp_conf = pptp_cnf_dir + '/pptp.config' - -# config path creation -if not os.path.exists(pptp_cnf_dir): - os.makedirs(pptp_cnf_dir) - -def _chk_con(): - cnt = 0 - s = socket(AF_INET, SOCK_STREAM) - while True: - try: - s.connect(("127.0.0.1", 2003)) - break - except ConnectionRefusedError: - sleep(0.5) - cnt += 1 - if cnt == 100: - raise("failed to start pptp server") - break - - -def _accel_cmd(command): - return run('/usr/bin/accel-cmd -p 2003 {command}') - -### -# inline helper functions end -### - +default_pptp = { + 'authentication': { + 'mode': 'local', + 'local-users': { + }, + 'radiussrv': {}, + 'auth_proto': 'auth_mschap_v2', + 'mppe': 'require' + }, + 'chap_secrets_file': pptp_chap_secrets, # used in Jinja2 template + 'outside_addr': '', + 'dns': [], + 'wins': [], + 'client_ip_pool': '', + 'mtu': '1436', + 'thread_cnt': get_half_cpus() +} def get_config(): c = Config() @@ -65,43 +54,28 @@ def get_config(): return None c.set_level(['vpn', 'pptp', 'remote-access']) - config_data = { - 'authentication': { - 'mode': 'local', - 'local-users': { - }, - 'radiussrv': {}, - 'auth_proto': 'auth_mschap_v2', - 'mppe': 'require' - }, - 'outside_addr': '', - 'dns': [], - 'wins': [], - 'client_ip_pool': '', - 'mtu': '1436', - 'thread_cnt': get_half_cpus() - } + pptp = deepcopy(default_pptp) ### general options ### if c.exists(['dns-servers', 'server-1']): - config_data['dns'].append(c.return_value(['dns-servers', 'server-1'])) + pptp['dns'].append(c.return_value(['dns-servers', 'server-1'])) if c.exists(['dns-servers', 'server-2']): - config_data['dns'].append(c.return_value(['dns-servers', 'server-2'])) + pptp['dns'].append(c.return_value(['dns-servers', 'server-2'])) if c.exists(['wins-servers', 'server-1']): - config_data['wins'].append( + pptp['wins'].append( c.return_value(['wins-servers', 'server-1'])) if c.exists(['wins-servers', 'server-2']): - config_data['wins'].append( + pptp['wins'].append( c.return_value(['wins-servers', 'server-2'])) if c.exists(['outside-address']): - config_data['outside_addr'] = c.return_value(['outside-address']) + pptp['outside_addr'] = c.return_value(['outside-address']) # auth local if c.exists(['authentication', 'mode', 'local']): if c.exists(['authentication', 'local-users', 'username']): for usr in c.list_nodes(['authentication', 'local-users', 'username']): - config_data['authentication']['local-users'].update( + pptp['authentication']['local-users'].update( { usr: { 'passwd': '', @@ -112,18 +86,18 @@ def get_config(): ) if c.exists(['authentication', 'local-users', 'username', usr, 'password']): - config_data['authentication']['local-users'][usr]['passwd'] = c.return_value( + pptp['authentication']['local-users'][usr]['passwd'] = c.return_value( ['authentication', 'local-users', 'username', usr, 'password']) if c.exists(['authentication', 'local-users', 'username', usr, 'disable']): - config_data['authentication']['local-users'][usr]['state'] = 'disable' + pptp['authentication']['local-users'][usr]['state'] = 'disable' if c.exists(['authentication', 'local-users', 'username', usr, 'static-ip']): - config_data['authentication']['local-users'][usr]['ip'] = c.return_value( + pptp['authentication']['local-users'][usr]['ip'] = c.return_value( ['authentication', 'local-users', 'username', usr, 'static-ip']) # authentication mode radius servers and settings if c.exists(['authentication', 'mode', 'radius']): - config_data['authentication']['mode'] = 'radius' + pptp['authentication']['mode'] = 'radius' rsrvs = c.list_nodes(['authentication', 'radius', 'server']) for rsrv in rsrvs: if not c.return_value(['authentication', 'radius', 'server', rsrv, 'fail-time']): @@ -137,7 +111,7 @@ def get_config(): reql = c.return_value( ['authentication', 'radius', 'server', rsrv, 'req-limit']) - config_data['authentication']['radiussrv'].update( + pptp['authentication']['radiussrv'].update( { rsrv: { 'secret': c.return_value(['authentication', 'radius', 'server', rsrv, 'key']), @@ -149,91 +123,86 @@ def get_config(): if c.exists(['client-ip-pool']): if c.exists(['client-ip-pool', 'start']): - config_data['client_ip_pool'] = c.return_value( + pptp['client_ip_pool'] = c.return_value( ['client-ip-pool', 'start']) if c.exists(['client-ip-pool', 'stop']): - config_data['client_ip_pool'] += '-' + \ + pptp['client_ip_pool'] += '-' + \ re.search( '[0-9]+$', c.return_value(['client-ip-pool', 'stop'])).group(0) if c.exists(['mtu']): - config_data['mtu'] = c.return_value(['mtu']) + pptp['mtu'] = c.return_value(['mtu']) # gateway address if c.exists(['gateway-address']): - config_data['gw_ip'] = c.return_value(['gateway-address']) + pptp['gw_ip'] = c.return_value(['gateway-address']) else: - config_data['gw_ip'] = re.sub( - '[0-9]+$', '1', config_data['client_ip_pool']) + pptp['gw_ip'] = re.sub( + '[0-9]+$', '1', pptp['client_ip_pool']) if c.exists(['authentication', 'require']): if c.return_value(['authentication', 'require']) == 'pap': - config_data['authentication']['auth_proto'] = 'auth_pap' + pptp['authentication']['auth_proto'] = 'auth_pap' if c.return_value(['authentication', 'require']) == 'chap': - config_data['authentication']['auth_proto'] = 'auth_chap_md5' + pptp['authentication']['auth_proto'] = 'auth_chap_md5' if c.return_value(['authentication', 'require']) == 'mschap': - config_data['authentication']['auth_proto'] = 'auth_mschap_v1' + pptp['authentication']['auth_proto'] = 'auth_mschap_v1' if c.return_value(['authentication', 'require']) == 'mschap-v2': - config_data['authentication']['auth_proto'] = 'auth_mschap_v2' + pptp['authentication']['auth_proto'] = 'auth_mschap_v2' if c.exists(['authentication', 'mppe']): - config_data['authentication']['mppe'] = c.return_value( + pptp['authentication']['mppe'] = c.return_value( ['authentication', 'mppe']) - return config_data + return pptp -def verify(c): - if c == None: +def verify(pptp): + if not pptp: return None - if c['authentication']['mode'] == 'local': - if not c['authentication']['local-users']: + if pptp['authentication']['mode'] == 'local': + if not pptp['authentication']['local-users']: raise ConfigError( 'pptp-server authentication local-users required') - for usr in c['authentication']['local-users']: - if not c['authentication']['local-users'][usr]['passwd']: + for usr in pptp['authentication']['local-users']: + if not pptp['authentication']['local-users'][usr]['passwd']: raise ConfigError('user ' + usr + ' requires a password') - if c['authentication']['mode'] == 'radius': - if len(c['authentication']['radiussrv']) == 0: + if pptp['authentication']['mode'] == 'radius': + if len(pptp['authentication']['radiussrv']) == 0: raise ConfigError('radius server required') - for rsrv in c['authentication']['radiussrv']: - if c['authentication']['radiussrv'][rsrv]['secret'] == None: + for rsrv in pptp['authentication']['radiussrv']: + if pptp['authentication']['radiussrv'][rsrv]['secret'] == None: raise ConfigError('radius server ' + rsrv + ' needs a secret configured') -def generate(c): - if c == None: +def generate(pptp): + if not pptp: return None - render(pptp_conf, 'pptp/pptp.config.tmpl', c, trim_blocks=True) + dirname = os.path.dirname(pptp_conf) + if not os.path.exists(dirname): + os.mkdir(dirname) + + render(pptp_conf, 'pptp/pptp.config.tmpl', pptp, trim_blocks=True) - if c['authentication']['local-users']: + if pptp['authentication']['local-users']: old_umask = os.umask(0o077) - render(chap_secrets, 'pptp/chap-secrets.tmpl', c, trim_blocks=True) + render(pptp_chap_secrets, 'pptp/chap-secrets.tmpl', pptp, trim_blocks=True) os.umask(old_umask) - # return c ?? - return c -def apply(c): - if c == None: - if os.path.exists(pidfile): - _accel_cmd('shutdown hard') - if os.path.exists(pidfile): - os.remove(pidfile) +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 - if not os.path.exists(pidfile): - ret = run(f'/usr/sbin/accel-pppd -c {pptp_conf} -p {pidfile} -d') - _chk_con() - if ret != 0 and os.path.exists(pidfile): - os.remove(pidfile) - raise ConfigError('accel-pppd failed to start') - else: - # if gw ip changes, only restart doesn't work - _accel_cmd('restart') + call('systemctl restart accel-ppp@pptp.service') if __name__ == '__main__': try: -- cgit v1.2.3 From 05f839574b101bdea4d91740834479811a271e11 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Wed, 22 Apr 2020 08:14:10 +0200 Subject: vpn: pptp: T2351: align configuration to other accel implementations --- data/templates/accel-ppp/pptp.config.tmpl | 89 +++++++++ data/templates/pptp/chap-secrets.tmpl | 6 - data/templates/pptp/pptp.config.tmpl | 86 -------- src/conf_mode/vpn_pptp.py | 318 ++++++++++++++++++------------ 4 files changed, 283 insertions(+), 216 deletions(-) create mode 100644 data/templates/accel-ppp/pptp.config.tmpl delete mode 100644 data/templates/pptp/chap-secrets.tmpl delete mode 100644 data/templates/pptp/pptp.config.tmpl (limited to 'src/conf_mode') diff --git a/data/templates/accel-ppp/pptp.config.tmpl b/data/templates/accel-ppp/pptp.config.tmpl new file mode 100644 index 000000000..0bbfc13c5 --- /dev/null +++ b/data/templates/accel-ppp/pptp.config.tmpl @@ -0,0 +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 }} +{% 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/pptp/chap-secrets.tmpl b/data/templates/pptp/chap-secrets.tmpl deleted file mode 100644 index f93f4607b..000000000 --- a/data/templates/pptp/chap-secrets.tmpl +++ /dev/null @@ -1,6 +0,0 @@ -# username server password acceptable local IP addresses -{% for user in authentication['local-users'] %} -{% if authentication['local-users'][user]['state'] == 'enabled' %} -{{ "%-12s" | format(user) }} * {{ "%-16s" | format(authentication['local-users'][user]['passwd']) }} {{ "%-16s" | format(authentication['local-users'][user]['ip']) }} -{% endif %} -{% endfor %} diff --git a/data/templates/pptp/pptp.config.tmpl b/data/templates/pptp/pptp.config.tmpl deleted file mode 100644 index 5f8395f2d..000000000 --- a/data/templates/pptp/pptp.config.tmpl +++ /dev/null @@ -1,86 +0,0 @@ -### generated by accel_pptp.py ### -[modules] -log_syslog -pptp -ippool -chap-secrets -{% if authentication['auth_proto'] %} -{{ authentication['auth_proto'] }} -{% else %} -auth_mschap_v2 -{% endif %} -{% if authentication['mode'] == 'radius' %} -radius -{% endif -%} - -[core] -thread-count={{thread_cnt}} - -[log] -syslog=accel-pptp,daemon -copy=1 -level=5 - -{% if dns %} -[dns] -{% if dns[0] %} -dns1={{dns[0]}} -{% endif %} -{% if dns[1] %} -dns2={{dns[1]}} -{% endif %} -{% endif %} - -{% if wins %} -[wins] -{% if wins[0] %} -wins1={{wins[0]}} -{% endif %} -{% if wins[1] %} -wins2={{wins[1]}} -{% endif %} -{% endif %} - -[pptp] -ifname=pptp%d -{% if outside_addr %} -bind={{outside_addr}} -{% endif %} -verbose=1 -ppp-max-mtu={{mtu}} -mppe={{authentication['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}} - -{% if authentication['mode'] == 'local' %} -[chap-secrets] -chap-secrets={{ chap_secrets_file }} -{% endif %} - -[ppp] -verbose=5 -check-ip=1 -single-session=replace - -{% if authentication['mode'] == 'radius' %} -[radius] -{% for rsrv in authentication['radiussrv']: %} -server={{rsrv}},{{authentication['radiussrv'][rsrv]['secret']}},\ -req-limit={{authentication['radiussrv'][rsrv]['req-limit']}},\ -fail-time={{authentication['radiussrv'][rsrv]['fail-time']}} -{% endfor %} -timeout=30 -acct-timeout=30 -max-try=3 -{%endif %} - -[cli] -tcp=127.0.0.1:2003 diff --git a/src/conf_mode/vpn_pptp.py b/src/conf_mode/vpn_pptp.py index 9e8d1c08b..d76cd4147 100755 --- a/src/conf_mode/vpn_pptp.py +++ b/src/conf_mode/vpn_pptp.py @@ -18,140 +18,200 @@ import os import re from copy import deepcopy -from socket import socket, AF_INET, SOCK_STREAM +from stat import S_IRUSR, S_IWUSR, S_IRGRP from sys import exit -from time import sleep from vyos.config import Config -from vyos import ConfigError -from vyos.util import call, get_half_cpus from vyos.template import render +from vyos.util import call, get_half_cpus +from vyos import ConfigError pptp_conf = '/run/accel-pppd/pptp.conf' pptp_chap_secrets = '/run/accel-pppd/pptp.chap-secrets' default_pptp = { - 'authentication': { - 'mode': 'local', - 'local-users': { - }, - 'radiussrv': {}, - 'auth_proto': 'auth_mschap_v2', - 'mppe': 'require' - }, + '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': '', - 'dns': [], + 'dnsv4': [], 'wins': [], 'client_ip_pool': '', 'mtu': '1436', + 'auth_proto' : ['auth_mschap_v2'], + 'ppp_mppe' : 'prefer', 'thread_cnt': get_half_cpus() } def get_config(): - c = Config() - if not c.exists(['vpn', 'pptp', 'remote-access']): + conf = Config() + base_path = ['vpn', 'pptp', 'remote-access'] + if not conf.exists(base_path): return None - c.set_level(['vpn', 'pptp', 'remote-access']) pptp = deepcopy(default_pptp) + conf.set_level(base_path) + + for server in ['server-1', 'server-2']: + if conf.exists(['dns-servers', server]): + tmp = conf.return_value(['dns-servers', server]) + pptp['dnsv4'].append(tmp) + + for server in ['server-1', 'server-2']: + if conf.exists(['wins-servers', server]): + tmp = conf.return_value(['wins-servers', server]) + pptp['wins'].append(tmp) + + 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' + } + + 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(['secret']): + radius['key'] = conf.return_value(['secret']) + + if not conf.exists(['disable']): + pptp['radius_server'].append(radius) + + # + # advanced radius-setting + conf.set_level(base_path + ['authentication', 'radius']) - ### general options ### - - if c.exists(['dns-servers', 'server-1']): - pptp['dns'].append(c.return_value(['dns-servers', 'server-1'])) - if c.exists(['dns-servers', 'server-2']): - pptp['dns'].append(c.return_value(['dns-servers', 'server-2'])) - if c.exists(['wins-servers', 'server-1']): - pptp['wins'].append( - c.return_value(['wins-servers', 'server-1'])) - if c.exists(['wins-servers', 'server-2']): - pptp['wins'].append( - c.return_value(['wins-servers', 'server-2'])) - if c.exists(['outside-address']): - pptp['outside_addr'] = c.return_value(['outside-address']) - - # auth local - if c.exists(['authentication', 'mode', 'local']): - if c.exists(['authentication', 'local-users', 'username']): - for usr in c.list_nodes(['authentication', 'local-users', 'username']): - pptp['authentication']['local-users'].update( - { - usr: { - 'passwd': '', - 'state': 'enabled', - 'ip': '' - } - } - ) - - if c.exists(['authentication', 'local-users', 'username', usr, 'password']): - pptp['authentication']['local-users'][usr]['passwd'] = c.return_value( - ['authentication', 'local-users', 'username', usr, 'password']) - if c.exists(['authentication', 'local-users', 'username', usr, 'disable']): - pptp['authentication']['local-users'][usr]['state'] = 'disable' - if c.exists(['authentication', 'local-users', 'username', usr, 'static-ip']): - pptp['authentication']['local-users'][usr]['ip'] = c.return_value( - ['authentication', 'local-users', 'username', usr, 'static-ip']) - - # authentication mode radius servers and settings - - if c.exists(['authentication', 'mode', 'radius']): - pptp['authentication']['mode'] = 'radius' - rsrvs = c.list_nodes(['authentication', 'radius', 'server']) - for rsrv in rsrvs: - if not c.return_value(['authentication', 'radius', 'server', rsrv, 'fail-time']): - ftime = '0' - else: - ftime = c.return_value( - ['authentication', 'radius', 'server', rsrv, 'fail-time']) - if not c.return_value(['authentication', 'radius-server', rsrv, 'req-limit']): - reql = '0' - else: - reql = c.return_value( - ['authentication', 'radius', 'server', rsrv, 'req-limit']) - - pptp['authentication']['radiussrv'].update( - { - rsrv: { - 'secret': c.return_value(['authentication', 'radius', 'server', rsrv, 'key']), - 'fail-time': ftime, - 'req-limit': reql - } - } - ) - - if c.exists(['client-ip-pool']): - if c.exists(['client-ip-pool', 'start']): - pptp['client_ip_pool'] = c.return_value( - ['client-ip-pool', 'start']) - if c.exists(['client-ip-pool', 'stop']): - pptp['client_ip_pool'] += '-' + \ - re.search( - '[0-9]+$', c.return_value(['client-ip-pool', 'stop'])).group(0) - if c.exists(['mtu']): - pptp['mtu'] = c.return_value(['mtu']) + 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', 'secret']): + dae['key'] = conf.return_value(['dynamic-author', 'secret']) + + 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 c.exists(['gateway-address']): - pptp['gw_ip'] = c.return_value(['gateway-address']) + if conf.exists(['gateway-address']): + pptp['gw_ip'] = conf.return_value(['gateway-address']) else: pptp['gw_ip'] = re.sub( '[0-9]+$', '1', pptp['client_ip_pool']) - if c.exists(['authentication', 'require']): - if c.return_value(['authentication', 'require']) == 'pap': - pptp['authentication']['auth_proto'] = 'auth_pap' - if c.return_value(['authentication', 'require']) == 'chap': - pptp['authentication']['auth_proto'] = 'auth_chap_md5' - if c.return_value(['authentication', 'require']) == 'mschap': - pptp['authentication']['auth_proto'] = 'auth_mschap_v1' - if c.return_value(['authentication', 'require']) == 'mschap-v2': - pptp['authentication']['auth_proto'] = 'auth_mschap_v2' + 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 c.exists(['authentication', 'mppe']): - pptp['authentication']['mppe'] = c.return_value( - ['authentication', 'mppe']) + if conf.exists(['authentication', 'mppe']): + pptp['ppp_mppe'] = conf.return_value(['authentication', 'mppe']) return pptp @@ -160,37 +220,47 @@ def verify(pptp): if not pptp: return None - if pptp['authentication']['mode'] == 'local': - if not pptp['authentication']['local-users']: - raise ConfigError( - 'pptp-server authentication local-users required') - for usr in pptp['authentication']['local-users']: - if not pptp['authentication']['local-users'][usr]['passwd']: - raise ConfigError('user ' + usr + ' requires a password') + if pptp['auth_mode'] == 'local': + if not pptp['local_users']: + raise ConfigError('PPTP local auth mode requires local users to be configured!') - if pptp['authentication']['mode'] == 'radius': - if len(pptp['authentication']['radiussrv']) == 0: - raise ConfigError('radius server required') - for rsrv in pptp['authentication']['radiussrv']: - if pptp['authentication']['radiussrv'][rsrv]['secret'] == None: - raise ConfigError('radius server ' + rsrv + - ' needs a secret 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') def generate(pptp): if not pptp: return None + import pprint + pprint.pprint(pptp) + dirname = os.path.dirname(pptp_conf) if not os.path.exists(dirname): os.mkdir(dirname) - render(pptp_conf, 'pptp/pptp.config.tmpl', pptp, trim_blocks=True) + render(pptp_conf, 'accel-ppp/pptp.config.tmpl', pptp, trim_blocks=True) - if pptp['authentication']['local-users']: - old_umask = os.umask(0o077) - render(pptp_chap_secrets, 'pptp/chap-secrets.tmpl', pptp, trim_blocks=True) - os.umask(old_umask) + 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): -- cgit v1.2.3 From fbdafa2987edece3dfff516f0f13f91a8dd5cb86 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Wed, 22 Apr 2020 08:16:11 +0200 Subject: vpn: pptp: T2351: use first IP from client pool as gateway address --- src/conf_mode/vpn_pptp.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'src/conf_mode') diff --git a/src/conf_mode/vpn_pptp.py b/src/conf_mode/vpn_pptp.py index d76cd4147..653b21161 100755 --- a/src/conf_mode/vpn_pptp.py +++ b/src/conf_mode/vpn_pptp.py @@ -194,8 +194,10 @@ def get_config(): if conf.exists(['gateway-address']): pptp['gw_ip'] = conf.return_value(['gateway-address']) else: - pptp['gw_ip'] = re.sub( - '[0-9]+$', '1', pptp['client_ip_pool']) + # 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 @@ -246,9 +248,6 @@ def generate(pptp): if not pptp: return None - import pprint - pprint.pprint(pptp) - dirname = os.path.dirname(pptp_conf) if not os.path.exists(dirname): os.mkdir(dirname) -- cgit v1.2.3 From f9fbda14a2559794999f3391e420c70b31e6a343 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Wed, 22 Apr 2020 17:55:30 +0200 Subject: vpn: pptp: T2351: migrate to common name-server, wins-server nodes --- interface-definitions/vpn_pptp.xml.in | 64 +++++++--------------------------- src/conf_mode/vpn_pptp.py | 15 ++++---- src/migration-scripts/pptp/1-to-2 | 65 +++++++++++++++++++++++++++++++++++ 3 files changed, 84 insertions(+), 60 deletions(-) create mode 100755 src/migration-scripts/pptp/1-to-2 (limited to 'src/conf_mode') diff --git a/interface-definitions/vpn_pptp.xml.in b/interface-definitions/vpn_pptp.xml.in index 439fd7259..2cafae60f 100644 --- a/interface-definitions/vpn_pptp.xml.in +++ b/interface-definitions/vpn_pptp.xml.in @@ -28,60 +28,20 @@ - + - IPv4 Domain Name Service (DNS) server - - - - - Primary DNS server - - ipv4 - IPv4 address - - - - - - - - - Secondary DNS server - - ipv4 - IPv4 address - - - - - - - - - - - Windows Internet Name Service (WINS) server settings + Domain Name Server (DNS) propagated to client + + ipv4 + Domain Name Server (DNS) IPv4 address + + + + + - - - - Primary WINS server - - - - - - - - Secondary WINS server - - - - - - - + + #include Pool of client IP addresses (must be within a /24) diff --git a/src/conf_mode/vpn_pptp.py b/src/conf_mode/vpn_pptp.py index 653b21161..841c1b375 100755 --- a/src/conf_mode/vpn_pptp.py +++ b/src/conf_mode/vpn_pptp.py @@ -62,15 +62,11 @@ def get_config(): pptp = deepcopy(default_pptp) conf.set_level(base_path) - for server in ['server-1', 'server-2']: - if conf.exists(['dns-servers', server]): - tmp = conf.return_value(['dns-servers', server]) - pptp['dnsv4'].append(tmp) + if conf.exists(['name-server']): + pptp['dnsv4'] = conf.return_values(['name-server']) - for server in ['server-1', 'server-2']: - if conf.exists(['wins-servers', server]): - tmp = conf.return_value(['wins-servers', server]) - pptp['wins'].append(tmp) + 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']) @@ -243,6 +239,9 @@ def verify(pptp): 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: diff --git a/src/migration-scripts/pptp/1-to-2 b/src/migration-scripts/pptp/1-to-2 new file mode 100755 index 000000000..605081f1c --- /dev/null +++ b/src/migration-scripts/pptp/1-to-2 @@ -0,0 +1,65 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 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 . + +# - migrate dns-servers node to common name-servers + +from sys import argv, exit + +from vyos.configtree import ConfigTree + +if (len(argv) < 1): + print("Must specify file name!") + exit(1) + +file_name = argv[1] + +with open(file_name, 'r') as f: + config_file = f.read() + +config = ConfigTree(config_file) +base = ['vpn', 'pptp', 'remote-access'] +if not config.exists(base): + # Nothing to do + exit(0) +else: + # Migrate IPv4 DNS servers + dns_base = base + ['dns-servers'] + if config.exists(dns_base): + for server in ['server-1', 'server-2']: + if config.exists(dns_base + [server]): + dns = config.return_value(dns_base + [server]) + config.set(base + ['name-server'], value=dns, replace=False) + + config.delete(dns_base) + + # Migrate IPv4 WINS servers + wins_base = base + ['wins-servers'] + if config.exists(wins_base): + for server in ['server-1', 'server-2']: + if config.exists(wins_base + [server]): + wins = config.return_value(wins_base + [server]) + config.set(base + ['wins-server'], value=wins, replace=False) + + config.delete(wins_base) + + + + try: + with open(file_name, 'w') as f: + f.write(config.to_string()) + except OSError as e: + print("Failed to save the modified config: {}".format(e)) + exit(1) -- cgit v1.2.3 From d55ab3a9fa06f3b4827665d269cef6819b549771 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Wed, 22 Apr 2020 18:16:13 +0200 Subject: vpn: pptp: T2351: migrate to common radius CLI --- interface-definitions/vpn_pptp.xml.in | 34 +--------------------------------- src/conf_mode/vpn_pptp.py | 8 ++++---- src/migration-scripts/pptp/1-to-2 | 8 +++++++- 3 files changed, 12 insertions(+), 38 deletions(-) (limited to 'src/conf_mode') diff --git a/interface-definitions/vpn_pptp.xml.in b/interface-definitions/vpn_pptp.xml.in index 2cafae60f..34b528690 100644 --- a/interface-definitions/vpn_pptp.xml.in +++ b/interface-definitions/vpn_pptp.xml.in @@ -152,39 +152,7 @@ - - - RADIUS specific configuration - - - - - IP address of radius server - - ipv4 - IP address of RADIUS server - - - - - - Key for accessing the specified server - - - - - Maximum number of simultaneous requests to server (default: unlimited) - - - - - If server does not responds mark it as unavailable for this time (seconds) - - - - - - + #include diff --git a/src/conf_mode/vpn_pptp.py b/src/conf_mode/vpn_pptp.py index 841c1b375..a602de412 100755 --- a/src/conf_mode/vpn_pptp.py +++ b/src/conf_mode/vpn_pptp.py @@ -119,8 +119,8 @@ def get_config(): if conf.exists(['port']): radius['port'] = conf.return_value(['port']) - if conf.exists(['secret']): - radius['key'] = conf.return_value(['secret']) + if conf.exists(['key']): + radius['key'] = conf.return_value(['key']) if not conf.exists(['disable']): pptp['radius_server'].append(radius) @@ -161,8 +161,8 @@ def get_config(): if conf.exists(['dynamic-author', 'port']): dae['port'] = conf.return_value(['dynamic-author', 'port']) - if conf.exists(['dynamic-author', 'secret']): - dae['key'] = conf.return_value(['dynamic-author', 'secret']) + if conf.exists(['dynamic-author', 'key']): + dae['key'] = conf.return_value(['dynamic-author', 'key']) pptp['radius_dynamic_author'] = dae diff --git a/src/migration-scripts/pptp/1-to-2 b/src/migration-scripts/pptp/1-to-2 index 605081f1c..a13cc3a4f 100755 --- a/src/migration-scripts/pptp/1-to-2 +++ b/src/migration-scripts/pptp/1-to-2 @@ -15,6 +15,7 @@ # along with this program. If not, see . # - migrate dns-servers node to common name-servers +# - remove radios req-limit node from sys import argv, exit @@ -55,7 +56,12 @@ else: config.delete(wins_base) - + # Remove RADIUS server req-limit node + radius_base = base + ['authentication', 'radius'] + if config.exists(radius_base): + for server in config.list_nodes(radius_base + ['server']): + if config.exists(radius_base + ['server', server, 'req-limit']): + config.delete(radius_base + ['server', server, 'req-limit']) try: with open(file_name, 'w') as f: -- cgit v1.2.3 From 6f090e918bae878463aa683511ceab4fbbbade54 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Wed, 22 Apr 2020 18:35:24 +0200 Subject: accel-ppp: fix wrong reference in verify() on missing attributes --- src/conf_mode/service_ipoe-server.py | 4 ++-- src/conf_mode/service_pppoe-server.py | 2 +- src/conf_mode/vpn_l2tp.py | 2 +- src/conf_mode/vpn_pptp.py | 2 +- src/conf_mode/vpn_sstp.py | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src/conf_mode') diff --git a/src/conf_mode/service_ipoe-server.py b/src/conf_mode/service_ipoe-server.py index 23a2091bd..17fa2c3f0 100755 --- a/src/conf_mode/service_ipoe-server.py +++ b/src/conf_mode/service_ipoe-server.py @@ -238,7 +238,7 @@ def verify(ipoe): for interface in ipoe['interfaces']: if not interface['range']: - raise ConfigError(f'No IPoE client subnet defined on interface "{{ interface }}"') + 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') @@ -253,7 +253,7 @@ def verify(ipoe): for radius in ipoe['radius_server']: if not radius['key']: server = radius['server'] - raise ConfigError(f'Missing RADIUS secret key for server "{{ 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!') diff --git a/src/conf_mode/service_pppoe-server.py b/src/conf_mode/service_pppoe-server.py index 066e997f6..95cb066d8 100755 --- a/src/conf_mode/service_pppoe-server.py +++ b/src/conf_mode/service_pppoe-server.py @@ -389,7 +389,7 @@ def verify(pppoe): for radius in pppoe['radius_server']: if not radius['key']: server = radius['server'] - raise ConfigError(f'Missing RADIUS secret key for server "{{ 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') diff --git a/src/conf_mode/vpn_l2tp.py b/src/conf_mode/vpn_l2tp.py index d8a1fb115..a4ef99d45 100755 --- a/src/conf_mode/vpn_l2tp.py +++ b/src/conf_mode/vpn_l2tp.py @@ -309,7 +309,7 @@ def verify(l2tp): for radius in l2tp['radius_server']: if not radius['key']: - raise ConfigError(f"Missing RADIUS secret for server {{ 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']): diff --git a/src/conf_mode/vpn_pptp.py b/src/conf_mode/vpn_pptp.py index a602de412..046fc8f9c 100755 --- a/src/conf_mode/vpn_pptp.py +++ b/src/conf_mode/vpn_pptp.py @@ -234,7 +234,7 @@ def verify(pptp): for radius in pptp['radius_server']: if not radius['key']: server = radius['server'] - raise ConfigError(f'Missing RADIUS secret key for server "{{ 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') diff --git a/src/conf_mode/vpn_sstp.py b/src/conf_mode/vpn_sstp.py index 90b4f1f34..e6ce94709 100755 --- a/src/conf_mode/vpn_sstp.py +++ b/src/conf_mode/vpn_sstp.py @@ -297,7 +297,7 @@ def verify(sstp): for radius in sstp['radius_server']: if not radius['key']: server = radius['server'] - raise ConfigError(f'Missing RADIUS secret key for server "{{ server }}"') + raise ConfigError(f'Missing RADIUS secret key for server "{ server }"') def generate(sstp): if not sstp: -- cgit v1.2.3