Knowledge Base

Preserving for the future: Shell scripts, AoC, and more

Ansible use ssh tunnel for http proxy

Overview

If you need to use a web proxy on an ansible node to get to the Internet, you can use the ansible role I hacked together. I had a need for using an ad-hoc ssh tunnel to a proxy server. So your node will need an ssh key for automatic authentication to the proxy server over ssh. The role just executes a "ssh -N -p 22 username@proxy.example.com -L 1234/localhost/1234" and sets up the environment hash which includes http_proxy and https_proxy. Check out the role at my gitlab page.

Code walkthrough

My roles always have incredibly basic main.ymls because I always use a subdirectory architecture. --- - hosts: all tasks: - include: tasks/main.yml handlers: - handlers/main.yml vars_files: - vars/main.yml Now the tasks/main.yml file is where half of the work occurs. --- # File: /etc/ansible/roles/use-proxy/tasks/main.yml - name: clear any ssh tunnel shell: ps -ef | grep -iE -- "ss[h].*{{local_proxy_port}}" | awk '{print $2}' | xargs kill -9 ignore_errors: yes - name: start ssh tunnel shell: nohup ssh -N -p {{proxy_server_ssh_port}} {{proxy_server}} -L {{local_proxy_port}}/localhost/{{proxy_port}} & notify: stop ssh tunnel It's pretty clear what each task is doing. The start ssh tunnel opens up an ssh connection. If it is successful, it notifies the stop ssh tunnel handler which will execute at the end of the play. - name: stop ssh tunnel shell: ps -ef | grep -iE -- "ss[h].*{{local_proxy_port}}" | awk '{print $2}' | xargs kill -9 The handler searches for and kills the ssh connection that is using the specified port. The vars/main.yml file is important because you must customize it to your environment. --- proxy_port: 3128 local_proxy_port: "{{proxy_port}}" proxy_server: tunnel@demo.example.com proxy_server_ssh_port: 22 proxy_env: http_proxy: "http://localhost:{{local_proxy_port}}" https_proxy: "http://localhost:{{local_proxy_port}}" How you use this role in a playbook is at the beginning of the list of roles. You also need to define the environment as seen below. --- - name: Playbook that uses an ssh tunnel for http_proxy hosts: test remote_user: root environment: "{{ proxy_env | default(omit) }}" roles: - { role: use-proxy, when: usehttpproxy is defined and usehttpproxy|bool == true } - example You can run this playbook with the use-proxy role and environment as is against any hosts that need the http proxy. To minimize traffic back and forth, just comment out the use-proxy role, and run the play against the regular hosts.

References

Weblinks

  1. https://ansiblemaster.wordpress.com/2016/04/29/run-ansible-tasks-to-a-remote-server-using-a-ssh-tunnel/
  2. https://www.engadget.com/2006/03/21/how-to-ssh-tunnels-for-secure-network-access/

Comments