diff --git a/.gitignore b/.gitignore index 2d96ba31563dddd93aad5d1b03d9d8e17d267d84..f2bc66c311a244b4735e637a2f52f4a5ce3f0478 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ *.kate-swp +.vscode/* \ No newline at end of file diff --git a/docs/DOCUMENTATION.md b/docs/DOCUMENTATION.md index 7cdc81ef8a0d6364540fd80d708c85f92479e5b9..6430d64cd9f0ace43897e1a26bb6e7615bd41785 100644 --- a/docs/DOCUMENTATION.md +++ b/docs/DOCUMENTATION.md @@ -38,7 +38,10 @@ Enter the `config` folder. When running ansible from this folder, it will read c ### `inventory` file ==This step is mandatory==. Devices (`nodes`) you'll control (your `inventory`) are described inside the `inventory` file. [[Ansible documentation](https://docs.ansible.com/ansible/latest/inventory_guide/intro_inventory.html)] -In order yo fill your inventory, you'll need to know your nodes' username and IP address. A static IP for each node is highly recommended. +In order yo fill your inventory, you'll need to know your nodes' username and IP address. A static IP for each node is highly recommended. \ +To get the IP addresses of your devices, either : +- Plug a screen in you RP; it will probably be shown on the login screen +- Use your network's management interface to find out which device is newly connected to your network In the following example, we create a group of devices `ss1` with two nodes inside. They are locally nicknamed `ss1-s1` and `ss1-s2`, and they are reachable using their respective IP addresses. Inline variables set here override variables defined globally. It is important to specify the super-sniffer inside the hostname, because else when tasks run you'll only see the number of the sniffer and not its group @@ -88,11 +91,11 @@ If you didn't configure it before, your `master` device isn't authorized to conn For this to be solved, we're going to transfer the master's ssh key to the nodes so that it lets us in without password. ++This is a one-time process.++ -Run the `ssh_setup.yml` playbook from the `config` folder : +Run the `ssh_setup.yml` playbook from the `config` folder with the additional argument `--ask-become-pass`: ``` -sudo ansible-playbook ../playbooks/ssh_setup.yml +ansible-playbook ../playbooks/ssh_setup.yml --ask-become-pass ``` -Fill in the prompt for nodes' ssh passord and your master's admin password, then wait for completion. From there on, you won't need to provide any authentication. +Fill in the prompt for your master's admin password and your nodes' ssh passord, then wait for completion. From there on, you won't need to provide any authentication. ### Testing the connection to your nodes @@ -149,9 +152,9 @@ In order for your sniffers to work correctly, they need some configuration (inst If you've just flashed your sniffers with the official Lite image, ++do not skip this step++.\ Detailed description of what this script does is to be found inside [Nodes setup and configuration](./PLAYBOOKS#nodes-setup-and-configuration) -Simply run the `sniffer-setup` playbook : +Simply run the `device-setup` playbook : ``` -ansible-playbook ../playbooks/sniffer_setup.yml +ansible-playbook ../playbooks/device_setup.yml ``` This can be ran just to make sure things are set up properly. @@ -167,13 +170,6 @@ And fill in the parameters to pass to the `sniffer.py` script.\ When running this command, note that it expects all sniffers to have the same amount of external adapters plugged in the same interfaces -#### Cancelling a future or running sniffing session -Detailed description of what this script does is to be found inside [Starting and Stopping mitik-sens](./PLAYBOOKS#starting-and-stopping-mitik-sens).\ -Run the `stop_sens_sniffer.yml` playbook: -``` -ansible-playbook ../playbooks/start_sens_sniffer.yml -``` - #### Cancelling a future or running sniffing session Detailed description of what this script does is to be found inside [Starting and Stopping mitik-sens](./PLAYBOOKS#starting-and-stopping-mitik-sens).\ Run the `stop_sens_sniffer.yml` playbook: diff --git a/docs/PLAYBOOKS.md b/docs/PLAYBOOKS.md index 51011fbcd52e3a70035e592c729d5290071827c7..b69840e37eda8dfefcd6a073b071c338eea97860 100644 --- a/docs/PLAYBOOKS.md +++ b/docs/PLAYBOOKS.md @@ -14,7 +14,8 @@ There are five main playbooks : All of them target the `sniffers` group by default. However, some tasks can be set to be run on the master device. ## First master-nodes connection: SSH setup In order to ease configuring ssh keys and passwordless authentication, the playbook `ssh_setup.yml` (previously `playbook_SSH_keygen.yml`) has been re-written. -It will need to be ran with sudo, because it tries to install packages to master machine. +It will need to be ran with th argument **--ask-become-pass**, because it tries to install packages to master machine. +- (`--ask-become-pass`) asks for sudo password (for local master machine) - Asks for SSH password - Installs sshpass and keychain (master) (needs superuser powers) - Creates a ssh key (master) @@ -60,7 +61,7 @@ Multiple configuration scripts, here called microstasks, have been put into a si The playbook `start_sens_sniffer.yml` asks parameters to run mitik-sens : - The folder of mitik-sens on the nodes. Defaults to `/home/tribe/mitik-sens/` - hour and minute at which to start the experiment. Defaults to current time +15m -- The format of the name of the output pcap file. Defaults to mitik_experiment-%post, with %post being replaced at mitik-sens level +- The format of the name of the output pcap file. Defaults to mitik_experiment_ssX-sX-?post, with ?post being replaced at mitik-sens level - Timeout after which to stop the experiment in seconds. Defaults to 3600 (1h) - The interfaces on which to run the experiment, separated by commas (e.g. `wifi5,wifi6`). Defaults to `wifi5`. Order matters. - The channels on which to start the interface, separated by commas. (e.g. `6,11`). Defaults to `1`. Order matters. @@ -70,7 +71,7 @@ Multiple configuration scripts, here called microstasks, have been put into a si - The fields to anonymize. All MACs and ssids is 15; not ssid is 14; nothing is 0. Defaults to 15 - The frequency at which location should be polled. Defaults to 900s (15m) -Then it translates the csv interfaces and channels into lists, and finds out the prefix to use for the gps file. It is {{ _pcap_name | replace('%post', '') }}-location-YYYYMMDD-ddmmss.gps +Then it translates the csv interfaces and channels into lists, and finds out the prefix to use for the gps file. It is {{ _pcap_name | replace('?post', '') }}-location-YYYYMMDD-ddmmss.gps it checks if the length of interfaces and channels is the same. If they are, we set up a crontab to run the sniffer when planned, and a crontab for saving the location of the device. @@ -117,4 +118,4 @@ You could also just run playbooks one by one, manually, with the following playb Test playbooks will not check : - That the hosts file is up-to-date (contains our sniffers) - That the gps is plugged into the pins, because checking that makes gathering info from the GPS impossible and requires a reboot -- That the network drivers repo and the mitik-sens repos are downloaded and up-to-date \ No newline at end of file +- That the network drivers repo and the mitik-sens repos are downloaded and up-to-date diff --git a/files/72-wlan-geo-dependent.rules b/files/72-wlan-geo-dependent.rules index 303053440a8ee4e0ccdc98ed3b6b97f3121686b8..6948c4346d72b488142a08b3120d97407e18cf54 100644 --- a/files/72-wlan-geo-dependent.rules +++ b/files/72-wlan-geo-dependent.rules @@ -1,3 +1,5 @@ +# ---------- RPI5 --------- + # wifi0 ACTION=="add", SUBSYSTEM=="net", SUBSYSTEMS=="sdio", ATTRS{device}=="0x4345", ATTRS{vendor}=="0x02d0", NAME="wifi0" @@ -5,8 +7,27 @@ ACTION=="add", SUBSYSTEM=="net", SUBSYSTEMS=="sdio", ATTRS{device}=="0x4345", AT # | wifi5 | wifi7 | # +-------+-------+ # | wifi6 | wifi8 | -# +---------------+ (RPI physical USB ports distribution) +# +---------------+ (RPI5 physical USB ports distribution) ACTION=="add", SUBSYSTEM=="net", SUBSYSTEMS=="usb", KERNELS=="3-1", NAME="wifi5", RUN+="/usr/bin/sudo /usr/sbin/ifconfig wifi5 up", RUN+="/usr/bin/sudo /usr/sbin/ifconfig wifi5 down", RUN+="/usr/bin/sudo /usr/sbin/iwconfig wifi5 mode monitor", RUN+="/usr/bin/sudo /usr/sbin/ifconfig wifi5 up" ACTION=="add", SUBSYSTEM=="net", SUBSYSTEMS=="usb", KERNELS=="1-1", NAME="wifi6", RUN+="/usr/bin/sudo /usr/sbin/ifconfig wifi6 up", RUN+="/usr/bin/sudo /usr/sbin/ifconfig wifi6 down", RUN+="/usr/bin/sudo /usr/sbin/iwconfig wifi6 mode monitor", RUN+="/usr/bin/sudo /usr/sbin/ifconfig wifi6 up" ACTION=="add", SUBSYSTEM=="net", SUBSYSTEMS=="usb", KERNELS=="1-2", NAME="wifi7", RUN+="/usr/bin/sudo /usr/sbin/ifconfig wifi7 up", RUN+="/usr/bin/sudo /usr/sbin/ifconfig wifi7 down", RUN+="/usr/bin/sudo /usr/sbin/iwconfig wifi7 mode monitor", RUN+="/usr/bin/sudo /usr/sbin/ifconfig wifi7 up" ACTION=="add", SUBSYSTEM=="net", SUBSYSTEMS=="usb", KERNELS=="3-2", NAME="wifi8", RUN+="/usr/bin/sudo /usr/sbin/ifconfig wifi8 up", RUN+="/usr/bin/sudo /usr/sbin/ifconfig wifi8 down", RUN+="/usr/bin/sudo /usr/sbin/iwconfig wifi8 mode monitor", RUN+="/usr/bin/sudo /usr/sbin/ifconfig wifi8 up" +# ---------- END RPI5 --------- + + +# ---------- RPI4 --------- + + +# wifi0 +ACTION=="add", SUBSYSTEM=="net", SUBSYSTEMS=="sdio", ATTRS{device}=="0xa9a6", ATTRS{vendor}=="0x02d0", NAME="wifi0" + +# +---------------+ +# | wifi5 | wifi7 | +# +-------+-------+ +# | wifi6 | wifi8 | +# +---------------+ (RPI5 physical USB ports distribution) + +ACTION=="add", SUBSYSTEM=="net", SUBSYSTEMS=="usb", KERNELS=="1-1.3", NAME="wifi5", RUN+="/usr/bin/sudo /usr/sbin/ifconfig wifi5 up", RUN+="/usr/bin/sudo /usr/sbin/ifconfig wifi5 down", RUN+="/usr/bin/sudo /usr/sbin/iwconfig wifi5 mode monitor", RUN+="/usr/bin/sudo /usr/sbin/ifconfig wifi5 up" +ACTION=="add", SUBSYSTEM=="net", SUBSYSTEMS=="usb", KERNELS=="1-1.4", NAME="wifi6", RUN+="/usr/bin/sudo /usr/sbin/ifconfig wifi6 up", RUN+="/usr/bin/sudo /usr/sbin/ifconfig wifi6 down", RUN+="/usr/bin/sudo /usr/sbin/iwconfig wifi6 mode monitor", RUN+="/usr/bin/sudo /usr/sbin/ifconfig wifi6 up" +ACTION=="add", SUBSYSTEM=="net", SUBSYSTEMS=="usb", KERNELS=="1-1.1", NAME="wifi7", RUN+="/usr/bin/sudo /usr/sbin/ifconfig wifi7 up", RUN+="/usr/bin/sudo /usr/sbin/ifconfig wifi7 down", RUN+="/usr/bin/sudo /usr/sbin/iwconfig wifi7 mode monitor", RUN+="/usr/bin/sudo /usr/sbin/ifconfig wifi7 up" +ACTION=="add", SUBSYSTEM=="net", SUBSYSTEMS=="usb", KERNELS=="1-1.2", NAME="wifi8", RUN+="/usr/bin/sudo /usr/sbin/ifconfig wifi8 up", RUN+="/usr/bin/sudo /usr/sbin/ifconfig wifi8 down", RUN+="/usr/bin/sudo /usr/sbin/iwconfig wifi8 mode monitor", RUN+="/usr/bin/sudo /usr/sbin/ifconfig wifi8 up" diff --git a/files/positionGetter.sh b/files/positionGetter.sh index 41e93f2160a6bda7527f0d1b853500567c8de898..f610ff539c7bc0e45838bee7677ec1961b33f21e 100755 --- a/files/positionGetter.sh +++ b/files/positionGetter.sh @@ -43,5 +43,5 @@ awk -F',' ' } END { printf "%.10f %.10f %.10f\n", lat/NR, lon/NR, alt/NR; -}' $gpsLocations > "$(echo $3"/"$4"$(date +%Y%m%d_%H%M%S)-location.gps.log")" +}' $gpsLocations > $(echo $3"/"$4"$(date +%Y%m%d_%H%M%S)-location.gps.log") # will write eg as ~/mitik-sens/ diff --git a/playbooks/microstask_GPS_setup.yml b/playbooks/microstask_GPS_setup.yml index 9e8fff3b73fc493bfaa07c817a5af8da8f2a7e73..0e03780685d431027af1ebf4b806ca0c6dedbf66 100644 --- a/playbooks/microstask_GPS_setup.yml +++ b/playbooks/microstask_GPS_setup.yml @@ -8,10 +8,17 @@ ansible.builtin.command: sudo timedatectl set-timezone Europe/Paris changed_when: false - - name: Raspi-config serial_hw + #enable + - name: Raspi-config do_serial_hw ansible.builtin.command: sudo raspi-config nonint do_serial_hw 0 changed_when: false + #disable + - name: Raspi-config do_serial_cons + ansible.builtin.command: sudo raspi-config nonint do_serial_cons 1 + changed_when: false + + - name: Install required packages tags: sniffer-setup config nodes ansible.builtin.apt: diff --git a/playbooks/microtask_hostname_update.yml b/playbooks/microtask_hostname_update.yml index 72aab8852a992024ce3b7095275a7ec758f78517..4ecec345d774cd0ce157cb270a1836336d56659a 100644 --- a/playbooks/microtask_hostname_update.yml +++ b/playbooks/microtask_hostname_update.yml @@ -2,7 +2,6 @@ - name: Set hostname of targets to group-device name (ss1-s1) hosts: sniffers tasks: - vars: - name: skip is good; check that hostnames look valid debug: msg: "The hostname {{ inventory_hostname }} looks invalid." @@ -10,4 +9,6 @@ - name: set system hostname shell: sudo hostnamectl set-hostname {{ inventory_hostname }} + become: true + become_user: root diff --git a/playbooks/microtask_hosts_update.yml b/playbooks/microtask_hosts_update.yml index 6e7653d1087b812905517cac2eb0d97e0c5debb3..1906f3455b085ffa198474cf1697a35f42cd2862 100644 --- a/playbooks/microtask_hosts_update.yml +++ b/playbooks/microtask_hosts_update.yml @@ -6,14 +6,14 @@ # 192.168.1.246 ss2-s5 # 192.168.1.244 ss2-s6 # It works when this line does not exist before; it also updates existing lines if necessary -- name: host file update - Local DNS setup across all nodes and master +# Task 1: Update hosts file of all sniffers +- name: host file update - Local DNS setup across all sniffers gather_facts: true tags: etchosts device-update become: true become_user: root - hosts: sniffers, localhost + hosts: sniffers tasks: - - name: Add IP address of all hosts to all hosts lineinfile: dest: "/etc/hosts" @@ -22,3 +22,28 @@ state: present when: hostvars[item].ansible_host is defined with_items: "{{ groups.sniffers }}" + +# Task 2: Update hosts file of localhost and ask for sudoer password +- name: Host file update - Local DNS setup on localhost + gather_facts: true + tags: etchosts device-update + become: true + become_user: root + become_method: sudo + hosts: localhost + vars_prompt: + - name: ansible_become_pass + prompt: "Superuser password for local machine" + private: true + default: "mandatory" + + tasks: + - name: Add IP address of all hosts to all hosts + lineinfile: + dest: "/etc/hosts" + regexp: '.*{{ item }}$' + line: "{{ hostvars[item].ansible_host }} {{ item }}" + state: present + when: hostvars[item].ansible_host is defined + with_items: "{{ groups.sniffers }}" + diff --git a/playbooks/microtask_mitik_sens_update.yml b/playbooks/microtask_mitik_sens_update.yml index e28d3db7f2b0cd69af3f59783e07bbd3a77b8857..5206f3bfdc4de9fa489bb88a5a5ee956043fa065 100644 --- a/playbooks/microtask_mitik_sens_update.yml +++ b/playbooks/microtask_mitik_sens_update.yml @@ -5,8 +5,16 @@ hosts: sniffers become: false tasks: - - name: Install git if necessary - ansible.builtin.shell: type git || sudo apt update && apt install git -y + - name: Install git and bc + tags: sniffer-setup config nodes + apt: + pkg: + # required + - git # to clone rtl8188 repo + - bc # required to compile the rtl8188 driver + update_cache: true + become: true + become_user: root - ansible.builtin.git: repo: https://gitlab.inria.fr/mitik/anonymous-measurement/mitik-sens diff --git a/playbooks/microtask_network_drivers_update.yml b/playbooks/microtask_network_drivers_update.yml index ef26c7baa40a9612828b60b4e643d0cdf7dc798b..9802614ca865520ee1a8fe6ae2a04392c11d54a5 100644 --- a/playbooks/microtask_network_drivers_update.yml +++ b/playbooks/microtask_network_drivers_update.yml @@ -2,7 +2,7 @@ - name: Update the drivers for external adapters hosts: sniffers - becomre: false + become: false tasks: - name: Install required packages tags: sniffer-setup config nodes diff --git a/playbooks/microtask_networking_naming_scheme_udev_setup.yml b/playbooks/microtask_networking_naming_scheme_udev_setup.yml index 9f401edf8acd0723c6409242422ec14d4c948ca3..60333e1f6576f9abaa145614805f7e1cbe0c4482 100644 --- a/playbooks/microtask_networking_naming_scheme_udev_setup.yml +++ b/playbooks/microtask_networking_naming_scheme_udev_setup.yml @@ -15,7 +15,7 @@ dest: /etc/udev/rules.d/72-wlan-geo-dependent.rules - - name: Query current interface names + - name: Query current interface names (except errors) shell: "ip a | grep wlan" ignore_errors: true register: any_wlans diff --git a/playbooks/ssh_setup.yml b/playbooks/ssh_setup.yml index 3d731e63b88ca81d148c7592a63c87b4ee0e228b..a4a4107b813342b989321d54e43b2eb94ae447f0 100644 --- a/playbooks/ssh_setup.yml +++ b/playbooks/ssh_setup.yml @@ -7,7 +7,8 @@ private: true vars: ansible_host_key_checking: false - + ansible_ssh_extra_args: '-o StrictHostKeyChecking=no' + gather_facts: no tasks: - name: Install sshpass and keychain to master device @@ -20,18 +21,25 @@ delegate_to: 127.0.0.1 run_once: true become: true - # when: false + become_user: root + + + - name: Check if SSH key file already exists + stat: + path: ~/.ssh/id_sniffer + delegate_to: 127.0.0.1 + run_once: True + register: ssh_key_file - name: SSH KeyGen command on master device tags: ssh-setup ssh-keygen config master ansible.builtin.shell: cmd: ssh-keygen -q -b 2048 -t rsa -N "" -C "master sniffer ssh access" -f ~/.ssh/id_sniffer - creates: "~/.ssh/id_sniffer" delegate_to: 127.0.0.1 run_once: True register: ssh_keygen_result - + when: not ssh_key_file.stat.exists - name: keygen failure status check tags: ssh-setup config keychain master @@ -42,19 +50,24 @@ Next task will be skipped. delegate_to: 127.0.0.1 run_once: True - when: ssh_keygen_result.stdout.find('skipped') == 0 | default(false) + when: + - ssh_key_file.stat.exists | default(false) - name: Copy the master's public key and add to nodes' authorized_keys tags: ssh-setup config ssh-copy nodes ansible.posix.authorized_key: user: "{{ansible_ssh_user}}" - key: "{{ lookup('file','~/.ssh/id_sniffer.pub')}}" + key: "{{ lookup('file', lookup('env','HOME') + '/.ssh/id_sniffer.pub')}}" + state: present + # exclusive: true + - name: Set up keychain inside .bashrc tags: ssh-setup config keychain master ansible.builtin.shell: - cmd: echo "eval \$(keychain --eval --quiet id_sniffer)" >> ~/.bashrc; eval \$(keychain --eval --quiet id_sniffer) - delegate_to: 127.0.0.1 + cmd: echo 'eval $(keychain --eval --quiet id_sniffer)' >> ~/.bashrc; keychain --quiet id_sniffer + delegate_to: localhost run_once: True - when: ssh_keygen_result.stdout.find('skipped') == -1 | default(true) + when: not ssh_key_file.stat.exists | default(true) + diff --git a/playbooks/start_sens_sniffer.yml b/playbooks/start_sens_sniffer.yml index 4355a411f1e56e5f7cb414278f6e7b2907e0b727..916906260b8b723b438c2ee823613759b0eef188 100644 --- a/playbooks/start_sens_sniffer.yml +++ b/playbooks/start_sens_sniffer.yml @@ -28,7 +28,7 @@ - name: _pcap_name prompt: "Name of the PCAP file. ?post will get replaced by a bunch of context info (date and params) and .pcap" - default: "mitik_experiment-?post" + default: "mitik_experiment_{{ansible_hostname}}-?post" private: false - name: _timeout @@ -70,7 +70,7 @@ - name: _gps_poll_timeout prompt: time in seconds between each location polling - default: 900 + default: 30 private: false tasks: @@ -104,4 +104,4 @@ name: "ansible_sens_gps {{ _hour }} {{ _minute }}" minute: "{{ _minute }}" hour: "{{ _hour }}" - job: "/home/{{ansible_ssh_user}}/positionGetter.sh {{_gps_poll_timeout}} 10 '{{_workdir}}' '{{_location_prefix}}'" + job: "/home/{{ansible_ssh_user}}/positionGetter.sh {{_gps_poll_timeout}} 5 '{{_workdir}}' '{{_location_prefix}}'"