Quickly bounce nic over ssh without losing ssh session

The story

If you make changes to a network card settings and need to restart it to take effect, you might find this useful.
Ssh is resilient enough to usually keep your session if you take the card down and up fast enough. Obviously you want to make sure the change you make will not prevent the card from being enabled correctly. I was making changes to my dns settings for the card, and I wanted them to take effect immediately.

The snippet

echo "ifdown eth0; sleep 2; ifup eth0;" > ~/foo.sh; chmod u+x ~/foo.sh; ~/foo.sh

Ssh into NATted VM via AutoSSH


Suppose you have a virtual machine running on a natted network connection. It can get out just fine to the Internet.
Now, with the network address translation (NAT), you can’t send traffic in to that network. So you can’t just ssh username@vm.example.com and get in. You are going to need something a little fancier to accomplish that. This document explains how to do that.

Sample environment

For this document, these example values will be used. The vm is centos.vm.example.com and the system on the main network is desktop.example.com. The desktop will have port 5000 be forwarded to the vm’s port 22, which is the standard ssh port.

Set up autossh

You need ssh connectivity between the vm and the physical host. Make sure you have an automatic log in from the vm to the physical host. A good way to do that is by having an ssh key. If you need to generate one on the vm and copy it to the physical machine, use these commands.
# on vm
ssh-keygen # follow the prompts

The next step is to copy it to the physical machine.
# still on vm
ssh-copy-id username@desktop.example.com

Check that you can log in automatically with
ssh username@desktop.example.com
Once that is done, install autossh and make a systemd service file and enable and start it.
yum -y install autossh
touch "${tf}"; chmod 0644 "${tf}"
cat <<EOF > "${tf}"
Description=AutoSSH tunnel service for ssh
ExecStart=/usr/bin/autossh -M 0 -o "ServerAliveInterval 30" -o "ServerAliveCountMax 3" -N -R 5000:localhost:22 username@desktop.example.com -p 22
systemctl daemon-reload
systemctl enable autossh-ssh.service
systemctl start autossh-ssh.service

Using the reverse tunnel

To connect to centos.vm.example.com, you just need to do this:
ssh centosusername@localhost -p 5000

Bonus: nickname the connection and copy ssh key

What I did was set up my ~/.ssh/config file with the following snippet, so I can just use the nickname “centosvm.”

# in ~/.ssh/config, mode 0600
Host centosvm centosvm.vm.example.com
 User centosuser
 Hostname localhost
 Port 5000

I then copied my ssh id to that, so I could connect without a password.
ssh-copy-id centosvm


  1. https://www.everythingcli.org/ssh-tunnelling-for-fun-and-profit-autossh/
  2. http://www.harding.motd.ca/autossh/index.html
  3. http://surniaulula.com/2012/12/10/autossh-startup-script-for-multiple-tunnels/

Ansible use ssh tunnel for http proxy


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 github page.

Code walkthrough

My roles always have incredibly basic main.ymls because I always use a subdirectory architecture.
- hosts: all
- include: tasks/main.yml
- handlers/main.yml
- 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
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) }}"
- { 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.



  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/

Ssh use password this time


If you normally use passwordless authentication for your ssh sessions, you know how helpful it is. It saves you from having to type your password in all the time. You might have ssh keys set up (ssh-keygen) or kerberos.

In either case, you found this post because you want to use ssh with a password this time. You need to force ssh to use the password, just this once, without having to make all sorts of complicated requirements.


In either case, you found this post because you want to use ssh with a password this time. You need to force the password. Here’s how to do that:

function sshp { ssh -o PreferredAuthentications=password,keyboard-interactive -o PubkeyAuthentication=no -o GSSAPIAuthentication=no "$@"; }

The above snippet comes from my latest and greatest bgscripts.bashrc in my bgscripts package.

What the function does is execute ssh with a few extra options, that are very straightforward. It specifically lists the preferred methods for authentication, while disabling public key (which is what most people use) and kerberos auth (GSSAPI).