Browse Source

merge I guess??

master
parent
commit
0d68b4fd93
57 changed files with 802 additions and 13038 deletions
  1. +29
    -0
      content/email-security.md
  2. +30
    -0
      content/envie-partout-temps-nulle-part.md
  3. +63
    -0
      content/key_migration.md
  4. +9
    -0
      content/let's_encrypt.md
  5. +174
    -0
      content/openvpn-openbsd.md
  6. +42
    -21
      content/pages/about.md
  7. +30
    -0
      content/pocorgtfo.md
  8. +405
    -0
      content/redondance_de_routeurs,_avec_openbsd_et_freebsd.md
  9. +19
    -22
      pelicanconf.py
  10. BIN
      pelicanconf.pyc
  11. +0
    -1109
      themes/bootstrap2/static/css/bootstrap-responsive.css
  12. +0
    -6180
      themes/bootstrap2/static/css/bootstrap.css
  13. +0
    -7
      themes/bootstrap2/static/css/extra.css
  14. +0
    -1268
      themes/bootstrap2/static/css/font-awesome.css
  15. +0
    -70
      themes/bootstrap2/static/css/pygments.css
  16. +0
    -70
      themes/bootstrap2/static/css/pygments.css.bak
  17. BIN
      themes/bootstrap2/static/font/FontAwesome.otf
  18. +0
    -1197
      themes/bootstrap2/static/font/font-awesome-ie7.css
  19. +0
    -382
      themes/bootstrap2/static/font/font-awesome-ie7.min.css
  20. +0
    -1471
      themes/bootstrap2/static/font/font-awesome.css
  21. +0
    -402
      themes/bootstrap2/static/font/font-awesome.min.css
  22. BIN
      themes/bootstrap2/static/font/fontawesome-webfont.eot
  23. +0
    -399
      themes/bootstrap2/static/font/fontawesome-webfont.svg
  24. BIN
      themes/bootstrap2/static/font/fontawesome-webfont.svgz
  25. BIN
      themes/bootstrap2/static/font/fontawesome-webfont.ttf
  26. BIN
      themes/bootstrap2/static/font/fontawesome-webfont.woff
  27. BIN
      themes/bootstrap2/static/img/favicon.ico
  28. BIN
      themes/bootstrap2/static/img/glyphicons-halflings-white.png
  29. BIN
      themes/bootstrap2/static/img/glyphicons-halflings.png
  30. +0
    -30
      themes/bootstrap2/static/js/autosidebar.js
  31. +0
    -6
      themes/bootstrap2/static/js/bootstrap.min.js
  32. +0
    -4
      themes/bootstrap2/static/js/jquery-1.7.2.min.js
  33. +0
    -11
      themes/bootstrap2/templates/analytics.html
  34. +0
    -13
      themes/bootstrap2/templates/archives.html
  35. +0
    -22
      themes/bootstrap2/templates/article.html
  36. +0
    -26
      themes/bootstrap2/templates/article_infos.html
  37. +0
    -2
      themes/bootstrap2/templates/author.html
  38. +0
    -0
      themes/bootstrap2/templates/authors.html
  39. +0
    -104
      themes/bootstrap2/templates/base.html
  40. +0
    -8
      themes/bootstrap2/templates/categories.html
  41. +0
    -2
      themes/bootstrap2/templates/category.html
  42. +0
    -7
      themes/bootstrap2/templates/comments.html
  43. +0
    -11
      themes/bootstrap2/templates/disqus_script.html
  44. +0
    -9
      themes/bootstrap2/templates/github.html
  45. +0
    -45
      themes/bootstrap2/templates/index.html
  46. +0
    -13
      themes/bootstrap2/templates/page.html
  47. +0
    -15
      themes/bootstrap2/templates/pagination.html
  48. +0
    -16
      themes/bootstrap2/templates/piwik.html
  49. +0
    -15
      themes/bootstrap2/templates/search_sidebar.html
  50. +0
    -47
      themes/bootstrap2/templates/sidebar.html
  51. +0
    -2
      themes/bootstrap2/templates/tag.html
  52. +0
    -6
      themes/bootstrap2/templates/taglist.html
  53. +0
    -13
      themes/bootstrap2/templates/tags.html
  54. +0
    -6
      themes/bootstrap2/templates/translations.html
  55. +0
    -6
      themes/bootstrap2/templates/twitter.html
  56. +0
    -1
      themes/bootstrap2/templates/twitter_profile.html
  57. +1
    -0
      themes/pelican-clean-blog

+ 29
- 0
content/email-security.md View File

@@ -0,0 +1,29 @@
Title: Email Security
Date: 2016-12-24T00:24+01:00
Author: Wxcafé
Category:
Slug: email-security

So, nowadays, everyone knows emails are **not** secure. If you didn't know that,
you should. Emails are to be treated like postcards : everyone between you and
the person you're talking to can read them. Don't write military secrets in
them. Back in the good old days, when the protocols they rely on were devised,
the people creating them didn't really need to secure them (and they didn't have
computers powerful enough to do encryption. Emails are **old**. Like, really
old. Like older than I am. By decades.)

There are, of course, a few methods to "secure" email. I'm ready to bet at this
point over 75% of the people reading this are at least thinking very hard "PGP".
Some might be thinking "S/MIME". Maybe a few of you who didn't think I was
talking about encryption by the user are thinking about STARTTLS in SMTP, or
SPF/DKIM/DMARC.

If this previous paragraph confused you, at least a bit, there's a very good
summary about these things over in the latest issue of *the IP Journal*,
[here](http://ipj.dreamhosters.com/wp-content/uploads/issues/2016/ipj19-3.pdf)
(pdf). I also am going to start mirroring the issues of that journal over on
[https://wxcafe.net/pub/IPJ/](https://wxcafe.net/pub/IPJ/). I encourage you to
subscribe to the paper version of the IP Journal, it's **free** and the content
is generally very good and informative.

That was all, see ya

+ 30
- 0
content/envie-partout-temps-nulle-part.md View File

@@ -0,0 +1,30 @@
Title: Envie partout, temps nulle part
Date: 2016-06-13T09:11+02:00
Author: Wxcafé
Category: Note
Slug: envie-partout-temps-nulle-part

Ça fait assez longtemps que j'ai pas posté ici, j'en suis bien conscient, et
j'écris donc ce petit post pour dire que c'est le cas, pourquoi c'est le cas, et
que ça va pas durer.

J'ai beaucoup de choses qui me prennent pas mal de temps en ce moment,
notamment:

- un boulot, je suis en stage
- la rédaction d'un rapport, puisque... je suis en stage
- la recherche d'une alternance, pour l'an prochain
- un bon nombre de démarches administratives variées
- insert autre raison here.

par contre, j'ai /énormément/ de choses dont j'aimerais parler, notamment:

- de la redondance de routeurs, avec CARP, PfSync, dhcpsync et ifstated
- du backup de confs réseau avec Oxidized
- des mésaventures avec debian et nvidia
- du junk hacking sur une liseuse ukrainienne
- des backups automatisés via puppet
- encore d'autres trucs, que j'ai oublié la comme ça mais ça va revenir


Du coup, vous inquietez pas, j'ai pas oublié ce blog, et je reviens vite.

+ 63
- 0
content/key_migration.md View File

@@ -0,0 +1,63 @@
Title: Key Migration
Date: 2016-12-29T03:49+01:00
Author: Wxcafé
Category: misc
Slug: key-migration

Here's a signed message about my key migration

```
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
```

<br/>
Hey

I'm at 33c3 at the moment, and I was inspired to make a new GPG key, since my
old one is from 2012 (and was revoked by me almost 6 months ago), and back
then I didn't do it the way I'd like to now

Anyways, so I made a new key, **0x58dd226b3ea71dc7**, which is both on
[pgp.mit.edu](http://pgp.mit.edu/pks/lookup?op=vindex&search=0x58DD226B3EA71DC7)
and [here](https://pub.wxcafe.net/wxcafe.asc). Of course, in these
kind of situations you're supposed to publish a message signed with both keys.
However, since I revoked the old one without thinking about this a few months
ago, it would be basically meaningless. Moreover, basically all the signatures
on that old key were from keys that expired since then, so it's not like that
old key was very trustable either.

Anyways, I'm signing this with the new key, and I'm also including [this
link](https://twitter.com/Wxcafe/status/814300732849553408) to a tweet I made,
which contains the key ID.

This should suffice to link this key to my identity, and I hope to gather some
signatures at 33c3 too 😃💯🚀

Thanks for your understanding

```
-----BEGIN PGP SIGNATURE-----

iQIzBAEBCAAdFiEEZDroKcxTGuCO4MGxjYC/gJdzRz8FAlhkgXEACgkQjYC/gJdz
Rz/r8A//alMfDwRARH/+eCYkesSfkpNS66GjkXp7CUUU+3j0hGT/54MonZSuoj97
md9AdVMjw2NqevFvEusA1QVijFBdqA5j4IZ+gPxmq2B/UG6lTcf0MNaw7/k0YzPk
CwAeTpBqq27wo4VMLwvmxMfZi0QK1QXL2JFiMxDwmIsep4KNzhuhymlpstBMxeOp
/uRw1Atq2mYa6+9j7aVb98OsgC+Ma4C03yU71EGwMkdCGdDPQzdVtBMnnUmB2tuX
nZQ/MmG7pwr/gRdllHWiTbJvaXFLiNIh8mE44ihinIrwAwdRpiLmohl9LIIr6VdM
Ry7AojwDWKeAEGj2Z2MlUbGlIHJ2GbTn8ScKpbhJLtMJv3kCQZ0sBdMeZSP8WeW2
ZO5pAc2/0UAK2NERnSCx8Ow4SDIVVavk2TOPHFqN9oOa4pm8dhi5bA2S5czuXaqz
y25wIdaoDZw5v5O77ATobWvc+NU/U0trFWW6jVoQlcR9OK5Jh2QraM5lKNL4nBAM
Ou1JqrwYojhprbhc1047ntCBe3z2bkfNCj94FYv2IwrEmOxsRVfUs6aJo+jQXa8B
HxCi1m8mFsnoU1jEUsqrf4MXbmlSKdUGCLyz4CW8u3uRoU/NU+XHogE31m3pk8N6
62rYGWBWLGAkGGC0JvOPbrf/kOIAZXXJvaMcQcRLirXX1q/bgwQ=
=PIuW
-----END PGP SIGNATURE-----
```

I'm also linking this message [over
here](https://pub.wxcafe.net/key_migration.asc) so that even if you can't verify
this by copy/pasting from the webpage you can still get the message unmodified
and verify it.

Thank you

+ 9
- 0
content/let's_encrypt.md View File

@@ -4,6 +4,15 @@ Author: Wxcafé
Category: Tutoriel
Slug: lets-encrypt-enfin

### Update 2016-09:
Ça fait un certain temps maintenant (depuis mai 2016, en fait) que le script
letsencrypt a été renommé `certbot`. Le dépot est donc maintenant
[https://github.com/certbot/certbot](https://github.com/certbot/certbot), mais
`letsencrypt-auto` est toujours un lien symbolique vers le bon script, il n'est
donc pas nécessaire de changer les commandes.

---

Vous avez peut être vu que ce blog, entre autres sites que j'administre, n'est
disponible depuis quelques jours qu'en HTTPS, et avec un certificat valide. Bon,
si vous êtes là, vous avez déjà entendu parler de Let's Encrypt, mais pour les


+ 174
- 0
content/openvpn-openbsd.md View File

@@ -0,0 +1,174 @@
Title: OpenVPN on OpenBSD
Date: 2016-11-30T23:59+01:00
Author: Wxcafé
Category: Tutorial
Slug: openvpn-openbsd

So this is a small article, because I wanted to see if I could write more if
I just wrote small things like that about a single, simple thing I did, without
too much detail and fluff

Also, I'm writing this in English, while I usually write in French. I'm
switching language because I believe English is a lot easier to express
technical concepts in, or at least I'm more fluent in it when it comes to
expressing technical concepts, and I believe now that my audience (at least, the
people I know/talk to on twitter/IRC/etc...) speak or read English much more
than French, and so it makes more sense for me to write in English here.
Therefore, I'll be writing in English only on this blog from now on.


(French version :)
De plus, j'écris ceci en Anglais, alors que j'écrivais ici habituellement en
Français. Je change de langue, parce qu'il me semble qu'il est plus facile
d'exprimer des concepts techniques en Anglais qu'en Français, ou en tout cas
que cela m'est plus facile personnellement, mais aussi parce que je pense que
mon audience (ou en tout cas, les gens que je connais/auxquels je parle sur
twitter/IRC/etc...), parlent ou lisent l'Anglais bien plus que le Français, et
il est donc plus logique pour moi d'écrire en Anglais ici.
J'écrirais donc uniquement en Anglais sur ce blog a partir de maintenant.

So, now that that's done, I can go on and write that "small article" I promised
at the top.

So, the idea is that I had a FreeBSD OpenVPN box that I used to have
a semi-decent Internet connection while at school (my school blocks all ports
that are not tcp/80 or tcp/443 or udp/53, basically. And apparently udp/443
too...). I wanted to try running that VM on OpenBSD, because of three things :

1. I really like OpenBSD, and wanted to have a VM that I could do some
experiments on without breaking all of my stuff,
2. I found a way to run OpenBSD on the provider I used for that box,
[vultr](https://vultr.com), and
3. why not?

Anyway, so once you've installed the OS, the first thing to do is

::bash
$ doas pkg_add openvpn

...

well okay the first thing to do is to

# vi /etc/doas.conf

and put this in it :

::bash
permit keepenv :wheel as root
permit nopass root as root

once this is done, you can now go and install the packages, before creating the
CA:

$ doas pkg_add vim openvpn easy-rsa
$ cd /usr/local/share/easy-rsa
$ doas ./easyrsa init-pki
$ doas ./easyrsa gen-dh
$ doas ./easyrsa build-ca [nopass]
$ doas ./easyrsa build-server-full [CN of the server] [nopass]
$ doas ./easyrsa build-client-full [CN of a client] [nopass]

please note that you can use passwords on all of those, but then you'll have to
type them every time you use one of them. I see no problem with having
a password on the CA and the client, but the server should be able to restart by
itself in my opinion.

Anyway, now we can write the config for OpenVPN:

$ doas mkdir /etc/openvpn/
$ doas vim /etc/openvpn/openvpn.conf

We'll run with these settings :

dev tap
tls-server
cert /usr/local/share/easy-rsa/pki/issued/[CN of the server].crt
key /usr/local/share/easy-rsa/pki/private/[CN of the server].key
ca /usr/local/share/easy-rsa/pki/ca.crt
dh /usr/local/share/easy-rsa/pki/dh.pem
proto udp
port 53
verb 3
status /var/log/openvpn-status.log
ifconfig 172.16.0.10 255.255.0.0
route-gateway 172.16.0.10
persist-key
persist-tun
keepalive 10 120
server 172.16.0.0 255.255.0.0
client-to-client
tls-cipher TLS-DHE-RSA-WITH-AES-256-CBC-SHA TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA
push "route 172.16.0.0 255.255.0.0"

Of course, feel free to edit that to match whatever you need.

Anyway, the next thing we need to do is to configure pf.

What, you thought that was it? Of course we're gonna filter this, it's an
internet-facing server!

$ doas vim /etc/pf.conf

So, here is the pf configuration file :

# $OpenBSD: pf.conf,v 1.54 2014/08/23 05:49:42 deraadt Exp $
#
# See pf.conf(5) and /etc/examples/pf.conf

set block-policy drop
set skip on lo0
block return in on ! lo0 proto tcp to port 6000:6010
match in all scrub (no-df random-id max-mss 1440)

block log all

match out on egress from (tap0:network) to any nat-to (egress:0)
pass out quick

# ssh
pass in on egress proto tcp from any to (egress) port 22

# mosh
pass in on egress proto udp from any to any port 60000:61000

# snmp
pass in on egress proto udp from [IP of my SNMP server] to any port 161
pass in on egress proto udp from [IPv6 block of my SNMP server]/48 to any port 161

# openvpn
pass in on egress proto udp from any to (egress) port 53
pass in on egress proto udp from any to (egress) port 443 rdr-to (egress:0) port 53
pass in on tap0

So, this should be easy enough to read, but just in case : we skip lo, we block
X, we scrub weird packets, we block and log by default.

Then, we NAT everything that comes out of the VPN and to the 'net. We let what
comes from the server out too, tho that could be improved...

The next three blocks are easy, and then in the OpenVPN block, we let in port
udp/53, we redirect port udp/443 to udp/53, and we let everything in from the
VPN.

We have to reload pf and add a sysctl knob if we want to actually route packets
coming from the VPN:

$ doas pfctl -f /etc/pf.conf
$ echo 'net.inet.ip.forwarding=1' | doas tee -a /etc/sysctl.conf

And now, we simply enable the OpenVPN service, and we're done:

$ doas rcctl enable openvpn
$ doas rcctl enable pflogd
$ doas rcctl start openvpn
$ doas rcctl start pflogd
$ doas rcctl ls on # to check

That's it! It was actually pretty easy, I guess.

Also, if you don't know what's wrong and want to get a detailed log, run
`/usr/local/sbin/opvnpn --verb 11 --config /etc/openvpn/openvpn.conf`


Seeya!

+ 42
- 21
content/pages/about.md View File

@@ -1,4 +1,4 @@
Date: 2013-06-13 00:54
Date: 2016-04-08 01:43
Title: A propos
Slug: about
Author: wxcafé
@@ -7,46 +7,67 @@ Category: Perso
Wxcafé, c'est moi.
------------------

Je m'appelle Clément Hertling, je suis né en 1995, et je suis étudiant en DUT a
[Paris 12 (UPEC)](http://www.u-pec.fr). Je vis actuellement a Villejuif, près de
Paris, en France.
Je m'appelle Clément Hertling, je suis né en 1995 (oui, ça m'évite de devoir
mettre à jour cette page régulièrement), et je suis étudiant en DUT à [Paris 12
(UPEC)](http://www.u-pec.fr), après un an de prépa integrée
a [Épita](http://www.epita.fr). Je vis actuellement a Villejuif, près de Paris,
en France.

Je suis enthousiaste dès qu'il s'agit de jouer avec des ordinateurs, que ce soit
avec des systèmes d'exploitations (et particulièrement les UNIX-like : Linux,
\*BSD, OS X, Plan 9, ...), mais aussi avec le réseau et son administration
(principalement couches 2 et 3, routage et commutation).
Bref, j'aime les systèmes : les observer, les démonter, les remonter, et les
comprendre. Ça s'applique aussi bien aux systèmes d'exploitation ou au réseau,
comme dit plus haut, mais aussi à la sécurité, ou bien même à des systèmes non
électroniques : je suis aussi très intéressé par l'horlogerie, par exemple, ou
par les jeux de rôles, qui sont aussi en quelque sorte des systèmes (de jeu,
mais des systèmes quand même).
Je suis aussi intéressé par le hardware, que ce soit de l'embarqué ou bien des
serveurs, et dans une moindre mesure par l'électronique. Je fais un peu (et de
plus en plus) de programmation, principalement en python et en Rust. Je
m'intéresse beaucoup a la théorie de la programmation, toutefois, et notamment
de plus en plus a la programmation fonctionnelle et a la théorie des types.
On peut probablement en conclure que j'aime travailler avec la technologie.
m'intéresse beaucoup a la théorie de la programmation, toutefois, et j'aime
beaucoup la programmation fonctionnelle.
J'aime aussi écrire a propos de ce que je fais, et de mes pensées sur la
technologie en général, et c'est ce que je fais (parfois) ici.
technologie en général, et c'est ce que je fais (parfois) ici (et a d'autres
endroits sur d'autres sujets.)

Vous pouvez aussi me lire sur Twitter. Les liens sont dans la
barre a droite. Si vous voulez me rencontrer en vrai, vous pouvez m'envoyer un
email.
Vous pouvez aussi me lire sur Twitter, c'est un moyen de communication que
j'utilise beaucoup. Les liens sont dans la barre a droite. Si vous voulez me
rencontrer IRL, vous pouvez m'envoyer un mail.

*-- Mis à jour pour la dernière fois le 2016-04-08 01:43*

Wxcafé, that's me.
------------------

I'm Clément Hertling, I was born in 1995, and I'm a student in a technical
formation at [Paris 12 (UPEC)](http://www.u-pec.fr). I live in Villejuif, near
Paris, France.
I'm Clément Hertling, I was born in 1995 (this is totally a trick not to have to
update this page regularly), and I'm a student in a technical
formation at [Paris 12 (UPEC)](http://www.u-pec.fr). Before that I did a year of
preparatory school at [Épita](http://www.epita.fr), a engineering school. I live
in Villejuif, near Paris, France.

I'm pretty enthusiastic when it's about playing with computers, whether that
I'm pretty enthusiastic about playing with computers, whether that
means operating systems (and more specifically UNIX-like OSes : Linux, \*BSD,
OS X, Plan 9, ...), or networks and their administration (generally speaking,
layer 2 and 3, routing and switching).
Well, I like systems : watching how they work, tinkering with them, and in the
end understanding how they work. This means OSes and networks, as I said before,
but also security, or even non-electronic systems : I'm very interested in
watch-making too, or by pen and paper role playing games, which are also
systems, in a sense. Game systems, but systems nonetheless.
I'm also interested in hardware, be it embedded systems or servers, and to a
smaller extent in electronics. I also do a bit of (but more and more)
programming, mostly in python and Rust. I'm very interested in CS theory,
though, and very much so in functionnal programming and type theory.
You could conclude that I like tech, and working in this domain. I also enjoy
writing about what I do and about my ideas on tech in general, and that's what I
(sometimes) do here.
though, and very much so in functionnal programming.
I also enjoy writing about what I do and about my ideas on tech in general, and
that's what I (sometimes) do here (and in other places, but on other topics).

You can also read my thoughts on twitter. The links are in the sidebar. If you
want to meet me, you can send me an email.
You can also read my thoughts on twitter, it's a communication medium that I use
a lot. The links are in the sidebar. If you want to meet me, you can send me
an email.

Sorry all the posts here are in French, btw. I'm thinking about starting to post
in English, but for now it's all in French. Maybe try Google Translate?

*-- Last updated 2016-04-08 01:43*

+ 30
- 0
content/pocorgtfo.md View File

@@ -0,0 +1,30 @@
Title: PoC||GTFO; now on a NEW MIRROR near you thanks to A NETWORKING STUDENT and world-famous NGINX REDIRECTION
Date: 2016-10-12 16:31
Author: Wxcafe
Category: Note
Slug: PoC||GTFO

Le titre dit a peu près tout : j'ai récemment commencé a lire les PoC||GTFO
(Proof of Concept OR Get The Fuck Out), dont j'avais entendu parler depuis
quelques années mais pour lesquels je n'avais jamais réussi jusqu'ici à prendre
du temps pour les lire. C'est désormais chose faite (je les ai imprimés, c'est
plus confortable, vous pouvez en voir pas mal d'extraits sur
[twitter](https://twitter.com/wxcafe)).

Pour celleux qui ne seraient pas au courant, je vais résumer vite fait :
PoC||GTFO est un journal publié depuis 2013 par un groupuscule composé de pas
mal de gens faisant de la sécurité informatique (Manul Laphroaig, the Grugq,
Ange Albertini, notamment...) et composé d'articles soumis par de nombreuses
personnes sur des sujets techniques en général centrés sur la sécurité et/ou
l'exploitation. Un ton très spécifique, et de nombreux easter-eggs cachés dans
chaque numéro, associés a une qualité exceptionnelle des articles, à très vite
fait connaître ce journal. Une des clauses de la licence autorisant la lecture
étant de le partager, je fais donc un mirroir.

Le mirroir est situé ici : [https://wxcafe.net/pub/PoC||GTFO](https://wxcafe.net/pub/PoC||GTFO).
A noter qu'il faut bien distinguer https://wxcafe.net/pub de
https://pub.wxcafe.net, et que d'autres publications intéressantes pourraient un
jour se trouver dans ce dossier (je ferai a ce moment la un post pour en
avertir, ou pas.)

Informationellement,

+ 405
- 0
content/redondance_de_routeurs,_avec_openbsd_et_freebsd.md View File

@@ -0,0 +1,405 @@
Title: Redondance de routeurs, avec OpenBSD et FreeBSD
Date: 2016-07-29T17:53+02:00
Author: Wxcafé
Category: Tutoriel
Slug: redondance-routeurs-openbsd-freebsd

Depuis le début de mon DUT (il y a deux ans), j'ai découvert le monde du réseau,
alors que j'étais plus système auparavant. Au cours de ce processus, j'ai
pu observer quelques coutumes étranges de ce milieu. Ainsi donc, dans cet étrange
domaine, il arrive parfois qu'on cherche à avoir un réseau stable pendant une
période relativement longue. Bien évidemment, ceci se trouve être un problème
Complexe®, a cause notamment des différents constructeurs de matériel réseau, et
des différents systèmes d'exploitation des machines qui font passer les chatons
dans les tuyaux.

Bref, en général on règle ce problème de façon relativement simple : en
utilisant un système stable, _par exemple_ OpenBSD. Cependant, ça ne suffit pas
toujours: on peut aussi rencontrer des erreurs hardware. Et puis même OpenBSD
peut rencontrer des problèmes softwares aussi, de temps en temps. Il paraît.
J'ai lu un truc la dessus quelque part.

Bref, après cette intro complètement objective, on va parler de redondance de
routeurs (c'est a dire la mise en place de deux routeurs hardwares en même
temps, avec un qui prend le relai de l'autre en cas de problème). On va aussi
faire en sorte qu'ils utilisent deux réseaux externes différents (d'opérateurs
séparés, par exemple), pour faire bonne mesure.
Vu que c'est un projet pour mon DUT à la base, et qu'on a fait que du Linux la
bas, j'ai décidé de le réaliser avec un OpenBSD et un FreeBSD, sur un laptop et
une Cubieboard 2 (une board ARM qui traînait chez moi), en utilisant des VLANs
(puisqu'ils n'ont qu'une seule NIC). C'est aussi pour ça qu'il y a un FreeBSD,
vu que la Cubieboard ne supporte qu'assez mal OpenBSD (en tout cas d'après mon
expérience)

Tout d'abord, je vais mettre [ici](https://pub.wxcafe.net/static/redondance.pdf)
le rapport produit pour mon DUT, comme le veut la tradition du TL;DR (tu le sens
mon LaTeX?). Si vous voulez pas lire cette explication, vous pouvez lire l'autre
explication qui est en PDF et orientée pour des profs de DUT. Si vous êtes prof
de DUT j'imagine que ça peut être intéressant.

Bon, donc la première chose a faire c'est de définir quelques trucs. La
redondance, on l'a dit, c'est le fait d'avoir plusieurs équipements effectuant
une tâche similaire, pour qu'en cas de panne l'un prenne la place de l'autre
sans interruption. Quelques acronymes :

- CARP, *Common Address Redundancy
Protocol*, est un protocole (développé par OpenBSD pour remplacer VRRP) qui
permet de faire de la redondance entre des équipements IP, en leur permettant
de partager une adresse IP en switchant rapidement en cas de problème avec l'un
des équipements.

- PF, *Packet Filter*, est le firewall d'OpenBSD et de FreeBSD.
Enfin, des versions différentes. Mais l'idée est la. (en pratique, la version de
FreeBSD est plus ancienne mais supporte le multi-CPU, contrairement a celle
d'OpenBSD (mais bon, on connait le support multi-CPU d'OpenBSD...)).

- PfSync, *Packet Filter Synchronisation*, est un service qui permet de
synchroniser la table d'état de deux instances de PF. De cette façon, quand un
des deux crashe, le second peut reprendre les connexions en cours et évite de
couper trop de transmissions.

- IfStated est un petit programme qui permet de vérifier l'état d'une interface
réseau régulièrement et de lancer des commandes en fonction de l'état de celle
ci.


Bon, maintenant que ces définitions sont claires, passons à la réalisation. Le
système OpenBSD sera le serveur primaire, et le FreeBSD sera la réplique, car
OpenBSD est capable de routage multipath (répartition du traffic entre deux
routes de manière égale), ce que FreeBSD ne sait pas faire. Ainsi, si R1 (la
machine OpenBSD) est primaire, elle est capable de transférer une partie du
traffic vers R2 (la machine FreeBSD). Si elle s'arrête de fonctionner, R2 n'a
pas besoin de faire de multipath, puisqu'a ce moment la une seule route valide
est encore disponible.

La première chose à faire est de configurer le réseau sur nos deux machines.
Puisqu'elles ont toutes les deux une seule interface réseau, nous utilisons des
VLANs (en conjonction avec un switch correct, je vous laisse trouver la
configuration de celui-ci. Il faut connecter les deux machines sur des ports
Trunk). Le VLAN 300 sera utilisé pour le réseau interne, le 400 pour le réseau
externe A et le 500 pour le réseau externe B. Ainsi, on aura un réseau qui
ressemble à ceci :

```
╭──╮ ╭─────────────╮ ╭──╮
│ │ │ Switch │ │ │
│R1│ │ │ │R2│
│ │ │ │ │ │
╰──╯ ╰─────────────╯ ╰──╯
╚════════╝ ╚═════════╝
```

en terme physique, et ceci :

```
╔══════╗ ╔══════╗
╭──╮ ╭────╮ ╭─────╮ ╭────╮ ╭──╮
│OP│ │ │ │ │ │ │ │OP│
│ │ │ R1 │ │ LAN │ │ R2 │ │ │
│A │ │ │ │ │ │ │ │B │
╰──╯ ╰────╯ ╰─────╯ ╰────╯ ╰──╯
╚════════╝ ╚════════╝
```

au niveau réseau.
On va aussi utiliser le réseau 30.30.30.0/24 sur le réseau interne pour cet
exemple.

Pour ce faire, on configure les routeurs ainsi :

#### R1 (OpenBSD):

**/etc/hostname.em0:**

```
up
```

**/etc/hostname.vlan0:**

```
inet 30.30.30.1 255.255.255.0 30.30.30.255 vlan 300 vlandev em0
```

**/etc/hostname.vlan1:**

```
dhcp vlan 400 vlandev em0
```

#### R2 (FreeBSD):

**/etc/rc.conf**

```
[...]
vlans_dcw0="300 500"
ifconfig_dwc0_300="inet 30.30.30.2 netmask 255.255.255.0"
ifconfig_dwc0_500="DHCP"
```

Une fois ceci fait, nos machines sont configurées sur leurs réseaux externes
respectifs (via DHCP, adaptez si votre réseau externe utilise une autre
méthode) et sur le réseau interne. Il faut bien entendu remplacer les noms
d'interfaces (`em0`, `dcw0`) par le noms des interfaces présentes sur vos
machines.

Nous allons maintenant configurer la redondance elle même avec CARP. Le réseau
avec lequel nous allons nous retrouver ressemble à ceci :

```
╭───────╮
╔═════│ VIP │══════╗
║ ╰───────╯ ║
║ ║ ║
╭──╮ ╭────╮ ╭─────╮ ╭────╮ ╭──╮
│OP│ │ │ │ │ │ │ │OP│
│ │ │ R1 │ │ LAN │ │ R2 │ │ │
│A │ │ │ │ │ │ │ │B │
╰──╯ ╰────╯ ╰─────╯ ╰────╯ ╰──╯
╚════════╝ ╚════════╝
```

La configuration de CARP se fait en fait comme pour une interface réseau
classique :

#### R1:

**/etc/hostname.carp0:**

```
vhid 125 pass pwd12345 carpdev vlan0 advbase 3 advskew 1 state master
30.30.30.254 netmask 255.255.255.0
```

#### R2:

**/etc/rc.conf:**

```
[...]
ifconfig_dwc0_300_alias0="vhid 125 advbase 3 advskew 200 \
state backup pass pwd12345 alias 30.30.30.254/24"
```

Une fois que CARP est mis en place, nous configurons PF, pour filtrer les flux
que nous laissons passer sur notre réseau. Les configurations suivantes,
différentes pour R1 et R2 (puisque FreeBSD et OpenBSD n'utilisent pas les mêmes
versions de PF), sont évidemment à modifier en fonction de votre installation:
elles sont très minimales (ne laissant même pas passer le http...)

#### Pour R1:

**/etc/pf.conf:**

```
set skip on lo

# définition des variables
int="30.30.30.0/24"
ext="0.0.0.0/0"
int_addr="30.30.30.1"
int_if="vlan0"
ext_if="vlan1"

# defaut : bloquage
block all

# vérification des paquets, anti-spoofing
antispoof for $int_if
antispoof for $ext_if

# nous laissons passer l'icmp
pass proto icmp

# nous mettons en place le NAT de l'interieur vers Internet
pass in on $int_if from $int to any keep state
pass out on $ext_if from $int to $ext nat-to $int_if keep state

# carp, pfsync et dhcpsync
pass out on $int_if proto carp keep state
pass quick on $int_if proto pfsync keep state
pass in on $int_if proto udp to any port 8067 keep state
pass out on $int_if proto udp to any port 8067 keep state

# nous laissons passer les connexions SSH vers le routeur
pass in on $int_if proto tcp from $int to $int_addr port ssh keep state
pass out on $int_if proto tcp from $int_addr port ssh to $int keep state
```

#### Et pour R2:

**/etc/pf.conf:**

```
set skip on lo

# définition des variables
int="30.30.30.0/24"
ext="0.0.0.0/0"
int_addr="30.30.30.2"
int_if="dwc0.300"
ext_if="dwc0.500"

# défaut : bloquage
block all

# vérification des paquets, anti-spoofing
antispoof for $int_if
antispoof for $ext_if

# nous laissons passer l'icmp
pass proto icmp

# nous mettons en place le NAT de l'interieur vers Internet
nat on $ext_if from $int to any -> ($ext_if)
pass in on $int_if from $int to any keep state
pass out on $ext_if from any to $ext

# carp, pfsync et dhcpsync
pass out on $int_if inet proto carp keep state
pass quick on $int_if inet proto pfsync keep state
pass in on $int_if inet proto udp to port 8067 keep state
pass out on $int_if inet proto udp to port 8067 keep state

# nous laissons passer les connexions SSH vers le routeur
pass in on $int_if inet proto tcp from $int to $int_addr \
port ssh keep state
pass out on $int_if inet proto tcp from $int to $int_addr \
port ssh keep state
```

Une fois que PF est configuré, on passe a pfsync, qui permet de synchroniser
l'état de deux instances de PF, même de versions différentes (je trouve ce truc
génial):

#### Pour R1:

**/etc/hostname.pfsync0:**

```
syncdev vlan0 syncpeer 30.30.30.2
```

#### Et pour R2:

**/etc/rc.conf:**

```
pfsync_enable="YES"
pfsync_syncdev="dwc0.300"
pfsync_syncpeer="30.30.30.1"
```

Passons à ifstated. Puisque R1 supporte le multihoming mais pas R2, nous allons
faire en sorte que R1 aie une route multipath vers R2. De cette façon, R1 (qui
est la machine principale pour CARP, et reçoit donc toutes les connexions venant
du réseau interne), transmet la moitié de ces connexions vers R2, qui les gère
comme nécessaire. Si R1 arrête de fonctionner, R2 récupère l'ensemble des
connexions (grâce a CARP), qui ne sont pas interrompues (grâce a pfsync). Si R2
arrête de fonctionner, ifstated rentre en action et retire la route multipath de
R1 vers R2, ce qui permet d'éviter de transmettre la moitié des connexions à un
routeur qui ne fonctionne plus (c'est en général une chose a éviter).

Par conséquent, la configuration d'ifstated n'a à être effectuée que sur R1 :

**/etc/ifstated.conf:**

```
peer = '( "ping -q -c 1 -w 3 30.30.30.2>/dev/null" every 5 )'

state auto {
if $peer
set-state multihome
if ! $peer
set-state singlehome
}
state multihome {
init {
run "route add -mpath default 30.30.30.2"
}
if ! $peer
set-state singlehome
}
state singlehome {
init {
run "route delete default 30.30.30.2"
}
if $peer
set-state multihome
}

init-state auto
```

Enfin, dernier point a configurer, la synchronisation DHCP. Elle nous permet de
faire en sorte que les machines gardent les mêmes adresses IP même si un des
deux routeurs reste en rade pendant une période prolongée. On configure donc
`isc-dhcpd` sur les deux routeurs, comme suit:

#### R1:

**/etc/dhcpd.conf:**

```
authoritative;
ddns-update-style none;

failover peer "dhcp-failover" {
primary;
address 30.30.30.1;
port 8067;
peer address 30.30.30.2;
peer port 8067;
}

subnet 30.30.30.0 netmask 255.255.255.0 {
option routers 30.30.30.254;
option domain-name-servers 30.30.30.254;
pool {
failover peer "dhcp-failover";
max-lease-time 86400;
range 30.30.30.10 30.30.30.250;
}
}
```

#### Et pour R2:

**/usr/local/etc/dhcpd.conf:**

```
authoritative;
ddns-update-style none;

failover peer "dhcp-failover" {
secondary;
address 30.30.30.2;
port 8067;
peer address 30.30.30.1;
peer port 8067;
}

subnet 30.30.30.0 netmask 255.255.255.0 {
option routers 30.30.30.254;
option domain-name-servers 30.30.30.254;
pool {
failover peer "dhcp-failover";
max-lease-time 86400;
range 30.30.30.10 30.30.30.250;
}
}
```

Et voilà! Notre réseau ressemble désormais à ça (j'ai repris le schéma de mon
rapport, j'ai pas le courage de le refaire en texte encore):

![schéma](https://pub.wxcafe.net/img/schema_redondance_routeurs.png)

avec le PC1 qui représente le réseau local.

Si vous avez bien lu la configuration du serveur DHCP, il reste encore à mettre
en place un serveur DNS écoutant sur l'IP virtuelle, donc a priori synchronisé
entre les deux routeurs. Comme c'est quelque chose de simple a mettre en place
et que c'est assez bien documenté ailleurs, je laisse cette tâche comme exercice
aux lecteurs-ices.

+ 19
- 22
pelicanconf.py View File

@@ -9,43 +9,40 @@ SITEURL = '//wxcafe.net'
TIMEZONE = 'Europe/Paris'
DEFAULT_LANG = u'fr'
DEFAULT_PAGINATION = 10
THEME="./themes/bootstrap2"
THEME="./themes/pelican-clean-blog"
HEADER_COVER = SITEURL + '/theme/cover.png'
COLOR_SCHEME_CSS = 'monokai.css'

# URL settings
ARTICLE_URL = "posts/{slug}/"
ARTICLE_SAVE_AS = "posts/{slug}/index.html"
ARTICLE_SAVE_AS = "posts/{slug}/index.html"
PAGE_URL = "pages/{slug}/"
PAGE_SAVE_AS = "pages/{slug}/index.html"
CATEGORY_URL = "category/{slug}/"
CATEGORY_SAVE_AS = "category/{slug}/index.html"

# Feeds settings
FEED_ATOM = "feeds/feed.atom.xml"
FEED_ALL_ATOM = "feeds/feed.atom.all.xml"
CATEGORY_FEED_ATOM = "feeds/feed.%s.xml"
# Feeds settings
FEED_RSS = "feeds/feed.rss.xml"
FEED_ALL_RSS = "feeds/feed.rss.all.xml"
CATEGORY_FEED_RSS = "feeds/feed.rss.%s.xml"
FEED_ATOM = "feeds/feed.atom.xml"
CATEGORY_FEED_ATOM = None
AUTHOR_FEED_ATOM = None
AUTHOR_FEED_RSS = None
FEED_ALL_ATOM = None

MD_EXTENSIONS = [
'codehilite(linenums=False, guess_lang=True, noclasses=True, pygments_style=monokai)',
'smarty',
'codehilite(linenums=False, guess_lang=True, noclasses=True, pygments_style=monokai)',
'smarty',
'extra']

# Blogroll
LINKS = (
('Source!', 'https://github.com/wxcafe/blog-source', 'code'),
('Public Git', 'http://git.wxcafe.net', 'github-sign'),
)

# Social
SOCIAL = (
('Twitter', 'https://twitter.com/wxcafe', 'twitter'),
('Github', 'https://github.com/wxcafe', 'github'),
('Email', 'mailto://wxcafe@wxcafe.net', 'envelope'),
('Gpg', 'https://pub.wxcafe.net/wxcafe.asc', 'key'),
('IRL', 'https://www.openstreetmap.org/relation/105146', 'map-marker')
)
('twitter', 'https://twitter.com/wxcafe'),
('github', 'https://github.com/wxcafe'),
('envelope', 'mailto://wxcafe@wxcafe.net'),
('key', 'https://pub.wxcafe.net/wxcafe.asc'),
('map-o', 'https://www.openstreetmap.org/relation/105146'),
('code', 'https://github.com/wxcafe/blog-source'),
)

# Categories on right-side bar but not on top menu
DISPLAY_CATEGORIES_ON_MENU = False


BIN
pelicanconf.pyc View File


+ 0
- 1109
themes/bootstrap2/static/css/bootstrap-responsive.css View File

@@ -1,1109 +0,0 @@
/*!
* Bootstrap Responsive v2.3.2
*
* Copyright 2012 Twitter, Inc
* Licensed under the Apache License v2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Designed and built with all the love in the world @twitter by @mdo and @fat.
*/

.clearfix {
*zoom: 1;
}

.clearfix:before,
.clearfix:after {
display: table;
line-height: 0;
content: "";
}

.clearfix:after {
clear: both;
}

.hide-text {
font: 0/0 a;
color: transparent;
text-shadow: none;
background-color: transparent;
border: 0;
}

.input-block-level {
display: block;
width: 100%;
min-height: 30px;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}

@-ms-viewport {
width: device-width;
}

.hidden {
display: none;
visibility: hidden;
}

.visible-phone {
display: none !important;
}

.visible-tablet {
display: none !important;
}

.hidden-desktop {
display: none !important;
}

.visible-desktop {
display: inherit !important;
}

@media (min-width: 768px) and (max-width: 979px) {
.hidden-desktop {
display: inherit !important;
}
.visible-desktop {
display: none !important ;
}
.visible-tablet {
display: inherit !important;
}
.hidden-tablet {
display: none !important;
}
}

@media (max-width: 767px) {
.hidden-desktop {
display: inherit !important;
}
.visible-desktop {
display: none !important;
}
.visible-phone {
display: inherit !important;
}
.hidden-phone {
display: none !important;
}
}

.visible-print {
display: none !important;
}

@media print {
.visible-print {
display: inherit !important;
}
.hidden-print {
display: none !important;
}
}

@media (min-width: 1200px) {
.row {
margin-left: -30px;
*zoom: 1;
}
.row:before,
.row:after {
display: table;
line-height: 0;
content: "";
}
.row:after {
clear: both;
}
[class*="span"] {
float: left;
min-height: 1px;
margin-left: 30px;
}
.container,
.navbar-static-top .container,
.navbar-fixed-top .container,
.navbar-fixed-bottom .container {
width: 1170px;
}
.span12 {
width: 1170px;
}
.span11 {
width: 1070px;
}
.span10 {
width: 970px;
}
.span9 {
width: 870px;
}
.span8 {
width: 770px;
}
.span7 {
width: 670px;
}
.span6 {
width: 570px;
}
.span5 {
width: 470px;
}
.span4 {
width: 370px;
}
.span3 {
width: 270px;
}
.span2 {
width: 170px;
}
.span1 {
width: 70px;
}
.offset12 {
margin-left: 1230px;
}
.offset11 {
margin-left: 1130px;
}
.offset10 {
margin-left: 1030px;
}
.offset9 {
margin-left: 930px;
}
.offset8 {
margin-left: 830px;
}
.offset7 {
margin-left: 730px;
}
.offset6 {
margin-left: 630px;
}
.offset5 {
margin-left: 530px;
}
.offset4 {
margin-left: 430px;
}
.offset3 {
margin-left: 330px;
}
.offset2 {
margin-left: 230px;
}
.offset1 {
margin-left: 130px;
}
.row-fluid {
width: 100%;
*zoom: 1;
}
.row-fluid:before,
.row-fluid:after {
display: table;
line-height: 0;
content: "";
}
.row-fluid:after {
clear: both;
}
.row-fluid [class*="span"] {
display: block;
float: left;
width: 100%;
min-height: 30px;
margin-left: 2.564102564102564%;
*margin-left: 2.5109110747408616%;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.row-fluid [class*="span"]:first-child {
margin-left: 0;
}
.row-fluid .controls-row [class*="span"] + [class*="span"] {
margin-left: 2.564102564102564%;
}
.row-fluid .span12 {
width: 100%;
*width: 99.94680851063829%;
}
.row-fluid .span11 {
width: 91.45299145299145%;
*width: 91.39979996362975%;
}
.row-fluid .span10 {
width: 82.90598290598291%;
*width: 82.8527914166212%;
}
.row-fluid .span9 {
width: 74.35897435897436%;
*width: 74.30578286961266%;
}
.row-fluid .span8 {
width: 65.81196581196582%;
*width: 65.75877432260411%;
}
.row-fluid .span7 {
width: 57.26495726495726%;
*width: 57.21176577559556%;
}
.row-fluid .span6 {
width: 48.717948717948715%;
*width: 48.664757228587014%;
}
.row-fluid .span5 {
width: 40.17094017094017%;
*width: 40.11774868157847%;
}
.row-fluid .span4 {
width: 31.623931623931625%;
*width: 31.570740134569924%;
}
.row-fluid .span3 {
width: 23.076923076923077%;
*width: 23.023731587561375%;
}
.row-fluid .span2 {
width: 14.52991452991453%;
*width: 14.476723040552828%;
}
.row-fluid .span1 {
width: 5.982905982905983%;
*width: 5.929714493544281%;
}
.row-fluid .offset12 {
margin-left: 105.12820512820512%;
*margin-left: 105.02182214948171%;
}
.row-fluid .offset12:first-child {
margin-left: 102.56410256410257%;
*margin-left: 102.45771958537915%;
}
.row-fluid .offset11 {
margin-left: 96.58119658119658%;
*margin-left: 96.47481360247316%;
}
.row-fluid .offset11:first-child {
margin-left: 94.01709401709402%;
*margin-left: 93.91071103837061%;
}
.row-fluid .offset10 {
margin-left: 88.03418803418803%;
*margin-left: 87.92780505546462%;
}
.row-fluid .offset10:first-child {
margin-left: 85.47008547008548%;
*margin-left: 85.36370249136206%;
}
.row-fluid .offset9 {
margin-left: 79.48717948717949%;
*margin-left: 79.38079650845607%;
}
.row-fluid .offset9:first-child {
margin-left: 76.92307692307693%;
*margin-left: 76.81669394435352%;
}
.row-fluid .offset8 {
margin-left: 70.94017094017094%;
*margin-left: 70.83378796144753%;
}
.row-fluid .offset8:first-child {
margin-left: 68.37606837606839%;
*margin-left: 68.26968539734497%;
}
.row-fluid .offset7 {
margin-left: 62.393162393162385%;
*margin-left: 62.28677941443899%;
}
.row-fluid .offset7:first-child {
margin-left: 59.82905982905982%;
*margin-left: 59.72267685033642%;
}
.row-fluid .offset6 {
margin-left: 53.84615384615384%;
*margin-left: 53.739770867430444%;
}
.row-fluid .offset6:first-child {
margin-left: 51.28205128205128%;
*margin-left: 51.175668303327875%;
}
.row-fluid .offset5 {
margin-left: 45.299145299145295%;
*margin-left: 45.1927623204219%;
}
.row-fluid .offset5:first-child {
margin-left: 42.73504273504273%;
*margin-left: 42.62865975631933%;
}
.row-fluid .offset4 {
margin-left: 36.75213675213675%;
*margin-left: 36.645753773413354%;
}
.row-fluid .offset4:first-child {
margin-left: 34.18803418803419%;
*margin-left: 34.081651209310785%;
}
.row-fluid .offset3 {
margin-left: 28.205128205128204%;
*margin-left: 28.0987452264048%;
}
.row-fluid .offset3:first-child {
margin-left: 25.641025641025642%;
*margin-left: 25.53464266230224%;
}
.row-fluid .offset2 {
margin-left: 19.65811965811966%;
*margin-left: 19.551736679396257%;
}
.row-fluid .offset2:first-child {
margin-left: 17.094017094017094%;
*margin-left: 16.98763411529369%;
}
.row-fluid .offset1 {
margin-left: 11.11111111111111%;
*margin-left: 11.004728132387708%;
}
.row-fluid .offset1:first-child {
margin-left: 8.547008547008547%;
*margin-left: 8.440625568285142%;
}
input,
textarea,
.uneditable-input {
margin-left: 0;
}
.controls-row [class*="span"] + [class*="span"] {
margin-left: 30px;
}
input.span12,
textarea.span12,
.uneditable-input.span12 {
width: 1156px;
}
input.span11,
textarea.span11,
.uneditable-input.span11 {
width: 1056px;
}
input.span10,
textarea.span10,
.uneditable-input.span10 {
width: 956px;
}
input.span9,
textarea.span9,
.uneditable-input.span9 {
width: 856px;
}
input.span8,
textarea.span8,
.uneditable-input.span8 {
width: 756px;
}
input.span7,
textarea.span7,
.uneditable-input.span7 {
width: 656px;
}
input.span6,
textarea.span6,
.uneditable-input.span6 {
width: 556px;
}
input.span5,
textarea.span5,
.uneditable-input.span5 {
width: 456px;
}
input.span4,
textarea.span4,
.uneditable-input.span4 {
width: 356px;
}
input.span3,
textarea.span3,
.uneditable-input.span3 {
width: 256px;
}
input.span2,
textarea.span2,
.uneditable-input.span2 {
width: 156px;
}
input.span1,
textarea.span1,
.uneditable-input.span1 {
width: 56px;
}
.thumbnails {
margin-left: -30px;
}
.thumbnails > li {
margin-left: 30px;
}
.row-fluid .thumbnails {
margin-left: 0;
}
}

@media (min-width: 768px) and (max-width: 979px) {
.row {
margin-left: -20px;
*zoom: 1;
}
.row:before,
.row:after {
display: table;
line-height: 0;
content: "";
}
.row:after {
clear: both;
}
[class*="span"] {
float: left;
min-height: 1px;
margin-left: 20px;
}
.container,
.navbar-static-top .container,
.navbar-fixed-top .container,
.navbar-fixed-bottom .container {
width: 724px;
}
.span12 {
width: 724px;
}
.span11 {
width: 662px;
}
.span10 {
width: 600px;
}
.span9 {
width: 538px;
}
.span8 {
width: 476px;
}
.span7 {
width: 414px;
}
.span6 {
width: 352px;
}
.span5 {
width: 290px;
}
.span4 {
width: 228px;
}
.span3 {
width: 166px;
}
.span2 {
width: 104px;
}
.span1 {
width: 42px;
}
.offset12 {
margin-left: 764px;
}
.offset11 {
margin-left: 702px;
}
.offset10 {
margin-left: 640px;
}
.offset9 {
margin-left: 578px;
}
.offset8 {
margin-left: 516px;
}
.offset7 {
margin-left: 454px;
}
.offset6 {
margin-left: 392px;
}
.offset5 {
margin-left: 330px;
}
.offset4 {
margin-left: 268px;
}
.offset3 {
margin-left: 206px;
}
.offset2 {
margin-left: 144px;
}
.offset1 {
margin-left: 82px;
}
.row-fluid {
width: 100%;
*zoom: 1;
}
.row-fluid:before,
.row-fluid:after {
display: table;
line-height: 0;
content: "";
}
.row-fluid:after {
clear: both;
}
.row-fluid [class*="span"] {
display: block;
float: left;
width: 100%;
min-height: 30px;
margin-left: 2.7624309392265194%;
*margin-left: 2.709239449864817%;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.row-fluid [class*="span"]:first-child {
margin-left: 0;
}
.row-fluid .controls-row [class*="span"] + [class*="span"] {
margin-left: 2.7624309392265194%;
}
.row-fluid .span12 {
width: 100%;
*width: 99.94680851063829%;
}
.row-fluid .span11 {
width: 91.43646408839778%;
*width: 91.38327259903608%;
}
.row-fluid .span10 {
width: 82.87292817679558%;
*width: 82.81973668743387%;
}
.row-fluid .span9 {
width: 74.30939226519337%;
*width: 74.25620077583166%;
}
.row-fluid .span8 {
width: 65.74585635359117%;
*width: 65.69266486422946%;
}
.row-fluid .span7 {
width: 57.18232044198895%;
*width: 57.12912895262725%;
}
.row-fluid .span6 {
width: 48.61878453038674%;
*width: 48.56559304102504%;
}
.row-fluid .span5 {
width: 40.05524861878453%;
*width: 40.00205712942283%;
}
.row-fluid .span4 {
width: 31.491712707182323%;
*width: 31.43852121782062%;
}
.row-fluid .span3 {
width: 22.92817679558011%;
*width: 22.87498530621841%;
}
.row-fluid .span2 {
width: 14.3646408839779%;
*width: 14.311449394616199%;
}
.row-fluid .span1 {
width: 5.801104972375691%;
*width: 5.747913483013988%;
}
.row-fluid .offset12 {
margin-left: 105.52486187845304%;
*margin-left: 105.41847889972962%;
}
.row-fluid .offset12:first-child {
margin-left: 102.76243093922652%;
*margin-left: 102.6560479605031%;
}
.row-fluid .offset11 {
margin-left: 96.96132596685082%;
*margin-left: 96.8549429881274%;
}
.row-fluid .offset11:first-child {
margin-left: 94.1988950276243%;
*margin-left: 94.09251204890089%;
}
.row-fluid .offset10 {
margin-left: 88.39779005524862%;
*margin-left: 88.2914070765252%;
}
.row-fluid .offset10:first-child {
margin-left: 85.6353591160221%;
*margin-left: 85.52897613729868%;
}
.row-fluid .offset9 {
margin-left: 79.8342541436464%;
*margin-left: 79.72787116492299%;
}
.row-fluid .offset9:first-child {
margin-left: 77.07182320441989%;
*margin-left: 76.96544022569647%;
}
.row-fluid .offset8 {
margin-left: 71.2707182320442%;
*margin-left: 71.16433525332079%;
}
.row-fluid .offset8:first-child {
margin-left: 68.50828729281768%;
*margin-left: 68.40190431409427%;
}
.row-fluid .offset7 {
margin-left: 62.70718232044199%;
*margin-left: 62.600799341718584%;
}
.row-fluid .offset7:first-child {
margin-left: 59.94475138121547%;
*margin-left: 59.838368402492065%;
}
.row-fluid .offset6 {
margin-left: 54.14364640883978%;
*margin-left: 54.037263430116376%;
}
.row-fluid .offset6:first-child {
margin-left: 51.38121546961326%;
*margin-left: 51.27483249088986%;
}
.row-fluid .offset5 {
margin-left: 45.58011049723757%;
*margin-left: 45.47372751851417%;
}
.row-fluid .offset5:first-child {
margin-left: 42.81767955801105%;
*margin-left: 42.71129657928765%;
}
.row-fluid .offset4 {
margin-left: 37.01657458563536%;
*margin-left: 36.91019160691196%;
}
.row-fluid .offset4:first-child {
margin-left: 34.25414364640884%;
*margin-left: 34.14776066768544%;
}
.row-fluid .offset3 {
margin-left: 28.45303867403315%;
*margin-left: 28.346655695309746%;
}
.row-fluid .offset3:first-child {
margin-left: 25.69060773480663%;
*margin-left: 25.584224756083227%;
}
.row-fluid .offset2 {
margin-left: 19.88950276243094%;
*margin-left: 19.783119783707537%;
}
.row-fluid .offset2:first-child {
margin-left: 17.12707182320442%;
*margin-left: 17.02068884448102%;
}
.row-fluid .offset1 {
margin-left: 11.32596685082873%;
*margin-left: 11.219583872105325%;
}
.row-fluid .offset1:first-child {
margin-left: 8.56353591160221%;
*margin-left: 8.457152932878806%;
}
input,
textarea,
.uneditable-input {
margin-left: 0;
}
.controls-row [class*="span"] + [class*="span"] {
margin-left: 20px;
}
input.span12,
textarea.span12,
.uneditable-input.span12 {
width: 710px;
}
input.span11,
textarea.span11,
.uneditable-input.span11 {
width: 648px;
}
input.span10,
textarea.span10,
.uneditable-input.span10 {
width: 586px;
}
input.span9,
textarea.span9,
.uneditable-input.span9 {
width: 524px;
}
input.span8,
textarea.span8,
.uneditable-input.span8 {
width: 462px;
}
input.span7,
textarea.span7,
.uneditable-input.span7 {
width: 400px;
}
input.span6,
textarea.span6,
.uneditable-input.span6 {
width: 338px;
}
input.span5,
textarea.span5,
.uneditable-input.span5 {
width: 276px;
}
input.span4,
textarea.span4,
.uneditable-input.span4 {
width: 214px;
}
input.span3,
textarea.span3,
.uneditable-input.span3 {
width: 152px;
}
input.span2,
textarea.span2,
.uneditable-input.span2 {
width: 90px;
}
input.span1,
textarea.span1,
.uneditable-input.span1 {
width: 28px;
}
}

@media (max-width: 767px) {
body {
padding-right: 20px;
padding-left: 20px;
}
.navbar-fixed-top,
.navbar-fixed-bottom,
.navbar-static-top {
margin-right: -20px;
margin-left: -20px;
}
.container-fluid {
padding: 0;
}
.dl-horizontal dt {
float: none;
width: auto;
clear: none;
text-align: left;
}
.dl-horizontal dd {
margin-left: 0;
}
.container {
width: auto;
}
.row-fluid {
width: 100%;
}
.row,
.thumbnails {
margin-left: 0;
}
.thumbnails > li {
float: none;
margin-left: 0;
}
[class*="span"],
.uneditable-input[class*="span"],
.row-fluid [class*="span"] {
display: block;
float: none;
width: 100%;
margin-left: 0;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.span12,
.row-fluid .span12 {
width: 100%;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.row-fluid [class*="offset"]:first-child {
margin-left: 0;
}
.input-large,
.input-xlarge,
.input-xxlarge,
input[class*="span"],
select[class*="span"],
textarea[class*="span"],
.uneditable-input {
display: block;
width: 100%;
min-height: 30px;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.input-prepend input,
.input-append input,
.input-prepend input[class*="span"],
.input-append input[class*="span"] {
display: inline-block;
width: auto;
}
.controls-row [class*="span"] + [class*="span"] {
margin-left: 0;
}
.modal {
position: fixed;
top: 20px;
right: 20px;
left: 20px;
width: auto;
margin: 0;
}
.modal.fade {
top: -100px;
}
.modal.fade.in {
top: 20px;
}
}

@media (max-width: 480px) {
.nav-collapse {
-webkit-transform: translate3d(0, 0, 0);
}
.page-header h1 small {
display: block;
line-height: 20px;
}
input[type="checkbox"],
input[type="radio"] {
border: 1px solid #ccc;
}
.form-horizontal .control-label {
float: none;
width: auto;
padding-top: 0;
text-align: left;
}
.form-horizontal .controls {
margin-left: 0;
}
.form-horizontal .control-list {
padding-top: 0;
}
.form-horizontal .form-actions {
padding-right: 10px;
padding-left: 10px;
}
.media .pull-left,
.media .pull-right {
display: block;
float: none;
margin-bottom: 10px;
}
.media-object {
margin-right: 0;
margin-left: 0;
}
.modal {
top: 10px;
right: 10px;
left: 10px;
}
.modal-header .close {
padding: 10px;
margin: -10px;
}
.carousel-caption {
position: static;
}
}

@media (max-width: 979px) {
body {
padding-top: 0;
}
.navbar-fixed-top,
.navbar-fixed-bottom {
position: static;
}
.navbar-fixed-top {
margin-bottom: 20px;
}
.navbar-fixed-bottom {
margin-top: 20px;
}
.navbar-fixed-top .navbar-inner,
.navbar-fixed-bottom .navbar-inner {
padding: 5px;
}
.navbar .container {
width: auto;
padding: 0;
}
.navbar .brand {
padding-right: 10px;
padding-left: 10px;
margin: 0 0 0 -5px;
}
.nav-collapse {
clear: both;
}
.nav-collapse .nav {
float: none;
margin: 0 0 10px;
}
.nav-collapse .nav > li {
float: none;
}
.nav-collapse .nav > li > a {
margin-bottom: 2px;
}
.nav-collapse .nav > .divider-vertical {
display: none;
}
.nav-collapse .nav .nav-header {
color: #777777;
text-shadow: none;
}
.nav-collapse .nav > li > a,
.nav-collapse .dropdown-menu a {
padding: 9px 15px;
font-weight: bold;
color: #777777;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
}
.nav-collapse .btn {
padding: 4px 10px 4px;
font-weight: normal;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
}
.nav-collapse .dropdown-menu li + li a {
margin-bottom: 2px;
}
.nav-collapse .nav > li > a:hover,
.nav-collapse .nav > li > a:focus,
.nav-collapse .dropdown-menu a:hover,
.nav-collapse .dropdown-menu a:focus {
background-color: #f2f2f2;
}
.navbar-inverse .nav-collapse .nav > li > a,
.navbar-inverse .nav-collapse .dropdown-menu a {
color: #999999;
}
.navbar-inverse .nav-collapse .nav > li > a:hover,
.navbar-inverse .nav-collapse .nav > li > a:focus,
.navbar-inverse .nav-collapse .dropdown-menu a:hover,
.navbar-inverse .nav-collapse .dropdown-menu a:focus {
background-color: #111111;
}
.nav-collapse.in .btn-group {
padding: 0;
margin-top: 5px;
}
.nav-collapse .dropdown-menu {
position: static;
top: auto;
left: auto;
display: none;
float: none;
max-width: none;
padding: 0;
margin: 0 15px;
background-color: transparent;
border: none;
-webkit-border-radius: 0;
-moz-border-radius: 0;
border-radius: 0;
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none;
}
.nav-collapse .open > .dropdown-menu {
display: block;
}
.nav-collapse .dropdown-menu:before,
.nav-collapse .dropdown-menu:after {
display: none;
}
.nav-collapse .dropdown-menu .divider {
display: none;
}
.nav-collapse .nav > li > .dropdown-menu:before,
.nav-collapse .nav > li > .dropdown-menu:after {
display: none;
}
.nav-collapse .navbar-form,
.nav-collapse .navbar-search {
float: none;
padding: 10px 15px;
margin: 10px 0;
border-top: 1px solid #f2f2f2;
border-bottom: 1px solid #f2f2f2;
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);
-moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);
}
.navbar-inverse .nav-collapse .navbar-form,
.navbar-inverse .nav-collapse .navbar-search {
border-top-color: #111111;
border-bottom-color: #111111;
}
.navbar .nav-collapse .nav.pull-right {
float: none;
margin-left: 0;
}
.nav-collapse,
.nav-collapse.collapse {
height: 0;
overflow: hidden;
}
.navbar .btn-navbar {
display: block;
}
.navbar-static .navbar-inner {
padding-right: 10px;
padding-left: 10px;
}
}

@media (min-width: 980px) {
.nav-collapse.collapse {
height: auto !important;
overflow: visible !important;
}
}

+ 0
- 6180
themes/bootstrap2/static/css/bootstrap.css View File

@@ -1,6180 +0,0 @@
/*!
* Bootstrap v2.3.2
*
* Copyright 2012 Twitter, Inc
* Licensed under the Apache License v2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Designed and built with all the love in the world @twitter by @mdo and @fat.
*/

.clearfix {
*zoom: 1;
}

.clearfix:before,
.clearfix:after {
display: table;
line-height: 0;
content: "";
}

.clearfix:after {
clear: both;
}

.hide-text {
font: 0/0 a;
color: transparent;
text-shadow: none;
background-color: transparent;
border: 0;
}

.input-block-level {
display: block;
width: 100%;
min-height: 30px;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}

article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
nav,
section {
display: block;
}

.summary {
font-family: Arial;
font-size: 16px;
}