Ansible for managed nodes behind firewalls



Hi from freezing Toronto to sunny LA ! 😎

Read your great intro article:

1. So how about using Ansible from an Ubuntu VPS to manage Linux boxes that are behind firewalls, i.e., only have private (non addressable) IPs?

2. I suppose you will need to create reverse SSH tunnels first between these boxes ( NATed servers) and Ansible VPS?

3. Can we just generate keys from the VPS and then simply copy these keys to all such NATed servers so that upon boot these NATed servers can establish persistent tunnels to the Ansible VPS?

Any links or code snippets to do this key gen/copying? (Of course the VPS domain IP will be used by NATed servers to establish the tunnels.)

I am assuming that all the NATed servers get the same keys generated by the Ansible VPS?


solved 0
siliconhippy 10 months 4 Answers 601 views

Answers ( 4 )

  1. Hi siliconhippy,
    what you’re looking for is called reverse SSH tunneling and you’re correct.

    The procedures to do reverse SSH tunneling automatically when your computer boots are demonstrated here.
    Take a look at the answer of Eugen Konkov.

    The public key of the machines behind NAT must be stored on the server (VPS). You can generate ssh keys on these machines with the ssh-keygen command and use the ssh-copy-id command to copy the keys to the server (VPS).

    I hope this helps.

    Shahriar Shovon

  2. Hello again,

    You may also take a look at this YouTube video to learn how to generate SSH keys and copy SSH public keys to the server/VPS.

    Thank you.



    Shahriar Shovon

    Best answer
  3. Shahriar,


    1. Your Youtube is the best I have seen on the topic !

    The $ssh-add command I learned the first time as a non coder hobbyist having done tons of online searches.

    One thing: you should show how to log into the remote (NAT-ed server) without the IP since the whole idea of reverse SSH is to access behind firewall /noIP devices.

    Client-admin >> middleman machine public IP>>> internet >>> firewall(s) >> NATed (remote) server, no public IP

    Also nobody explains that identity simply means the private key as opposed to the key ! And that the middleman machine (which handles passing of SSH connection from client-admin to target remote servers aka NATed servers) keeps both private keys- any device with the public key can now communicate with this middleman to establish a connection, with or without a password.

    2. How could one write a simple bash script which could be installed on multiple RPis, for example, with some variable(s) (eg port numbers on the middleman server to identify each RPi box at login time) that could be input at RPi user boot up?

    Of course the client-admin can copy the public key generated on middleman to all RPi boxes at the time of installing such a script and then giving away these boxes to different home users who then should be able to login at first boot time to do minimal configuration to make the SSH tunnel work automatically via autossh (persistence) at next boot. The client admin should then be able to log into the middleman to access all these RPi boxes at home via SSH to do small upgrades etc.

    The idea is to make things as simple as possible for the non tech user. Perhaps the best way to identify a given RPi box among multiple SSH tunnels without passwords is to assign a unique port on the middleman machine to each RPi currently logged in?

    3. Now re: the real Ansible question 😎😎

    Someone suggested ansible-pull in which case the NATed server aka managed node (s) will establish outbound connection to Ansible control node since the managed node itself doesn’t have a public IP.

    What are your thoughts? Will establishing a reverse SSH tunnel(s) first help with Ansible setup?


  4. You’re welcome.

    1. To access the remote NAT-ed servers without IP address, you can use a method called reverse proxy.
    You have to map the DNS names to your server IP and port.
    You may take a look at this videoΒ to learn how to configure HTTP reverse proxy. This works well if you’re hosting websites on your NATed machines.

    2. You’re correct. Just write a bash script and make it start on system boot. Again, you can do it by using crontab.
    Write the script so that it accepts the port number as the argument. Then, all you have to do is to change the argument in your crontab and the port will be different for each Raspberry Pi devices.
    You can also use the init script method to run a shell script at startup. Check the comment of syb0rg on this page.

    3. If you can access the NATed machines from the server, then I think you can add them to your ansible control node.
    It should work, I think. Give it a go and see what happens.

    Shahriar Shovon

Leave an answer