Skip to content

Instantly share code, notes, and snippets.

@oleduc
Created February 23, 2025 18:58
Show Gist options
  • Save oleduc/ded8ab6d0baf92a81acf50ba633f7c51 to your computer and use it in GitHub Desktop.
Save oleduc/ded8ab6d0baf92a81acf50ba633f7c51 to your computer and use it in GitHub Desktop.
Automate the setup of RClone and Proton Drive on Linux
#!/usr/bin/env bash
#
# Proton-Drive-Interactive-Setup.sh
#
# This script automates installing the RClone beta, configuring an
# encrypted RClone config, adding a "protondrive" remote, storing
# credentials in an OS keyring, and setting up a user systemd service.
#
# Written as an example. Please audit thoroughly before running!
###############################################################################
# 1. Preliminary checks and disclaimers
###############################################################################
if [[ $EUID -eq 0 ]]; then
echo "WARNING: It is recommended to run this script as a regular user, not root."
echo "Press Ctrl+C to abort or Enter to continue..."
read
fi
echo "This script will attempt to automate the setup of Proton Drive using RClone."
echo "It will install RClone beta, set up config encryption, configure a remote,"
echo "store your encryption password in the OS keyring, and install a systemd user service."
echo "Please carefully review the script before running it."
echo
echo "Press Enter to continue, or Ctrl+C to abort."
read
###############################################################################
# 2. Dependencies installation
###############################################################################
echo
echo "Step 1: Installing dependencies (Python3, pip, keyring)..."
# Check if python3 is installed
if ! command -v python3 &> /dev/null; then
echo "Python3 not found. Attempting to install..."
if command -v apt &> /dev/null; then
sudo apt update && sudo apt install -y python3
elif command -v yum &> /dev/null; then
sudo yum install -y python3
else
echo "Could not detect a supported package manager (apt or yum). Install python3 manually."
exit 1
fi
else
echo "Python3 is already installed."
fi
# Check if pip is installed
if ! command -v pip &> /dev/null; then
echo "pip not found. Attempting to install..."
if command -v apt &> /dev/null; then
sudo apt update && sudo apt install -y python3-pip
elif command -v yum &> /dev/null; then
sudo yum install -y python3-pip
else
echo "Could not detect a supported package manager (apt or yum). Install pip manually."
exit 1
fi
else
echo "pip is already installed."
fi
# Install python keyring
if ! python3 -c "import keyring" &> /dev/null; then
echo "Installing python keyring..."
pip install --user keyring
else
echo "python-keyring is already installed."
fi
###############################################################################
# 3. (Re)Install RClone Beta
###############################################################################
echo
echo "Step 2: Installing or reinstalling the RClone beta version..."
# Optional removal of old rclone
echo "If you have a previous RClone installed, it's recommended to remove it first."
read -p "Remove old RClone? (y/n) [n] " REMOVE_OLD
REMOVE_OLD=${REMOVE_OLD:-n}
if [[ "$REMOVE_OLD" == "y" ]]; then
if command -v rclone &> /dev/null; then
echo "Removing old rclone binaries (if installed via package manager, it won't remove those)."
sudo rm -f $(which rclone)
fi
fi
# Download and audit the official rclone install script
curl -s https://rclone.org/install.sh > install-rclone.sh
echo "Downloaded install-rclone.sh from https://rclone.org/install.sh"
echo "It's recommended to audit the install script now."
echo "Press Enter to display the script or Ctrl+C to quit..."
read
cat install-rclone.sh
echo
echo "If you are satisfied the install script is safe, press Enter to proceed with the beta installation."
read
# Run the script
sudo -v && sudo bash install-rclone.sh beta
###############################################################################
# 4. Configure RClone config encryption
###############################################################################
echo
echo "Step 3: Configure RClone config encryption."
CONFIG_PASS=""
echo "RClone can encrypt its config to protect your login credentials."
echo "This script will walk you through setting the config password."
echo "You will be prompted for the config encryption password (not your Proton password)."
read -p "Enter the RClone config encryption password you'd like to use: " -s CONFIG_PASS
echo
if [[ -z "$CONFIG_PASS" ]]; then
echo "No password entered. Exiting."
exit 1
fi
# Use rclone's 'config password' subcommand to set the config encryption
# We can feed the password with an expect script to automate it.
if ! command -v expect &> /dev/null; then
echo "Installing 'expect' to handle interactive prompts..."
if command -v apt &> /dev/null; then
sudo apt update && sudo apt install -y expect
elif command -v yum &> /dev/null; then
sudo yum install -y expect
else
echo "Could not detect a supported package manager to install 'expect'. Install it manually."
exit 1
fi
fi
cat << EOF > /tmp/set_rclone_config_pw.exp
#!/usr/bin/env expect
set timeout 60
spawn rclone config password
expect "Enter NEW configuration password:"
send "$CONFIG_PASS\r"
expect "Confirm NEW password:"
send "$CONFIG_PASS\r"
expect {
"Password set" {}
timeout { exit 1 }
}
expect eof
EOF
chmod +x /tmp/set_rclone_config_pw.exp
echo "Setting the RClone config encryption password..."
/tmp/set_rclone_config_pw.exp
if [[ $? -ne 0 ]]; then
echo "Failed to set rclone config password. Exiting."
exit 1
fi
rm -f /tmp/set_rclone_config_pw.exp
###############################################################################
# 5. Configure the Proton remote in RClone
###############################################################################
echo
echo "Step 4: Configure the Proton Drive remote in RClone."
read -p "Enter your Proton Email (ex: [email protected]): " PROTON_USER
if [[ -z "$PROTON_USER" ]]; then
echo "No Proton email entered. Exiting."
exit 1
fi
echo "Proton password (not the RClone config encryption password)."
read -p "Enter your Proton password: " -s PROTON_PASS
echo
read -p "Do you use 2FA? (y/n) [n] " USE_2FA
USE_2FA=${USE_2FA:-n}
PROTON_2FA=""
if [[ "$USE_2FA" == "y" ]]; then
echo "2FA tokens expire quickly. You can enter it now, or you will have to type it quickly in the prompt."
read -p "Enter your 2FA code (leave empty to skip): " PROTON_2FA
fi
echo
echo "Creating an RClone remote named 'proton' using the 'protondrive' backend..."
# We'll do a two-stage approach:
# 1) rclone config create ... minimal
# 2) run `rclone ls proton:` quickly to finalize the session
REMOTE_NAME="proton"
# For 2FA, we can pass an environment variable or attempt a direct config approach.
# RClone's protondrive fields are:
# user = your email
# pass = your pass
# 2fa = your 2fa code (optional)
# If 2FA is used, we must do it quickly. We might try to do it inline:
# However, if the code expires, you might need to re-run it or quickly fix it.
echo "Creating the remote with the provided credentials..."
rclone config create \
"$REMOTE_NAME" \
protondrive \
user "$PROTON_USER" \
pass "$PROTON_PASS" \
2fa "$PROTON_2FA" 2> /dev/null
if [[ $? -ne 0 ]]; then
echo "Remote creation encountered an error. You may need to run 'rclone config' manually."
exit 1
fi
echo
echo "Attempting 'rclone ls proton:' to verify the remote is working (this will prompt for config encryption password if needed)."
echo "If 2FA is expired, you might see an error. In that case, run 'rclone ls proton:' again quickly with a fresh 2FA code."
rclone ls "${REMOTE_NAME}:" || true
###############################################################################
# 6. Store your RClone config password in OS Keyring
###############################################################################
echo
echo "Step 5: Store the RClone config encryption password in your OS keyring."
echo "This is so that on reboot or via systemd, we can retrieve it securely."
echo "You'll be prompted again for the same config encryption password you entered earlier."
if python3 -c "import keyring" &> /dev/null; then
echo "Storing RClone config password in the keyring under service='rclone' and username='proton'."
# We can store it by echoing the password into 'keyring set', but let's do it more safely:
# echo "$CONFIG_PASS" | keyring set rclone proton
# However, not all shells let you pipe correctly. We'll just read it again from user with a direct approach.
# For a fully non-interactive approach, you can do:
# printf "%s" "$CONFIG_PASS" | keyring set rclone proton
python3 -c "import keyring; keyring.set_password('rclone', 'proton', '$CONFIG_PASS')"
if [[ $? -eq 0 ]]; then
echo "Successfully stored RClone config password in the keyring."
else
echo "Failed to store password in keyring. You may have to do this manually: keyring set rclone proton."
fi
else
echo "python3 keyring is not found, skipping. Please install python3-keyring manually."
fi
###############################################################################
# 7. Download the mount management script
###############################################################################
echo
echo "Step 6: Downloading the rclone-mount-proton.sh script and installing it to /usr/local/bin/."
curl -s https://gist.githubusercontent.com/oleduc/b3473b34801f9618b77e579392a12d79/raw/3fa46a7adc9418d59cd0e38b096765e919fc703d/rclone-mount-proton.sh > rclone-mount-proton.sh
sudo mv rclone-mount-proton.sh /usr/local/bin/rclone-mount-proton.sh
sudo chmod +x /usr/local/bin/rclone-mount-proton.sh
echo "It's recommended to edit the script to match your preferred mount path and remote name (default is 'proton')."
read -p "Press Enter to open nano for editing or Ctrl+C to skip..."
sudo nano /usr/local/bin/rclone-mount-proton.sh
###############################################################################
# 8. Create and enable the systemd user service
###############################################################################
echo
echo "Step 7: Setting up the systemd user service for automatic mounting."
mkdir -p ~/.config/systemd/user
SERVICE_FILE=~/.config/systemd/user/rclone-proton-mount.service
if [[ -f "$SERVICE_FILE" ]]; then
echo "A systemd service file already exists at $SERVICE_FILE. Backing it up..."
mv "$SERVICE_FILE" "$SERVICE_FILE.bak.$(date +%s)"
fi
cat << 'EOF' > "$SERVICE_FILE"
[Unit]
Description=Mount Proton Drive using Rclone
After=default.target
Requires=default.target
[Service]
Type=simple
ExecStart=/usr/local/bin/rclone-mount-proton.sh mount
ExecStop=/usr/local/bin/rclone-mount-proton.sh unmount
ExecReload=/usr/local/bin/rclone-mount-proton.sh unmount && /usr/local/bin/rclone-mount-proton.sh mount
Restart=always
RestartSec=10
Environment=HOME=%h
KillMode=process
[Install]
WantedBy=default.target
EOF
echo "Reloading user daemon and enabling service..."
systemctl --user daemon-reload
systemctl --user enable rclone-proton-mount.service
echo "Starting the service now..."
systemctl --user start rclone-proton-mount.service
echo
echo "The systemd user service log is accessible via:"
echo " journalctl --user -u rclone-proton-mount.service -f"
echo
echo "If the mount fails, please ensure you typed the correct config encryption password, remote name, or that the 2FA session is valid."
echo
echo "Done! On reboot, you should be prompted for your keyring password, and your Proton Drive should be mounted automatically."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment