perjantai 25. toukokuuta 2012

Encrypting SWAP partition and taking previously encrypted home partition into use

Due to my personal Ubuntu release update process, I have to configure encryption of my boot and home partition manually every now and then. Because I do this regularly, I'm documenting my process here in my blog...

Here's my Ubuntu release update process.
  1. Make Ubuntu installation program to format the partition that held the previous Ubuntu version
  2. Format and configure existing boot partition as the new boot partition
  3. Configure existing swap partition as the new swap partition
  4. Install Ubuntu normally without dedicated home partition
After installation, my encrypted home partition is not accessible anymore, because it was not configured as part of the installation process. I haven't been able to configure either normal installer or alternative installer to take previously encrypted partitions into use. So, it has to be done after installation.

After installation has finished, install cryptsetup.

$ sudo apt-get install cryptsetup

Then configure /etc/fstab file by adding configuration for swap and home. For example.

/dev/mapper/sda7_crypt /home           ext4    defaults        0       2
/dev/mapper/sda5_crypt none            swap    sw              0       0

The actual values depend on your hard disk partitioning. Here's example from my laptop.

$ sudo fdisk -l

Disk /dev/sda: 500.1 GB, 500107862016 bytes
255 heads, 63 sectors/track, 60801 cylinders, total 976773168 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x7250e0b9

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1            2048    24588287    12293120   27  Hidden NTFS WinRE
/dev/sda2        24588288    24793087      102400    7  HPFS/NTFS/exFAT
/dev/sda3   *    24793088    26746879      976896   83  Linux
/dev/sda4        26748926   976773119   475012097    5  Extended
/dev/sda5        26748928    34559999     3905536   82  Linux swap / Solaris
/dev/sda6        34562048   132216831    48827392   83  Linux
/dev/sda7       132218880   976773119   422277120   83  Linux

The next step is to configure /etc/crypttab by adding appropriate encryption setup. In my case it looks like this.

sda5_crypt /dev/sda5 /dev/urandom cipher=aes-cbc-essiv:sha256,size=256,swap
sda7_crypt UUID=5a9c38c3-2aa9-433b-9efd-c0e9357d0811 none luks

The swap partition setup is "universal" and it should work on any computer (of course the correct partition may differ from this example). The swap is encrypted with a key that is randomly generated on each system startup.

For the home partition you have to know the UUID of the partition. Here's one way to find it.

$ sudo blkid 
/dev/sda1: LABEL="Recovery" UUID="78F82CACF82C6A98" TYPE="ntfs" 
/dev/sda2: LABEL="System Reserved" UUID="62ACA8E6ACA8B5C7" TYPE="ntfs" 
/dev/sda3: UUID="7d526d52-018a-4b0c-9e26-64f1143cf0da" TYPE="ext4" 
/dev/sda5: UUID="0d0178b1-ade5-416f-8535-82455a8febd5" TYPE="swap" 
/dev/sda6: UUID="b0d7a0b7-0bb8-4cf9-978a-f7c6ebb2126f" TYPE="ext4" 
/dev/sda7: UUID="5a9c38c3-2aa9-433b-9efd-c0e9357d0811" TYPE="crypto_LUKS" 
/dev/sdb1: LABEL="siirtoNTFS" UUID="494640E516B11A6B" TYPE="ntfs" 
/dev/sdb2: LABEL="siirto" UUID="570857a6-4ab3-4d4b-99a2-88d383d3e588" TYPE="ext4" 

With this configuration, the system should ask for home partition's encryption key during system startup and everything should work as before.

sunnuntai 20. toukokuuta 2012

Jetty Maven Plugin with hot code replace



I'm often using Jetty Maven plugin to execute my web applications right from the build. It provides an easy and operating system independent way to execute the web app. You only have to check out the source code from version contol, execute Maven build and start Jetty with Maven command. What could be easier way to run your web application in development environment?

I want to point out the following benefits in using Maven Jetty plugin

  • IDE independent way to execute web application. Works on Eclipse, IDEA, NetBeans and whatever
  • Support hot code replace: you can change code inside methods without restarting the whole application
  • Works on Windows, Linux and Mac or any other Java compatible operating system. No need to setup the application server instance
  • Starts fast and it's easy to reload the application to the server after changes

Just add the XML snippet in the end of this post to your pom.xml and execute Maven with mvn jetty:run. As a result, you will get response from your web app in http://localhost:8180/example/. You can run the same goal from your favorite IDE and, thus, you get an IDE independent web app execution!

In case you want to try hot code replace, add the classpaths containing your code inside the extraclasspath-element. Then start the Maven build running Jetty in debug mode and connect to the debugging session with your favorite IDE. The easiest way to achieve this in Eclipse is to run the Maven build in debug mode and then connect to the process with Eclipse debugger. After Eclipse is properly connected to the Maven process running Jetty, all the code changes in method bodies are instantly visible in the running process  (of course the same code has to be modified by Eclipse so that the changes get to the classpath of Jetty).

If you prefer doing things in IDE, at least Eclipse has excellent Jetty plugin called Run Jetty Run (http://code.google.com/p/run-jetty-run/).

<build>
<plugins>
...
<plugin>
    <groupid>org.mortbay.jetty</groupid>
    <artifactid>jetty-maven-plugin</artifactid>
    <version>7.5.2.v20111006</version>
    <configuration>
        <stopport>9966</stopport>
        <stopkey>${project.artifactId}<stopkey>
        <!-- scanning is not used if reload is set to manual -->
        <scanintervalseconds>5</scanintervalseconds>
        <!-- application reloading by pressing enter in the console -->
        <reload>manual</reload>
        <webappconfig>
            <contextpath>/example</contextpath>
            <!-- Changes in these classes will be instantly applied to running Jetty process without restart -->
            <extraclasspath>target/classes;../dependant-project/target/classes;../another-dependant-project/target/classes</extraclasspath>
        </webappconfig>
        <!-- directories whose changes cause automated Jetty context reloading, not used if reload is manual -->
        <scantargets>
            <scantarget>../dependant-project/target/classes</scantarget>
        </scantargets>
        <connectors>
            <connector implementation="org.eclipse.jetty.server.nio.SelectChannelConnector">
                <port>8180</port>
                <maxidletime>60000</maxidletime>
            </connector>
        </connectors>
        <systemproperties>
            <!-- system properties that are used for running Jetty -->
            <systemproperty>
                <name>some.system.property</name>
                <value>somevalue</value>
            </systemproperty>
        </systemproperties>
    </configuration>
    <dependencies>
        <!-- dependencies added to Jetty's classpath -->
        <dependency>
            <groupid>log4j</groupid>
            <artifactid>log4j</artifactid>
            <version>${log4j.version}</version>
            <type>jar</type>
        </dependency>
    </dependencies>
</plugin>
...
</plugins>
</build>

maanantai 9. huhtikuuta 2012

Automatisoidun asennuksen autuus

Kuinka monesti olet omassa projektissasi joutunut rutiininomaisesti asentamaan tekemäsi sovelluksen testi- ja tuotantoympäristöihin yhä uudelleen ja uudelleen? Kuinka monta kertaa muistat tehneesi huolimattomuusvirheen asennuksen aikana? Montako kertaa olet ihmetellyt testi- ja tuotantoympäristön konfiguraatiota, jonka joku muu on muuttanut tietämättäsi ja sovelluksesi rikkoen? Oma vastaukseni edellisiin kysymyksiin on lähes joka projektissa ja erittäin monta kertaa. Onneksi poikkeuksiakin mahtuu joukkoon. Näissä poikkeustapauksissa asennusautomaatio on tehty enemmän tai vähemmän täydelliseksi. Keskityn tässä blogauksessa käsittelemään näitä poikkeusprojekteja ja syitä siihen, miksi jokaisen projektin pitäisi automatisoida sovelluksen ja käyttöympäristön asennukset. Poikkeuksesta pitäisi siis tulla pääsääntö!

Asennuksen eri tasot

Oman kokemukseni perusteella sovelluksien asentamiseen liittyy neljä eritasoista asiaa.
  1. Laitteisto, joko fyysinen tai virtuaalinen
  2. Käyttöjärjestelmä ja sen päälle asennettavat perusbinäärit, kuten WWW-palvelin
  3. Ympäristön yleiset konfiguraatiot, jotka liittyvät käyttöympäristön ylläpitoon. Esimerkkinä ajastetusti suoritettavat varmuuskopioinnit
  4. Itse asennettavat sovellukset ja niiden konfiguraatiot
Nähdäkseni tason 1 asennusautomaation tekeminen on mahdollista vain, mikäli laitteisto on virtualisoitu. Esimerkiksi Amazon Web Services mahdollistaa virtuaalisen laitteiston luomisen komentoriviskripteillä. Laitteisto-käsitteeseen liitän tässä yhteydessä kaiken "raudan", kuten laskentakapasiteetin, tallennuskapasiteetin, verkkoyhteydet ja vaikkapa varmuuskopiointivälineet. Kun näiden luomisen automatisoi, tietää tarkasti ympäristön rakenteen ja tarvittaessa voi luoda helposti uusia vastaavia ympäristöjä. Laitteiston asennusautomaatiolla vältytään luomasta ympäristöjä, jotka ajan kanssa kasvavat tuntemattomiksi viidakoiksi.

Tasolla 2 sijaitsevat sekä käyttöjärjestelmä että käyttöjärjestelmässä ajettavat natiivisovellukset. Jos projektissa tehtävä sovellus on natiivisovellus, ei sitä silti lasketa tälle tasolle kuuluvaksi. Koska käyttöjärjestelmän ja natiivisovelluksien asentamisen automatisointi on yleensä vaikeata, eikä siitä välttämättä ole juurikaan hyötyä, voi tämän tason automatisoinnissa helposti oikaista tekemällä käsin asennetusta ympäristöstä levykuvan (disk image) ja käyttää sitä muussa automaatiossa. Mikäli projektissa tehtävälle sovellukselle tai sovelluksille riittää yhdenlainen käyttöympäristö, on manuaalisesti ylläpidettävä levykuva helpoin ratkaisu. Jos tarvitaan useita erilaisia käyttöympäristöjä, on syytä automatisoida myös käyttöjärjestelmän ja natiivisovelluksien asentaminen. Ainakin useimmissa Linux-pohjaisissa käyttöjärjestelmissä tämä on helppoa.

Tason 3 konfiguroinnilla tarkoitan sellaisia käyttöympäristöön liittyviä tehtäviä, jotka eivät liity suoranaisesti sovellukseen, mutta joiden pitää olla muutettavissa helposti kulloiseenkin tilanteeseen sopivasti. Yhtenä esimerkkinä voisi olla tietokannasta otettavat ajastetut varmuuskopiot. Periaatteessa ajastuksen voisi laittaa jo tasolla 2 suoraan vaikkapa levykuvaan, mutta tämä ei ole kovin joustavaa. On nimittäin mahdollista, että sovellus ottaa käyttöön esimerkiksi uuden tietokannan, joka pitäisi myös varmuuskopioda ja levykuvan muokkaaminen ja uudelleenasennus on työläs tehtävä näin pienen muutoksen takia. Tasolla 3 tehtävät muutokset elävät useammin sovelluksen kanssa, mutta ovat toisaalta siitä täysin irrallaan.

Tasolla 4 asennetaan ja konfiguroidaan projektin tuottama sovellus. Varsinkin testiympäristöissä sovellusta joudutaan asentamaan ja konfiguroimaan jatkuvasti, kenties jopa muutaman minuutin välein. Parhaimmillaan uusi sovellusversio voidaan asentaa jokaisen versionhallintaan tehtävän muutoksen jälkeen, jolloin uusimmat muutokset ovat jatkuvasti testattavissa oikeassa testiympäristössä.

Eri tasoilla tapahtuu muutoksia eri tahdilla. On selvää, että tason 1 muutokset ovat harvinaisimpia, koska laitteistoa ei yleensä ihan joka päivä muuteta. Tasolla 2 muutokset tapahtuvat harvoin, ehkäpä vain esimerkiksi käyttöjärjestelmän ja natiivisovellusten turvallisuuspäivitysten takia. Tasolla 3 voi olla jo päivittäisiä muutoksia, mutta muutoksia on varmasti paljon harvemmin kuin tasolla 4. Onhan projekteissa yleensä itse sovellus suurimpien muutosten kohteena.

Koska on paras hetki automatisoida?

Asennusautomaation tekeminen kannattaa aloittaa heti projektin alussa. Ensin voi asentaa vaikkapa vain tyhjän sovelluksen, jolla voi todentaa, että sovelluksen tarvitsemat ympäristön tarjoamat palvelut toimivat. Kun automaatiota tekee heti projektin alussa, tulee sovelluksestakin sellainen, että sen asennuksen voi automatisoida. On helppoa kirjoittaa vahingossa sellainen sovellus, jonka automaattinen asennus ja ylläpito ei ole kenenkään mielestä mukavaa.

Itse toimin asennusautomaation kanssa yleensä niin, että teen ensin jossain sopivassa ympäristössä käsin tarvittavat muutokset, joilla voin varmistua muutosten oikeellisuudesta. Kun tiedän tarkalleen mitä pitää tehdä, muokkaan automaattista sovellusasennusta vastaavasti. Näin vältän turhien asioiden tekemisen automaattisesti, vaikka riskinä onkin se, että unohdan automatisoida kaikki käsin tehdyt asiat.

Ikinä ei kannata jättää asennusautomaation tekemistä projektin loppupuolelle tai siihen hetkeen, kun "ei ole muutakaan tekemistä". Jos näin toimii, jää automaatio varmasti tekemättä ja käsin tehtävät asennukset maksavat ajallisesti nopeasti enemmän kuin automaation luominen ja ylläpito. Valitettavasti käsin asentamisen ja automaation kustannusten vertailu on niiden luonteen takia hankalaa. Projektijohto ei siten lyhytnäköisyyttään välttämättä ymmärrä antaa aikaa automaation rakentamiselle projektin alkuvaiheessa. Silloin kun on kiire tehdä muutakin ja alussa asennukset on nopeaa ja helppoa tehdä käsinkin, koska kaikki on vielä tuoreessa muistissa eikä sovellus ole kasvanut isoksi.

Automaation kustannukset

Automaattisen ja käsin tehtävän asennuksen kustannusvertailussa kannattaa ottaa huomioon seuraavat tekijät.
  • Käsin tehtävän asennuksen dokumentointi. Asennusta ei voi toistaa ilman laadukasta dokumentaatiota
  • Käsin tehtyjen asennusten huolimattomuusvirheiden korjaaminen. Ihminen tekee huolimattomuusvirheitä, kone ei
  • Käsin tehtyjen muutosten seurannan mahdottomuus. Useamman ihmisen porukassa kenelläkään ei ole tietoa mitä tarkkaan ottaen on tehty eikä yksinkään toimiva ihminen muista kaikkea mitä on tehnyt
  • Käsin tehtyjen asennusten henkilöriippuvuus. Asennuksen taitavan ihmisen pitää olla paikalla jokaisessa asennuksessa
  • Käsin tehtävien asennusten hitaus ja skaalausongelmat. Yksi ympäristö on helppo hallita, kaksi vaikeata ja kymmenen alkaa lähentelemään mahdottomuutta, vaikka asentajien määrää lisäisi
  • Käsin tehtävien asennusten vaatimien pääsyoikeuksien hallinta. Ketkä kaikki saavat päivittää eri ympäristöjä ja millä oikeuksilla. Automaation kautta voidaan sallia vähäisilläkin pääsyoikeuksilla kokonaisten ympäristöjen luominen ilman tietoturvaheikennyksiä
Asennusautomaation tekemisen käynnistäminen vaatii projektilta ison alkupanoksen. Ensin pitää valita käytettävä automatisointitapa. Tehdäänkö automaatio komentoriviskripteillä vai käytetäänkö jotain asennusautomaation erityisesti suunniteltua ohjelmistoa (http://en.wikipedia.org/wiki/Comparison_of_open_source_configuration_management_software).

Kun on tiedossa millä välineellä automaatiota lähdetään tekemään, pitää alkaa tutkimaan käytössä olevien ohjelmistojen konfiguroimista ilman sovelluksien omia GUI-työkaluja. Kaikki ohjelmistot eivät välttämättä tee automatisointia helpoksi. Yksi pahimmista näkemistäni ongelmista on se, että ohjelmistoja voi konfiguroida vain ja ainoastaan GUI-työkaluilla, jotka tuottavat binäärimuotoisia konfiguraatiotiedostoja. Näitä ohjelmistoja kannattaa välttää, mikäli mahdollista.

Automaation ylläpitäminen on myös työlästä, eikä jokainen kehittäjä välttämättä jaksa opetella miten automatisointi toimii. Tämä saattaa hidastaa projektin toimintaa, mikäli kaikkien kehittäjien on kuitenkin pakko opetella automaation salat tai mikäli kehittäjien pitää odotella erikoistuneita asennusautomaation tekijöitä.

Puhtaan pöydän lähestyminen

Asennusautomaation voi hoitaa kahdella tavalla, joko 1) automatisoimalla asennukset aina niin, että kaikki tehdään täysin puhtaalta pöydältä tai 2) niin, että asennuksissa jatketaan aina edellisen asennuksen tuottamasta tilasta.

Jos suinkin vain on mahdollista, kannattaa asennukset suorittaa aina puhtaalta pöydältä. Aina tätä vaihtoehtoa ei varmasti ole, mutta mikäli asennusautomaation ei tarvitse välittää edeltäneistä asennuksista, saadaan varmemmin täsmälleen haluttu lopputulos. Mikäli uusimman version asennus riippuu aina edellisen version asennuksesta, on migraatioskriptien luominen työlästä ja virheherkkää. Lisäksi kaikki sovellusversiot pitää asentaa tietyssä järjestyksessä kaikkiin ympäristöihin, koska migraatioskriptejä ei yleensä voi laatia toimimaan yhteensopivasti minkä tahansa lähtötilanteen kanssa. 

Jos puhtaan pöydän lähestymistapaan päätyy, on syytä varoa kahta asiaa.
  • Sovelluksen pitää toimia, vaikka sovelluksella ei ole käytössä aiemmin kerättyä dataa. Sovelluksessa voi olla esimerkiksi sisäisiä tarkistuksia, jotka olettavat, että sovelluksella on tietty määrä vanhaa kertynyttä dataa käytössä, mutta näinhän ei ole puhtaalta pöydältä lähdettäessä
  • Mikäli sovellus tallettaa aiemman käytön perusteella mitä tahansa tilatietoja, täytyy tila siirtää puhtaalta pöydältä asennettuun ympäristöön. Tällaista tilaa voi olla esimerkiksi lokitiedot.
Mitenkä asennukset sitten valitseekaan tehtäväksi, kannattaa varoa tallettamasta tilatietoja liian moneen paikkaan. Esimerkiksi erillisen tietokantapalvelimen ylläpito on paljon helpompaa kuin pyörittää tietokantaa ja sovellusta samalla koneella. Mikäli koko sovellus halutaan esimerkiksi asentaa puhtaaseen ympäristöön, mutta vanha data halutaan säilyttää, pitää tieto siirtää vanhasta ympäristöstä uuteen asennuksen yhteydessä. Mikäli käytetään erillistä tietokantapalvelinta, ei uuden version asennuksessa tarvitse tehdä mitään vanhan tiedon siirtämistä. Sama ajatus pätee pienempiinkin ympäristöihin, joissa ei pelata erillisillä koneilla: mieti aina minne tilan tallennat.

Automaation hyödyt

Mielestäni suurin hyöty automatisoidusta asennuksesta on työn mielekkyyden ylläpitäminen. Harvaa kiinnostaa saman rutiiniasian huolellinen toistaminen päivästä toiseen. Tästä seuraa asennuksen muut hyvät puolet.
  • Koska rutiinin toistamiselta ihmisivoimin vältytään, asennuksien laatu paranee.
  • Automatisoitu asennustapa on aina nopein, koska hidasta ihmistä ei tarvitse painelemaan nappeja.
  • Asennuksien dokumentaatio on aina ajan tasalla, koska kenenkään ei tarvitse päivittää ihmisen seurattavaa dokumentaatiota: asennusskriptit ovat asennukselle sama asia kuin ohjelmakoodi sovellukselle!
  • Projektin riippuvuus yksittäisistä ihmisistä vähenee, koska uuden version asennus ei vaadi asentajien paikalla oloa
  • Virheet korjataan täsmälleen kerran asennusautomaatioon eikä virheitä ja niiden ratkaisuita tarvitse muistaa joka asennuksen yhteydessä
  • Osaamisen siirto on helppoa, koska osaamisen siirrossa riittää pitkälti se, että selittää miten asennusautomaatio toimii. Yksityiskohdat näkee skripteistä

Automaation ongelmat

Automaation näkyvin ongelma lienee se, että jostain pitää projektin alkupuolella löytää aika automaation toteuttamiseen ja sen jälkeen ylläpitoon. Väitän, että aikaa ei kokonaisuudessaan mene enempää kuin työn tekemiseen käsin joka kerta, mutta tämä on vain näppituntumatietoutta. 

Automatisoitujen asioiden muuttaminen projektin paniikkitilanteissa, kuten järjestelmän tai tuotantoasennuksen yhtäkkisen sekoamisen yhteydessä on aivan liian hidasta. Pelastuskeinona paniikkitilanteissa voi käyttää asioiden selvittämistä käsityönä ja automatisoimista myöhemmin. 

Automatisoinnissa on riskinä, että projektin alussa valitaan väärä automaatiotapa ja toteutus menee hukkaan. Mikäli automatisointitoteutus joudutaan vaihtamaan kesken projektin, on se kuitenkin helpompaa kuin automaation tuominen kokonaan puhtaalta pöydältä aiemmin käsin asennettuun sovellukseen. Näin siksi, että vanha, vaikkakin huono, automaatio sisältää kaiken tarvittavan tiedon uudelle toteutukselle.

Täydellisesti automatisoitu asennus voi mennä täydellisesti metsään, jos toteutus ei tarkista asennuksen onnistumista sen edetessä. Hyvä virheen käsittely toki auttaa useimmiten. Vanha totuus on kuitenkin se, että mitenkään ei voi päästä niin suuriin ongelmiin kuin automaattisesti etenemällä (vrt. autonavigaattori vs. paperikartta). Asennuksen pitää siis kertoa kohtaamistaan ongelmista heti ja jäädä odottamaan ylläpitäjän korjaustoimenpiteitä.

Automaation sopivuus erilaisiin projekteihin

Uskon, että asennusautomaatio maksaa itsensä takaisin projektissa kuin projektissa. Ainoa mieleen tuleva poikkeus voisi olla joku start-up-projekti, missä kerta kaikkiaan kaikki resurssit on pakko laittaa yhden ainoan sovelluksen mahdollisimman pikaiseen tuottamiseen. Itse en ole tällaista projektia ikinä kokenut, joten mahdoton sanoa onko näin. Projektin asennusautomaatio kannattaa hoitaa kuntoon, niin pääsee keskittymään projektin oikeisiin ongelmiin!

tiistai 3. huhtikuuta 2012

Using Apache as reverse proxy through HTTP and HTTPS


HTTP reverse proxying


The ultimate goal is to reverse proxy SSL secured web site over Apache installed on Ubuntu server. This means that we are using Apache to serve content from a remote web site in a way that browser thinks its getting the data from our Apache and the remote web site thinks our Apache is a browser accessing the site data.

Let's start with reverse proxying without SSL. These instructions work on a fresh Ubuntu 10.04 installation (I'm using an image from Amazon Web Services). First install Apache.
$ sudo apt-get install apache2

Install mod_proxy_html on Apache.
$ sudo apt-get install libapache2-mod-proxy-html

It seems that this command also enables the mod_proxy_html automatically:
$ ls /etc/apache2/mods-enabled/proxy_html.*
/etc/apache2/mods-enabled/proxy_html.conf  /etc/apache2/mods-enabled/proxy_html.load

Enable the modules needed by proxying.
$ sudo a2enmod proxy_http
$ sudo a2enmod headers

Disable default site that comes with Apache installation.
sudo a2dissite 000-default

Create reverse proxy configuration. Add the following to file /etc/apache2/sites-available/reverseproxy
<VirtualHost *:80>
  ServerAdmin webmaster@localhost

  ErrorLog /var/log/apache2/reverseproxy_error.log

  # Possible values include: debug, info, notice, warn, error, crit,
  # alert, emerg.
  LogLevel info

  CustomLog /var/log/apache2/access.log combined

  # We're not an open proxy
  ProxyRequests off

  # Proxying is available for anyone
  <Proxy *>
    Order deny,allow
    Allow from all
  </Proxy>

  # The site we're proxying through http://oursite.fi/proxytest/
  ProxyPass /proxytest/ http://www.iltalehti.fi/
  ProxyPassReverse /proxytest/ http://www.iltalehti.fi/

  # Use mod_proxy_html to rewrite URLs
  SetOutputFilter proxy-html
  ProxyHTMLURLMap http://www.iltalehti.fi /proxytest
  ProxyHTMLURLMap  /      /proxytest/

  # Disable compressed communication between Apache and target server
  RequestHeader    unset  Accept-Encoding
</VirtualHost>

Enable our reverse proxy site and restart Apache
$ sudo a2ensite reverseproxy
$ sudo service apache2 restart
Now you should be able to see Iltalehti (http://www.iltalehti.fi) through your site under /proxytest.

Securing proxied connection with SSL (HTTPS reverse proxying)


Create self signed certificates. These commands are explained on page https://help.ubuntu.com/10.04/serverguide/C/certificates-and-security.html
$ openssl genrsa -des3 -out server.key 1024
$ openssl rsa -in server.key -out server.key.insecure
$ mv server.key server.key.secure
$ mv server.key.insecure server.key
$ openssl req -new -key server.key -out server.csr
$ openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
$ sudo cp server.crt /etc/ssl/certs
$ sudo cp server.key /etc/ssl/private

Disable plain HTTP based reverse proxy.
$ sudo a2dissite reverseproxy

Add the following to file /etc/apache2/sites-available/reverseproxy-ssl.
<VirtualHost *:443>

  ServerAdmin webmaster@localhost

  ErrorLog /var/log/apache2/reverseproxy-ssl_error.log

  # Possible values include: debug, info, notice, warn, error, crit,
  # alert, emerg.
  LogLevel info

  CustomLog /var/log/apache2/access-ssl.log combined

  # We're not an open proxy
  ProxyRequests off

  # Proxying is available for anyone
  <Proxy *>
    Order deny,allow
    Allow from all
  </Proxy>

  # The site we're proxying through http://oursite.fi/proxytest/
  ProxyPass /proxytest/ https://www.veikkaus.fi/
  ProxyPassReverse /proxytest/ https://www.veikkaus.fi/

  # Use mod_proxy_html to rewrite URLs
  SetOutputFilter proxy-html
  ProxyHTMLURLMap https://www.veikkaus.fi:443 /proxytest
  ProxyHTMLURLMap https://www.veikkaus.fi /proxytest
  ProxyHTMLURLMap  /      /proxytest/

  # Disable compressed communication between Apache and target server
  RequestHeader    unset  Accept-Encoding

  #   SSL Engine Switch:
  #   Enable/Disable SSL for this virtual host.
  SSLEngine on

  # Allows the proxying of an SSL connection
  SSLProxyEngine On

  # A self-signed certificate
  SSLCertificateFile    /etc/ssl/certs/server.crt
  SSLCertificateKeyFile /etc/ssl/private/server.key
</VirtualHost>

Enable HTTPS based reverse proxy.
$ sudo a2enmod ssl
$ sudo a2ensite reverseproxy-ssl
$ sudo service apache2 restart

Now you should be able to see Veikkaus (https://www.veikkaus.fi) through your site under path /proxytest.

tiistai 6. maaliskuuta 2012

Jaettu lähdekoodin omistajuus - miksei jaettu tuoteomistajuus?

Kuulen erittäin usein ihmisten hehkuttavan kuinka maailma on parempi, mikäli kaikki versionhallinnassa oleva lähdekoodi on kaikkien muokattavissa. Projektipäälliköt ja tuotepäälliköt erityisesti ovat innoissaan siitä, että kun lähdekoodi on kaikkien muokattavissa, projekteihin ei pääse muodostumaan pullonkauloja kiireisimpien ihmisten kohdalle. Kuka tahansa projektin kehittäjä kun voi muokata mitä tahansa ominaisuutta!

Koska lähdekoodin muokkaaminen käy keneltä tahansa, niin voisiko tuoteomistaja ja projektipäällikkökin olla vain resurssi muiden joukossa. Jos yrityksessä on useampi tuoteomistaja tai projektipäällikkö, voidaanko näistä ihmisistä ottaa kuka tahansa vastaamaan tuotteita tai projekteja vaivaaviin kysymyksiin? Jos tuotepäälliköltä kysyy, niin vastaus on useimmiten ei. Eihän muut tuotepäälliköt välttämättä tunne tuotetta niin hyvin eivätkä tuotteeseen halutut ominaisuudet ole kaikkien tiedossa yhtä kirkkaasti. Projektipäällikkö puolestaan helposti toteaa, että pitäähän sitä tuntea projektin sidosryhmät ja aikataulut sekä muut vaatimukset, että voi tehdä hyviä päätöksiä. Todettakoon, että en ole tehnyt aiheesta kattavaa kyselyä ja siksi en tiedä kuinka moni tuotepäällikkö tai projektipäällikkö esittämälläni tavalla ajattelee.

Oletetaan nyt kuitenkin, että edellisessä kappaleessa esittämäni arvaukset ovat totta ja tuoteomistajat sekä projektipäälliköt eivät pidä järkevänä geneeristen tuoteomistaja- ja projektipäällikköresurssialtaiden luomista. Onko sovelluskehittäjän työ sitten niin yksinkertaista ja rutiininomaista, että kuka tahansa voi tehdä muutoksia mihin tahansa tuloksen säilyessä hyvänä? Olettavatko kaikki ei-sovelluskehittäjät näin? Olettavatko monet sovelluskehittäjät, että näin on? Miksei sovelluskehittäjän tarvitse tuntea eri ominaisuuksien taustoja tai tulevia tarpeita, jos kerran asiasta päättävien tarvitsee?

Myönnän, että suuri osa lähdekoodin kirjoittamisesta on täysin rutiininomaista ja tylsää puuhastelua, johon pystyy lähes kuka tahansa sovelluskehittäjä, mikäli välineet ovat tuttuja. Silti väitän, että rutiininomaisesta puuhastelusta syntyy hyvin nopeasti kokonaisuuksia, joita ei ymmärrä, ellei ole tekemisissä kyseessä olevan lähdekoodin kanssa tarpeeksi ja ajallisesti lähellä. On helppo tehdä muutaman rivin muutoksia yksinkertaisiin ominaisuuksiin. Sen sijaan ei ole helppoa tehdä isompia muutoksia saati pystyä johdonmukaisesti muuttamaan isompia kokonaisuuksia, mikäli ei tunne vanhaa toteutusta.

Ihmettelen myös sitä, että jaetussa lähdekoodin omistajuudessa ei kukaan tunnu tietävän keneltä voisi kysyä, mikäli joku asia ei toimi. Joskus vastaus tähän ongelmaan on se, että koska kaikki on kaikkien muokattavissa, niin voit korjata ongelman itse. Tämähän toimii mainiosti, mikäli ongelman hoksaa ajoympäristöjen ylläpitäjä, testaaja tai loppukäyttäjä - eikö vain? Mitä isompi ryhmä vastaa tuotteen toteutuksesta, sen vaikeampi on löytää ihmistä keneltä voi kysyä. Yleensä tekijätkään eivät hetken päästä muista mitä kaikkea ovat toteuttaneet ja minne, koska yksityiskohdat tuppaavat unohtumaan. Vastaava ongelma kohdattaisin nopeasti, mikäli eri tuoteomistajat tai projektipäälliköt joutuisivat vastailemaan erikseen samoihin kysymyksiin: vastaukset olisivat 100% varmuudella erilaisia.

Minun mielestäni on hyvä, että ihmiset tietävät noin suunnilleen mistä palikoista he ovat vastuussa. Tämä tarkoittaa myös sitä, että he muokkaavat tiettyjä lähdekoodin osia pääosin itse ja vastaavat muidenkin tekemistä muutoksista vastuullaan oleviin osiin. Kaikki saavat muokata kaikkea, mutta kaikille osille pitää löytyä selkeät vastuulliset. Eri vastuualueiden välistä raja-aitaa voi helposti pienentää koodikatselmoinneilla ja vastuuttamalla nimettyjä ihmisiä toistensa varahenkilöiksi lomien ja muiden poissaolojen ajaksi. Näin ainakin pari ihmistä kyttää jokaiselle alueelle tapahtuvia muutoksia.

Varsinkin hyvin suuren lähdekoodimäärän ylläpitämisessä ei ole mitään järkeä lähteä hajottamaan kaikkien tekemisiä kaikkialle, koska tällöin varmistetaan se, että oikeastaan kukaan ei kunnolla tunne mitään osaa järjestelmästä. Samalla muutokset rapauttavat järjestelmää kokonaisuutena, koska kukaan kehittäjistä ei välttämättä ymmärrä tai välitä kokonaisuudesta. Voidaan toki väittää, että kaikkien häärääminen kaikkialla pelkästään vahvistaa kokonaiskuvaa järjestelmästä. Isommissa järjestelmissä osaamista pitäisi kuitenkin yleensä olla tähtitieteellisen paljon, jotta ylläpitäjänä voi nopeasti hahmottaa sekä kokonaisuuden toiminnan että kaikki yksityiskohdat.

Projekteissa on usein mukana henkilöitä (useimmiten pitkään projektissa työskennelleet tai muuten vaan keskimääräistä pätevämmät kaverit), jotka pystyvät hallitsemaan erittäin laajoja kokonaisuuksia. Näille poikkeusihmisille ei tuota mitään ongelmia muuttaa koko lähdekoodimassaa koherentisti ja heille ei ole välttämätöntä rajata omaa hiekkalaatikkoa. Toisaalta, vaikka ko. ihmisille annetaan koko projektin lähdekoodiin vaikuttavia tehtäviä, pitää heidän silti muistaa myös keskustella muutoksista eri alueiden vastuullisten kanssa.

Jos tuoteomistajana tai projektipäällikkönä luet tätä tekstiä, niin mietihän seuraavan kerran kahdesti, kun joku tulee vouhottamaan jaetun lähdekoodin autuudesta. Vasta kun olet valmis antamaan tuotteesi tai projektisi muiden satunnaisesti johtamaksi, voit kirkkain silmin todeta jaetun lähdekoodin omistajuuden olevan absoluuttisesti hyvä asia.

maanantai 27. helmikuuta 2012

Cell based positioning with TK-202

The TK-202 tracker sends the mobile network data, when you configure it to reply in "SMS format" and request current location with smsone+password command.

The last four numbers in the SMS define MCC (Mobile Country Code), MNC (Mobile Network Code), LAC (Location Area Code) and Cell Id. The last two are in hexadecimal format. To find out the location of the tracker without GPS signal, you can use for example the following services:

  1. http://cellphonetrackers.org/gsm/gsm-tracker.php (before inserting the LAC and Cell Id, remember to convert them into decimal format!)
  2. http://www.track-position.com/loc?c=cellid-lac-mnc-mcc (replace word cell id and lac with decimal converted values; replace words mnc and mcc with their respective values)
  3. http://openbmap.org/api/getGPSfromCellular.html
  4. https://labs.ericsson.com/apis/mobile-location/ (requires registration)
  5. http://opencellid.org/ (requires registration)

sunnuntai 26. helmikuuta 2012

TK-202 tracker

TK-202 tracker
Be warned: this blog post is not about software. It's about hardware!

Here's some usage instructions for TK-202 (or TK202) tracker manufactured by Xexun. Although Xexun offers user manuals on their web site, the manuals are far from perfect. By combining different manuals for different products, you can find almost all the information written below.

Some comments about the tracker

It seems that the tracker stays functional over 30 hours if it's only using GPS and GSM connections. I haven't tried to use it with the home station that would allow the tracker to shut down GPS (and maybe even GSM) modules.

The TK-202 is quite well built. However, it has some features I don't like too much. First of all, you cannot change the time or date shown by the watch. When TK-202 has a GPS signal, it sets the time automatically to the current time. I guess it should also change the date according the the GPS data, but I have never seen it working. The time is set to UTC (GMT) time and user has to configure the offset from UTC time to get the local time correctly shown.

Another disturbing feature is that the small buttons the watch has are very difficult to operate. If you manage to press the buttons, you don't get any feedback from the watch. There are two buttons on the side of the watch. One of them sends SOS message and the other shows current tracker coordinates. To show the current tracker coordinates, you need to hold down the coordinate switching button for a couple of seconds. If the tracker doesn't know it's coordinates, it just shows blank screen. When coordinates are shown, the tracker displays them with blue back light on the screen. You can easily send an SOS message by pressing a button, but there's no way to tell whether the watch really has sent the SOS message or not. To turn the tracker on and off, you have to hold down the both buttons simultaneously for some seconds. It seems that you must press the coordinate switching button just before pressing the SOS button. Otherwise the tracker just sends the SOS message and doesn't turn off. Even when the tracker is turned off, it uses a lot of battery.

Small side buttons
The worst feature of TK-202 is that it's quite bad in locating itself. I have been walking with the tracker by the sea (guaranteeing that there's nothing that could disturb the GPS signal) for more than half an hour and the tracker hasn't been able to find its location. If the tracker looses the GPS signal, it may not be able to recover or the recovery takes ages.



General  instructions for using SMS commands
The + sign used in the tracker SMS commands means that the text should be catenated together without any other characters such as space.

After each command, the tracker sends some form of OK message. Don't try to send more than one command at a time.

Tracker initialization

begin+password

When the tracker is in default configuration (first time use), the command is the following.

begin123456

Send this command after the tracker has acquired its position for the first time.

Changing the password
To change the default password, use the following command.

password+old password+space+new password

For example to change password from 123456 to 654321, send the following SMS.

password123456 654321

Adding authorized phone numbers
Authorized phone numbers are allowed to query tracker's position either by SMS or call (depending on the operating mode). Although authorization is required by some TK-202 features, it's generally not mandatory. To make all features easily  accessible from your own cell phone, you may authorize it (and by doing this, you also block random people from accessing your tracker).

admin+password+space+cell phone

For example, to authorize Finnish cell phone number 040 1234567 so that it would work also outiside Finland (i.e. using international format, the Finnish country code is +358), you could use the following.

admin123456 00358401234567

Note that the + sign is coded as double zeroes! The rest of the authorized numbers (there may be five at most) must be configured by the first authorized number.

To remove one authorized number,  send the following SMS (I haven't tried this).

noadmin+password+space+authorized number

To remove all authorized numbers, use normal begin command that was used when the tracker was taken into use (I haven't tried this). For example.

begin123456

Changing answering modes (positioning, monitoring, two-way calling)

For some reason the TK-202 manual does not tell how to set up two-way calling mode. This is weird, because on of the selling points of TK-202 is definitively the two way calling feature (I haven't found many watch trackers with microphone and loudspeaker that would allow user to make two way calls)!

There are three modes in TK-202 that I'm aware of: tracking, monitoring and two-way talk. When the tracking mode is on, the tracker sends its position as SMS when it's being called by an authorized number. In monitoring mode, the tracker hangs up when called by an authorized number and calls back automatically. When call is answered, the authorized caller is able to hear what's happening in the surroundings of the tracker. In two-way talk mode, a call from authorized number is automatically answered by the tracker and the caller and the person carrying the tracker may talk to each other. Here's how to change between the modes.

tracker+password
monitor+password
talk+password

For example.

tracker123456
monitor123456
talk123456

In my opinion, both the monitoring and two-way talking are very well implemented. There is a faint echo on the line, but it's still very easy to communicate.

Changing the time zone (to set the time shown by LCD display)


The tracker is showing time in UTC time, if not changed by configuration. You can set the time difference between UTC and local time with this command.

time zone+password+space+GMT time

For example, for Finnish winter time, you should use the following.

time zone123456 2

Use negative numbers for time zones "before" UTC.


Changing the SMS format sent by the tracker

This is also something that's completely missing from the TK-202 manual. User is allowed to change the format of the SMS sent by the tracker. Here's some instructions.

To get one Google map link from the tracker, send the following message.

smslinkone+password

To get the results always in Google maps format, send the following message.

smslink+password

To get the results always in plain SMS format (default mode), send the following message (I haven't tried this).

smstext+password

It's also possible to get a single SMS formatted message.

smsone+password

Tracking periodically

You can configure the tracker to send multiple location SMSs with one command. You can specify how many location messages you want and how often these messages should be sent. However, it seems that the tracker is somehow failing to count the number of messages correctly and you may get more messages than you requested.
The command form is the following.

tXXXsYYYn+password

The part XXX is number of seconds, minutes or hours that the tracker should wait between the messages. Replace s with m to get minutes and h to get hours, respectively. The YYY part is the total number of messages the tracker should send. Both XXX and YYY have range of 001 - 255 and you must always use three digits.

To turn of periodic tracking, use this command.

notn+password

Some features to be tried later

TK-202 may have the following features that I haven't tried them yet (I'm not sure as I found these from manuals for other products).

  1. tlimit+password+space+distance in meters (for example tlimit123456 50)
    • This command should set the tracker to alarm if it is being moved more than 50 meters away from the point where the command was given. Distance of 0 meters will cancel the warning.
  2. GpsAutoSearch+password+space+120 (for example GpsAutoSearch123456 120)
    • This command should change the refreshing frequency of GPS measured coordinates in seconds. The accepted values are between 120 - 600 seconds.
  3. restart+password (for example restart123456)
    • This command should remotely restart the tracker. Perhaps useful in some situations
    • I tried this once and the tracker stopped functioning. The only way to get it working again was to remove the battery
  4. volume+password+number
    • This command should change the loud speaker volume. Accepted range is 0 to 99.
  5. Some other commands? Geofencing is also interesting, but not useful for me...
Battery cover
Battery front
Battery back