Skip to content

Things to optimize are:

  • server connection time
  • time to first byte
  • number of server requests
  • total size of downloaded content

Before you start optimizing, test your site's performance using

  1. Request to server
    1. DNS request
      • Here it's probably interesting to switch to a CDN because they usually have faster DNS servers than the standard providers.
    2. connect to server
    3. SSL handshake
  2. Server processing
    1. i/o and memory
    2. httpd
    3. php
    4. mysql
    5. load and execute wordpress
    6. load and execute themes and active plugins
  3. server gives response to client (time to first byte)
    1. update apache to the latest version, something like 2.4.x. to check your version httpd -v
    2. add caching plugin to wordpress W3 total cache
      • page cache enable - disk enhanced
      • minify disable - modpagespeed will do that
      • Opcode Cache enable - zend opcache (enable it in php.ini by uncommenting zend_extension=opcache)
      • Database cache enable - disk
      • Object cache enable - disk
      • Browser cache disable - modpagespeed will do that
      • Fragment cache enable - disk
    3. add modpagespeed to site
      • ...
    4. move to http/2
      • in http.conf, uncomment
        LoadModule http2_module modules/<IfModule http2_module>
        LogLevel http2:info
      • in virtual hosts, add this
        # for a https serverProtocols h2 http/1.1# for a http server
        Protocols h2c http/1.1
      • An additional requirement is that no cipher from a specified black list may be used. An acceptable Apache SSL configuration regarding this is:
        SSLProtocol All -SSLv2 -SSLv3
      • restart apache and test it: or chrome://net-internals/#http2
    5. change apache from mpm_prefork to mpm_worker/mpm_event
      • check apache server mpm type using httpd -V
      • install php-fpm package
      • start php-fpm service
      • edit httpd.conf and switch to event or worker
        LoadModule mpm_event_module modules/
        #LoadModule mpm_prefork_module modules/
        #LoadModule mpm_worker_module modules/
      • uncomment
        LoadModule proxy_module modules/
        LoadModule proxy_fcgi_module modules/
      • create new httpd config file php-fpm.conf
        DirectoryIndex index.php index.html
        <FilesMatch \.php$>
        SetHandler "proxy:unix:/run/php-fpm/php-fpm.sock|fcgi://localhost/"
      • include it at the bottom of httpd.conf
        Include conf/extra/php-fpm.conf
      • restart services php-fpm and httpd
    6. get rid of not used apache modules. to check which modules are used httpd -M
    7. check apache workers count and memory usage httpd-mpm.conf
    8. get rid of unnecessary wordpress plugins
    9. speed can be tested with xdebug
      • install xdebug
      • edit /etc/php/conf.d/xdebug.ini

        ; profiler
        xdebug.profiler_enable_trigger = 1
        xdebug.profiler_enable_trigger_value = "test"
        xdebug.profiler_output_dir = "/var/log/xdebug"
        xdebug.profiler_output_name = "callgrind.%s.%H"

      • systemctl restart httpd
        systemctl restart php-fpm
      • You can test if xdebug is working with the following code in a php file:
        function test()
        echo "Called @ ".xdebug_call_file().
        ":".xdebug_call_line()." from".


      • to test the profiler



Surveillance cameras are big business and way too expensive when you want to buy one from a reputable brand. Here's an example: Logitech Alert 750e Outdoor Master Security Camera System with Night Vision currently sells at US$999.

In this post I'll show you how to build your own surveillance camera for fun and for way cheaper. Let's get started.

For this, you'll need:

  1. a Raspberry Pi 2
  2. a 16GB micro SD card for the Raspberry software
  3. your favorite USB webcam
  4. an Ethernet cable and a router with at least one RJ-45 free LAN slot
  5. And of course a computer with an SD card reader


  • The first step is to download and install the operating system for the Raspberry Pi. While Raspbian the official Linux OS for the Raspberry Pi is an option, I didn't like it that much as there are way too many things that get automatically installed on it. I decided to go the leanway by installing Debian Jessie instead. Download it from here (latest image at then extract the gzip archive and use Win32DiskImager to write the downloaded image to the SD card.win32-disk-imager
  • Eject the SD card and insert it into the Raspberry Pi, then power the Raspberry using the micro-USB slot. Also connect the Raspberry to your router using Ethernet cable.
  • The Raspberry Pi will automatically boot on the SD card pre-installed image, establish an network connection and the SSH deamon will be listening for us. But first we need to find its IP address. For that we can use nmap which is a network scanner. Download and install nmap then open a command prompt .
  • In the command prompt type ipconfig. This will provide valuable info about our local network. As you can see, my IP address is
  • Now we scan the network using nmap -p22 (replace 88 with your local flavor). What this does is to scan the whole local network (except for the gateway) for devices listening on port 22 which is the SSH default port.nmap-results
  • In this example, you can see that 6 devices are present (my computer included) and among them are 4 Raspberry Pi. Now that we have its IP address we can establish a connection using SSH. Probably the best SSH option on Windows is Putty. Download and install it.
  • Start Putty and enter the IP address of the Raspberry Pi under Host name then click openputty-connect
  • The default login is root/debianlogin-as-root
  • Start by changing the root password using the passwd commandpasswd
  • Update the system: apt-get update then apt-get upgradeapt-get-update
  • Update the Raspberry date, time and timezone.
    1. apt-get install ntpdate
    2. ntpdate pool.ntp.orgntpdate
    3. cp /usr/share/zoneinfo/Europe/Riga /etc/localtime to set the time zone (adjust to your flavor)set-timezone
  • Install sudo and add a user account: apt-get install sudo then adduser yourusersudo-adduser
  • Make the new user a system administrator: sudo adduser cat sudosudo-adduser-2
  • Now that we created the user account, let's disconnect from this session and reconnect but with the user account this time. Now let's remove the possibility to login as root. sudo passwd -l rootremove-root-loginIf you want to learn more about why it's important to disable root login...
  • Add USB utilities: sudo apt-get install usbutils
  • Check that your camera is detected: lsusb detect-usb-camera
  • Install the camera software: sudo apt-get install motioninstall-motion
  • Backup the motion configuration file: sudo cp /etc/motion/motion.conf /etc/motion/motion.conf.bak
  • Edit the motion configuration file: sudo nano /etc/motion/motion.conf
  • Here's the list of changes I made on mine
    logfile /var/motion/motion.log
    width 1280
    height 960framerate 5quality 95

    #sdl_threadnr 0

    snapshot_interval 360

    target_dir /var/motion

    snapshot_filename snapshot-%Y-%m-%d_%H%M%S-%v
    picture_filename motion-%Y-%m-%d_%H%M%S-%v-%q-%v
    movie_filename movie-%Y-%m-%d_%H%M%S-%v
    timelapse_filename timelapse-%Y-%m-%d
    stream_quality 95
    stream_motion on
    stream_localhost off

Save the file CTRL + O and exit nano CTRL + X

  • Create dir /var/motion/ : sudo mkdir /var/motion and assign ownership to motion: sudo chown motion:motion /var/motionmotion-dir
  • Start the motion deamon when the system starts: sudo nano /etc/default/motion and set daemon to yes
  • Test if everything works accordingly: sudo service motion restart
  • After a few seconds check if any content was generated in the motion target dir: ls /var/motion/ -lmotion-test
  • And even better, you can now also access the live stream server at . Well that's it! If you have any issues or problems, just report them in the comments
  • Update: if you notice after reboot that no photos are being captured, here's how to troubleshoot: sudo service motion status. This will show the status of the motion service and will show any errors that could have occurred. It's usually permission issues on the motion config file or the motion log file which can be fixed with chown and chmod.

I recently broke my iPhone 5S screen and decided that I should try to fix it myself.

I headed to to see how hard this could be. After a quick search on their website, I found the exact guide I needed as well as the price for a replacement screen. A quick look at the repair guide convinced me and off I went to order the replacement screen. A week later or so I received the package and was ready to start the surgery 🙂

Following the guide made the repair relatively easy, the only issue I experienced was that the screen connector was not exactly in place the first time I tried which resulted in screen artifacts.

photo 1photo 2

photo 3photo 4



Windows 10 now being definitely released, I wanted to have a fresh look at it and decided to install it. As I want to keep my current installation of Windows 7 for the time being, I opted to install it on a second internal hard drive I have on my fantastic Folio 9470m (it has 2 HD slots: one for a standard 2.5" SATA drive and another for a mSATA micro-drive).

Unfortunately this turned into a really frustrating fiasco as the installer is not letting me decide anything!

The only options I have is to upgrade my current Windows 7 to Windows 10 or make a Windows 10 clean install!!! WTF?


While I certainly understand the installation process should be kept as simple as possible for the non-techy crowd, I simply refuse to imagine that the people in charge of UI have not thought about any other options.

For now I'm just going to enjoy doing other stuff instead of trying to find the hack for this ocean of frustration...

I recently had the opportunity to play around with x64_dbg as OllyDbg can only debug 32 bit executables. In fact this is not exactly correct as there is a version 2 of OllyDbg that supports x64 but it's still a work in progress (last updated in February 2014) and I didn't have much success with the apps I tested.

My initial impression is that any OllyDbg user will immediately feel familiar with x64_dbg and quickly get debugging. Of course x64_dbg being a relatively new project it only has a few plugins so far. Anyway try it out if you have any 64 bit apps laying around.


Sysinternals' Process Explorer is just the best when it comes to watching all processes that are running on your machine. I've been using it for years and I'm not afraid to say it's the best single executable I ever came across. Tools such as this one are what makes Windows a great OS to work on.


I use it all the time to check:

  • how much memory/cpu processes take
  • to kill processes
  • to find new processes running on my machine (such as after a new software install: I dislike those pesky installers that silently install services and processes that start with Windows)
  • to find the path to a certain executable

What I recently discovered however is that right from within Process Explorer, you can actually verify the signatures of all presently running executables.


and even better submit the hash of every single running executable to Virustotal for validation with all major antivirus engines.


Here's how it looks once the check was done.


As you can see I have one process that requires further attention. It's Notepad++. Simply clicking on the "1/57" brings up the virustotal report which after verification proves to be harmless.


I have experienced problems with one of the 2 USBasp programmers we have at MakeRiga and decided to flash the firmware. Here's how to do it.

  • Download the latest firmware from At the time of writing this it was
  • Extract the archive
  • There are 3 firmwares inside the usbasp.2011-05-28\bin\firmware directory: usbasp.atmega88.2011-05-28.hex, usbasp.atmega8.2011-05-28.hex and usbasp.atmega48.2009-02-28.hex. The difference between them is the target micro-controller. Check which one you have.


  • To update the firmware you also need to set jumper J2 on the USBasp to update as explained in  the Readme.txt
  • Set both USBasp to 5V on jumper J1 and connect them via a 10 pin cable
  • Finally connect the programmer to the computer USB port


    • Now let's get to avrdude. Copy the correct firmware to the avrdude directory.
    • Backup the original firmware. You'll need to replace VARIABLE with your micro-controller version: atmega8, atmega48 or atmega88

avrdude -c usbasp -p VARIABLE -U flash:r:flash-usbasp.bin:r


  • To write the latest firmware. Replace FIRMWARE with your firmware

avrdude -c usbasp -p VARIABLE -U flash:w:FIRMWARE


That's it!

In May, MakeRiga organized a great hacking event. I provided a few software challenges for the competitors while others contributed with hardware challenges. These last few days I spent some time discovering the later as I have close to no experience in hardware. Here's my journey with my first hardware challenge: Blinky. Blinky is simple circuit with a blinking red led and a green led that stays switched off.


There are 2 objectives for this challenge:

  1. Make the green led blick synchronously with the red led
  2. Make the green led blick asynchronously with the red led


The first thing I did is look at the components on the circuit and the associated wiring.


  • a chip labeled ATMEL1412 TINY13A SSU
  • 1 green led, 1 red led
  • 2 resistors
  • 1 capacitor
  • 1 switch
  • 3V CR2032 battery

Of course the most interesting part is the chip and as I didn't know what it does, I searched for it on (I started google detox a few days ago and so far I'm very happy with the results Duck Duck Go gives me). Here's the official documentation for the chip.

The Atmel picoPower 8-bit AVR RISC-based microcontroller featuring 1KB of ISP Flash, 64-byte EEPROM, 64-byte SRAM, 32-Byte register file, and 4-channel 10-bit A/D converter. The device achieves up to 20 MIPS throughput at 20 MHz at 1.8-5.5 V operation.

So since it's a micro-controller, it means that there's software written inside it to blink the led. So at this stage, there are 2 ways to complete the objectives:

  • hardware: solder new wires to the circuit
  • software: modify the software on the chip

As I'm more of the software guy I took this approach. It ended up being much longer than the hardware approach but I really learnt a lot from it. So my first question was: how can I extract the software from the micro-controller?

I found out that you need both software and hardware for that task. For software avrdude is very popular and for hardware I opted for a USBasp programmer as we have 2 of them at MakeRiga. Here's how it works: Avrdude communicates with the micro-controller through the USBasp. For it to work the USBasp pins must simply be connected to the corresponding pins on the ATtiny 13A micro-controller. I also had to solder pins to the circuit for easier connection.


Here's how it looks with everything connected. Note that the led is blinking because the circuit is powered through the USBasp.

usbasp connected to circuit

Now it's time to dump the software from the chip:

avrdude -p t13 -c usbasp -U flash:r:flash-13.bin:r


For it to work make sure that avrdude finds its config file and that the jumper 3 on USBasp is connected. Here's a copy of flash-13.bin (it's only 64 bytes of code). To check that everything is working, let's upload the firmware back to the device.

avrdude -p t13 -c usbasp -U flash:w:flash-13.bin


Now that we know it's working comes the next question: how can I write software for the micro-controller? I found out that the main options are Arduino IDE with a few changes or use Atmel Studio. I opted for Arduino IDE as it was a lighter download. Atmel Tiny micro-controllers are unfortunately not supported out of the box and I had to fiddle for a while until I found out how to do it thanks to this blog.

In Arduino IDE, under Tools, select board ATtiny, processor ATtiny13 and clock 1Mhz internal.

Next problem was to get some start source code to play with. Arduino IDE has a blink example so I started with this one.


The code only required a few modifications to work. First our micro-controller only has 8 pins, so it can't be pin 13. After looking at the circuit pinout again, I concluded that PB0 is connected to the red led and PB1 to the green led and PB0 is pin 0, PB1 is pin 1. I uploaded the code and ended up with a red led but not blinking. strange...

Changing the pin to 1 turned the green led and setting the digitalWrite to low would turn the light off. So I understood there was some problem with the delay function. I found out that I had to use another function named _delay_ms and that did the trick.


Interestingly my software ended up costing 364 bytes, which is a huge inflation compared to the original 64 bytes.

Solving the objectives 1 and 2 was a piece of cake from there on. Here's the code for both leds blinking at the same time.


And asynchronously...


Finally the software way was much harder but definitely a lot more fun 😀

Here's how the hardware approach looks for the alternative blinking.


I happened to find 3 Swisscom Netopia 3347-02 DSL routers that were laying around and I thought maybe I could get them to be useful again. Unfortunately those routers come with a custom firmware for every network provider that used them and are close to useless if you don't use this provider any longer (Swisscom, Qwest, Eircom among others). So let's see if we can reclaim their freedom.

[router photo]

exact model: 3347-02-20SC, type: 0x69

The idea is to install an alternative firmware on them. The 2 most popular options are OpenWRT and DD-WRT. So the first thing to do is to check if the router is supported. A quick check in the OpenWRT brings up this for Netopia routers:

ModelVersionPlatform & FrequencyFlashRAMWireless NICSwitchboot_waitSerialJTAGUSBStatus
3387WG-ENTCX86113 @ 200MHz4MB16MBTNETW1130GVFBCM5325EKQMNoUntested
3347NWGTexas Instruments AR7 (TNETD7300AZDW) @???4MB16MBTNETW1130ZVFBCM5325EKQMGNoUntested
3347W/3357WCX82310 @ 168MHz2MB16MBACX100AGHKBCM5325A2KQMNoUntested

Unfortunately our exact model is not listed and all the listed models are untested. No luck with DD-WRT either as it doesn't have any Netopia routers listed. Let's don't get discouraged and see if we can still proceed further.

Opening the router will bring important information about the key hardware components. Three screws later we get access to the board.

[router board photo]

Here's the list of identified components:

Infineon PSB7200ZDW 83A48KW
CPU Infineon AR7 Ohio PSB7200ZDW @ 212MHz?
The AR7 combines a MIPS32 processor, a DSP-based digital transceiver, and an ADSL analog front end. Integrated high performance MIPS 4KEc 32-Bit RISC processor

Flash memory

SAMSUNG K4S281632I-UC75 (or NANYA NT5SV8M16FS-75B on another board)
RAM memory 128Mb Synchronous DRAM

Broadcom BCM5325EKQMG
Ethernet Switch 6-Port 10Mbps/100Mbps 128-Pin MQFP

Wireless chip

LAN filter

Well that's it. So we have a little computer here composed of a MIPS32 CPU, flash memory (to store the firmware), RAM memory, an ethernet switch and a wireless chip.

Going back to our OpenWRT table, we conclude that our closest relative is the 3347NWG as they share the same processor and switch although the wireless chip is a different model from the same company. Let's see if any OpenWRT compatible routers use the AR7 MIPS chip:

Here we got several hits such as

GT724WG10.03?ar7Texas Instruments TNETD7200212416TI TNETW1350Ab/g4 + DSLNoNo
AG241v18.09.2ar7ar7?416--4x 100M + 1xADSLNo?

So that's definitely comforting, it means that although not tested it's probably possible to install OpenWRT on this router. Let's try it. Next we need to download the correct firmware image for our router. In this case it's

Let's connect to the router admin interface (admin/1234) and try to install the firmware we just downloaded.

[firmware update1 and firmware update2]

Ah shit, the firmware update failed. It says the file upload failed. Let's see if we have more success through a telnet connection. For this purpose, I installed Putty. Login and password just like before.

[putty connection] [terminal]

login: admin
Password: 1234

Terminal shell v1.0
Copyright ▒2008 Motorola, Inc.  All rights reserved.
Netopia Model 3347-02 AnnexA High-Power Wireless DSL Ethernet Managed Switch
Running Netopia SOC OS version 7.8.1 (build r2)
Multimode ADSL Capable
(admin completed login: Full Read/Write access)

Ok we're in. Let's get the list of commands by typing help:

Netopia-3000/32309508> help
arp                           to send ARP request
atmping                       to send ATM OAM loopback
clear                         to erase all stored configuration information
clear_certificate             to clear stored SSL certificate
clear_log                     to clear stored log data
configure                     to configure unit's options
diagnose                      to run self-test
download                      to download config file
exit                          to quit this shell
help                          to get more: "help all" or "help help"
hotspot                       to set or show hotspot authentication info
install                       to download and program an image into flash
license                       to enter an upgrade key to add a feature
log                           to add a message to the diagnostic log
loglevel                      to report or change diagnostic log level
netstat                       to show IP information
nslookup                      to send DNS query for host
ping                          to send ICMP Echo request
quit                          to quit this shell
reset                         to reset subsystems
restart                       to restart unit
show                          to show system information
start                         to start subsystem
status                        to show basic status of unit
telnet                        to telnet to a remote host
traceroute                    to send traceroute probes
upload                        to upload config file
view                          to view configuration summary
wan_type                      to Set WAN interface type
who                           to show who is using the shell
?                             to get help: "help all" or "help help"
wps                           to issue Wireless Protected Setup commands
wol                           to Wake On LAN


So it's install we're actually looking for. Let's try

Netopia-3000/32309508> install


Do you wish to proceed? (type `yes' to confirm): yes

Enter TFTP server IP address:

Ok we need to setup a TFTP server that will serve the firmware.

[TFTP screenshot]

Enter TFTP server IP address:
Enter file path of image to install: openwrt-ar7-generic-squashfs.bin

About to install new Flash EPROM software image:
file:  "openwrt-ar7-generic-squashfs.bin"

Should installation proceed with this information?
(type `yes' to confirm): yes

Starting Firmware download.
Downloading file .................................................................................................................................................................
Firmware Load Failed:  Invalid file

Well firmware refused again but this time we know that the file is invalid. So that means there's some kind of way to check that the firmware is of the correct type. Just to confirm the assumption, I tried to install an official Swisscom firmware and that works both in web and telnet. So there's definitely some check in place. I looked at it from many different angles but it seems not possible from the telnet console to anywhere further.

Let's dig deeper. Looking at the board there are two interesting locations named J5 and J2. J5 consists of 4 pins in a rectangle, while J2 consists or 14 pins in a rectangle.

[J5 photo and J2 photo]

This happens to be the Serial and JTAG pins.

Most routers come with an UART integrated into the System-on-chip and its pins are routed on the Printed Circuit Board (PCB) to allow debugging, firmware replacement or serial device connection (like modems). The bootloader is responsible for listening on it. So in contrast to the JTAG-Port, the Serial Port needs some software running on the CPU so we can use it! If the bootloader is damaged, or doesn't offer such a feature, the port is useless.

Once the serial is found, you can easily check where is the GND, which is connected to the same ground layer than the power connector. The VCC should be fixed at 3.3V and connected to the supply layer ; the TX is also at 3.3V level, but using a multimeter as an ohm-meter, if you find an infinite resistance between the TX and VCC pins, it means they're distinct signals (else, you'll need to find the correct TX or VCC pin). The RX and GND are by default at 0V, so you can check them using the same technique. Typically there are four pins to identify: GND - Ground, Vcc - 3.3VDC or 5VDC, TXD - Transmit data, and RXD - Receive data.

Pin    Signal
1    GND - can only be next to J5 - Most PCB designers will draw a square pad to indicate pin number 1 - which is the case here
2    TxD - tranmission
3    VCC - positive voltage
4    RxD - reception

To use the serial console, we need to solder the pins.

[serial console soldered]

Now to communicate with the serial console, we need a USB to serial "transformer". It's called a CP210x USB to UART Bridge. Luckily they have one at the hacker space. The thingy needs drivers to run under Windows. We also need the Realterm software to read the serial console stuff.

Before connecting the router and the computer, it's best to test the USB to UART Bridge by connecting its TX to its RX. This is often called a "null-modem" configuration; the signal is sent through TX to RX (loopback).

[null-modem] [realterm settings]

Let's connect the serial console with the UART bridge. In order to interact with the device over the serial port, we need a minimum of three wires connected: a ground (GND); transmit (TX); and receive (RX). Connect both GND together and connect computer side TX to device RX and vice-versa. That way, what you say will get heard by the device and what the device says will get heard by your computer. Time to test it.