diff --git a/README.md b/README.md
index 35213f1da3784df4c6c4680573146405f3632770..b5e8c43034fa0fe76b1f7fb3066c9bc73c4990ab 100644
--- a/README.md
+++ b/README.md
@@ -18,7 +18,7 @@ Suitable for server and workstation.
 | [`become_user_cfg.yml`](tasks/become_user_cfg.yml)    |   Set `sudo` without password for `become_user` access                |
 | [`host_info.yml`](tasks/host_info.yml)                |   Return message with distribution full name & version                |
 | [`shutdown.yml`](tasks/shutdown.yml)                  |   Shutdown target in 5 min (not if host is in production group)       |
-| [`system_cfg`](tasks/system_cfg/main.yml)             |   Configure  `root` users , NTP & `{{ my_users }}` shell              |
+| [`system_cfg`](tasks/system_cfg/main.yml)             |   Configure  `root`, firewall, NTP, LDP & `{{ my_users }}` shell      |
 | [`user_cfg`](tasks/user_cfg/main.yml)                 |   Configure `{{ my_user }}`                                           |
 | [`whoami.yml`](tasks/whoami.yml)                      |   Return message with `ansible_user` & `become_user` (`sudo` method)  |
 
diff --git a/inventory.sample b/inventory.sample
index 2828b709f2a56e2c080ee15b2715ecdadb5ff4f0..a3506360ce931cceb09b6c81dbe9a080c316a48a 100644
--- a/inventory.sample
+++ b/inventory.sample
@@ -17,6 +17,7 @@ localhost
 
 [server:vars]
 timezone="UTC"
+gateway="<GATEWAY_IP>"
 
 [workstation:vars]
 timezone="Europe/Paris"
diff --git a/tasks/become_user_cfg.yml b/tasks/become_user_cfg.yml
index aee552ec320d3127a6fcf59009acd7ccf00c452b..960cfceb4396e140d13fd6f9cebabc1fe7aa0eb2 100644
--- a/tasks/become_user_cfg.yml
+++ b/tasks/become_user_cfg.yml
@@ -1,7 +1,9 @@
 ---
+# When 1st user is root, set it as "remote_user"  and remove all "become: yes"
 - hosts: "{{ host_list }}"
   become_method: sudo
   remote_user: "{{ my_user }}"
+  #remote_user: root
 
   tasks:
     - name: SUDO | Group sudo presence
diff --git a/tasks/ldp.yml b/tasks/ldp.yml
deleted file mode 100644
index c8e06b825af410374dc53ad673fd9bc88dd86d60..0000000000000000000000000000000000000000
--- a/tasks/ldp.yml
+++ /dev/null
@@ -1,28 +0,0 @@
----
-- hosts: "{{ host_list }}"
-  remote_user: root
-
-  tasks:
-    - name: LDP | install packages
-      ansible.builtin.apt:
-        cache_valid_time: 3600
-        force_apt_get: yes
-        pkg:
-          - syslog-ng
-          - ca-certificates
-        state: present
-        update_cache: true
-
-    - name: LDP | syslog-ng config
-      ansible.builtin.template:
-        src: templates/ldp.conf.j2
-        dest: "/etc/syslog-ng/conf.d/ldp.conf"
-        mode: 0640
-        owner: root
-        group: root
-
-    - name: LDP | restart syslog-ng deamon
-      ansible.builtin.systemd:
-        state: restarted
-        daemon_reload: yes
-        name: syslog-ng
diff --git a/tasks/system_cfg/firewall.yml b/tasks/system_cfg/firewall.yml
new file mode 100644
index 0000000000000000000000000000000000000000..ea26c82c7d96bbd74396eb3e1734c6d98f892c8a
--- /dev/null
+++ b/tasks/system_cfg/firewall.yml
@@ -0,0 +1,61 @@
+---
+- name: FIREWALL | install packages
+  ansible.builtin.apt:
+    cache_valid_time: 3600
+    force_apt_get: yes
+    pkg:
+        - fail2ban
+        - ufw
+    state: present
+    update_cache: true
+
+- name: UFW | reset before setting
+  community.general.ufw:
+    state: reset
+
+- name: UFW | deny everything IN
+  community.general.ufw:
+    direction: incoming
+    policy: deny
+
+- name: UFW | allow everything OUT
+  community.general.ufw:
+    direction: outgoing
+    policy: allow
+
+- name: UFW | limit tcp port 22 IN
+  community.general.ufw:
+    direction: in
+    log: yes
+    port: '22'
+    proto: tcp
+    rule: limit
+
+- name: UFW | allow tcp port 80 IN
+  when: inventory_hostname in groups.web
+  community.general.ufw:
+    direction: in
+    rule: allow
+    port: '80'
+    proto: tcp
+
+- name: UFW | enable & set logging
+  community.general.ufw:
+    logging: low
+    state: enabled
+
+- name: FAIL2BAN | ensure deamon is running
+  ansible.builtin.service:
+    name: fail2ban
+    state: started
+    enabled: true
+
+- name: FAIL2BAN | set local config
+  ansible.builtin.template:
+    src: templates/jail.local.j2
+    dest: /etc/fail2ban/jail.local
+
+- name: FAIL2BAN | restart service
+  ansible.builtin.service:
+    name: fail2ban
+    state: restarted
diff --git a/tasks/system_cfg/ldp.yml b/tasks/system_cfg/ldp.yml
new file mode 100644
index 0000000000000000000000000000000000000000..baa1e8a7817e8de56ea1b13e5916ff8951896ed6
--- /dev/null
+++ b/tasks/system_cfg/ldp.yml
@@ -0,0 +1,24 @@
+---
+- name: LDP | install packages
+  ansible.builtin.apt:
+    cache_valid_time: 3600
+    force_apt_get: yes
+    pkg:
+      - syslog-ng
+      - ca-certificates
+    state: present
+    update_cache: true
+
+- name: LDP | syslog-ng config
+  ansible.builtin.template:
+    src: templates/ldp.conf.j2
+    dest: "/etc/syslog-ng/conf.d/ldp.conf"
+    mode: 0640
+    owner: root
+    group: root
+
+- name: LDP | restart syslog-ng deamon
+  ansible.builtin.systemd:
+    state: restarted
+    daemon_reload: yes
+    name: syslog-ng
diff --git a/tasks/system_cfg/main.yml b/tasks/system_cfg/main.yml
index ff73bb2ca6529be3f0e38e6e2904b1fbf61a814e..2169f10af6920a7e3943c89412cd68eb293ae4ad 100644
--- a/tasks/system_cfg/main.yml
+++ b/tasks/system_cfg/main.yml
@@ -6,9 +6,15 @@
 
   tasks:
 
+  - name: IMPORT_TASKS | firewall
+    ansible.builtin.import_tasks: firewall.yml
+
   - name: IMPORT_TASKS | font
     ansible.builtin.import_tasks: font.yml
 
+  - name: IMPORT_TASKS | ldp
+    ansible.builtin.import_tasks: ldp.yml
+
   - name: IMPORT_TASKS | ntp
     ansible.builtin.import_tasks: ntp.yml
 
diff --git a/tasks/system_cfg/templates/jail.local.j2 b/tasks/system_cfg/templates/jail.local.j2
new file mode 100644
index 0000000000000000000000000000000000000000..fde1f94fe4b49c93361c6635f37d44a35923271b
--- /dev/null
+++ b/tasks/system_cfg/templates/jail.local.j2
@@ -0,0 +1,12 @@
+[DEFAULT]
+banaction = ufw
+bantime   = 3600
+maxretry  = 3
+ignoreip  = 127.0.0.1 {{gateway}} {% for host in groups['all'] %}{{hostvars[host]['ansible_host']|ansible.netcommon.ipaddr('public')}} {% endfor %}
+
+
+[ssh]
+enabled  = true
+filter = sshd
+logpath = /var/log/auth.log
+findtime = 300
diff --git a/tasks/system_cfg/templates/ldp.conf.j2 b/tasks/system_cfg/templates/ldp.conf.j2
new file mode 100644
index 0000000000000000000000000000000000000000..61193533f832edd7dcac8d6c3338bc635fda3f5e
--- /dev/null
+++ b/tasks/system_cfg/templates/ldp.conf.j2
@@ -0,0 +1,32 @@
+template ovhTemplate {
+    # Source: https://docs.ovh.com/fr/logs-data-platform/how-to-log-your-linux/
+
+    template("<${LEVEL_NUM}>1 ${ISODATE} ${HOST} ${PROGRAM} ${PID} - [sdid@32473 X-OVH-TOKEN=\"{{ ldp_token }}\" pid=\"${PID}\" facility=\"${FACILITY}\" priority=\"${PRIORITY}\"] ${MSG}\n");
+    template_escape(no);
+};
+
+destination ovhPaaSLogs {
+    network("{{ ldp_zone }}.logs.ovh.com"
+        port(6514),
+        template(ovhTemplate),
+        ts_format("iso"),
+        transport("tls"),
+        tls(peer-verify("required-trusted") ca_dir("/etc/ssl/certs/")),
+        keep-alive(yes),
+        so_keepalive(yes),
+    );
+};
+
+destination localfile {
+    file("/var/log/temporaryfiletochecklogs.log");
+};
+
+log {
+     source(s_src);
+     destination(ovhPaaSLogs);
+};
+
+log {
+     source(s_src);
+     destination(localfile);
+};
diff --git a/tasks/templates/jail.local.j2 b/tasks/templates/jail.local.j2
new file mode 100644
index 0000000000000000000000000000000000000000..fde1f94fe4b49c93361c6635f37d44a35923271b
--- /dev/null
+++ b/tasks/templates/jail.local.j2
@@ -0,0 +1,12 @@
+[DEFAULT]
+banaction = ufw
+bantime   = 3600
+maxretry  = 3
+ignoreip  = 127.0.0.1 {{gateway}} {% for host in groups['all'] %}{{hostvars[host]['ansible_host']|ansible.netcommon.ipaddr('public')}} {% endfor %}
+
+
+[ssh]
+enabled  = true
+filter = sshd
+logpath = /var/log/auth.log
+findtime = 300
diff --git a/tasks/whoami.yml b/tasks/whoami.yml
index 7be52270dd2a48de1c14dec58c7e03ad362dcced..7bc2b88ee4af0e840b82e50247c7ac4b1901862b 100644
--- a/tasks/whoami.yml
+++ b/tasks/whoami.yml
@@ -21,8 +21,8 @@
 
     - name: Who is «remote_user»?
       ansible.builtin.debug:
-        msg: "I am «{{ who_is_remote_user.stdout_lines }}»"
+        msg: "I am {{ who_is_remote_user.stdout_lines | join }}"
 
     - name: Who is «become_user»?
       ansible.builtin.debug:
-        msg: "I am {{ who_is_become_user.stdout_lines | flatten | first }}"
+        msg: "I am {{ who_is_become_user.stdout_lines | join }}"