From 51afeb661b8210527b48d35bafcef02ac0cc14f3 Mon Sep 17 00:00:00 2001 From: hagbard Date: Tue, 24 Jul 2018 10:57:22 -0700 Subject: T736: Rewrite remote logging (syslog) to XML/Python --- interface-definitions/syslog.xml | 859 +++++++++++++++++++++++++++++++++++++++ src/conf_mode/syslog.py | 267 ++++++++++++ 2 files changed, 1126 insertions(+) create mode 100644 interface-definitions/syslog.xml create mode 100755 src/conf_mode/syslog.py diff --git a/interface-definitions/syslog.xml b/interface-definitions/syslog.xml new file mode 100644 index 000000000..050cff41b --- /dev/null +++ b/interface-definitions/syslog.xml @@ -0,0 +1,859 @@ + + + + + + + + System logging + 400 + + + + + Logging to specific user's terminal + + ^[a-z_][a-z0-9_-]{1,31}[$]? + + illegal characters in user + + username + user login name + + + + + + Facility for logging + + auth authpriv cron daemon kern lpr mail mark news protocols security syslog user uucp local0 local1 local2 local3 local4 local5 local6 local7 all + + + all + All facilities excluding "mark" + + + auth + Authentication and authorization + + + authpriv + Non-system authorization + + + cron + Cron daemon + + + daemon + System daemons + + + kern + Kernel + + + lpr + Line printer spooler + + + mail + Mail subsystem + + + mark + Timestamp + + + news + USENET subsystem + + + protocols + depricated will be set to local7 + + + security + depricated will be set to auth + + + syslog + Authentication and authorization + + + user + Application processes + + + uucp + UUCP subsystem + + + local0 + Local facility 0 + + + local1 + Local facility 1 + + + local2 + Local facility 2 + + + local3 + Local facility 3 + + + local4 + Local facility 4 + + + local5 + Local facility 5 + + + local6 + Local facility 6 + + + local7 + Local facility 7 + + + + + + Logging level + + emerg alert crit err warning notice info debug all + + + emerg + Emergency messages + + + alert + Urgent messages + + + crit + Critical messages + + + err + Error messages + + + warning + Warning messages + + + notice + Messages for further investigation + + + info + Informational messages + + + debug + Debug messages + + + all + Log everything + + + + + + + + + + Logging to a remote host + + x.x.x.x or host.domain.tld + Remote host name or IP address + + + + + + + Facility for logging + + auth authpriv cron daemon kern lpr mail mark news protocols security syslog user uucp local0 local1 local2 local3 local4 local5 local6 local7 all + + + all + All facilities excluding "mark" + + + auth + Authentication and authorization + + + authpriv + Non-system authorization + + + cron + Cron daemon + + + daemon + System daemons + + + kern + Kernel + + + lpr + Line printer spooler + + + mail + Mail subsystem + + + mark + Timestamp + + + news + USENET subsystem + + + protocols + depricated will be set to local7 + + + security + depricated will be set to auth + + + syslog + Authentication and authorization + + + user + Application processes + + + uucp + UUCP subsystem + + + local0 + Local facility 0 + + + local1 + Local facility 1 + + + local2 + Local facility 2 + + + local3 + Local facility 3 + + + local4 + Local facility 4 + + + local5 + Local facility 5 + + + local6 + Local facility 6 + + + local7 + Local facility 7 + + + + + + syslog communication protocol + + udp + send log messages to remote syslog server over udp + + + tcp + send log messages to remote syslog server over tdp + + + + + + + Logging level + + emerg alert crit err warning notice info debug all + + + emerg + Emergency messages + + + alert + Urgent messages + + + crit + Critical messages + + + err + Error messages + + + warning + Warning messages + + + notice + Messages for further investigation + + + info + Informational messages + + + debug + Debug messages + + + all + Log everything + + + + + + + + + + + + Log file size and rotation characteristics + + + + + Number of saved files (default is 5) + + ^[0-9]+ + + illegal characters in number of files + + + + + Size of log files (in kbytes, default is 256) + + ^[0-9]+ + + illegal characters in size + + + + + + + Facility for logging + + auth authpriv cron daemon kern lpr mail mark news protocols security syslog user uucp local0 local1 local2 local3 local4 local5 local6 local7 all + + + all + All facilities excluding "mark" + + + auth + Authentication and authorization + + + authpriv + Non-system authorization + + + cron + Cron daemon + + + daemon + System daemons + + + kern + Kernel + + + lpr + Line printer spooler + + + mail + Mail subsystem + + + mark + Timestamp + + + news + USENET subsystem + + + protocols + depricated will be set to local7 + + + security + depricated will be set to auth + + + syslog + Authentication and authorization + + + user + Application processes + + + uucp + UUCP subsystem + + + local0 + Local facility 0 + + + local1 + Local facility 1 + + + local2 + Local facility 2 + + + local3 + Local facility 3 + + + local4 + Local facility 4 + + + local5 + Local facility 5 + + + local6 + Local facility 6 + + + local7 + Local facility 7 + + + + + + Logging level + + emerg alert crit err warning notice info debug all + + + emerg + Emergency messages + + + alert + Urgent messages + + + crit + Critical messages + + + err + Error messages + + + warning + Warning messages + + + notice + Messages for further investigation + + + info + Informational messages + + + debug + Debug messages + + + all + Log everything + + + + + + + + + + Logging to a file + + ^[a-zA-Z0-9\-_.]{1,255} + + illegal characters in filename or filename longer than 255 characters + + + + + Log file size and rotation characteristics + + + + + Number of saved files (default is 5) + + ^[0-9]+ + + illegal characters in number of files + + + + + Size of log files (in kbytes, default is 256) + + ^[0-9]+ + + illegal characters in size + + + + + + + Facility for logging + + auth authpriv cron daemon kern lpr mail mark news protocols security syslog user uucp local0 local1 local2 local3 local4 local5 local6 local7 all + + + all + All facilities excluding "mark" + + + auth + Authentication and authorization + + + authpriv + Non-system authorization + + + cron + Cron daemon + + + daemon + System daemons + + + kern + Kernel + + + lpr + Line printer spooler + + + mail + Mail subsystem + + + mark + Timestamp + + + news + USENET subsystem + + + protocols + depricated will be set to local7 + + + security + depricated will be set to auth + + + syslog + Authentication and authorization + + + user + Application processes + + + uucp + UUCP subsystem + + + local0 + Local facility 0 + + + local1 + Local facility 1 + + + local2 + Local facility 2 + + + local3 + Local facility 3 + + + local4 + Local facility 4 + + + local5 + Local facility 5 + + + local6 + Local facility 6 + + + local7 + Local facility 7 + + + + + + Logging level + + emerg alert crit err warning notice info debug all + + + emerg + Emergency messages + + + alert + Urgent messages + + + crit + Critical messages + + + err + Error messages + + + warning + Warning messages + + + notice + Messages for further investigation + + + info + Informational messages + + + debug + Debug messages + + + all + Log everything + + + + + + + + + + logging to serial console + + + + + Facility for logging + + auth authpriv cron daemon kern lpr mail mark news protocols security syslog user uucp local0 local1 local2 local3 local4 local5 local6 local7 all + + + all + All facilities excluding "mark" + + + auth + Authentication and authorization + + + authpriv + Non-system authorization + + + cron + Cron daemon + + + daemon + System daemons + + + kern + Kernel + + + lpr + Line printer spooler + + + mail + Mail subsystem + + + mark + Timestamp + + + news + USENET subsystem + + + protocols + depricated will be set to local7 + + + security + depricated will be set to auth + + + syslog + Authentication and authorization + + + user + Application processes + + + uucp + UUCP subsystem + + + local0 + Local facility 0 + + + local1 + Local facility 1 + + + local2 + Local facility 2 + + + local3 + Local facility 3 + + + local4 + Local facility 4 + + + local5 + Local facility 5 + + + local6 + Local facility 6 + + + local7 + Local facility 7 + + + + + + Logging level + + emerg alert crit err warning notice info debug all + + + emerg + Emergency messages + + + alert + Urgent messages + + + crit + Critical messages + + + err + Error messages + + + warning + Warning messages + + + notice + Messages for further investigation + + + info + Informational messages + + + debug + Debug messages + + + all + Log everything + + + + + + + + + + + + diff --git a/src/conf_mode/syslog.py b/src/conf_mode/syslog.py new file mode 100755 index 000000000..3cfc0e5ff --- /dev/null +++ b/src/conf_mode/syslog.py @@ -0,0 +1,267 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2018 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 . +# +# + +import sys +import os +import jinja2 +import re + +from vyos.config import Config +from vyos import ConfigError + +########### config templates + +#### /etc/rsyslog.d/vyos-rsyslog.conf ### +configs = ''' +## generated by syslog.py ## +## file based logging +{% for file in files %} +$outchannel {{file}},{{files[file]['log-file']}},{{files[file]['max-size']}},{{files[file]['action-on-max-size']}} +{{files[file]['selectors']}} :omfile:${{file}} +{% endfor %} +{% if console %} +## console logging +{% for con in console %} +{{console[con]['selectors']}} /dev/console +{% endfor %} +{% endif %} +{% if hosts %} +## remote logging +{% for host in hosts %} +{% if hosts[host]['proto'] == 'tcp' %} +{{hosts[host]['selectors']}} @@{{host}} +{% else %} +{{hosts[host]['selectors']}} @{{host}} +{% endif %} +{% endfor %} +{% endif %} +{% if user %} +{% for u in user %} +{{user[u]['selectors']}} :omusrmsg:{{u}} +{% endfor %} +{% endif %} +''' + +logrotate_configs = ''' +{% for file in files %} +{{files[file]['log-file']}} { + missingok + notifempty + create + rotate {{files[file]['max-files']}} + size={{ files[file]['max-size']//1024}}k + postrotate + invoke-rc.d rsyslog rotate > /dev/null + endscript +} +{% endfor %} +''' +############# config templates end + +def get_config(): + c = Config() + if not c.exists('system syslog'): + return None + c.set_level('system syslog') + + config_data = { + 'files' : {}, + 'console' : {}, + 'hosts' : {}, + 'user' : {} + } + + ##### + # /etc/rsyslog.d/vyos-rsyslog.conf + # 'set system syslog global' + ##### + config_data['files'].update( + { + 'global' : { + 'log-file' : '/var/log/vyos-rsyslog', + 'max-size' : 262144, + 'action-on-max-size' : '/usr/sbin/logrotate /etc/logrotate.d/vyos-rsyslog', + 'selectors' : '*.notice;local7.debug', + 'max-files' : '5' + } + } + ) + + if c.exists('global facility'): + config_data['files']['global']['selectors'] = generate_selectors(c, 'global facility') + if c.exists('global archive size'): + config_data['files']['global']['max-size'] = int(c.return_value('global archive size'))* 1024 + if c.exists('global archive files'): + config_data['files']['global']['max-files'] = c.return_value('global archive files') + + ### + # set system syslog file + ### + + if c.exists('file'): + filenames = c.list_nodes('file') + for filename in filenames: + config_data['files'].update( + { + filename : { + 'log-file' : '/var/log/user/' + filename, + 'max-files' : '5', + 'action-on-max-size' : '/usr/sbin/logrotate /etc/logrotate.d/' + filename, + 'selectors' : '*.err', + 'max-size' : 262144 + } + } + ) + + if c.exists('file ' + filename + ' facility'): + config_data['files'][filename]['selectors'] = generate_selectors(c, 'file ' + filename + ' facility') + if c.exists('file ' + filename + ' archive size'): + config_data['files'][filename]['max-size'] = int(c.return_value('file ' + filename + ' archive size'))* 1024 + if c.exists('file ' + filename + ' archive files'): + config_data['files'][filename]['max-files'] = c.return_value('file ' + filename + ' archive files') + + ## set system syslog console + if c.exists('console'): + config_data['console'] = { + '/dev/console' : { + 'selectors' : '*.err' + } + } + + for f in c.list_nodes('console facility'): + if c.exists('console facility ' + f + ' level'): + config_data['console'] = { + '/dev/console' : { + 'selectors' : generate_selectors(c, 'console facility') + } + } + + ## set system syslog host + if c.exists('host'): + rhosts = c.list_nodes('host') + for rhost in rhosts: + for fac in c.list_nodes('host ' + rhost + ' facility'): + if c.exists('host ' + rhost + ' facility ' + fac + ' protocol'): + proto = c.return_value('host ' + rhost + ' facility ' + fac + ' protocol') + else: + proto = 'udp' + + config_data['hosts'].update( + { + rhost : { + 'selectors' : generate_selectors(c, 'host ' + rhost + ' facility'), + 'proto' : proto + } + } + ) + + ## set system syslog user + if c.exists('user'): + usrs = c.list_nodes('user') + for usr in usrs: + config_data['user'].update( + { + usr : { + 'selectors' : generate_selectors(c, 'user ' + usr + ' facility') + } + } + ) + + return config_data + +def generate_selectors(c, config_node): +## protocols and security are being mapped here +## for backward compatibility with old configs +## security and protocol mappings can be removed later + if c.is_tag(config_node): + nodes = c.list_nodes(config_node) + selectors = "" + for node in nodes: + lvl = c.return_value( config_node + ' ' + node + ' level') + if lvl == None: + lvl = "err" + if lvl == 'all': + lvl = '*' + if node == 'all' and node != nodes[-1]: + selectors += "*." + lvl + ";" + elif node == 'all': + selectors += "*." + lvl + elif node != nodes[-1]: + if node == 'protocols': + node = 'local7' + if node == 'security': + node = 'auth' + selectors += node + "." + lvl + ";" + else: + if node == 'protocols': + node = 'local7' + if node == 'security': + node = 'auth' + selectors += node + "." + lvl + return selectors + +def generate(c): + tmpl = jinja2.Template(configs, trim_blocks=True) + config_text = tmpl.render(c) + #print (config_text) + with open('/etc/rsyslog.d/vyos-rsyslog.conf', 'w') as f: + f.write(config_text) + + ## eventually write for each file its own logrotate file, since size is defined it shouldn't matter + tmpl = jinja2.Template(logrotate_configs, trim_blocks=True) + config_text = tmpl.render(c) + #print (config_text) + with open('/etc/logrotate.d/vyos-rsyslog', 'w') as f: + f.write(config_text) + +def verify(c): + if c == None: + return None + + fac = ['*','auth','authpriv','cron','daemon','kern','lpr','mail','mark','news','protocols','security',\ + 'syslog','user','uucp','local0','local1','local2','local3','local4','local5','local6','local7'] + lvl = ['emerg','alert','crit','err','warning','notice','info','debug','*'] + for conf in c: + if c[conf]: + for item in c[conf]: + for s in c[conf][item]['selectors'].split(";"): + f = re.sub("\..*$","",s) + if f not in fac: + print (c[conf]) + raise ConfigError('Invalid facility ' + s + ' set in '+ conf + ' ' + item) + l = re.sub("^.+\.","",s) + if l not in lvl: + raise ConfigError('Invalid logging level ' + s + ' set in '+ conf + ' ' + item) + +def apply(c): + ### vyatta-log.conf is being generated somewhere + ### this is just a quick hack to remove the old configfile + + if os.path.exists('/etc/rsyslog.d/vyatta-log.conf'): + os.remove('/etc/rsyslog.d/vyatta-log.conf') + os.system("sudo invoke-rc.d rsyslog restart >/dev/null") + +if __name__ == '__main__': + try: + c = get_config() + verify(c) + generate(c) + apply(c) + except ConfigError as e: + print(e) + sys.exit(1) -- cgit v1.2.3