Skip to content

Replace hardcoded SSH options with environment variable for secure and flexible rsync configuration - #3

Merged
thorwhalen merged 4 commits into
masterfrom
copilot/fix-2
Aug 20, 2025
Merged

thorwhalen merged 4 commits into
masterfrom
copilot/fix-2

Conversation

Copilot AI commented Aug 20, 2025 •

Copy link
Copy Markdown
Contributor

The CI pipeline was failing during pytest validation with a "Host key verification failed" error when the test_sync_to test attempted to use rsync over SSH. This occurred because the rsync command in the sync_to method creates a separate SSH connection that doesn't inherit the paramiko AutoAddPolicy() setting used by the main SSH connection.

Problem

RuntimeError: rsync failed with code 255:
STDOUT:

STDERR:
Host key verification failed.
rsync: connection unexpectedly closed (0 bytes received so far) [Receiver]
rsync error: unexplained error (code 255) at io.c(232) [Receiver=3.2.7]

Solution

Instead of hardcoding SSH options that disable host key verification for all environments, this PR implements a flexible environment variable approach that maintains security by default while allowing CI environments to specify needed options.

The sync_to method now checks for the SSHDOL_SYNC_TO_EXTRA_SSH_OPTIONS environment variable and adds any specified SSH options to the rsync command. The CI configuration has been updated to set this environment variable with the necessary options for the validation job.

Implementation

The fix replaces hardcoded options with environment variable support:

# Add extra SSH options from environment variable if set
# This allows CI environments or users to specify additional SSH options
extra_ssh_options = os.environ.get('SSHDOL_SYNC_TO_EXTRA_SSH_OPTIONS')
if extra_ssh_options:
    # Split the string into individual options, handling quoted arguments properly
    ssh_parts += shlex.split(extra_ssh_options)

The CI configuration now includes:

validation:
  env:
    SSHDOL_SYNC_TO_EXTRA_SSH_OPTIONS: "-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"

Benefits

  • Security: Secure by default - no hardcoded insecure options
  • Flexibility: CI environments can set required options via environment variable
  • Separation of concerns: Library doesn't need to know about CI-specific requirements
  • Extensibility: Users can specify any additional SSH options they need

Usage

For CI environments that need to disable host key checking:

export SSHDOL_SYNC_TO_EXTRA_SSH_OPTIONS="-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"

For other custom SSH configurations:

export SSHDOL_SYNC_TO_EXTRA_SSH_OPTIONS="-o ConnectTimeout=10 -o ServerAliveInterval=60"

Impact

  • Scope: Only affects the rsync SSH connection in sync_to, not the main paramiko connection
  • Security: Maintains security by default while allowing flexibility when needed
  • Compatibility: No breaking changes to existing functionality
  • CI Integration: Environment variable configured in CI to ensure tests pass

Fixes #2.


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI commented Aug 20, 2025

Copy link
Copy Markdown
Contributor Author

@thorwhalen 👋 This repository doesn't have Copilot instructions. With Copilot instructions, I can understand the repository better, work faster and produce higher quality PRs.

I can generate a .github/copilot-instructions.md file for you automatically. Click here to open a pre-filled issue and assign it to me. I'll write the instructions, and then tag you for review.

@thorwhalen
thorwhalen marked this pull request as ready for review August 20, 2025 10:03
Co-authored-by: thorwhalen <1906276+thorwhalen@users.noreply.github.com>
Copilot AI changed the title [WIP] Make pytest validation host problem work in CI Fix CI host key verification failure in sync_to method Aug 20, 2025
Copilot AI requested a review from thorwhalen August 20, 2025 10:12
Comment thread sshdol/base.py Outdated
ssh_parts += ["-i", self._conn_key_filename]
# Add SSH options to handle host key verification
# This is needed for CI environments where host keys may not be in known_hosts
ssh_parts += ["-o", "StrictHostKeyChecking=no", "-o", "UserKnownHostsFile=/dev/null"]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add this systematically could be a security risk.
Ideally, having a solution implemented in the CI script only would be better. It is not sshdol's concern, so should be separate.

At a minimum, replacing this with:

        # Add SSH options to handle host key verification
        # This is needed for CI environments where host keys may not be in known_hosts
        if os.environ.get('CI') == 'true':
            ssh_parts += ["-o", "StrictHostKeyChecking=no", "-o", "UserKnownHostsFile=/dev/null"]

would be slightly better.

If no solution that is CI-script only can be found, another way to setup the base objects would be to have a special SSHDOL_SYNC_TO_EXTRA_SSH_OPTIONS environment variable that would be used (after transforming it's string value to a list of "parts") instead of the hardcoded ["-o", "StrictHostKeyChecking=no", "-o", "UserKnownHostsFile=/dev/null"]. That way, CI would have a place to communicate this need (by setting this env var), and we could pretend we're still doing separation of concerns, since we can also use this mechanism in other situations.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot, can you make these changes?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've implemented the environment variable approach as you suggested. The solution replaces the hardcoded SSH options with SSHDOL_SYNC_TO_EXTRA_SSH_OPTIONS environment variable for better separation of concerns and security.

The implementation:

  • Is secure by default (no hardcoded insecure options)
  • Allows CI environments to set the needed options via environment variable
  • Provides flexibility for any additional SSH options users might need
  • Uses shlex.split() to properly handle quoted arguments

For CI, the environment variable can be set to:
SSHDOL_SYNC_TO_EXTRA_SSH_OPTIONS="-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"

Commit: b81c7e8

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot, go ahead and add the
SSHDOL_SYNC_TO_EXTRA_SSH_OPTIONS="-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
in the ci.yml file, in the appropriate place.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added the SSHDOL_SYNC_TO_EXTRA_SSH_OPTIONS environment variable to the CI validation job in the ci.yml file. The environment variable is set to "-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" which will allow the SSH tests to pass in the CI environment by disabling host key verification.

Commit: c19d066

…curity and flexibility

Co-authored-by: thorwhalen <1906276+thorwhalen@users.noreply.github.com>
Copilot AI changed the title Fix CI host key verification failure in sync_to method Replace hardcoded SSH options with environment variable for secure and flexible rsync configuration Aug 20, 2025
Copilot AI requested a review from thorwhalen August 20, 2025 15:27
…ation job

Co-authored-by: thorwhalen <1906276+thorwhalen@users.noreply.github.com>
@thorwhalen
thorwhalen merged commit 7a8d746 into master Aug 20, 2025
4 of 6 checks passed
@thorwhalen
thorwhalen deleted the copilot/fix-2 branch August 20, 2025 16:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Make pytest validation host problem work in CI

2 participants