• Oktober, vår nya plattform och 44 miljoner pageviews

    Our web servers delivered 44 million page views in October - at most 2.5 million in a day. In addition CloudFront delivered around 800 million requests resulting in 17 TB of data. The system managed to handle 800 incoming orders in one hour.

    Texten ovan summerar oktober ganska bra.

  • Husköp & annat

    Har vart ganska dött här ett bra tag. Anledningen är att jag & min fru köpte ett hus i våras sen har sommaren gått åt åt renoveringar & bröllopsplanering. Får bättra mig nu, snart är det spännande tider: Oktober!

  • UniFi® Security Gateway Pro rebootar och är seg

    Har installerat en UniFi® Security Gateway Pro. Tyvärr så verkar det som att när många enheter ansluter mot samma host så flippar den ur. Den rebootar med jämna intervall på några timmar och det tar lång tid att initiera nya anslutningar mot hosten. Den temporära lösningen som fungerade var att slå av hårdvaru TCP/IP offloading. För att göra detta lär man SSHa in på Gatewayen efter varje omstart eller konfigurationsändring.

    configure
    set system offload ipv4 pppoe disable
    set system offload ipv4 vlan disable
    set system offload ipv4 forwarding disable
    set system offload ipv6 vlan disable
    set system offload ipv6 forwarding disable
    commit;save;exit

    Får se om det kommer något nytt firmware som fixar detta eller om det blir s/UniFi® Security Gateway Pro/EdgerRouter PRO/g istället.

  • PHP: Få kod att exekveras innan en closure

    Ganska dålig rubrik va? I vilket fall så stötte vi på ett tillfälle där vi ville köra kod innan en closure kördes. Vi vill alltså “prependa kod i en closure”. Just i det här fallet var det att vi ville köra funktionen newrelic_name_transaction för att kunna spåra en request innan routen körs i newrelic - utan att behöva lägga till koden i varje routes kod.

    <?php
    /* Såhär skapar vi en route exempelvis */
    $routes[] = new Route('GET /index/@var1', function($var1) {
      echo 'Hello world! '.$var1;
    });
    
    /* Såhär ville vi inte göra */
    $routes[] = new Route('GET /index/@var1', function($var1) {
        if(function_exists('newrelic_name_transaction')) {
            newrelic_name_transaction('GET /index/@var1');
        }
        echo 'Hello world! '.$var1;
    });
    
    /**
     * Såhär löste vi det
     */
    class Route
    {
        /* .. */
        function __construct($request, closure $functions, $weight = NULL)
        {
            $this->request = $request;
            $this->weight = $weight;
    
            $this->function = function (...$vars) use ($functions) {
                if(function_exists('newrelic_name_transaction')) {
                    newrelic_name_transaction($this->request);
                }
    
                return $functions(...$vars);
            };
        }
        /* .. */
    }

  • Sätta tidszon i Amazon Linux EBS

    För att timezonen ska sparas även när nya EBS-instanser skapas (ex. vid skalning) skapar vi en ny fil i “.ebextensions”.

    .ebextensions/00-set-timezone.config

    commands:
      set_time_zone:
        command: 'ln -f -s /usr/share/zoneinfo/Europe/Stockholm /etc/localtime'

  • Swish API, klientcertifikat & Amazon Linux (EBS) (NSS)

    På jobbet håller vi på att migrera till Amazons infrastruktur från de virtualiserade VMWare-instanserna med Debian vi kör idag. På Amazon har vi valt en uppsättning med Amazon Linux (PHP) som körs i “Elastic Beanstalk”. Målet med migreringen är att få bort så mycket manuellt underhåll som möjligt, öka driftsäkerheten och få en miljö som skalar av sig själv.

    Amazons Linuxversion bygger på CentOS / Redhat / RPM av pakethanteringssystem och struktur att döma. Deras curl är kompilerat mot Mozillas NSS istället för OpenSSL. I Swish e-handelslösning som vi använder så autentiserar man mot deras API med hjälp av klientcertifikat, något ganska ovanligt för betallösningar riktade mot e-handel.

    Fick en massa problem med att SSL-handskaken inte fungerade, curl spottade ut felmeddelande på felmeddelande. Här var PHP-koden som användes. Fungerar felfritt med curl & openssl:

    <?php
    $options = [
       CURLOPT_CUSTOMREQUEST => 'POST',
       CURLOPT_RETURNTRANSFER => true,
       CURLOPT_HEADER => true,
       CURLOPT_SSL_VERIFYPEER => false,
       CURLOPT_SSL_VERIFYHOST => false,
       CURLOPT_URL => $url,
       CURLOPT_CAINFO => '/etc/ssl/certs/Swish server TLS certificate.pem',
       CURLOPT_SSLCERT => APP_DIR . 'config/Swish/Swish.pem',
       CURLOPT_POST => true,
       CURLOPT_FOLLOWLOCATION => true,
       CURLOPT_POSTFIELDS => $data_string,
       CURLOPT_HTTPHEADER => [
           'Content-Type: application/json'
       ]
    ];

    Efter en massa felsökning så misstänkte jag att NSS var boven i dramat. Visade sig att man var tvungen att lägga till Swish certifikat i NSS certifkikatdb. Det fungerade alltså inte att skicka med certfikaten som ovan.

    a) Skapa en pksc12-fil från din private key och Swish-certet:

    openssl pkcs12 -export -out /tmp/server.pfx -inkey /tmp/www_partykungen_se.key -in /tmp/swish.pem -certfile /tmp/Swish_server_TLS_certificate.pem -password pass:

    b) Importera deras CA-cert.

    certutil -d sql:/etc/pki/nssdb/ -A -t "C,C,C" -n "Swish Root Cert" -i /tmp/Swish_server_TLS_certificate.pem

    c) Importera Swish-certet vi skapade i steg “a”

    pk12util -i /tmp/server.pfx -d sql:/etc/pki/nssdb/ -W "" -K ""

    Nu får vi istället i CURL använda oss av certifikatets namn i nssdb. Det hittar vi genom att köra följande:

    [ec2-user@ip-127-0-0-1 ~]$ certutil -d sql:/etc/pki/nssdb/ -L
    
    Certificate Nickname                                         Trust Attributes
                                                                 SSL,S/MIME,JAR/XPI
    
    Swish Root Cert                                              C,C,C
    12345678 - Swedbank AB (publ)                              u,u,u #<- Denna
    Swedbank Customer CA1 v1 for Swish - Swedbank AB (publ)      ,,   
    Swedbank Root CA v1 for Swish - Getswish AB                  ,,   
    Swish Root CA v1 - Getswish AB                               ,,  

    Så vi får anpassa PHP-koden:

    <?php
    $options = [
       CURLOPT_CUSTOMREQUEST => 'POST',
       CURLOPT_RETURNTRANSFER => true,
       CURLOPT_HEADER => true,
       CURLOPT_URL => $url,
       CURLOPT_SSLCERT => '12345678 - Swedbank AB (publ)',
       CURLOPT_POST => true,
       CURLOPT_FOLLOWLOCATION => true,
       CURLOPT_POSTFIELDS => $data_string,
       CURLOPT_HTTPHEADER => [
           'Content-Type: application/json'
       ]
    ];

    Sen kommer nästa problem: inget är persistent i en EBS-miljö. Miljön “nollas” ju ibland, så vi får se till att köra allt när en ny instans startas med hjälp av .ebextensions:

    .ebextensions/03-certificate-files.config Lägger till våra certifikat-filer.

    files:
      "/tmp/Swish_server_TLS_certificate.pem" :
        mode: "000755"
        owner: root
        group: root
        content: |
          -----BEGIN CERTIFICATE-----
          ...
          -----END CERTIFICATE-----
          -----BEGIN CERTIFICATE-----
          ...
          -----END CERTIFICATE-----
      "/tmp/swish.pem" :
        mode: "000755"
        owner: root
        group: root
        content: |
          -----BEGIN CERTIFICATE-----
          ...
          -----END CERTIFICATE-----
          -----BEGIN CERTIFICATE-----
          ...
          -----END CERTIFICATE-----
          -----BEGIN CERTIFICATE-----
          ...
          -----END CERTIFICATE-----
          -----BEGIN CERTIFICATE-----
          ...
          -----END CERTIFICATE-----
      "/tmp/www_partykungen_se.key" :
        mode: "000755"
        owner: root
        group: root
        content: |
          -----BEGIN PRIVATE KEY-----
          ...
          -----END PRIVATE KEY-----

    .ebextensions/04-generate-pkcs12-and-add-to-nssdb.config Genererar pkcs12-filen från certifikaten vi behöver och lägger till Swish CA-cert och vårt cert i nssdbn. Sen städar upp! Finns ingen anledning för dem att ligga kvar.

    commands:
      a_create_pfx:
        command: 'openssl pkcs12 -export -out /tmp/server.pfx -inkey /tmp/www_partykungen_se.key -in /tmp/swish.pem -certfile /tmp/Swish_server_TLS_certificate.pem -password pass:'
      b_import_swish_ca:
        command: 'certutil -d sql:/etc/pki/nssdb/ -A -t "C,C,C" -n "Swish Root Cert" -i /tmp/Swish_server_TLS_certificate.pem'
      c_import_swish_cert:
        command: 'pk12util -i /tmp/server.pfx -d sql:/etc/pki/nssdb/ -W "" -K ""'
      d_rm_files:
        command: 'rm /tmp/Swish_server_TLS_certificate.pem /tmp/server.pfx /tmp/swish.pem /tmp/www_partykungen_se.key'

subscribe via RSS