30/06/2015

Weblog de Natacha >> Autres temps, autres supports

Par : Natacha Kerensikova
Tags:
Site

Ça fait déjà six ans et demi que ce weblog fonctionne, et ceci en est le cent trente huitième article. C'est un temps raisonnable pour remettre en question sa façon de fonctionner, et peut-être essayer de nouvelles choses.

J'imagine que ce n'est pas le meilleur moment pour sonder un lectorat, mais je vais quand même essayer, pour voir.

J'ai déjà quelques idées en tête, mais elles sont loin d'être révolutionnaires. Comme j'ai l'ambition de faire de ce site plus qu'un simple préchoir dans le désert, j'aimerais beaucoup avoir votre avis sur les différentes façons de vous faire parvenir mon contenu habituel, et en bonus votre avis sur quelques idées de nouveau contenu.

Parmi les nouvelles idées de contenu, j'ai surtout retenu :

Merci de répondre à chaque point de ce petit sondage en postant un commentaire ci-dessous, ou dans le champ « message » si préférez que votre réponse ne soit pas publiée, ou par le formulaire de contact, ou par tout autre support à votre convenance.

Même une lettre en braille pour démonter l'idée d'un blog-BD serait bienvenue, c'est dire…


23/06/2015

Olivier's Blog >> Serial-PXE-TFTP install of FreeBSD(BSDRP,Xsense,NAS4Free)/OpenBSD/Centos

Tags:
BSDRP
FreeBSD
english
linux

Objectives

Remote  installation of multiples Operating systems using only:

I didn't found an easy way for PXE+TFTP (only!) serial remote installation for NetBSD or DragonFly.
FreeBSD was very complex too (need to recompile bootloader for TFTP and serial usage), but hopefully mfsBSD hides this problem.
OpenBSD and CentOS, by providing ramdisk natively and easy way of configuring their bootloader, were the most admin-friendly.

dnsmasq

This step will install an all-in-once DHCP/TFTP server:
pkg install dnsmasq
Then, create a small configuration file (example with "bce1" as NIC and local subnet in 192.168.1.0/24)
cat > /usr/local/etc/dnsmasq.conf <<EOF
interface=bce1
dhcp-range=192.168.1.80,192.168.1.85
pxe-service=x86PC, "pxelinux", pxelinux
enable-tftp
tftp-root=/tftpboot
EOF


And start it:
sysrc dnsmasq_enable=yes
service dnsmasq start

pxelinux

This step will install pxelinux binaries and configure PXE menu:
mkdir /tftpboot
cd /tftpboot
fetch https://www.kernel.org/pub/linux/utils/boot/syslinux/syslinux-6.03.zip
unzip -d syslinux syslinux-6.03.zip
cp syslinux/bios/memdisk/memdisk /tftpboot
cp syslinux/bios/core/pxelinux.0 /tftpboot
cp syslinux/bios/com32/elflink/ldlinux/ldlinux.c32 /tftpboot
cp syslinux/bios/com32/menu/menu.c32 /tftpboot
cp syslinux/bios/com32/libutil/libutil.c32 /tftpboot
cp syslinux/bios/com32/modules/pxechn.c32 /tftpboot
cp syslinux/bios/com32/lib/libcom32.c32 /tftpboot

cp syslinux/bios/com32/chain/chain.c32 /tftpboot
cp syslinux/bios/com32/modules/reboot.c32 /tftpboot/
rm syslinux-6.03.zip
rm -rf syslinux
mkdir /tftpboot/pxelinux.cfg
cat > /tftpboot/pxelinux.cfg/default <<EOF

SERIAL 0 115200
CONSOLE 0
UI menu.c32
TIMEOUT 300
MENU TITLE PXE BOOT MENU
LABEL freebsd
 MENU DEFAULT
 MENU LABEL mfsbsd (FreeBSD, pfSense, BSDRP, NAS4Free, etc...)
 KERNEL memdisk
 APPEND initrd=/mfsbsd-10.1-RELEASE-amd64.img harddisk raw
LABEL openbsd
 MENU LABEL OpenBSD
 KERNEL pxechn.c32
 APPEND ::/openbsd/pxeboot
LABEL netbsd
 MENU LABEL NetBSD
 KERNEL pxechn.c32
 APPEND ::/netbsd/pxeboot_ia32_com0.bin
LABEL centos
 MENU LABEL Centos 7
 kernel centos/vmlinuz
 append initrd=centos/initrd.img method=http://mirror.centos.org/centos/7/os/x86_64/ devfs=nomount ip=dhcp console=ttyS0,115200 earlyprint=serial,ttyS0,115200
LABEL local
 MENU LABEL local disk
 KERNEL chain.c32
 APPEND hd0

LABEL reboot
 MENU LABEL reboot
 KERNEL reboot.c32
EOF

FreeBSD

Download mfsBSD image and enable serial port:
fetch -o /tftpboot/mfsbsd-10.1-RELEASE-amd64.img http://mfsbsd.vx.sk/files/images/10/amd64/mfsbsd-10.1-RELEASE-amd64.img
mdconfig -a -t vnode -f mfsbsd-10.1-RELEASE-amd64.img
mount /dev/md0a /mnt/
echo "-S115200 -h" > /mnt/boot.config

umount /mnt
mdconfig -d -u 0

OpenBSD

Download OpenBSD's pxeboot and RamDisk image, then enable serial port:
mkdir /tftpboot/openbsd/
fetch -o /tftpboot/openbsd/pxeboot http://ftp.openbsd.org/pub/OpenBSD/5.7/amd64/pxeboot
fetch -o /tftpboot/openbsd/bsd.rd http://ftp.openbsd.org/pub/OpenBSD/5.7/amd64/bsd.rd
mkdir /tftpboot/etc
cat > /tftpboot/etc/boot.conf <<EOF
stty com0 115200
set tty com0
boot tftp:/openbsd/bsd.rd
EOF

CentOS

Download CentOS kernel and RamDisk:
mkdir /tftpboot/centos
fetch -o /tftpboot/centos/initrd.img ftp://ftp.free.fr/mirrors/ftp.centos.org/7.1.1503/os/x86_64/images/pxeboot/initrd.img
fetch -o /tftpboot/centos/vmlinuz ftp://ftp.free.fr/mirrors/ftp.centos.org/7.1.1503/os/x86_64/images/pxeboot/vmlinuz

Installing BSDRP, pfSense, OPNsense, NAS4Free, or any nanoBSD

From mfsbsd, just dd their serial nanobsd/embedded image to the local hard drive.
For installing FreeBSD: just uses bsdinstall

Debugging PXE/TFTP process

From the server, start a tcpdump accepting only bootps and tftp packets:
tcpdump -ni bce1 -vv port bootps or port tftp


15/06/2015

Philpep's blog >> Changer l'adresse IP d'un serveur

Par : Philippe Pepiot
Tags:
iptables
linux

Aujourd'hui il n'est pas rare d'avoir à changer l'adresse IP d'un serveur, par exemple si vous changez de fournisseur.

Dans mon cas je devais migrer tout mes services, à savoir du web, du mail et du dns, d'un serveur à un autre sans avoir la possibilité de garder mon adresse IP. L'occasion pour moi de vous donner quelques bons conseils sur cette opération toujours un peu délicate. Le but étant d'avoir un minimum de temps de coupure.

Donc la première bonne chose à faire c'est de baisser le TTL de vos enregistrement DNS, c'est tout simplement le temps en secondes pendant lequel l'enregistrement pourra rester en cache sur les serveurs DNS récursifs, comme ça le jour où vous changez l'enregistrement DNS la propagation ira beaucoup plus vite.

Moi je suis passé de 1 jour, ou 86400 secondes, à 5 minutes, soit 300 secondes:

mail 300 IN A 178.33.42.27

Évidement dans mon cas il faudrait attendre un jour le temps que le nouveau TTL se propage et ensuite espérer n'avoir que 5 minutes de problèmes. Mais ça suppose que le serveur DNS de vos visiteurs respecte bien le TTL que vous avez indiqué, et ce n'est pas toujours le cas et puis 5 minutes c'est déjà trop long pour un perfectioniste comme vous non ?

Donc les idées qui viennent ensuite sont de rendre accessible le service depuis l'ancien serveur même si le service tourne sur le nouveau serveur. Surtout si vous avez un VPN entre vos deux serveurs. On peut par exemple monter des proxy inverses voire même faire du NAT mais ces deux solutions ont le désavantage de modifier l'adresse IP source des requêtes, ce qui peut être très gênant si comme moi vous utilisez des antispam basés sur l'adresse IP comme le DNSBL.

La solution que j'ai utilisée c'est tout simplement de faire du routage à travers mon VPN, l'idée est simple mais dans les faits c'est assez compliqué. Voilà un schéma simplifié du réseau:

                 +----------------+                                    +-----------------+
<- 1.2.3.4 eth0 -| Ancien serveur | vpn0 10.0.0.1 <---> 10.0.0.2 vpn0 -| Nouveau serveur |- eth0 5.6.7.8 ->
                 +----------------+                                    +-----------------+

Ce que l'on veut c'est qu'un visiteur qui se connecte sur 1.2.3.4 soit routé dans le VPN jusqu'au service qui tourne sur le nouveau serveur (et qui écoute sur 10.0.0.2 et sur 5.6.7.8).

Une redirection comme ça est un cas d'école avec iptables, par exemple pour le port http:

vieux:~# iptables -t nat -A PREROUTING -i eth0 -p tcp --dport http -j DNAT --to 10.0.0.2

Là le paquet va bien arriver sur 10.0.0.2, mais les paquets retour vont repartir avec l'IP source 5.6.7.8 car c'est la route par défaut pour répondre à l'IP de votre visiteur. Du coup il faut faire une table de routage dédiée à ce traffic pour faire en sorte que tout ce qui arrive sur 10.0.0.2 reparte sur 10.0.0.1

nouveau:~# echo "200 VPN" >> /etc/iproute2/rt_tables
nouveau:~# ip route add default via 10.0.0.1 dev vpn0 table VPN
nouveau:~# iptables -t mangle -A PREROUTING -i vpn0 -p tcp -m connmark --cstate NEW -j CONNMARK --set-mark 1
nouveau:~# iptables -t mangle -A PREROUTING -j CONNMARK --restore-mark
nouveau:~# ip rule add fwmark 1 table VPN

Ici on crée une table de routage "VPN" qui a une route par défaut vers 10.0.0.1. Ensuite avec iptables on matche les connexions tcp qui arrivent sur l'interface vpn0 (CONNMARK) avec le numéro arbitraire 1.

La deuxième règle iptables sert à marquer les paquets qui ont CONNMARK à 1 avec MARK à 1, c'est équivalent à iptables -t mangle -A PREROUTING -m connmark --mark 1 -j MARK --set-mark 1. CONNMARK marque les connections et MARK les paquets mais iproute (la commande suivante) ne comprends que le marquage des paquets.

La dernière commande ip rule add fwmark 1 table VPN permet de dire au système de routage d'utiliser la table de routage "VPN" quand les paquets sont marqués à 1.

À ce stade les paquets retour reviennent bien sur l'ancien serveur, il ne reste plus qu'à faire du source NAT pour qu'ils repartent avec l'IP 1.2.3.4:

vieux:~# iptables -t nat -A POSTROUTING -s 10.0.0.2 -o eth0 -j SNAT --to-source 1.2.3.4

Et voilà, le service est accessible depuis les deux adresses publiques, et dans les deux cas le service verra la vraie adresse source du client.


11/06/2015

There is no spoon. >> Keyboard issues with i3wm on Ubuntu 15.04

Par : kAworu
Tags:
i3wm Logo

Since the update to 15.04 "Vivid Vervet" I've experienced some new input issues: I could not input some characters, most notably those requiring a combination of key to press. With a swiss-french layout I could not input stuff like ` ^ ~ and use my configured compose key. The culprit was unknown to me until then: IBus.

To solve this issue, you can either launch im-config(8) as user and select the "none" Input Method or simply do:

% echo "run_im none" > ~/.xinputrc
Now restart X and enjoy your keyboard back.
06/06/2015

Emile "iMil" Heitor 's home >> EC2 VPN connection informations (updated)

Par : iMil
Tags:
AWS
Blogroll
VPC
VPN
XML
python

For a mysterious reason, EC2 VPN connection informations are stored in XML within the JSON data retrieved by either boto or the awscli command line tool.

Here’s a quick python snippet to convert those datas in a convenient, easily parsable dict:

#!/usr/bin/env python

import sys
import boto3
import xmltodict

profile = sys.argv[1]

s = boto3.Session(profile_name=profile)
ec2 = s.client('ec2')

vpn = ec2.describe_vpn_connections()
x = vpn['VpnConnections'][0]['CustomerGatewayConfiguration']

d = xmltodict.parse(x)

# ...

Combining this piece of code with jinja2 could help you generate racoon (or whatever IPSec software you use) on the fly.

Update

here‘s a complete example of an automatic generation for racoon / ipsec configuration files using the previous snippet, along with jinja2.

The post EC2 VPN connection informations (updated) appeared first on Emile "iMil" Heitor 's home.


04/06/2015

Emile "iMil" Heitor 's home >> Latency based Alias DNS record in Route53

Par : iMil
Tags:
AWS
Blogroll
CloudFormation
Route53
python
troposphere

Yes, I know I write a lot about AWS these days, but you know, obsession is my thing.

So as I wrote earlier, I generate my CloudFormation templates using troposphere, and the one thing I had to finish today was to register a latency based Alias record on Route53 for an ELB. While Route53 GUI is fairly easy to use, I’ve been stuck on its programmatic emanation for quite a while, so here’s a troposphere definition of such a CloudFormation object:

if scheme == 'internal':
    # for details about this condition, read:
    # http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-elb.html
    canonzn = 'DNSName'
else:
    canonzn = 'CanonicalHostedZoneName'

name = 'foo'
profile = 'eu-west-1'

fooDNSRecord = t.add_resource(RecordSetType(
    'fooDNSRecord'.format(name),
    HostedZoneName = Join('', [Ref('SubZone'), '.']),
    Comment = '{0} DNS Name'.format(name),
    Name = Join('', ['{0}.'.format(name), Ref('SubZone'), '.']),
    Type = 'A',
    Region = region,
    SetIdentifier = '{0}-{1}'.format(name, profile),
    AliasTarget = AliasTarget(
        GetAtt('{0}LoadBalancer'.format(name), 'CanonicalHostedZoneNameID'),
        GetAtt('{0}LoadBalancer'.format(name), canonzn)
    )
))

Note the catch, you can’t use Ref('AWS::Region') for the Region parameter or your CloudFormation will fail at the DNS entry creation with the Invalid request error. Do not forget to declare the SetIdentifier parameter which is mandatory for a latency-type record.

The post Latency based Alias DNS record in Route53 appeared first on Emile "iMil" Heitor 's home.


04/06/2015

Emile "iMil" Heitor 's home >> Rock your CloudFormation with troposphere and boto

Par : iMil
Tags:
AWS
Blogroll
CloudFormation
DevOps
python

So you’re using AWS CloudFormation in order to bring up complex infrastructures; haven’t you already told yourself that instead of writing down all those JSON lines by hand, you could bring more fun to your architect life?
I did, and I found a way to programmatically design a whole architecture using troposphere and boto3.
Simply put, troposphere gives you bindings in order to generate CloudFormation‘s JSON template, but hey, it’s python, meaning that you can create loops, use conditions and even dynamically build objects.

Let me give a simple example on how this will change your Cloud builder life. Let’s assume you’d like to create a couple of defaults SecurityGroups, we’ll create a convenient dict that will hold needed informations:

sgs = [{
    'name': 'SSHAny',
    'tag': 'ssh-any',
    'cidr': '0.0.0.0/0',
    'proto': 'tcp',
    'port': 22
},{
    'name': 'ICMPAny',
    'tag': 'icmp-any',
    'cidr': '0.0.0.0/0',
    'proto': 'icmp',
    'port': -1
},{
    'name': 'HTTPAny',
    'tag': 'http-any',
    'cidr': '0.0.0.0/0',
    'proto': 'tcp',
    'port': 80
},{
    'name': 'HTTPSAny',
    'tag': 'https-any',
    'cidr': '0.0.0.0/0',
    'proto': 'tcp',
    'port': 443
},{
    'name': 'SSHHQAny',
    'tag': 'ssh-hq',
    'cidr': Ref('HQCIDR'),
    'proto': 'tcp',
    'port': 22
},{
    'name': 'SSHOver2000',
    'tag': 'ssh-over-2000-any',
    'cidr': '0.0.0.0/0',
    'proto': 'tcp',
    'port': '2000-2200'
},{
    'name': 'SMTPAny',
    'tag': 'smtp-any',
    'cidr': '0.0.0.0/0',
    'proto': 'tcp',
    'port': 25
}]

Note that you could use any structure type you like, I just found this one to be practical. Now, dynamically build all the associated SecurityGroups:

def mksg(cidr, proto, ports):
    sg = []
    for port in ports:
        if type(port) is not int and '-' in port:
            [fromport, toport] = port.split('-')
        else:
            fromport = port
            toport = port
        sg.append(
            SecurityGroupRule(
                IpProtocol = proto,
                FromPort = fromport,
                ToPort = toport,
                CidrIp = cidr
            )
        )
    return sg

# ...

for sg in sgs:
    sgname = '{0}SecurityGroup'.format(sg['name'])
    vars()[sgname] = t.add_resource(SecurityGroup(
        '{0}SecurityGroup'.format(sg['name']),
        GroupDescription = 'Enable port(s) {0} from {1}'.format(
            sg['port'], sg['cidr']
        ),
        SecurityGroupIngress = mksg(sg['cidr'], sg['proto'], [sg['port']]),
        VpcId = Ref('VPC'),
        Tags = Tags(Name = '{0}'.format(sg['tag']))
    ))

Now, to bring a little bit more of awesomeness, consider adding the power of Amazon‘s own python module, boto3. Haven’t you struggled by writing AMI mapping directly on the JSON file? Well consider the following function:

import boto3

s = boto3.session.Session(profile_name = sys.argv[1])
ec2 = s.resource('ec2')

def getami(glob):
    return [
        i for i in ec2.images.filter(
            Filters=[ {'Name': 'name', 'Values': [glob]} ]
        )
    ][-1]

And later on your JSON generator, using troposphere wrappers:

MyInstance = t.add_resource(Instance(
    'MyInstance',

    ImageId = getami('amzn-ami-vpc-nat-hvm*').id,

    InstanceType = 't2.micro',
    KeyName = Ref('KeyName'),
    SecurityGroupIds = [Ref('SecurityGroup')],
    SubnetId = Ref('MySubnet'),
))

Troposphere website has an example section that contains a lot of useful examples in order to manipulate all well-known AWS products.

HTH!

The post Rock your CloudFormation with troposphere and boto appeared first on Emile "iMil" Heitor 's home.


28/05/2015

Emile "iMil" Heitor 's home >> Reserved Instances mystery solved

Par : iMil
Tags:
AWS
Blogroll
Reserved Instances

AWS is an amazing piece of cloud, but the documentation is not always clear. I’ve been scratching my head trying to understand how Reserved Instances pricing was applied to actual instances. First I was searching for a “Launch a Reserved Instance” button, or even “Associate this Reserved Instance”, but no, nothing. I found the official documentation to be quite evasive so I took my chance on the ##aws IRC channel on irc.freenode.net; there I found a very friendly community that explained me (and many more after me) the simple truth: It’s all automagic!

In short: once you purchased a Reserved Instance, any instance that will match this RI properties will have its price set to the purchased RI. That simple.

The post Reserved Instances mystery solved appeared first on Emile "iMil" Heitor 's home.


20/05/2015

Emile "iMil" Heitor 's home >> aws cli and jq filtering

Par : iMil
Tags:
AWS
Blogroll
cli
filter
jq

Long time no see huh? ;)

I’m diving into Amazon Web Services for some months now, and I must say I’m pretty impressed by the overall quality. Compared to the other “clouds” I’ve played with, it’s the most mature and comprehensive by far.

While writing a couple of tools to make my life easier, there’s one piece that took me longer: filtering the output of the aws ec2 describe-instances command. The output is in JSON, which is quite nice you might say, and it is, but when it comes to interact with JSON in the command line, things can get a little messy.

There’s a fantastic tool around to ease the process, its name is jq. While its basic usage is pretty straightforward, things are way more complicated to order and filter datas coming out from the aws command line.

Here are a couple of examples that I would have loved someone had written before me:

aws ec2 describe-instances | jq '.Reservations[].Instances[]'

That command will output the full instances list and their properties.

aws ec2 describe-instances | jq -r '.Reservations[].Instances[].InstanceId'

This will output your instances id list in a raw (-r) format

Now what about listing your instances ids, followed by the names you gave in the tag property? Sounds easy right? well let’s see:

aws ec2 describe-instances | jq -r '.Reservations[].Instances[]|.InstanceId + " " + (.Tags[]|select(.["Key"] == "Name")|.Value)'

Yeaah, right, now you get what I meant. You might want to crawl jq’s official documentation, but honestly it served me very little in comparison of this fantastic post written by a guy with much more patience than I have :)

Hope this helps!

The post aws cli and jq filtering appeared first on Emile "iMil" Heitor 's home.


08/05/2015

There is no spoon. >> running php-fpm inside a FreeBSD jail

Par : kAworu
Tags:
FreeBSD Logo

I had an issue while trying to run a php-fpm FastCGI process from a FreeBSD jail using nginx from the host. Like many others I experienced the infamous White Screen Of Death™ but no errors were logged at all (even with the full debug config all set from both php-fpm.conf and php.ini).

nginx.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# ...
upstream princesse-bulldozer-php-fpm {
    server [2a01:4f8:120:5388:0:b:249:1]:9000;
} server {
    listen   *:80;
    listen   [::]:80;
    # ...
    root /usr/jails/jail0.kaworu.ch/home/princesse-bulldozer.ch/wordpress;
    index index.php;
    # Pass all .php files onto a php-fpm/php-fcgi server.
    location ~ [^/]\.php(/|$) {
        fastcgi_index index.php;

        fastcgi_pass princesse-bulldozer-php-fpm;
        # fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param SCRIPT_FILENAME /home/princesse-bulldozer.ch/wordpress$fastcgi_script_name;
        include fastcgi_params;
    }
}

As nginx is run from the host, using the "full" path as root (line 8) is correct. But since php-fpm is jailed, the SCRIPT_FILENAME path should not use $document_root (see line 15 which does not work). It has to be set to the "jailed" path (line 16). Hope it can avoid a couple of painful debugging out there :)