├── README.md ├── defaults └── main.yml ├── handlers └── main.yml ├── hosts.example ├── meta └── main.yml ├── tasks └── main.yml └── test.yml /README.md: -------------------------------------------------------------------------------- 1 | Secure SSH 2 | ========== 3 | 4 | This document describes some simple steps that improve the security of your SSH 5 | installation. That steps are include: 6 | 7 | * Disable the empty password login. Empty password is a **very bad** idea. 8 | 9 | * Disable remote root login. The preferred way to gain root permissions is use 10 | `su` or `sudo` command. 11 | 12 | * Add your identity key to `~/.ssh/authorized_keys` on remote host for 13 | passwordless login. 14 | 15 | * Disable password login (done only if previous step is successful). 16 | 17 | * Enable [PAM](http://en.wikipedia.org/wiki/Pluggable_authentication_modules). 18 | 19 | Role Variables 20 | -------------- 21 | 22 | The desired behavior can be refined via variables. 23 | 24 | Option | Description 25 | --- | --- 26 | `sshd` | Name of ssh daemon, default is `ssh`. 27 | `sshd_config` | Path to ssh daemon config, default is `/etc/ssh/sshd_config`. 28 | `ssh_identity_key` | Path to your identity key. Added to `~/.ssh/authorized_keys` on remote host if both `ssh_identity_key` and `ssh_user` are defined. Default is `undefined`. 29 | `ssh_user` | Username on remote host whose authorized keys will be modified. Uses only if `ssh_identity_key` is defined. Default is `undefined`. 30 | 31 | For example, you can override default variables by passing it as a parameter to 32 | the role like so: 33 | 34 | ```yaml 35 | roles: 36 | - { role: ., ssh_user: vital, ssh_identity_key: /home/vital/.ssh/id_rsa.pub } 37 | ``` 38 | 39 | Or send them via command line: 40 | 41 | ```bash 42 | ansible-playbook test.yml --extra-vars "sshd_config=/etc/sshd_config" 43 | ``` 44 | 45 | Example Playbook 46 | ---------------- 47 | 48 | The example below uses `sudo` to play book on your localhost via local 49 | connection. 50 | 51 | ```bash 52 | ansible-playbook test.yml \ 53 | -i hosts.example \ 54 | -c local \ 55 | -s --ask-sudo-pass 56 | ``` 57 | 58 | ```yaml 59 | # file: test.yml 60 | - hosts: local 61 | roles: 62 | - { role: ., sshd: ssh, sshd_config: /etc/sshd_config } 63 | ``` 64 | 65 | License 66 | ------- 67 | 68 | Licensed under the [MIT license](http://mit-license.org/vitalk). 69 | 70 | Author Information 71 | ------------------ 72 | 73 | Created by Vital Kudzelka. 74 | 75 | Don't hesitate create [a GitHub Issue](https://github.com/vitalk/ansible-secure-ssh/issues) if you have any bugs or suggestions. 76 | -------------------------------------------------------------------------------- /defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # The name of ssh daemon 3 | sshd: ssh 4 | 5 | # Where is ssh config is located at 6 | sshd_config: /etc/ssh/sshd_config 7 | -------------------------------------------------------------------------------- /handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: restart sshd 3 | service: name={{ sshd }} state=restarted 4 | -------------------------------------------------------------------------------- /hosts.example: -------------------------------------------------------------------------------- 1 | [local] 2 | 127.0.0.1 3 | -------------------------------------------------------------------------------- /meta/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | galaxy_info: 3 | author: Vital Kudzelka 4 | description: Improve the security of your SSH installation 5 | license: MIT 6 | min_ansible_version: 1.2 7 | platforms: 8 | - name: Darwin 9 | versions: 10 | - all 11 | - name: Debian 12 | versions: 13 | - all 14 | - name: Ubuntu 15 | versions: 16 | - all 17 | categories: 18 | - networking 19 | - system 20 | dependencies: [] 21 | -------------------------------------------------------------------------------- /tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Add identity key to authorized keys on host 3 | authorized_key: 4 | user: "{{ ssh_user }}" 5 | key: "{{ lookup('file', ssh_identity_key) }}" 6 | register: add_identity_key 7 | when: ssh_identity_key is defined and ssh_user is defined 8 | 9 | - name: Disable empty password login 10 | lineinfile: 11 | dest: "{{ sshd_config }}" 12 | regexp: '^#?PermitEmptyPasswords' 13 | line: 'PermitEmptyPasswords no' 14 | notify: restart sshd 15 | 16 | - name: Disable remote root login 17 | lineinfile: 18 | dest: "{{ sshd_config }}" 19 | regexp: '^#?PermitRootLogin' 20 | line: 'PermitRootLogin no' 21 | notify: restart sshd 22 | 23 | - name: Disable password login 24 | lineinfile: 25 | dest: "{{ sshd_config }}" 26 | regexp: '^(#\s*)?PasswordAuthentication ' 27 | line: 'PasswordAuthentication no' 28 | when: 29 | - add_identity_key is succeeded 30 | - not add_identity_key is skipped 31 | notify: restart sshd 32 | 33 | - name: Enable PAM 34 | lineinfile: 35 | dest: "{{ sshd_config }}" 36 | regexp: '^#?UsePAM' 37 | line: 'UsePAM yes' 38 | notify: restart sshd 39 | -------------------------------------------------------------------------------- /test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: local 3 | roles: 4 | - { role: ., sshd: ssh, sshd_config: /etc/sshd_config } 5 | --------------------------------------------------------------------------------