Tag Archive: tutoriel


Recently, I needed to interconnect two private networks using on one side, a SOHO Cisco 871 router (because it’s silent, and people don’t want a desktop appliance to be as loud as an aircraft), and on the other side, an existing linux box with some services we want to connect to.

The main purpose of this setup is not to get optimal performances nor security, but to test interoperability on the two involved IPSec stack.

NAT configuration on the cisco side will be given as a bonus, at the end of this article, as it might be tricky to deal with simultaneous NAT and VPN.

You will find below the schema of our example setup.

netschemaIn our example, let’s assume our PSK is qFcOx72WVERsNobVsimx

Before we begin to overlook the configuration, let’s recall some points on IPSec.

IPSec is a quite complete protocol that can be used in a vast number of use cases: site to site VPNs, roadwarrior remote access, host to host security, with a focus on either integrity or integrity and confidentiality enforcement.

IPSec is thus commonly considered as a complex technology: its features are described and standardized by over 30 IETF RFCs, and it’s modularity reaches such a point that different implementations may not interoperate out of the box as we will see below. Some bonus features are not even standard (e.g. Opportunistic Encryption).

When two endpoints establish a security association (SA), the endpoint that attempt to establish the SA is called the initiator.

To summarize, the protocol works in two phases:

  • Phase 1:the security association and key management, where the two IPSec endpoints mutually authenticate and exchange keys that will be used on phase 2.
  • Phase 2: the security policy(ies) setup, where the two IPSec endpoints decide to do either encryption or authentication of the secured payload, and if they want to secure host to host, or network to network communications.

Here is the list of the different components that are involved in my sample setup:

  • Debian wheezy with a stock 3.2.54-2 kernel and the racoon and ipsec-tools packages from the official repository (version 1:0.8.0-14 for both these packages).
  • Cisco 871 with a Cisco IOS C870 Software (C870-ADVIPSERVICESK9-M), Version 12.4(15)T7, RELEASE (fc3)

Racoon configuration

To begin with, the configuration of racoon was not especially tricky until I experienced a strange issue: when the tunnel was initiated by the linux box, the phase 1 handshake worked properly, but the phase 2 failed to bring up, with a NO-PROPOSAL-CHOSEN error even if sa parameters were matching. If you have more feedback on this, you’re welcome to contribute in the comments. Edit: I have found what was the problem: I forgot to include the second sainfo section in racoon.conf, and I also made a mistake in the cisco configuration. Refer to the appropriate section for further details.

To avoid getting stuck in this case, I managed to make the linux box passive, and to bring up automatically the tunnel using a trick on the cisco side.

Racoon-issued dead peer detection also made my phase 2 die after timeout, as the cisco agent did not send appropriate replies. I addressed this issue by configuring racoon as a passive DPD responder.

/etc/racoon/racoon.conf

path pre_shared_key "/etc/racoon/psk.txt";
path certificate "/etc/racoon/certs";
log notify;

listen
{
	isakmp 198.51.100.37 [500];
}

remote 192.0.2.13 {
	exchange_mode aggressive,main;
	generate_policy off;
	my_identifier address 198.51.100.37;
	peers_identifier address 192.0.2.13;
	lifetime time 3600 sec;	
	passive on;
	
	proposal {
		encryption_algorithm 3des;
                authentication_method pre_shared_key;
                hash_algorithm sha1;
                dh_group 2;
		lifetime time 3600 sec;
	}
}


sainfo address 10.0.0.0/24[any] any address 10.224.9.0/24[any] any {
{
        pfs_group modp1024;
        encryption_algorithm 3des;
        authentication_algorithm hmac_sha1;
        compression_algorithm deflate;
        lifetime time 3600 sec;
}

sainfo address 10.224.9.0/24[any] any address 10.0.0.0/24[any] any {
{
        pfs_group modp1024;
        encryption_algorithm 3des;
        authentication_algorithm hmac_sha1;
        compression_algorithm deflate;
        lifetime time 3600 sec;
}

/etc/racoon/psk.conf

192.0.2.13 	qFcOx72WVERsNobVsimx

/etc/ipsec-tools.conf

#!/usr/sbin/setkey -f

flush;
spdflush;

spdadd 10.0.0.0/24 10.224.9.0/24 any -P out ipsec
    esp/tunnel/198.51.100.37-192.0.2.13/require;

spdadd 10.224.9.0/24 10.0.0.0/24 any -P in ipsec
    esp/tunnel/192.0.2.13-198.51.100.37/require;

Cisco 871 configuration

To get a nailed-up IPSec tunnel at boot time, I decided to set up a permanent ping probe using the ip sla feature of my IOS.

Edit: There was a mistake in the « crypto isakmp profile » section: when you use the match identity host directive, the identifier that follows is a fqdn, not an IP address. If you want to match IP addresses, use the match identity address directive. This is extremely important, as the phase 2 negociation might screw up because of this.

!
version 12.4
no service pad
service timestamps debug datetime msec
service timestamps log datetime msec
no service password-encryption
!
hostname nettest
!
boot-start-marker
boot-end-marker
!
!
no aaa new-model
!
!
dot11 syslog
ip cef
!
!
no ip dhcp use vrf connected
ip dhcp excluded-address 10.224.9.1
!
ip dhcp pool POOL_VLAN1
   network 10.224.9.0 255.255.255.0
   default-router 10.224.9.1 
!
!
ip domain name example.local
!
multilink bundle-name authenticated
!
!
username admin privilege 15 secret 0 youradminpassword
! 
!
crypto isakmp policy 1
 encr 3des
 authentication pre-share
 group 2
 lifetime 3600
crypto isakmp key qFcOx72WVERsNobVsimx address 198.51.100.37 no-xauth
crypto isakmp keepalive 10 3 periodic
crypto isakmp profile 1
   keyring default
   self-identity address
   match identity address 198.51.100.37
   keepalive 25 retry 3
!
!
crypto ipsec transform-set MyTransformSet esp-3des esp-sha-hmac 
!         
crypto map MyMap local-address FastEthernet4
crypto map MyMap isakmp-profile 1
crypto map MyMap 10 ipsec-isakmp 
 set peer 198.51.100.37
 set transform-set MyTransformSet 
 set pfs group2
 set isakmp-profile 1
 match address 150
!
archive
 log config
  hidekeys
!
!
ip tftp source-interface Vlan1
!
!
!
interface FastEthernet0
!
interface FastEthernet1
!
interface FastEthernet2
!
interface FastEthernet3
!
interface FastEthernet4
 description WAN interface
 ip address 192.0.2.13 255.255.255.0
 duplex auto
 speed auto
 crypto map MyMap
!
interface Vlan1
 description Internal interface
 ip address 10.224.9.1 255.255.255.0
 no autostate
!
ip forward-protocol nd
ip classless
ip route 0.0.0.0 0.0.0.0 192.0.2.13
!
!
no ip http server
no ip http secure-server
!
ip sla 10
 icmp-echo 10.0.0.1 source-interface Vlan1
 timeout 1000
 frequency 1
ip sla schedule 10 life forever start-time now
access-list 150 permit ip 10.224.9.0 0.0.0.255 10.0.0.0 0.0.0.255
!
!
!
!         
control-plane
!
banner motd ^C
*************************************************************
$(hostname) - VPN tests cisco router
Contact: Geoffroy GRAMAIZE
*************************************************************
^C
!
line con 0
 logging synchronous
 login local
 no modem enable
line aux 0
line vty 0 4
 logging synchronous
 login local
!
scheduler max-task-time 5000
end

As promised, If you want your internal network, on the cisco side, to communicate with the internet, you should add the following commands to the above configuration:

interface FastEthernet4
 ip nat outside
!
interface Vlan1
 ip nat inside
!
ip access-list extended NAT_list
 deny   ip 10.0.0.0 0.0.0.255 10.224.9.0 0.0.0.255
 deny   ip 10.224.9.0 0.0.0.255 10.0.0.0 0.0.0.255
 permit ip 10.224.9.0 0.0.0.255 any
!
ip nat inside source list NAT_list interface FastEthernet4 overload

I’ve recently purchased an Edgerouter PoE from Ubiquiti, which is a great deal regarding its price and performance. The only caveat was related to the lack of native support for load balancing and failover. This lack has been fixed with the release of the 1.4.0 firmware, which embeds a load balancing functionnality with native connection tracking.

For this example, I’ll take a generic scenario of a dual WAN setup, in a failover configuration with some policy routes, as we assume some ISP specific services are not available from the internet (e.g. administration interfaces, SMTP and DNS servers…)

Let’s also assume your ISP CPEs are configured in bridge mode.  To show all the potential of the router, the IP address we’ll get from ISP 1 is dynamic and the one from ISP 2 is static, but both are acquired from ISP’s DHCP server (yes, my ISP are serious people, and they don’t use PPPo[E|A] ^.^).

I also use an internal autonomous DNS server to avoid unreachability delays during failover, and to have a trusted DNSSEC anchor. You will find below the schema for this scenario. The fqdn and IP addresses in this scenario have been changed to protect the innocents.

Our sample topology.

Our sample topology.

To begin with, set up your 3 interfaces on the router, the dhcp on the inside part, and the DNAT rules.

interfaces {
    ethernet eth0 {
    address dhcp
        description ISP_1
        duplex auto
        poe {
            output off
        }
        speed auto
    }
    ethernet eth1 {
        address dhcp
        description ISP_2
        duplex auto
        poe {
            output off
        }
        speed auto
    }
    switch switch0 {
        address 192.168.0.254/24
        switch-port {
            interface eth2
            interface eth3
            interface eth4
        }
    }
}
service {
    dhcp-server {
        disabled false
        hostfile-update disable
        shared-network-name Home {
            authoritative disable
            subnet 192.168.0.0/24 {
                default-router 192.168.0.254
                dns-server 192.168.0.252
                lease 86400
                start 192.168.0.1 {
                    stop 192.168.0.50
                }
            }
        }
    }
}
nat {
    rule 5000 {
            description ISP_1_NAT
            log disable
            outbound-interface eth0
            protocol all
            type masquerade
    }
    rule 5001 {
            description ISP_2_NAT
            log disable
            outbound-interface eth1
            type masquerade
    }
}

Next, we’ll setup the load balancer to use ISP1 as our primary access and ISP2 as our failover access. I decided to change some of the check parameters to show you how powerful the tool is. As we are in a failover setup, I won’t use the weight command, which you would use for load balancing scenarios, to adjust the percentage of traffic you’d like to send to the corresponding interface.

load-balance {
    group lb-output {
        interface eth0 {
            route-test {
                count {
                    failure 3
                    success 4
                }
                interval 5
                type {
                    ping {
                        target 203.0.113.42
                    }
                }
            }
        }
        interface eth1 {
            failover-only
        }
    }
}

As told at the beginning of this article, the load balancer will take care of tracking and marking the connection, to avoid that a current session gets in and out by different IP addresses. This is especially useful if you decide to use SNAT rules. As shown above, I decided to check ISP 1 connectivity against a specific IP address, but by default, the equipment will run the check against « ping.ubnt.com ».

Next, we’ll configure the fwr-lbalance firewall modifier group to set the policy routes. This firewall modifier will be used to let the trafic through the load balancer « lb-output », expect for:

  • RFC1918 networks which we will route through the main routing table.
  • 192.0.2.129 which is only reachable via ISP 1 (we’ll set up the target VRF table 10 for this case).
  • 198.51.100.192/28 which is only reachable via ISP 2. (we’ll assume our gateway is 198.51.100.62, and we’ll set up another target VRF table 20 for this case).

Edit: ubnt-stig advised me to use a firewall group to define the RFC1918 in the comment, so you will find an updated version below.

And here is the associated configuration:

firewall {
    group {
        network-group RFC1918 {
            network 10.0.0.0/8
            network 172.16.0.0/12
            network 192.168.0.0/16
        }
    }
    modify fwr-lbalance {
        rule 1 {
            action modify
            destination {
                group {
                    network-group RFC1918
                }
            }
            modify {
                table main
            }
        }
        rule 100 {
            action modify
            destination {
                address 192.0.2.129
            }
            modify {
                table 10
            }
        }
        rule 200 {
            action modify
            destination {
                address 198.51.100.192/28
            }
            modify {
                table 20
            }
        }
        rule 500 {
            action modify
            modify {
                lb-group lb-output
            }
        }
    }
} 
protocols {
    static {
        table 10 {
            interface-route 0.0.0.0/0 {
                next-hop-interface eth0 {
                }
            }
        }
        table 20 {
            route 0.0.0.0/0 {
                next-hop 198.51.100.62 {
                }
            }
        }    
    }
}

Now, you need to tell the router to apply the firewall modifier instance to your internal interfaces:

interfaces {
    switch switch0 {
        address 192.168.0.254/24
        firewall {
            in {
                modify fwr-lbalance
            }
        }
        switch-port {
            interface eth2
            interface eth3
            interface eth4
        }
    }
}

And finally, you’re done! Your dual wan setup is operationnal. Now you can configure SNAT rules for your publicly available services. If you want to use different a different load balancing policy, create another load-balancer group with the appropriate settings, and add a new rule into the firewall modifier group. Before exiting configuration mode, don’t forget to commit the configuration, and to save the configuration if it fits your requirement.

Edit: On the following screenshot, you can see the output of the load-balancer status commands.

Load Balander status

Load Balander status

Hi,In this article, I’ll talk about some problems you might encounter while working on a Cisco device:

When I plug a device on my Cisco CPE, I have some issues to get a DHCP lease.

This problem is mainly caused by the following points:

  • Your CPE ports are configured with the default spanning-tree behaviour. With the default behaviour, after being plugged, a switch port is temporarily put in a blocking state for 30 to 50 seconds, to acquire and calculate STP topology. If this behaviour is absolutely safe, some early network applications – like DHCP – will be subject to timeout.
  • When plugging your first equipment, if your CPE uses a level 2 switch, and has « vlan » interfaces , the vlan management interface takes some time to toggle from down/down to up/up state. The DHCP server is bound to this interface, so it won’t be able to process a request until the associated vlan interface is in up/up state.

To deal with the first issue, you have either to use the following commands to switch the level 2 port in STP portfast mode:

interface fastethernet X
 spanning-tree portfast

or to disable the spanning tree for your VLAN by typing the following in configuration mode:

no spanning-tree vlan <VID>

To mitigate the second issue, you must stick the vlan interface to the up/up state. You can do so using the following commands:

interface vlan X
 no autostate

I have screwed while flashing my Cisco device! Rommon tells me that it cannot find a bootable image.

keepcalm

Using tftpdnld, you can load a bootable image from a TFTP server from the rommon prompt. To do so, hook up your Cisco device to a network with a TFTP server, and type the following commands in the rommon prompt:

IP_ADDRESS=X.X.X.X
IP_SUBNET_MASK=X.X.X.X
DEFAULT_GATEWAY=X.X.X.X
TFTP_SERVER=<tftp_server_IPv4_address>
TFTP_FILE=<path_to_your_IOS_image_on_tftp_server>
tftpdnld -r

Once your image has booted, copy again your image from TFTP to flash, then check its integrity by computing and checking the resulting hash.

copy tftp://<tftp_server_addr>/<path_to_IOS_image> flash:<image_filename>
verify /md5 flash:<image_filename>

Then, configure the bootloader to load your image at boot time:

configure terminal
 boot system flash:<image_filename>
 exit
copy running-config startup-config

Now, you can reboot safely and enjoy your fresh IOS image.

I don’t remember my login/enable password, how to recover it?

To begin with, you need a serial console client which support the break signal: this is something you can’t emulate only with your keyboard. If you don’t know what the break signal is, please refer to the following document: Cisco Standard Break Key Sequence Combinations

As the recovery procedures is model dependent, visit the Password Recovery Procedures web page where you will find the detailed instructions for your device.

À l’attention des personnes qui éditent leur site en direct (c’est très mal) et/ou qui oublient de supprimer leurs fichiers de sauvegarde avant de mettre en production, ce tweet devrait vous faire réfléchir…

Un hack de brute tout simple.

Un hack de brute bête et méchant.

Si vous éditez rapidement vos pages sur place et/ou que vous faites une copie de sauvegarde, les fichiers de sauvegarde que vous créez restent disponibles par défaut, et ne seront pas interprétés comme des scripts. Il devient facile d’accéder à votre code source et donc, éventuellement à des données sensibles comme les crédentiels de votre base de données par exemple.

Si vous êtes sur Apache, vous pouvez ajouter ceci dans votre fichier de configuration principal pour colmater cette vulnérabilité:

<Files ~ "(\.(bak|old)|\~)$">
    Order allow,deny
    Deny from all
    Satisfy all
</Files>

Pour terminer, relancez l’indien (^_–)  ~ ☆

Au cours de mes différentes expérimentations, j’ai voulu renforcer l’authentification de certains de mes services en m’appuyant sur une infrastructure à clés publiques dont je disposais déjà. Étant donné que la configuration du VirtualHost sur Apache n’a pas forcément été simple à mettre en place, je vous propose par la suite un template de Virtualhost que j’ai conçu. Les aspects relatifs à la gestion d’une PKI ou de la génération de certificats ne sera pas traitée dans ce billet.

Prérequis

La présente configuration suppose que vous disposiez au préalable:

  • d’un serveur Apache fonctionnel avec un virtualhost qui vous permettra de accueillir les utilisateurs dont l’authentification a échoué
  • des modules apache suivants (liste non exhaustive): mod_ssl, mod_rewrite, mod_headers
  • de certificats SSL serveurs et clients valides.

Gestion des erreurs

Un des problèmes principaux de l’authentification SSL repose sur le fait que le client se retrouve sur une page d’erreur du navigateur et non sur une page d’erreur de votre site web. La configuration suivante vous permettra de rediriger le client vers une autre page lui proposant éventuellement d’autres modes d’authentification (forte de préférence). La redirection mise en place est de type HTTP/307 et est complètement standard.

Pour notre exemple, je vous fournis une mire d’échec très simpliste en PHP qui permettra au client de relancer la procédure d’authentification vers le bon site une fois les problèmes corrigés de son côté. Pour la suite de ce billet, on supposera cette page accessible via l’URL suivante: https://login.yourdomain.com/sslfail.php

<html>
    <head>
        <title>FAIL</title>
    </head>
    <body>
        <p>SSL authentication failed. <?php
            if(isset($_GET["from"]))
            {
                echo("<a href=\"https://". $_GET["from"] .".yourdomain.com/\">Try Again.</a>");
            }
        ?></p>
    </body>
</html>

Le fichier VirtualHost

Pour la suite, on va considérer que le service à protéger sera accessible aux clients sur secureservice.yourdomain.com.

<IfModule mod_ssl.c>
    <VirtualHost *:443>
        ServerName secureservice.yourdomain.com
        DocumentRoot /var/secureservice-wwws

        # Configuration SSL côté serveur
        SSLEngine on
        SSLCertificateFile    /path/to/ca/certs/secureservice.pem
        SSLCertificateKeyFile /path/to/ca/private/secureservice.key
        SSLCertificateChainFile /path/to/ca/keystore/ca.crt

        # Configuration SSL côté client
        SSLCACertificateFile /path/to/ca/certs/ca.pem
        SSLCARevocationFile /path/to/ca/crl/ca-crl.crl
        SSLVerifyDepth  10

        <IfModule mod_rewrite.c>
            # If mod_rewrite is available, redirect clients on failure
            SSLVerifyClient optional

            <IfModule mod_headers.c>
                Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
                Header set Pragma "no-cache"
                Header set Expires "Wed, 11 Jan 1984 05:00:00 GMT"
            </IfModule>
            RewriteEngine On
            RewriteCond %{SSL:SSL_CLIENT_VERIFY} !^SUCCESS$
            RewriteRule .* https://login.yourdomain.com/sslfail.php?from=secureservice [r=307]
        </IfModule>
        <IfModule !mod_rewrite.c>
            # If mod_rewrite is not available, just deny clients on failure
            SSLVerifyClient require
        </IfModule>

        BrowserMatch "MSIE [2-6]" \
            nokeepalive ssl-unclean-shutdown \
            downgrade-1.0 force-response-1.0
        # MSIE 7 and newer should be able to use keepalive
        BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown
    </VirtualHost>
</IfModule>

Concernant les attributs côté client, je tiens à vous préciser quelque points: en plus de la configuration classique du certificat serveur, 3 lignes sont impératives pour mettre en place l’authentification SSL:

  • La ligne qui dit au serveur où chercher les certificats des CA qui ont signé les certificats client (SSLCACertificateFile). Le chemin doit impérativement pointer sur un fichier encodé au format PEM. Si vous avez plusieurs CA à prendre en compte, concaténez vos différents fichiers PEM et faites pointer cette ligne sur le fichier résultant.
  • La ligne qui indique combien de niveaux de validation sont supportés pour les certificats clients (SSLVerifyDepth).  Si la valeur associée vaut zéro, le certificat client doit être auto-signé. Si la valeur vaut 1, le certificat doit être validé par le certificat d’une autorité présente dans le fichier des autorité client. Si la valeur vaut 2 ou plus, le certificat peut avoir été signé par une autorité intermédiaire valide. Avec 2, le client peut avoir été signé par une CA signée par une CA présente dans le fichier des autorités.
  • La ligne qui va spécifier le comportement à tenir en cas d’échec. Lorsque SSLVerifyClient est positionné sur require, la négociation SSL/TLS sera annulée si le certificat de l’utilisateur n’est pas validé par le serveur. Le client sera informé par son navigateur que l’opération a échoué. Si par contre SSLVerifyClient est positionné sur optional, et que le certificat de l’utilisateur n’est toujours pas valide, la connexion s’établit quand même, mais il sera, dans notre cas, redirigé vers la page d’échec (http://login.tourdomain.com/sslfail.php?from=secureservice) par le biais d’une réponse HTTP/307. À ce sujet, il est très important d’ajouter le module headers à apache, car les navigateurs ont tendance à mettre en cache les redirections. Si une redirection est mise en cache, votre client pourrait croire que son authentification échoue en permanence, ce qui n’est pas souhaitable.

La spécification d’une liste de révocation de certificats n’est pas toujours nécessaire, mais il reste préférable de l’utiliser car elle vous permettra d’assurer une gestion des droits d’accès plus propre. La ligne avec SSLCARevocationFile doit pointer sur un fichier qui contient la concaténation de toutes les listes de révocation des autorités client encodées au format PEM.

En août 2010, OpenSSH 5.6 a ajouté le support de l’authentification serveur par certificats. Cette fonctionnalité peu évoquée va simplifier votre vie, même sur des réseaux de petite taille.

Si la clé de chacune de vos machines est signée par une autorité, les utilisateurs n’auront besoin que de cette autorité pour authentifier les machines de votre réseau. Ceci signifie entre autre le glas du célèbre et embêtant message:

The authenticity of host 'xxxxx (****:****:****::****:****)' can't be established.
RSA key fingerprint is xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx.

L’ampleur de la manœuvre est proportionnelle au nombre de machines dont vous disposez (sachant que c’est facilement scriptable dans certaines conditions), et bien plus simple que la génération de certificats avec openssl.

Tout au long du tutoriel suivant, on va considérer que nous sommes dans un dossier dédié, inaccessible à d’autre utilisateurs que root.

Étape 1: Générer une paire de clés pour l’autorité de certification

Cette paire de clés est sensible, gardez-la en lieu sûr et de préférence chiffrée.

ssh-keygen -b 4096 -t rsa -C "Mon_autorite" -f ca_cert

Étape 2: Signer la clé publique d’un serveur préalablement générée ou rapatriée

La clé publique du serveur à signer se nommera myhost_key.pub pour la suite du tutoriel.

Vous pouvez (et il est suggéré de) restreindre les noms d’hôtes valides pour votre serveur (dans notre cas hostname valid.hostname.org et server.example.com ).

L’exemple ci-dessous délivre une signature valable 1 an et un jour (option -V). Cette durée peut être changée à volonté; pour plus d’informations, echo $( rtfm -p ) 😉

ssh-keygen -h -s ca_cert -I IdentifiantDeLaClé -V +52w1d \
-n hostname,valid.hostname.org,server.example.com myhost_key.pub

Étape 3: Installer le certificat sur votre serveur

L’étape 2 vous a généré un fichier nommé myhost_key-cert.pub. Ce fichier est à copier dans le même dossier que la clé hôte sur le serveur.

Ajoutez la ligne suivante dans le fichier de configuration du démon OpenSSH (généralement /etc/ssh/sshd_config):

HostCertificate /chemin/vers/les/cles/myhost_key-cert.pub

Redémarrez le démon ssh de la machine concernée.

Répétez l’opération avec tous vos serveurs.

Étape 4: Installer les données de l’autorité sur votre compte client SSH.

Gardez le contenu de ca_cert.pub sous la main, vous allez en avoir besoin pour la suite.

Allez dans le dossier ~/.ssh de l’utilisateur concerné par l’installation de votre autorité.

Créez le fichier known_hosts_cert et ajoutez la ligne suivante et sauvez.

@cert-authority * <contenu du fichier ca_cert.pub>

C’est en place! Deux méthodes ensuite:

  • Connectez-vous directement à un de vos serveurs avec la commande suivante
ssh -oUserKnownHostsFile=~/.ssh/known_hosts_cert hostname
  • Ajoutez la ligne suivante à votre fichier .ssh/config pour les hôtes concernés
UserKnownHostsFile ~/.ssh/known_hosts_cert

Connectez-vous ensuite avec votre commande habituelle.

Répétez cette étape pour tous vos utilisateurs.

À ce point du tutoriel, l’authentification devrait marcher sans alerte, même si vous renouvelez et re-signez la clé de hôte.