<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Tom Moulard</title>
    <description>The latest articles on DEV Community by Tom Moulard (@tommoulard).</description>
    <link>https://dev.to/tommoulard</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F781432%2Fccb2661e-9e5c-41ae-9ec7-af793e23a76b.jpeg</url>
      <title>DEV Community: Tom Moulard</title>
      <link>https://dev.to/tommoulard</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tommoulard"/>
    <language>en</language>
    <item>
      <title>Klipse, a new way of blogging</title>
      <dc:creator>Tom Moulard</dc:creator>
      <pubDate>Tue, 31 Aug 2021 12:00:00 +0000</pubDate>
      <link>https://dev.to/tommoulard/klipse-a-new-way-of-blogging-15j2</link>
      <guid>https://dev.to/tommoulard/klipse-a-new-way-of-blogging-15j2</guid>
      <description>&lt;p&gt;For a modern tech blogging framework, a live coding experience is quasi necessary.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://github.com/viebel/klipse"&gt;Klipse&lt;/a&gt; is a JavaScript plugin for embedding interactive code snippets in tech blogs.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To make this easy, you add a small library to your blog front end dependency, and voilà, you have your &lt;code&gt;&amp;lt;code&amp;gt;&amp;lt;/code&amp;gt;&lt;/code&gt; live executing in the browser. As a bonus, your code can no be edited directly in the &lt;code&gt;&amp;lt;code&amp;gt;&amp;lt;/code&amp;gt;&lt;/code&gt; tags.&lt;/p&gt;

&lt;p&gt;Go check out &lt;a href="https://blog.klipse.tech/golang/2021/08/29/blog-go.html"&gt;this blog post&lt;/a&gt; if you want to have more information about Klipse!&lt;/p&gt;

&lt;h1&gt;
  
  
  Klipsify your blogging framework
&lt;/h1&gt;

&lt;p&gt;To integrate the klipse plugin on a blog, you have to follow 3 simple steps.&lt;/p&gt;

&lt;p&gt;1) Make sure you have &lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/code&gt; at the top of your html file and &lt;code&gt;&amp;lt;meta charset="utf-8"&amp;gt;&lt;/code&gt; right after your &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; (It is required to display properly elements used by Klipse.)&lt;/p&gt;

&lt;p&gt;2) Add css and custom configuration somewhere in the page (it could be in the &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; or in the &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt;) before the &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; element of step #3. The selector keys are per language (you’ll find in &lt;a href="https://github.com/viebel/klipse#configuration"&gt;GitHub&lt;/a&gt; a list of supported languages) and the value are the CSS selector of the elements that you want to klipsify.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;link rel="stylesheet" type="text/css" href="https://storage.googleapis.com/app.klipse.tech/css/codemirror.css"&amp;gt;

&amp;lt;script&amp;gt;
    window.klipse_settings = {
        selector_golang: '.language-klipse-eval-js', // css selector for the html elements you want to klipsify
    };
&amp;lt;/script&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3) Add the JavaScript tag at the end of the body tag :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!-- ... --&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;!-- ... --&amp;gt;
    &amp;lt;script src="https://storage.googleapis.com/app.klipse.tech/plugin_prod/js/klipse_plugin.min.js"&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Write some code
&lt;/h1&gt;

&lt;p&gt;Now that you have installed Klipse on your blog, it remains to add some code to a blog post.&lt;/p&gt;

&lt;p&gt;Add this code snippet to try it on:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import "fmt"

func main() {
  fmt.Println("Hello World! Klipse is so much fun !")
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, this code is now live and interactive.&lt;/p&gt;

&lt;p&gt;Feel free to modify it to your own liking!&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Live and interactive coding was a long dream of mine when creating this blog.&lt;/p&gt;

&lt;p&gt;Klipse made this dream super easy to integrate on my blog!&lt;/p&gt;

&lt;p&gt;This post was inspired by &lt;a href="https://github.com/viebel"&gt;@viebel&lt;/a&gt;.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>A Dynamic Web Site using Python and AWS Lambda</title>
      <dc:creator>Tom Moulard</dc:creator>
      <pubDate>Wed, 27 Jan 2021 09:40:17 +0000</pubDate>
      <link>https://dev.to/tommoulard/a-dynamic-web-site-using-python-and-aws-lambda-2hld</link>
      <guid>https://dev.to/tommoulard/a-dynamic-web-site-using-python-and-aws-lambda-2hld</guid>
      <description>&lt;p&gt;Nous allons voir comment utiliser les Lambda d’AWS pour servir un site web dynamique et en mode serverless.&lt;/p&gt;

&lt;h1&gt;
  
  
  Python
&lt;/h1&gt;

&lt;p&gt;La fonction python que l’on va utiliser pour la lambda doit avoir deux paramètres : &lt;code&gt;event&lt;/code&gt; et &lt;code&gt;context&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def my_lambda_function(event, context):
    return "Hello world !"

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pour donner une idée de ce que contiennent &lt;code&gt;event&lt;/code&gt; et &lt;code&gt;context&lt;/code&gt;, j’ai créé cette fonction :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import os
import json

def debug_lambda(event, context):
    json_region = os.environ['AWS_REGION']
    return {
            "statusCode": 200,
            "headers": {
                "Content-Type": "application/json"
                },
            "body": json.dumps({
                "Region ": json_region,
                'event' : str(event),
                'context': str(context)
                })
            }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Où la réponse de la lambda donne :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "Region ": "eu-west-3",
    "event": "{'resource': '/', 'path': '/', 'httpMethod': 'GET', 'headers': {'Accept': 'text/html', 'Accept-Encoding': 'gzip, deflate, br', 'cache-control': 'max-age=0', 'CloudFront-Forwarded-Proto': 'https', 'CloudFront-Is-Desktop-Viewer': 'true', 'CloudFront-Is-Mobile-Viewer': 'false', 'CloudFront-Is-SmartTV-Viewer': 'false', 'CloudFront-Is-Tablet-Viewer': 'false', 'CloudFront-Viewer-Country': 'FR', 'dnt': '1', 'Host': '[REDACTED]', 'sec-fetch-dest': 'document', 'sec-fetch-mode': 'navigate', 'sec-fetch-site': 'none', 'sec-fetch-user': '?1', 'sec-gpc': '1', 'upgrade-insecure-requests': '1', 'User-Agent': '[REDACTED]', 'Via': '[REDACTED]', 'X-Amz-Cf-Id': '[REDACTED]', 'X-Amzn-Trace-Id': 'Root=1-[REDACTED]', 'X-Forwarded-For': '[REDACTED]', 'X-Forwarded-Port': '443', 'X-Forwarded-Proto': 'https'}, 'multiValueHeaders': {'Accept': ['text/html'], 'Accept-Encoding': ['gzip, deflate, br'], 'Accept-Language': ['fr-FR'], 'cache-control': ['max-age=0'], 'CloudFront-Forwarded-Proto': ['https'], 'CloudFront-Is-Desktop-Viewer': ['true'], 'CloudFront-Is-Mobile-Viewer': ['false'], 'CloudFront-Is-SmartTV-Viewer': ['false'], 'CloudFront-Is-Tablet-Viewer': ['false'], 'CloudFront-Viewer-Country': ['FR'], 'dnt': ['1'], 'Host': ['[REDACTED]'], 'sec-fetch-dest': ['document'], 'sec-fetch-mode': ['navigate'], 'sec-fetch-site': ['none'], 'sec-fetch-user': ['?1'], 'sec-gpc': ['1'], 'upgrade-insecure-requests': ['1'], 'User-Agent': ['[REDACTED]'], 'Via': ['[REDACTED]'], 'X-Amz-Cf-Id': ['[REDACTED]'], 'X-Amzn-Trace-Id': ['Root=1-[REDACTED]'], 'X-Forwarded-For': ['[REDACTED]'], 'X-Forwarded-Port': ['443'], 'X-Forwarded-Proto': ['https']}, 'queryStringParameters': None, 'multiValueQueryStringParameters': None, 'pathParameters': None, 'stageVariables': None, 'requestContext': {'resourceId': '[REDACTED]', 'resourcePath': '/', 'httpMethod': 'GET', 'extendedRequestId': '[REDACTED]', 'requestTime': '[REDACTED]', 'path': '/test', 'accountId': '[REDACTED]', 'protocol': 'HTTP/1.1', 'stage': 'test', 'domainPrefix': '[REDACTED]', 'requestTimeEpoch': 1611741450517, 'requestId': '[REDACTED]', 'identity': {'cognitoIdentityPoolId': None, 'accountId': None, 'cognitoIdentityId': None, 'caller': None, 'sourceIp': '[REDACTED]', 'principalOrgId': None, 'accessKey': None, 'cognitoAuthenticationType': None, 'cognitoAuthenticationProvider': None, 'userArn': None, 'userAgent': '[REDACTED]', 'user': None}, 'domainName': '[REDACTED]', 'apiId': '[REDACTED]'}, 'body': None, 'isBase64Encoded': False}",
    "context": "&amp;lt; __main__.LambdaContext object at 0x7f0f14df07c0&amp;gt;"
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Maintenant qu’on a ça, on peut faire tous ce qu’on veut :-)&lt;/p&gt;

&lt;p&gt;Pour pouvoir utiliser le code, il va falloir créer une archive zip.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ zip python.zip *.py

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Terraform
&lt;/h1&gt;

&lt;p&gt;Maintenant qu’on a une fonction python à faire tourner, il faut la déployer ! Dans ce tuto, nous utiliserons Terraform.&lt;/p&gt;

&lt;p&gt;Pour déployer sur AWS il faut avoir une clef d’accès avec son ID et son secret. Cette clef peut être récupérée dans la partie IAM de la console AWS.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setup Terraform
&lt;/h2&gt;

&lt;p&gt;Pour commencer, il faut dire a Terraform quel &lt;code&gt;provider&lt;/code&gt; utiliser:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;provider "aws" {
    region = "eu-west-3"
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;J’utilise &lt;code&gt;eu-west-3&lt;/code&gt;, mais vous pouvez utiliser n’importe quelle région :)&lt;/p&gt;

&lt;h2&gt;
  
  
  La Lambda
&lt;/h2&gt;

&lt;p&gt;Pour la resource de la lambda, il faut avoir une resource de type &lt;code&gt;aws_lambda_function&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;resource "aws_lambda_function" "lambda_function" {
  role = aws_iam_role.lambda_exec_role.arn
  handler = var.handler
  runtime = var.runtime # le type de code utilisé (i.e. python3.8)
  filename = var.src_zip # le nom du ficher .zip contentant le code
  function_name = var.function_name # le nom de la fonction
  source_code_hash = filebase64sha256(var.src_zip)
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Il faut aussi une resource de type &lt;code&gt;aws_iam_role&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;resource "aws_iam_role" "lambda_exec_role" {
  name = "lambda_exec"
  path = "/"
  description = "Allows Lambda Function to call AWS services on your behalf."

  assume_role_policy = &amp;lt;&amp;lt;EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
EOF
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  La gateway
&lt;/h2&gt;

&lt;p&gt;Pour pouvoir accéder au code de la lambda, il faut mettre une gateway API en tant que proxy.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;resource "aws_api_gateway_rest_api" "example" {
  name = "ServerlessExample"
  description = "Terraform Serverless Application Example"
}

resource "aws_api_gateway_resource" "proxy" {
  rest_api_id = aws_api_gateway_rest_api.example.id
  parent_id = aws_api_gateway_rest_api.example.root_resource_id
  path_part = "proxy"
}

resource "aws_api_gateway_method" "proxy" {
  rest_api_id = aws_api_gateway_rest_api.example.id
  resource_id = aws_api_gateway_resource.proxy.id
  http_method = "ANY"
  authorization = "NONE"
}

resource "aws_api_gateway_integration" "lambda" {
  rest_api_id = aws_api_gateway_rest_api.example.id
  resource_id = aws_api_gateway_method.proxy.resource_id
  http_method = aws_api_gateway_method.proxy.http_method

  integration_http_method = "POST"
  type = "AWS_PROXY"
  uri = aws_lambda_function.lambda_function.invoke_arn
}

resource "aws_api_gateway_method" "proxy_root" {
  rest_api_id = aws_api_gateway_rest_api.example.id
  resource_id = aws_api_gateway_rest_api.example.root_resource_id
  http_method = "ANY"
  authorization = "NONE"
}

resource "aws_api_gateway_integration" "lambda_root" {
  rest_api_id = aws_api_gateway_rest_api.example.id
  resource_id = aws_api_gateway_method.proxy_root.resource_id
  http_method = aws_api_gateway_method.proxy_root.http_method

  integration_http_method = "POST"
  type = "AWS_PROXY"
  uri = aws_lambda_function.lambda_function.invoke_arn
}

resource "aws_api_gateway_deployment" "example" {
  depends_on = [
    aws_api_gateway_integration.lambda,
    aws_api_gateway_integration.lambda_root,
  ]

  rest_api_id = aws_api_gateway_rest_api.example.id
  stage_name = "test"
}

resource "aws_lambda_permission" "apigw" {
  statement_id = "AllowAPIGatewayInvoke"
  action = "lambda:InvokeFunction"
  function_name = aws_lambda_function.lambda_function.function_name
  principal = "apigateway.amazonaws.com"

  # The "/*/*" portion grants access from any method on any resource
  # within the API Gateway REST API.
  source_arn = "${aws_api_gateway_rest_api.example.execution_arn}/*/*"
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Et pour enfin avoir l’url sur laquelle tapper pour voir le résultat de la fonction.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;output "base_url" {
  value = aws_api_gateway_deployment.example.invoke_url
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cela va donner:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Outputs:

base_url = https://wncgbhu7te.execute-api.eu-west-3.amazonaws.com/test

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;La source du blog est disponible sur &lt;a href="https://github.com/tomMoulard/LambdaCSVChart/tree/blog"&gt;github&lt;/a&gt;. Et la lambda est accessible sur &lt;a href="https://wncgbhu7te.execute-api.eu-west-3.amazonaws.com/test"&gt;aws&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Aller plus loin
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/tomMoulard/LambdaCSVChart/blob/main/.github/workflows/terraform.yml"&gt;github action publish&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Utiliser un DNS (R53)&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>iptable : Comment debug iptables ?</title>
      <dc:creator>Tom Moulard</dc:creator>
      <pubDate>Fri, 20 Nov 2020 12:19:36 +0000</pubDate>
      <link>https://dev.to/tommoulard/iptable-comment-debug-iptables--28ip</link>
      <guid>https://dev.to/tommoulard/iptable-comment-debug-iptables--28ip</guid>
      <description>&lt;h1&gt;
  
  
  iptables, comment ça fonctionne ?
&lt;/h1&gt;

&lt;p&gt;Mes deux URLs de références :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Le livre: &lt;a href="https://inetdoc.net/pdf/iptables-tutorial.pdf"&gt;https://inetdoc.net/pdf/iptables-tutorial.pdf&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Le man: &lt;a href="http://www.delafond.org/traducmanfr/man/man8/iptables.8.html"&gt;http://www.delafond.org/traducmanfr/man/man8/iptables.8.html&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Comment savoir si un filtre est utilisé ?
&lt;/h1&gt;

&lt;p&gt;Le paramètre magique est &lt;code&gt;-vnL&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# iptables -vnL
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target prot opt in out source destination
34250 1884K ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
    0 0 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0
    0 0 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0
   13 780 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22
 3068 1194K REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited

Chain FORWARD (policy ACCEPT 25664 packets, 4647K bytes)
 pkts bytes target prot opt in out source destination

Chain OUTPUT (policy ACCEPT 30801 packets, 4552K bytes)
 pkts bytes target prot opt in out source destination

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On peut voir que 3068 paquets ont été &lt;code&gt;REJECT&lt;/code&gt; par la règle &lt;code&gt;5&lt;/code&gt; lors de l’entrée sur le system &lt;code&gt;INPUT&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# iptables -t nat -vnL
Chain PREROUTING (policy ACCEPT 73305 packets, 4104K bytes)
 pkts bytes target prot opt in out source destination
   23 11316 DNAT udp -- eth1 * xxx.xxx.xxx.xxx 0.0.0.0/0 udp dpt:500 to:yyy.yyy.yyy.yyy:500
    1 384 DNAT udp -- eth1 * xxx.xxx.xxx.xxx 0.0.0.0/0 udp dpt:4500 to:yyy.yyy.yyy.yyy:4500
    0 0 DNAT udp -- eth1 * yyy.yyy.yyy.yyy 0.0.0.0/0 udp dpt:500 to:xxx.xxx.xxx.xxx:500
    0 0 DNAT udp -- eth1 * yyy.yyy.yyy.yyy 0.0.0.0/0 udp dpt:4500 to:xxx.xxx.xxx.xxx:4500

Chain INPUT (policy ACCEPT 4 packets, 240 bytes)
 pkts bytes target prot opt in out source destination

Chain OUTPUT (policy ACCEPT 128 packets, 10244 bytes)
 pkts bytes target prot opt in out source destination

Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target prot opt in out source destination
  130 11120 MASQUERADE all -- * * 0.0.0.0/0 0.0.0.0/0

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ici on peut voir que la règle de NAT 1 a été appliquée sur 23 paquets. Les règles &lt;code&gt;3&lt;/code&gt; et &lt;code&gt;4&lt;/code&gt; n’ont traité aucun paquet.&lt;/p&gt;

&lt;h1&gt;
  
  
  Comment demander a iptables de loger les paquets ?
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;iptables -I INPUT 1 -j LOG --log-level 7 --log-prefix "INPUT : "
iptables -I FORWARD 1 -j LOG --log-level 7 --log-prefix "FORWARD : "
iptables -I OUTPUT 1 -j LOG --log-level 7 --log-prefix "OUTPUT : "

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Avec ces filtres positionnés, &lt;code&gt;iptables&lt;/code&gt; va envoyer les logs pour les paquets qui arrivent &lt;code&gt;INPUT&lt;/code&gt;, ils sont retransmit &lt;code&gt;FORWARD&lt;/code&gt; ou envoyés &lt;code&gt;OUTPUT&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;iptables -t nat -I PREROUTING 1 -j LOG --log-level 7 --log-prefix "PREROUTING : "
iptables -t nat -I POSTROUTING 1 -j LOG --log-level 7 --log-prefix "POSTROUTING : "
iptables -t nat -I OUTPUT 1 -j LOG --log-level 7 --log-prefix "NAT OUTPUT : "

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ici les paquets qui passent par les tables de NAT seront envoyés dans les logs de la machine.&lt;/p&gt;

&lt;p&gt;Depuis la version 3.x il est possible d’utiliser &lt;strong&gt;-j TRACE&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;iptables -t raw -A OUTPUT -p icmp -j TRACE

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;merci &lt;strong&gt;Ludo&lt;/strong&gt; pour le liens : &lt;a href="https://www.opensourcerers.org/2016/05/27/how-to-trace-iptables-in-rhel7-centos7/"&gt;https://www.opensourcerers.org/2016/05/27/how-to-trace-iptables-in-rhel7-centos7/&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Comment consulter les logs?
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ dmesg -H
[Nov19 14:49] FORWARD : IN=eth1 OUT=eth1 MAC=fa:16:3e:e6:11:db:fa:16:3e:cc:4b:7e:08:00 SRC=195.25.2
[+0.079319] FORWARD : IN=eth1 OUT=eth1 MAC=fa:16:3e:e6:11:db:fa:16:3e:cc:4b:7e:08:00 SRC=90.115.1
[+3.939384] FORWARD : IN=eth1 OUT=eth1 MAC=fa:16:3e:e6:11:db:fa:16:3e:cc:4b:7e:08:00 SRC=195.25.2

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>VPN : Comment NATer un VPN IPSEC?</title>
      <dc:creator>Tom Moulard</dc:creator>
      <pubDate>Fri, 20 Nov 2020 12:19:36 +0000</pubDate>
      <link>https://dev.to/tommoulard/vpn-comment-nater-un-vpn-ipsec-20g</link>
      <guid>https://dev.to/tommoulard/vpn-comment-nater-un-vpn-ipsec-20g</guid>
      <description>&lt;h1&gt;
  
  
  Q/A
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Est-il possible de faire du NAT sur un firewall
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Oui&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;C’est un peu contre intuitif, mais oui il est possible de faire du NAT de vpn ipsec.&lt;/p&gt;

&lt;p&gt;Habituellement un VPN IPSEC est entre &lt;code&gt;@IP-Partener1&lt;/code&gt; et &lt;code&gt;@IP-Partener2&lt;/code&gt;. En fait, il est tout à fait possible d’introduire un intermédiaire qui NAT les 2 flux UDP nécessaires au VPN IPSEC &lt;code&gt;500-dpt:isakmp&lt;/code&gt; et &lt;code&gt;4500-dpt:ipsec-nat-t&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mermaid.initialize({ startOnLoad:true });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
graph LR;
    A["@IP-Partener1"]
    B["@NAT"]
    C["@IP-Partener2"]
    A --&amp;gt; B --&amp;gt; C
    C --&amp;gt; B --&amp;gt; A

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cela à été testé sur de multiples technologies de VPN sans poser de problème d’implémentation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Est-il possible d’utiliser des FQDN pour mettre en place des VPNs
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Oui&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Par exemple sur l’interface des PFsence pour la remote gateway il est noté:&lt;code&gt;Enter the public IP address or host name of the remote gateway&lt;/code&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Mettre en place du NAT d’un VPN sur &lt;code&gt;centOS7-iptables&lt;/code&gt;.
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Step 1 : Installer les softs et paramétrer l’OS
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ package yum install -y iptables tcpdump iptables-services
$ systemctl enable iptables
$ systemctl start iptables
$ echo "1" &amp;gt; /proc/sys/net/ipv4/ip_forward
$ sysctl -w net.ipv4.ip_forward=1

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 2 : Valider le routage
&lt;/h2&gt;

&lt;p&gt;Pour que le NAT fonctionne sur la machine il faut que les 2 partenaires soient accessibles. L’utilisation conjointe de 2 commandes permet de valider cela:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;tcpdump -p -i eth1 port 500&lt;/code&gt; permet de voir les paquets passés&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;telnet $IP-Partener2 500&lt;/code&gt; permet de générer des paquets&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 3 : Installer les règles de NAT des 2 flux et paramétrer la bonne redirection :
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ iptables -t nat -A PREROUTING -p udp -s $IP-Partener1 --dport 500 -i eth1 -j DNAT --to $IP-Partener2:500
$ iptables -t nat -A PREROUTING -p udp -s $IP-Partener1 --dport 4500 -i eth1 -j DNAT --to $IP-Partener2:4500
$ iptables -t nat -A PREROUTING -p udp -s $IP-Partener2 --dport 500 -i eth1 -j DNAT --to $IP-Partener1:500
$ iptables -t nat -A PREROUTING -p udp -s $IP-Partener2 --dport 4500 -i eth1 -j DNAT --to $IP-Partener1:4500

$ iptables -F FORWARD
$ iptables -t nat -A POSTROUTING -j MASQUERADE

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Mettre en place du NAT d’un VPN sur packet filter.
&lt;/h1&gt;

&lt;p&gt;Voila un exemple de règle de nat:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#rdr on vtnet0 inet proto udp from $IP-Partener1 port = isakmp to $IPInterfaceOne port = isakmp -&amp;gt; $IP-Partener2
#rdr on vtnet0 inet proto udp from $IP-Partener2 port = isakmp to $IPInterfaceOne port = isakmp -&amp;gt; $IP-Partener1
#rdr on vtnet0 inet proto udp from $IP-Partener1 port = sae-urn to $IPInterfaceOne port = sae-urn -&amp;gt; $IP-Partener2
#rdr on vtnet0 inet proto udp from $IP-Partener2 port = sae-urn to $IPInterfaceOne port = sae-urn -&amp;gt; $IP-Partener1

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Quelques liens utiles :
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Le livre : &lt;a href="https://inetdoc.net/pdf/iptables-tutorial.pdf"&gt;https://inetdoc.net/pdf/iptables-tutorial.pdf&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;La doc CentOS pour mettre en place du NAT : &lt;a href="http://web.mit.edu/rhel-doc/4/RH-DOCS/rhel-sg-fr-4/s1-firewall-ipt-fwd.html"&gt;http://web.mit.edu/rhel-doc/4/RH-DOCS/rhel-sg-fr-4/s1-firewall-ipt-fwd.html&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>A Traefik Hackaethon</title>
      <dc:creator>Tom Moulard</dc:creator>
      <pubDate>Tue, 27 Oct 2020 14:00:00 +0000</pubDate>
      <link>https://dev.to/tommoulard/a-traefik-hackaethon-51m8</link>
      <guid>https://dev.to/tommoulard/a-traefik-hackaethon-51m8</guid>
      <description>&lt;h1&gt;
  
  
  The beginning of a long story
&lt;/h1&gt;

&lt;p&gt;At The root of this story, I, one of the author (&lt;a href="https://tom.moulard.org"&gt;Tom Moulard&lt;/a&gt;). I used Traefik for my &lt;a href="https://github.com/tomMoulard/make-my-server"&gt;home server configuration&lt;/a&gt; and I was looking for an internship. On my journey, I stumbled upon a &lt;a href="https://traefik.io/blog/announcing-the-inaugural-traefik-hackaethon-2020-in-october/"&gt;Traefik Hackaethon&lt;/a&gt;, a fun project with a cash prize and mainly goodies \o/&lt;/p&gt;

&lt;p&gt;Looking for a team, I looked for some of the best student to come working with me. And I found: - &lt;a href="https://github.com/nitra-mfs"&gt;Martin Huvelle&lt;/a&gt; (the co author) - &lt;a href="https://www.linkedin.com/in/alexandre-bossut-lasry/"&gt;Alexandre Bossut-Lasry&lt;/a&gt; - &lt;a href="https://github.com/cledavid"&gt;Clément David&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We are a team of EPITA student in the TCOM major, and we are all working as teachers assistants to prepare and teach practical courses on our fields of studies.&lt;/p&gt;

&lt;p&gt;We had a master plan to have fun in this hackaethon. First we build a “small” plugin to warm up on Tuesday and then the big project to really have fun during those three days.&lt;/p&gt;

&lt;p&gt;The plan:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Day&lt;/th&gt;
&lt;th&gt;Task&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Tuesday&lt;/td&gt;
&lt;td&gt;Warm up and try a simple plugin&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Wednesday&lt;/td&gt;
&lt;td&gt;Implement all main features&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Thursday&lt;/td&gt;
&lt;td&gt;Go full hardcore and fix every bug&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;During this time, we even did some gophers (Go mascots) for each of us.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tom Moulard&lt;/th&gt;
&lt;th&gt;Clément David&lt;/th&gt;
&lt;th&gt;Martin Huvelle&lt;/th&gt;
&lt;th&gt;Alexandre Bossut-Lasry&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://tom.moulard.org"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VnUWQ6XW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.moulard.org/img/2020/traefik/gopher-tom_moulard.png" alt="" width="490" height="570"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/cledavid"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sr401zAO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.moulard.org/img/2020/traefik/gopher-clement_david.png" alt="" width="490" height="570"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/nitra-mfs"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xCFn2JjY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.moulard.org/img/2020/traefik/gopher-martin_huvelle.png" alt="" width="490" height="570"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.linkedin.com/in/alexandre-bossut-lasry/"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Vsf_iYWs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.moulard.org/img/2020/traefik/gopher-alexandre_bossut-lasry.png" alt="" width="490" height="570"&gt;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h1&gt;
  
  
  Day 1, The warm up.
&lt;/h1&gt;

&lt;p&gt;We had a &lt;a href="https://traefik.io/resources/plugin-to-traefik-create-and-publish-your-own-middleware-3/"&gt;demo&lt;/a&gt; from &lt;a href="https://twitter.com/notsureifkevin"&gt;Kevin Crawley&lt;/a&gt; a few days prior the Tuesday.&lt;/p&gt;

&lt;p&gt;It was a demo on how to add a Header on a request. Thus, starting from there, managing headers was an easy task for us. Therefore we made &lt;a href="https://github.com/tomMoulard/htransformation"&gt;htransformation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/tomMoulard/htransformation"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DT9_Serh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://gh-card.dev/repos/tommoulard/htransformation.svg" alt="htranformation github card" width="442" height="130"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By the end of the day, we published the plugin on &lt;a href="https://pilot.traefik.io/plugins/279923829278507529/header-transformation"&gt;traefik pilot&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Day 2, Some dark times
&lt;/h1&gt;

&lt;p&gt;Wednesday morning, the dark time of our hackatheon. We needed an idea, not only an idea that would be fun (believe me we had a lot) but one that would be useful ! We had a lot of chat with one of the organizer (Thank you &lt;a href="https://twitter.com/manuel_zapf"&gt;Santo&lt;/a&gt; for all of your help, support and motivation !). After a lot of “Santo! We got an idea !!!” and a “Yeah that’s sounds fun but what would be the purpose of this?” we finally extract the idea of “fail2ban” integration.&lt;/p&gt;

&lt;p&gt;To be sure that no one had did this, as usual we check github, traefik etc. Nothing, until we check discord, our future teammate Mike had the same idea. So we decided to team up (We didn’t know how much it would be a good idea) !&lt;/p&gt;

&lt;h1&gt;
  
  
  Day 3, A happy ending
&lt;/h1&gt;

&lt;p&gt;After a lot of hours, thinking about the design and coding every piece of the plugin, combine every part we each created. We had one last bug, we tried everything, review every lines with differents people at each time. Last helping call, we ask the discord about our issue, of course after few second we post, we managed to solve it and of course the patch was “use caps for your config variables”. Typical, we even stumbled upon this reflection for the first plugin.&lt;/p&gt;

&lt;p&gt;The plugin worked, all of the tests displayed “&lt;a href="https://travis-ci.com/github/tomMoulard/fail2ban/jobs/403817444"&gt;PASSED&lt;/a&gt;”, &lt;a href="https://github.com/tomMoulard/fail2ban/commit/ebea16634226d7846c0c9b576872f76740ef1579"&gt;we did it&lt;/a&gt; !&lt;/p&gt;

&lt;p&gt;The last job we had was to push the plugin &lt;a href="https://github.com/tomMoulard/fail2ban"&gt;Fail2Ban&lt;/a&gt; on &lt;a href="https://pilot.traefik.io/plugins/280093067746214409/fail2-ban"&gt;traefik pilot&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/tomMoulard/fail2ban"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BxBvq0WT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://gh-card.dev/repos/tommoulard/fail2ban.svg" alt="Fail2ban github card" width="442" height="109"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We were proud and we learn a lot in a very short period of time but what we didn’t know was the next mail which arrived at midnight the next day. I looked quickly thinking it was a simple mail which thanks us to participate but the mention “I would like to proudly announce that you have won FIRST PLACE!!” did not sound usual for a “thanks for your participation” kind of mail.&lt;/p&gt;

&lt;h1&gt;
  
  
  Wrapping up
&lt;/h1&gt;

&lt;p&gt;We’d like to thanks Traefik for organizing this amazing event ! And &lt;a href="https://www.epita.fr"&gt;EPITA&lt;/a&gt; for providing the structure to hold us during theses difficult times.&lt;/p&gt;

&lt;p&gt;Thanks to this experience, we became &lt;a href="https://info.traefik.io/traefik-ambassador-program"&gt;Traefik Ambassador&lt;/a&gt; !&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9TFBNzII--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.moulard.org/img/2020/traefik/traefik-ambassador-flatten.svg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9TFBNzII--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.moulard.org/img/2020/traefik/traefik-ambassador-flatten.svg" alt="We are Traefik Ambassador" width="880" height="658"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Comment bien installer docker ?</title>
      <dc:creator>Tom Moulard</dc:creator>
      <pubDate>Tue, 06 Oct 2020 11:00:00 +0000</pubDate>
      <link>https://dev.to/tommoulard/comment-bien-installer-docker--gf5</link>
      <guid>https://dev.to/tommoulard/comment-bien-installer-docker--gf5</guid>
      <description>&lt;p&gt;Vu que c’est une question que me revient souvent, voila un petit tutoriel sur comment installer docker proprement et surtout comment le configurer.&lt;/p&gt;

&lt;h1&gt;
  
  
  Comment installer docker ?
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Sur windows ou Mac
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.docker.com/products/docker-desktop"&gt;Docker Desktop&lt;/a&gt; est pour moi un bon compromis pour l’installation de Docker sur Windows ou Mac.&lt;/p&gt;

&lt;p&gt;Le GUI apporte une manière simple de visualiser se qui se passe dans docker.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sur une Distro basée sur Debian
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt install -y docker docker.io
sudo groupadd docker
sudo gpasswd -a $USER docker
newgrp docker
reboot

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;La commande &lt;code&gt;newgrp docker&lt;/code&gt; permet d’utiliser docker sans avoir à le préfixer de &lt;code&gt;sudo&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sur une Distro basée sur Arch
&lt;/h2&gt;

&lt;p&gt;Avec l’user &lt;code&gt;root&lt;/code&gt; (&lt;code&gt;sudo su&lt;/code&gt;), faire:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pacman -Syu docker docker-compose
groupadd docker
gpasswd -a $USER docker
systemctl enable docker
systemctl start docker
newgrp docker
reboot

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;La commande &lt;code&gt;newgrp docker&lt;/code&gt; permet d’utiliser docker sans avoir à le préfixer de &lt;code&gt;sudo&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sur une Distro basée sur Centos
&lt;/h2&gt;

&lt;p&gt;Avec l’user &lt;code&gt;root&lt;/code&gt; (&lt;code&gt;sudo su&lt;/code&gt;), faire:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yum install -y yum-utils

yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo

yum install --allowerasing -y docker-ce docker-ce-cli containerd.io
systemctl enable docker
systemctl start docker

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Tester son installation:
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker run hello-world

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Comment installer docker-compose ?
&lt;/h1&gt;

&lt;p&gt;On peut utiliser la dernière version de &lt;code&gt;docker-compose&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -L https://github.com/docker/compose/releases/download/$(curl -Ls https://www.servercow.de/docker-compose/latest.php)/docker-compose-$(uname -s)-$(uname -m) &amp;gt; /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sinon, il faut utiliser la dernière version présente sur les repository de la distro que vous utilisez.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Fibonacci et Phi</title>
      <dc:creator>Tom Moulard</dc:creator>
      <pubDate>Thu, 01 Oct 2020 11:10:04 +0000</pubDate>
      <link>https://dev.to/tommoulard/fibonacci-et-phi-2j2a</link>
      <guid>https://dev.to/tommoulard/fibonacci-et-phi-2j2a</guid>
      <description>&lt;h1&gt;
  
  
  Fibonacci et $\phi$
&lt;/h1&gt;

&lt;p&gt;En tant qu’utilisateur de Youtube, je suis récemment tombé sur la vidéo&lt;a href="https://www.youtube.com/watch?v=48sCx-wBs34"&gt;The Infinite Pattern That Never Repeats&lt;/a&gt;par &lt;a href="https://www.youtube.com/channel/UCHnyfMqiRRG1u-2MsSQLbXA"&gt;Veritasium&lt;/a&gt;. Et à un moment, (précisément &lt;a href="https://youtu.be/48sCx-wBs34?t=895"&gt;14:55&lt;/a&gt;), il explique la relation entre la suite de Fibonacci et le &lt;code&gt;golden ratio&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The ratio of one fibonacci number to the previous one approaches the golden ratio&lt;/p&gt;

&lt;p&gt;– &lt;cite&gt;&lt;a href="https://youtu.be/48sCx-wBs34?t=895"&gt;Derek Muller&lt;/a&gt;&lt;/cite&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Mais ne serait-ce pas quelque chose que nous pourrions observer simplement avec un peut de python ?&lt;/p&gt;

&lt;h2&gt;
  
  
  Python
&lt;/h2&gt;

&lt;p&gt;Il décidé d’écrire la fonction &lt;code&gt;fibo&lt;/code&gt; qui afficherais les &lt;code&gt;n&lt;/code&gt; premières valeurs de la suite:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def fibo(n):
    print(1)
    prev = 1
    actual = 1
    for i in range(n):
        print(actual)
        tmp = actual
        actual += prev
        prev = tmp

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Si on essaye avec 5, on se retrouve avec:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; fibo(5)
1
1
2
3
5
8

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Maintenant, ajoutons un paramètre supplémentaire qui va permettre d’effectuer un rapport entre les deux dernières valeurs et en afficher le résultat:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def fibo(n, f=lambda p, r: p / r):
    print(f"i: 0, f: 1, r: {f(0, 1)}")
    prev = 1
    actual = 1
    for i in range(n):
        print(f"i: {i}, f: {actual}, r: {f(actual, prev)}")
        tmp = actual
        actual += prev
        prev = tmp

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Si on essaye avec 5 et la fonction qui permet de faire le rapport entre les deux, on obtient:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; fibo(5)
i: 0, f: 1, r: 0.0
i: 0, f: 1, r: 1.0
i: 1, f: 2, r: 2.0
i: 2, f: 3, r: 1.5
i: 3, f: 5, r: 1.6666666666666667
i: 4, f: 8, r: 1.6

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On peut observer que l’on se rapproche de la valeur de $\phi$ qui vaut $\phi \approx 1.6180339887…$. On peut d’ailleurs l’approximer facilement:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; (1 + 5 ** 0.5) / 2
1.618033988749895

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;D’autre part, si on utilise la fonction que j’ai écrite, on peut observer que le résultat converge vers $\phi$ rapidement mais qu’il faut attendre la 39 ième itération avant de voir la version arrondie de python:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; fibo(40, f=lambda a,b: a/b)
i: 0, f: 1, r: 0.0
i: 0, f: 1, r: 1.0
i: 1, f: 2, r: 2.0
i: 2, f: 3, r: 1.5
i: 3, f: 5, r: 1.6666666666666667
i: 4, f: 8, r: 1.6
i: 5, f: 13, r: 1.625
i: 6, f: 21, r: 1.6153846153846154
i: 7, f: 34, r: 1.619047619047619
i: 8, f: 55, r: 1.6176470588235294
i: 9, f: 89, r: 1.6181818181818182
i: 10, f: 144, r: 1.6179775280898876
i: 11, f: 233, r: 1.6180555555555556
i: 12, f: 377, r: 1.6180257510729614
i: 13, f: 610, r: 1.6180371352785146
i: 14, f: 987, r: 1.618032786885246
i: 15, f: 1597, r: 1.618034447821682
i: 16, f: 2584, r: 1.6180338134001253
i: 17, f: 4181, r: 1.618034055727554
i: 18, f: 6765, r: 1.6180339631667064
i: 19, f: 10946, r: 1.6180339985218033
i: 20, f: 17711, r: 1.618033985017358
i: 21, f: 28657, r: 1.6180339901755971
i: 22, f: 46368, r: 1.618033988205325
i: 23, f: 75025, r: 1.618033988957902
i: 24, f: 121393, r: 1.6180339886704431
i: 25, f: 196418, r: 1.6180339887802426
i: 26, f: 317811, r: 1.618033988738303
i: 27, f: 514229, r: 1.6180339887543225
i: 28, f: 832040, r: 1.6180339887482036
i: 29, f: 1346269, r: 1.6180339887505408
i: 30, f: 2178309, r: 1.6180339887496482
i: 31, f: 3524578, r: 1.618033988749989
i: 32, f: 5702887, r: 1.618033988749859
i: 33, f: 9227465, r: 1.6180339887499087
i: 34, f: 14930352, r: 1.6180339887498896
i: 35, f: 24157817, r: 1.618033988749897
i: 36, f: 39088169, r: 1.618033988749894
i: 37, f: 63245986, r: 1.6180339887498951
i: 38, f: 102334155, r: 1.6180339887498947
i: 39, f: 165580141, r: 1.618033988749895
i: 40, f: 267914296, r: 1.618033988749895

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QOHRkZd6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.moulard.org/img/2020/fibonacci/phibonacci.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QOHRkZd6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.moulard.org/img/2020/fibonacci/phibonacci.png" alt="Courbe de l'évolution des valeurs" width="590" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Boot in Kali Live</title>
      <dc:creator>Tom Moulard</dc:creator>
      <pubDate>Thu, 17 Sep 2020 06:09:31 +0000</pubDate>
      <link>https://dev.to/tommoulard/boot-in-kali-live-496m</link>
      <guid>https://dev.to/tommoulard/boot-in-kali-live-496m</guid>
      <description>&lt;p&gt;Ce “tutoriel” va vous présenter comment installer une clef bootable et comment l’utiliser avec une version live de kali Linux.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Attention, par défaut, une version live d’un OS ne va pas sauvegarder vos données, ni configuration&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Préparation
&lt;/h2&gt;

&lt;p&gt;Il va falloir télécharger l’image &lt;code&gt;.iso&lt;/code&gt; que vous allez vouloir installer sur la clef USB.&lt;/p&gt;

&lt;h3&gt;
  
  
  Télécharger l’image
&lt;/h3&gt;

&lt;p&gt;Pour télécharger l’image, il faut aller sur le site de&lt;a href="https://www.kali.org/"&gt;Kali&lt;/a&gt;, dans la section&lt;a href="https://www.kali.org/downloads/"&gt;download&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Puis choisir l’image qui correspond a la version voulue:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://cdimage.kali.org/kali-2020.3/kali-linux-2020.3-installer-amd64.iso"&gt;Kali Linux 64-Bit (installer)&lt;/a&gt;, &lt;a href="https://images.kali.org/kali-linux-2020.3-installer-amd64.iso.torrent"&gt;torrent&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://cdimage.kali.org/kali-2020.3/kali-linux-2020.3-live-amd64.iso"&gt;Kali Linux 64-Bit (live)&lt;/a&gt;, &lt;a href="https://images.kali.org/kali-linux-2020.3-live-amd64.iso.torrent"&gt;torrent&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://cdimage.kali.org/kali-2020.3/kali-linux-2020.3-installer-netinst-amd64.iso"&gt;Kali Linux 64-Bit (net installer)&lt;/a&gt;, &lt;a href="https://images.kali.org/kali-linux-2020.3-installer-netinst-amd64.iso.torrent"&gt;torrent&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://cdimage.kali.org/kali-2020.3/kali-linux-2020.3-installer-i386.iso"&gt;Kali Linux 32-Bit (installer)&lt;/a&gt;, &lt;a href="https://images.kali.org/kali-linux-2020.3-installer-i386.iso.torrent"&gt;torrent&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://cdimage.kali.org/kali-2020.3/kali-linux-2020.3-live-i386.iso"&gt;Kali Linux 32-Bit (live)&lt;/a&gt;, &lt;a href="https://images.kali.org/kali-linux-2020.3-live-i386.iso.torrent"&gt;torrent&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://cdimage.kali.org/kali-2020.3/kali-linux-2020.3-installer-netinst-i386.iso"&gt;Kali Linux 32-Bit (net installer)&lt;/a&gt;, &lt;a href="https://images.kali.org/kali-linux-2020.3-installer-netinst-i386.iso.torrent"&gt;torrent&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;La version &lt;code&gt;Kali Linux 64-Bit (live)&lt;/code&gt; est préférée.&lt;/p&gt;

&lt;h3&gt;
  
  
  Burn la clef USB
&lt;/h3&gt;

&lt;p&gt;Une fois le fichier &lt;code&gt;.iso&lt;/code&gt; disponible sur votre PC, il faut l’installer (ou le burn) sur la clef USB.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Brancher la Clef USB au PC&lt;/strong&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Logiciel sur Windows
&lt;/h4&gt;

&lt;p&gt;Utiliser l’outil &lt;a href="https://rufus.ie/"&gt;rufus&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VfayJ5nM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.moulard.org/img/2020/kali/rufus_fr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VfayJ5nM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.moulard.org/img/2020/kali/rufus_fr.png" alt="Interface rufus" width="418" height="538"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Télécharger le logiciel, &lt;a href="https://github.com/pbatard/rufus/releases/download/v3.11/rufus-3.11.exe"&gt;lien&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Choisir de périphérique&lt;/li&gt;
&lt;li&gt;Sélectionner le fichier image (dans &lt;code&gt;Type de démarrage&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Choisir un schema de partition &lt;code&gt;MBR&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Utiliser le mode &lt;code&gt;BIOS ou UEFI&lt;/code&gt; pour le &lt;code&gt;Système de destination&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;DEMARRER&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Programme sur Linux
&lt;/h4&gt;

&lt;p&gt;Il faut connaitre le nom du device qui est mount sur votre PC:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ lsblk # avant avoir branché la clef
sda 8:0 0 447,1G 0 disk
└─sda1 8:0 0 447,1G 0 part /
$ lsblk # après avoir branché la clef
sda 8:0 0 447,1G 0 disk
└─sda1 8:0 0 447,1G 0 part /
sdb 8:16 0 14,6G 0 disk
├─sdb1 8:17 0 1K 0 part
└─sdb5 8:21 0 14,6K 0 part /media/root/best-usb

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On remarque que &lt;code&gt;sdb&lt;/code&gt; viens d’apparaitre.&lt;/p&gt;

&lt;p&gt;On va maintenant Burn l’image:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sudo dd status="progress" conv="fdatasync" bs=4M if=/root/Downloads/kali-linux-2020.3-live-amd64.iso of=/dev/sdb

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Décomposons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;sudo&lt;/code&gt;: il faut être root pour pouvoir utiliser le tool&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;dd&lt;/code&gt;: (AKA &lt;code&gt;Disk Destroyer&lt;/code&gt;) outils pour convertir et copier des fichiers (cf &lt;code&gt;man dd&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;status="progress"&lt;/code&gt;: Permet de savoir ce qu’est en train de faire &lt;code&gt;dd&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;conv="fdatasync"&lt;/code&gt;: Permet à &lt;code&gt;dd&lt;/code&gt; de bien flush les buffers d’écriture a la fin de l’écriture.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;bs=4M&lt;/code&gt;: Décrit la taille des “blocks” à écrire sur le support.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;if=&amp;lt;ISO FILE&amp;gt;&lt;/code&gt;: Permet de choisir le fichier à écrire sur la clef USB.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;of=&amp;lt;device&amp;gt;&lt;/code&gt;: Choisis le device où on va écrire le fichier &lt;strong&gt;Attention: ne pas se tromper de device&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Booter
&lt;/h2&gt;

&lt;p&gt;Re démarrer le PC.&lt;/p&gt;

&lt;h3&gt;
  
  
  Entrer dans le BIOS
&lt;/h3&gt;

&lt;p&gt;Lorsque le PC est en train de démarrer, il affiche sur l’écran le logo du constructeur et une touche sur laquelle appuyer pour entre dans le BIOS.&lt;/p&gt;

&lt;p&gt;Ses touches peuvent être:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Suppr&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Del&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;F1&lt;/code&gt; (ou les autre touches fonction)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Ctrl + Alt + Echap&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Ctrl + Alt + S&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Ctrl + Alt + Ins&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;…&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Choisir le “disque” USB
&lt;/h3&gt;

&lt;p&gt;On va donc aller chercher dans le BIOS l’option qui permet de choisir l’ordre des disques de boot. C’est-à-dire l’ordre des devices dans lequel de BIOS va regarder pour démarrer un OS.&lt;/p&gt;

&lt;p&gt;Dans ce menu, il va falloir mettre le device correspondant a la clef USB en premier.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Attention: Si vous laissez cette option d’activée, n’importe qui qui possède une clef bootable va pouvoir utiliser votre ordinateur et pouvoir utiliser vos disques&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Une fois cette options modifiée, il faut sauvegarder les settings et quitter le BIOS.&lt;/p&gt;

&lt;h3&gt;
  
  
  Choisir l’option de boot en live
&lt;/h3&gt;

&lt;p&gt;L’écran va ensuite afficher le GRUB GNU de Kali.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OahxY3Ok--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.moulard.org/img/2020/kali/grub-kali.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OahxY3Ok--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.moulard.org/img/2020/kali/grub-kali.jpeg" alt="GRUB GNU de Kali Linux" width="474" height="355"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Et Voilà, vous avez boot sur une version Live de Kali.&lt;/p&gt;

&lt;p&gt;La première chose a faire est de faire un:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sudo apt-get update &amp;amp;&amp;amp; apt-get upgrade -y

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;La prochaine fois, si la clef USB est branchée, le PC va démarrer Kali, sinon il va démarrer sur votre OS de base(celui qui est déjà installé sur votre machine)&lt;/p&gt;

</description>
    </item>
    <item>
      <title>ANSSI et automatisation de MOOC Secnumacademie avec Selenium</title>
      <dc:creator>Tom Moulard</dc:creator>
      <pubDate>Mon, 13 Apr 2020 16:57:41 +0000</pubDate>
      <link>https://dev.to/tommoulard/anssi-et-automatisation-de-mooc-secnumacademie-avec-selenium-51e0</link>
      <guid>https://dev.to/tommoulard/anssi-et-automatisation-de-mooc-secnumacademie-avec-selenium-51e0</guid>
      <description>&lt;p&gt;Pour mon école, j’ai eu a faire un &lt;a href="https://secnumacademie.gouv.fr/"&gt;MOOC&lt;/a&gt; de l’ANSSI.&lt;/p&gt;

&lt;p&gt;Or après avoir fait tous les tests du mooc à 100% sans avoir écouté les cours, j’ai décidé de récupérer l’attestation de réussite du MOOC pour le donner à mon école. Mais j’ai eu un message d’erreur:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--54kCUOWc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.moulard.org/img/2020/mooc/error.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--54kCUOWc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.moulard.org/img/2020/mooc/error.png" alt="Erreur de récupération de l'attestation" width="864" height="334"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;J’ai donc voulu suivre les cours, mais ils prenaient beaucoup trop de temps à suivre. Voici donc un bot pour suivre les cours de manière semi-automatique:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from selenium import webdriver
import time

user = "REDACTED"
passw = "REDACTED"

def main():
    driver = webdriver.Chrome()
    driver.get("https://secnumacademie.gouv.fr/")
    driver.find_elements_by_id("btn_access_insc")[0].click()
    driver.find_elements_by_id("login")[0].send_keys(user)
    driver.find_elements_by_id("password")[0].send_keys(passw)
    xpath = '/html/body/div[2]/div/div[2]/div/div[1]/div[1]/div[2]/a[1]'
    driver.find_elements_by_xpath(xpath)[0].click()
    while True:
        if input("continue ? [Y/n]") == "n":
            exit(0)
        driver.switch_to.default_content()
        driver.switch_to.frame("DEFAUT")
        driver.switch_to.frame("contents")
        iframe_id = driver.find_elements_by_id("content")[0].find_elements_by_tag_name("iframe")[0].get_attribute("id")
        driver.switch_to.frame(iframe_id)
        driver.execute_script("for(var i = 0; i &amp;lt; 15; i++) {document.querySelector('#Stage_menu_inferieur_bouton_suivant_hit').click()}")

if __name__ == ' __main__':
    main()

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Un bot que vous pourrez trouver sur mon &lt;a href="https://github.com/tomMoulard/python-projetcs"&gt;repository github&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Il suffit de:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;mettre son username et son password dans les variables &lt;code&gt;user&lt;/code&gt; et &lt;code&gt;passwd&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;lancer le bot&lt;/li&gt;
&lt;li&gt;attendre que le bot ait connecté le navigateur&lt;/li&gt;
&lt;li&gt;sélectionner le module, l’unité ainsi que le premier cours&lt;/li&gt;
&lt;li&gt;entrer &lt;code&gt;Y&lt;/code&gt; quand le bot demande si on veut continuer (étape à répéter tant qu’il y a un sous module à suivre)&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  En images
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Récupérer le code
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir mook-hack &amp;amp;&amp;amp; cd mook-hack
wget https://raw.githubusercontent.com/tomMoulard/python-projetcs/master/anssi-mooc/mooc.py

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Installer les dépendances
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt install -y python3-selenium chromium-chromedriver

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Mettre son username/password
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$EDITOR +4 mooc.py

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Lancer le bot
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;python3 mooc.py

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--khwy6fxc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.moulard.org/img/2020/mooc/waiting.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--khwy6fxc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.moulard.org/img/2020/mooc/waiting.png" alt="le bot qui attends" width="880" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Sélectionner le module
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--7B25AmoP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.moulard.org/img/2020/mooc/module.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7B25AmoP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.moulard.org/img/2020/mooc/module.png" alt="Sélectionner le module" width="467" height="214"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Sélectionner l’unité
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SAocJXEz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.moulard.org/img/2020/mooc/unity.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SAocJXEz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.moulard.org/img/2020/mooc/unity.png" alt="Sélectionner l'unité" width="469" height="216"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Sélectionner le premier cours
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;angry clicking noise * &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fx30CvAs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.moulard.org/img/2020/mooc/first-course.png" alt="Sélectionner le premier cours" width="283" height="45"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Entrer &lt;code&gt;Y&lt;/code&gt;
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;y

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Upgrades
&lt;/h1&gt;

&lt;p&gt;Dans le futur, on pourrait:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;lire les vidéos&lt;/li&gt;
&lt;li&gt;ne pas faire &lt;code&gt;Y&lt;/code&gt; pour chaque cours&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;bla bla bla il faut suivre ses cours&lt;/p&gt;

&lt;p&gt;Selenium c’est cool pour automatiser l’utilisation d’un site web&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Se blog a été écrit en réalisant un mooc ANSSI *&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Corona et CLI</title>
      <dc:creator>Tom Moulard</dc:creator>
      <pubDate>Fri, 27 Mar 2020 11:22:48 +0000</pubDate>
      <link>https://dev.to/tommoulard/corona-et-cli-4ak9</link>
      <guid>https://dev.to/tommoulard/corona-et-cli-4ak9</guid>
      <description>&lt;h1&gt;
  
  
  Comment utiliser des outils “modernes” pour avoir des informations utiles sur l’état actuel des choses
&lt;/h1&gt;

&lt;p&gt;On a des sites qui offrent les données liées au virus accessible grâce à &lt;code&gt;cURL&lt;/code&gt;:&lt;/p&gt;

&lt;h2&gt;
  
  
  Récupérer les informations
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ curl https://corona-stats.online/fr
╔══════╤═════════════╤══════════════╤═════════════╤══════════════╤══════════════╤═══════════╤═════════╤══════════╤════════════════╗
║ Rank │ Country │ Total Cases │ New Cases ▲ │ Total Deaths │ New Deaths ▲ │ Recovered │ Active │ Critical │ Cases / 1M pop ║
╟──────┼─────────────┼──────────────┼─────────────┼──────────────┼──────────────┼───────────┼─────────┼──────────┼────────────────╢
║ 1 │ France (FR) │ 29,155 │ │ 1,696 │ │ 4,948 │ 22,511 │ 3,375 │ 447 ║
╟──────┼─────────────┼──────────────┼─────────────┼──────────────┼──────────────┼───────────┼─────────┼──────────┼────────────────╢
║ │ World │ 548,806 │ 16,996 ▲ │ 24,862 │ 794 ▲ │ 128,599 │ 395,345 │ 20,968 │ 70.41 ║
╚══════╧═════════════╧══════════════╧═════════════╧══════════════╧══════════════╧═══════════╧═════════╧══════════╧════════════════╝

Stay safe. Stay inside.
Code: https://github.com/sagarkarira/coronavirus-tracker-cli
Twitter: https://twitter.com/ekrysis

Last Updated on: 27-Mar-2020 11:03 UTC

UPDATE: Source 2 is now default source
JHU Source 1 table: https://corona-stats.online?source=1
HELP: https://corona-stats.online/help

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Extraire les informations
&lt;/h2&gt;

&lt;p&gt;Extraire des données de ce curl est donc faisable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ curl https://corona-stats.online/fr | grep an
║ Rank │ Country │ Total Cases │ New Cases ▲ │ Total Deaths │ New Deaths ▲ │ Recovered │ Active │ Critical │ Cases / 1M pop ║
║ 1 │ France (FR) │ 29,155 │ │ 1,696 │ │ 4,948 │ 22,511 │ 3,375 │ 447 ║

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Nettoyer les informations
&lt;/h2&gt;

&lt;p&gt;Il suffit ensuite de nettoyer avec un coup de &lt;code&gt;sed&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ curl https://corona-stats.online/fr |\
    grep an |\
    sed "s/\s*//g ; s/║//g ; s/│/;/g"
Rank;Country;TotalCases;NewCases▲;TotalDeaths;NewDeaths▲;Recovered;Active;Critical;Cases/1Mpop
1;France(FR);29,155;;1,696;;4,948;22,511;3,375;447

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Les trois arguments de sed permettent: - &lt;code&gt;s/\s*//g&lt;/code&gt;: supprimer les espaces superflu - &lt;code&gt;s/║//g&lt;/code&gt;: enlever le caractère de fin - &lt;code&gt;s/│/;/g"&lt;/code&gt;: Remplacer les séparateurs par quelque chose d’utilisable&lt;/p&gt;

&lt;h2&gt;
  
  
  Formater les informations
&lt;/h2&gt;

&lt;p&gt;On peux mieux voir les informations grâce à &lt;code&gt;AWK&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ curl https://corona-stats.online/fr |\
    grep France |\
    sed "s/\s*//g ; s/║//g ; s/│/;/g" |\
    awk -F';' '{print $2":"$3"("$7","$8")"}'
Country:TotalCases(Recovered,Active)
France(FR):29,155(4,948,22,511)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Attention: ne pas oublier d’enlever la ligne avec les informations de champ avec une utilisation un peut plus poussée.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Il ne nous reste plus qu’à utiliser ces informations, dans une barre d’état par exemple.&lt;/p&gt;

&lt;p&gt;Pour aller plus loin, on pourrais ne pas utiliser &lt;code&gt;cURL&lt;/code&gt; à chaque appel, mais utiliser un cache car les informations ne sont pas mises a jours toutes les heures:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl https://corona-stats.online/fr &amp;gt; $HOME/.cache/corona_data
grep France $HOME/.cache/corona_data |\
    sed "s/\s*//g ; s/║//g ; s/│/;/g" |\
    awk -F';' '{print $2":"$3"("$7","$8")"}'

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>sysadmin function bakup</title>
      <dc:creator>Tom Moulard</dc:creator>
      <pubDate>Thu, 12 Mar 2020 09:19:36 +0000</pubDate>
      <link>https://dev.to/tommoulard/sysadmin-function-bakup-1iol</link>
      <guid>https://dev.to/tommoulard/sysadmin-function-bakup-1iol</guid>
      <description>&lt;h1&gt;
  
  
  sysadmin function bakup
&lt;/h1&gt;

&lt;p&gt;Dans les règles d’or de tout sysadmin il y a bien sûr la nécessité de mettre en œuvre une politique de backup complet des systèmes. Ce n’est pas le sujet de cet article !!! Il existe une bonne pratique pour garantir la traçabilité et la capacité de revenir sur une mauvaise manip.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Avant de modifier une fichier, il faut en faire une copie !!!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Alors c’est simple à première vue:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cp /etc/fstab /etc/fstab.bkp

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Bon ça c’est la base :) Franchement ça aide dans bien des cas. On peut aller un peu plus loin et ajouter un horodatage.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cp /etc/fstab /etc/fstab-bkp200312002553

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pour ma part je me suis souvent demandé pourquoi personne n’avait écrit en &lt;code&gt;cp&lt;/code&gt; avec cette fonction… Bien probablement car il y a les function en shell :)&lt;/p&gt;

&lt;p&gt;Il faut juste la créer dans son environnement et le mettre dans son fichier &lt;code&gt;$HOME/.bashrc&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bkp (){ cp -a $1 $1-bkp$(date +"%y%m%d%H%M%S") ; }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On peut alors ensuite l’utiliser comme une commande classique&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;root@pi3:~&amp;gt; bkp (){ cp -a $1 $1-bkp$(date +"%y%m%d%H%M%S") ; }
root@pi3:~&amp;gt; bkp /etc/fstab
root@pi3:~&amp;gt; ls -l /etc/fstab*
-rw-r--r-- 1 root root 305 nov. 29 18:40 /etc/fstab
-rw-r--r-- 1 root root 305 nov. 29 18:40 /etc/fstab-bkp200312003354

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Cool non!!!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Bien sûr l’utilisation des fonctions en bash n’a pas de limite, voilà une autre que j’utilise souvent pour répéter X fois la même commande…&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;t10 (){ for x in {01..10}; do $@ ; done }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Et à l’utilisation&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pi@pi3:~ $ t10 (){ for x in {01..10}; do $@ ; done }
pi@pi3:~ $ t10 echo g &amp;gt;&amp;gt; /tmp/10g
pi@pi3:~ $ cat /tmp/10g
g
g
g
g
g
g
g
g
g
g

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On peut faire des choses beaucoup plus sophistiquées… Voila une fonction qui décompresse les principaux fichiers d’archive.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Extract the content of an achive
function extract {
 if [-z "$1"]; then
    # display usage if no parameters given
    echo "Usage: extract &amp;lt;path/file_name&amp;gt;.&amp;lt;zip|rar|bz2|gz|tar|tbz2|tgz|Z|7z|xz|ex|tar.bz2|tar.gz|tar.xz&amp;gt;"
    echo " extract &amp;lt;path/file_name_1.ext&amp;gt; [path/file_name_2.ext] [path/file_name_3.ext]"
    return 1
 else
    for n in $@
    do
      if [-f "$n"] ; then
          case "${n%,}" in
            *.tar.bz2|*.tar.gz|*.tar.xz|*.tbz2|*.tgz|*.txz|*.tar)
                         tar xvf "$n" ;;
            *.lzma) unlzma ./"$n" ;;
            *.bz2) bunzip2 ./"$n" ;;
            *.rar) unrar x -ad ./"$n" ;;
            *.gz) gunzip ./"$n" ;;
            *.zip) unzip ./"$n" ;;
            *.z) uncompress ./"$n" ;;
            *.7z|*.arj|*.cab|*.chm|*.deb|*.dmg|*.iso|*.lzh|*.msi|*.rpm|*.udf|*.wim|*.xar)
                         7z x ./"$n" ;;
            *.xz) unxz ./"$n" ;;
            *.exe) cabextract ./"$n" ;;
            *)
                         echo "extract: '$n' - unknown archive method"
                         return 1
                         ;;
          esac
      else
          echo "'$n' - file does not exist"
          return 1
      fi
    done
fi
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
    <item>
      <title>Sécurisation SSH : Utilisation de clés à la place de password.</title>
      <dc:creator>Tom Moulard</dc:creator>
      <pubDate>Mon, 09 Mar 2020 12:19:36 +0000</pubDate>
      <link>https://dev.to/tommoulard/securisation-ssh-utilisation-de-cles-a-la-place-de-password-21m5</link>
      <guid>https://dev.to/tommoulard/securisation-ssh-utilisation-de-cles-a-la-place-de-password-21m5</guid>
      <description>&lt;h1&gt;
  
  
  Pourquoi des clés ssh et pas des password ?
&lt;/h1&gt;

&lt;p&gt;Il y a deux raisons d’utiliser des clés et pas des password pour le SSH, l’une est bonne et l’autre mauvaise. La mauvaise raison est gérer, mémoriser et taper des password. Ce n’est pas le but de la vie car cela est pénible. La bonne est que les passowrd, sur internet, ça ne résiste pas aux attaques de force brute. Un password de 8 caractères, même complexe, est bien moins sécurisé qu’une clé de 4096 bits.&lt;/p&gt;

&lt;p&gt;Dans le cloud quand vous laissez un serveur SSH accessible, en quelques minutes c’est the final bot attaque !!!&lt;/p&gt;

&lt;p&gt;J’aime bien dire que la clé privée est une clé, et que la clé publique est une serrure. La clé privée permet d’ouvrir les portes sécurisée avec la clé publique. Évidement si vous pouvez partager la clé publique, il faut précieusement garder secrète la clé privée. La passphrase, est le code secret nécessaire à l’utilisation de la clé privée.&lt;/p&gt;

&lt;h2&gt;
  
  
  Comment empêcher les password dans SSH
&lt;/h2&gt;

&lt;p&gt;Il suffit de mettre à &lt;code&gt;no&lt;/code&gt; le paramètre de &lt;code&gt;PasswordAuthentication&lt;/code&gt; du fichier &lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt; :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pi@pi3:~/.ssh $ grep PasswordAuthentication /etc/ssh/sshd_config
PasswordAuthentication no

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Et de redémarrer le serveur ssh (&lt;code&gt;sshd&lt;/code&gt;)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;root@pi3:~&amp;gt; systemctl restart sshd

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Comment faire une clé ?
&lt;/h1&gt;

&lt;p&gt;Avec &lt;code&gt;puttygen&lt;/code&gt; sous Windows c’est simplissime, il ne faut juste pas oublier de bouger la souris sous la barre verte pour générer de l’aléatoire.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZSKgc31y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.moulard.org/img/2020/puttyGen.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZSKgc31y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.moulard.org/img/2020/puttyGen.png" alt="puttyGen3" width="717" height="722"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Avec openssh, c’est encore plus simple :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pi@pi3:~/.ssh $ ssh-keygen -t rsa -b 4096
Generating public/private rsa key pair.
Enter file in which to save the key (/home/pi/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/pi/.ssh/id_rsa.
Your public key has been saved in /home/pi/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:WJfG2b35KlyIkbY+jo+H3dyMKrtJiSoC0JRyIe9ptlw pi@pi3
The keys randomart image is:
+---[RSA 4096]----+
|. .o |
|.o+ . + . |
| =. . *.. . |
|.... o o+ o |
|. = E . S. + .o |
|.+ o . .o . .. |
|. o . o+ + = .|
|. . . .o+= * o. |
| . .. *B+o .. |
+----[SHA256]-----+

pi@pi3:~/.ssh $ cat id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC0g4DwF...LUSQeFGB7NrP0R9F3A4ose01JCX5kbXp91W6R7Q== pi@pi3

pi@pi3:~/.ssh $ cat id_rsa
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,91FE4EEA4EF377C38F0D56DC7BE40B3F

XgeIahCfT+cL/4tUgUDrPY7p3+b5imo/0FGwLLmX3U9pPY6AlbhOksAaglXYUP/r
Q3dGNBO7zDYiiMB3ZIn2rRYlmVShlLT1xCSryFDy/BEnGDPFA8QSVxD+EnOcevtj
akFbUfC2RYBxMMN4/e1mHK00ILUFqGmCYVR0qFU0SH8QB5BrKXbBfYK7LVQxKrKs
...
...
...
GGR/SS22KBTs4KksYPtgYvOu/cxV4LLdNDS0zBGC89txFhSvsfT/+SwC6vyfaf9G
vqbQ59U8VvNQFPkU9v0DfN6lg5/4mFhbDncc92yGqouXEGS/YVwXUx/BCVaYAadd
Ue+B5sxn6T+0VypJK/0cQvnLZ8o2d2SekAde3lMRLP/Bn4VHt/6S5XfY1z1ILnvB
pFmgdzSEzY37bHQedPcqqSqVposf9dZ1zLRHhLyqcKKx7xRLBX7oY4EPSaT8VwvF
7z16A4Fjrkc4twARvpyIRbX2CYqa7ZELo83tIvWTFzZKA99tL6p0upAOME+0zFwm
-----END RSA PRIVATE KEY-----

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Comment pousser sa clé sur un serveur ?
&lt;/h1&gt;

&lt;p&gt;La clé publique doit être mise dans la liste des clés du compte que l’on souhaite accéder. Classiquement &lt;code&gt;/home/&amp;lt;&amp;lt;user&amp;gt;&amp;gt;/.ssh/authorized_keys&lt;/code&gt;. Il faut mettre, dans le fichier &lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt;, la clé &lt;code&gt;AuthorizedKeysFile&lt;/code&gt; par défaut à &lt;code&gt;%h/.ssh/authorized_keys&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Copie de la clé sur un server
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pi@pi3:~/.ssh $ ssh-copy-id pi@pi4b.home
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/pi/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed

/usr/bin/ssh-copy-id: WARNING: All keys were skipped because they already exist on the remote system.
                (if you think this is a mistake, you may want to use -f option)

pi@pi3:~/.ssh $ ssh pi@pi4b.home -i id_rsa
Linux pi4b 4.19.75-v7l+ #1270 SMP Tue Sep 24 18:51:41 BST 2019 armv7l

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Sat Mar 7 11:05:33 2020 from 192.168.1.29
pi@pi4b:~ $

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Copie de la clé manuellement
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pi@pi3:~/.ssh $ cat id_rsa.pub &amp;gt;&amp;gt; /home/pi/.ssh/authorized_keys

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Attention aux autorisations sur le fichier authorized_keys&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pi@pi3:~/.ssh $ ls -l /home/pi/.ssh/authorized_keys
-rw------- 1 pi pi 3505 mars 7 12:01 /home/pi/.ssh/authorized_keys

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
    </item>
  </channel>
</rss>
