Inleiding
Er is een tijd van komen en gaan, dat zeggen ze wel eens. Om even beeld te geven: ik heb diverse virtuele machines in mijn eigen Vmware cloud. Daarvan zijn er 2 met publieke functies te weten “uxx-001” en “uxx-002” met respectievelijk Centos6.8 en Centos5.11. De uxx-002 is de oudste in het ‘serverpark’. Waarom 002 ? Ik weet eerlijk niet meer wat de eerste 001 was.
De uxx-002 server is na ruim 5 jaar definitief uitgezet en verwijderd. Het OS is ouderwets en de software erop niet meer van deze tijd. Dat brengt mij op deze post.
Ik heb daarom ook ruim een jaar terug redelijk wat inhoud van websites uit Centos5.11 met PHP5.3 en functionaliteit verhuisd naar de uxx-001. Daar is tenminste PHP5.6 actief, MySQL (MariaDB) 5.6, Postfix i.p.v Sendmail en meer.
Echter; ik heb nog 2 service VM’s. Deze “services-001” en “services-002” doen bijzaken voor het gehele netwerk, dus ook de via VPN bereikbare thuis netwerken. Deze doen: DNS caching (met Adblock), SMTP (met TLS), LDAP, Tacacs en NTP. Het zijn relatief simpele en platte VM met 1 cpu, 1GB mem en 10GB disk, ook Centos6.8.
Het idee is dus nu ontstaan om deze service VM’s samen te voegen op de bestaande uxx-001 en de nieuwe uxx-002. En uiteindelijk de websites te verhuizen.
De nieuwe server
- Centos7 minimal install, x86_64
- default packages na installatie:
wget mailx mlocate open-vm-tools vim epel-release bind-utils ftp - firewalld vervangen voor iptables
- httpd
- php7
- functionaliteit vanuit services-00x
- ntpd
- dnsmasq
- ldap
- tacacs
- functionaliteit vanuit uxx-001
- mysql
- postfix voor pc-mania.nl domain
- rsyslog vervangen voor syslog-ng
- vsftpd
- cacti en snmpd
- phpmyadmin
- default packages na installatie:
Redelijk eenvoudig zou je zeggen.
Na de basis installatie:
yum install -y wget mailx mlocate open-vm-tools vim epel-release bind-utils ftp systemctl enable vmtoolsd systemctl start vmtoolsd yum update -y && reboot
Na de reboot is de basis er en kunnen we aan de slag. Het eerste is de firewalld vervangen voor iptables. Dit is puur gemak, firewalld werkt ook prima.
yum install -y iptables-services systemctl stop firewalld systemctl start iptables systemctl start ip6tables systemctl enable iptables systemctl enable ip6tables systemctl disable firewalld yum -y remove firewalld
Dan, kunnen we beginnen aan de httpd en php setup. Hiervoor moeten we een extra Repo installeren. Dit is bij de voorkeur REMI. De webtatic en IUS repo’s zijn het over het algemeen nét niet.
wget -4 http://rpms.remirepo.net/enterprise/remi-release-7.rpm rpm -Uvh remi-release-7.rpm
De installatie van httpd en php is dan als volgt
yum install -y httpd mod_ssl yum install -y --enablerepo=remi-php70 php php70-php-mysqlnd php-mysqli php70-php-ldap php70-php-gd
Dan moet er, vanwege een externe Repo wat recht gezet gaan worden.
echo "extension=gd.so" > /etc/php.d/30-gd.ini echo "extension=ldap.so" > /etc/php.d/30-ldap.ini echo "date.timezone = Europe/Amsterdam" /etc/php.ini mv /usr/lib64/php/modules /usr/lib64/php/modules.old ln -s /opt/remi/php70/root/usr/lib64/php/modules /usr/lib64/php/modules systemctl restart httpd
Nu dat gebeurd is kan ook de MySQL server geïnstalleerd. Hier is de voorkeur Percona 5.7 ten opzichte van MariaDB.
yum install -y http://www.percona.com/downloads/percona-release/redhat/0.1-3/percona-release-0.1-3.noarch.rpm yum install -y Percona-Server-server-57
En niet te vergeten:
systemctl enable httpd systemctl enable mysqld systemctl start httpd systemctl start mysqld
Gefeliciteerd! Er is een LAMP-stack actief. Goed, de firewall rules voor poort 80/443 moeten er nog in maar dat ter zijde.
SELinux?
Er is, wat dat moet opgevallen zijn, sprake van een “enforcing” SELinux policy. Vele zetten dit direct in het begin uit met “setenforce 0” maar dat is relatief laf. Daarom alles met Enforcing. Hier zijn later dus ook wat trucs voor. De belangrijkste nu omdat we zover zijn is:
setsebool -P httpd_can_network_connect_db 1
Je leest het goed. Anders werkt je website gewoon niet met MySQL samen.
Netwerk statisch maken
Er is vanuit de basis installatie middels DHCP een adres en via de IPV6_ND een IPv6 adres verkregen. Dit is voor de basis installatie prima geweest maar we veranderen dit nu. Hier is de VMware console voor nodig.
rm -f /var/lib/NetworkManager/dhclient* systemctl stop NetworkManager systemctl disable NetworkManager
Daarna kan je het ifcfg-eth0 bestand keurig invullen naar wens:
TYPE="Ethernet" BOOTPROTO="none" DEFROUTE="yes" IPADDR="192.168.190.52" PREFIX="24" GATEWAY="192.168.190.254" DNS1="192.168.190.21" DOMAIN="192.168.190.22" IPV4_FAILURE_FATAL="yes" IPV6INIT="yes" IPV6ADDR="2001:9a0:5004:1900::52/64" IPV6_DEFAULTGW="2001:9a0:5004:1900::1" IPV6_AUTOCONF="no" IPV6_DEFROUTE="yes" IPV6_FAILURE_FATAL="no" IPV6_FORWARDING="no" IPV6_ADDR_GEN_MODE="stable-privacy" NAME="eth0" # This is system specific and can be created using 'uuidgen eth0' command # UUID="c27bbe86-3299-440e-88bc-9ed5901b2142" DEVICE="ens192" ONBOOT="yes" NM_CONTROLLED=no
Het commando in de comment is mogelijk nog nodig om te draaien op de prompt. Let hier op. Na een extra ‘systemctl restart network’ moet je weer verbonden zijn en kan je het verifiëren met ‘ip a’ of ‘ifconfig’.
De laatste regel is met name van belang zodat deze file gebruikt word voor configuratie van het ‘eth0’ interface, in plaats dat de NetworkManager dit overneemt.
Syslog-NG met MySQL Logparser (Netlog)
Vanuit de Uxx-001 server heb ik een Syslog systeem wat dermate handig en simplistisch is in gebruik maar wel goed oogt dat dit ook mee moet. Hier is in de basis Syslog-NG voor nodig, als mede MySQL en een stukje PHP software. De laatst genoemde functionaliteit is mogelijk, dus nu Syslog-NG nog. Vanuit de CentOS community is er gekozen voor RSyslog en deze zal verwijderd moeten worden.
wget https://copr.fedorainfracloud.org/coprs/czanik/syslog-ng37/repo/epel-7/czanik-syslog-ng37-epel-7.repo mv czanik-syslog-ng37-epel-7.repo /etc/yum.repos.d/syslog-ng37-epel-7.repo systemctl stop rsyslog systemctl disable rsyslog yum -y remove rsyslog yum install -y syslog-ng systemctl start syslog-ng systemctl enable syslog-ng
Meer is het niet, gelukkig en dat scheelt. Nu de meer interessante stukken. Eerst zal de basis van MySQL nog even goed gezet moeten worden.
Configureer in /root een bestand ‘.my.cnf’ . Zoek hiervoor het root password op via “cat /var/log/mysqld.log | grep root@”
[client] user=root pass=<wat je vond>
Nu kan je inloggen in de MySQL server. Hier zullen diverse changes doorgevoerd moeten worden als basis. Het eerste is je password opnieuw invoeren.
ALTER USER 'root'@'localhost' IDENTIFIED BY '<je password>';
Er zullen een aantal databases en tabellen aangemaakt moeten worden. Door onderstaand in te voeren is dat geregeld (voer indien gewenst een ander wachtwoord in op regels 5 en 6:
CREATE DATABASE `syslog`; CREATE DATABASE `netlogconfig`; GRANT ALL ON syslog.* TO 'syslog'@'localhost' IDENTIFIED BY 'WonFaznu$(s#3nCi'; GRANT ALL ON netlogconfig.* TO 'syslog'@'localhost' IDENTIFIED BY 'WonFaznu$(s#3nCi'; USE syslog; CREATE TABLE `template` ( `id` int(15) unsigned NOT NULL AUTO_INCREMENT, `HOST` varchar(39) NOT NULL, `FAC` varchar(255) NOT NULL, `PRIO` varchar(255) NOT NULL, `LVL` varchar(255) NOT NULL, `TAG` varchar(255) NOT NULL, `DAY` varchar(10) NOT NULL, `TIME` varchar(8) NOT NULL, `PROG` varchar(255) NOT NULL, `MSG` text NOT NULL, PRIMARY KEY (`id`), KEY `HOST` (`HOST`), KEY `DAY` (`DAY`), KEY `TIME` (`TIME`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1; USE netlogconfig; CREATE TABLE `hostnames` ( `id` int(10) unsigned NOT NULL auto_increment, `hostip` text NOT NULL, `hostname` text NOT NULL, `hosttype` int(10) unsigned NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1; CREATE TABLE `hosttype` ( `id` int(10) unsigned NOT NULL auto_increment, `name` text NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM; CREATE TABLE `lograte` ( `id` int(10) NOT NULL auto_increment, `hostnameid` int(10) NOT NULL, `timestamp` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, `1min` float default NULL, `5min` float default NULL, `10min` float default NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM; CREATE TABLE `lograteconf` ( `hostnameid` int(10) NOT NULL, `samplerate` int(10) default NULL ) ENGINE=MyISAM; CREATE TABLE `logscavenger` ( `id` int(11) NOT NULL AUTO_INCREMENT, `keyword` varchar(100) DEFAULT NULL, `dateadded` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `active` int(1) NOT NULL, `datedeleted` timestamp NULL DEFAULT NULL, `emailrcpt` varchar(255) DEFAULT NULL, `emailgroup` int(2) DEFAULT NULL, KEY `id` (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1; CREATE TABLE `emailgroups` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `groupname` varchar(40) NOT NULL, `recepients` text NOT NULL, `active` int(1) DEFAULT '1', PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1; CREATE TABLE `logcache` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `host` varchar(39) NOT NULL, `msg` text NOT NULL, PRIMARY KEY (`id`), KEY `host` (`host`), KEY `timestamp` (`timestamp`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
Vervolgens kan de basis van Netlog geinstalleerd worden. Download de installatie files van de Netlog applicatie:
wget https://www.pc-mania.nl/netlog_v2.01.tgz
Dan kan het bestand uitgepakt worden, bij voorkeur in de /tmp of /root directory en de installatie uitgevoerd:
tar xvf netlog_v2.01.tgz cd netlog_v2.01 ./install.sh
Deze zal de bestanden verplaatsen naar de juiste directories. Na deze stap kan het nodige aan instellingen rechtgezet worden indien je bijvoorbeeld het wachtwoord van een of beide databases hebt aangepast. De 2 bestanden voor wachtwoorden zijn, zoals je zag in de install.sh output duidelijk te vinden.
Nu de belangrijkste 2 directory’s en bestanden bestaan is het tijd om deze ‘logparser’ als daemon (service) mee te laten draaien. Dit kan via de systemd systematiek binnen Centos7. De oude ‘/etc/inittab’ met runlevels (3 bijv.) zijn niet meer namelijk.
Maak een bestand aan met de naam ‘/usr/lib/systemd/system/logparser.service‘ en vul deze met:
[Unit] Description=System Logger Parser Daemon After=mysqld.service [Service] ExecStart=/usr/bin/php /usr/share/syslog-ng/php/logparser.php Restart=on-failure [Install] WantedBy=multi-user.target Alias=logparser.service
Dan kan het systeem herladen worden en de service gestart.
systemctl daemon-reload systemctl enable logparser.service systemctl status logparser
De service word nog niet gestart! Dat is met reden dat de Syslog-NG backend nog verteld moet worden wat deze moet doen en hoe deze inkomende berichten moet verwerken.
In het bestand ‘/etc/syslog-ng/syslog-ng.conf’ moeten er 2 sources, 1 destination en 2 log methodes voor toegevoegd worden.
#voer in onder de stanza van 'source s_sys' source s_network_udp { network( ip(0.0.0.0) port(514) transport("udp") ); }; source s_network_tcp { network( ip(0.0.0.0) port(514) transport("tcp") ); }; #voer in onder de stanza van 'destination d_mlal' destination d_mysql { pipe("/var/log/syslog.fifo" template("HOST_:_$SOURCEIP _,_ FAC_:_$FACILITY _,_ PRIO_:_$PRI _,_ LVL_:_$LEVEL _,_ TAG_:_$TAG _,_ DAY_:_$YEAR-$MONTH-$DAY _,_ TIME_:_$HOUR:$MIN:$SEC _,_ PROG_:_$PROGRAM _,_ MSG_:_$MSG\n") template-escape(yes)); }; #voer in onder de laatste stanza van 'log { source(s_sys)' log { source(s_network_udp); destination(d_mysql); }; log { source(s_network_tcp); destination(d_mysql); };
Sla het werk op en herstart de Syslog-NG daemon via “systemctl restart syslog-ng“. Voer desgewenst een check uit met “systemctl status syslog-ng” en “ss -ln|grep 514”:
udp UNCONN 0 0 *:514 *:* tcp LISTEN 0 128 *:514 *:*
Nu Syslog-NG weet wat er moet gebeuren met de inkomende berichten en deze dus met een specifieke opmaak naar het FiFo bestand in ‘/var/log/syslog.fifo‘ moet schrijven kunnen we de logparser service starten.
systemctl start logparser systemctl status logparser ● logparser.service - System Logger Parser Daemon Loaded: loaded (/usr/lib/systemd/system/logparser.service; enabled; vendor preset: disabled) Active: active (running) since Wed 2017-03-29 13:33:37 CEST; 4s ago Main PID: 3155 (php) CGroup: /system.slice/logparser.service └─3155 /usr/bin/php /usr/share/syslog-ng/php/logparser.php Mar 29 13:33:37 uxx-002.pc-mania.nl systemd[1]: Started System Logger Parser Daemon. Mar 29 13:33:37 uxx-002.pc-mania.nl systemd[1]: Starting System Logger Parser Daemon...
Voila. De Netlog parser service draait en als alles goed verlopen is zal ook de website werken. Browse naar http://192.168.190.52/ en de website moet getoond worden. Uiteraard zonder informatie, hosts of categorieen.
Vergeet niet de jobs in ‘/etc/crontab’ actief te zetten. Let op; de laatste regel met “prunelog.php” is alleen noodzakelijk bij een archiver situatie. In dit geval dus even niet.
Test door middel van een extra host of netwerk device of je logging werkt. Een check kan als volgt uitgevoerd worden:
iptables -L -nv Chain INPUT (policy DROP 0 packets, 0 bytes) pkts bytes target prot opt in out source destination ... 96 17444 ACCEPT udp -- * * 0.0.0.0/0 0.0.0.0/0 state NEW udp dpt:514 mysqlshow --count syslog Database: syslog +-------------------------------------+----------+------------+ | Tables | Columns | Total Rows | +-------------------------------------+----------+------------+ | HST_192_168_190_254_DATE_2017_03_29 | 10 | 235 | | template | 10 | 0 | +-------------------------------------+----------+------------+ 2 rows in set.
Voor de lograte pagina moet er een correctie gedaan worden. Vanwege PHP7 is GD nog niet volledig up to date. Bewerk het bestand ‘/usr/share/php/jpgraph/gd_image.inc.php’ op regel 110 en zet de “//” voor deze regel
//JpGraphError::RaiseL(25128);//(......
Om de pagina direct beter te laten werken (er zijn namelijk wat functies missend in de settings.php) moet er handmatig even wat via MySQL gedaan worden:
use netlogconfig; insert into hosttype values (1,"Firewall") insert into hostnames (hostip,hostname,hosttype) values ("192.168.190.254","dc-firewall",1); insert into lograteconf values (1,1); exit;
Ga naar de logout knop op de pagina om de sessie te resetten. En dan zal de logging getoond moeten worden.
Webserver en TLS/SSL
De standaard inrichting van httpd en php zijn nog van toepassing. Ook de zojuist geïnstalleerde Netlog applicatie draait, jawel, in de standaard ‘/var/www/html’ directory. Geen probleem. Er zal wat aangepast moeten worden.
#Listen 80 Listen *:80 #ServerAdmin root@localhost ServerAdmin bartjan [ at ] pc-mania [dot] nl #ServerName www.example.com:80 ServerName uxx-002.pc-mania.nl
Maak een default site aan, zodat alle request daar op binnen komen in de configuratie ‘/etc/httpd/conf.d/_default-site.conf‘
<VirtualHost *:80> DocumentRoot /var/www/html ServerName uxx-002.pc-mania.nl <Directory /var/www/html> AllowOverride all Options MultiViews IncludesNoExec FollowSymLinks </Directory> </VirtualHost>
Test de configuratie met het commando ‘httpd -t‘ en eventueel met de output van ‘httpd -S’ zoals hieronder (let op, het voorheen gebruikte ‘apachectl -S’ word niet meer gebruikt):
httpd -S VirtualHost configuration: *:443 uxx-002.pc-mania.nl (/etc/httpd/conf.d/ssl.conf:56) *:80 is a NameVirtualHost default server uxx-002.pc-mania.nl (/etc/httpd/conf.d/_default-site.conf:1) port 80 namevhost uxx-002.pc-mania.nl (/etc/httpd/conf.d/_default-site.conf:1)
Nu kunnen er meer websites toegevoegd worden, door elke in zijn eigen .conf bestand te plaatsen. Verplaats de inhoud van de map ‘/var/www/html’ naar een nieuwe map ‘/var/www/syslog’ en voeg deze configuratie toe in ‘/etc/httpd/conf.d/syslog.pc-mania.nl.conf’
<VirtualHost *:80> DocumentRoot /var/www/syslog ServerName syslog.pc-mania.nl <Directory /var/www/syslog> AllowOverride all Options MultiViews IncludesNoExec FollowSymLinks </Directory> </VirtualHost>
Voer een herstart uit met ‘apachectl restart’ of ‘systemctl restart httpd’ en controleer of de output van ‘httpd -S’ nu uitgebreid is.
TLS/SSL hardening toepassen
Voordat we TLS (of SSL) gaan toepassen moeten er wat regels gezet worden wat de beveiliging omhoog brengt. Dit voorkomt mogelijke man-in-the-middle aanvallen of andere meeluister praktijken. Dat zal niet hard lopen met de hobby matige informatie maar toch.
Maak een bestand aan ‘/etc/httpd/conf.d/security.conf en voeg onderstaande in.
ServerTokens Prod ServerSignature Off TraceEnable Off Header set X-Content-Type-Options: "nosniff" Header set X-Frame-Options: "sameorigin" Header unset ETag FileETag None
Nadat deze aangemaakt is moet ook de ‘/etc/httpd/conf.d/ssl.conf’ er aan geloven. Open deze en voeg het volgende toe onderaan het bestand:
SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1 SSLCipherSuite EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH:AES256+ED SSLHonorCipherOrder on ## ## Header context ## Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" Header always edit Set-Cookie ^(.*)$ $1;secure Header always set X-Frame-Options "DENY" Header always set X-XSS-Protection "1; mode=block" Header always set X-Content-Type-Options "nosniff" Header always set X-Permitted-Cross-Domain-Policies "none"
Verwijderd het gehele stuk van de ‘virtualhost _default_:443’ en voeg dit toe aan de ‘/etc/httpd/conf.d/_default-site.conf:
<VirtualHost *:443> DocumentRoot /var/www/html ServerName uxx-002.pc-mania.nl SSLEngine on SSLCertificateFile /etc/pki/tls/certs/localhost.crt SSLCertificateKeyFile /etc/pki/tls/private/localhost.key <Directory /var/www/html> AllowOverride all Options MultiViews IncludesNoExec FollowSymLinks </Directory> </VirtualHost>
En ook dat werkt nu, op het certificaat na, goed. Dat is eenvoudig toe te voegen door LetsEncrypt.
yum install -y python-certbot-apache
Zorg wel dat de server uiteraard bereikbaar is op DNS en IP adres, zowel poort 80 en 443.
certbot --apache certonly -m bartjan [ at ] pc-mania [dot] nl -d uxx-002.pc-mania.nl
Hierna zijn er diverse files gegenereerd en kan je de configuratie in de ‘/etc/httpd/conf.d/_default-site.conf’ aanpassen:
SSLCertificateFile /etc/letsencrypt/live/uxx-002.pc-mania.nl/cert.pem SSLCertificateKeyFile /etc/letsencrypt/live/uxx-002.pc-mania.nl/privkey.pem SSLCertificateChainFile /etc/letsencrypt/live/uxx-002.pc-mania.nl/chain.pem