ELK en CentOs7

Aprofitant els dies lliures de vacances i amb el propòsit de conèixer les novetats de ELK, m’he decidit a instalar-ho en una màquina virtual vBox amb l’objectiu conèixer i practicar l’indexació de logs implementant-ho en un CentOs7. Alhora, tinc un bon amic que ho vol implementar i m’agradaria que serveixi de recull de comandes i una petita guia d’implementació.

En aquest post va dirigit a tots els usuaris que coneixen ELK (Elasticsearch+Logstash+kibana), no vull pas explicar que és cada component sinó únicament recopilar totes les configuracions i joc de proves utilitzades en el montatge del següent diagrama.

En aquest diagrama recullo la foto de totes les eines que he utilitzat en la màquina virtual, alhora, he pujat les diferents configuracions, VagrantFile i passwords al GitHub i la màquina virtual en el MEGA, pesa 1.5GB , deixo aquí els links per si algú la vol descarregar.

Elk-CentoOs7

Bàsicament veiem com utilitzem logstash per agafar els logs de APACHE, SYSLOG, ELASTICSEARCH i CARBON, on enviem els logs filtrats amb els camps ja splittejats a 4 cues diferents de Redis, on tindrem una altra instancia de logstash que va agafant les dades d’aquestes 4 cues i les va insertant al Elasticsearch. A través de la interficie Kibana podem crear dashboard i interpretar les dades (els logs) recopilats.

Si ens centrem com he utilitzat logstash per a tal de recollir els logs:
– Apache: la instancia de logstash va recollint les traces dels fitxers de logs del apaches, les filtra i les envia al redis.
– Carbon-cache: una instancia de logstash va recollint les traces dels fitxers de logs del carbon-cache, aplica un filtre i ho envia al redis
– Syslog: Hem afegit en el Rsyslog de Centos7 l’enviem dels logs del SYSLOG al port 514/tcp, on tenim una instancia de logstash que agafa els logs, els filtra i els envia a Redis.
– Elasticsearch: molt semblant al anterior, es a dir, modifiquem el logging de ES per a escriure els logs al port 9300/tcp, on tindrem una instancia de logstash que anirà recollint els logs, filtrant i enviant-ho al Redis.

Alhora, hem instalat un graphite+carbon que va recollint les dades del OS i dels serveis Redis i Elasticsearch a través de “diamond”, un python script molt complert per recollir dades al graphite. En aquest cas, la interficie de Grafana i Graphite ens permetrà graficar.

yum -y update
yum install -y httpd net-snmp perl pycairo mod_wsgi python-devel git gcc-c++
yum install -y python-pip node npm
pip install 'django<1.6'
pip install 'Twisted<12'
pip install django-tagging
pip install whisper
pip install graphite-web
pip install carbon
yum install collectd collectd-snmp
cp /opt/graphite/examples/example-graphite-vhost.conf /etc/httpd/conf.d/graphite.conf
cp /opt/graphite/conf/storage-schemas.conf.example /opt/graphite/conf/storage-schemas.conf
cp /opt/graphite/conf/storage-aggregation.conf.example /opt/graphite/conf/storage-aggregation.conf
cp /opt/graphite/conf/graphite.wsgi.example /opt/graphite/conf/graphite.wsgi
cp /opt/graphite/conf/graphTemplates.conf.example /opt/graphite/conf/graphTemplates.conf
cp /opt/graphite/conf/carbon.conf.example /opt/graphite/conf/carbon.conf
chown -R apache:apache /opt/graphite/storage/
vi /opt/graphite/conf/storage-schemas.conf #set granularity and retention data on whisper files
cd /opt/graphite/webapp/graphite
sudo python manage.py syncdb
systemctl enable httpd
systemctl start httpd
/opt/graphite/bin/carbon-cache.py start
#/opt/graphite/bin/run-graphite-devel-server.py /opt/graphite/ #developer mode
chmod 777 /opt/graphite/storage/log/webapp/
# Be ware fix permissions for sqlite database
chmod 777 /opt/graphite/storage/graphite.db
vi /etc/systemd/system/carbon-cache-a.service
 [Unit]
 Description=carbon-cache instance A (graphite)

 [Service]
 User=root
 Group=root
 ExecStartPre=/bin/rm -f /opt/graphite/storage/carbon-cache-a.pid
 ExecStart=/opt/graphite/bin/carbon-cache.py --instance=a start
 Type=forking
 PIDFile=/opt/graphite/storage/carbon-cache-a.pid
 LimitNOFILE=128000

 [Install]
 WantedBy=multi-user.target
systemctl enable carbon-cache-a.service
yum -y install java-1.7.0-openjdk
rpm --import http://packages.elasticsearch.org/GPG-KEY-elasticsearch
vi /etc/yum.repos.d/elasticsearch.repo #add follow lines
 [elasticsearch-1.1]
 name=Elasticsearch repository for 1.1.x packages
 baseurl=http://packages.elasticsearch.org/elasticsearch/1.1/centos
 gpgcheck=1
 gpgkey=http://packages.elasticsearch.org/GPG-KEY-elasticsearch
 enabled=1
yum -y install elasticsearch-1.1.1
vi /etc/elasticsearch/elasticsearch.yml #modify next parameters if it is necessary
 script.disable_dynamic: true
 discovery.zen.ping.multicast.enabled: false
systemctl start elasticsearch.service
systemctl enable elasticsearch.service
#Enable kopek and head elastic search pluging
/usr/share/elasticsearch/bin/plugin --install mobz/elasticsearch-head
/usr/share/elasticsearch/bin/plugin --install lmenezes/elasticsearch-kopf
mkdir -p /opt/www/kibana
cd !$; curl -s -L https://download.elasticsearch.org/kibana/kibana/kibana-3.0.1.tar.gz | tar xz
mv kibana-3.0.1/* . && rmdir kibana-3.0.1
vi ~/kibana-3.0.1/config.js #modify next parameters if it is necessary
 elasticsearch: "http://"+window.location.hostname+":80",
vi /etc/httpd/conf.d/kibana3.conf #modify next parameters if it is necessary

  ServerName kibana

  DocumentRoot /opt/www/kibana

    Allow from all
    Options -Multiviews


  LogLevel debug
  ErrorLog /var/log/httpd/kibana_error_log
  CustomLog /var/log/httpd/kibana_access_log combined

  # Set global proxy timeouts
  
    ProxySet connectiontimeout=5 timeout=90


  # Proxy for _aliases and .*/_search
  <LocationMatch "^/(_nodes|_aliases|.*/_aliases|_search|.*/_search|_mapping|.*/_mapping)$">
    ProxyPassMatch http://127.0.0.1:9200/$1
    ProxyPassReverse http://127.0.0.1:9200/$1


  # Proxy for kibana-int/{dashboard,temp} stuff (if you don't want auth on /, then you will want these to be  protected)
  <LocationMatch "^/(kibana-int/dashboard/|kibana-int/temp)(.*)$">
    ProxyPassMatch http://127.0.0.1:9200/$1$2
    ProxyPassReverse http://127.0.0.1:9200/$1$2


systemctl start httpd.service
systemctl enable httpd.service
vi /etc/yum.repos.d/logstash.repo #add follow lines
 [logstash-1.4]
 name=logstash repository for 1.4.x packages
 baseurl=http://packages.elasticsearch.org/logstash/1.4/centos
 gpgcheck=1
 gpgkey=http://packages.elasticsearch.org/GPG-KEY-elasticsearch
 enabled=1
yum -y install logstash-1.4.2
mkdir -p /opt/www/grafana
cd !$; curl -s -L http://grafanarel.s3.amazonaws.com/grafana-1.9.0.tar.gz | tar xz
mv grafana-1.9.0/* .
rmdir grafana-1.9.0
cp config.sample.js config.js
vi config.js #be sure these lines are enabled
      datasources: {
        graphite: {
          type: 'graphite',
          url: "http://graphite:80",
        },
        elasticsearch: {
          type: 'elasticsearch',
          url: "http://127.0.0.1:9200",
          index: 'grafana-dash',
          grafanaDB: true,
        }
vi /etc/httpd/conf.d/grafana.conf #add these configuration lines

  ServerName grafana

  DocumentRoot /opt/www/grafana

    Allow from all
    Options -Multiviews


  LogLevel debug
  ErrorLog /var/log/httpd/grafana_error_log
  CustomLog /var/log/httpd/grafana_access_log combined

systemctl start httpd.service
systemctl enable httpd.service
#we need Epel repository enabled
yum install redis
systemctl start redis.service
systemctl status redis.service
systemctl enable redis.service
redis-cli ping
echo "127.0.0.1 kibana grafana graphite redis-commander" > /etc/hosts
systemctl stop firewalld
systemctl disable firewalld
vi /etc/selinux/config #Be ware is disabled instead of enforced in the next config line
 SELINUX=disabled
reboot
#Add "Require all granted" in any vhost applied in this lab
#more info: http://httpd.apache.org/docs/2.4/upgrading.html
 Require all granted

Aquestes són les eines implementades:
-Elasticsearch, prices java on tenim indexat les diferents tipus de traces, com podem veure:
Captura de pantalla 2015-01-12 a les 1.24.07
-Kibana, aplicació javascript que permet fer consultes, dashboards per interpretar els logs indexats en el ES.
Kibana_3_-_BasicELK1_-_2015-01-12_01.33.44
-Logstash, aplicació java que recull els logs, el filtra i categoritza i els indexa al ES, utilitzant Redis com a memoria intermedia.
-Grafana, aplicació Javascript que permet fer consultes, dashboards de les dades de graphite.
Grafana_-_ELK-1_-_2015-01-10_18.15.38
-Graphite+Carbon-Cache+Diamond, aplicació en python que recull estat dels serveis i els introdueix al carbon. Aquí veiem com ho podem consultar a través de la webapp de graphite.
Captura de pantalla 2015-01-12 a les 1.28.00
-Redis + Redis-Commander, memoria intermedia on logstash va guardant els logs ja filtrats. Redis-Commander es una aplicació en nodeJS que permet monitorar l’estat de les 4 cues que utlitzem de Redis.
Captura de pantalla 2015-01-11 a les 20.11.09

Si us baixeu la maquina virtual vBox i la inicieu amb Vagrant (utilitzant aquest VagrantFile que linko aquí), aquestes serán les URLs de les aplicacions implementades:
URL ES: http://127.0.0.1:39200
Pluguin Head ES, http://127.0.0.1:39200/_plugin/head/
Kibana GUI, http://kibana:3080
Grafana GUI, http://grafana:3080/
Graphite GUI, http://graphite:3080/
Redis Commander GUI, http://redis-commander:3080/

També recopilo les fonts que he seguit per instalar-ho i configurar-ho.
http://sourceforge.net/projects/mustsyslog/?source=typ_redirec
http://kartar.net/2014/09/when-logstash-and-syslog-go-wrong/
http://www.ozmonet.com/projects/graphite.html
https://www.digitalocean.com/community/tutorials/how-to-use-logstash-and-kibana-to-centralize-logs-on-centos-7
http://www.rsyslog.com/doc/rsyslog_reliable_forwarding.html


Graphite: gran recurs per gràficar sistemes

després de un parell de caps de setmana aprenent el potencial del Grpahite i aprofitant que he descobert el Omnigraffle també m’he animat a fer uns dibuixets.

En aquest post recopilaré les comandes i configuracions aplicades per montar un lab en el macbook, on l’objectiu ha estat conèixer cadascun dels components que ens proporciona el Grpahite per a tal d’escalar-ho i també d’aconseguir una mica de alta disponibilitat.

Mostraré 3 escenaris i comentaré les configuracions, on anirà creixent la complexitat alhora que tindrem el montatge preparat per recollir/graficar més quantitat de dades de forma més segura, ja enfoncant-ho per entorns de producció.

Les eines que he fet servir han estat Vagrant+VirtualBox per a virtualizat i Ubuntu 13.04 LTS en cadascun dels nodes virtualitzats.

Evidentment, tot el que he practicat i après ha estat llegint les següents fonts:
https://launchpad.net/graphite
http://graphite.wikidot.com/installation
http://bitprophet.org/blog/2013/03/07/graphite/

Comencem per el escenari més sencill, on montem una maquina virtual Ubuntu a sobre el virtual Box amb Vagrant, on us pasaré les comandes utilitzades per a la instalació base.

	
wget https://launchpad.net/graphite/0.9/0.9.10/+download/check-dependencies.py
python check-dependencies.py
apt-get update
apt-get upgrade
apt-get update
apt-get -y install python-cairo python-django python-django-tagging python-memcache python-ldap python-zope python-twisted python-txamqp
python check-dependencies.py
apt-get -y install git vim 

wget https://launchpad.net/graphite/0.9/0.9.10/+download/whisper-0.9.10.tar.gz
tar xvfz whisper-0.9.10.tar.gz
cd whisper-0.9.10/
python setup.py install
cd ..
wget https://launchpad.net/graphite/0.9/0.9.10/+download/carbon-0.9.10.tar.gz
tar xvfz carbon-0.9.10.tar.gz
cd carbon-0.9.10/
python setup.py install
cd ..
wget https://launchpad.net/graphite/0.9/0.9.10/+download/graphite-web-0.9.10.tar.gz
tar xvfz graphite-web-0.9.10.tar.gz
cd graphite-web-0.9.10/
python setup.py install
cd ..

apt-get install libapache2-mod-wsgi
cd /opt/graphite/conf
cp carbon.conf.example carbon.conf
vim carbon.conf
cp storage-schemas.conf.example storage-schemas.conf
vim storage-schemas.conf
/opt/graphite/bin/carbon-cache.py start
cp /opt/graphite/webapp/graphite/local_settings.py.example /opt/graphite/webapp/graphite/local_settings.py
vim /opt/graphite/webapp/graphite/local_settings.py
rm /etc/apache2/sites-enabled/000-default
cd /opt/graphite
cp ./examples/example-graphite-vhost.conf /etc/apache2/sites-enabled/
chown -R www-data webapp
chgrp www-data storage
chmod g+w storage
su - www-data
 cd /opt/graphite
 PYTHONPATH=`pwd`/webapp:`pwd`/whisper python ./webapp/graphite/manage.py syncdb
cp /opt/graphite/conf/graphite.wsgi.example /opt/graphite/conf/graphite.wsgi
chgrp www-data /opt/graphite/storage/log/webapp
chmod g+w /opt/graphite/storage/log/webapp
/etc/init.d/apache2 restart

L’escenari que obtenir és el segment i detallem per sobre cadascuna de les peces:
scenari1

diamon.py: Python script que recull dades del sistema que volem graficar. Més info a aquí. Aquest dimoni enviará les dades en format plà al port 2003/tcp del carbon-cache.py amb el format: “NOM_DADE VALOR_DADA TIMESTAMP”. També ho pot enviar al port 2004/tcp si volem optimitzar l’enviament.
carbon-cache.py: Python Script que recull les dades tcp o udp, va emmagatzemant les dades en RAM i va volcant les dades al filesystem. La granularitat i la retenció de dades són definides a aquí.
Fitxer de dades WHISPER: En el sistema de fitxers tindrem un fitxer per a cada tipu de dada, amb extensió WSP
Una webapp python serà la encarregada de partir dels fitxers WHISPER permetré graficar-los i obetnir els reports.

El carbon-cache.py és el component més important, per una banda, a ell li direm com guardarem les dades i per una altra també defineix com s’escala tota la solució, ja que si volem més capacitat haurem de posar més carbon-cache.py (1 per vCPU) i un carbon-relay.py per sobre que vagi distribuint l’entrada de dades.
TIP: En el cas de voler fer sharding de dades, ho hauriem de definir a aquí.

A l’hore de agregar dades, ho tenim en 3 formes diferents:
– Les guardem totes les dades granulades en els fitxers WSP i en la webapp graphite serà on les pintem agregades utilitzant funcions i el gran amic wilcard “*”.
– Fem un agregat de dades en el carbon-cache.py a l’hora de emmagatzemar-ho a disc en el fitxer WSP, per defecte, quant tenim varies dades per a un mateix “instant” de temps, carbon-cache utilitza la funció de mitjana amb les dades entrants i només guarda un resultat. Podem canviar la funció de agregació i jugant amb els patrons en el carbon-cache.py, això ho especifiquem en el fitxer storage-aggregations.conf.
– Per sobre del carbon-cache.py hi posem un altre python script carbon-aggregator.py on anirà agregant les dades rebudes del collectors i les enviarà al carbon-cache.

Ara ja estem en condicions d’entendre el seguent resum:
summary

El segon escenari, duplicarem el numero de nodes i afegirem el carbon-relay.py en cadascun d’ells. En aquest hi definirem un factor de replicació de 2 i enviarem les dades el corresponent carbon-cache.py i al carbon-relay de l’altre node. Obtindrem el següent escenari:
HAcreuat

En la següent captura teniu els dos webapps on veiem que grafiquen dades dels 2 collectors:
Captura de pantalla 2014-04-26 a les 10.35.46

Finalment, l’ultime escenari que tenim es afegir un 3 node on únicament hi montarem un carbon-relay.py i serà ell qui rebi tot el trafic d’entrada i qui apliqui un factor de replicació 2, on passarà el trafic als carbon-relay.py que hi tenim en cada node. A més, duplicarem en cada node el numero de carbon-cache.py. En el fitxer relay-rules.conf definirem quines dades enviarem a cadascun del cabon-caches.py de cada node.

hafull

Per concluir, us paso el fitxer de Vagrant on teniu definides les 3 VMs per si algú el vol aprofitar.

❯ cat Vagrantfile
Vagrant::Config.run do |config|
    config.vm.define :graphiterelay do |graphiterelay_config|
        graphiterelay_config.vm.box = "graphiterelay"
        graphiterelay_config.vm.box_url = "package.box"
        graphiterelay_config.vm.forward_port 80,8000
        graphiterelay_config.vm.forward_port 8888,8888
        graphiterelay_config.vm.forward_port 443,44300
        graphiterelay_config.vm.network :hostonly, "192.168.50.2", :netmask => "255.255.255.0"
    end
    config.vm.define :graphite do |graphite_config|
	graphite_config.vm.box = "graphite"
	graphite_config.vm.box_url = "/Users/mcortinas/Boxes/ubuntu-precise12042-x64-vbox43.box"
        graphite_config.vm.forward_port 80,8001
        graphite_config.vm.forward_port 443,44301
	graphite_config.vm.forward_port 8888,18888
	graphite_config.vm.network :hostonly, "192.168.50.4", :netmask => "255.255.255.0"
    end
    config.vm.define :graphite2 do |graphite2_config|
        graphite2_config.vm.box = "graphite2"
        graphite2_config.vm.box_url = "package.box"
        graphite2_config.vm.forward_port 80,8002
	graphite2_config.vm.forward_port 8888,28888
        graphite2_config.vm.forward_port 443,44302
	graphite2_config.vm.network :hostonly, "192.168.50.5", :netmask => "255.255.255.0"
    end
end

Kibana ens ajuda amb els logs de AWS Cloudfront i WAF Akamai

L’anàlisis dels logs en qualsevol plataforma és molt important ja que ens permet veure quin és el comportament de cadascun dels components, alhora, ens permet des de corregir error, preveure averies a millorar el producte. De totes les solucions que he tingut la sort de probar, Splunk és la que més m’ha agradat. L’unic inconvenient d’utilitzar l’Splunk és el seu preu.

Degut al alt cost de l’Splunk i aprofitant que l’empresa on treballo necessita analitzar els logs de les CDNs de AWS Cloudfront i Akamai, vaig aprofitar per probar Kibana+Elastcisearch+Logstash. L’objectiu d’aquest post és mostrar el potencial d’aquesta combinació, una solució més econòmica que el gran tot poderos Splunk.

Comencem amb els logs de Akmaai, aquí us paso el format de log que volem analitzar, extret de la documentació oficial:

waf_logformat

apache_logformat

El filtre de logstash que he implementat és :

filter {
    grok {
      type => "esw3c_waf"
      match => { "message" => "%{IPORHOST:clientip} %{USER:ident} %{USER:auth} \[%{HTTPDATE:timestamp}\] (?:%{WORD:verb} %{NOTSPACE:request}(?: HTTP/%{NUMBER:httpversion})?|%{DATA:rawrequest}) %{NUMBER:response} (?:%{NUMBER:bytes}|-) %{QS:referrer} %{QS:agent} %{QS:cookies} \"%{WORD:WafPolicy}\|%{DATA:WafAlertRules}\|%{DATA:WafDenyRules}\"" }
    }

    date {
      type => "esw3c_waf"
      match => [ "timestamp", "dd/MMM/yyyy:HH:mm:ss Z" ]
      locale => "en"
    }

}

Pel que fa als logs de AWS Cloudfront, el format del log esta documentat en aquest , però basicament és:

#Fields: date time x-edge-location sc-bytes c-ip cs-method cs(Host) cs-uri-stem sc-status cs(Referer) cs(User-Agent) cs-uri-query cs(Cookie) x-edge-result-type x-edge-request-id x-host-header cs-protocol cs-bytes 
07/01/2012 01:13:11 FRA2 182 192.0.2.10 GET d111111abcdef8.cloudfront.net /view/my/file.html 200 www.displaymyfiles.com Mozilla/4.0%20(compatible;%20MSIE%205.0b1;%20Mac_PowerPC) - zip=98101 RefreshHit MRVMF7KydIvxMWfJIglgwHQwZsbG2IhRJ07sn9AkKUFSHS9EXAMPLE== d111111abcdef8.cloudfront.net http -

A més, logstash té implementat un input contra S3, ideal per a aquest cas.
Per la part del filtre, l’expressió és la seguent:

filter {
    grok {
    type => "aws"
    pattern => "%{DATE_EU:date}\t%{TIME:time}\t%{WORD:x-edge-location}\t(?:%{NUMBER:sc-bytes}|-)\t%{IPORHOST:c-ip}\t%{WORD:cs-method}\t%{HOSTNAME:cs-host}\t%{NOTSPACE:cs-uri-stem}\t%{NUMBER:sc-status}\t%{GREEDYDATA:referrer}\t%{GREEDYDATA:User-Agent}\t%{GREEDYDATA:cs-uri-stem}\t%{GREEDYDATA:cookies}\t%{WORD:x-edge-result-type}\t%{NOTSPACE:x-edge-request-id}\t%{HOSTNAME:x-host-header}\t%{URIPROTO:cs-protocol}\t%{INT:cs-bytes}"
}
mutate {
    type => "aws"
        add_field => [ "listener_timestamp", "%{date} %{time}" ]
    }
date {
      type => "aws"
      match => [ "listener_timestamp", "yy-MM-dd HH:mm:ss" ]
    }
}

Per cert, recomenar-vos activar el LifeCycle en el Bucket de S3 per a configurar un purgat de logs, creix ràpid (evidentment, el creixement també depen del vostre tràfic).

Un cop definit com farem la importació passem a comentar on guardarem les dades, ho farem en el Elasticsearch 1.0 aprofitant que ha sortit recentment. Vull destarcar 2 pluguins que als sysadmins els agradara conèixer, el pluguin HEAD i MARVEL.

Captura de pantalla del pluguin HEAD, on hem fet un index per dia/cdn
ElasticHead

Captura de pantalla del pluguin MARVEL
Marvel

Abans de pasar a la part de pintar les dades, us paso dos links amb les GROKS disponibles i una eina per a contruir-les
Llista de patrons GROK disponibles
Eina per construir les configuracions

Per acabar, per a pintar totes aquestes dades utilitzarem la aplicació de Kibana, una aplicació javascript que utilitza les dades del elaticsearch per a poder crear informes, gràfiques i filtres acurats.

Per començar he fet 2 dashboards molt simples, per una banda el de WAF de Akamai i per una altra el de Cloudfront.

Dashboard de Cloudfront:
CloudfrontDashboard

Dashboard de Akamai:
AkamaiDashboard


varnish-cache, un molt bon aliat per a la web

Ja fa un parell d’anys que faig servir el varnish cache i és un molt bon aliat de qualsevol plataforma web per descarregar als servidors http (apache, nginx, lighthttpd, etc… ) i al backend, ja sigui per aplicacions amb poc tràfic com per aplicacions/plataformes d’alt rendiment, on pot ser un CLAU aliat.

Per això, en aquest post enumenarem les raons principals d’implantar el varnish, citarem els processos i posarem 4 exemples de configuracions amb diferents proposits.

Bueno, començaré enumerant les 3 funcionalitats principals:
– Accelerador de continguts web, minimitzant considerablement els temps mitjans de resposta dels continguts dinamics d’un site.
– Alliberar de càrrega el backend, des dels servidors web i sobretot a les bases de dades, sql i nosql.
– Permetre servir continguts “caducats” en cas que la plataforma tingui problemes de rendiment.

Altres funcionalitats més avançades que podem fer amb Varnish es,
– Si treballeu amb CDNs pot fer el paper d’amortidor en moments de canvis bruscos de tràfic, per exemple, un campanya amb molt èxit, una noticia important, etc…
– Securitzar el website, per segons quines parts de la web podem exigir que les peticions haguin de complir uns determinats requeriments. Això també ho pot fer el apache, però aixi el podem alliberar d’aquestes tasques.
– En plataformes d’alt rendiment, si treballeu amb CDNs, per bloquejar l’accés a determinades parts de les webs que no es puguin processar per averia en el sistema.

Segur que podeu trobar altres funcionalitats, aquestes són les que he utilitzat.

La filosofia del Varnish es emmagatzemar a memòria volàtil tots els cantinguts “cachejables” i estalviar de cicles de proces i cicles d’espera d’entrada i sortida, es a dir, l’equiliri IO-CPU-RAM es veurà afectat així: disminuim IO, disminuim us de CPU, increment ús de memoria, on és molt important dimensionar bé la memòria que utilitzarem.

Un dels principals inconvenients dels Varnish és el HTTPS, encara que té el sentit. Varnish és un accelerador de continguts HTTP que vol disminuir el temps de resposta, el httpS és el contrari, requereix de temps de proces per a tal d’assegurar la seguretat. Conclusió, Varnish no es capaç i no ho serà mai de servir contignut per HTTPS. Només el podrem fer servir per aquelles parts del website que no siguin segures. També ho podeu utilitzar en parts de la web segures si poseu un nginx per davant, en aquest altre post teniu explicat millor aquesta solució.

D’altra banda, la corba d’aprenentatge del varnish es considerable, de fet, un graph em va ajudar a entendre totes les transicions possibles, es a dir, és el tipic aliat que si el compliquem molt es pot tornar en enemic. De fet, el varnish són 2 procesos un pare i un fill (fork), on el pare fa el paper de gestió i compila les configuracion escrites amb llenguatge VCL i el fill és qui realment fa realment les funcions descrites en la configuracio VCL. En aquest link ho explica detalladament.

Es a dir, la clau del varnish, és escriure un VCL amb allò que realment necessitem que faci. Aqui us deixo un graph que vaig decidir fer un cop vaig llegir la documentació oficial del varnish d’aquest link.
Varnish_subroutines_Graph

Seguidament posarem 3 exemples de fitxers basics de VCL i comentarem la seva finalitat:

Exemple 1

backend default {
  .host = "127.0.0.1";
  .port = "8080";
  .max_connections = 40;
  .first_byte_timeout = 180s;
  .between_bytes_timeout = 180s;
}

sub vcl_recv {
      return(pass);
}

Aquesta configuració l’únic que voliem és limitar la quantitat de connexions(max_connections) que li passarem al un apache en local, en aquest cap no cachejem res.

Exemple 2

backend default {
  .host = "127.0.0.1";
  .port = "8080";
  .max_connections = 200;
  .connect_timeout = 180s;
  .first_byte_timeout = 180s;
  .between_bytes_timeout = 180s;
  .probe = {
    .url = "/healthcheck.php";
    .timeout = 100 ms;
    .interval = 1s;
    .window = 10;
    .threshold = 8;
  }
}

sub vcl_recv {
  if (req.http.Host == "setup.domain.com")
  {
    set req.grace = 30s;
    return(lookup);
  }
  else
  {
   return(pass);
  }
}

sub vcl_fetch {
  set beresp.grace = 1h;
}

En aquest exemple només cachejem les peticions del domini “setup.domain.com”, domini intern de la plataforma que serveix les configuracions de l’aplicació. Ademés, volem que si el backend no respon, seguiran sen vàlids durant 1 hora. Això ho conseguim en les tres últimes linies de codi. El meu company Tomas té un article on exemplifica molt bé aquest comportament. Una de les coses més interessants del article de Tomàs es diferenciar les dues situacions en les que aquest parametre es important.
– No hi ha cap backend disponible, per tant servim contingut antic.
– Hi ha backends disponibles, i un fil ja ha demanat nou contingut. Mentre aquest nou contingut arriba des del backend, el varnish continua servint l’antic a la resta de fils.

Exemple 3

sub vcl_recv {
…
        if (req.url ~ ".*remindmethepassword.*" && !req.http.User-Agent) {
            error 403 "Forbidden";
        }
…
        return(pass);
}

En el exemple anterior, podem aferir-hi regles que augmentent la seguretat, per exemple, en les peticions que tinguin remindmethepassword en la URL necessitaran tenir el User-Agent, sino retornem un 403.

Exemple 4

backend default {
  .host = "127.0.0.1";
  .port = "8080";
  .max_connections = 200;
  .connect_timeout = 180s;
  .first_byte_timeout = 180s;
  .between_bytes_timeout = 180s;
  .probe = {
    .url = "/healthcheck.php";
    .timeout = 10 ms;
    .interval = 5s;
    .window = 5;
    .threshold = 3;
  }
}

sub vcl_error {
}

sub vcl_recv {
     if (req.restarts == 0) {
       if (req.http.x-forwarded-for) {
           set req.http.X-Forwarded-For =
               req.http.X-Forwarded-For + ", " + client.ip;
       } else {
           set req.http.X-Forwarded-For = client.ip;
       }
     }
     if (req.request != "GET" &&
       req.request != "HEAD" &&
       req.request != "PUT" &&
       req.request != "POST" &&
       req.request != "TRACE" &&
       req.request != "OPTIONS" &&
       req.request != "DELETE") {
         /* Non-RFC2616 or CONNECT which is weird. */
         return (pipe);
     }
     if (req.request != "GET" && req.request != "HEAD" && req.request != "POST" ) {
         /* We only deal with GET and HEAD by default */
         return (pass);
     }
   set req.grace = 30s;
    return(lookup);
}

sub vcl_fetch {
     if (beresp.ttl <= 0s ||
         beresp.http.Vary == "*") {
               return (hit_for_pass);
     }
 if(beresp.ttl > 0s){  unset beresp.http.Set-Cookie;}

  set beresp.grace = 1h;
  return(deliver);
}

En aquest exemple ja comença a ser més complert:
– limitat a 200 connexions, a més peticions, retornem 503.
– accepted petitions GET, HEAD, PUT, POST, TRACE, OPTIONS, DELETE.
– cachejem GET, POST, HEAD segons les capceleres HTTP que emet el backend
– en el moment en que anem a buscar un objecte en la cache, eliminem les capçeleres Set-Cookie
– tindrem 1 hora els elements en la cache, en cas que el backend estigui caigut o no respongui

Finalment, el ideal seria tenir ben segmentada la plana web amb les diferents seccions i tenir identificades les url’s de cadascuna d’elles facilitant així:
– La propia aplicació generi les capçeleres HTTP adecuades especificant quant de temps serà vàlid el contingut, segons quines seccións o accions tindrem uns temps de caducitat diferents
– La propia aplicació permite caducar/invalidar el contingut en el varnish en les situacions que ho necessitin.
– Securitzar les parts de la web que ho requereixin jugant amb les capçeleres


breu resum de la nostra història

la “Història de Catalunya” ha estat un breu, molt breu llibre que el meu avi em va recomenar llegir, un llibre d’escola de l’any 1933 que recopila molts dels més importants esdeveniments de la història de la nostra terra, Catalunya.

la foto

Degut a la meva mala memòria i aprofitant la gran sintesi realitzada en aquest llibre, m’he vist obligat de fer la seguent taula per tal de reordenar-me tots els esdeveniments, la qual cosa m’ha agradat.

Epoca Títol Capítol Resum d'Esdeveniment Personatges Importants Recursos literaris
- Caçadors i Artistes Celtes i Ibers viuen de la caça i primeres pintures rupestres - -
- Caçadors i Artistes Primers pagesos i comerciants - -
500 ac Els grecs a Catalunya Grecs s'assenten a Empuries (emporion és mercat en grec) - -
200 ac Indíbil i Mandoni Ibers lluiten contra els cartaginesos i romans sense èxit. Romans ens ensenyen arquitectura i el llatí. Sorgeix el primer ús del Català fruit de la mescla del llatí importat pels romans i les llengues autòctones. Indíbil i Mandoni -
100 ac La predicación del cristianismo Primers predicadors del cristianisme. La fe del poble guanyen als romans. Sant Pau Sant Feliu Sant Cugat -
600 dc La revolta de Paulus poble germanic (visigots) invaeix la peninsula destronant als romans. Toledo és la capital.Sorgeix una revolta del poble on Paulus es coronat rei de Narbona (prop del Roselló). Finalemnt els visigots destronen a Paulus Paulus Ranosind Hilderic -
800 dc Sarrains i Francs Els sarrains provinents del nord d'Africa i Àrabia s'apoderen de tota la peninsula (exceptuant els Pirineus). Els francs entren pels pirineus i arribaran a invair Girona i Vic. Arribaran a Barcelona on faran un setge i guanyaran a Zaid Lluís el Piadós (fill de Carlemany) i Zaid -
- Lluita contra els francs Guifré amb l'ajut de patriotes catalans van vencer al compte franc Salomó recuperant les terres.(Urgell Cerdanya Girona Besalú Barcelon) Salomó de Cerdanya i Guifré el Pilós Gesta Comitum Barchinonensium
- La légenda de les quatre barres Guifré ajuda a l'emperador frances Carles el Calb a lluitar contra els normands on cau ferit. Carles es qui pinta sobre l'escut de Guifré les 4 barres amb la sang del ferit. Neix la nostra bandera Guifré el Pilós Carles el Calb -
- Lluita amb els sarraïns Guifré consegueix guanyar territori als sarraïns posant-hi monestirs.(Ripolles-Plana de Vic-Monstserrat). Gruifre mor a Lleida lluitant contra els sarraïns i es enterrat a Ripoll Guifré el Pilós -
900 dc L'abat que amava els pelegrinatges L'abat Guarí va viatjar per moltes terres (França-Italia-Terra Sant). El duc Venecia Pere Urseol li obre el seucor de bat a bat. Duc Venecia emigra de Venecia amb Guari en silenci. Guarí abat de Sant Miquel de Cuixà – Pere Urseol (duc de Venecia) -
1000 dc L'abat que amava les ciències L'abat Oliva consegueix arreplegar al monestir de Ripoll els homes més savis Oliva abat de Ripoll -
- Catalunya i Provença S'uneixen els territoris de Provença i Catalunya amb el matrimoni del compte i Dolça. Després els francs dels "Anjou" ens arrebatarien Provença Ramon Berenguer i la princesa Dolça -
1100 dc Catalunya i Aragó El rei Ramir II d'Aragó va casar la seva filla Peronella amb el compte de Barcelona. Ramon va recuperar Lleida i Tortosa als sarrains. L'hereu va ser el fill de Ramon (Alfons el Cast). Ramon Berenguer IV – Peronella d'Arago – Ramir II – Alfons I el Cast -
1200 dc La batalla de Muret Alfons I conquereix Provença i el Llenguadoc. Pere el Catolic (fill d'Alfons I) es qui defendra les terres del llenguadoc(Tolosa-Foix-Comenge-Carcassona-Beziers) del compte franc Simo de Montfort qui amb un pretext religios en deien Croades. Pere mor en els camps de Muret(prop de Tolosa) Pere el Catolic-Simo de Montfort -
- La infantesa de Jaume I El fill del Pere es Jaume I. La mare de Jaume I mor a Roma al visitar el papa Innocent III(subdit de Simo de Montfort). El catalans reclamen a Jaume I al papa Innocent III qui el lliure i esdevingue rei amb 5 anys. Va creixer en el castell de Montço. Als 13 anys es casa amb Elionor de Castella. Els primers combats van ser contra nobles com Pere d'Ahonés. Jaume I Innocent III Elionor de Castella Pere d'ahonés Llibre dels fets
- La conquesta de Mallorca Jaume va conquerir Penyiscola i Terol als sarraïns. Als 20 va conquerir Mallorca Jaume I -
- El rei Jaume I i l'oreneta Jaume I cami de Valencia salva la vida a les orenetes que havien posat el niu a sobre la seva tenda. Aquest va ser un acte de grandesa i generositat en mig de camps de batalla Jaume I -
- El setge de València Jaume va interceptar els ajuts del rei de Tunis va enviar als sarrains de Valencia. Jaume fos ferit per un ballester sarrai. El casc li salva la vida. Jaume I -
- La conquesta de València Jaume I conquereix Valencia i besa la terra valenciana en acte simbolic. Neix el catala a les terres valencianes Jaume I -
- L'alliberació de Sicília Els sicilians patien els excessos dels soldats francs dels Anjou. Constança de Sicilia es casa amb el fill de Jaume I. Pere II allibera Sicilia dels francs. Pere II el Gran. Constança de Sicilia. Carles d'Anjou -
- El desafiament de Pere el Gran amb Carles d'Anjou Carles d'Anjou i Pere el Gran es desafien en un combat a Bordeus. Pere el Gran amb 4 caballers van a contrarellotge des de Navarra a Burdeos d'amagatotis. El senescal de Burdeos no pot garantir la seguretat a Pere. Un notari certifica la seva presencia Pere el Gran i Carles d'Anjou -
- Una resposta de Pere el Gran el papa Marti IV(amic de Carles d'Anjou) proclama una Croada com si Pere fos un rei moro(enemic del cristianisme). Pere els barra el pas en el Coll de Panissars. Despres de varies negociacions els deixen passar pero son vençuts vora els murs de Girona Pere el Gran. papa Marti IV. Ferran III rei de França -
1200 dc El gran Almirall Roger de Lluria va ser gran almirall que va vençer amb 12 galeres les 20 galeres franceses de Carles d'Anjou. Va fer presoner Carles de Salern(fill de Carles d'Anjou). Roger de Lluria(almirall de Pere el Gran) Llibre del consolat de la mar.
1300 dc Ramon Llull Home de ciencies. Promulgava als moros i jueus el cristianisme. Neix a Barcelona i recorres molts territoris. (Bolonya Paris Montpellier Genova Napols Xipre Rodes Malta Bugia Tunis..). Mort a Mallorca. Ramon Llull -
- Els Catalans a Orient Roger de Flor ers un gran capitost que un cop signada la pau de Sicilia amb els francs va anar a ajudar Constantinoble dels turcs. En deien els almogabers. Magnats grecs maten a traició els almogabers en un banquet. Les restes de la companyia van ferse forts a Gal·lípoli. La majoria de dones dels almogabers morts defenen la ciutat dels atacs genovesos amb Ramon Muntaner al capdavant aconseguint pararlos. Després aconsegueixen conquerir Atenes i Neopàtria. Roger de Flor. Ramon Muntaner Cronica de Ramon Muntaner
- La bandera Invencible Jaume II i despres el seu fill Alfons reinen a Serdenya. Avui encara tenim l'Alguer on es parla català Jaume II i el seu fill Alfons -
- La reina de Pedralbes Elisenda va viure en el monestir de Pedralbes on va repartir la seva riquesa i generositat amb els poble català Elisenda de Montcada(muller de Jaume II) -
- El nostre poble és lliure… El rei Alfons II es assessorat pels seus consellers i escolta al seu poble a diferencia de les corts castellanes Alfons el Benigne(fill de Jaume II) -
- Terra Beneïda Pere beneix les terres de Praga al tornar de Saragossa arribant a Catalunya Pere el Cerimoniós(fill de Alfons el Benigne) -
1300 dc L'amador de la gentilesa Va viure a Barcelona on va omplir la cort de gentilesa. Va voler omplir la cort de d'art. Joan I(fill de Pere el Cerimonios) -
1400 dc Coses glorioses son dites de tu Catalunya Martí va aplegar les Corts Catalanes a Perpinya. Va ajudar a molts pobles veins. Va morir a Sardenya. Marti el jove va ser el seu unic fill que va morir de petit. Martí l'Huma va ser el ultim descendent directe de Guifré el Pilos Marti l'Humà(fill de Joan I) -
- Jaume el dissortat La corona pertocava a Jaume d'Urgell. Tenia molts enemics. La corona havia de ser estriada per 9 compromisaris que van estriar un rei castellà Ferran d'Antequera en comptes de Jaume. Jaume va ser emmenat a Xàtiva. Jaume d'Urgell. Ferran d'Antequera -
- Fiveller Conseller Barceloni va discrepar la autoritat de Ferran defensant un impost pel poble català on Ferran va cedir. Sort vem tindre que Ferran va morir pel còlera a Igualada. Ferran d'Antequera. Joan Fiveller -
- La conquesta de Nàpols Alfons IV va conquerir Napols on s'hi va quedar per a viure a pesar que la seva dona el reclamés. Alfons IV(fill de Ferran) -
- El príncep de Viana Joan II es casa amb la reina Blanca de Navarra i tenen el seu fill Carles. Joan II es casa despres amb Joana Enriquez i te el seu segon fill Ferran despres de la mort de Blanca. Joan II demanar empressonar el seu fill Carles. El poble catala es rebela apojant a Carles i Joan recapassita. Carles torna a Barcelona com a princep de Viana on mort al poc temps. Joan II(fill de Alfons IV) -
1400 dc El gran descobridor a Barcelona Cristòfor Colom descobreix el nou món ajudat per galeres de la corona castella. Després del descobriment va a Barcelona a lliurar les terres a la corona. Alguns historiadors diuen que Cristòfor era català i no genovés. Cristòfor Colom. Ferran(fill de Joan II) -
1600 dc Pau Clarís Pau Clarís va ser qui va afrontar les lleis del rei castella Felip IV que volia pendre llibertats al poble catala. A mes dels excessos dels soldats de la corona d'Espanya feien sobre els catalans. Finalment els segadors catalans s'alçaren a les armes el dia de Corpus rebutjant la soldadescat i alliberant diputats i consellers. El compte d'Olivares va ser vençut en la batalla de Montjuic. Tot dirigit per canonge Pau Clarís. Pau Clarís -
1700 dc L'11 de setembre de 1714 Carles II mor sense descendencia. Felip V el borbo reclama el tro pero els catalans prefereixen l'arxiduc Carles d'Austria. Carles renuncia a les pretencions i abandona al poble català qui es defendra del castellans i francesos en el setge de Barcelona al 1714. Finalment en Rafael Casanova es vençut en el baluard de Santa Clara. Felip V suprimirà les llibertats catalnes. Felip V. Rafael Casanova. Ballester. Bach de Roda. Victus
1900 dc Catalunya Immortal Catalunya perd tots els icones de la seva identitat. Però més tart tot tornarà a nèixer no només a Catlunya sinò en totes les terres de parla catalana. Tindrem molts homes que contribuiran en aquest renaixement als diferents indrets de parla catalana. Mossent Jacint Verdaguer. Angel Guimerà. Joan Maragall. Mossèn Costa i Llobera. Joan Alcover. Teodor Llorente. Enric Prat de la Riba La nacionalitat catalana.

Finalment us deixo aquests enllaços interessants:

Com sempre, aquí teniu la viquipèdia que on podràs trobar més informació amb més detall.

Video Mapa Politic Europeu des del 1000ac fins ara.


openSSL, recopilem comandes i eines web per securitzar

Tots tart o d’hora ens trobem amb la necessitat d’haber de securitzar comunicacions, i moltes vegades no tens a má la comanda openssl per segons quins casos, és per això que m’he decidit per recopilar-les.

– Per crear petición de certificar (CSR) i clau no signada, demana info per command line:

openssl req -nodes -new -keyout cortinasval.key.pem -out cortinasval.csr.pem
openssl req -nodes -new -keyout cortinasval.key.pem -out cortinasval.csr.pem rsa:2048 

– Per crear petición de certificar (CSR) a partir de clau, demana info per command line:

openssl req -nodes -new -key cortinasval.key.pem -out cortinasval.csr.pem

– Mostra la clau fingerprint d’un clau:

openssl x509 -subject -dates -fingerprint -in cortinasval.key.pem

– Generem clau de 4096 bits

openssl genrsa -out cortinasval.key.pem 4096

– Mostrem informació d’una solicitud de firma (CSR)

openssl req -text -noout -in cortinasval.csr.pem

– Mostrem informació d’un certificat generat

openssl x509 -in cortinasval.crt.pem -noout -text

– Creant fitxers PEM per als servidors

cat cortinasval.key.pem cortinasval.crt.pem cortinasval.dhp.pem > cortinasval.pem

– Firmar e-mails

openssl smine -sign -in msg.txt -text -out msg.encrypted -signer cortinasval.crt.pem -inkey cortinasval.key.pem

– Crear fitxer PKCS12

openssl pkcs12 -export -in cortinasval.crt.pem -inkey cortinasval.key.pem -out fitxer.p12 -name "Marc Cortinas"

– Mostrar certificats utilitzats en la comunicació a un socket

openssl s_client -showcerts -connect marc.cortinasval.cat:443 -CApath /etc/pki/tls/certs

Si volem crear una entitat certificadora ens hem d’assegurar que existeixin els fitxers index.txt(buit) i el serial(posat a 01), a mes, crearem directoris private i network. Editem el fitxer openssl.cnf i configurem default_days_certificate i private_key, finalment posem la cantitat de bits que utilitzarem per a la key (1024..2048)

– Per crear certificat CA

openssl req -new -x509 -days 3650 -keyout private/cortinasval-CA.key.pem -out ./cortinasval-CA.crt.pem 

– Exportar el certificat CA al format DER

openssl x509 -in cortinasval-CA.crt.pem -outform der -out cortinasval-CA.crt

– Revokem un certificat

openssl ca -revoke cortinasval.crt.pem

– Generem la llista de Revocacio de certificats

openssl ca -gencrl -out crl/cortinaslval-CA.crl

– Firmem la petició de certificat (CSR)

openssl ca -out cortinasval.crt.pem -in cortinaslval.req.pem

– Creem el parametre Diffie-Hoffman per l’actual CA

openssl dhparam -out cortinasval-CA.dhp.pem 1536

– Creem certificat auto-signat a partir d’una clau

openssl req -new -x509 -key cortinasval.key.pem -out cortinasval.crt.pem

– Encriptar un fitxer sencill

openssl enc -bf -A -in fitxer_de_test.txt

– Desencriptar un fitxer sencill

openssl enc -bf -d -A -in fitxer_de_test.txt

– Calcul de claus sha1

 openssl speed sha1

Pels servidors Webs que volguem fer ús del httpS, cada proveidor d’entitats certificadores te el seu manual, deixo aquí els 2 que he hagut d’instalar:
Thawte
Startssl

Eines utils per obtener información del nivel de seguretat:
Thhwte tool
SSL Labs

Quins conceptes hem de tenir clar?
– Tamany de Bits utilitzats a l’hora de crear el fitxers .pem
– SAN, noms de dominos acceptats pels certifictats, poden ser N noms, i tambe portar wildcard.


Balancejador HTTP/S econòmic: Nginx+Haproxy+Pacemaker

Seguidament us explicaré com es pot montar un balancejador httpS molt econòmic i molt eficient, el qual s’ha implementat tan en entorns productius com no productius, la motivació inicial del qual va ser centralitzar el balanceig dels diferents entorns d’integració continua d’una aplicació web. En entorns productius també l’he implementat després de fer varies probes de rendiment amb el “ab” i el “siege” .

L’únic requeriment que hem d’asumir és allotjar tot tràfic dels diferents entorns en subdominis d’un domini (p.e.example.com), on podem tenir int01.example.com, int02.example.com, test01.example.com, test02.example.com, pre.example.com, etc..

Anàlogament, en els entorns de producció, podem fer la mateixa discriminació diferenciant el tràfic pels paisos(es.example.com,fr.example.com), plataformes(m.example.com), tipus de contingut(static.example.com).

Els objectius que em vaig marcar van ser:

  • Baix cost econòmic: utilitzarem programari de codi obert des dels operatius fins als dimonis: CentOS, Nginx, Haproxy, Pacemaker, Corosync.
  • Alta disponibilitat de maquinari i programari: a nivell de maquinari ho montarem en una infraestructura virtualitzada amb varis nodes físics i implemtarem el pacemaker+corosync per a tenir alta disponibilitat en els dimonis.
  • Centralitzar la negociació SSL de tota la plataforma en un punt inicial i alliberar càrrega SSL del reste de la plataforma.
  • Permetre més flexibilitat i control en els balancejos de cadascún dels entorns: haproxy permet fa possible controlar en un pool de balanceig si un frontal hi està activat segons el seu nivell de càrrega o si te connexió contra la base de dades, per exemple.
  • Tenir una plataforma securitzada, requeriment essencial sobretot en entorns productius.
  • Els dimonis que utilitzarem serà Nginx, Haproxy, Pacemaker i Corosync, tot programari lliure on abarata el cost considerablement.

    En el següent esquema es veu clarament l’arquitectura de tot el montatge.

    fisicalLB

    El comento breument, no entraré en detall en tot, em centro en lo important d’aquest post. Els navegadors dels usuaris fan les peticions a les empreses que fan de CDN, després aquestes peticions van a parar en la nostra plataforma on filtrarem el tràfic amb un firewall. Un cop les peticions són filtrades van a parar un nginx. La finalitat del nginx es discriminar el tràfic segons el entorn i centralitzar totes les negociacions SSL del tràfic HTTPS. Seguidament, les peticions passen a un haproxy on aquest balanceja entre els diferents frontals de cadascun dels entorns.

    Per tal de securitzar-ho tot, definirem 3 VLAN’s, dmz, frontend i backend. Tot el tràfic és filtrat pel firewall, el tràfic sortint, el entrant i el tràfic entre zones. En la DMZ posarem 2 maquines virtuals CentOs on tindrem els serveis de Nginx i Haproxy en actiu-passiu utlitzant pacemaker-corosync. En el frontend tenim els frontals de cadascun dels entorns i en el backend tenim les dades, mysql, cassandras, mongos, nfs, cifs, etc….

    Per exemplificar-ho millor, ens centrarem només en un entorn, int01.example.com.

    Primerament en la DMZ montarem una 2 màquines virtuals on hi tindrem 2 ip flotants, una per el nginx i l’altre pel haproxy. Jo ho he implemetat en una infraestructura virtualitzada vmware però també es poden montar solucions més econòmiques com XenServer, KVM, etc… Evidentment, sigui quina sigui la solució de virtualització, hem d’assegurar-nos que les màquines virtuales sempre estàn corrent en màquines físiques diferents.

    Les peticions entraran en la ip flotant del nginx, el nginx té dues funcions, centralitzar la negociació SSL i discriminar el tràfic per entorns. En el tràfic HTTPS afegirem una capçalera HTTP “X-forwarded-proto: https”, on l’apache la recollirà i activarà la variable HTTPS emmascarant-li a la aplicació. El tipus de certificat que afegirem en el nginx serà un certificat signat per una entitat certificadora oficial on el Common-Name que utilitzarem serà de tipus wildcard, es a dir, per aquest exemple, “*.example.com”, això ens facilitza molt la gestió del certificats i ens dona molta facilitat de gestió. En entorns de producció ho dimensionem assignant els valors correctes de worker_processes i worker_connections tenint en compte la formula: max clients = worker_processes * worker_connections/4.

    Seguidament les peticions passen al haproxy on aquest balanceja entre els diferents frontals de cadascun del entorn. El haproxy ens permet estriar l’algorisme de balanceig, jo acostumo a utilitzar Round Robin. A més, podem prefixar els rangs de IPs dels frontals que hi hauran en cadascun dels entorns, així podem desplegar més frontals en el cas que sigui necessari sense haber de reinicilitzar el dimoni.
    Haproxy fara una petició a un php que hi ha en cadascun dels frontals on retorna un “OK” si no està swapejant, no té molta càrrega i té conectivitat en les bases de dades. Cal remarcar que haproxy també ens permet realitzar balancejos “sticky” tan en aplicacions JAVA com PHP, depenentment d’una capçalara HTTP, habitualment les capçaleres JSESSIONID i PHPSESSID respectivament. (en apps ASP teniem ASPSESSIONID). En entorns de producció fixarem la variable maxconn tenim en compte que cada petició consumeix 17kb.

    Finalment les peticions arriben als frontals on primerament passen pel varnish i les peticions que no siguin cachejables arribaran finalment al apache, crec que aquests dos dimonis es mereixen un post especial per ells dos, que ja tinc en el backlog del blog.

    En el següent diagrama clarifica tota l’arquitectura:

    Diagrama Lògic

    Diagrama Lògic

    Seguidament posaré les configuracions més importants, Nginx, Haproxy, Pacemaker:

    Parametres del Nginx

    ....
    upstream http-example-int01 {
        server lb2-vip.example.com:8080;
        keepalive 16;
    }
    server {
            listen lb1-vip.example.com:80;
        server_name int01.example.com ~^.*-int01\.example\.com$;
    
            location / {
                    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                    proxy_set_header Host $host;
                    proxy_pass http://http-example-int01/;
                    proxy_redirect off;
            }
    }
    server {
            listen lb1-vip.example.com:443 ssl;
        server_name int01.example.com ~^.*-int01\.example\.com$;
    
            ssl on;
            ssl_certificate /etc/nginx/ssl/crt/concat.pem;
            ssl_certificate_key /etc/nginx/ssl/key/example.key;
    
            location / {
                    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                    proxy_set_header X-Forwarded-Proto https;
                    proxy_set_header Host $host;
                    proxy_pass http://http-example-int01/;
                    proxy_redirect off;
            }
    }
    ....
    

    Parametres del Haproxy

    ...
    frontend example-int01 lb2-vip.grpprod.com:8080
        default_backend example-int01
    backend  example-int01
            option forwardfor
            option httpchk GET /healthcheck.php
            http-check expect string OK
            server  web01 x.y.z.w:80 check inter 2000 fall 3
            server  web02 x.y.z.w:80 check inter 2000 fall 3
            server  web03 x.y.z.w:80 check inter 2000 fall 3
            server  web04 x.y.z.w:80 check inter 2000 fall 3
            server  web05 x.y.z.w:80 check inter 2000 fall 3
    ...
    

    Parametres del Apache

    
     ServerName int01.example.com
        DocumentRoot "/srv/www/example/fa-front/public"
    
       <Directory "/srv/www/example/fa-front/public">
          Options -Indexes FollowSymLinks
          AllowOverride None
          Allow from All
          Order Allow,Deny
          RewriteEngine On
          RewriteCond %{HTTP:X-Forwarded-Proto} https
          RewriteRule .* - [E=HTTPS:on]
    
          RewriteCond %{REQUEST_FILENAME} -s [OR]
          RewriteCond %{REQUEST_FILENAME} -l [OR]
          RewriteCond %{REQUEST_FILENAME} -d
          RewriteRule ^.*$ - [NC,L]
          RewriteRule ^.*$ index.php [NC,L]
    
       SetEnv APPLICATION_ENV int01
       DirectoryIndex index.php
    
       LogFormat "%v %{Host}i %h %l %u %t \"%r\" %>s %b %{User-agent}i" marc.int01
       CustomLog /var/log/httpd/cloud-example-front.log example
    
    

    Parametres del Pacemaker

    node balance01
    node balance02
    primitive nginx lsb:nginx \
            op monitor interval="1s" \
            meta target-role="Started
    primitive haproxy lsb:haproxy \
            op monitor interval="1s" \
            meta target-role="Started"
    primitive lb1-vip ocf:heartbeat:IPaddr2 \
            params ip="x.x.x.x" iflabel="nginx-vip" cidr_netmask="32" \
            op monitor interval="1s"
    primitive lb2-vip ocf:heartbeat:IPaddr2 \
            params ip="y.y.y.y" iflabel="haproxy-vip" cidr_netmask="32" \
            op monitor interval="1s"
    group haproxy_cluster lb2-vip haproxy \
            meta target-role="Started"
    group nginx_cluster lb1-vip  nginx \
            meta target-role="Started"
    property $id="cib-bootstrap-options" \
            dc-version="1.1.7-6.el6-148fccfd5985c5590cc601123c6c16e966b85d14" \
            cluster-infrastructure="openais" \
            expected-quorum-votes="2" \
            stonith-enabled="false" \
            last-lrm-refresh="1355137974" \
            no-quorum-policy="ignore"
    rsc_defaults $id="rsc-options" \
            resource-stickiness="100"
    

    Tmux ha guanyat!

    Parlem de terminals de consola! Parlem de TMUX!!!
    Fa ja uns mesos que estem treballant en el departament amb aquest multiplexor de terminals i estem tant contents amb ell que s’ha guanyat un post!

    Encara recordo amb nostàlgia quant vem descobrir l’screen, eina que vem explotar en els servidors per

  • llençar processos que sabem que tenen una llarga durada, aqui tenim d’aliats el “&>>” i el time ( /usr/bin/time –format=”%E %S %U %P” –output=”logfile”)
  • llençar processos crítics on volem minimitzar els riscos de deixar-ho a mitges per algun tall de llum en el nostre laptop
  • llençar processos de forma desatesa que volem que es comportin com un dimoni, util quan et demanen llençar script com si fos un dimoni a mode urgent.
  • llençar processos on puguin fer seguiment als companys, útil per el processos que duran varis torns d’operadors
  • però com va dir un colega, l’screen està “depre” ( de deprecated! està passat de moda! ), amb tota la raó del món! ja veureu…

    D’una altra banda, Terminator(Linux) i iTerm(Mac) han estat les consoles utilitzades per realitzar varies tasques a la vegades en diferents servidors, per fer desplegaments de codi, canvis de configuracions, apagar focs, etc… Mitjançant les pestanyes pots tindre varies consoles connectades a diferents entorns o grups de servidors diferents, a més, cadascuna de les pestanyes les pots dividir en panells i executar les mateixes commandes o scripts alhora, MOLT útil!!!

    Doncs si aquestes funcionalitats del iTerm/Terminator ens han estat MOLT útils, imagineu-vos combinat amb el screen, i n’obtenim el TMUX!!. Ja fa uns quants caps de setmana que vaig passar una tarda per apendre les opcions i preparant-me la configuració a mida, i va ser MOLT productiu, ho recomano a qualsevol sysadmin. Haig de reconèixer que al principi vaig tenir una mica de reticiència però ara ho agraeixo.

    Descric el que més valoro:

  • tenim pestanyes per agrupar per roles/entorns els servidor on estic connectat
  • cadascuna de les pestanyes les podem dividir en panells
  • podem enviar comandes a tots els panells alhora d’una mateixa pestanya
  • podem redimensionar els panells fàcilment
  • podem desplaçar-nos pels diferents panells i/o pestanyes amb comoditat
  • NO necessitem de les X11, impresionant!
  • pots definir el buffer de cadascun del panell, recomano perdre uns moments per definir un gran buffer, sempre ho acabem utilitzant en algun moment
  • podem fer ús de plantilles, definint les pestanyes i les mides que obrirem i inclus automatitzar-ho
  • podem personalitzar quins són la combinació de tecles utilitzades per a fer ús del tmux
  • Adjunto el meu perfil del tmux en aquest post, on recalcaré les que trobo més interessants.
    Fitxer per descarregar: tmux.conf
    Path: $HOME/.tmux.conf

    # Avisa on fa perpellugues el nom de la pestanya on algun dels seus panells ha tingut activitat
    set -g visual-activity on
    # Per a cada panell guardem 10000 linies de buffer
    set -g buffer-limit 10000
    # C^B+r per recarregar en el tmux canvis en aquestes configuracion (aixo per nota!)
    unbind r
    bind r source-file ~/.tmux.conf  \; display "Reloaded!"
    #C^B+a :(All) per escriure en tots els panells de la pestanya
    unbind a
    bind a setw synchronize-panes on
    # C^B+o :(One) per escriure nomes en panell seleccionat
    unbind o
    bind o setw synchronize-panes off
    # Els indexos de panells i pestanyes comencen per 1, en comptes de 0 que és el per defecte
    set -g base-index 1
    setw -g pane-base-index 1
    # Personalitzant la barra d'estat
    # Powerline symbols: ⮂ ⮃ ⮀ ⮁ ⭤
    set -g status-utf8 on
    set -g status-left-length 32
    set -g status-right-length 150
    set -g status-interval 2
    
    set -g status-left '#[fg=colour15,bg=colour238,bold] #S #[fg=colour238,bg=colour234,nobold]⮀'
    set -g status-right '#[fg=colour245]⮃ %R ⮃ %d %b #[fg=colour254,bg=colour234,nobold]⮂#[fg=colour16,bg=colour254,bold] #h '
    set -g window-status-format "#[fg=white,bg=colour234] #I #W "
    set -g window-status-current-format "#[fg=colour234,bg=colour39]⮀#[fg=colour16,bg=colour39,noreverse,bold] #I ⮁ #W #F #[fg=colour39,bg=colour234,nobold]⮀"
    

    Aqui defineixo una plantilla del tmux per facilitar l’ús, molt útil a l’hora d’apagar focs.
    tmux_magento.sh
    El seguent gif mostra la execució de la plantilla que us he penjat, on hem connecto a tots els frontals d’un mateix role(magento), 8 frontals. La plantilla no deixa de ser un shell script on cada linia mofica el tmux on estem. De fet, per fer-lo funcionar, ÉS NECESSARI estar dins una pestanya del tmux i tenir els indexos dels panells configurats a 1, en comptes de 0 com té per defecte el tmux.

    tmux_magento

    Com podeu veure en el gif anterior, jo estic acostumat a connectar-me des d’un tmux a moltes consoles tty de varis servidors per SSH2. Un altre forme de treballar seria connectar-me a instancies de tmux en cadascun dels servidors a través d’un fitxer socket, en comptes de connectar-me a la consola, ideal per a compartir sessions remotes alhora entre varis operadors.

    Per finalitzar, les fonts consultades:
    Zooming Tmux Panes
    Simple Remote Pairing with Wemux
    Splitting terminal with tmux
    Manual del Tmux

    Projects Links:
    Tmux Project
    Wemux Project


    WordPress en Raspberry Pi

    Primer post del blog!! Tot just acabo de instalar el wordpress i vaig a recopilar tots els pasos.
    En la RaspberryPi he instalat com a operatiu un debian amb els daemons nginx, php-fpm i mysql per a fer correr el wordpress. Enumero els pasos:

      • Instalo berryboot en la targeta SD, on instalo el debian en la raspberry, aqui més info
      • Faig un “apt-get update” per actualitzar les fonts dels repositoris i instalo el meu editor preferit.
      • Instalo tots els dimonis:
    $sudo apt-get install nginx php5-fpm php5-cgi php5-cli php5-common php5-curl php5-gd php5-mcrypt php5-mysql mysql-server
    
    • Configuro el php-fpm amb el nginx, per utilizarem un file unix per comunicar la interpretació del  php amb el nginx que el servirà, en conclusió, definirem el virtualhost de nginx i settejarem una variable del php

    File: /etc/nginx/sites-available/marc.cortinasval.cat

    server {
            listen   80; ## listen for ipv4; this line is default and implied
            root /usr/share/nginx/www;
            index index.php;
            server_name marc.cortinasval.cat;
            location / {
                    rewrite  ^/?$  /blog/  redirect;
                    try_files $uri $uri/ /index.php;
            }
            location /blog/ {
                    try_files $uri $uri/ /blog/index.php?$args;
            }
            location ~ \.php$ {
                    fastcgi_split_path_info ^(.+\.php)(/.+)$;
                    fastcgi_pass unix:/var/run/php5-fpm.sock;
                    fastcgi_index index.php;
                    include fastcgi_params;
            }
            location = /favicon.ico {
                    log_not_found off;
                    access_log off;
            }
            location = /robots.txt {
                    allow all;
                    log_not_found off;
                    access_log off;
            }
            location ~ /\.ht {
                    deny all;
            }
            location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
                    expires max;
                    log_not_found off;
            }
    }
    

    Ens asegurem que el socket unix definit en el fastcgi_pass del nginx correspon al del php-fpm

    $ grep listen /etc/php5/fpm/pool.d/www.conf
    listen = /var/run/php5-fpm.sock
    

    Finalment canviarem el parametre del cgi.fix_pathinfo a 0 en el file /etc/php5/fpm/php.ini

    $grep cgi.fix_pathinfo /etc/php5/fpm/php.ini
    cgi.fix_pathinfo=0
    
    • Instalo wordpress, per una banda els fitxers php de blog i per una altra preparem la base de dades de mysql que utilitzara i configurem la cadena de conexió de la aplicació.

    Baixem la aplicacio i la posem on toca

    $ cd /usr/share/nginx/www/
    $ wget http://wordpress.org/latest.zip
    $ unzip latest.zip
    $ mv wordpress blog
    $ rm latest.zip
    

    Preparem la base de dades en mysql, des del client del mysql

    mysql> CREATE DATABASE wordpress;
    Query OK, 1 row affected (6.58 sec)
    mysql> GRANT ALL PRIVILEGES ON wordpress.* TO "wordpress"@"localhost"IDENTIFIED BY "wordpress";
    Query OK, 0 rows affected (0.01 sec)
    mysql> flush privileges;
    Query OK, 0 rows affected (0.02 sec)
    mysql> exit;
    Bye
    

    Configurem la cadena de conexio de la aplicació

    cp wp-config-sample.php wp-config.php
    vim wp-config.php
    [\sourcecode]
    
    File /usr/share/nginx/www/blog/wp-config.php
    
    
    /** The name of the database for WordPress */
    define('DB_NAME', 'wordpress');
    /** MySQL database username */
    define('DB_USER', 'wordpress');
    /** MySQL database password */
    define('DB_PASSWORD', 'wordpress');
    /** MySQL hostname */
    define('DB_HOST', 'localhost');
    

    Corregim permisos i reiniciem dimonis

    $sudo chown -R www-data.www-data /usr/share/nginx/www/
    $sudo service nginx restart 
    $sudo service php5-fpm restart
    

    Accedem via web on configurarem el nom del blog i el nom i password del usuari que administrarà el blog, en aquest pas serà quant es crearà la estructura de dades en el mysql.

    Configuro el permanent link del wordpress, aixo serveix per a tenir url’s més amistoses, com per exemple:  http://marc.cortinasval.cat/blog/index.php/2013/03/wordpress-en-raspberry-pi
    Per aconseguir-ho, primer ens asegurem que tenim les seguents linies en el virtualhost de nginx i després anem a settings–>permalinks i configurem el format.
    File: /etc/nginx/sites-available/marc.cortinasval.cat

    ...
            location /blog/ {
                    try_files $uri $uri/ /blog/index.php?$args;
            }
    ...
    
    • Afegeixo i configuro els pluguins de wordpress, llisto aquí els que més m’han molat:

    SyntaxHighlighter Evolved
    WP to Twitter
    NextScripts: Social Networks Auto-Poster
    Author Spotlight (Widget)
    ExtraWatch Live Stats and Visitor Counter FREE
    Google Analytics
    Google Analytics for WordPress
    Social Login for wordpress
    User Photo

    • Poso un minim de categories i creo un menu amb aquestes categories
    • Finalment em baixo un thema i poso el menu en el tema
    • Poso el witget de delicious

    Escric aquest primer post i ja tinc el blog preparat per a recopilar més info!!!!


    Afinem RHEL/CentOs per a l’NGINX+HAPROXY en entorns de producció

    Per una banda, l’Nginx es un servidor WEB molt lleuger capaç de gestionar gran quantitat de connexions concurrents amb una eficaç gestió dels recursos, jo l’he utilitzat com a servidor proxy on he balancejat el tràfic de diferents aplicacions, tan en entorns productius com en entorns de desenvolupament.

    D’una altra banda utilitzarem el HAPROXY com a balancejador, ja que és un dels programaris més potents, lleugers i flexibles a l’hora de balancejar tràfic, poden implementar-ho com a balancejador HTTP o TCP, en el meu cas, HTTP amb balanceig enganxós. Per a aquest dimoni només he hagut d’afinar valors com tune.bufsize i tune.maxrewrite

    En un entorn productiu cal afinar la plataforma per a tindre’ls preparats per a que ens permeti un bon rendiment, l’objectiu del post es tenir ben recopilada tota la informació que he utilitzat. Per la xarxa hi han molta documentació sobre aquest propòsit, aquí únicament els recopilarem per a tenir-ho ben recol·lectat, al final del post hi llisto les fonts.

    CentOs/RHEL es la plataforma on ho he muntat, on el nginx únicament fa la funció de “reverse proxy” de diferents sites, descartant les funcionalitats de balanceig i de cache, on les he implementat amb HAProxy i Varnish-cache que ja he explicat en un altre post, aquí amb vull centrar en afinar-ho i llistar els petits problemes que m’he trobat/corregit.

    Per tal d’afinar-ho, segmentem 3 configuracions diferents:

    • Paràmetres del nucli del sistema operatiu
    • Límits del sistema Operatiu
    • Configuració del nginx

    Paràmetres del nucli del sistema operatiu

    Valor per defecte i aplicat:

    sysctl -w net.ipv4.tcp_congestion_control = cubic
    

    Algorisme de gestió dels trafic TCP, en el paràmetre net.ipv4.tcp_available_congestion_control podem saber quines opcions tenim carregades en el kernel de linux
    En CentOs6 tenim aquestes opcions: cubic reno, en el següent enllaç ho explica
    http://kaivanov.blogspot.com.es/2010/09/linux-tcp-tuning.html

    • reno: Traditional TCP used by almost all other OSes. (default)
    • cubic: CUBIC-TCP (NOTE: There is a cubic bug in the Linux 2.6.18 kernel used by Redhat Enterprise Linux 5.3 and Scientific Linux 5.3. Use 2.6.18.2 or higher!)
    • bic: BIC-TCP
    • htcp: Hamilton TCP
    • vegas: TCP Vegas
    • westwood: optimized for lossy networks

    Valor per defecte i aplicat:

    sysctl -w net.ipv4.tcp_window_scaling = 1
    

    Auto-escalat de la mida de la finestra de recepció TCP utilitzat, la finestra més gran pot ocupar 65,535 bytes. 1 ho activem i 0 ho desactivem.

    Valor per defecte:

    sysctl -w net.ipv4.ip_local_port_range="32768 61000"
    

    Valor per aplicat:

    sysctl -w net.ipv4.ip_local_port_range="2000 65000"
    

    Defineix el conjunt de ports locals que fa servir el SO per connexions les connexions TCP i UDP

    Valor per defecte:

    sysctl -w net.ipv4.tcp_max_syn_backlog="2048"
    

    Valor per aplicat:

    sysctl -w net.ipv4.tcp_max_syn_backlog="204800"
    

    Numero màxim de peticions per les connexions rebudes que encara no ha rebut el ACK del emissor, per defecte és 1024 i en sistemes de menys de 128Mb li assignem 128. Si el servidor pateix sobrecàrrega intenta incrementar aquest valor.

    Valor per defecte:

    sysctl -w net.core.somaxconn="128""
    

    Valor per aplicat:

    sysctl -w net.core.somaxconn="12800"
    

    Numero màxim de connexions que estan passant de LISTEN a ESTABLISHED, si es supera aquest número de connexions establertes el sistema les rebutja.

    Valor per defecte:

    sysctl -w net.ipv4.tcp_max_tw_buckets="262144"
    

    Valor per aplicat:

    sysctl -w net.ipv4.tcp_max_tw_buckets="524284"
    

    Numero màxim de connexions en estat TIME_WAIT, quant el superem, el sistema elimina els sockets i envia un avís. Aquest limit només s’utilitza per AVISAR de atacs DDOS. Aquest valor no s’acostuma a baixar sinó a incrementar proporcionalment amb la memòria, si les condicions de xarxa aixi ho requereixen.

    Valor per defecte:

    sysctl -w net.core.rmem_default="229376"
    

    Valor per aplicat:

    sysctl -w net.core.rmem_default="262142"
    

    Mida de la memòria asignada per defecte en la recepció pels socket

    Valor per defecte:

    sysctl -w net.core.rmem_max="131071"
    

    Valor per aplicat:

    sysctl -w net.core.rmem_max="524284"
    

    Mida màxima de memòria assignada per defecte en la recepció pels socket, aquest valor ha de ser superior al net.core.rmem_default
    Alerta! En RHEL compleix aquesta ultima recomanació però en CentOS6 no ho segueix

    Valor per defecte:

    sysctl -w net.core.wmem_default="229376"
    

    Valor per aplicat:

    sysctl -w net.core.wmem_default="262142
    

    Mida de memòria asignada per defecte en l’enviament pels socket

    Valor per defecte:

    sysctl -w net.core.wmem_max="131071"
    

    Valor per aplicat:

    sysctl -w net.core.wmem_max="524284"
    

    Mida màxima de memòria assignada per defecte en la emissió pels socket, aquest valor ha de ser superior al net.core.rmem_default
    Alerta! En RHEL compleix aquesta ultima recomanació però en CentOS6 no ho segueix

    Valor per defecte i aplicat:

    sysctl -w net.ipv4.tcp_rmem="4096 87380 4194304"
    

    Paràmetres de auto configuració TCP en la recepció de dades: El primer valor es la mida mínima de memòria utilitzat per a cada connexió TCP. El segon valor especifica la mida PER DEFECTE de buffer en la recepció per a cadascun dels socket. Aquest valor sobreescriu el /proc/sys/net/core/rmem_default utilitzat en altres protocols(!=TCP). El tercer i ultim valor especifica la mida màxima de memòria per la recepció de dades per a cadascun de les connexions TCP.

    Valor per defecte i aplicat:

    sysctl -w net.ipv4.tcp_wmem="4096 65536 4194304"
    

    Parametres de auto configuració TCP en la emissió: Aquests tres valors indiquen quin es l’espai de memòria assignat a cada socket en l’enviament de dades. El primer es la mida mínima, el segon la mida per defecte i el tercer la mida màxim del buffer reservat per a l’enviament de dades.

    Valor per defecte:

    sysctl -w net.ipv4.tcp_mem="753888 1005184 1507776"
    

    Valor per aplicat:

    sysctl -w net.ipv4.tcp_mem="753888 1005184 4194304"
    

    Paràmetres de auto configuració TCP: Defineix com el sistema operatiu gestion l’ús de la memòria per a les connexions TCP. El primer valor especifica el umbral mínim. Per sota d’aquest valor el SO no va cap canvi de gestió de la memòria pels diferents socket TCP. El segons valor indica la mida per defecte permès per a 1a connexió TCP, el tercer valor ens indica la mida màxima de memòria utilitzat per les connexions TCP, si el SO consumeix més memòria per a les connexions TCP comença a fer DROPS de les noves connexions.

    Valor per defecte i aplicat:

    sysctl -w fs.file-max="793779"
    

    Defineix el número màxim de descriptors de fitxers que gestiona el SO (Recordem que tant els sockets com els fitxers son descriptors de fitxers en entorns Linux/Unix)

    Valor per defecte:

    sysctl -w net.ipv4.tcp_tw_reuse="0"
    

    Valor per aplicat:

    sysctl -w net.ipv4.tcp_tw_reuse="1"
    

    Permetre reutilitzar els sockets que estan en TIME_WAIT quant es segur des del punt de vista del protocol. Non hauria de ser modificat sense la supervisió d’un expert 😉

    Valor per defecte:

    sysctl -w net.ipv4.tcp_tw_recycle="0"
    

    Valor per aplicat:

    sysctl -w net.ipv4.tcp_tw_recycle="1"
    

    Permetre la rapida reutilització de sockets en TIME_WAIT. Activant aquesta opcio no es recomenada si estas fent NAT. En canvi amb el HAPROXY es molt recomenable per baixar CONSIDERABLEMENT el numero de connexions en TIME_WAIT. Adjunto una captura de graphite on podem veure el canvi només aplicant aquesta variable.
    haproxy

    Valor per defecte:

    sysctl -w net.ipv4.tcp_max_orphans="262144"
    

    Valor per aplicat:

    sysctl -w net.ipv4.tcp_max_orphans="30000"
    

    Número màxim de TCP sockets orfans que no estan connectats a cap proces. Quant aquest numero s’excedeix, les connexions orfanes es resetejant i es notifica amb una alerta. Aquest limit existeix nomes per prevenir atacs de denegament de servei. Decrementar aquest valor no es aconsellable. Les condicions de xarxa poden requerir que incrementis el numero de orfans permesos, cadascun dels orfans poden ocupar aproximadament 64k de memoria NO-SWAPEJABLE. El valor per defecte es igual que el parametre NR_FILE del kernel, en 262144 en RHEL6/CentOS6, ajustat a la memoria del sistema.

    Valor per defecte:

    sysctl -w net.ipv4.tcp_synack_retries="5"
    

    Valor per aplicat:

    sysctl -w net.ipv4.tcp_synack_retries="3"
    

    Número màxim de vegades que un segment SYN/ACK per a una connexio TCP passiva sera retransmitit. Aquest numero no pot excedir de 255.

    Límits del sistema Operatiu
    Amb concordança amb el últim paràmetre explicat en l’apartat anterior, hem de ampliar el numero de descriptors de fitxers que permetem realitzar al usuari que instancia el nginx, afegint les línies següents al fitxer /etc/security/limits.conf

    nginx       soft    nofile   10000
    nginx       hard    nofile   30000
    

    Configuració del nginx
    No menys important que les configuracions de sistema són la configuració del nginx.

    Primerament cal dimensionar la memòria i la CPU del sistema. Cal dimensionar assignant els valors correctes de worker_processes i worker_connections tenint en compte la formula: max clients = worker_processes * worker_connections/4. En el meu cas tenim més de 1200 connexions concurrents on tinc una maquina amb 8 vCPUs i 8GB de RAM, on he assignat:

    worker_processes  8;
    events {
        worker_connections  1024;
    }
    

    Seguidament segons el tipus d’aplicacions que estiguem balancejant amb l’nginx, tenint en compte el número i el tipus d’aplicacions, les connexions concurrents que requereixen, la mida tant de les capçaleres com del cos, tant de les peticions com de les respostes, caldrà afinar els següents paràmetres.

    ## Size Limits
      client_body_buffer_size     128K;
      client_header_buffer_size   8k;
      client_max_body_size          1M;
      large_client_header_buffers 8 32k;
    ## Timeouts
      client_body_timeout   60;
      client_header_timeout 60;
      expires               24h;
      keepalive_timeout     60 60;
      send_timeout          60;
      proxy_connect_timeout 60s; 
      proxy_read_timeout 120s;
      proxy_send_timeout 120s
    ## TCP options
      tcp_nodelay on;
      tcp_nopush  on;
    ## Proxy options
      proxy_buffering           on;
      proxy_buffers 16 16k;
      proxy_buffer_size 32k;
    ##Fix header too big http://forum.nginx.org/read.php?2,188352
      fastcgi_buffers 16 16k;
      fastcgi_buffer_size 32k;
    

    Aquests paràmetres els utilitzo per a publicar aplicacions PHP i contingut estàtic on es connecten tot tipus de navegadors tan estacions de treball, ordinadors portàtils, dispositius mòbils com tabletes des de diferents proveïdors ADSL, 2G, 3G, 4G, WiMax, FTH, etc…. Remarco que no utilitzo la funció de cache del nginx.
    Seguidament faig esmena de 2 problemes que m’he trobat amb les nostres aplicacions.

    Per part del Nginx, si volem augmentar les mides de la capçalera que reben del frontal a més de 16kb, també s’ha de parametritzar el parametres fastcgi_buffers i fastcgi_buffer_size tal com ho reporten en el foro aquest link, no li vaig trobar logica però va ser aplicar-ho i desapareixer.

    Per part del Haproxy també hi han limitacions del tamany del buffsize, en Centos/RHEL els paquets compilats del repositori yum estan tots a 16kb, en el foro de HAPROXY trobem com recompilar-ho
    Molt útil per corregir aquest tipus de errors:

    echo show errors | socat stdio unix-connect:<path-to-socket>
    

    Les principals fonts que he seguit són:

    http://linux.die.net/man/7/tcp
    http://dak1n1.com/blog/12-nginx-performance-tuning
    http://www.cyberciti.biz/faq/rhel-linux-install-nginx-as-reverse-proxy-load-balancer/
    http://www.cyberciti.biz/faq/linux-unix-nginx-too-many-open-files
    http://www.exceliance.fr/sites/default/files/biblio/art-2006-making_applications_scalable_with_lb.pdf
    http://comments.gmane.org/gmane.comp.web.haproxy/11145