Giter Club home page Giter Club logo

circleci-dmz-orb's Introduction

circleci-dmz-orb

Allows CircleCI builds to access private network services over a intermediate jump host using SSH port forwarding.

Image showing traffic flow from CircleCI, through Jump Host to target server on private network

Note: port 3306 represents the local port, in this example for a DB connection, but can be any available port.

Examples

Full usage examples can be found under the examples key in the orb's source

version: 2.1

orbs:
  dmz: eddiewebb/dmz@volatile

workflows:
  test_all:
    jobs:
      - build
      - build_key_path
      - build_key_value
      - build_key_variable

jobs:
  build: # this job uses ssh-keyscan to dynamically trust public key of bastion host
    docker:
      - image: circleci/node:10
    steps:
      - checkout
      - dmz/open_tunnel:
          local_port: "9001"
          target_host: "104.154.89.105"
          target_port: "80"
          bastion_user: ubuntu
          bastion_host: ec2-18-191-19-150.us-east-2.compute.amazonaws.com 
      # and simply confirm that accessing local port resolves the target (in this case an HTTP server)
      - run: curl localhost:9001
  
  build_key_path: #this job uses a *public* key file within the repo to be explicitly trusted
    docker:
      - image: circleci/node:10
    steps:
      - checkout
      - dmz/open_tunnel:
          local_port: "9001"
          target_host: "104.154.89.105"
          target_port: "80"
          bastion_user: ubuntu
          bastion_host: ec2-18-191-19-150.us-east-2.compute.amazonaws.com
          bastion_public_key: bastion.pub
      # and simply confirm that accessing local port resolves the target (in this case an HTTP server)
      - run: curl localhost:9001
  
  build_key_value: # this job uses a public key string value to trust bastion explicitly
    docker:
      - image: circleci/node:10
    steps:
      - checkout
      - dmz/open_tunnel:
          local_port: "9001"
          target_host: "104.154.89.105"
          target_port: "80"
          bastion_user: ubuntu
          bastion_host: ec2-18-191-19-150.us-east-2.compute.amazonaws.com
          bastion_public_key: 'ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEQonlo27Q6jHMBHm7FczYsVbSDMMejUCZmSTcloE2DrDNfL/fzbzNlP5Xk8MxqRfjrPEsrlvRlyNYSxDLVA+0g='
      # and simply confirm that accessing local port resolves the target (in this case an HTTP server)
      - run: curl localhost:9001
  
  build_key_variable: # this job uses a public key string value to trust bastion explicitly
    docker:
      - image: circleci/node:10
    steps:
      - checkout
      - dmz/open_tunnel:
          local_port: "9001"
          target_host: "104.154.89.105"
          target_port: "80"
          bastion_user: ubuntu
          bastion_host: ec2-18-191-19-150.us-east-2.compute.amazonaws.com
          bastion_public_key: ${BASTION_PUBLIC_KEY}
      # and simply confirm that accessing local port resolves the target (in this case an HTTP server)
      - run: curl localhost:9001

circleci-dmz-orb's People

Contributors

eddiewebb avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

circleci-dmz-orb's Issues

ssh -f seems to create race condition

Hi Eddie!

One of my teammates has picked your orb to run integration testing against an internal DB instance, using tunneling through a bastion host. Thanks for publishing BTW, it's pretty useful to trim down the mess that our 500-line .circleci/config.yml is!

However, there's a recurring issue where the next step after dmz/open_tunnel fails with Connection Refused to the tunneled port. Most of the time, of course, it works fine โ€” and my usual interpretation of such symptom is that there is connection-opening race present.

Meaning that ssh -f (I guess!) will listen the local socket very soon, but still after forking; creating a small window of time when the ssh -f has returned control to bash but the socket isn't listened yet. Occasionally, the OS scheduler will starve ssh and resume the bash script instead (which naturally assumes that the tunnel port is already open) โ€” and hit ECONNREFUSED.

I see that in the usage examples, you always add a curl localhost to maybe keep track of the problem. It's also easy to work around such issues by adding explicit polling of the port (effectively synchronizing away the race between ssh and bash).

I'd appreciate if you have any comment on this. Maybe something as simple as adding:

while test 7 -eq $(curl -s localhost:1234; echo $?); do sleep 0.1; done

after the ssh -Nf call in the orb source. What do you think?

Tunnel creation is not stable without ExitOnForwardFailure and extra sleep

first of all I hope https://circleci.com/developer/orbs/orb/eddiewebb/dmz#orb-source is this repo.

We have setup of this orb and it worked most of time stable.
But there are bunch of cases when tunnel creation is finished successfully but our next step is failing connect nu tunnel.
Unrelated to this orb log:

2020/07/13 23:30:41 Waiting for: tcp://localhost:****
2020/07/13 23:30:41 Problem with dial: dial tcp 127.0.0.1:****: connect: connection refused. Sleeping 1s
2020/07/13 23:30:42 Problem with dial: dial tcp 127.0.0.1:****: connect: connection refused. Sleeping 1s
2020/07/13 23:30:43 

restart of the whole CircleCI job, helps.
After bunch of experiments we found a solution by patching of orb with 1 extra argument for ssh and one extra command to let tunnel be created in our case sleep

example of modification:

      - run:
          # MODIFICATION: -o ExitOnForwardFailure=yes
          # MODIFICATION: sleep 5
          command: |
            ssh -o ExitOnForwardFailure=yes -4 -L <<parameters.local_port>>:<<parameters.target_host>>:<<parameters.target_port>> -Nf <<parameters.bastion_user>>@<<parameters.bastion_host>>
            sleep 5
          name: Open Local Port Forwarding on <<parameters.local_port>> to <<parameters.target_host>>:<<parameters.target_port>>
            via <<parameters.bastion_host>>

After more then 6 month of no problems I think we can discuss how to contribute it original repo.


I clearly understand that "sleep 5" is not ideal solution to keep, and what I can suggest is to make allow user to execute any command he wants eval << parameters.post_ssh_command>> to let use make any verification of tunnel or simply sleep X up to his amount and nuances of network.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.