electron-userland / electron-builder

A complete solution to package and build a ready for distribution Electron app with “auto update” support out of the box
https://www.electron.build
MIT License
13.61k stars 1.74k forks source link

How to pass --no-sandbox Debian appImage? #5371

Closed davidhealey closed 2 years ago

davidhealey commented 3 years ago

In order to run electron on Debian I have to start it with the --no-sandbox option. How can I have this automatically done for my appImage generated by electron-builder? I don't want my users to have to run the app from the command line and enter --no-sandbox everytime.

Thanks.

jely2002 commented 3 years ago

I'm having the exact same problem, any solutions or workarounds yet?

stale[bot] commented 3 years ago

Is this still relevant? If so, what is blocking it? Is there anything you can do to help move it forward?

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.

csett86 commented 3 years ago

Yes, still relevant for Debian 10+

jely2002 commented 3 years ago

Sharing my solution for other folks who stumble across this issue.

In my package.json I run a script after packaging the app:

 "build": {
    "afterPack": "./appimage-fix.js",

This script renames the executable that usually gets launched to <app-name>.bin and creates a shell script with the old name of the executable: <app-name>. So that when you launch the app-image the shell script gets executed.

The shell script then opens the <app-name>.bin file with the --no-sandbox option.

appimage-fix.js

Just swap out the appName variable with the one specified in your package.json and you're good to go.

const child_process = require('child_process'),
    fs = require('fs'),
    path = require('path');

const appName = "youtube-dl-gui";    

function isLinux (targets) {
    const re = /AppImage|snap|deb|rpm|freebsd|pacman/i;
    return !!targets.find ( target => re.test (target.name));
}

async function afterPack ({targets, appOutDir}) {
    if ( !isLinux ( targets ) ) return;
    const scriptPath = path.join(appOutDir, appName),
        script = '#!/bin/bash\n"${BASH_SOURCE%/*}"/' + appName + '.bin "$@" --no-sandbox';
    new Promise((resolve) => {
        const child = child_process.exec(`mv ${appName} ${appName}.bin`, {cwd: appOutDir});  
        child.on('exit', () => {
            resolve();
        });    
    }).then(() => {
        fs.writeFileSync (scriptPath, script);
        child_process.exec(`chmod +x ${appName}`, {cwd: appOutDir});
    });
}

module.exports = afterPack;
csett86 commented 3 years ago

Thanks a lot @jely2002, this is a good workaround.

Based on your solution I have taken the same approach for https://github.com/jitsi/jitsi-meet-electron/pull/550, only difference is that it takes the executable name from the packager context and the renames and file writing is done via the async promises nodejs api: https://github.com/csett86/jitsi-meet-electron/blob/fix-231/linux-sandbox-fix.js

stale[bot] commented 3 years ago

Is this still relevant? If so, what is blocking it? Is there anything you can do to help move it forward?

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.

jely2002 commented 3 years ago

Yes, this is still relevant for Debian 10+

stale[bot] commented 3 years ago

Is this still relevant? If so, what is blocking it? Is there anything you can do to help move it forward?

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.

bahadirdogru commented 3 years ago

yes

probonopd commented 2 years ago

AppImages based on Electron require the kernel to be configured in a certain way to allow for its sandboxing to work as intended (specifically, the kernel needs to be allowed to provide “unprivileged namespaces”). Many distributions come with this configured out of the box (like Ubuntu for instance), but some do not (for example Debian).

To temporarily enable unprivileged namespaces, you can run this command:

sudo sysctl -w kernel.unprivileged_userns_clone=1

This command will take effect immediately but will not survive a reboot. To permanently enable unprivileged namespaces, run:

echo kernel.unprivileged_userns_clone = 1 | sudo tee /etc/sysctl.d/00-local-userns.conf

This command will take effect only on the next reboot.

Please see https://docs.appimage.org/user-guide/troubleshooting.html#i-have-issues-with-electron-based-appimages-and-their-sandboxing for more information.

If you think that Debian should enable unprivileged namespaces by default (like most other desktop distributions do), then please file an issue with Debian.

stale[bot] commented 2 years ago

Is this still relevant? If so, what is blocking it? Is there anything you can do to help move it forward?

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.

probonopd commented 2 years ago

Please reopen.

mmaietta commented 2 years ago

This is the only information I could locate on your request, but I don't know what AppRun is. https://discourse.appimage.org/t/command-line-parameter-transfer/1537

AFAICT, this is not a feature that can be built by electron-builder. AppImage creation is handled by an upstream project https://github.com/develar/app-builder, so any feature request will need to be opened there.

mmaietta commented 2 years ago

@probonopd I found this PR that might serve what you need for AppImages? https://github.com/electron-userland/electron-builder/pull/6429/files Way to pass --no-sandbox for linux is via executableArgs in electron-builder config, but it's already considered default if no other args provided

Alternatively, in my project, I noticed previous logic for just adding it in main/index.ts

app.commandLine.appendSwitch("--no-sandbox");
probonopd commented 2 years ago

Thanks @mmaietta. This will help a lot of people. It should be made the default.

gergof commented 2 years ago

I have made a tool that automatically applies the --no-sandbox flag when the unprivileged_userns_clone kernel feature is not enabled: https://www.npmjs.com/package/electron-builder-sandbox-fix

probonopd commented 2 years ago

Cool! We should add this to the AppImage (and Electron?) docs.

Even better, this should be made the default in Electron for AppImages.

csett86 commented 2 years ago

I would not make this the default, as Debian 11 also no longer requires the --no-sandbox. Since Debian 11 unprivileged processes can create namespaces by default: https://www.debian.org/releases/bullseye/amd64/release-notes/ch-information.en.html#linux-user-namespaces

mmaietta commented 2 years ago

@probonopd AppImage target already applies --no-sandbox by default (added Oct 16th, 2020 in ede6d50ddb6c23fe6bbb056bd80509c8f2ea0116) if no custom executableArgs are passed in via the electron-builder config https://github.com/electron-userland/electron-builder/blob/f205998999ff615c9ea63184520a1efbbff5a785/packages/app-builder-lib/src/targets/AppImageTarget.ts#L22-L23

hz2018tv commented 1 year ago

I am getting "[1109/191656.470723:FATAL:electron_main_delegate.cc(298)] Running as root without --no-sandbox is not supported. See https://crbug.com/638180.". passing --no-sandbox will fix it. but none of the executableArgs and the app.commandLine.appendSwitch("--no-sandbox") worked. (electron v21.2.2, electron-builder v23.6.0 FWIW)