├── .ansible-lint ├── .github └── workflows │ ├── ci.yml │ └── release.yml ├── .gitignore ├── .yamllint ├── Dockerfile ├── LICENSE.txt ├── README.md ├── Vagrantfile ├── defaults └── main.yml ├── files └── empty ├── handlers └── main.yml ├── meta └── main.yml ├── molecule └── default │ ├── collections.yml │ ├── converge.yml │ ├── molecule.yml │ ├── prepare.yml │ └── verify.yml ├── requirements.yml ├── tasks └── main.yml ├── templates └── empty ├── tests ├── inventory ├── tasks │ └── pre.yml ├── test.yml ├── vagrant.yml └── vars │ └── main.yml └── vars └── main.yml /.ansible-lint: -------------------------------------------------------------------------------- 1 | --- 2 | warn_list: 3 | - role-name 4 | - name[play] 5 | - name[casing] 6 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: CI 3 | 'on': 4 | pull_request: 5 | push: 6 | branches: 7 | - master 8 | schedule: 9 | - cron: '30 1 * * 3' 10 | 11 | jobs: 12 | 13 | lint: 14 | name: Lint 15 | runs-on: ubuntu-latest 16 | steps: 17 | - name: Check out the codebase 18 | uses: actions/checkout@v3 19 | 20 | - name: Set up Python 3 21 | uses: actions/setup-python@v4 22 | with: 23 | python-version: '3.x' 24 | 25 | - name: Install test dependencies 26 | run: | 27 | pip install ansible-lint 28 | ansible-galaxy install -r requirements.yml 29 | 30 | - name: Lint code 31 | run: | 32 | yamllint . 33 | ansible-lint 34 | 35 | molecule: 36 | name: Molecule 37 | runs-on: ubuntu-latest 38 | defaults: 39 | run: 40 | working-directory: "${{ github.repository }}" 41 | needs: 42 | - lint 43 | strategy: 44 | fail-fast: false 45 | matrix: 46 | include: 47 | - distro: debian8 48 | - distro: debian9 49 | - distro: debian10 50 | - distro: ubuntu1604 51 | ansible-version: '>=2.10, <2.11' 52 | - distro: ubuntu1604 53 | - distro: ubuntu1804 54 | - distro: ubuntu2004 55 | 56 | steps: 57 | - name: Check out the codebase 58 | uses: actions/checkout@v3 59 | with: 60 | path: "${{ github.repository }}" 61 | 62 | - name: Set up Python 3 63 | uses: actions/setup-python@v4 64 | with: 65 | python-version: '3.x' 66 | 67 | - name: Install test dependencies 68 | run: pip install 'ansible${{ matrix.ansible-version }}' molecule[docker] docker 69 | 70 | - name: Run Molecule tests 71 | run: | 72 | molecule test 73 | env: 74 | ANSIBLE_FORCE_COLOR: '1' 75 | ANSIBLE_VERBOSITY: '2' 76 | MOLECULE_DEBUG: '1' 77 | MOLECULE_DISTRO: "${{ matrix.distro }}" 78 | PY_COLORS: '1' 79 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Release 3 | 'on': 4 | push: 5 | tags: 6 | - '*' 7 | 8 | jobs: 9 | 10 | release: 11 | name: Release 12 | runs-on: ubuntu-latest 13 | steps: 14 | - name: Check out the codebase 15 | uses: actions/checkout@v3 16 | 17 | - name: Publish to Galaxy 18 | uses: robertdebock/galaxy-action@1.2.0 19 | with: 20 | galaxy_api_key: ${{ secrets.GALAXY_API_KEY }} 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # OS generated files # 2 | ###################### 3 | .DS_Store 4 | .DS_Store? 5 | ._* 6 | .Spotlight-V100 7 | .Trashes 8 | Icon? 9 | ehthumbs.db 10 | Thumbs.db 11 | 12 | # IDE files # 13 | ################# 14 | /.settings 15 | /.buildpath 16 | /.project 17 | /nbproject 18 | *.komodoproject 19 | *.kpf 20 | /.idea 21 | 22 | # Vagrant files # 23 | .virtualbox/ 24 | .vagrant/ 25 | vagrant_ansible_inventory_* 26 | ansible.cfg 27 | 28 | # Other files # 29 | ############### 30 | !empty 31 | -------------------------------------------------------------------------------- /.yamllint: -------------------------------------------------------------------------------- 1 | --- 2 | extends: default 3 | 4 | rules: 5 | braces: 6 | max-spaces-inside: 1 7 | level: error 8 | brackets: 9 | max-spaces-inside: 1 10 | level: error 11 | line-length: disable 12 | truthy: disable 13 | 14 | ignore: | 15 | .tox/ 16 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:18.04 2 | MAINTAINER Mischa ter Smitten 3 | 4 | ENV LANG C.UTF-8 5 | ENV LC_ALL C.UTF-8 6 | 7 | # python 8 | RUN apt-get update && \ 9 | DEBIAN_FRONTEND=noninteractive apt-get install -y python3-minimal python3-dev curl && \ 10 | apt-get clean 11 | RUN curl -sL https://bootstrap.pypa.io/pip/3.6/get-pip.py | python3 - 12 | RUN rm -rf $HOME/.cache 13 | 14 | # ansible 15 | RUN DEBIAN_FRONTEND=noninteractive apt-get install -y python3-apt && \ 16 | apt-get clean 17 | RUN pip3 install ansible==2.10.7 18 | RUN rm -rf $HOME/.cache 19 | 20 | # provision 21 | COPY . /etc/ansible/roles/ansible-role 22 | WORKDIR /etc/ansible/roles/ansible-role 23 | RUN ansible-playbook -i tests/inventory tests/test.yml --connection=local 24 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) Oefenweb.nl 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is furnished 8 | to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## autossh-tunnel-server 2 | 3 | [![CI](https://github.com/Oefenweb/ansible-autossh-tunnel-server/workflows/CI/badge.svg)](https://github.com/Oefenweb/ansible-autossh-tunnel-server/actions?query=workflow%3ACI) 4 | [![Ansible Galaxy](http://img.shields.io/badge/ansible--galaxy-autossh--tunnel--server-blue.svg)](https://galaxy.ansible.com/Oefenweb/autossh_tunnel_server) 5 | 6 | Set up a persistent tunnel (using `autossh`) in Debian-like systems (server side). 7 | 8 | #### Requirements 9 | 10 | None 11 | 12 | #### Variables 13 | 14 | * `autossh_tunnel_server_user`: [default: `autossh`]: The user that will accept the `autossh` connection 15 | * `autossh_tunnel_server_group`: [default: `autossh`]: The primary group of the `autossh` user 16 | * `autossh_tunnel_server_groups`: [default: `[ssh_users]`]: The secondary groups of the `autossh` user 17 | * `autossh_tunnel_server_shell`: [default: `/bin/false`]: The shell of the `autossh` user 18 | 19 | * `autossh_tunnel_server_authorized_keys`: [default: `[]`]: Authorized key declarations 20 | * `autossh_tunnel_server_authorized_keys.{n}.src`: [required]: The local path of the key 21 | * `autossh_tunnel_server_authorized_keys.{n}.state`: [optional, default: `present`]: State 22 | 23 | ## Dependencies 24 | 25 | None 26 | 27 | ## Recommended 28 | 29 | * `ansible-autossh-tunnel-client` ([see](https://github.com/Oefenweb/ansible-autossh-tunnel-client)) 30 | 31 | #### Example 32 | 33 | ```yaml 34 | --- 35 | - hosts: all 36 | roles: 37 | - oefenweb.autossh-tunnel-server 38 | vars: 39 | autossh_tunnel_server_groups: 40 | - ssh_users 41 | autossh_tunnel_server_authorized_keys: 42 | - src: ../../../files/autossh-tunnel/etc/autossh/id_rsa.pub 43 | ``` 44 | 45 | #### License 46 | 47 | MIT 48 | 49 | #### Author Information 50 | 51 | Mischa ter Smitten 52 | 53 | #### Feedback, bug-reports, requests, ... 54 | 55 | Are [welcome](https://github.com/Oefenweb/ansible-autossh-tunnel-server/issues)! 56 | -------------------------------------------------------------------------------- /Vagrantfile: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | # vi: set ft=ruby ts=2 sw=2 tw=0 et : 3 | 4 | role = File.basename(File.expand_path(File.dirname(__FILE__))) 5 | 6 | boxes = [ 7 | { 8 | :name => "ubuntu-1604", 9 | :box => "bento/ubuntu-16.04", 10 | :ip => '10.0.0.12', 11 | :cpu => "50", 12 | :ram => "256" 13 | }, 14 | { 15 | :name => "ubuntu-1804", 16 | :box => "bento/ubuntu-18.04", 17 | :ip => '10.0.0.13', 18 | :cpu => "50", 19 | :ram => "384" 20 | }, 21 | { 22 | :name => "ubuntu-2004", 23 | :box => "bento/ubuntu-20.04", 24 | :ip => '10.0.0.14', 25 | :cpu => "50", 26 | :ram => "384" 27 | }, 28 | { 29 | :name => "debian-8", 30 | :box => "bento/debian-8", 31 | :ip => '10.0.0.16', 32 | :cpu => "50", 33 | :ram => "256" 34 | }, 35 | { 36 | :name => "debian-9", 37 | :box => "bento/debian-9", 38 | :ip => '10.0.0.17', 39 | :cpu => "50", 40 | :ram => "256" 41 | }, 42 | { 43 | :name => "debian-10", 44 | :box => "bento/debian-10", 45 | :ip => '10.0.0.18', 46 | :cpu => "50", 47 | :ram => "256" 48 | }, 49 | ] 50 | 51 | Vagrant.configure("2") do |config| 52 | boxes.each do |box| 53 | config.vm.define box[:name] do |vms| 54 | vms.vm.box = box[:box] 55 | vms.vm.hostname = "ansible-#{role}-#{box[:name]}" 56 | 57 | vms.vm.provider "virtualbox" do |v| 58 | v.customize ["modifyvm", :id, "--cpuexecutioncap", box[:cpu]] 59 | v.customize ["modifyvm", :id, "--memory", box[:ram]] 60 | end 61 | 62 | vms.vm.network :private_network, ip: box[:ip] 63 | 64 | vms.vm.provision :ansible do |ansible| 65 | ansible.playbook = "tests/vagrant.yml" 66 | ansible.verbose = "vv" 67 | end 68 | end 69 | end 70 | end 71 | -------------------------------------------------------------------------------- /defaults/main.yml: -------------------------------------------------------------------------------- 1 | # defaults file 2 | --- 3 | autossh_tunnel_server_user: autossh 4 | autossh_tunnel_server_group: autossh 5 | autossh_tunnel_server_groups: [] 6 | autossh_tunnel_server_shell: /bin/false 7 | autossh_tunnel_server_authorized_keys: [] 8 | -------------------------------------------------------------------------------- /files/empty: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Oefenweb/ansible-autossh-tunnel-server/4ab72d1a2d2d4d6c7ba9241646dcf8e5101c73a2/files/empty -------------------------------------------------------------------------------- /handlers/main.yml: -------------------------------------------------------------------------------- 1 | # handlers file 2 | --- 3 | -------------------------------------------------------------------------------- /meta/main.yml: -------------------------------------------------------------------------------- 1 | # meta file 2 | --- 3 | galaxy_info: 4 | author: oefenweb 5 | role_name: autossh_tunnel_server 6 | company: Oefenweb.nl B.V. 7 | description: Set up a persistent tunnel (using autossh) in Debian-like systems (server side) 8 | license: MIT 9 | min_ansible_version: 2.10.0 10 | platforms: 11 | - name: Ubuntu 12 | versions: 13 | - xenial 14 | - bionic 15 | - focal 16 | - name: Debian 17 | versions: 18 | - jessie 19 | - stretch 20 | - buster 21 | galaxy_tags: 22 | - system 23 | - networking 24 | dependencies: [] 25 | -------------------------------------------------------------------------------- /molecule/default/collections.yml: -------------------------------------------------------------------------------- 1 | --- 2 | collections: 3 | - name: community.docker 4 | version: '>=1.2.0,<2' 5 | - name: community.general 6 | version: '>=2,<3' 7 | -------------------------------------------------------------------------------- /molecule/default/converge.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Converge 3 | hosts: all 4 | become: true 5 | roles: 6 | - ../../../ 7 | -------------------------------------------------------------------------------- /molecule/default/molecule.yml: -------------------------------------------------------------------------------- 1 | --- 2 | dependency: 3 | name: galaxy 4 | driver: 5 | name: docker 6 | platforms: 7 | - name: instance 8 | image: "geerlingguy/docker-${MOLECULE_DISTRO:-ubuntu1604}-ansible:latest" 9 | command: ${MOLECULE_DOCKER_COMMAND:-""} 10 | volumes: 11 | - /sys/fs/cgroup:/sys/fs/cgroup:rw 12 | - /var/lib/containerd 13 | cgroupns_mode: host 14 | privileged: true 15 | pre_build_image: true 16 | provisioner: 17 | name: ansible 18 | playbooks: 19 | prepare: prepare.yml 20 | converge: converge.yml 21 | verify: verify.yml 22 | -------------------------------------------------------------------------------- /molecule/default/prepare.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Prepare 3 | hosts: all 4 | become: true 5 | tasks: [] 6 | -------------------------------------------------------------------------------- /molecule/default/verify.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Verify 3 | hosts: all 4 | become: true 5 | tasks: [] 6 | -------------------------------------------------------------------------------- /requirements.yml: -------------------------------------------------------------------------------- 1 | # requirements file 2 | --- 3 | collections: 4 | - name: ansible.posix 5 | -------------------------------------------------------------------------------- /tasks/main.yml: -------------------------------------------------------------------------------- 1 | # tasks file 2 | --- 3 | - name: add group 4 | ansible.builtin.group: 5 | name: "{{ item }}" 6 | system: true 7 | with_items: "{{ [autossh_tunnel_server_group] + autossh_tunnel_server_groups }}" 8 | tags: 9 | - configuration 10 | - autossh-tunnel-server 11 | - autossh-tunnel-server-add-group 12 | 13 | - name: add user 14 | ansible.builtin.user: 15 | name: "{{ autossh_tunnel_server_user }}" 16 | system: true 17 | group: "{{ autossh_tunnel_server_group }}" 18 | groups: "{{ autossh_tunnel_server_groups | join(',') }}" 19 | shell: "{{ autossh_tunnel_server_shell }}" 20 | tags: 21 | - configuration 22 | - autossh-tunnel-server 23 | - autossh-tunnel-server-add-user 24 | 25 | - name: create authorized_keys from public key 26 | ansible.posix.authorized_key: 27 | user: "{{ autossh_tunnel_server_user }}" 28 | key: "{{ lookup('file', item.src) }}" 29 | state: "{{ item.state | default('present') }}" 30 | with_items: "{{ autossh_tunnel_server_authorized_keys }}" 31 | tags: 32 | - configuration 33 | - autossh-tunnel-server 34 | - autossh-tunnel-server-authorized-keys 35 | -------------------------------------------------------------------------------- /templates/empty: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Oefenweb/ansible-autossh-tunnel-server/4ab72d1a2d2d4d6c7ba9241646dcf8e5101c73a2/templates/empty -------------------------------------------------------------------------------- /tests/inventory: -------------------------------------------------------------------------------- 1 | localhost 2 | -------------------------------------------------------------------------------- /tests/tasks/pre.yml: -------------------------------------------------------------------------------- 1 | # pre test file 2 | --- 3 | - name: install dependencies 4 | ansible.builtin.apt: 5 | name: 6 | - openssh-client 7 | state: "{{ apt_install_state | default('latest') }}" 8 | cache_valid_time: "{{ apt_update_cache_valid_time | default(3600) }}" 9 | 10 | - name: generate ssh key 11 | ansible.builtin.command: > 12 | ssh-keygen -t rsa -b 2048 -C '' -P '' -f {{ autossh_tunnel_server_private_key_file }} -q 13 | args: 14 | creates: "{{ autossh_tunnel_server_private_key_file }}" 15 | connection: local 16 | become: false 17 | -------------------------------------------------------------------------------- /tests/test.yml: -------------------------------------------------------------------------------- 1 | # test file 2 | --- 3 | - hosts: localhost 4 | connection: local 5 | become: true 6 | pre_tasks: 7 | - name: include vars 8 | ansible.builtin.include_vars: "{{ playbook_dir }}/vars/main.yml" 9 | - name: include tasks 10 | ansible.builtin.import_tasks: "{{ playbook_dir }}/tasks/pre.yml" 11 | roles: 12 | - ../../ 13 | -------------------------------------------------------------------------------- /tests/vagrant.yml: -------------------------------------------------------------------------------- 1 | # test file 2 | --- 3 | - hosts: all 4 | remote_user: vagrant 5 | become: true 6 | pre_tasks: 7 | - name: include vars 8 | ansible.builtin.include_vars: "{{ playbook_dir }}/vars/main.yml" 9 | - name: include tasks 10 | ansible.builtin.import_tasks: "{{ playbook_dir }}/tasks/pre.yml" 11 | roles: 12 | - ../../ 13 | -------------------------------------------------------------------------------- /tests/vars/main.yml: -------------------------------------------------------------------------------- 1 | # vars file 2 | --- 3 | autossh_tunnel_server_authorized_keys: 4 | - src: "{{ autossh_tunnel_server_public_key_file }}" 5 | 6 | autossh_tunnel_server_ssh_directory: "{{ playbook_dir }}/../files" 7 | autossh_tunnel_server_private_key_file: "{{ autossh_tunnel_server_ssh_directory }}/id_rsa" 8 | autossh_tunnel_server_public_key_file: "{{ autossh_tunnel_server_private_key_file }}.pub" 9 | -------------------------------------------------------------------------------- /vars/main.yml: -------------------------------------------------------------------------------- 1 | # vars file 2 | --- 3 | --------------------------------------------------------------------------------