Merge pull request #166 from clems4ever/no-search-engine-indexing
- Add a meta tag to avoid search engine indexing - Improve security with Content-Security-Policy - Change basicauth.test.local into single_factor.test.localpull/168/merge
commit
004a55ea2f
|
@ -17,7 +17,7 @@ addons:
|
|||
hosts:
|
||||
- admin.test.local
|
||||
- auth.test.local
|
||||
- basicauth.test.local
|
||||
- single_factor.test.local
|
||||
- dev.test.local
|
||||
- home.test.local
|
||||
- mx1.mail.test.local
|
||||
|
|
|
@ -4,3 +4,4 @@ who commit code to the project are encouraged to add their names
|
|||
here. Please keep the list sorted by first names
|
||||
|
||||
Clement Michaud <clement.michaud34@gmail.com>
|
||||
Antoine Favre <@n4kre>
|
||||
|
|
23
README.md
23
README.md
|
@ -101,6 +101,7 @@ Add the following lines to your **/etc/hosts** to alias multiple subdomains so t
|
|||
127.0.0.1 admin.test.local
|
||||
127.0.0.1 mx1.mail.test.local
|
||||
127.0.0.1 mx2.mail.test.local
|
||||
127.0.0.1 single_factor.test.local
|
||||
127.0.0.1 auth.test.local
|
||||
|
||||
### Run it!
|
||||
|
@ -221,6 +222,28 @@ that the attacker must also require the certificate to retrieve the cookies.
|
|||
Note that using [HSTS] has consequences. That's why you should read the blog
|
||||
post nginx has written on [HSTS].
|
||||
|
||||
### More protections measures
|
||||
|
||||
You can also apply the following headers to your nginx configuration for
|
||||
improving security. Please read the documentation of those headers before
|
||||
applying them blindly.
|
||||
|
||||
```
|
||||
# We don't want any credentials / TOTP secret key / QR code to be cached by
|
||||
# the client
|
||||
add_header Cache-Control "no-store";
|
||||
add_header Pragma "no-cache";
|
||||
|
||||
# Clickjacking / XSS protection
|
||||
|
||||
# We don't want Authelia's login page to be rendered within a <frame>,
|
||||
# <iframe> or <object> from an external website.
|
||||
add_header X-Frame-Options "SAMEORIGIN";
|
||||
|
||||
# Block pages from loading when they detect reflected XSS attacks.
|
||||
add_header X-XSS-Protection "1; mode=block";
|
||||
```
|
||||
|
||||
## Documentation
|
||||
### Authelia configuration
|
||||
The configuration of the server is defined in the file
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
body {
|
||||
background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1NiIgaGVpZ2h0PSIxMDAiPgo8cmVjdCB3aWR0aD0iNTYiIGhlaWdodD0iMTAwIiBmaWxsPSIjRkZGRkZGIj48L3JlY3Q+CjxwYXRoIGQ9Ik0yOCA2NkwwIDUwTDAgMTZMMjggMEw1NiAxNkw1NiA1MEwyOCA2NkwyOCAxMDAiIGZpbGw9Im5vbmUiIHN0cm9rZT0iI0ZDRkNGQyIgc3Ryb2tlLXdpZHRoPSIyIj48L3BhdGg+CjxwYXRoIGQ9Ik0yOCAwTDI4IDM0TDAgNTBMMCA4NEwyOCAxMDBMNTYgODRMNTYgNTBMMjggMzQiIGZpbGw9Im5vbmUiIHN0cm9rZT0iI0ZCRkJGQiIgc3Ryb2tlLXdpZHRoPSIyIj48L3BhdGg+Cjwvc3ZnPg==");
|
||||
background-image: url("/img/background.svg");
|
||||
}
|
||||
|
||||
.authelia-brand {
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="56" height="100">
|
||||
<rect width="56" height="100" fill="#FFFFFF"></rect>
|
||||
<path d="M28 66L0 50L0 16L28 0L56 16L56 50L28 66L28 100" fill="none" stroke="#FCFCFC" stroke-width="2"></path>
|
||||
<path d="M28 0L28 34L0 50L0 84L28 100L56 84L56 50L28 34" fill="none" stroke="#FBFBFB" stroke-width="2"></path>
|
||||
</svg>
|
After Width: | Height: | Size: 347 B |
|
@ -10,27 +10,22 @@ import ResetPasswordForm from "./lib/reset-password/reset-password-form";
|
|||
import jslogger = require("js-logger");
|
||||
import jQuery = require("jquery");
|
||||
import U2fApi = require("u2f-api");
|
||||
import Endpoints = require("../../shared/api");
|
||||
|
||||
jslogger.useDefaults();
|
||||
jslogger.setLevel(jslogger.INFO);
|
||||
|
||||
export = {
|
||||
firstfactor: function () {
|
||||
(function () {
|
||||
if (window.location.pathname == Endpoints.FIRST_FACTOR_GET)
|
||||
FirstFactor(window, jQuery, FirstFactorValidator, jslogger);
|
||||
},
|
||||
secondfactor: function () {
|
||||
else if (window.location.pathname == Endpoints.SECOND_FACTOR_GET)
|
||||
SecondFactor(window, jQuery, U2fApi);
|
||||
},
|
||||
register_totp: function() {
|
||||
else if (window.location.pathname == Endpoints.SECOND_FACTOR_TOTP_IDENTITY_FINISH_GET)
|
||||
TOTPRegister(window, jQuery);
|
||||
},
|
||||
register_u2f: function () {
|
||||
else if (window.location.pathname == Endpoints.SECOND_FACTOR_U2F_IDENTITY_FINISH_GET)
|
||||
U2fRegister(window, jQuery);
|
||||
},
|
||||
reset_password_request: function () {
|
||||
ResetPasswordRequest(window, jQuery);
|
||||
},
|
||||
reset_password_form: function () {
|
||||
else if (window.location.pathname == Endpoints.RESET_PASSWORD_IDENTITY_FINISH_GET)
|
||||
ResetPasswordForm(window, jQuery);
|
||||
}
|
||||
};
|
||||
else if (window.location.pathname == Endpoints.RESET_PASSWORD_REQUEST_GET)
|
||||
ResetPasswordRequest(window, jQuery);
|
||||
})();
|
||||
|
|
|
@ -74,7 +74,7 @@ ldap:
|
|||
authentication_methods:
|
||||
default_method: two_factor
|
||||
per_subdomain_methods:
|
||||
basicauth.test.local: single_factor
|
||||
single_factor.test.local: single_factor
|
||||
|
||||
# Access Control
|
||||
#
|
||||
|
|
222
config.test.yml
222
config.test.yml
|
@ -1,222 +0,0 @@
|
|||
###############################################################
|
||||
# Authelia configuration #
|
||||
###############################################################
|
||||
|
||||
# The port to listen on
|
||||
port: 80
|
||||
|
||||
# Log level
|
||||
#
|
||||
# Level of verbosity for logs
|
||||
logs_level: debug
|
||||
|
||||
# LDAP configuration
|
||||
#
|
||||
# Example: for user john, the DN will be cn=john,ou=users,dc=example,dc=com
|
||||
ldap:
|
||||
# The url of the ldap server
|
||||
url: ldap://openldap
|
||||
|
||||
# The base dn for every entries
|
||||
base_dn: dc=example,dc=com
|
||||
|
||||
# An additional dn to define the scope to all users
|
||||
additional_users_dn: ou=users
|
||||
|
||||
# The users filter used to find the user DN
|
||||
# {0} is a matcher replaced by username.
|
||||
# 'cn={0}' by default.
|
||||
users_filter: cn={0}
|
||||
|
||||
# An additional dn to define the scope of groups
|
||||
additional_groups_dn: ou=groups
|
||||
|
||||
# The groups filter used for retrieving groups of a given user.
|
||||
# {0} is a matcher replaced by username.
|
||||
# {dn} is a matcher replaced by user DN.
|
||||
# 'member={dn}' by default.
|
||||
groups_filter: (&(member={dn})(objectclass=groupOfNames))
|
||||
|
||||
# The attribute holding the name of the group
|
||||
group_name_attribute: cn
|
||||
|
||||
# The attribute holding the mail address of the user
|
||||
mail_attribute: mail
|
||||
|
||||
# The username and password of the admin user.
|
||||
user: cn=admin,dc=example,dc=com
|
||||
password: password
|
||||
|
||||
|
||||
# Authentication methods
|
||||
#
|
||||
# Authentication methods can be defined per subdomain.
|
||||
# There are currently two available methods: "single_factor" and "two_factor"
|
||||
#
|
||||
# Note: by default a domain uses "two_factor" method.
|
||||
#
|
||||
# Note: 'per_subdomain_methods' is a dictionary where keys must be subdomains and
|
||||
# values must be one of the two possible methods.
|
||||
#
|
||||
# Note: 'per_subdomain_methods' is optional.
|
||||
authentication_methods:
|
||||
default_method: two_factor
|
||||
per_subdomain_methods:
|
||||
basicauth.test.local: single_factor
|
||||
|
||||
# Access Control
|
||||
#
|
||||
# Access control is a set of rules you can use to restrict user access to certain
|
||||
# resources.
|
||||
# Any (apply to anyone), per-user or per-group rules can be defined.
|
||||
#
|
||||
# If 'access_control' is not defined, ACL rules are disabled and the `allow` default
|
||||
# policy is applied, i.e., access is allowed to anyone. Otherwise restrictions follow
|
||||
# the rules defined.
|
||||
#
|
||||
# Note: One can use the wildcard * to match any subdomain.
|
||||
# It must stand at the beginning of the pattern. (example: *.mydomain.com)
|
||||
#
|
||||
# Note: You must put the pattern in simple quotes when using the wildcard for the YAML
|
||||
# to be syntaxically correct.
|
||||
#
|
||||
# Definition: A `rule` is an object with the following keys: `domain`, `policy`
|
||||
# and `resources`.
|
||||
# - `domain` defines which domain or set of domains the rule applies to.
|
||||
# - `policy` is the policy to apply to resources. It must be either `allow` or `deny`.
|
||||
# - `resources` is a list of regular expressions that matches a set of resources to
|
||||
# apply the policy to.
|
||||
#
|
||||
# Note: Rules follow an order of priority defined as follows:
|
||||
# In each category (`any`, `groups`, `users`), the latest rules have the highest
|
||||
# priority. In other words, it means that if a given resource matches two rules in the
|
||||
# same category, the latest one overrides the first one.
|
||||
# Each category has also its own priority. That is, `users` has the highest priority, then
|
||||
# `groups` and `any` has the lowest priority. It means if two rules in different categories
|
||||
# match a given resource, the one in the category with the highest priority overrides the
|
||||
# other one.
|
||||
#
|
||||
access_control:
|
||||
# Default policy can either be `allow` or `deny`.
|
||||
# It is the policy applied to any resource if it has not been overriden
|
||||
# in the `any`, `groups` or `users` category.
|
||||
default_policy: deny
|
||||
|
||||
# The rules that apply to anyone.
|
||||
# The value is a list of rules.
|
||||
any:
|
||||
- domain: public.test.local
|
||||
policy: allow
|
||||
|
||||
# Group-based rules. The key is a group name and the value
|
||||
# is a list of rules.
|
||||
groups:
|
||||
admin:
|
||||
# All resources in all domains
|
||||
- domain: '*.test.local'
|
||||
policy: allow
|
||||
# Except mx2.mail.test.local (it restricts the first rule)
|
||||
- domain: 'mx2.mail.test.local'
|
||||
policy: deny
|
||||
dev:
|
||||
- domain: dev.test.local
|
||||
policy: allow
|
||||
resources:
|
||||
- '^/groups/dev/.*$'
|
||||
|
||||
# User-based rules. The key is a user name and the value
|
||||
# is a list of rules.
|
||||
users:
|
||||
john:
|
||||
- domain: dev.test.local
|
||||
policy: allow
|
||||
resources:
|
||||
- '^/users/john/.*$'
|
||||
harry:
|
||||
- domain: dev.test.local
|
||||
policy: allow
|
||||
resources:
|
||||
- '^/users/harry/.*$'
|
||||
bob:
|
||||
- domain: '*.mail.test.local'
|
||||
policy: allow
|
||||
- domain: 'dev.test.local'
|
||||
policy: allow
|
||||
resources:
|
||||
- '^/users/bob/.*$'
|
||||
|
||||
|
||||
# Configuration of session cookies
|
||||
#
|
||||
# The session cookies identify the user once logged in.
|
||||
session:
|
||||
# The secret to encrypt the session cookie.
|
||||
secret: unsecure_session_secret
|
||||
|
||||
# The time in ms before the cookie expires and session is reset.
|
||||
expiration: 3600000 # 1 hour
|
||||
|
||||
# The inactivity time in ms before the session is reset.
|
||||
inactivity: 300000 # 5 minutes
|
||||
|
||||
# The domain to protect.
|
||||
# Note: the authenticator must also be in that domain. If empty, the cookie
|
||||
# is restricted to the subdomain of the issuer.
|
||||
domain: test.local
|
||||
|
||||
# The redis connection details
|
||||
redis:
|
||||
host: redis
|
||||
port: 6379
|
||||
|
||||
# Configuration of the authentication regulation mechanism.
|
||||
#
|
||||
# This mechanism prevents attackers from brute forcing the first factor.
|
||||
# It bans the user if too many attempts are done in a short period of
|
||||
# time.
|
||||
regulation:
|
||||
# The number of failed login attempts before user is banned.
|
||||
# Set it to 0 for disabling regulation.
|
||||
max_retries: 3
|
||||
|
||||
# The length of time between login attempts before user is banned.
|
||||
find_time: 15
|
||||
|
||||
# The length of time before a banned user can login again.
|
||||
ban_time: 4
|
||||
|
||||
# Configuration of the storage backend used to store data and secrets.
|
||||
#
|
||||
# You must use only an available configuration: local, mongo
|
||||
storage:
|
||||
# The directory where the DB files will be saved
|
||||
# local: /var/lib/authelia/store
|
||||
|
||||
# Settings to connect to mongo server
|
||||
mongo:
|
||||
url: mongodb://mongo/authelia
|
||||
|
||||
# Configuration of the notification system.
|
||||
#
|
||||
# Notifications are sent to users when they require a password reset, a u2f
|
||||
# registration or a TOTP registration.
|
||||
# Use only an available configuration: filesystem, gmail
|
||||
notifier:
|
||||
# For testing purpose, notifications can be sent in a file
|
||||
# filesystem:
|
||||
# filename: /tmp/authelia/notification.txt
|
||||
|
||||
# Use your gmail account to send the notifications. You can use an app password.
|
||||
# gmail:
|
||||
# username: user@example.com
|
||||
# password: yourpassword
|
||||
# sender: admin@example.com
|
||||
|
||||
# Use a SMTP server for sending notifications
|
||||
smtp:
|
||||
username: test
|
||||
password: password
|
||||
secure: false
|
||||
host: 'smtp'
|
||||
port: 1025
|
||||
sender: admin@example.com
|
|
@ -52,7 +52,7 @@
|
|||
mx2.main.test.local <a href="https://mx2.mail.test.local:8080/secret.html"> / secret.html</a>
|
||||
</li>
|
||||
<li>
|
||||
basicauth.test.local <a href="https://basicauth.test.local:8080/secret.html"> / secret.html</a>
|
||||
single_factor.test.local <a href="https://single_factor.test.local:8080/secret.html"> / secret.html</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
|
|
@ -244,9 +244,9 @@ http {
|
|||
|
||||
server {
|
||||
listen 443 ssl;
|
||||
root /usr/share/nginx/html/basicauth.test.local;
|
||||
root /usr/share/nginx/html/single_factor.test.local;
|
||||
|
||||
server_name basicauth.test.local;
|
||||
server_name single_factor.test.local;
|
||||
|
||||
ssl on;
|
||||
ssl_certificate /etc/ssl/server.crt;
|
||||
|
|
|
@ -16,6 +16,3 @@ block content
|
|||
a(href=reset_password_request_endpoint, class="pull-right link forgot-password") Forgot password?
|
||||
<span class="clearfix"></span>
|
||||
</form>
|
||||
|
||||
block entrypoint
|
||||
<script>authelia.firstfactor();</script>
|
|
@ -4,6 +4,8 @@ html
|
|||
head
|
||||
title Authelia - 2FA
|
||||
meta(name="viewport", content="width=device-width, initial-scale=1.0")/
|
||||
meta(name="robots", content="noindex, nofollow, nosnippet, noarchive")/
|
||||
meta(http-equiv="Content-Security-Policy", content="default-src 'self'; img-src 'self' data:;")/
|
||||
link(rel="icon", href="/img/icon.png" type="image/png" sizes="32x32")/
|
||||
link(rel="stylesheet", type="text/css", href="/css/authelia.css")/
|
||||
if redirection_url
|
||||
|
@ -26,5 +28,5 @@ html
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
script(src="/js/authelia.js")
|
||||
block entrypoint
|
||||
script(src="/js/authelia.js")
|
|
@ -18,6 +18,3 @@ block content
|
|||
<button id="reset-password-button" class="btn btn-lg btn-primary btn-block" type="submit">Reset Password</button>
|
||||
<span class="clearfix"></span>
|
||||
</form>
|
||||
|
||||
block entrypoint
|
||||
<script>authelia.reset_password_form();</script>
|
||||
|
|
|
@ -17,7 +17,3 @@ block content
|
|||
<button id="reset-password-button" class="btn btn-lg btn-primary btn-block" type="submit">Reset Password</button>
|
||||
<span class="clearfix"></span>
|
||||
</form>
|
||||
|
||||
block entrypoint
|
||||
<script>authelia.reset_password_request();</script>
|
||||
|
||||
|
|
|
@ -22,8 +22,3 @@ block content
|
|||
a(href=u2f_identity_start_endpoint, class="pull-right link register-u2f") Need to register?
|
||||
<span class="clearfix"></span>
|
||||
</form>
|
||||
|
||||
block entrypoint
|
||||
<script>
|
||||
| authelia.secondfactor();
|
||||
</script>
|
|
@ -14,6 +14,3 @@ block content
|
|||
|
||||
block entrypoint
|
||||
<script src="/js/qrcode.min.js"></script>
|
||||
<script>
|
||||
| authelia.register_totp();
|
||||
</script>
|
||||
|
|
|
@ -9,6 +9,3 @@ block form-header
|
|||
|
||||
block content
|
||||
<img src="/img/pendrive.png" alt="pendrive" />
|
||||
|
||||
block entrypoint
|
||||
<script>window.authelia.register_u2f()</script>
|
||||
|
|
|
@ -17,7 +17,7 @@ Feature: User has access restricted access to domains
|
|||
| https://dev.test.local:8080/users/bob/secret.html |
|
||||
| https://admin.test.local:8080/secret.html |
|
||||
| https://mx1.mail.test.local:8080/secret.html |
|
||||
| https://basicauth.test.local:8080/secret.html |
|
||||
| https://single_factor.test.local:8080/secret.html |
|
||||
And I have no access to:
|
||||
| url |
|
||||
| https://mx2.mail.test.local:8080/secret.html |
|
||||
|
@ -42,7 +42,7 @@ Feature: User has access restricted access to domains
|
|||
| https://admin.test.local:8080/secret.html |
|
||||
| https://dev.test.local:8080/users/john/secret.html |
|
||||
| https://dev.test.local:8080/users/harry/secret.html |
|
||||
| https://basicauth.test.local:8080/secret.html |
|
||||
| https://single_factor.test.local:8080/secret.html |
|
||||
|
||||
@need-registered-user-harry
|
||||
Scenario: User harry has restricted access
|
||||
|
@ -64,4 +64,4 @@ Feature: User has access restricted access to domains
|
|||
| https://dev.test.local:8080/users/john/secret.html |
|
||||
| https://mx1.mail.test.local:8080/secret.html |
|
||||
| https://mx2.mail.test.local:8080/secret.html |
|
||||
| https://basicauth.test.local:8080/secret.html |
|
||||
| https://single_factor.test.local:8080/secret.html |
|
||||
|
|
|
@ -2,10 +2,10 @@ Feature: User is redirected when factors are already validated
|
|||
|
||||
@need-registered-user-john
|
||||
Scenario: User has validated first factor and tries to access service protected by second factor. He is then redirect to second factor step.
|
||||
When I visit "https://basicauth.test.local:8080/secret.html"
|
||||
And I'm redirected to "https://auth.test.local:8080/?redirect=https%3A%2F%2Fbasicauth.test.local%3A8080%2Fsecret.html"
|
||||
When I visit "https://single_factor.test.local:8080/secret.html"
|
||||
And I'm redirected to "https://auth.test.local:8080/?redirect=https%3A%2F%2Fsingle_factor.test.local%3A8080%2Fsecret.html"
|
||||
And I login with user "john" and password "password"
|
||||
And I'm redirected to "https://basicauth.test.local:8080/secret.html"
|
||||
And I'm redirected to "https://single_factor.test.local:8080/secret.html"
|
||||
And I visit "https://public.test.local:8080/secret.html"
|
||||
Then I'm redirected to "https://auth.test.local:8080/secondfactor?redirect=https%3A%2F%2Fpublic.test.local%3A8080%2Fsecret.html"
|
||||
|
||||
|
|
|
@ -2,9 +2,9 @@ Feature: User can access certain subdomains with single factor
|
|||
|
||||
@need-registered-user-john
|
||||
Scenario: User is redirected to service after first factor if allowed
|
||||
When I visit "https://auth.test.local:8080/?redirect=https%3A%2F%2Fbasicauth.test.local%3A8080%2Fsecret.html"
|
||||
When I visit "https://auth.test.local:8080/?redirect=https%3A%2F%2Fsingle_factor.test.local%3A8080%2Fsecret.html"
|
||||
And I login with user "john" and password "password"
|
||||
Then I'm redirected to "https://basicauth.test.local:8080/secret.html"
|
||||
Then I'm redirected to "https://single_factor.test.local:8080/secret.html"
|
||||
|
||||
@need-registered-user-john
|
||||
Scenario: Redirection after first factor fails if single_factor not allowed. It redirects user to first factor.
|
||||
|
|
Loading…
Reference in New Issue