Score:1

Cubic custom ISO which executes shell script at startup

ae flag

I'm trying to customise an Ubuntu ISO with Cubic to run a couple of shell scripts when the Live user logs in. I've been following a bunch of tutorials with a ton of instructions and I eventually had it working at one point. Unfortunately, I'm not able to recreate the setup and worse still, I've deleted the particular ISO thinking I won't be needing it. So far, I've moved my shell scripts to the /etc/skel directory through the chroot environment in Cubic and modified the the crontab by adding an @reboot command. After that, I let Cubic create my ISO and I flashed it to a USB. I booted it up but realised the scripts hadn't been executed. I checked the home directory (since thats where the contents of /etc/skel are supposed to go) and all my scripts were present. How can I get this working?

us flag
Does your script need to run as root? Do you need this script to run upon each login? Does this script need to run only for the live environment user (i.e. "ubuntu") or should it run for other users as well (i.e. if you create new users while using the live environment)? Does this script also need to run in the *installed* system (i.e. after you've installed the OS from the live ISO)?
n00dles avatar
ae flag
@PJSingh well some of the scripts involve mounting attached devices. It'll need to be root. No, the scripts need to be run only after the first login and only for the live user. Although, if possible please explain the process for running it for multiple users. As for the last question, I have no intentions of installing permanently, so no.
Score:1
us flag

Instead of using chron, you can use an autostart script to connect to the remote machine.

You should setup key based authentication to the remote machine, so no user interaction is required.

In the instructions below, replace the following values as needed.

  • LOCAL - the IP address or host name of your local computer (where you are running Cubic)
  • REMOTE - the IP address or host name of the remote computer
  • n00dles - the user name on the local computer and/or the remote computer
  • REMOTE_LOCATION_PATH - the path of the directory you want to mount on the remote computer
  1. Generate public and private keys for your local machine.

    These keys will be used in your custom ISO. Be aware of the security implications. Anyone who gets a hold of your customized USB will be able to login to your remote machine.

    Execute the following commands on your local machine (e.g. not in Cubic).

    cd ~
    ssh-keygen -t rsa
    

    Accept the defaults. The output will look something like this.

    Generating public/private rsa key pair.
    Enter file in which to save the key (/home/n00dles/.ssh/id_rsa): 
    Enter passphrase (empty for no passphrase):
    Enter same passphrase again:
    Your identification has been saved in /home/n00dles/.ssh/id_rsa
    Your public key has been saved in /home/n00dles/.ssh/id_rsa.pub
    The key fingerprint is:
    SHA256:G48dcTOXpUhzWxuzwn8pgdOTP9WmlLtXBCJkkiSEywk n00dles@LOCAL
    The key's randomart image is:
    +---[RSA 3072]----+
    |     xxxxxx x xxx|
    |  x x  xxxxxxxxxx|
    |   x x    xxxxxxx|
    |    x      xxxxxx|
    |  x     x x  xxxx|
    |         x x  xxx|
    |  x     x x   x x|
    |               x |
    |  x              |
    +----[SHA256]-----+
    
  2. Setup remote login.

    Copy the public key to the remote machine. Be aware of the security implications. This will allow remote connections from any computer using the corresponding private key.

    ssh-copy-id -i .ssh/id_rsa.pub user@host
    

    Create a new known_hosts file that you will copy to the customized ISO. This will allow the Live environment to connect to the remote machine without prompting the user to confirm.

    Temporarily backup your current known_hosts file. Remember to replace n00dles@REMOTE and REMOTE_LOCATION_PATH as necessary.

    mv ~/.ssh/known_hosts ~/.ssh/known_hosts.original
    
    # Login to the remote machine to automatically create a new `known_hosts` file.
    sudo mkdir /mnt/remote
    sshfs [email protected]:/REMOTE_LOCATION_PATH/ /mnt/remote/
    
    ECDSA key fingerprint is SHA256:XXXX.
    Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
    
    # Unmount the remote machine.
    fusermount -u /mnt/remote
    sudo rmdir /mnt/remote
    
    # Save the new known_hosts file.
    mv ~/.ssh/known_hosts ~/
    
    # Revert the original known_hosts file.
    mv ~/.ssh/known_hosts.original ~/.ssh/known_hosts
    
  3. Customize the ISO using Cubic.

    Launch Cubic and do the following on the Terminal page.

    Make sure sshfs is installed so we can connect to remote machines.

    apt install sshfs
    

    Copy the keys and the new known_hosts file to the custom OS.

    cd /etc/skel
    mkdir .ssh
    chmod u=rwx,g=,o= .ssh
    cd .ssh
    

    Open a file browser such as Nautilus and navigate to your local ~/.ssh directory.

    Select id_rsa and id_rsa.pub and drag them onto the Cubic window to copy them into the current directory, /etc/skel.ssh.

    Open a file browser such as Nautilus and navigate to your home directory.

    Select the new known_hosts file and drag it onto the Cubic window to copy it into the current directory, /etc/skel/.ssh.

    Make sure the permissions are correctly set for these files; this is very important. In Cubic, execute the following:

    chmod u=rw,g=,o= id_rsa
    chmod u=rw,g=r,o=r id_rsa.pub
    chmod u=rw,g=r,o=r known_hosts
    
    ls -la
    
    -rw------- 1 root root 2602 Jun  7 09:35 id_rsa
    -rw-r--r-- 1 root root  566 Jun  7 09:35 id_rsa.pub
    -rw-r--r-- 1 root root  222 Jun  7 09:35 known_hosts
    

    Create a mount point for the remote location, make sure it can be used by all users, and add a link named Remote in each user's home directory.

    mkdir /mnt/remote
    chmod a+rw /mnt/remote
    ln -s /mnt/remote /etc/skel/Remote
    
  4. Create a script to mount the remote location.

    nano /opt/mount_remote.sh
    

    Add the following to the script. Remember to replace n00dles@REMOTE and REMOTE_LOCATION_PATH as necessary.

    #!/bin/bash
    # Mounts the remote location.
    # To mount use: sshfs [email protected]:/REMOTE_LOCATION_PATH/ /mnt/remote
    # To unmount use: fusermount -u /mnt/remote
    for i in {1..5}; do
        if mountpoint /mnt/remote; then
            echo "[email protected]:/REMOTE_LOCATION_PATH is mounted."
            break
        else
            # Attempt to mount the remote location to /mnt/remote
            echo "Attempt # $i to mount [email protected]:/REMOTE_LOCATION_PATH."
            sleep $i
            sshfs [email protected]:/REMOTE_LOCATION_PATH/ /mnt/remote
        fi
    done
    if mountpoint /mnt/remote; then
        echo "Successfully mounted [email protected]:/REMOTE_LOCATION_PATH."
    else
        echo "Unable to mount [email protected]:/REMOTE_LOCATION_PATH."
    fi
    

    Type CTRLX, Y, Enter to save the file.

    You can use environment variables such as $HOME in the script, if you need to.

    Make the script executable.

    chmod +x /opt/mount_remote.sh
    
  5. Create an autostart file that will run for each user after login.

    nano ~/mount_remote.desktop
    

    For XUbuntu 20.04+ or older versions of Ubuntu, add the following to the file.

    [Desktop Entry]
    Encoding=UTF-8
    Version=0.9.4
    Type=Application
    Name=mount_remote
    Comment=Mount remote location
    Exec=/opt/mount_remote.sh
    OnlyShowIn=XFCE;
    RunHook=0
    StartupNotify=false
    Terminal=false
    Hidden=false
    

    For Ubuntu 20.04+, add the following to the file.

    [Desktop Entry]
    Type=Application
    Exec=/opt/mount_remote.sh
    Hidden=false
    NoDisplay=false
    X-GNOME-Autostart-enabled=true
    Name[en_US]=Mount Remote
    Name=Mount Remote
    Comment[en_US]=Mount remote location
    Comment=Mount remote location
    

    Type CTRLX, Y, Enter to save the file.

    You can add Terminal=true to the *.desktop file for debugging purposes, but the remote location will be immediately unmounted once the terminal window automatically closes.

  6. Move the autostart file to the correct location. You have two options.

    • If you want to use a global autostart file, move it to /etc/xdg/autostart.

      mv ~/mount_remote.desktop /etc/xdg/autostart
      
    • If you want each user to have thier own copy of the autostart file, move it to /etc/skel/.config/autostart. (Users will be able to delete this file because it will be placed in their home folder).

      mkdir -p /etc/skel/.config/autostart
      mv ~/mount_remote.desktop /etc/skel/.config/autostart
      
  7. Continue customizing your OS, and generate a new ISO.

  8. Testing

    If you use the remote host name instead of the IP address, when you test the generated ISO, make sure DNS resolution works. In VirtualBox, I usually set the Network to use the "Bridge Adapter" instead of the default "NAT" adapter.

us flag
In the above answer, I assume you only needed your script to run as root in order to mount the remote location. Since this can be done without root, the script in this answer does not run with root privileges.
n00dles avatar
ae flag
Hey @PJSingh, thanks for the detailed answer. I wanted to test whether the autorun was working first before messing with mounting. Since there's no way of checking if the scripts were even getting called, I created a test script in /opt as /opt/test.sh. The contents were the shebang at the first line and a touch command to create a file "it_worked.txt" at the home directory. And then, I did the chmod and created the autostart file The idea was that if the script gets called after the live user logs in, I'd see "it_worked.txt" in my home directory. The problem is, I didn't. What could be wrong?
us flag
Did you create a corresponding `/etc/skel/.config/autostart/mount_remote.desktop` file? If you're testing by creating a custom ISO using cubic, the `*.desktop` file should be in `/etc/skel/.config/autostart`. If are testing on your local system, the file should be placed in `~/.config/autostart`, and you can test by logging out and back in. I would also suggest using use full paths, not relative paths, in `test.sh` (so something like `touch /home/ubuntu/it_worked.txt`).
n00dles avatar
ae flag
I followed the 5th point in your answer to the letter. The .desktop file is in /etc/skel/.config/autostart directory. Since it was for testing purposes I ran multiple touch commands just to be sure. Here are the contents of "test.sh". Lines have been separated by " ### " --> #!/bin/bash ### sleep 2 ### sudo touch "/etc/skel/it_worked_1.txt" ### sudo touch "$HOME/it_worked_2.txt". Neither of the files were created after startup. I ran the script manually and it worked. So I'm messing something up in the autorun.
us flag
I don't know if the script will have access to `$HOME`. Your script will not have write permissions for `/etc/skel/`; that's why we made `/mnt/remote` writable in step 3. In your `*.desktop` file, set `Terminal=true`. Add `sleep 10` as the last line of your script. This way, you will see a terminal pop-up when your script runs, and you will have 10 seconds to read the output before the terminal automatically closes, so you can debug. Use can use echo commands to print output as the script runs. For example, you could do `echo $HOME`.
n00dles avatar
ae flag
I changed Terminal to true and changed the script to create "it_worked.txt" at /mnt/test. It didn't work. And a terminal window didn't pop up for 10 seconds after startup. What could be the issue?
us flag
I see the issue. The format for the autostart file has changed. Use the new layout "For Ubuntu 20.04+" shown in step 5. Also, I suggest placing the autostart file in `/etc/xdg/autostart`, as shown in step 6.
us flag
By the way, I tested, and the environment variable `$HOME` is available to the script when it executes.
n00dles avatar
ae flag
Hey @PJSingh, making those changes did the trick! Everything works as intended, thank you for all the help. I had another Cubic question. Seeing as how you know your way around it, could you please take a look?https://askubuntu.com/q/1344916/1287755
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.