Trying to run a Python script for Linux

We’re trying to run a python script on Linux servers with no luck. I’ve tried packaging the script and running it in a BigFix task, also by creating a file then running it that way. But neither runs using BigFix. Although that same file runs successfully locally. So that tells me it’s the way we’re running it via BigFix.

The python script is a downloaded onboarding script for Microsoft Defender Advanced Threat Protection. The command used to run the script is listed below.

sudo python MicrosoftDefenderATPOnboardingLinuxServer.py

When running it via BigFix I’ve used the below commands.

Wait chmod +x __Download/MicrosoftDefenderATPOnboardingLinuxServer.py
Wait python __Download/MicrosoftDefenderATPOnboardingLinuxServer.py

Or I move it to the /tmp directory and run it from there.

Wait chmod +x /tmp/MicrosoftDefenderATPOnboardingLinuxServer.py
Wait python /tmp/ MicrosoftDefenderATPOnboardingLinuxServer.py

Again, the same file that is downloaded using BigFix runs successfully when ran locally.
Has anyone run a python script in Linux? What am I doing wrong?

Thanks in advance!
-Joe

1 Like

What messages do you get in the client log when the action runs? At first glance, I think that ‘python’ might not be in the PATH for the BESClient service, so you might try supplying the full path to python i.e. /bin/python or whatever your installed path is.

1 Like

Hi Jason, I usually get completed exit code 1 . Also, python is in /usr/bin so I 've used the full path as well. Each time, I leave the file behind so that I can verify the file locally and it runs with a simple “python MicrosoftDefenderATPOnboardingLinuxServer.py” command that completes successfully.

Command succeeded (Exit Code=1) wait python /usr/bin/MicrosoftDefenderATPOnboardingLinuxServer.py

Command succeeded (Exit Code=1) wait /usr/bin/python /tmp/MicrosoftDefenderATPOnboardingLinuxServer.py

I even used the create file method and that didn’t work. However, the file I created and left behind on the server will work locally.

Thanks for your suggestions. I’m currently stumpped and any help is appreciated.

Does the Microsoft script have some dependency on environment variables, that might not be present when running a non-login shell?

You might try

Wait /bin/sh --login -c "/usr/sbin/python /tmp/MicrosoftDefenderATPOnboardingLinuxServer.py > /tmp/output.txt 2>&1"

That should run with a login shell (processes things like .login that may supply more environment variables), and redirects the output and error messages to /tmp/output.txt. reading the output file may give more clues if python or the script itself are presenting error messages.

1 Like

I don’t see anything on the Microsoft site about that. It basically says to copy the file down locally and run the command I’m using, but that might be in play here.

From Microsoft:
"Client configuration
1.Copy MicrosoftDefenderATPOnboardingLinuxServer.py to the target device.

Note
Initially the client device is not associated with an organization and the orgId attribute is blank.

Bash
mdatp health --field org_id

2.Run MicrosoftDefenderATPOnboardingLinuxServer.py.

Note
To run this command, you must have python or python3 installed on the device depending on the distro and version. If needed, see Step-by-step Instructions for Installing Python on Linux.

If you’re running RHEL 8.x or Ubuntu 20.04 or higher, you will need to use python3.

Bash
sudo python3 MicrosoftDefenderATPOnboardingLinuxServer.py
For the rest of distros and versions, you will need to use python.

Bash
sudo python MicrosoftDefenderATPOnboardingLinuxServer.py"

Here’s the link on how to deploy MS Defender for Endpoint on Linux Manually. We’re able to get the mde_installer.sh script pushed with no issues. It’s this python script giving us grief.

I ran your command and it came back with exit code 127 and the server is still not onboarded. In other words, not healthy or licensed.

Command started - wait /bin/sh --login -c “/usr/sbin/python /tmp/MicrosoftDefenderATPOnboardingLinuxServer.py > /tmp/output.txt 2>&1” (action:1943628)
At 19:16:03 -0500 -
Report posted successfully
At 19:16:03 -0500 - actionsite (http://172.16.0.32:52311/cgi-bin/bfgather.exe/actionsite)
Command succeeded (Exit Code=127) wait /bin/sh --login -c “/usr/sbin/python /tmp/MicrosoftDefenderATPOnboardingLinuxServer.py > /tmp/output.txt 2>&1” (action:1943628)

Here’s the output from the file.
[root@ap01srdxqa2800 tmp]# cat output.txt
/bin/sh: /usr/sbin/python: No such file or directory

Ah, my mistake. You mentioned earlier that python was at /use/bin/python, but ai mistyped that as /usr/sbin/python. Try changing that path to python.

Also, verify that /usr/bin/python is python version 3, since the Microsoft script says it requires that. I’d expect that /usr/bin/python might be python v2 and there may be a /usr/bin/python3 to run (or install) instead.

1 Like

Jason, after running your command with the correct path (Wait /bin/sh --login -c “/usr/bin/python /tmp/MicrosoftDefenderATPOnboardingLinuxServer.py > /tmp/output.txt 2>&1”), I received the output below.

“sudo: sorry, you must have a tty to run sudo
Generating /etc/opt/microsoft/mdatp/mdatp_onboard.json …
Command ‘sudo mkdir -p ‘/etc/opt/microsoft/mdatp’’ returned non-zero exit status 1”

After reading up on tty or teletypewriter and understanding it, I checked our sudoers file, I realized that the following line was present.

“Defaults requiretty”

I changed that to…

“Defaults !requiretty”

I’ve tested my task on a few servers which installs Microsoft Defender for Endpoint on Linux, and onboarding script all in one command (command below), runs successfully now. Before only the mde_installer.sh portion would complete, not the onboarding python script.

“wait /bin/sh -c “/tmp/mde_installer.sh --install --channel prod --onboard /tmp/MicrosoftDefenderATPOnboardingLinuxServer.py --tag GROUP LinuxServer --min_req -y””

Because I was able to run numerous tasks & fixlets (installs, config changes, patches) on these servers, I was perplexed with this python file. I wasn’t familiar with “TTY Requirement” so I can’t thank you enough for pointing me to the root cause.

I owe you a beer or two for sure!
Thank you Jason!

Glad you got it sorted out!

I guess that internally their python script was explicitly trying to execute ‘sudo’… that shouldn’t be necessary when running via BigFix because we run with root privilege already, but their script must assume that sudo is needed.

That seems a bit janky, i.e. I would not appreciate a script silently sudo’ing something for me, better to let the script fail and let me know I need to sudo before running the script as a whole, but I guess it’s not shocking MS would do it that way.

1 Like

You know, I opened the file searching and thinking, do curly brackets come in to play here? But then I thought, nah…can’t be within a prefetched downloaded file. But I didn’t think to search for sudo. :frowning:

Sure enough. Here are the contents of that file.

" Line 34: print(‘Re-running as sudo (you may be required to enter sudo’‘s password)’)
Line 35: os.execvp(‘sudo’, [‘sudo’, ‘python’] + sys.argv) # final version
Line 39: cmd = “sudo mkdir -p ‘%s’” % (os.path.dirname(destfile))
"
I learned a few things today that I’m going keep in my back pocket for another time. It’s good to know BigFix has guys like you to help out with issues like these.

Thanks again, I truly appreciate the assist!

3 Likes

@JoeG Do you mind sharing your .BES file so I could use your script as well? :slight_smile: Thank you