--- # All nodes may use the ssh proxy user to connect to any other node # to use point-to-point tunnelling. # remove existing interfaces in case of an error so we don't run out of ip addresses - name: Remove existing tunnel interfaces include: ssh-down.yml - name: Add the proxy user user: name: "{{ proxy_ssh_user }}" shell: /bin/false - name: Allow point-to-point tunnelling for the ssh proxy user blockinfile: block: | # sshproxy start Match User {{ proxy_ssh_user }} AllowTcpForwarding yes PermitTunnel point-to-point ForceCommand /bin/false # sshproxy end dest: "/etc/ssh/sshd_config" validate: "/usr/sbin/sshd -T -f %s" notify: reload sshd - meta: flush_handlers - name: Create ssh private key shell: yes '' | ssh-keygen -N '' args: chdir: "/home/{{ proxy_ssh_user }}" creates: "/home/{{ proxy_ssh_user }}/.ssh/id_rsa.pub" become: True become_method: su become_flags: '-s /bin/sh' become_user: "{{ proxy_ssh_user }}" - name: Read public key slurp: src: "/home/{{ proxy_ssh_user }}/.ssh/id_rsa.pub" register: public_key_result - name: Set public key fact set_fact: proxy_ssh_public_key: "{{ public_key_result.content | b64decode | trim }}" - block: - name: Set authorized keys authorized_key: user: "{{ proxy_ssh_user }}" key: "{{ item }}" with_items: "{{ hostvars.values() | selectattr('inventory_hostname', 'in', groups['k8s']) | selectattr('proxy_ssh_public_key', 'defined') | map(attribute='proxy_ssh_public_key') | list }}" - name: Create tunnel interfaces on the router host shell: cmd: | bash -s <<'EOF' {{ lookup('template', './tunnel.j2') }} EOF register: tun_result with_items: "{{ hostvars.values() | selectattr('inventory_hostname', 'in', groups['k8s']) | selectattr('proxy_inet', '==', False) | map(attribute='inventory_hostname') | list }}" - name: Set created interfaces fact set_fact: proxy_ssh_tunnel_map: "{{ tun_result.results | map(attribute='stdout') | map('from_json') | list }}" - name: Add tunnel iptables (1/2) iptables: chain: FORWARD in_interface: "{{ proxy_interface }}" out_interface: "{{ item.interface }}" ctstate: - RELATED - ESTABLISHED jump: ACCEPT with_items: "{{ proxy_ssh_tunnel_map }}" - name: Add tunnel iptables (2/2) iptables: chain: FORWARD in_interface: "{{ item.interface }}" out_interface: "{{ proxy_interface }}" jump: ACCEPT with_items: "{{ proxy_ssh_tunnel_map }}" when: inventory_hostname == proxy_router_hostname - block: - set_fact: proxy_target="{{ ( hostvars[proxy_router_hostname].proxy_ssh_tunnel_map | selectattr('target_hostname', '==', inventory_hostname) | list )[0] }}" - block: - shell: "ip route get 169.254.42.42 | head -n1 | sed -E 's/.+ dev ([^ ]+).+/\\1/'" register: result - set_fact: proxy_private_interface="{{ result.stdout }}" when: proxy_private_interface | length == 0 # TODO edit /etc/network/interfaces (?) to apply rules on network up - name: Create tunnel interface on the target hosts shell: cmd: | bash -s <<'EOF' echo "## sshproxy" > /etc/network/interfaces.d/{{ proxy_target.interface }} ip tuntap add mode tun dev {{ proxy_target.interface }} ip addr add {{ proxy_target.target_ip }}/30 peer {{ proxy_target.router_ip }} dev {{ proxy_target.interface }} ip link set dev {{ proxy_target.interface }} up DEFAULT_GATEWAY=$(ip route | awk '$3 == "{{ proxy_private_interface }}" { print $1 }' | cut -d'/' -f1) ip route add 10.0.0.0/8 via $DEFAULT_GATEWAY dev {{ proxy_private_interface }} ip route add 169.254.0.0/16 via $DEFAULT_GATEWAY dev {{ proxy_private_interface }} ip route add 172.16.0.0/12 via $DEFAULT_GATEWAY dev {{ proxy_private_interface }} ip route add 192.168.0.0/16 via $DEFAULT_GATEWAY dev {{ proxy_private_interface }} ip route replace default via {{ proxy_target.target_ip }} EOF - name: Establish the SSH tunnel shell: | ssh -N -f \ -w {{ proxy_target.interface_id }}:{{ proxy_target.interface_id }} \ -o StrictHostKeyChecking=no \ -o UserKnownHostsFile=/dev/null \ {{ hostvars[proxy_router_hostname]['ansible_' + proxy_private_interface].ipv4.address }} & echo $! become: True become_method: su become_flags: '-s /bin/sh' become_user: "{{ proxy_ssh_user }}" when: inventory_hostname in hostvars[proxy_router_hostname].proxy_ssh_tunnel_map | map(attribute='target_hostname') | list