PROJET AUTOBLOG


Shaarli - Les discussions de Shaarli

Archivé

Site original : Shaarli - Les discussions de Shaarli

⇐ retour index

Twitter Bootstrap Now Powering 1% of The Web | meanpath

dimanche 28 juillet 2013 à 21:56
Colibri, le 28/07/2013 à 21:56
Impressionnant !
(Permalink)

Sails.js | Realtime MVC Framework for Node.js

dimanche 28 juillet 2013 à 21:53
Colibri, le 28/07/2013 à 21:53
Sails.js make it easy to build custom, enterprise-grade Node.js apps. It is designed to mimic the MVC pattern of frameworks like Ruby on Rails, but with support for the requirements of modern apps: data-driven APIs with scalable, service-oriented architecture. It's especially good for building chat, realtime dashboards, or multiplayer games.
(Permalink)

La surveillance : Si vous n'avez rien à cacher, pourquoi vous inquiéter ? | HabiloMédias

dimanche 28 juillet 2013 à 21:51
Kevin Vuilleumier, le 27/07/2013 à 13:46
Cet article vous explique pourquoi il est important de s'inquiéter de tous types de surveillances, bien malgré le fait que « vous n'avez rien à cacher » !
(Permalink)

florian1, le 28/07/2013 à 21:51
(Permalink)

Recevez des notifications par email quand une mise à jour est disponible pour votre serveur Debian ou Ubuntu | crowd42crowd42

dimanche 28 juillet 2013 à 21:47
m0le, le 28/07/2013 à 18:51
Sympa ce "apticron". Il permet de surveiller votre serveur debian, et vous envoyer un mail lorsqu'il y a une mise à jour de disponible !
(Permalink)

Oros, le 28/07/2013 à 21:47
apt-get install apticron
nano /etc/apticron/apticron.conf

via http://shaarli.m0le.net/?X5pSUA
(Permalink)

Doxa #6 - La scolarité - YouTube

dimanche 28 juillet 2013 à 21:34
ex0artefact, le 28/07/2013 à 21:34
Toujours très intéressant.
(Permalink)

http://www.ldapguru.info/ldap/ldap-programming-practices.html

dimanche 28 juillet 2013 à 21:13
Manuel Flury, le 28/07/2013 à 21:13
sitemap | blog

LDAP Programming Practices
Introduction

This page delivers information about known best practices for dealing with LDAP servers (directory servers) from a programming point-of-view (with some design pointers for good measure). The information is drawn primarily from experiences where people got it wrong and obtained puzzling or incorrect results, unexplained application processing failures, poor performance, and a sub-standard user experience. Following each piece of advice to the letter is very important and will save programmers much trouble, time, and frustration in the future. Never cut corners with programming, the easiest or fastest way is rarely the best way.

It would be difficult to say which of the best practices listed herein is the most important, but it could be said that matching rules, the root DSE, schema familiarity, understanding of the available request controls, features, and extensions, remembering that attribute values and DNs are un-ordered (that is, the ordering is not repeatable), and never, ever reading back an entry that was just modified have to be close to the top of the list.
Summary
general

   always use LDAPv3
   always code to the LDAP standard documentation - this enhances the reusability of your code.
   never hard code attribute types or aliases
   use application-specific accounts
   use base-level scope when a DN is known and only the one entry is needed
   always check result codes (note that some non-zero result codes are not errors)
   always handle exceptions in a meaningful way
   always transmit passwords in clear-text on a secure connection so the server can check password quality and history
   always use an API that supports connection time-outs and response time-outs
   avoid hard-coding distinguished names in application code
   avoid storing large values in attributes
   before transmitting a request control check that the request control OID is handled by the server by checking for the existence of the OID of the request control in the supportControl attribute in the root DSE
   check for controls in responses and exceptions
   do not rely on names or values or availability of operational attributes, and do not hard-code names of attributes, DNs or expected values.
   do not use JNDI for new code, instead, consider using the UnboundID LDAP SDK for new code
   do not use Net::LDAP (perl) with threads - this API is not thread-safe
   ensure that your application can handle referrals
   ensure your application can handle an unsolicited notification from the server (unsolicited notifications are often sent when a server is shutting down, for example). UnsolicitedNotification.java contains an example of how to handle an unsolicited notification.
   if available, use the GetEffectiveRightsRequestControl to determine access rights for the authentication state of a connection
   make as few assumptions as possible about the directory server infrastructure (security, replication, namespace, operational attributes)
   minimize or avoid vendor-specific code
   never make assumptions about server software or server configuration. For example, I am told that AD imposes a size limit of 1000 out of the box. This might be well-known, but since it is not under programmer control, it is best not to make assumptions - Microsoft could change the size limit at any time. Recently I witnessed some application code failed because the code was written on the assumption that the server size limit was 2000 (something the developers had learned through tribal knowledge). The administrators, for reasons of their own, changed the size limit and the code failed
   notify directory server administrators of access control requirements ahead of time
   retrieve only the attributes that are required by the application
   understand and use the root DSE
   use connection pooling
   use matching rules to make attribute value comparisons and distinguished name comparisons - never use language-based equality comparisons or regular expressions applications that use language comparison operaters to compare data retrieved from a directory might be subject to unexpected errors
   use secure connections only - administrators should configure directory servers instances to accept only SSL connections and to reject any operation on an unsecure connection that is not a StartTLS operation
   use the post-read control to read back attributes after a modification or add - never search for an entry that was just modified or added
   when handling a referral, remember to bind
   when using LDAP transactions, understand that the server can abort a transaction without a client having requested the abort
   Use SSL in preference to StartTLS. Some information on the internet states that LDAP over SSL is deprecated. Those sites with that information are incorrect. StartTLS is less efficient than SSL (it requires at least one additional operation).

search

   always supply a non-zero client-requested size limit and time limit in a search request - never use a size limit of zero or a time limit of zero unless the application, network, and directory server can handle the number of entries that might be returned in the response. Be aware that application searches might be restricted at the server because they can affect other clients
   use the most restricted search scope possible
   do not rely on the order in which attributes and entries are returned

authentication

   use the Authorization Identity Request and Response Controls or Who am I? Operation extended operation to determine the authorization state of a connection

password

   understand the details of how zero-length passwords are handled by directory server
   where possible, use the LDAP: Password Modify Extended Operation to change passwords

schema

   use standard schema elements (the ones defined in the standards documents)
   get information about attributes from the schema
   understand attribute syntaxes, matching rules, and ordering rules
   avoid "MUST" (mandatory) attributes in new schema element design
   try to make new objectClasses AUXILIARY, not STRUCTURAL - this will enhance their reusability
   avoid the use of the extensibleObject objectClass unless there is no other way to accomplish the application's needs (see extensibleObject)

Prefer LDAP Version 3 in new code

LDAPv3 offers the following advantages over LDAPv2:

   LDAPv3 has more authentication mechanisms for the bind request
   LDAPv3 provides for extensions
   LDAPv3 supports attribute options, such as language tagging
   LDAPv3 supports attribute value size limits
   LDAPv3 supports paged results where the page size is determined by the client
   LDAPv3 supports the manageDSAIt extension
   LDAPv3 supports the newsuperior name for Modify DN operations; this means support for moving entire branches of the directory
   LDAPv3 uses UTF-8 for string values and distinguished names: this is more efficient than ASCII or T.61
   Naming contexts can be distributed and referrals are supported. This capability increases the flexibility of the architecture and simplifies application configuration because applications need not be configured to contact multiple servers in most cases

Do not use JNDI in new code

Java programmers should consider using the UnboundID LDAP SDK instead of JNDI for new code. The UnboundID LDAP SDK:

   is cleaner
   is clearer
   has support for failover and load-balancing
   has support for localization
   makes the use of matching rules easy
   supports a shorter learning curve, easier to use than JNDI
   supports asynchronous operations
   supports in-memory directory server, which can be useful in unit testing

JNDI has very little to recommend it, the available examples are horrible, it uses a disconnected parameter setting mechanism, it has a number of defects, and it uses a deprecated configuration. The UnboundID LDAP SDK supports sensible constructs for connection and LDAP operations. The following class provides a method that transmits a simple bind request to a server and also sets a response timeout.

/*
* Copyright 2008-2011 UnboundID Corp. All Rights Reserved.
*
* Copyright (C) 2008-2011 UnboundID Corp. This program is free
* software; you can redistribute it and/or modify it under the terms of
* the GNU General Public License (GPLv2 only) or the terms of the GNU
* Lesser General Public License (LGPLv2.1 only) as published by the
* Free Software Foundation. This program is distributed in the hope
* that it will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details. You
* should have received a copy of the GNU General Public License along
* with this program; if not, see http://www.gnu.org/licenses.
*/
package samplecode;


import com.unboundid.ldap.sdk.BindResult;
import com.unboundid.ldap.sdk.DN;
import com.unboundid.ldap.sdk.LDAPConnection;
import com.unboundid.ldap.sdk.LDAPConnectionOptions;
import com.unboundid.ldap.sdk.LDAPException;
import com.unboundid.ldap.sdk.SimpleBindRequest;
import com.unboundid.util.Validator;


/**
* Handles simple authentication on a connection to an LDAP server.
*/
@Author("terry.gardner@unboundid.com")
@Since("Dec 11, 2011")
@CodeVersion("1.0")
final class SimpleBindExample {


 BindResult authenticate(final LDAPConnection ldapConnection,final DN dn,
     final String password,final int responseTimeout) throws LDAPException {
   Validator.ensureNotNull(ldapConnection,dn,password);
   final SimpleBindRequest simpleBindRequest =
       new SimpleBindRequest(dn,password);
   final LDAPConnectionOptions connectionOptions = new LDAPConnectionOptions();
   connectionOptions.setResponseTimeoutMillis(responseTimeout);
   ldapConnection.setConnectionOptions(connectionOptions);
   BindResult result = ldapConnection.bind(simpleBindRequest);
   return result;
 }

}

The UnboundID LDAP SDK also provides packages that assist developers with migrating away from the Netscape LDAP SDK and JNDI.
Code to the published LDAP standard

Always write code that adheres to published LDAP standards. Avoid writing code that makes assumptions about the target directory server. If it is absolutely essential that features specific to a directory server be used, isolate the use of these features in the code. An example of this might be the use of the memberOf or isMemberOf attribute types. Another example would be the expectation that the server supports the numSubordinates attribute. Object-oriented programming languages make the process of encapsulating feature expectations a straightforward one.

Note that the LDAP standard expresses support for the vendorName and vendorVersion attributes the the Root DSE. Applications must not rely on the values contained in these attributes, and LDAP system administrators should configure access controls to prevent LDAP clients from retrieving these values.

Check with the Root DSE before using a request control or extension. If the OID does not appear in the Root DSE, do not use the control or extension.

Check the schema for attribute matching rules and do not, under any circumstances, perform bitwise or bytewise comparison of LDAP attribute values. Language comparison constructs such as == and = should not be used. AGAIN: applications must use matching rules to compare attribute values.
Understand and use the Root DSE

Consult the root DSE where necessary before making LDAP requests. Always check the root DSE before using an extension or request control. Read LDAP: The Root DSE for more information about the root DSE. The UnboundID LDAP SDK provides a class that encapsulates the root DSE, and a convenience methodLDAPConnection.getRootDSE().

Attributes that might be present in the root DSE:

   altServer - the URI of alternative servers
   namingContexts - suffixes hosted or shadowed by the server
   supportedControl - request controls recognized by the server
   supportedExtension - extended operations recognized by the server
   supportedLDAPVersion - LDAP versions recognized by the server
   supportedSASLMechanisms - SASL mechanisms recognized by the server
   vendorName - the name of the LDAP server vendor applications that depend on values of this attribute tend to be fragile, brittle, and resistant to change
   vendorVersion - software version of the LDAP server applications that depend on values of this attribute tend to be fragile, brittle, and resistant to change

Using the UnboundID LDAP SDK to check whether the OperationPurposeRequestControl is supported by the server:

LDAPConnectionPool ldapConnectionPool;
final boolean useOperationPurposeRequestControl;
try {
 final int initialConnections = 4;
 final int maxConnections = 6;
 ldapConnectionPool =
     new LDAPConnectionPool(getConnection(),
                            initialConnections,
                            maxConnections);

 /*
  * Determine whether the server supports the
  * OperationPurposeRequestControl:
  */
 final String controlOID =
     OperationPurposeRequestControl.OPERATION_PURPOSE_REQUEST_OID;
 useOperationPurposeRequestControl =
     ldapConnectionPool.getRootDSE().supportsControl(controlOID);
} catch (final LDAPException ldapException) {
 ldapException.printStackTrace();
 return null;
}

Prefer matching rules for comparisons

Code should use matching rules to make comparisons between attributes values, or between distinguished names. The directory server uses matching rules to match DNs and attribute values (for example, when matching values for fulfilling search requests), therefore, applications must use matching rules when comparing values. Failure to use matching rules can result in unexpected results.

For example, consider the following distinguished names:

'uid=user.0,ou=people,dc=example,dc=com'

and

'uid=user.0, ou=people, DC=example, DC=com'

These two DNs are equivalent, differing outwardly by case and spaces, but an application executing a character-by-character comparison would not consider the two to be the same (and would thus be incorrect). The use of matching rules prevents this error.

For further discussion and examples, see LDAP: Matching Rules. Application APIS that do not support matching rules should not be used for mission-critical and non-trivial LDAP work.
Prefer connection pooling to individual connections

Applications should use connection pooling instead of individual connections for performance reasons and applications should re-use connections wherever possible to avoid the performance cost of establishing TCP/IP connections and secure connection handshakes. The UnboundID LDAP SDK provides an LDAPConnectionPool class which encapsulates connection pooling services. Application coders should determine, if necessary, the authorization state of a connection using the Authorization State Request Control or the Who am I? extended operation. See the example code.

Example of creating a connection pool using the UnboundID LDAP SDK:

LDAPConnectionPool connectionPool(final String hostname,
                               final int port,
                               final int initialConnections,
                               final int maxConnections)
 throws LDAPException {
   if(initialConnections <= 0) {
     throw new IllegalArgumentException(initialConnections +
         "is not a legal value for 'initialConnections'");
   }
  if(maxConnections <= 0) {
     throw new IllegalArgumentException(maxConnections +
         "is not a legal value for 'maxConnections'");
   }
   final LDAPConnection ldapConnection =
         new LDAPConnection(hostname,port);
   return new LDAPConnectionPool(ldapConnection,
                                 initialConnections,
                                 maxConnections);
}

Use application-specific accounts

Directory administrators and programmers should use application-specific authentication accounts instead of sharing accounts amongst applications, or even worse, using the rootDN. By contrast, application-specific authentication:

   access controls can be employed on an application-by-application basis
   applications can be limited in their interaction with directory server
   audits are more accurate and more meaningful. The UnboundID Directory Server supports Client Connection Policies which allow directory security professionals to limit the resources used by applications in very granular ways, for example:
   ensures that operations can be tracked easily in logs
   impose an application-specific size limit
   impose an application-specific time limit
   limit the amount of time a connection can be idle before it is terminated
   limit the duration of a connection
   limit the maximum number of concurrent connections
   limit the number of concurrent operations per connection
   limit the number of operations per connection
   limit the types of extended operations
   limit the types of operations (bind, search, add, etc)
   limit the types of request controls

Do not rely on ordering of entries and attributes

Applications must not rely on the ordering of entries, attributes, attribute options, and attribute values in a search request. See also LDAP: Attributes Are Not Ordered.

Entries, attributes, and attribute values can be returned in any order (that is, the ordering is not repeatable); entries, attributes, and attribute value ordering can change from one request to the next. Encapsulate search responses with listeners or callbacks to isolate attribute ordering variations from the main flow of the application code.
Check for controls in responses

Directory servers can attach response controls to most responses. A response control is a piece of data attached to a response. Always check for controls in a response and handle response controls with listeners or callbacks to isolate the processing of response controls from the application. Request controls should be listed as values for the supportedControl multi-valued attribute in the root DSE, but response controls need not be enumerated in the Root DSE. Programming APIs that do not support LDAP controls should probably not be used in non-trivial or mission-critical code.

Example of important response controls are password expired controls attached to bind responses and sort controls.

See also: The Root DSE
Use the post-read control instead of retrieving an entry after a modification

Always use the post-read control to verify updates instead of a search after an update. The post-read control is designed so that applications need not issue a search request after an update – it is bad form to retrieve an entry for the sole purpose of checking that an update worked because of the replication eventual consistency model and one of top causes of failures of LDAP applications. Even some poorly-designed commercial software makes this error. Never assume that your LDAP client connects to the same directory server for each request because architects may have placed load-balancers or LDAP proxies or both between LDAP clients and servers. Example:

 private void addDescriptionValues() {
   final List mods = new ArrayList();
   mods.add(new Modification(ModificationType.ADD,
                             "description",
                             "description 1"));
   mods.add(new Modification(ModificationType.ADD,
                             "description",
                             "description 2"));
   final ModifyRequest modifyRequest = new ModifyRequest(entry,mods);
   modifyRequest.addControl(new PreReadRequestControl("description"));
   modifyRequest.addControl(new PostReadRequestControl("description"));
   try {
     final LDAPResult result = ldapConnectionPool.modify(modifyRequest);
     final String preReadResponseControlOid =
         PreReadResponseControl.PRE_READ_RESPONSE_OID;
     if(result.hasResponseControl(preReadResponseControlOid)) {
       final Control c = result.getResponseControl(preReadResponseControlOid);
       final ReadOnlyEntry e = ((PreReadResponseControl)c).getEntry();
       System.out.println("the entry pre-modify:" + e);
     }
     final String postReadResponseOid =
         PostReadResponseControl.POST_READ_RESPONSE_OID;
     if(result.hasResponseControl(postReadResponseOid)) {
       final Control c = result.getResponseControl(postReadResponseOid);
       final ReadOnlyEntry e = ((PostReadResponseControl)c).getEntry();
       System.out.println("the entry post-modify:" + e);
     }
   } catch (final LDAPException lex) {
     lex.printStackTrace();
   }
 }

The example above modifies and entry and attaches the pre-read and post-read request controls to the MODIFY request. The above method is the correct way of getting attributes from an entry that was just modified.
Passwords

If the directory server supports password-quality checks, passwords should be transmitted in clear text over a secure connection because the server will not be able to check password quality and history otherwise. Secure connections should be preferred for all LDAP interaction.

Directory Server security professionals should require that LDAP servers reject all requests except for the StartTLS request on non-secure connections.

See also authentication best practices.
Operational Attributes

Application code must not rely on the names or values of operational attributes, and applications must not attempt to modify the value of an operational attribute. Applications must not rely on being able to retrieve operational attributes from the directory – directory administrators can restrict access to operational attributes. Note that RFC4512 states that directory servers should maintain operational attributes like modifyTimestamp, not that they must maintain them. There are three different varieties of operational attributes:

   directory
   shared
   specific

References
LDAP Standards Documents at the IETF

   LDAP: Protocol
   LDAP: Directory Information Models
   LDAP: Password Modify Extended Operation
   LDAP: Authorization Identity Request and Response Controls
   LDAP: Who am I? Operation
   LDAP: Read Entry Controls
   LDAP: StartTLS

Blog Entries

   LDAP: The Root DSE
   LDAP: Ordering
   Mastering ldapsearch
   Mastering search filters

UnboundID

   UnboundID Directory Server
   UnboundID LDAP SDK
   UnboundID Directory Proxy Server
   UnboundID Synchronization Server

Miscellaneous

   tribal knowledge

Last Update: 24-Feb-2013. © 2012-2013 Terry Gardner
(Permalink)

A l'eau quoi ? Cette voiture télécommandée roule à l'eau | Gizmodo

dimanche 28 juillet 2013 à 20:54
m0le, le 28/07/2013 à 19:15
Une voiture télécommandée qui roule uniquement à l'eau et pilotable par un smartphone. Fun :)
(Permalink)

vader, le 28/07/2013 à 20:54
Le vieux titre putassier de la voiture à l'eau.

"fonctionnant uniquement à l’eau" ahaha ಠ_ಠ

Ouais enfin avec de l'électricité venu de l'énergie solaire ou d'une autre source qui permet de changer l'eau en hydrogène/oxygène via électrolyse. Ca ne consomme pas que de l'eau quoi. Qu'est-ce que ça apporte de maintenir l’ambiguïté ? Enfin à part des clics je veux dire ?

Via http://shaarli.m0le.net/?Cf408Q
(Permalink)

Le fact checking sur le web francophone · Global Voices en Français

dimanche 28 juillet 2013 à 20:50
Valentin Champer, le 28/07/2013 à 19:19
(Permalink)

vader, le 28/07/2013 à 20:50
Article sur le fact checking.
Plus que jamais je pense qu'il est important d'interroger les informations que nous recevons et que nous partageons.

Via https://tviblindi.legtux.org/shaarli/?Itha2g
(Permalink)

sshuttle - VPN / SSH - Yop

dimanche 28 juillet 2013 à 20:48
m0le, le 28/07/2013 à 20:48
Tiens, c'est à tester ca .. sshuttle pour faire du pseudo vpn-tunneling. L'auteur l'utilise avec un raspberrypi, pas con.
(Permalink)

F-Droid · F-Droid Workshop – Berlin

dimanche 28 juillet 2013 à 20:47
la vache libre, le 28/07/2013 à 20:47
Si vous êtes sur Berlin et que vous ne savez pas quoi faire, F-Droid organise un Workshop. Ça peut être sympa si vous voulez bosser un peu. Connaissance du terminal GNU/Linux et de l'utilisation de GIT fortement recommandés.
(Permalink)

Back to Basis : Make - K-Tux

dimanche 28 juillet 2013 à 18:48
m0le, le 28/07/2013 à 18:48
Certe, ca ne sert pas souvent, mais je savais pas qu'on pouvait demander à "make" de s’exécuter en plusieurs jobs.
(Permalink)

Mock Response

dimanche 28 juillet 2013 à 18:37
Sebsauvage, le 23/07/2013 à 16:44
Un serveur web qui vous renvoie l'erreur HTTP de votre choix.
Exemple: http://mock.isssues.com/500
(Permalink)

Famille Michon, le 25/07/2013 à 13:35
Un serveur web qui renvoie le code HTTP voulu en fonction de l'URL appelée (ou répond longuement, voire en timeout)

Exemple : http://mock.isssues.com/200

(Un "mock" (ou "bouchon" en français) est un objet fictif qu'on utilise pour simuler le comportement de l'objet final (qu'on n'a pas encore codé) en respectant son API, mais en ne faisant rien derrière).
(Permalink)

Riduidel, le 28/07/2013 à 18:37
Chouette façon de tester un client HTTP tiens
(Permalink)

Energy Cycles

dimanche 28 juillet 2013 à 18:29
Mescanefeux, le 28/07/2013 à 18:29
(Permalink)

kraftysimmer:Peru recently announced that they intend to...

dimanche 28 juillet 2013 à 18:28
Riduidel, le 28/07/2013 à 18:28
Et pendant ce temps-là, la France n'a que très très peu de panneaux solaires
(Permalink)

Get Home Early

dimanche 28 juillet 2013 à 18:02
Riduidel, le 28/07/2013 à 18:02
Eh ouais : StackOverflow est en train de devenir plus important que maven central, plus important en fait que tous les autres sites d'informatique réunis. Et, ce qui fait plaisir, c'est que toutes les données sont accessibles sous licence creative commons
(Permalink)

Spaceships by Jong Won Park

dimanche 28 juillet 2013 à 17:51
Riduidel, le 28/07/2013 à 17:51
Très chouette série d'illustration
(Permalink)

Who needs health insurance??? I have Jesus | Dumb USA

dimanche 28 juillet 2013 à 17:44
Valentin Champer, le 28/07/2013 à 17:44
(Permalink)

Retro-Future: Glorious Urbanism

dimanche 28 juillet 2013 à 17:42
Riduidel, le 28/07/2013 à 17:42
Du vrai urbanisme science-fictif
(Permalink)

the miracle of life

dimanche 28 juillet 2013 à 17:38
Riduidel, le 28/07/2013 à 17:38
Ca me rappelle une série de dessins dans l'excellente BD Arthur, de Lereculley et Chauvel, où Arthur envisage d'ouvrir le ventre de sa Gwenifer pour découvrir l'être qui se développe en elle.
(Permalink)

Ik sta op de rand der wereld en roep: “Waar zijt Gij?” De echo antwoordt: “Zijt gij? Gij?”

dimanche 28 juillet 2013 à 17:37
Riduidel, le 28/07/2013 à 16:51
Très très chouette série de reproductions de tour de Babel. Le concept est beau, et les oeuvres tout autant.
(Permalink)

Oros, le 28/07/2013 à 17:37
Tien la Tour de Babel !

Ça me fait penser à la BD "La Tour" de François Schuiten ( http://www.altaplana.be/albums/la_tour )
C'est une très bonne BD.

Je vois recommande les œuvres de François Schuiten : https://fr.wikipedia.org/wiki/Fran%C3%A7ois_Schuiten

à voir aussi http://www.urbicande.be/
(Permalink)