Kevin Decherf's blog

Technologies de l'information … et plus si affinité

Oracle, I download your JDK by eating magic cookies

| Comments

Today, I had to install the SunOracle JDK on some servers, so I visited the JDK download page to retrieve the direct download link for wget on each server:

$ wget http://download.oracle.com/otn-pub/java/jdk/7u3-b04/jdk-7u3-linux-x64.rpm

After launching the command, the server redirects me to a 5K HTML file:

Location: http://download.oracle.com/errors/download-fail-1505220.html [following]

WAIT, WHAT? I can’t download the file if I don’t visit their download page to accept the OTN license.

Challenge accepted, I’m going to play with requests… What happens when I click on the archive link?

First request:

Request URL:http://download.oracle.com/otn-pub/java/jdk/7u3-b04/jdk-7u3-linux-x64.rpm
Request Method:GET
Cookie:s_nr=some_integer; s_cc=true; gpw_e24=http%3A%2F%2Fwww.oracle.com%2Ftechnetwork%2Fjava%2Fjavase%2Fdownloads%2Fjdk-7u3-download-1501626.html; s_sq=%5B%5BB%5D%5D

Okay, trying to play with cookie values (I deleted the useless values):

$ wget --no-cookies --header "Cookie: gpw_e24=http%3A%2F%2Fwww.oracle.com%2Ftechnetwork%2Fjava%2Fjavase%2Fdownloads%2Fjdk-7u3-download-1501626.html;" http://download.oracle.com/otn-pub/java/jdk/7u3-b04/jdk-7u3-linux-x64.rpm

--2012-04-12 18:47:58--  http://download.oracle.com/otn-pub/java/jdk/7u3-b04/jdk-7u3-linux-x64.rpm
Resolving download.oracle.com (download.oracle.com)... 24.29.138.48, 24.29.138.40
Connecting to download.oracle.com (download.oracle.com)|24.29.138.48|:80... connected.
HTTP request sent, awaiting response... 302 Moved Temporarily
Location: https://edelivery.oracle.com/otn-pub/java/jdk/7u3-b04/jdk-7u3-linux-x64.rpm [following]
--2012-04-12 18:47:59--  https://edelivery.oracle.com/otn-pub/java/jdk/7u3-b04/jdk-7u3-linux-x64.rpm
Resolving edelivery.oracle.com (edelivery.oracle.com)... 2.18.222.174
Connecting to edelivery.oracle.com (edelivery.oracle.com)|2.18.222.174|:443... connected.
HTTP request sent, awaiting response... 302 Moved Temporarily
Location: http://download.oracle.com/otn-pub/java/jdk/7u3-b04/jdk-7u3-linux-x64.rpm?AuthParam=THEIR_AUTHPARAM [following]
--2012-04-12 18:48:00--  http://download.oracle.com/otn-pub/java/jdk/7u3-b04/jdk-7u3-linux-x64.rpm?AuthParam=THEIR_AUTHPARAM
Connecting to download.oracle.com (download.oracle.com)|24.29.138.48|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 67667318 (65M) [application/x-redhat-package-manager]
Saving to: `jdk-7u3-linux-x64.rpm'

Fuck Yea.

More information

You can set what you want in gpw_e24, I think it’s a kind of referer. As for me, I’m using the download page URL.

According to the OTN BCL document for Java SE:

BY SELECTING THE “ACCEPT LICENSE AGREEMENT” (OR THE EQUIVALENT) BUTTON AND/OR BY USING THE SOFTWARE YOU ACKNOWLEDGE THAT YOU HAVE READ THE TERMS AND AGREE TO THEM.

Enjoy it!

Bonus

Rendre temporairement accessible un site hébergé sur sa machine

| Comments

Avec le passage de mon blog de Wordpress à Jekyll/Octopress, j’ai été confronté à un problème existentiel : comment diffuser un billet en cours de rédaction pour lecture “privée” sans le publier ?

Jekyll dispose d’un mode “serveur embarqué” afin d’avoir accès aux pages en local, il ne me reste plus qu’à supprimer la limite du réseau local et la version en développement pourra être accessible depuis les internets. A défaut d’avoir une adresse IPv6, qui arrangerait tous nos problèmes, nous avons plusieurs solutions à notre disposition pour rendre accessible sur la toile un site hébergé localement :

  • Redirection de port sur sa box, mais c’est une technique limitée à son propre réseau
  • Installation d’un VPN sur une machine distante, mais c’est sortir le char pour tuer une mouche
  • Utilisation d’un tunnel SSH, similaire dans l’idée à l’installation d’un VPN mais beaucoup plus simple à mettre en place

Bien entendu, je vais vous présenter la solution la plus portable : un tunnel SSH.

A ce stade vous pouvez y accéder via un port spécifique. Si vous souhaitez rendre accessible le site via un sous-domaine (ou un sous-dossier), la suite de l’article est pour vous.

Principe

Principe

Je pars du principe que nous disposons d’un serveur avec un serveur web qui écoute sur le port 80 et d’un laptop avec le serveur web local qui écoute sur le port 4000.

L’idée est de se servir d’un reverse proxy pour pouvoir mapper plusieurs serveurs web sur le même port et ainsi pouvoir jouer avec les domaines/sous-domaines pour rediriger correctement. Si vous êtes à l’aise avec Apache vous pouvez jouer avec, personnellement je préfère HAProxy.
Le reverse proxy va écouter sur le port 80 et diffuser les requêtes entrantes, en fonction de critères que nous allons définir plus bas, aux différents serveurs : le serveur web actuel peut écouter sur le port 127.0.0.1:80 (pour l’exemple) et vous réservez un port pour le tunnel SSH (8001 dans l’exemple). Ensuite ce tunnel SSH servira à faire communiquer le port local 8001 du serveur avec le port local 4000 du laptop.

Reverse proxy

La première étape est donc de migrer votre serveur web actuel sur un port local uniquement, si vous utilisez Apache Listen 127.0.0.1:80 fera l’affaire. Pensez à changer les directives VirtualHost et NameVirtualHost en conséquence.

Si vous utilisez HAProxy comme reverse proxy, la configuration pour notre exemple doit ressembler à ça :

[...]
frontend webfront
        bind ippubliqueduserveur:80

        default_backend cluster_local

backend cluster_local
        mode http
        option  httplog
        option httpclose        #Disable keepalive
        option forwardfor
        balance roundrobin
        server  apache 127.0.0.1:80 check inter 2000 rise 2 fall 5
        errorfile       400     /etc/haproxy/errors/400.http
        errorfile       403     /etc/haproxy/errors/403.http
        errorfile       408     /etc/haproxy/errors/408.http
        errorfile       500     /etc/haproxy/errors/500.http
        errorfile       502     /etc/haproxy/errors/502.http
        errorfile       503     /etc/haproxy/errors/503.http
        errorfile       504     /etc/haproxy/errors/504.http

Remarque : si vous ne précisez pas l’adresse IP publique du serveur, HAProxy va rentrer en conflit avec Apache en écoutant sur 0.0.0.0:80

Tunnel SSH

En suivant l’exemple, la commande ssh à lancer sur le laptop pour rediriger le port 8001 du serveur sur le port 4000 [du laptop] est :

ssh -N -R127.0.0.1:8001:127.0.0.1:4000 monserveur

Je vous laisse lire le manuel très complet pour comprendre les deux options utiles ;-)

Configuration du reverse proxy

Une fois que le tunnel est prêt, on peut finir la configuration du reverse proxy.

Dans l’exemple je vais rediriger preview.kdecherf.com vers le port 8001 (qui redirigera sur le port 4000 de mon laptop).

[...]

frontend webfront
        bind ippubliqueduserveur:80

        acl is_preview_kdecherf_com hdr_dom(host) -i preview.kdecherf.com

        use_backend cluster_preview if is_preview_kdecherf_com
        default_backend cluster_local

[...]

backend cluster_preview
        mode http
        option httplog
        option httpclose
        option forwardfor
        balance roundrobin
        server  rakeup 127.0.0.1:8081 check inter 2000 rise 2 fall 5
        errorfile       400     /etc/haproxy/errors/400.http
        errorfile       403     /etc/haproxy/errors/403.http
        errorfile       408     /etc/haproxy/errors/408.http
        errorfile       500     /etc/haproxy/errors/500.http
        errorfile       502     /etc/haproxy/errors/502.http
        errorfile       503     /etc/haproxy/errors/503.http
        errorfile       504     /etc/haproxy/errors/504.http

Pour résumer ce qui se passe :

  • Toutes les requêtes ayant pour host preview.kdecherf.com sont redirigées vers le cluster cluster_preview
  • Les autres requêtes (default_backend) sont redirigées vers le cluster cluster_local

Et voilà, tout simplement. Libre à vous d’ajouter des clusters et des ACL pour ajouter d’autres redirections et d’autres ports.

Quid du référencement

Tous ceux qui ont déjà mis en ligne une version de test d’un site ont surement connu cette sensation désagréable quand on remarque que Google est déjà passé par là (merci Chrome, entres autres). Plutôt que de devoir penser à mettre un robots.txt à chaque fois qu’on veut rendre accessible un site, on va plutôt utiliser une autre ACL d’HAProxy pour servir le fichier depuis un autre cluster :

[...]
frontend webfront
        bind ippubliqueduserveur:80

        acl is_preview_kdecherf_com hdr_dom(host) -i preview.kdecherf.com
        acl is_robots_txt path_beg /robots.txt

        use_backend cluster_local if is_preview_kdecherf_com is_robots_txt
        use_backend cluster_preview if is_preview_kdecherf_com
        default_backend cluster_local
[...]

Qu’est-ce qui se passe ? Si la requête a comme host preview.kdecherf.com et que le chemin commence par /robots.txt alors on redirige vers le cluster cluster_local. On met cette condition en premier car le premier bloc use_backend qui a toutes ses conditions vraies stoppe les tests (équivalent de [L] avec mod_rewrite). Sur le cluster local (Apache par exemple) on va ajouter un fichier robots.txt dans le dossier du VirtualHost par défaut pour ne pas dépendre du sous-domaine appelé.

Dans l’ordre, le test donne :

  • Si la requête a comme host preview.kdecherf.com et commence par /robots.txt alors on redirige vers cluster_local
  • Si la requête a comme host preview.kdecherf.com alors on redirige vers cluster_preview
  • Pour le reste on redirige sur cluster_local

Quid de la sécurité

Etant donné que seules les requêtes HTTP passent, les seules failles pouvant être exploitées lorsque vous diffusez votre site sont les failles de l’application elle-même. Alors faites attention ;-)

Quid des communications chiffrées

Si vous souhaitez mettre en place un accès HTTPS tout en ayant les ACL du reverse proxy, vous devrez utiliser une solution telle que STunnel en amont. En revanche si vous n’avez pas d’ACL à faire jusqu’à votre poste, vous pouvez activer HAProxy en mode TCP et gérer les communications SSL directement en local.

 

Et voilà, vous pouvez désormais diffuser une appli web locale :-)
Quand vous coupez l’accès au serveur local, le reverse proxy renverra une erreur 503 Service Unavailable jusqu’à sa prochaine apparition.

FFmpeg: converting M4A files to MP3 with the same bitrate

| Comments

Hello World,

Today I show you a (really) tiny tip to convert M4A files to MP3 keeping bitrate with FFmpeg.

By using the command ffmpeg -i thefile we obtain data about all streams of the file (codec, bitrate, …), like this:

$ ffmpeg -i test.m4a
[...]
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'test.m4a':
  Metadata:
    major_brand     : M4A 
    minor_version   : 1
    compatible_brands: M4A mp42isom
    creation_time   : 2012-01-06 13:08:47
    composer        : Tiësto
    title           : clublife_episode249
    artist          : Tiësto
    album           : Tiësto
    encoder         : GarageBand 6.0.4
  Duration: 00:59:04.87, start: 0.000000, bitrate: 324 kb/s
    Chapter #0.0: start 0.000000, end 31.000000
    Metadata:
      title           : Begin
    [...]
    Stream #0.0(eng): Subtitle: tx3g / 0x67337874, 0 kb/s
    Metadata:
      creation_time   : 2012-01-06 13:08:47
    Stream #0.1(eng): Subtitle: tx3g / 0x67337874
    Metadata:
      creation_time   : 2012-01-06 13:08:47
    Stream #0.2(eng): Audio: aac, 44100 Hz, stereo, s16, 319 kb/s
    Metadata:
      creation_time   : 2012-01-06 13:08:47
    Stream #0.3(eng): Video: mjpeg, yuvj444p, 300x300 [PAR 72:72 DAR 1:1], 2 kb/s, 0k fps, 600 tbr, 600 tbn, 600 tbc
    Metadata:
      creation_time   : 2012-01-06 13:08:47

Well, the line we need to use for the bitrate is Stream #0.2(eng): Audio: aac, 44100 Hz, stereo, s16, 319 kb/s. Now we can play with grep and awk to extract 319 (according to the example line):

$ ffmpeg -i test.m4a 2>&1 | grep Audio | awk -F', ' '{print $5}' | cut -d' ' -f1
319

This output will be used for the -ab argument:

ffmpeg -i test.m4a -ab `ffmpeg -i test.m4a 2>&1 | grep Audio | awk -F', ' '{print $5}' | cut -d' ' -f1`k test.mp3

Finally, we verify the new file:

$ ffmpeg -i test.mp3
[...]
Input #0, mp3, from 'test.mp3':
  Metadata:
    major_brand     : M4A 
    minor_version   : 1
    compatible_brands: M4A mp42isom
    creation_time   : 2012-01-06 13:08:47
    composer        : Tiësto
    title           : clublife_episode249
    artist          : Tiësto
    album           : Tiësto
    encoder         : Lavf53.2.0
  Duration: 00:59:04.93, start: 0.000000, bitrate: 320 kb/s
    Stream #0.0: Audio: mp3, 44100 Hz, stereo, s16, 320 kb/s

Enjoy it !

Iftop : utiliser l’interface par défaut

| Comments

Je ne poste pas souvent ces temps-ci, mais en ce début de week-end je vous offre une petite astuce pour iftop, l’utilitaire qui permet d’afficher en détail le traffic entrant et sortant d’une interface réseau.

Venant de migrer sur tmux, je me suis réservé une fenêtre pour iftop. Le soucis c’est qu’il faut préciser à chaque fois quelle interface doit utiliser ce dernier au lancement et je ne suis pas tout le temps sur un réseau filaire. Voilà une petite astuce pour contourner ce problème :

1
iftop -i `ip route | grep -E "^default" | awk -F' ' '{print $5}' | sed -n 1p`

Cette commande va récupérer l’interface par défaut via la table de routage. S’il y a plusieurs routes par défaut, on prend la première. A noter que je pars du principe que la route par défaut précise toujours une interface et que vous avez installé ip, exemple :

% ip route
default via 192.168.0.1 dev eth0  proto static

Enjoy it !