From mboxrd@z Thu Jan 1 00:00:00 1970 From: Michael Tremer To: development@lists.ipfire.org Subject: Re: [PATCH v3 1/5] zabbix_agentd: Update to v5.0.20 (LTS) Date: Mon, 21 Feb 2022 11:41:20 +0000 Message-ID: <5D290314-88A5-45A3-876C-0C42DF3499A7@ipfire.org> In-Reply-To: <193dfdc20801a7106042e0f905848c283f95cd0e.camel@sicho.home> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============8071191881226593411==" List-Id: --===============8071191881226593411== Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Hello, > On 20 Feb 2022, at 22:18, Robin Roevens wrote: >=20 > Hi Michael >=20 > Michael Tremer schreef op zo 20-02-2022 om 18:10 [+0000]: >>=20 >>=20 >> The reason why pakfire is doing this is because it is simply a >> wrapper around tar. It is not that sophisticated of a package >> management system because it wasn=E2=80=99t designed for this scale. >>=20 >> In order to avoid overwriting any existing configuration, we backup >> everything, extract the new package which will then overwrite the >> existing configuration files and then restore the backup to have the >> old configuration again. We could have built something that avoids >> overwriting the files in the first place which is what pakfire in >> IPFire 3 does. > The current method indeed is probably the best possible considering the > way pakfire currently works when updating an addon. But for as far as I > currently understand it, when you uninstall an addon, all config files > are backed up and then are removed (due to being in the rootfile). For > the user the addon is gone on the system. > If the user opts to install the addon again, say about half a year or a > year later, the install will restore the backup of the config it took > during uninstall half a year ago. I think this will cause confusion in > many cases? > Is this implemented this way for a good reason? or just to accommodate > the update procedure without much further thought? I am not if this is for the best reason, but it prevents that people will los= e their configuration for any reason and there is an easy option to drop conf= iguration if you want to. Although it might not be the best, it is a good solution. > I myself (if I didn't know how pakfire worked internally) would expect > that if I uninstalled an addon, checked and removed potentially left- > over config files, that a new install would give me a fresh install > which I would have to configure manually again. >=20 > If pakfire worked that way, the user could make a copy of his config > himself, uninstall and re-install an addon to have a fresh config which > he then could merge himself with his old config-copy to make the addon > work again. >=20 > So if there is no real reason to always backup on uninstall I would > like to propose to perform the backup restore in the actual update- > script instead of in the install and uninstall scripts? This way there > is a quite logical way for the average user to start over with a fresh > install of an addon. That would feel much more 'natural' to me. There is the reason, that there is no other way at the moment than backing it= up and restoring it. Otherwise the configuration will always be overwritten = which is not what we want at all. Additionally, I would want all packages to behave the same. If we change this= for Zabbix, we will have to change this for everything else, too. > Anyway this discussion about pakfire working is maybe worth its own > thread as it is not really zabbix-agent specific. >=20 >>=20 >> Lots of other distributions work in a similar way where they rename >> the existing configuration files and might rename them back again. >>=20 >>> The problem I'm having with the current way is that when an addon >>> is >>> updated, a new version of the config is just discarded due to the >>> restore of the previous config during install (even if that config >>> was >>> never changed by the user). >>> So if settings in the config are added, deprecated or even no >>> longer >>> valid, the user will never know until a version would no longer >>> start >>> up or no longer behave as expected due to the old config. >>> And even if a user would think about checking config changes on an >>> update he would have to go search the internet for a config example >>> for >>> this version of the addon. >>=20 >> Yes, this is a huge problem for us all. The question there is to >> answer is: >>=20 >> Do we know better than the user? >>=20 >> Answering that with a yes means that we would make decisions on their >> behalf and that might potentially go wrong. Answering that with a no >> means that the user needs to invest a lot of time into the >> configuration of each part of the distribution and the reason why we >> have a nice shiny web user interface is that they don=E2=80=99t have to do >> this. The correct answer is probably somewhere in the middle. >>=20 >> What we do in practise is: We keep systems consistent with their >> previous behaviour. An update should never change that (there are of >> course exceptions to every rule). New features might only be >> activated on new systems. >=20 > The problem I see with this is that if software provided by an addon is > for example deprecating one or more config-options. Keeping the systems > constistent would mean > - not providing any newer version for that addon anymore, which I don't > think is what we want. Or > - trying to 'convert' the possibly user-changed deprecated config- > setting in the config file using sed, which I can see failing in may > ways :-) Or This is what we do quite regularly and it has never failed. Ultimately, if upstream decides to discontinue support for something, there i= sn=E2=80=99t much else that we can do. > - providing the user with a straight forward way to reinstall an addon > completely afresh, and/or > - what I'm trying to do here, provide the user with the new config in > some easily accessible way (currently .ipfirenew, but could be a > simpler .example, see below), keeping his old config active possibly > making the new addon version fail to work, but giving him the > possibility to manually merge his deprecated config to what the current > version of the addon-software expects. I am not sure how they should know about those changes. Showing a diff is probably hard to understand for many users and showing that= diff on the UI is even more difficult. I am not against *what* you are trying to achieve at all. I am just not sure = if the *how* is the best. How about just copying the configuration and put it next to the configuration= file with a =E2=80=9C.sample=E2=80=9D suffix? Then people are still on their= own, but I would consider a sample suffix more clear than a .ipfirenew becau= se that doesn=E2=80=99t tell me much about what I should be doing with it. >>=20 >>> In this specific case, as we update from a rather old version of >>> zabbix >>> agent, there are quite a few interesting config changes that can >>> harden >>> the security of the agent, which I would not want the user to miss >>> out >>> on. Also one option is deprecated, is currently still supported, >>> but in >>> the next version it probably will no longer work, possibly breaking >>> some users' monitoring or causing the agent to fail starting. >>=20 >> Is this an add-on that generally requires configuration on the >> console? >>=20 >> We do we not build a page on the web UI for this so that people can >> enable the things they want? Would that be overkill for the possible >> options? >=20 > As I said before, I would indeed prefer a web ui for the config of the > addon. That way we are in complete control of the config file. And I > plan to build such a page (I have already put some effort in it, but it > is not even nearly ready for now).=20 > The page should give the user access to all possible configuration > options. If not, we could handicap/limit the use of the agent or force > the advanced user to still manually tinker with the config file. >=20 > But the zabbix agent has many options including defining certificates > and encryption keys for communication and a web ui should do sanity > checking on all options as well as provide methods to upload and/or > generate those certs/keys so it is not a page that is easily designed > overnight. But it is coming sooner or later. Wouldn=E2=80=99t the system automatically generate any keys for the agent? Scrolling through the configuration, I do not see anything the user would wan= t to change. Do you have an example for me to understand this better? >=20 >>=20 >>> For the sudoers file it is even more problematic; the user can of >>> course modify that file to add additional commands he requires the >>> agent to execute as root, but possible future additions to the >>> ipfire >>> specific monitoring that I or other contributors in the future may >>> add, >>> may also need extra commands in that file to work. (for example the >>> upcoming services monitoring that would require some form of >>> addonctrl >>> status) >>> But I can't update that file with the current behaviour.. or I >>> would >>> have to try to implement some sed magic after the restore in >>> install.sh >>> hoping not to damage the file if it has user customizations in it. >>=20 >> This is not a configuration file in my eyes. It technically is one of >> course, but we call these files a =E2=80=9Csystem configuration file=E2=80= =9D. It >> will be overwritten because what is in it is necessary for the system >> to work. It does not contain any choices by the user at all. >>=20 >> For that reason, this file should not be backed up and overwritten by >> every package update. >>=20 >>> So I'm not sure on how to handle this differently at the moment. >>> I was thinking for the main config maybe just installing a >>> ".example" >>> version of the latest config so that a user would not have to go >>> search >>> for it on internet ? And in that case even remove all comments and >>> defaults from the actual config (on a fresh install) as that is >>> then >>> provided in the ".example" version as documentation.=20 >>=20 >> Having some example configuration in a location the user would >> normally not look at is probably not helpful. > I agree with the "location the user would normally not look at". But as > I currently see it, I would like to add the the config example next to > the actual config. (I see this happen in many software packages in > other linux distro's too. Granted, most of the time it is the vendor > itself that provides that example config, not the distro. But since we > don't have config merging or '.rpmnew' systems as those distro's do > have, I see this as some kind of middle way) >=20 > So /etc/zabbix_agentd/ in a fresh install would contain=20 > - zabbix_agentd.conf.example - the config as shipped with the zabbix > source, but renamed to '.example' during build. (with all options in it > accompanied with option documentation as comments.) Okay. I can live with this. > - zabbix_agentd.conf - the active config, provided by us, with only the > bare minimum of options required for the agent to run (secure). - this > config will not be altered by us after initial install due to the > backup/restore. Unless we need to remove any deprecated options, etc. Agreed. > This way the example config is automatically accurate for the current > version of the addon. And the user stays in complete control of his own > config in the same way it is in other addons. >=20 > Until the web ui is finished.. That sounds good to me. >>=20 >> If you want them to configure things themselves, why not provide good >> documentation on the wiki? > I do not 'want' them to configure things themselves.. but if they want > to actually use the agent they have to at least point the agent to > their zabbix server. So minimal manual configuration is required, and > that is also already documented on the wiki. But the agent has many > options and possibilities and I don't think it is our job to provide > extensive non-IPFire specific configuration documentation as that is > the job of the vendor (and in case of Zabbix the docs are there and > very clear). No, that would just be duplicating documentation. -Michael > But I do am convinced that we should provide a straight-forward way for > the more advanced user to get a version of the default config as it is > shipped with the current release of the software, especially when it is > as verbose in documentation comments as provided by Zabbix.=20 >=20 >>=20 >>> But that still leaves the sudoers file. The only other possibility >>> I >>> see there is that we don't add this file to the backup and add a >>> comment in it that a user should not modify it as it will get >>> overwritten on update. He can then always still create his own >>> sudoers- >>> file with his own custom rights for the agent. >>=20 >> This is the way to go. In many cases, we have extra files that end on >> =E2=80=9C.user=E2=80=9D or =E2=80=9C.local=E2=80=9D to make it clear that = users should make their own >> changes here. > Ok, for the sudoers, I will go this route then. >=20 >=20 > Robin >=20 >>=20 >>> Of course all this can be solved by managing the config using the >>> webgui.. and I'm still planning to create a webgui config page for >>> the >>> agent someday. But we are not there yet :-) >>=20 >> -Michael >>=20 >>>=20 >>> Regards >>>=20 >>> Robin >>>=20 >>>>=20 >>>> -Michael >>>>=20 >>>>> On 9 Feb 2022, at 23:26, Robin Roevens >>>>> >>>>> wrote: >>>>>=20 >>>>> - Update from 4.2.6 to latest LTS version 5.0.20 >>>>> See release notes: https://www.zabbix.com/rn/rn5.0.20 >>>>>=20 >>>>> Signed-off-by: Robin Roevens >>>>> --- >>>>> config/zabbix_agentd/zabbix_agentd.conf | 135 >>>>> ++++++++++++++++++++++-- >>>>> lfs/zabbix_agentd | 11 +- >>>>> 2 files changed, 132 insertions(+), 14 deletions(-) >>>>>=20 >>>>> diff --git a/config/zabbix_agentd/zabbix_agentd.conf >>>>> b/config/zabbix_agentd/zabbix_agentd.conf >>>>> index 21b8e0122..aa8b899dc 100644 >>>>> --- a/config/zabbix_agentd/zabbix_agentd.conf >>>>> +++ b/config/zabbix_agentd/zabbix_agentd.conf >>>>> @@ -63,14 +63,33 @@ LogFileSize=3D0 >>>>> # Default: >>>>> # SourceIP=3D >>>>>=20 >>>>> -### Option: EnableRemoteCommands >>>>> -# Whether remote commands from Zabbix server are allowed. >>>>> -# 0 - not allowed >>>>> -# 1 - allowed >>>>> +### Option: AllowKey >>>>> +# Allow execution of item keys matching pattern. >>>>> +# Multiple keys matching rules may be defined in >>>>> combination >>>>> with DenyKey. >>>>> +# Key pattern is wildcard expression, which support "*" >>>>> character to match any number of any characters in certain >>>>> position. It might be used in both key name and key arguments. >>>>> +# Parameters are processed one by one according their >>>>> appearance order. >>>>> +# If no AllowKey or DenyKey rules defined, all keys are >>>>> allowed. >>>>> +# >>>>> +# Mandatory: no >>>>> + >>>>> +### Option: DenyKey >>>>> +# Deny execution of items keys matching pattern. >>>>> +# Multiple keys matching rules may be defined in >>>>> combination >>>>> with AllowKey. >>>>> +# Key pattern is wildcard expression, which support "*" >>>>> character to match any number of any characters in certain >>>>> position. It might be used in both key name and key arguments. >>>>> +# Parameters are processed one by one according their >>>>> appearance order. >>>>> +# If no AllowKey or DenyKey rules defined, all keys are >>>>> allowed. >>>>> +# Unless another system.run[*] rule is specified >>>>> DenyKey=3Dsystem.run[*] is added by default. >>>>> # >>>>> # Mandatory: no >>>>> # Default: >>>>> -# EnableRemoteCommands=3D0 >>>>> +# DenyKey=3Dsystem.run[*] >>>>> + >>>>> +### Option: EnableRemoteCommands - Deprecated, use >>>>> AllowKey=3Dsystem.run[*] or DenyKey=3Dsystem.run[*] instead >>>>> +# Internal alias for AllowKey/DenyKey parameters >>>>> depending on >>>>> value: >>>>> +# 0 - DenyKey=3Dsystem.run[*] >>>>> +# 1 - AllowKey=3Dsystem.run[*] >>>>> +# >>>>> +# Mandatory: no >>>>>=20 >>>>> ### Option: LogRemoteCommands >>>>> # Enable logging of executed shell commands as warnings. >>>>> @@ -177,6 +196,28 @@ ServerActive=3D127.0.0.1 >>>>> # Default: >>>>> # HostMetadataItem=3D >>>>>=20 >>>>> +### Option: HostInterface >>>>> +# Optional parameter that defines host interface. >>>>> +# Host interface is used at host auto-registration >>>>> process. >>>>> +# An agent will issue an error and not start if the value >>>>> is >>>>> over limit of 255 characters. >>>>> +# If not defined, value will be acquired from >>>>> HostInterfaceItem. >>>>> +# >>>>> +# Mandatory: no >>>>> +# Range: 0-255 characters >>>>> +# Default: >>>>> +# HostInterface=3D >>>>> + >>>>> +### Option: HostInterfaceItem >>>>> +# Optional parameter that defines an item used for >>>>> getting >>>>> host interface. >>>>> +# Host interface is used at host auto-registration >>>>> process. >>>>> +# During an auto-registration request an agent will log a >>>>> warning message if >>>>> +# the value returned by specified item is over limit of >>>>> 255 >>>>> characters. >>>>> +# This option is only used when HostInterface is not >>>>> defined. >>>>> +# >>>>> +# Mandatory: no >>>>> +# Default: >>>>> +# HostInterfaceItem=3D >>>>> + >>>>> ### Option: RefreshActiveChecks >>>>> # How often list of active checks is refreshed, in >>>>> seconds. >>>>> # >>>>> @@ -265,7 +306,6 @@ ServerActive=3D127.0.0.1 >>>>>=20 >>>>> Include=3D/etc/zabbix_agentd/zabbix_agentd.d/*.conf >>>>>=20 >>>>> - >>>>> ####### USER-DEFINED MONITORED PARAMETERS ####### >>>>>=20 >>>>> ### Option: UnsafeUserParameters >>>>> @@ -299,7 +339,7 @@ >>>>> Include=3D/etc/zabbix_agentd/zabbix_agentd.d/*.conf >>>>> # >>>>> # Mandatory: no >>>>> # Default: >>>>> -# LoadModulePath=3D/usr/lib/modules >>>>> +# LoadModulePath=3D${libdir}/modules >>>>>=20 >>>>> LoadModulePath=3D/usr/lib/zabbix >>>>>=20 >>>>> @@ -357,14 +397,14 @@ LoadModulePath=3D/usr/lib/zabbix >>>>> # TLSCRLFile=3D >>>>>=20 >>>>> ### Option: TLSServerCertIssuer >>>>> -# Allowed server certificate issuer. >>>>> +# Allowed server certificate issuer. >>>>> # >>>>> # Mandatory: no >>>>> # Default: >>>>> # TLSServerCertIssuer=3D >>>>>=20 >>>>> ### Option: TLSServerCertSubject >>>>> -# Allowed server certificate subject. >>>>> +# Allowed server certificate subject. >>>>> # >>>>> # Mandatory: no >>>>> # Default: >>>>> @@ -397,3 +437,80 @@ LoadModulePath=3D/usr/lib/zabbix >>>>> # Mandatory: no >>>>> # Default: >>>>> # TLSPSKFile=3D >>>>> + >>>>> +####### For advanced users - TLS ciphersuite selection >>>>> criteria >>>>> ####### >>>>> + >>>>> +### Option: TLSCipherCert13 >>>>> +# Cipher string for OpenSSL 1.1.1 or newer in TLS 1.3. >>>>> +# Override the default ciphersuite selection criteria for >>>>> certificate-based encryption. >>>>> +# >>>>> +# Mandatory: no >>>>> +# Default: >>>>> +# TLSCipherCert13=3D >>>>> + >>>>> +### Option: TLSCipherCert >>>>> +# GnuTLS priority string or OpenSSL (TLS 1.2) cipher >>>>> string. >>>>> +# Override the default ciphersuite selection criteria for >>>>> certificate-based encryption. >>>>> +# Example for GnuTLS: >>>>> +# NONE:+VERS-TLS1.2:+ECDHE-RSA:+RSA:+AES-128- >>>>> GCM:+AES-128-CBC:+AEAD:+SHA256:+SHA1:+CURVE-ALL:+COMP- >>>>> NULL:+SIGN- >>>>> ALL:+CTYPE-X.509 >>>>> +# Example for OpenSSL: >>>>> +# EECDH+aRSA+AES128:RSA+aRSA+AES128 >>>>> +# >>>>> +# Mandatory: no >>>>> +# Default: >>>>> +# TLSCipherCert=3D >>>>> + >>>>> +### Option: TLSCipherPSK13 >>>>> +# Cipher string for OpenSSL 1.1.1 or newer in TLS 1.3. >>>>> +# Override the default ciphersuite selection criteria for >>>>> PSK-based encryption. >>>>> +# Example: >>>>> +# =20 >>>>> TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256 >>>>> +# >>>>> +# Mandatory: no >>>>> +# Default: >>>>> +# TLSCipherPSK13=3D >>>>> + >>>>> +### Option: TLSCipherPSK >>>>> +# GnuTLS priority string or OpenSSL (TLS 1.2) cipher >>>>> string. >>>>> +# Override the default ciphersuite selection criteria for >>>>> PSK-based encryption. >>>>> +# Example for GnuTLS: >>>>> +# NONE:+VERS-TLS1.2:+ECDHE-PSK:+PSK:+AES-128- >>>>> GCM:+AES-128-CBC:+AEAD:+SHA256:+SHA1:+CURVE-ALL:+COMP- >>>>> NULL:+SIGN- >>>>> ALL >>>>> +# Example for OpenSSL: >>>>> +# kECDHEPSK+AES128:kPSK+AES128 >>>>> +# >>>>> +# Mandatory: no >>>>> +# Default: >>>>> +# TLSCipherPSK=3D >>>>> + >>>>> +### Option: TLSCipherAll13 >>>>> +# Cipher string for OpenSSL 1.1.1 or newer in TLS 1.3. >>>>> +# Override the default ciphersuite selection criteria for >>>>> certificate- and PSK-based encryption. >>>>> +# Example: >>>>> +# =20 >>>>> TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256 >>>>> :TLS_AES_128_GCM_SHA256 >>>>> +# >>>>> +# Mandatory: no >>>>> +# Default: >>>>> +# TLSCipherAll13=3D >>>>> + >>>>> +### Option: TLSCipherAll >>>>> +# GnuTLS priority string or OpenSSL (TLS 1.2) cipher >>>>> string. >>>>> +# Override the default ciphersuite selection criteria for >>>>> certificate- and PSK-based encryption. >>>>> +# Example for GnuTLS: >>>>> +# NONE:+VERS-TLS1.2:+ECDHE-RSA:+RSA:+ECDHE- >>>>> PSK:+PSK:+AES-128-GCM:+AES-128-CBC:+AEAD:+SHA256:+SHA1:+CURVE- >>>>> ALL:+COMP-NULL:+SIGN-ALL:+CTYPE-X.509 >>>>> +# Example for OpenSSL: >>>>> +# =20 >>>>> EECDH+aRSA+AES128:RSA+aRSA+AES128:kECDHEPSK+AES128: >>>>> kPSK+AES128 >>>>> +# >>>>> +# Mandatory: no >>>>> +# Default: >>>>> +# TLSCipherAll=3D >>>>> + >>>>> +####### For advanced users - TCP-related fine-tuning >>>>> parameters >>>>> ####### >>>>> + >>>>> +## Option: ListenBacklog >>>>> +# The maximum number of pending connections in the >>>>> queue. >>>>> This parameter is passed to >>>>> +# listen() function as argument 'backlog' (see "man >>>>> listen"). >>>>> +# >>>>> +# Mandatory: no >>>>> +# Range: 0 - INT_MAX (depends on system, too large values may >>>>> be >>>>> silently truncated to implementation-specified maximum) >>>>> +# Default: SOMAXCONN (hard-coded constant, depends on system) >>>>> +# ListenBacklog=3D >>>>> diff --git a/lfs/zabbix_agentd b/lfs/zabbix_agentd >>>>> index c69643a54..28fe97b4f 100644 >>>>> --- a/lfs/zabbix_agentd >>>>> +++ b/lfs/zabbix_agentd >>>>> @@ -1,7 +1,7 @@ >>>>> ############################################################### >>>>> #### >>>>> ############ >>>>> # =20 >>>>> =20 >>>>> # >>>>> # IPFire.org - A linux based >>>>> firewall # >>>>> -# Copyright (C) 2007-2019 IPFire Team=20 >>>>> # >>>>> +# Copyright (C) 2007-2022 IPFire Team=20 >>>>> # >>>>> # =20 >>>>> =20 >>>>> # >>>>> # This program is free software: you can redistribute it and/or >>>>> modify # >>>>> # it under the terms of the GNU General Public License as >>>>> published >>>>> by # >>>>> @@ -24,7 +24,7 @@ >>>>>=20 >>>>> include Config >>>>>=20 >>>>> -VER =3D 4.2.6 >>>>> +VER =3D 5.0.20 >>>>>=20 >>>>> THISAPP =3D zabbix-$(VER) >>>>> DL_FILE =3D $(THISAPP).tar.gz >>>>> @@ -32,7 +32,7 @@ DL_FROM =3D $(URL_IPFIRE) >>>>> DIR_APP =3D $(DIR_SRC)/$(THISAPP) >>>>> TARGET =3D $(DIR_INFO)/$(THISAPP) >>>>> PROG =3D zabbix_agentd >>>>> -PAK_VER =3D 4 >>>>> +PAK_VER =3D 5 >>>>> DEPS =3D >>>>>=20 >>>>> ############################################################### >>>>> #### >>>>> ############ >>>>> @@ -43,7 +43,7 @@ objects =3D $(DL_FILE) >>>>>=20 >>>>> $(DL_FILE) =3D $(DL_FROM)/$(DL_FILE) >>>>>=20 >>>>> -$(DL_FILE)_MD5 =3D 6cd55cd743d416d9ffbf2e6fdee680ee >>>>> +$(DL_FILE)_MD5 =3D 52df25394f9a4cf83ff55278b23e6295 >>>>>=20 >>>>> install : $(TARGET) >>>>>=20 >>>>> @@ -80,7 +80,8 @@ $(TARGET) : $(patsubst >>>>> %,$(DIR_DL)/%,$(objects)) >>>>> --prefix=3D/usr \ >>>>> --enable-agent \ >>>>> --sysconfdir=3D/etc/zabbix_agentd \ >>>>> - --with-openssl >>>>> + --with-openssl \ >>>>> + --with-libcurl >>>>>=20 >>>>> cd $(DIR_APP) && make >>>>> cd $(DIR_APP) && make install >>>>> --=20 >>>>> 2.34.1 >>>>>=20 >>>>>=20 >>>>> --=20 >>>>> Dit bericht is gescanned op virussen en andere gevaarlijke >>>>> inhoud door MailScanner en lijkt schoon te zijn. >>>>>=20 >>>>=20 >>>>=20 >>>=20 >>> --=20 >>> Dit bericht is gescanned op virussen en andere gevaarlijke >>> inhoud door MailScanner en lijkt schoon te zijn. >>=20 >>=20 >=20 > --=20 > Dit bericht is gescanned op virussen en andere gevaarlijke > inhoud door MailScanner en lijkt schoon te zijn. --===============8071191881226593411==--