Created
February 23, 2025 18:58
-
-
Save oleduc/ded8ab6d0baf92a81acf50ba633f7c51 to your computer and use it in GitHub Desktop.
Automate the setup of RClone and Proton Drive on Linux
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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