setup-python icon indicating copy to clipboard operation
setup-python copied to clipboard

Advise users of self-hosted Windows runners how to resolve: "unable to get local issuer certificate" error

Open cacti77 opened this issue 1 year ago • 14 comments

I'm using a self-hosted Windows 10 runner with GHES 3.6.5. The actions/setup-python@v4 step in my workflow fails with: unable to get local issuer certificate. I presume I need to get a certificate from the server somewhere, install it in Windows and tell my self-hosted runner where to find it. But the instructions at https://github.com/actions/setup-python/blob/main/docs/advanced-usage.md#using-setup-python-with-a-self-hosted-runner do not say anything about certificates.

Description: Add a section to the instructions for the setup-python action (possibly at https://github.com/actions/setup-python/blob/main/docs/advanced-usage.md#using-setup-python-with-a-self-hosted-runner) to explain how to resolve the unable to get local issuer certificate error. E.g., Please explain:

  1. Where to get the certificate(s) from.
  2. Where/how to install the certificate(s) in Windows.
  3. How to configure a self-hosted runner so that it can find the certificates.

Justification: Get the setup python task to work.

Are you willing to submit a PR? No, sorry.

cacti77 avatar Jun 01 '23 09:06 cacti77

Example debug output from a failed run on my self-hosted Windows 10 runner:

Run actions/setup-python@v4
  with:
    python-version: 3.7
    token: ***
##[debug]Python is expected to be installed into RUNNER_TOOL_CACHE==C:\actions-runner\_work\_tool
##[debug]Semantic version spec of 3.7 is 3.7
##[debug]isExplicit: 
##[debug]explicit? false
##[debug]evaluating 0 versions
##[debug]match not found
Version 3.7 was not found in the local cache
##[debug]check 3.12.0-beta.1 satisfies 3.7
<blah, blah>
##[debug]matched 3.7.9
Version 3.7 is available for downloading
Download from "https://github.com/actions/python-versions/releases/download/3.7.9-109486/python-3.7.9-win32-x64.zip"
##[debug]Downloading https://github.com/actions/python-versions/releases/download/3.7.9-109486/python-3.7.9-win32-x64.zip
##[debug]Destination C:\actions-runner\_work\_temp\3413da6d-e5c7-4e55-ac76-8748f0e7539d
unable to get local issuer certificate
Waiting 17 seconds before trying again
unable to get local issuer certificate
Waiting 16 seconds before trying again
Error: unable to get local issuer certificate
##[debug]Node Action run completed with exit code 1
##[debug]Finishing: Set up Python 3.7

cacti77 avatar Jun 01 '23 09:06 cacti77

In case it helps, here's the relevant section of my workflow:

jobs:
  build:

    runs-on: self-hosted
    strategy:
      matrix:
        python-version: ["3.7", "3.8"]

    steps:
      - uses: actions/checkout@v3

      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v4
        with:
          python-version: ${{ matrix.python-version }}

It's a race between the Python 3.7 and 3.8 jobs as to which fails first, but whichever fails first fails with the unable to get local issuer certificate error, and then the other job is cancelled.

cacti77 avatar Jun 01 '23 10:06 cacti77

Hello, @cacti77 ! Thank you for creating an issue and providing additional context, your input is highly appreciated. We will take a look at it and see what can be done :)

dusan-trickovic avatar Jun 01 '23 10:06 dusan-trickovic

Thanks @dusan-trickovic! BTW I also came across more help docs here, but I don't even know if our GHES server is using a self-signed certificate, much less where to get it and put it in Windows. (Unfortunately I've not had any help from our corporate IT team yet!)

cacti77 avatar Jun 01 '23 12:06 cacti77

@cacti77 thank you for the follow-up! In case you get any more information from the IT team that you believe would be helpful for this issue, feel free to add them in the replies as well :)

dusan-trickovic avatar Jun 01 '23 12:06 dusan-trickovic

I was able to get a bit further today by doing this:

  1. I downloaded a corporate .crt certifcate file (possibly a self-signed certificate?) someone in my company pointed me at.
  2. Saved it to a local folder on my Windows laptop (C:\Certs)
  3. Created a .env file in C:\actions-runner
  4. Added this entry to that file: NODE_EXTRA_CA_CERTS=C:\Certs\name_of_corporate_cert.crt
  5. Restarted the GitHub Actions Runner service under Windows services (as an administrator).

When I ran my workflow again I no longer got the "unable to get local issuer certificate" error. It looks like it now downloads the Python archive successfully but fails to extract it from the archive because my machine doesn't grant the script sufficient permissions to execute:

##[debug]matched 3.7.9
Version 3.7 is available for downloading
Download from "https://github.com/actions/python-versions/releases/download/3.7.9-109486/python-3.7.9-win32-x64.zip"
##[debug]Downloading https://github.com/actions/python-versions/releases/download/3.7.9-109486/python-3.7.9-win32-x64.zip
##[debug]Destination C:\actions-runner\_work\_temp\c7971ddd-f935-4416-bb96-fe2fc5c49615
##[debug]download complete
Extract downloaded archive
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -NoLogo -Sta -NoProfile -NonInteractive -ExecutionPolicy Unrestricted -Command "$ErrorActionPreference = 'Stop' ; try { Add-Type -AssemblyName System.IO.Compression.FileSystem } catch { } ; [System.IO.Compression.ZipFile]::ExtractToDirectory('C:\actions-runner\_work\_temp\c7971ddd-f935-4416-bb96-fe2fc5c49615', 'C:\actions-runner\_work\_temp\c5183b43-70e4-41d1-971c-fe5066931972')"
Execute installation script
Error: ./setup.ps1 : File C:\actions-runner\_work\_temp\c5183b43-70e4-41d1-971c-fe5066931972\setup.ps1 cannot be loaded
Error: because running scripts is disabled on this system. For more information, see about_Execution_Policies at
https:/go.microsoft.com/fwlink/?LinkID=135170.
At line:1 char:1
+ ./setup.ps1
Error: + ~~~~~~~~~~~
Error: + CategoryInfo : SecurityError: (:) [], PSSecurityException
+ FullyQualifiedErrorId : UnauthorizedAccess
Error: The process 'C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe' failed with exit code 1
##[debug]Node Action run completed with exit code 1
##[debug]Finishing: Set up Python 3.7

cacti77 avatar Jun 02 '23 09:06 cacti77

Note when I registered the runner on my laptop I did run PowerShell with admin permissions. And I chose these options during the registration process:

Would you like to run the runner as service? (Y/N) [press Enter for N] y
User account to use for the service [press Enter for NT AUTHORITY\NETWORK SERVICE]
Granting file permissions to 'NT AUTHORITY\NETWORK SERVICE'.

In the docs here it does say:

If your runner is configured as a service, make sure the account that is running the service has the appropriate write permissions so that Python can get installed. The default NT AUTHORITY\NETWORK SERVICE should be sufficient.

...but it looks like that's maybe not sufficient in my case?

cacti77 avatar Jun 02 '23 09:06 cacti77

After googling https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_execution_policies?view=powershell-7.3 and other sites I ran this in a PowerShell terminal with admin privileges to try to fix the "running scripts is disabled on this system" error:

> Set-ExecutionPolicy RemoteSigned

Execution Policy Change
The execution policy helps protect you from scripts that you do not trust. Changing the execution policy might expose
you to the security risks described in the about_Execution_Policies help topic at
https:/go.microsoft.com/fwlink/?LinkID=135170. Do you want to change the execution policy?
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help (default is "N"): yes

After restarting the runner service and retrying the workflow I got this new error:

##[debug]matched 3.7.9
Version 3.7 is available for downloading
Download from "https://github.com/actions/python-versions/releases/download/3.7.9-109486/python-3.7.9-win32-x64.zip"
##[debug]Downloading https://github.com/actions/python-versions/releases/download/3.7.9-109486/python-3.7.9-win32-x64.zip
##[debug]Destination C:\actions-runner\_work\_temp\9457974f-b686-4d6a-8b4f-b403cb70984c
##[debug]download complete
Extract downloaded archive
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -NoLogo -Sta -NoProfile -NonInteractive -ExecutionPolicy Unrestricted -Command "$ErrorActionPreference = 'Stop' ; try { Add-Type -AssemblyName System.IO.Compression.FileSystem } catch { } ; [System.IO.Compression.ZipFile]::ExtractToDirectory('C:\actions-runner\_work\_temp\9457974f-b686-4d6a-8b4f-b403cb70984c', 'C:\actions-runner\_work\_temp\61c4f77c-1[170](https://github.build.ge.com/ProDAPS/github-actions-sandbox/runs/364134?check_suite_focus=true#step:3:171)-49aa-b824-91cbd6a28504')"
Execute installation script
Check if Python hostedtoolcache folder exist...
Create Python toolcache folder
Check if current Python version is installed...
No Python3.7.* found
Remove registry entries for Python 3.7(x64)...
Create Python 3.7.9 folder in C:\actions-runner\_work\_tool\Python
Copy Python binaries to C:\actions-runner\_work\_tool\Python\3.7.9\x64
Install Python 3.7.9 in C:\actions-runner\_work\_tool\Python...
Error: Error happened during Python installation
Error: At C:\actions-runner\_work\_temp\61c4f77c-1170-49aa-b824-91cbd6a28504\setup.ps1:125 char:5
+     Throw "Error happened during Python installation"
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : OperationStopped: (Error happened ...on installation:String) [], RuntimeException
    + FullyQualifiedErrorId : Error happened during Python installation
Error: The process 'C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe' failed with exit code 1
##[debug]Node Action run completed with exit code 1
##[debug]Finishing: Set up Python 3.7

BTW There was now a copy of python-3.7.9-amd64.exe in C:\actions-runner_work_tool\Python\3.7.9\x64. However it's not clear what the installation error was.

cacti77 avatar Jun 02 '23 12:06 cacti77

Without making any changes, if I run my workflow again it seems Python 3.8 is 'winning the race' and it fails with more info than the Python 3.7 job above...

##[debug]matched 3.8.10
Version 3.8 is available for downloading
Download from "https://github.com/actions/python-versions/releases/download/3.8.10-117959/python-3.8.10-win32-x64.zip"
##[debug]Downloading https://github.com/actions/python-versions/releases/download/3.8.10-117959/python-3.8.10-win32-x64.zip
##[debug]Destination C:\actions-runner\_work\_temp\5745c6f4-8f0c-45c7-a557-f48ad1e42fd8
##[debug]download complete
Extract downloaded archive
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -NoLogo -Sta -NoProfile -NonInteractive -ExecutionPolicy Unrestricted -Command "$ErrorActionPreference = 'Stop' ; try { Add-Type -AssemblyName System.IO.Compression.FileSystem } catch { } ; [System.IO.Compression.ZipFile]::ExtractToDirectory('C:\actions-runner\_work\_temp\5745c6f4-8f0c-45c7-a557-f48ad1e42fd8', 'C:\actions-runner\_work\_temp\d75624dc-d367-4987-9953-0d2e1b9b18ba')"
Execute installation script
Check if Python hostedtoolcache folder exist...
Check if current Python version is installed...
Python3.8 (x64) was found in C:\actions-runner\_work\_tool\Python...
Deleting C:\actions-runner\_work\_tool\Python\3.8.10\x64...
Error: Remove-Item : Cannot find path 'C:\actions-runner\_work\_tool\Python\3.8.10\x64.complete' because it does not exist.
Error: At C:\actions-runner\_work\_temp\d75624dc-d367-4987-9953-0d2e1b9b18ba\setup.ps1:104 char:13
+             Remove-Item -Path "$($InstalledVersion.Parent.FullName)/$ ...
+             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (C:\actions-runn...10\x64.complete:String) [Remove-Item], ItemNotFoundEx 
   ception
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.RemoveItemCommand
Remove registry entries for Python 3.8(x64)...
Error: Remove-Item : Requested registry access is not allowed.
Error: At C:\actions-runner\_work\_temp\d75624dc-d367-4987-9953-0d2e1b9b18ba\setup.ps1:56 char:13
+             Remove-Item Registry::$_ -Recurse -Force -Verbose
+             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : PermissionDenied: (HKEY_LOCAL_MACH...rsion\Uninstall:String) [Remove-Item], SecurityExce 
   ption
    + FullyQualifiedErrorId : System.Security.SecurityException,Microsoft.PowerShell.Commands.RemoveItemCommand
Create Python 3.8.10 folder in C:\actions-runner\_work\_tool\Python
Copy Python binaries to C:\actions-runner\_work\_tool\Python\3.8.10\x64
Install Python 3.8.10 in C:\actions-runner\_work\_tool\Python...
Error: Error happened during Python installation
At C:\actions-runner\_work\_temp\d75624dc-d367-4987-9953-0d2e1b9b18ba\setup.ps1:125 char:5
Error: +     Throw "Error happened during Python installation"
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : OperationStopped: (Error happened ...on installation:String) [], RuntimeException
    + FullyQualifiedErrorId : Error happened during Python installation
Error: The process 'C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe' failed with exit code 1
##[debug]Node Action run completed with exit code 1
##[debug]Finishing: Set up Python 3.8

It looks like the shell script is being denied access to the Windows registry during the installation process for Python 3.8.

cacti77 avatar Jun 02 '23 13:06 cacti77

In the docs it says:

MSI installers are used when setting up Python on Windows. A word of caution as MSI installers update registry settings. The 3.8 MSI installer for Windows will not let you install another 3.8 version of Python. If setup-python fails for a 3.8 version of Python, make sure any previously installed versions are removed by going to "Apps & Features" in the Settings app.

Python 3.11 rather than 3.8 is installed on my Windows system. Does the second point above only apply to Python 3.8, or to all versions of Python? I'd rather not have to uninstall Python though, as it's used by other things.

cacti77 avatar Jun 02 '23 13:06 cacti77

I've now decided to abandon my attempts to get the self-hosted runner to run GitHub Actions on my Windows 10 laptop because:

  1. I don't want any pre-existing versions of Python to be uninstalled or interfered with. I need them to create Python virtual environments for example.
  2. I strongly suspect my corporate CyberSecurity team would not approve the running of commands like Set-ExecutionPolicy RemoteSigned on user's general-purpose machines except in very tightly prescribed circumstances.

If the GitHub Actions team can find ways of supporting self-hosted Windows runners in a more isolated sandbox, security-wise, and without interfering with existing Python installations, I would reconsider. Otherwise I'll just have to resort to using GitHub-hosted Windows runners instead. (Setting up a local Windows VM would be too onerous.)

@dusan-trickovic - I leave it up to you whether to close this ticket; e.g., to add further info in the GitHub docs about self-hosted Windows runners.

cacti77 avatar Jun 05 '23 09:06 cacti77

Hello, @cacti77 ! Thank you for all your updates and additional context. As mentioned before, I will discuss with the team about what can be done and I will get back to you with the verdict / a potential solution as soon as we reach it. In the meantime, whichever the case, you can certainly use hosted runners to do the job that you need.

Thank you again for your patience and cooperation :)

dusan-trickovic avatar Jun 05 '23 12:06 dusan-trickovic

Thanks @dusan-trickovic! Ideally I would have found a way to work through all the problems to get setup-python and other actions working successfully on my laptop as hosted runners aren't offered by corporate IT (yet) unfortunately. So effectively GitHub Actions is out of reach for the time being, unless you go to the trouble of installing a Windows/Linux VM on your laptop; something I was hoping to avoid.

cacti77 avatar Jun 06 '23 13:06 cacti77

Any update on this issue? Would love to use this plugin for self hosted Windows runners, but we cannot enable admin access for security reasons.

It's possible that this could be addressed by adding noprofile -executionpolicy bypass arguments to https://github.com/actions/setup-python/blob/b64ffcaf5b410884ad320a9cfac8866006a109aa/src/install-python.ts#L65

jnguyen75 avatar Nov 17 '23 18:11 jnguyen75