Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added better ssh defaults, added fail2ban, ferm for added security.
- Loading branch information
1 parent
5be55f5
commit 313853c
Showing
31 changed files
with
896 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,18 @@ | ||
--- | ||
www_root: /srv/www | ||
mariadb_dist: trusty | ||
apt_cache_valid_time: 86400 | ||
|
||
sudoers: | ||
- user: "admin" | ||
groups: ["sudo"] | ||
|
||
ferm_input_list: | ||
- type: "dport_accept" | ||
dport: ["http", "https"] | ||
filename: "nginx_accept" | ||
- type: "dport_limit" | ||
dport: ["ssh"] | ||
seconds: "300" | ||
hits: "5" | ||
disabled: false |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
The MIT License (MIT) | ||
|
||
Copyright (c) 2014 Nick Janetakis nick.janetakis@gmail.com | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining | ||
a copy of this software and associated documentation files (the | ||
'Software'), to deal in the Software without restriction, including | ||
without limitation the rights to use, copy, modify, merge, publish, | ||
distribute, sublicense, and/or sell copies of the Software, and to | ||
permit persons to whom the Software is furnished to do so, subject to | ||
the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be | ||
included in all copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, | ||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY | ||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | ||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | ||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
## What is ansible-fail2ban? | ||
|
||
It is an [ansible](http://www.ansible.com/home) role to install and configure fail2ban. | ||
|
||
### What problem does it solve and why is it useful? | ||
|
||
Security is important and fail2ban is an excellent tool to harden your server with minimal or even no configuration. | ||
|
||
## Role variables | ||
|
||
Below is a list of default values along with a description of what they do. | ||
|
||
``` | ||
# Which log level should it be output as? | ||
# 1 = ERROR, 2 = WARN, 3 = INFO, 4 = DEBUG | ||
fail2ban_loglevel: 3 | ||
# Where should log outputs be sent to? | ||
# SYSLOG, STDERR, STDOUT, file | ||
fail2ban_logtarget: /var/log/fail2ban.log | ||
# Where should the socket be created? | ||
fail2ban_socket: /var/run/fail2ban/fail2ban.sock | ||
# Which IP address, CIDR mark or DNS host should be ignored? | ||
fail2ban_ignoreip: 127.0.0.1/8 | ||
# How long in seconds should the ban last for? | ||
fail2ban_bantime: 600 | ||
# How many times can they try before getting banned? | ||
fail2ban_maxretry: 6 | ||
# How should the file changes be detected? | ||
# gamin, polling, auto | ||
fail2ban_backend: polling | ||
# Where should e-mail reports be sent to? | ||
fail2ban_destemail: root@localhost | ||
# How should the ban be applied? | ||
# iptables, iptables-new, iptables-multiport, shorewall, etc. | ||
fail2ban_banaction: iptables-multiport | ||
# What e-mail action should be used? | ||
# sendmail or mail | ||
fail2ban_mta: sendmail | ||
# What should the default protocol be? | ||
fail2ban_protocol: tcp | ||
# Which chain would the JUMPs be added into iptables-*? | ||
fail2ban_chain: INPUT | ||
# What should the default ban action be? | ||
# action_, action_mw, action_mwl | ||
fail2ban_action: action_ | ||
# What services should fail2ban monitor? | ||
# You can define fail2ban_services as an empty string to not monitor anything. | ||
# You can define multiple services as a standard yaml list. | ||
fail2ban_services: | ||
# The name of the service | ||
# REQUIRED. | ||
- name: ssh | ||
# Is it enabled? | ||
# OPTIONAL: Defaults to "true" (must be a string). | ||
enabled: "true" | ||
# What port does the service use? | ||
# Separate multiple ports with a comma, no spaces. | ||
# REQUIRED. | ||
port: ssh | ||
# What protocol does the service use? | ||
# OPTIONAL: Defaults to the protocol listed above. | ||
protocol: tcp | ||
# What filter should it use? | ||
# REQUIRED. | ||
filter: sshd | ||
# Which log path should it monitor? | ||
# REQUIRED. | ||
logpath: /var/log/auth.log | ||
# How many times can they try before getting banned? | ||
# OPTIONAL: Defaults to the maxretry listed above. | ||
maxretry: 6 | ||
# What should the default ban action be? | ||
# OPTIONAL: Defaults to the action listed above. | ||
action: action_ | ||
# How should the ban be applied? | ||
# OPTIONAL: Defaults to the banaction listed above. | ||
banaction: iptables-multiport | ||
``` | ||
|
||
## Example playbook | ||
|
||
Let's say you want to edit a few values, you can do this by opening `group_vars/all` and then add the following: | ||
|
||
``` | ||
fail2ban_services: | ||
- name: ssh | ||
port: ssh | ||
filter: sshd | ||
logpath: /var/log/auth.log | ||
- name: postfix | ||
port: smtp,ssmtp | ||
filter: postfix | ||
logpath: /var/log/mail.log | ||
``` | ||
|
||
## Attribution | ||
|
||
Many thanks to [nickjj](https://github.com/nickjj/) for creating the [original version](https://github.com/nickjj/ansible-fail2ban/) of this role. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
--- | ||
fail2ban_loglevel: 3 | ||
fail2ban_logtarget: /var/log/fail2ban.log | ||
fail2ban_socket: /var/run/fail2ban/fail2ban.sock | ||
|
||
fail2ban_ignoreip: 127.0.0.1/8 | ||
fail2ban_bantime: 600 | ||
fail2ban_maxretry: 6 | ||
|
||
fail2ban_backend: polling | ||
|
||
fail2ban_destemail: root@localhost | ||
fail2ban_banaction: iptables-multiport | ||
fail2ban_mta: sendmail | ||
fail2ban_protocol: tcp | ||
fail2ban_chain: INPUT | ||
|
||
fail2ban_action: action_ | ||
|
||
fail2ban_services: | ||
- name: ssh | ||
port: ssh | ||
filter: sshd | ||
logpath: /var/log/auth.log |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
--- | ||
- name: restart fail2ban | ||
service: name=fail2ban state=restarted |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
--- | ||
- name: ensure fail2ban is installed | ||
apt: pkg=fail2ban state=latest update_cache=true cache_valid_time={{ apt_cache_valid_time }} | ||
notify: | ||
- restart fail2ban | ||
|
||
- name: ensure fail2ban is configured | ||
template: src={{ item }}.j2 dest=/etc/fail2ban/{{ item }} | ||
with_items: | ||
- jail.local | ||
- fail2ban.local | ||
notify: | ||
- restart fail2ban | ||
|
||
- name: ensure fail2ban starts on a fresh reboot | ||
service: name=fail2ban state=started enabled=yes |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
[Definition] | ||
|
||
loglevel = {{ fail2ban_loglevel }} | ||
logtarget = {{ fail2ban_logtarget }} | ||
socket = {{ fail2ban_socket }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
[DEFAULT] | ||
|
||
ignoreip = {{ fail2ban_ignoreip }} | ||
bantime = {{ fail2ban_bantime }} | ||
maxretry = {{ fail2ban_maxretry }} | ||
|
||
backend = {{fail2ban_backend}} | ||
|
||
destemail = {{ fail2ban_destemail }} | ||
banaction = {{ fail2ban_banaction }} | ||
mta = {{ fail2ban_mta }} | ||
protocol = {{ fail2ban_protocol }} | ||
chain = {{ fail2ban_chain }} | ||
|
||
action_ = %(banaction)s[name=%(__name__)s, port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"] | ||
|
||
action_mw = %(banaction)s[name=%(__name__)s, port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"] | ||
%(mta)s-whois[name=%(__name__)s, dest="%(destemail)s", protocol="%(protocol)s", chain="%(chain)s"] | ||
|
||
action_mwl = %(banaction)s[name=%(__name__)s, port="%(port)s", protocol="%(protocol)s", chain="%(chain)s"] | ||
%(mta)s-whois-lines[name=%(__name__)s, dest="%(destemail)s", logpath=%(logpath)s, chain="%(chain)s"] | ||
|
||
action = %({{ fail2ban_action }})s | ||
|
||
{% if fail2ban_services is iterable %} | ||
{% for service in fail2ban_services %} | ||
[{{ service.name }}] | ||
|
||
enabled = {{ service.enabled|default("true") }} | ||
port = {{ service.port }} | ||
filter = {{ service.filter }} | ||
logpath = {{ service.logpath }} | ||
{% if service.maxretry is defined %} | ||
maxretry = {{ service.maxretry }} | ||
{% endif %} | ||
{% if service.protocol is defined %} | ||
protocol = {{ service.protocol }} | ||
{% endif %} | ||
{% if service.action is defined %} | ||
action = %({{ service.action }})s | ||
{% endif %} | ||
{% if service.banaction is defined %} | ||
banaction = {{ service.banaction }} | ||
{% endif %} | ||
|
||
{% endfor %} | ||
{% endif %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
The MIT License (MIT) | ||
|
||
Copyright (c) 2014 Nick Janetakis nick.janetakis@gmail.com | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining | ||
a copy of this software and associated documentation files (the | ||
'Software'), to deal in the Software without restriction, including | ||
without limitation the rights to use, copy, modify, merge, publish, | ||
distribute, sublicense, and/or sell copies of the Software, and to | ||
permit persons to whom the Software is furnished to do so, subject to | ||
the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be | ||
included in all copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, | ||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY | ||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | ||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | ||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
Oops, something went wrong.
313853c
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems cool but I don't really understand why we need yet another user. It's confusing to have the built-in ubuntu (with sudo powers), new admin (with sudo powers), and deploy. What specifically are the roles of each user in the default configuration? Also, is it really necessary to manually generate a password during setup and paste it into a configuration file? Seems like the goal should be making this more portable with less files to edit, rather than expanding. Surely there's an automated way to auto-generate a good random password when the play is run (BTW: since passwords aren't ever used shouldn't they be disabled with passwd -l)
313853c
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also ufw is still installed in dev-tools role, does this conflict with ferm?
313853c
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
ubuntu
user isn't "built-in", at least not on DigitalOcean's Ubuntu droplets. The admin user is basically theubuntu
user but with a more general name (in case you're using Debian, for example).The deploy user owns all the web files for security reasons.
You should have a password; logging in should require a public/private key pair but running sudo commands on the box should require the password.
@nathanielks will have to speak to ufw/ferm.
313853c
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@30suns ufw is definitely an oversight, we can remove that. It doesn't conflict because it isn't configured.
Everthing @mAAdhaTTah said :)
In addition to that, yes, there are automated ways of generating passwords, like so. In the research I was doing though, it's generally recommended not to do a plain text lookup though because of security reasons and lack of portability as the file would exist outside the repo (most likely). At least with this implementation, the file can be encrypted and edited using
ansible-vault
and safely stored in the repo when encrypted. I'd love to hear alternate solutions! All for more portability and security.313853c
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nathanielks fail2ban is also in dev-tools :)
As far as a sudo password goes, I'm down with that, but I get an error now when I run vagrant up
Missing sudo password
Also, stock ubuntu amis on aws come with with full passwordless sudo and root ssh already disabled. So is bedrock-ansible DigitalOcean-specific (fine if it is, but if not, should be made more portable). I guess on aws we'd need to remove the ubuntu user, but that's challenging to do since you can't log in as root :)
313853c
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@30suns that's probably a separate issue, unless you ran
secure-root.yml
on your vagrant box? ( This isn't recommended ).It's not necessarily DO specific, but I do believe the team prefers it. I know we're waiting on a few other tools so we can build in DO integration. As far as AWS is concerned, I believe @austinpray likes it. I haven't/don't use it, so tbh I'm building with DO in mind.
I don't see why we'd need to remove the ubuntu user on AWS. @swalkinshaw any ideas on techniques to make sure we can play well with other hosts?
313853c
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nathanielks @30suns This playbook should definitely be portable enough to work on AWS. I would say that is a good litmus test for portability.
To work with AWS: couldn't you just set the "remote_user" to "ubuntu" and then just not run the secure-root.yml playbook? AWS already does this for you, so you can just skip it right?
313853c
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@austinpray this sounds correct to me as well. I'm not sure secure-root.yml would add anymore security than what's already built in to AWS's. @30suns would you mind comparing AWS's
/etc/ssh/sshd_config
to ours and see if there are any differences?313853c
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the followup everyone.
@mAAdhaTTah on debian-based systems installed with d-i there's normally a default-user and a root user 'built in', and ubuntu images tend to use
ubuntu
. I'm not sure why DO ubuntu droplets don't have a default user other than root, but that certainly explains why secure-root.yml assumes a root user has SSH access, and some of the other choices made. Some of those choices might need to be tweaked for portability.@mAAdhaTTah e.g., passwords for sudo may be really great (I'm not saying they aren't) but there are quite a few gymnastics one has to go through to enable them on most AWS AMIs I've used. e.g., have a look at http://www.whiteboardcoder.com/2013/04/amazon-aws-fix-cloud-init-in-ubuntu-1210.html Further gymnastics will need to be done to remove the /etc/sudoers.d/90-cloud-init-users and possibly other things (I gave up after a few hours trying to get Packer to build me a Ubuntu image using a user_data_file that would enable passwords for the default user).
I'm agnostic about what to call the users but I do think there should be clearer baseline roles defined in
bedrock-ansible
as well as a bootstrap process portable enough for AWS. AWS assumes the root user is locked out of SSH altogether, and the default user's password is locked, and has passwordless sudo. To change those defaults is going to require a separate play, mucking around with a user_data_file and possibly involve generating a new AMI; And I question whether the security will really be 'better'.@mAAdhaTTah The
deploy
owns web files 'for security reasons', can you elaborate? It appears that it's capistrano can deploy to the web directory, but what about cap tasks involving restarting services, etc.? As currently implemented,wordpress_sites
is an array, each with its ownuser
defined and used in various plays. Said users are also in the same class as the 'deploy' user intended to be used with capistrano though there's presumably only one of those in use?@austinpray As far as ignoring root-setup.yml, and just using the
ubuntu
user, certainly, but maybe the play should be renamed to secure-DO-root.yml Perhaps unsurprisingly, the security assumptions of that play are pretty different than those made by other teams. :)@nathanielks I will take a look at AWS's
/etc/ssh/sshd_config
and post my results separately.313853c
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nathanielks Stock Ubuntu on AWS
/etc/ssh/sshd_config
: https://gist.github.com/30suns/25d7fb94c5e753f1fb63313853c
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@30suns Yeah, generally speaking, the development of
bedrock-ansible
has been DO-focused. I remember seeing issues suggesting testing using DO droplets, plus #40. I'm not sure how much extra work is required to make this portable to AWS, but if as you say it's a lot of extra work without being "safer," you can always skip runningsecure-root.yml
for your AWS instances and secure it yourself. That's the reason it's a separate playbook. Maybe there's an argument for renaming it or including some documentation explaining it's for DO, but yeah, this was certainly written with DO in mind.#61 addresses including some of the services under the
deploy
user so you can restart them when you deploy. The idea is you could give other developers access to deployment without giving them full access to the server, i.e. installing software, manipulating the database, etc. Though I guess this does raise the question about whether thedeploy
user should be given permissions to the.env
file, though it's still better than full DB access. Similarly, if the deploy user is compromised, the damage is still more limited than full server access (i.e. they wouldn't be able to lock you out).313853c
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@30suns ideally this playbook should be portable and work on different providers (assuming Ubuntu 14.04 at least for now). Ansible has cloud modules so it shouldn't be too hard to at least make this playbook work with those easily.
Regarding users and
deploy
. I generally think there should be 3 "classes" of users/groups:root
(obviously built-in and should be avoided as AWS does),admin
/ubuntu
(these are really the same thing, we should just avoid duplicating them), and then a web/deploy user.I prefer to avoid using a user which has full
sudo
access and system wide permissions for ownership of web directories and access to a few services it may need to restart. This last one may be debatable but I don't think 3 users which clearly defined roles is too much.I'm not sure even sure about some of the options for
wordpress_sites
anymore. I wanted to make it configurable but allowing for different users/groups for each one just seems confusing now.I think at this point it would be useful to open up an issue about the conflict between the
admin
user and the built-in one some providers have. Do you want to do that? If there's any other issues for AWS, I'd welcome issues for those as well.