mirror of
https://github.com/mail-in-a-box/mailinabox.git
synced 2026-03-12 17:07:23 +01:00
Compare commits
52 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0c0a079354 | ||
|
|
42e86610ba | ||
|
|
7c62f4b8e9 | ||
|
|
1eba7b0616 | ||
|
|
9c7820f422 | ||
|
|
87ec4e9f82 | ||
|
|
08becf7fa3 | ||
|
|
5eb4a53de1 | ||
|
|
598ade3f7a | ||
|
|
8f399df5bb | ||
|
|
ae73dc5d30 | ||
|
|
c409b2efd0 | ||
|
|
6961840c0e | ||
|
|
6162a9637c | ||
|
|
47c968e71b | ||
|
|
ed3e2aa712 | ||
|
|
fe597da7aa | ||
|
|
61e9888a85 | ||
|
|
35fed8606e | ||
|
|
ef6f121491 | ||
|
|
ec3aab0eaa | ||
|
|
8c69b9e261 | ||
|
|
e7150e3bc6 | ||
|
|
8d6d84d87f | ||
|
|
a6a1cc7ae0 | ||
|
|
b5c0736d27 | ||
|
|
8ee7de6ff3 | ||
|
|
0088fb4553 | ||
|
|
b2d103145f | ||
|
|
fc9e279cec | ||
|
|
257983d559 | ||
|
|
e924459140 | ||
|
|
441bd35053 | ||
|
|
a0e603a3c6 | ||
|
|
88604074d6 | ||
|
|
d43111eb48 | ||
|
|
6729588d8c | ||
|
|
5f14eca67f | ||
|
|
8944cd7980 | ||
|
|
2bbbc9dfa3 | ||
|
|
544f155948 | ||
|
|
f080eabb3a | ||
|
|
7bf377eed1 | ||
|
|
cd554cf480 | ||
|
|
e5448405ae | ||
|
|
a7eff8fb35 | ||
|
|
341aa8695a | ||
|
|
5efdd72f41 | ||
|
|
f25801e88d | ||
|
|
cc7be13098 | ||
|
|
2556e3fbc2 | ||
|
|
4dd4b4232a |
70
CHANGELOG.md
70
CHANGELOG.md
@@ -1,6 +1,76 @@
|
|||||||
CHANGELOG
|
CHANGELOG
|
||||||
=========
|
=========
|
||||||
|
|
||||||
|
v0.27 (June 14, 2018)
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
* A report of box activity, including sent/received mail totals and logins by user, is now emailed to the box's administrator user each week.
|
||||||
|
* Update Roundcube to version 1.3.6 and Z-Push to version 2.3.9.
|
||||||
|
* The undocumented feature for proxying web requests to another server now sets X-Forwarded-For.
|
||||||
|
|
||||||
|
v0.26c (February 13, 2018)
|
||||||
|
--------------------------
|
||||||
|
|
||||||
|
Setup:
|
||||||
|
|
||||||
|
* Upgrades from v0.21c (February 1, 2017) or earlier were broken because the intermediate versions of ownCloud used in setup were no longer available from ownCloud.
|
||||||
|
* Some download errors had no output --- there is more output on error now.
|
||||||
|
|
||||||
|
Control Panel:
|
||||||
|
|
||||||
|
* The background service for the control panel was not restarting on updates, leaving the old version running. This was broken in v0.26 and is now fixed.
|
||||||
|
* Installing your own TLS/SSL certificate had been broken since v0.24 because the new version of openssl became stricter about CSR generation parameters.
|
||||||
|
* Fixed password length help text.
|
||||||
|
|
||||||
|
Contacts/Calendar:
|
||||||
|
|
||||||
|
* Upgraded Nextcloud from 12.0.3 to 12.0.5.
|
||||||
|
|
||||||
|
v0.26b (January 25, 2018)
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
* Fix new installations which broke at the step of asking for the user's desired email address, which was broken by v0.26's changes related to the control panel.
|
||||||
|
* Fix the provisioning of TLS certificates by pinning a Python package we rely on (acme) to an earlier version because our code isn't yet compatible with its current version.
|
||||||
|
* Reduce munin's log_level from debug to warning to prevent massive log files.
|
||||||
|
|
||||||
|
v0.26 (January 18, 2018)
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
Security:
|
||||||
|
|
||||||
|
* HTTPS, IMAP, and POP's TLS settings have been updated to Mozilla's intermediate cipher list recommendation. Some extremely old devices that use less secure TLS ciphers may no longer be able to connect to IMAP/POP.
|
||||||
|
* Updated web HSTS header to use longer six month duration.
|
||||||
|
|
||||||
|
Mail:
|
||||||
|
|
||||||
|
* Adding attachments in Roundcube broke after the last update for some users after rebooting because a temporary directory was deleted on reboot. The temporary directory is now moved from /tmp to /var so that it is persistent.
|
||||||
|
* `X-Spam-Score` header is added to incoming mail.
|
||||||
|
|
||||||
|
Control panel:
|
||||||
|
|
||||||
|
* RSASHA256 is now used for DNSSEC for .lv domains.
|
||||||
|
* Some documentation/links improvements.
|
||||||
|
|
||||||
|
Installer:
|
||||||
|
|
||||||
|
* We now run `apt-get autoremove` at the start of setup to clear out old packages, especially old kernels that take up a lot of space. On the first run, this step may take a long time.
|
||||||
|
* We now fetch Z-Push from its tagged git repository, fixing an installation problem.
|
||||||
|
* Some old PHP5 packages are removed from setup, fixing an installation bug where Apache would get installed.
|
||||||
|
* Python 3 packages for the control panel are now installed using a virtualenv to prevent installation errors due to conflicts in the cryptography/openssl packages between OS-installed packages and pip-installed packages.
|
||||||
|
|
||||||
|
v0.25 (November 15, 2017)
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
This update is a security update addressing [CVE-2017-16651, a vulnerability in Roundcube webmail that allows logged-in users to access files on the local filesystem](https://roundcube.net/news/2017/11/08/security-updates-1.3.3-1.2.7-and-1.1.10).
|
||||||
|
|
||||||
|
Mail:
|
||||||
|
|
||||||
|
* Update to Roundcube 1.3.3.
|
||||||
|
|
||||||
|
Control Panel:
|
||||||
|
|
||||||
|
* Allow custom DNS records to be set for DNS wildcard subdomains (i.e. `*`).
|
||||||
|
|
||||||
v0.24 (October 3, 2017)
|
v0.24 (October 3, 2017)
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,50 @@
|
|||||||
|
# Contributing
|
||||||
|
|
||||||
|
Mail-in-a-Box is an open source project. Your contributions and pull requests are welcome.
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
To start developing Mail-in-a-Box, [clone the repository](https://github.com/mail-in-a-box/mailinabox) and familiarize yourself with the code.
|
||||||
|
|
||||||
|
$ git clone https://github.com/mail-in-a-box/mailinabox
|
||||||
|
|
||||||
|
### Vagrant and VirtualBox
|
||||||
|
|
||||||
|
We recommend you use [Vagrant](https://www.vagrantup.com/intro/getting-started/install.html) and [VirtualBox](https://www.virtualbox.org/wiki/Downloads) for development. Please install them first.
|
||||||
|
|
||||||
|
With Vagrant set up, the following should boot up Mail-in-a-Box inside a virtual machine:
|
||||||
|
|
||||||
|
$ vagrant up --provision
|
||||||
|
|
||||||
|
_If you're seeing an error message about your *IP address being listed in the Spamhaus Block List*, simply uncomment the `export SKIP_NETWORK_CHECKS=1` line in `Vagrantfile`. It's normal, you're probably using a dynamic IP address assigned by your Internet provider–they're almost all listed._
|
||||||
|
|
||||||
|
### Modifying your `hosts` file
|
||||||
|
|
||||||
|
After a while, Mail-in-a-Box will be available at `192.168.50.4` (unless you changed that in your `Vagrantfile`). To be able to use the web-based bits, we recommend to add a hostname to your `hosts` file:
|
||||||
|
|
||||||
|
$ echo "192.168.50.4 mailinabox.lan" | sudo tee -a /etc/hosts
|
||||||
|
|
||||||
|
You should now be able to navigate to https://mailinabox.lan/admin using your browser. There should be an initial admin user with the name `me@mailinabox.lan` and the password `12345678`.
|
||||||
|
|
||||||
|
### Making changes
|
||||||
|
|
||||||
|
Your working copy of Mail-in-a-Box will be mounted inside your VM at `/vagrant`. Any change you make locally will appear inside your VM automatically.
|
||||||
|
|
||||||
|
Running `vagrant up --provision` again will repeat the installation with your modifications.
|
||||||
|
|
||||||
|
Alternatively, you can also ssh into the VM using:
|
||||||
|
|
||||||
|
$ vagrant ssh
|
||||||
|
|
||||||
|
Once inside the VM, you can re-run individual parts of the setup like in this example:
|
||||||
|
|
||||||
|
vm$ cd /vagrant
|
||||||
|
vm$ sudo setup/owncloud.sh # replace with script you'd like to re-run
|
||||||
|
|
||||||
|
### Tests
|
||||||
|
|
||||||
|
Mail-in-a-Box needs more tests. If you're still looking for a way to help out, writing and contributing tests would be a great start!
|
||||||
|
|
||||||
## Public domain
|
## Public domain
|
||||||
|
|
||||||
This project is in the public domain. Copyright and related rights in the work worldwide are waived through the [CC0 1.0 Universal public domain dedication][CC0]. See the LICENSE file in this directory.
|
This project is in the public domain. Copyright and related rights in the work worldwide are waived through the [CC0 1.0 Universal public domain dedication][CC0]. See the LICENSE file in this directory.
|
||||||
|
|||||||
10
README.md
10
README.md
@@ -59,7 +59,7 @@ by me:
|
|||||||
$ curl -s https://keybase.io/joshdata/key.asc | gpg --import
|
$ curl -s https://keybase.io/joshdata/key.asc | gpg --import
|
||||||
gpg: key C10BDD81: public key "Joshua Tauberer <jt@occams.info>" imported
|
gpg: key C10BDD81: public key "Joshua Tauberer <jt@occams.info>" imported
|
||||||
|
|
||||||
$ git verify-tag v0.24
|
$ git verify-tag v0.27
|
||||||
gpg: Signature made ..... using RSA key ID C10BDD81
|
gpg: Signature made ..... using RSA key ID C10BDD81
|
||||||
gpg: Good signature from "Joshua Tauberer <jt@occams.info>"
|
gpg: Good signature from "Joshua Tauberer <jt@occams.info>"
|
||||||
gpg: WARNING: This key is not certified with a trusted signature!
|
gpg: WARNING: This key is not certified with a trusted signature!
|
||||||
@@ -72,7 +72,7 @@ and on my [personal homepage](https://razor.occams.info/). (Of course, if this r
|
|||||||
|
|
||||||
Checkout the tag corresponding to the most recent release:
|
Checkout the tag corresponding to the most recent release:
|
||||||
|
|
||||||
$ git checkout v0.24
|
$ git checkout v0.27
|
||||||
|
|
||||||
Begin the installation.
|
Begin the installation.
|
||||||
|
|
||||||
@@ -82,6 +82,12 @@ For help, DO NOT contact me directly --- I don't do tech support by email or twe
|
|||||||
|
|
||||||
Post your question on the [discussion forum](https://discourse.mailinabox.email/) instead, where me and other Mail-in-a-Box users may be able to help you.
|
Post your question on the [discussion forum](https://discourse.mailinabox.email/) instead, where me and other Mail-in-a-Box users may be able to help you.
|
||||||
|
|
||||||
|
Contributing and Development
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
Mail-in-a-Box is an open source project. Your contributions and pull requests are welcome. See [CONTRIBUTING](CONTRIBUTING.md) to get started.
|
||||||
|
|
||||||
|
|
||||||
The Acknowledgements
|
The Acknowledgements
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
PATH=/sbin:/usr/sbin:/bin:/usr/bin
|
PATH=/sbin:/usr/sbin:/bin:/usr/bin
|
||||||
DESC="Mail-in-a-Box Management Daemon"
|
DESC="Mail-in-a-Box Management Daemon"
|
||||||
NAME=mailinabox
|
NAME=mailinabox
|
||||||
DAEMON=/usr/local/bin/mailinabox-daemon
|
DAEMON=/usr/local/lib/mailinabox/start
|
||||||
PIDFILE=/var/run/$NAME.pid
|
PIDFILE=/var/run/$NAME.pid
|
||||||
SCRIPTNAME=/etc/init.d/$NAME
|
SCRIPTNAME=/etc/init.d/$NAME
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,6 @@
|
|||||||
add_header X-Frame-Options "DENY";
|
add_header X-Frame-Options "DENY";
|
||||||
add_header X-Content-Type-Options nosniff;
|
add_header X-Content-Type-Options nosniff;
|
||||||
add_header Content-Security-Policy "frame-ancestors 'none';";
|
add_header Content-Security-Policy "frame-ancestors 'none';";
|
||||||
add_header Strict-Transport-Security max-age=31536000;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Nextcloud configuration.
|
# Nextcloud configuration.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# from: https://gist.github.com/konklone/6532544
|
# from https://gist.github.com/konklone/6532544 and https://mozilla.github.io/server-side-tls/ssl-config-generator/
|
||||||
###################################################################################
|
###################################################################################################################
|
||||||
|
|
||||||
# Basically the nginx configuration I use at konklone.com.
|
# Basically the nginx configuration I use at konklone.com.
|
||||||
# I check it using https://www.ssllabs.com/ssltest/analyze.html?d=konklone.com
|
# I check it using https://www.ssllabs.com/ssltest/analyze.html?d=konklone.com
|
||||||
@@ -27,17 +27,17 @@
|
|||||||
#
|
#
|
||||||
# Reference client: https://www.ssllabs.com/ssltest/analyze.html
|
# Reference client: https://www.ssllabs.com/ssltest/analyze.html
|
||||||
ssl_prefer_server_ciphers on;
|
ssl_prefer_server_ciphers on;
|
||||||
ssl_ciphers 'kEECDH+ECDSA+AES128 kEECDH+ECDSA+AES256 kEECDH+AES128 kEECDH+AES256 kEDH+AES128 kEDH+AES256 DES-CBC3-SHA +SHA !aNULL !eNULL !LOW !MD5 !EXP !DSS !PSK !SRP !kECDH !CAMELLIA !RC4 !SEED';
|
ssl_ciphers 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS';
|
||||||
|
|
||||||
# Cut out (the old, broken) SSLv3 entirely.
|
# Cut out (the old, broken) SSLv3 entirely.
|
||||||
# This **excludes IE6 users** and (apparently) Yandexbot.
|
# This **excludes IE6 users** and (apparently) Yandexbot.
|
||||||
# Just comment out if you need to support IE6, bless your soul.
|
# Just comment out if you need to support IE6, bless your soul.
|
||||||
ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
|
ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
|
||||||
|
|
||||||
# Turn on session resumption, using a 10 min cache shared across nginx processes,
|
# Turn on session resumption, using a cache shared across nginx processes,
|
||||||
# as recommended by http://nginx.org/en/docs/http/configuring_https_servers.html
|
# as recommended by http://nginx.org/en/docs/http/configuring_https_servers.html
|
||||||
ssl_session_cache shared:SSL:10m;
|
ssl_session_cache shared:SSL:50m;
|
||||||
ssl_session_timeout 10m;
|
ssl_session_timeout 1d;
|
||||||
#keepalive_timeout 70; # in Ubuntu 14.04/nginx 1.4.6 the default is 65, so plenty good
|
#keepalive_timeout 70; # in Ubuntu 14.04/nginx 1.4.6 the default is 65, so plenty good
|
||||||
|
|
||||||
# Buffer size of 1400 bytes fits in one MTU.
|
# Buffer size of 1400 bytes fits in one MTU.
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#!/usr/bin/python3
|
#!/usr/local/lib/mailinabox/env/bin/python
|
||||||
|
|
||||||
# This script performs a backup of all user data:
|
# This script performs a backup of all user data:
|
||||||
# 1) System services are stopped.
|
# 1) System services are stopped.
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
#!/usr/bin/python3
|
|
||||||
|
|
||||||
import os, os.path, re, json, time
|
import os, os.path, re, json, time
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,12 @@ export LC_ALL=en_US.UTF-8
|
|||||||
export LANG=en_US.UTF-8
|
export LANG=en_US.UTF-8
|
||||||
export LC_TYPE=en_US.UTF-8
|
export LC_TYPE=en_US.UTF-8
|
||||||
|
|
||||||
|
# On Mondays, i.e. once a week, send the administrator a report of total emails
|
||||||
|
# sent and received so the admin might notice server abuse.
|
||||||
|
if [ `date "+%u"` -eq 1 ]; then
|
||||||
|
management/mail_log.py -t week | management/email_administrator.py "Mail-in-a-Box Usage Report"
|
||||||
|
fi
|
||||||
|
|
||||||
# Take a backup.
|
# Take a backup.
|
||||||
management/backup.py | management/email_administrator.py "Backup Status"
|
management/backup.py | management/email_administrator.py "Backup Status"
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#!/usr/bin/python3
|
#!/usr/local/lib/mailinabox/env/bin/python
|
||||||
|
|
||||||
# Creates DNS zone files for all of the domains of all of the mail users
|
# Creates DNS zone files for all of the domains of all of the mail users
|
||||||
# and mail aliases and restarts nsd.
|
# and mail aliases and restarts nsd.
|
||||||
@@ -14,9 +14,9 @@ from utils import shell, load_env_vars_from_file, safe_domain_name, sort_domains
|
|||||||
|
|
||||||
# From https://stackoverflow.com/questions/3026957/how-to-validate-a-domain-name-using-regex-php/16491074#16491074
|
# From https://stackoverflow.com/questions/3026957/how-to-validate-a-domain-name-using-regex-php/16491074#16491074
|
||||||
# This regular expression matches domain names according to RFCs, it also accepts fqdn with an leading dot,
|
# This regular expression matches domain names according to RFCs, it also accepts fqdn with an leading dot,
|
||||||
# as well as underscores which are allowed in domain names but not hostnames (i.e. allowed in
|
# underscores, as well as asteriks which are allowed in domain names but not hostnames (i.e. allowed in
|
||||||
# DNS but not in URLs), which are common in certain record types like for DKIM.
|
# DNS but not in URLs), which are common in certain record types like for DKIM.
|
||||||
DOMAIN_RE = "^(?!\-)(?:[a-zA-Z\d\-_]{0,62}[a-zA-Z\d_]\.){1,126}(?!\d+)[a-zA-Z\d_]{1,63}(\.?)$"
|
DOMAIN_RE = "^(?!\-)(?:[*][.])?(?:[a-zA-Z\d\-_]{0,62}[a-zA-Z\d_]\.){1,126}(?!\d+)[a-zA-Z\d_]{1,63}(\.?)$"
|
||||||
|
|
||||||
def get_dns_domains(env):
|
def get_dns_domains(env):
|
||||||
# Add all domain names in use by email users and mail aliases and ensure
|
# Add all domain names in use by email users and mail aliases and ensure
|
||||||
@@ -528,12 +528,13 @@ zone:
|
|||||||
|
|
||||||
def dnssec_choose_algo(domain, env):
|
def dnssec_choose_algo(domain, env):
|
||||||
if '.' in domain and domain.rsplit('.')[-1] in \
|
if '.' in domain and domain.rsplit('.')[-1] in \
|
||||||
("email", "guide", "fund", "be"):
|
("email", "guide", "fund", "be", "lv"):
|
||||||
# At GoDaddy, RSASHA256 is the only algorithm supported
|
# At GoDaddy, RSASHA256 is the only algorithm supported
|
||||||
# for .email and .guide.
|
# for .email and .guide.
|
||||||
# A variety of algorithms are supported for .fund. This
|
# A variety of algorithms are supported for .fund. This
|
||||||
# is preferred.
|
# is preferred.
|
||||||
# Gandi tells me that .be does not support RSASHA1-NSEC3-SHA1
|
# Gandi tells me that .be does not support RSASHA1-NSEC3-SHA1
|
||||||
|
# Nic.lv does not support RSASHA1-NSEC3-SHA1 for .lv tld's
|
||||||
return "RSASHA256"
|
return "RSASHA256"
|
||||||
|
|
||||||
# For any domain we were able to sign before, don't change the algorithm
|
# For any domain we were able to sign before, don't change the algorithm
|
||||||
|
|||||||
@@ -1,11 +1,17 @@
|
|||||||
#!/usr/bin/python3
|
#!/usr/local/lib/mailinabox/env/bin/python
|
||||||
|
|
||||||
# Reads in STDIN. If the stream is not empty, mail it to the system administrator.
|
# Reads in STDIN. If the stream is not empty, mail it to the system administrator.
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
import html
|
||||||
import smtplib
|
import smtplib
|
||||||
from email.message import Message
|
|
||||||
|
from email.mime.multipart import MIMEMultipart
|
||||||
|
from email.mime.text import MIMEText
|
||||||
|
|
||||||
|
# In Python 3.6:
|
||||||
|
#from email.message import Message
|
||||||
|
|
||||||
from utils import load_environment
|
from utils import load_environment
|
||||||
|
|
||||||
@@ -26,11 +32,23 @@ if content == "":
|
|||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
# create MIME message
|
# create MIME message
|
||||||
msg = Message()
|
msg = MIMEMultipart('alternative')
|
||||||
|
|
||||||
|
# In Python 3.6:
|
||||||
|
#msg = Message()
|
||||||
|
|
||||||
msg['From'] = "\"%s\" <%s>" % (env['PRIMARY_HOSTNAME'], admin_addr)
|
msg['From'] = "\"%s\" <%s>" % (env['PRIMARY_HOSTNAME'], admin_addr)
|
||||||
msg['To'] = admin_addr
|
msg['To'] = admin_addr
|
||||||
msg['Subject'] = "[%s] %s" % (env['PRIMARY_HOSTNAME'], subject)
|
msg['Subject'] = "[%s] %s" % (env['PRIMARY_HOSTNAME'], subject)
|
||||||
msg.set_payload(content, "UTF-8")
|
|
||||||
|
content_html = "<html><body><pre>{}</pre></body></html>".format(html.escape(content))
|
||||||
|
|
||||||
|
msg.attach(MIMEText(content, 'plain'))
|
||||||
|
msg.attach(MIMEText(content_html, 'html'))
|
||||||
|
|
||||||
|
# In Python 3.6:
|
||||||
|
#msg.set_content(content)
|
||||||
|
#msg.add_alternative(content_html, "html")
|
||||||
|
|
||||||
# send
|
# send
|
||||||
smtpclient = smtplib.SMTP('127.0.0.1', 25)
|
smtpclient = smtplib.SMTP('127.0.0.1', 25)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#!/usr/bin/python3
|
#!/usr/local/lib/mailinabox/env/bin/python
|
||||||
import argparse
|
import argparse
|
||||||
import datetime
|
import datetime
|
||||||
import gzip
|
import gzip
|
||||||
@@ -53,10 +53,10 @@ VERBOSE = False
|
|||||||
# List of strings to filter users with
|
# List of strings to filter users with
|
||||||
FILTERS = None
|
FILTERS = None
|
||||||
|
|
||||||
# What to show by default
|
# What to show (with defaults)
|
||||||
SCAN_OUT = True # Outgoing email
|
SCAN_OUT = True # Outgoing email
|
||||||
SCAN_IN = True # Incoming email
|
SCAN_IN = True # Incoming email
|
||||||
SCAN_CONN = False # IMAP and POP3 logins
|
SCAN_DOVECOT_LOGIN = True # Dovecot Logins
|
||||||
SCAN_GREY = False # Greylisted email
|
SCAN_GREY = False # Greylisted email
|
||||||
SCAN_BLOCKED = False # Rejected email
|
SCAN_BLOCKED = False # Rejected email
|
||||||
|
|
||||||
@@ -76,7 +76,8 @@ def scan_files(collector):
|
|||||||
tmp_file = tempfile.NamedTemporaryFile()
|
tmp_file = tempfile.NamedTemporaryFile()
|
||||||
shutil.copyfileobj(gzip.open(fn), tmp_file)
|
shutil.copyfileobj(gzip.open(fn), tmp_file)
|
||||||
|
|
||||||
print("Processing file", fn, "...")
|
if VERBOSE:
|
||||||
|
print("Processing file", fn, "...")
|
||||||
fn = tmp_file.name if tmp_file else fn
|
fn = tmp_file.name if tmp_file else fn
|
||||||
|
|
||||||
for line in reverse_readline(fn):
|
for line in reverse_readline(fn):
|
||||||
@@ -105,7 +106,7 @@ def scan_mail_log(env):
|
|||||||
"scan_time": time.time(), # The time in seconds the scan took
|
"scan_time": time.time(), # The time in seconds the scan took
|
||||||
"sent_mail": OrderedDict(), # Data about email sent by users
|
"sent_mail": OrderedDict(), # Data about email sent by users
|
||||||
"received_mail": OrderedDict(), # Data about email received by users
|
"received_mail": OrderedDict(), # Data about email received by users
|
||||||
"dovecot": OrderedDict(), # Data about Dovecot activity
|
"logins": OrderedDict(), # Data about login activity
|
||||||
"postgrey": {}, # Data about greylisting of email addresses
|
"postgrey": {}, # Data about greylisting of email addresses
|
||||||
"rejected": OrderedDict(), # Emails that were blocked
|
"rejected": OrderedDict(), # Emails that were blocked
|
||||||
"known_addresses": None, # Addresses handled by the Miab installation
|
"known_addresses": None, # Addresses handled by the Miab installation
|
||||||
@@ -119,8 +120,8 @@ def scan_mail_log(env):
|
|||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
print("Scanning from {:%Y-%m-%d %H:%M:%S} back to {:%Y-%m-%d %H:%M:%S}".format(
|
print("Scanning logs from {:%Y-%m-%d %H:%M:%S} to {:%Y-%m-%d %H:%M:%S}".format(
|
||||||
START_DATE, END_DATE)
|
END_DATE, START_DATE)
|
||||||
)
|
)
|
||||||
|
|
||||||
# Scan the lines in the log files until the date goes out of range
|
# Scan the lines in the log files until the date goes out of range
|
||||||
@@ -138,8 +139,8 @@ def scan_mail_log(env):
|
|||||||
# Print Sent Mail report
|
# Print Sent Mail report
|
||||||
|
|
||||||
if collector["sent_mail"]:
|
if collector["sent_mail"]:
|
||||||
msg = "Sent email between {:%Y-%m-%d %H:%M:%S} and {:%Y-%m-%d %H:%M:%S}"
|
msg = "Sent email"
|
||||||
print_header(msg.format(END_DATE, START_DATE))
|
print_header(msg)
|
||||||
|
|
||||||
data = OrderedDict(sorted(collector["sent_mail"].items(), key=email_sort))
|
data = OrderedDict(sorted(collector["sent_mail"].items(), key=email_sort))
|
||||||
|
|
||||||
@@ -173,8 +174,8 @@ def scan_mail_log(env):
|
|||||||
# Print Received Mail report
|
# Print Received Mail report
|
||||||
|
|
||||||
if collector["received_mail"]:
|
if collector["received_mail"]:
|
||||||
msg = "Received email between {:%Y-%m-%d %H:%M:%S} and {:%Y-%m-%d %H:%M:%S}"
|
msg = "Received email"
|
||||||
print_header(msg.format(END_DATE, START_DATE))
|
print_header(msg)
|
||||||
|
|
||||||
data = OrderedDict(sorted(collector["received_mail"].items(), key=email_sort))
|
data = OrderedDict(sorted(collector["received_mail"].items(), key=email_sort))
|
||||||
|
|
||||||
@@ -199,43 +200,55 @@ def scan_mail_log(env):
|
|||||||
[accum]
|
[accum]
|
||||||
)
|
)
|
||||||
|
|
||||||
# Print Dovecot report
|
# Print login report
|
||||||
|
|
||||||
if collector["dovecot"]:
|
if collector["logins"]:
|
||||||
msg = "Email client logins between {:%Y-%m-%d %H:%M:%S} and {:%Y-%m-%d %H:%M:%S}"
|
msg = "User logins per hour"
|
||||||
print_header(msg.format(END_DATE, START_DATE))
|
print_header(msg)
|
||||||
|
|
||||||
data = OrderedDict(sorted(collector["dovecot"].items(), key=email_sort))
|
data = OrderedDict(sorted(collector["logins"].items(), key=email_sort))
|
||||||
|
|
||||||
|
# Get a list of all of the protocols seen in the logs in reverse count order.
|
||||||
|
all_protocols = defaultdict(int)
|
||||||
|
for u in data.values():
|
||||||
|
for protocol_name, count in u["totals_by_protocol"].items():
|
||||||
|
all_protocols[protocol_name] += count
|
||||||
|
all_protocols = [k for k, v in sorted(all_protocols.items(), key=lambda kv : -kv[1])]
|
||||||
|
|
||||||
print_user_table(
|
print_user_table(
|
||||||
data.keys(),
|
data.keys(),
|
||||||
data=[
|
data=[
|
||||||
("imap", [u["imap"] for u in data.values()]),
|
(protocol_name, [
|
||||||
("pop3", [u["pop3"] for u in data.values()]),
|
round(u["totals_by_protocol"][protocol_name] / (u["latest"]-u["earliest"]).total_seconds() * 60*60, 1)
|
||||||
|
if (u["latest"]-u["earliest"]).total_seconds() > 0
|
||||||
|
else 0 # prevent division by zero
|
||||||
|
for u in data.values()])
|
||||||
|
for protocol_name in all_protocols
|
||||||
],
|
],
|
||||||
sub_data=[
|
sub_data=[
|
||||||
("IMAP IP addresses", [[k + " (%d)" % v for k, v in u["imap-logins"].items()]
|
("Protocol and Source", [[
|
||||||
for u in data.values()]),
|
"{} {}: {} times".format(protocol_name, host, count)
|
||||||
("POP3 IP addresses", [[k + " (%d)" % v for k, v in u["pop3-logins"].items()]
|
for (protocol_name, host), count
|
||||||
for u in data.values()]),
|
in sorted(u["totals_by_protocol_and_host"].items(), key=lambda kv:-kv[1])
|
||||||
|
] for u in data.values()])
|
||||||
],
|
],
|
||||||
activity=[
|
activity=[
|
||||||
("imap", [u["activity-by-hour"]["imap"] for u in data.values()]),
|
(protocol_name, [u["activity-by-hour"][protocol_name] for u in data.values()])
|
||||||
("pop3", [u["activity-by-hour"]["pop3"] for u in data.values()]),
|
for protocol_name in all_protocols
|
||||||
],
|
],
|
||||||
earliest=[u["earliest"] for u in data.values()],
|
earliest=[u["earliest"] for u in data.values()],
|
||||||
latest=[u["latest"] for u in data.values()],
|
latest=[u["latest"] for u in data.values()],
|
||||||
|
numstr=lambda n : str(round(n, 1)),
|
||||||
)
|
)
|
||||||
|
|
||||||
accum = {"imap": defaultdict(int), "pop3": defaultdict(int), "both": defaultdict(int)}
|
accum = { protocol_name: defaultdict(int) for protocol_name in all_protocols }
|
||||||
for h in range(24):
|
for h in range(24):
|
||||||
accum["imap"][h] = sum(d["activity-by-hour"]["imap"][h] for d in data.values())
|
for protocol_name in all_protocols:
|
||||||
accum["pop3"][h] = sum(d["activity-by-hour"]["pop3"][h] for d in data.values())
|
accum[protocol_name][h] = sum(d["activity-by-hour"][protocol_name][h] for d in data.values())
|
||||||
accum["both"][h] = accum["imap"][h] + accum["pop3"][h]
|
|
||||||
|
|
||||||
print_time_table(
|
print_time_table(
|
||||||
["imap", "pop3", " +"],
|
all_protocols,
|
||||||
[accum["imap"], accum["pop3"], accum["both"]]
|
[accum[protocol_name] for protocol_name in all_protocols]
|
||||||
)
|
)
|
||||||
|
|
||||||
if collector["postgrey"]:
|
if collector["postgrey"]:
|
||||||
@@ -348,9 +361,9 @@ def scan_mail_log_line(line, collector):
|
|||||||
elif service == "postfix/lmtp":
|
elif service == "postfix/lmtp":
|
||||||
if SCAN_IN:
|
if SCAN_IN:
|
||||||
scan_postfix_lmtp_line(date, log, collector)
|
scan_postfix_lmtp_line(date, log, collector)
|
||||||
elif service in ("imap-login", "pop3-login"):
|
elif service.endswith("-login"):
|
||||||
if SCAN_CONN:
|
if SCAN_DOVECOT_LOGIN:
|
||||||
scan_dovecot_line(date, log, collector, service[:4])
|
scan_dovecot_login_line(date, log, collector, service[:4])
|
||||||
elif service == "postgrey":
|
elif service == "postgrey":
|
||||||
if SCAN_GREY:
|
if SCAN_GREY:
|
||||||
scan_postgrey_line(date, log, collector)
|
scan_postgrey_line(date, log, collector)
|
||||||
@@ -448,44 +461,43 @@ def scan_postfix_smtpd_line(date, log, collector):
|
|||||||
collector["rejected"][user] = data
|
collector["rejected"][user] = data
|
||||||
|
|
||||||
|
|
||||||
def scan_dovecot_line(date, log, collector, prot):
|
def scan_dovecot_login_line(date, log, collector, protocol_name):
|
||||||
""" Scan a dovecot log line and extract interesting data """
|
""" Scan a dovecot login log line and extract interesting data """
|
||||||
|
|
||||||
m = re.match("Info: Login: user=<(.*?)>, method=PLAIN, rip=(.*?),", log)
|
m = re.match("Info: Login: user=<(.*?)>, method=PLAIN, rip=(.*?),", log)
|
||||||
|
|
||||||
if m:
|
if m:
|
||||||
# TODO: CHECK DIT
|
# TODO: CHECK DIT
|
||||||
user, rip = m.groups()
|
user, host = m.groups()
|
||||||
|
|
||||||
if user_match(user):
|
if user_match(user):
|
||||||
|
add_login(user, date, protocol_name, host, collector)
|
||||||
|
|
||||||
|
|
||||||
|
def add_login(user, date, protocol_name, host, collector):
|
||||||
# Get the user data, or create it if the user is new
|
# Get the user data, or create it if the user is new
|
||||||
data = collector["dovecot"].get(
|
data = collector["logins"].get(
|
||||||
user,
|
user,
|
||||||
{
|
{
|
||||||
"imap": 0,
|
|
||||||
"pop3": 0,
|
|
||||||
"earliest": None,
|
"earliest": None,
|
||||||
"latest": None,
|
"latest": None,
|
||||||
"imap-logins": defaultdict(int),
|
"totals_by_protocol": defaultdict(int),
|
||||||
"pop3-logins": defaultdict(int),
|
"totals_by_protocol_and_host": defaultdict(int),
|
||||||
"activity-by-hour": {
|
"activity-by-hour": defaultdict(lambda : defaultdict(int)),
|
||||||
"imap": defaultdict(int),
|
|
||||||
"pop3": defaultdict(int),
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
data[prot] += 1
|
|
||||||
data["activity-by-hour"][prot][date.hour] += 1
|
|
||||||
|
|
||||||
if data["latest"] is None:
|
if data["latest"] is None:
|
||||||
data["latest"] = date
|
data["latest"] = date
|
||||||
data["earliest"] = date
|
data["earliest"] = date
|
||||||
|
|
||||||
if rip not in ("127.0.0.1", "::1") or True:
|
data["totals_by_protocol"][protocol_name] += 1
|
||||||
data["%s-logins" % prot][rip] += 1
|
data["totals_by_protocol_and_host"][(protocol_name, host)] += 1
|
||||||
|
|
||||||
collector["dovecot"][user] = data
|
if host not in ("127.0.0.1", "::1") or True:
|
||||||
|
data["activity-by-hour"][protocol_name][date.hour] += 1
|
||||||
|
|
||||||
|
collector["logins"][user] = data
|
||||||
|
|
||||||
|
|
||||||
def scan_postfix_lmtp_line(date, log, collector):
|
def scan_postfix_lmtp_line(date, log, collector):
|
||||||
@@ -561,6 +573,8 @@ def scan_postfix_submission_line(date, log, collector):
|
|||||||
|
|
||||||
collector["sent_mail"][user] = data
|
collector["sent_mail"][user] = data
|
||||||
|
|
||||||
|
# Also log this as a login.
|
||||||
|
add_login(user, date, "smtp", client, collector)
|
||||||
|
|
||||||
# Utility functions
|
# Utility functions
|
||||||
|
|
||||||
@@ -640,7 +654,7 @@ def print_time_table(labels, data, do_print=True):
|
|||||||
for i, d in enumerate(data):
|
for i, d in enumerate(data):
|
||||||
lines[i] += base.format(d[h])
|
lines[i] += base.format(d[h])
|
||||||
|
|
||||||
lines.insert(0, "┬")
|
lines.insert(0, "┬ totals by time of day:")
|
||||||
lines.append("└" + (len(lines[-1]) - 2) * "─")
|
lines.append("└" + (len(lines[-1]) - 2) * "─")
|
||||||
|
|
||||||
if do_print:
|
if do_print:
|
||||||
@@ -650,7 +664,7 @@ def print_time_table(labels, data, do_print=True):
|
|||||||
|
|
||||||
|
|
||||||
def print_user_table(users, data=None, sub_data=None, activity=None, latest=None, earliest=None,
|
def print_user_table(users, data=None, sub_data=None, activity=None, latest=None, earliest=None,
|
||||||
delimit=False):
|
delimit=False, numstr=str):
|
||||||
str_temp = "{:<32} "
|
str_temp = "{:<32} "
|
||||||
lines = []
|
lines = []
|
||||||
data = data or []
|
data = data or []
|
||||||
@@ -764,7 +778,7 @@ def print_user_table(users, data=None, sub_data=None, activity=None, latest=None
|
|||||||
|
|
||||||
# Print totals
|
# Print totals
|
||||||
|
|
||||||
data_accum = [str(a) for a in data_accum]
|
data_accum = [numstr(a) for a in data_accum]
|
||||||
footer = str_temp.format("Totals:" if do_accum else " ")
|
footer = str_temp.format("Totals:" if do_accum else " ")
|
||||||
for row, (l, _) in enumerate(data):
|
for row, (l, _) in enumerate(data):
|
||||||
temp = "{:>%d}" % max(5, len(l) + 1)
|
temp = "{:>%d}" % max(5, len(l) + 1)
|
||||||
@@ -818,7 +832,7 @@ if __name__ == "__main__":
|
|||||||
action="store_true")
|
action="store_true")
|
||||||
parser.add_argument("-s", "--sent", help="Scan for sent emails.",
|
parser.add_argument("-s", "--sent", help="Scan for sent emails.",
|
||||||
action="store_true")
|
action="store_true")
|
||||||
parser.add_argument("-l", "--logins", help="Scan for IMAP/POP logins.",
|
parser.add_argument("-l", "--logins", help="Scan for user logins to IMAP/POP3.",
|
||||||
action="store_true")
|
action="store_true")
|
||||||
parser.add_argument("-g", "--grey", help="Scan for greylisted emails.",
|
parser.add_argument("-g", "--grey", help="Scan for greylisted emails.",
|
||||||
action="store_true")
|
action="store_true")
|
||||||
@@ -863,8 +877,8 @@ if __name__ == "__main__":
|
|||||||
if not SCAN_OUT:
|
if not SCAN_OUT:
|
||||||
print("Ignoring sent emails")
|
print("Ignoring sent emails")
|
||||||
|
|
||||||
SCAN_CONN = args.logins
|
SCAN_DOVECOT_LOGIN = args.logins
|
||||||
if not SCAN_CONN:
|
if not SCAN_DOVECOT_LOGIN:
|
||||||
print("Ignoring logins")
|
print("Ignoring logins")
|
||||||
|
|
||||||
SCAN_GREY = args.grey
|
SCAN_GREY = args.grey
|
||||||
|
|||||||
@@ -1,4 +1,13 @@
|
|||||||
#!/usr/bin/python3
|
#!/usr/local/lib/mailinabox/env/bin/python
|
||||||
|
|
||||||
|
# NOTE:
|
||||||
|
# This script is run both using the system-wide Python 3
|
||||||
|
# interpreter (/usr/bin/python3) as well as through the
|
||||||
|
# virtualenv (/usr/local/lib/mailinabox/env). So only
|
||||||
|
# import packages at the top level of this script that
|
||||||
|
# are installed in *both* contexts. We use the system-wide
|
||||||
|
# Python 3 in setup/questions.sh to validate the email
|
||||||
|
# address entered by the user.
|
||||||
|
|
||||||
import subprocess, shutil, os, sqlite3, re
|
import subprocess, shutil, os, sqlite3, re
|
||||||
import utils
|
import utils
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#!/usr/bin/python3
|
#!/usr/local/lib/mailinabox/env/bin/python
|
||||||
# Utilities for installing and selecting SSL certificates.
|
# Utilities for installing and selecting SSL certificates.
|
||||||
|
|
||||||
import os, os.path, re, shutil
|
import os, os.path, re, shutil
|
||||||
@@ -556,7 +556,7 @@ def create_csr(domain, ssl_key, country_code, env):
|
|||||||
"openssl", "req", "-new",
|
"openssl", "req", "-new",
|
||||||
"-key", ssl_key,
|
"-key", ssl_key,
|
||||||
"-sha256",
|
"-sha256",
|
||||||
"-subj", "/C=%s/ST=/L=/O=/CN=%s" % (country_code, domain)])
|
"-subj", "/C=%s/CN=%s" % (country_code, domain)])
|
||||||
|
|
||||||
def install_cert(domain, ssl_cert, ssl_chain, env, raw=False):
|
def install_cert(domain, ssl_cert, ssl_chain, env, raw=False):
|
||||||
# Write the combined cert+chain to a temporary path and validate that it is OK.
|
# Write the combined cert+chain to a temporary path and validate that it is OK.
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#!/usr/bin/python3
|
#!/usr/local/lib/mailinabox/env/bin/python
|
||||||
#
|
#
|
||||||
# Checks that the upstream DNS has been set correctly and that
|
# Checks that the upstream DNS has been set correctly and that
|
||||||
# TLS certificates have been signed, etc., and if not tells the user
|
# TLS certificates have been signed, etc., and if not tells the user
|
||||||
|
|||||||
@@ -31,8 +31,8 @@
|
|||||||
<label for="customdnsType" class="col-sm-1 control-label">Type</label>
|
<label for="customdnsType" class="col-sm-1 control-label">Type</label>
|
||||||
<div class="col-sm-10">
|
<div class="col-sm-10">
|
||||||
<select id="customdnsType" class="form-control" style="max-width: 400px" onchange="show_customdns_rtype_hint()">
|
<select id="customdnsType" class="form-control" style="max-width: 400px" onchange="show_customdns_rtype_hint()">
|
||||||
<option value="A" data-hint="Enter an IPv4 address (i.e. a dotted quad, such as 123.456.789.012).">A (IPv4 address)</option>
|
<option value="A" data-hint="Enter an IPv4 address (i.e. a dotted quad, such as 123.456.789.012). The 'local' alias sets the record to this box's public IPv4 address.">A (IPv4 address)</option>
|
||||||
<option value="AAAA" data-hint="Enter an IPv6 address.">AAAA (IPv6 address)</option>
|
<option value="AAAA" data-hint="Enter an IPv6 address. The 'local' alias sets the record to this box's public IPv6 address.">AAAA (IPv6 address)</option>
|
||||||
<option value="CAA" data-hint="Enter a CA that can issue certificates for this domain in the form of FLAG TAG VALUE. (0 issuewild "letsencrypt.org")">CAA (Certificate Authority Authorization)</option>
|
<option value="CAA" data-hint="Enter a CA that can issue certificates for this domain in the form of FLAG TAG VALUE. (0 issuewild "letsencrypt.org")">CAA (Certificate Authority Authorization)</option>
|
||||||
<option value="CNAME" data-hint="Enter another domain name followed by a period at the end (e.g. mypage.github.io.).">CNAME (DNS forwarding)</option>
|
<option value="CNAME" data-hint="Enter another domain name followed by a period at the end (e.g. mypage.github.io.).">CNAME (DNS forwarding)</option>
|
||||||
<option value="TXT" data-hint="Enter arbitrary text.">TXT (text record)</option>
|
<option value="TXT" data-hint="Enter arbitrary text.">TXT (text record)</option>
|
||||||
|
|||||||
@@ -159,7 +159,11 @@ function ssl_install(elem) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function show_csr() {
|
function show_csr() {
|
||||||
|
// Can't show a CSR until both inputs are entered.
|
||||||
if ($('#ssldomain').val() == "") return;
|
if ($('#ssldomain').val() == "") return;
|
||||||
|
if ($('#sslcc').val() == "") return;
|
||||||
|
|
||||||
|
// Scroll to it and fetch.
|
||||||
$('#csr_info').slideDown();
|
$('#csr_info').slideDown();
|
||||||
$('#ssl_csr').text('Loading...');
|
$('#ssl_csr').text('Loading...');
|
||||||
api(
|
api(
|
||||||
|
|||||||
@@ -30,7 +30,7 @@
|
|||||||
|
|
||||||
<table class="table">
|
<table class="table">
|
||||||
<thead><tr><th>For...</th> <th>Use...</th></tr></thead>
|
<thead><tr><th>For...</th> <th>Use...</th></tr></thead>
|
||||||
<tr><td>Contacts and Calendar</td> <td><a href="https://play.google.com/store/apps/details?id=at.bitfire.davdroid">DAVdroid</a> ($3.69; free <a href="https://f-droid.org/repository/browse/?fdfilter=dav&fdid=at.bitfire.davdroid">here</a>)</td></tr>
|
<tr><td>Contacts and Calendar</td> <td><a href="https://play.google.com/store/apps/details?id=at.bitfire.davdroid">DAVdroid</a> ($3.69; free <a href="https://f-droid.org/packages/at.bitfire.davdroid/">here</a>)</td></tr>
|
||||||
<tr><td>Only Contacts</td> <td><a href="https://play.google.com/store/apps/details?id=org.dmfs.carddav.sync">CardDAV-Sync free beta</a> (free)</td></tr>
|
<tr><td>Only Contacts</td> <td><a href="https://play.google.com/store/apps/details?id=org.dmfs.carddav.sync">CardDAV-Sync free beta</a> (free)</td></tr>
|
||||||
<tr><td>Only Calendar</td> <td><a href="https://play.google.com/store/apps/details?id=org.dmfs.caldav.lib">CalDAV-Sync</a> ($2.89)</td></tr>
|
<tr><td>Only Calendar</td> <td><a href="https://play.google.com/store/apps/details?id=org.dmfs.caldav.lib">CalDAV-Sync</a> ($2.89)</td></tr>
|
||||||
</table>
|
</table>
|
||||||
|
|||||||
@@ -213,7 +213,7 @@ function users_set_password(elem) {
|
|||||||
|
|
||||||
show_modal_confirm(
|
show_modal_confirm(
|
||||||
"Set Password",
|
"Set Password",
|
||||||
$("<p>Set a new password for <b>" + email + "</b>?</p> <p><label for='users_set_password_pw' style='display: block; font-weight: normal'>New Password:</label><input type='password' id='users_set_password_pw'></p><p><small>Passwords must be at least four characters and may not contain spaces.</small>" + yourpw + "</p>"),
|
$("<p>Set a new password for <b>" + email + "</b>?</p> <p><label for='users_set_password_pw' style='display: block; font-weight: normal'>New Password:</label><input type='password' id='users_set_password_pw'></p><p><small>Passwords must be at least eight characters and may not contain spaces.</small>" + yourpw + "</p>"),
|
||||||
"Set Password",
|
"Set Password",
|
||||||
function() {
|
function() {
|
||||||
api(
|
api(
|
||||||
|
|||||||
@@ -149,7 +149,10 @@ def make_domain_config(domain, templates, ssl_certificates, env):
|
|||||||
|
|
||||||
# any proxy or redirect here?
|
# any proxy or redirect here?
|
||||||
for path, url in yaml.get("proxies", {}).items():
|
for path, url in yaml.get("proxies", {}).items():
|
||||||
nginx_conf_extra += "\tlocation %s {\n\t\tproxy_pass %s;\n\t}\n" % (path, url)
|
nginx_conf_extra += "\tlocation %s {" % path
|
||||||
|
nginx_conf_extra += "\n\t\tproxy_pass %s;" % url
|
||||||
|
nginx_conf_extra += "\n\t\tproxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;"
|
||||||
|
nginx_conf_extra += "\n\t}\n"
|
||||||
for path, url in yaml.get("redirects", {}).items():
|
for path, url in yaml.get("redirects", {}).items():
|
||||||
nginx_conf_extra += "\trewrite %s %s permanent;\n" % (path, url)
|
nginx_conf_extra += "\trewrite %s %s permanent;\n" % (path, url)
|
||||||
|
|
||||||
@@ -158,9 +161,9 @@ def make_domain_config(domain, templates, ssl_certificates, env):
|
|||||||
|
|
||||||
# Add the HSTS header.
|
# Add the HSTS header.
|
||||||
if hsts == "yes":
|
if hsts == "yes":
|
||||||
nginx_conf_extra += "add_header Strict-Transport-Security max-age=31536000;\n"
|
nginx_conf_extra += "add_header Strict-Transport-Security max-age=15768000;\n"
|
||||||
elif hsts == "preload":
|
elif hsts == "preload":
|
||||||
nginx_conf_extra += "add_header Strict-Transport-Security \"max-age=10886400; includeSubDomains; preload\";\n"
|
nginx_conf_extra += "add_header Strict-Transport-Security \"max-age=15768000; includeSubDomains; preload\";\n"
|
||||||
|
|
||||||
# Add in any user customizations in the includes/ folder.
|
# Add in any user customizations in the includes/ folder.
|
||||||
nginx_conf_custom_include = os.path.join(env["STORAGE_ROOT"], "www", safe_domain_name(domain) + ".conf")
|
nginx_conf_custom_include = os.path.join(env["STORAGE_ROOT"], "www", safe_domain_name(domain) + ".conf")
|
||||||
|
|||||||
11
security.md
11
security.md
@@ -40,21 +40,14 @@ The services all follow these rules:
|
|||||||
|
|
||||||
* TLS certificates are generated with 2048-bit RSA keys and SHA-256 fingerprints. The box provides a self-signed certificate by default. The [setup guide](https://mailinabox.email/guide.html) explains how to verify the certificate fingerprint on first login. Users are encouraged to replace the certificate with a proper CA-signed one. ([source](setup/ssl.sh))
|
* TLS certificates are generated with 2048-bit RSA keys and SHA-256 fingerprints. The box provides a self-signed certificate by default. The [setup guide](https://mailinabox.email/guide.html) explains how to verify the certificate fingerprint on first login. Users are encouraged to replace the certificate with a proper CA-signed one. ([source](setup/ssl.sh))
|
||||||
* Only TLSv1, TLSv1.1 and TLSv1.2 are offered (the older SSL protocols are not offered).
|
* Only TLSv1, TLSv1.1 and TLSv1.2 are offered (the older SSL protocols are not offered).
|
||||||
* Export-grade ciphers, the anonymous DH/ECDH algorithms (aNULL), and clear-text ciphers (eNULL) are not offered.
|
* HTTPS, IMAP, and POP track the [Mozilla Intermediate Ciphers Recommendation](https://wiki.mozilla.org/Security/Server_Side_TLS), balancing security with supporting a wide range of mail clients. Diffie-Hellman ciphers use a 2048-bit key for forward secrecy. For more details, see the [output of SSLyze for these ports](tests/tls_results.txt).
|
||||||
* The minimum cipher key length offered is 112 bits. The maximum is 256 bits. Diffie-Hellman ciphers use a 2048-bit key for forward secrecy.
|
* SMTP (port 25) uses the Postfix medium grade ciphers and SMTP Submission (port 587) uses the Postfix high grade ciphers ([more info](http://www.postfix.org/postconf.5.html#smtpd_tls_mandatory_ciphers)).
|
||||||
|
|
||||||
Additionally:
|
Additionally:
|
||||||
|
|
||||||
* SMTP Submission (port 587) will not accept user credentials without STARTTLS (true also of SMTP on port 25 in case of client misconfiguration), and the submission port won't accept mail without encryption. The minimum cipher key length is 128 bits. (The box is of course configured not to be an open relay. User credentials are required to send outbound mail.) ([source](setup/mail-postfix.sh))
|
* SMTP Submission (port 587) will not accept user credentials without STARTTLS (true also of SMTP on port 25 in case of client misconfiguration), and the submission port won't accept mail without encryption. The minimum cipher key length is 128 bits. (The box is of course configured not to be an open relay. User credentials are required to send outbound mail.) ([source](setup/mail-postfix.sh))
|
||||||
* HTTPS (port 443): The HTTPS Strict Transport Security header is set. A redirect from HTTP to HTTPS is offered. The [Qualys SSL Labs test](https://www.ssllabs.com/ssltest) should report an A+ grade. ([source 1](conf/nginx-ssl.conf), [source 2](conf/nginx.conf))
|
* HTTPS (port 443): The HTTPS Strict Transport Security header is set. A redirect from HTTP to HTTPS is offered. The [Qualys SSL Labs test](https://www.ssllabs.com/ssltest) should report an A+ grade. ([source 1](conf/nginx-ssl.conf), [source 2](conf/nginx.conf))
|
||||||
|
|
||||||
For more details, see the [output of SSLyze for these ports](tests/tls_results.txt).
|
|
||||||
|
|
||||||
The cipher and protocol selection are chosen to support the following clients:
|
|
||||||
|
|
||||||
* For HTTPS: Firefox 1, Chrome 1, IE 7, Opera 5, Safari 1, Windows XP IE8, Android 2.3, Java 7.
|
|
||||||
* For other protocols: TBD.
|
|
||||||
|
|
||||||
### Password Storage
|
### Password Storage
|
||||||
|
|
||||||
The passwords for mail users are stored on disk using the [SHA512-CRYPT](http://man7.org/linux/man-pages/man3/crypt.3.html) hashing scheme. ([source](management/mailconfig.py))
|
The passwords for mail users are stored on disk using the [SHA512-CRYPT](http://man7.org/linux/man-pages/man3/crypt.3.html) hashing scheme. ([source](management/mailconfig.py))
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
#########################################################
|
#########################################################
|
||||||
|
|
||||||
if [ -z "$TAG" ]; then
|
if [ -z "$TAG" ]; then
|
||||||
TAG=v0.24
|
TAG=v0.27
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Are we running as root?
|
# Are we running as root?
|
||||||
|
|||||||
@@ -179,7 +179,7 @@ function wget_verify {
|
|||||||
DEST=$3
|
DEST=$3
|
||||||
CHECKSUM="$HASH $DEST"
|
CHECKSUM="$HASH $DEST"
|
||||||
rm -f $DEST
|
rm -f $DEST
|
||||||
wget -q -O $DEST $URL || exit 1
|
hide_output wget -O $DEST $URL
|
||||||
if ! echo "$CHECKSUM" | sha1sum --check --strict > /dev/null; then
|
if ! echo "$CHECKSUM" | sha1sum --check --strict > /dev/null; then
|
||||||
echo "------------------------------------------------------------"
|
echo "------------------------------------------------------------"
|
||||||
echo "Download of $URL did not match expected checksum."
|
echo "Download of $URL did not match expected checksum."
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ apt_install \
|
|||||||
# - https://www.dovecot.org/list/dovecot/2011-December/132455.html
|
# - https://www.dovecot.org/list/dovecot/2011-December/132455.html
|
||||||
tools/editconf.py /etc/dovecot/conf.d/10-master.conf \
|
tools/editconf.py /etc/dovecot/conf.d/10-master.conf \
|
||||||
default_process_limit=$(echo "`nproc` * 250" | bc) \
|
default_process_limit=$(echo "`nproc` * 250" | bc) \
|
||||||
default_vsz_limit=$(echo "`free -tom | tail -1 | awk '{print $2}'` / 3" | bc)M \
|
default_vsz_limit=$(echo "`free -tm | tail -1 | awk '{print $2}'` / 3" | bc)M \
|
||||||
log_path=/var/log/mail.log
|
log_path=/var/log/mail.log
|
||||||
|
|
||||||
# The inotify `max_user_instances` default is 128, which constrains
|
# The inotify `max_user_instances` default is 128, which constrains
|
||||||
@@ -85,7 +85,7 @@ tools/editconf.py /etc/dovecot/conf.d/10-ssl.conf \
|
|||||||
"ssl_cert=<$STORAGE_ROOT/ssl/ssl_certificate.pem" \
|
"ssl_cert=<$STORAGE_ROOT/ssl/ssl_certificate.pem" \
|
||||||
"ssl_key=<$STORAGE_ROOT/ssl/ssl_private_key.pem" \
|
"ssl_key=<$STORAGE_ROOT/ssl/ssl_private_key.pem" \
|
||||||
"ssl_protocols=!SSLv3 !SSLv2" \
|
"ssl_protocols=!SSLv3 !SSLv2" \
|
||||||
"ssl_cipher_list=TLSv1+HIGH !SSLv2 !RC4 !aNULL !eNULL !3DES @STRENGTH" \
|
"ssl_cipher_list=ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS" \
|
||||||
"ssl_prefer_server_ciphers = yes" \
|
"ssl_prefer_server_ciphers = yes" \
|
||||||
"ssl_dh_parameters_length = 2048"
|
"ssl_dh_parameters_length = 2048"
|
||||||
|
|
||||||
|
|||||||
@@ -6,21 +6,33 @@ echo "Installing Mail-in-a-Box system management daemon..."
|
|||||||
|
|
||||||
# DEPENDENCIES
|
# DEPENDENCIES
|
||||||
|
|
||||||
# Install Python packages that are available from the Ubuntu
|
# duplicity is used to make backups of user data. It uses boto
|
||||||
# apt repository:
|
# (via Python 2) to do backups to AWS S3. boto from the Ubuntu
|
||||||
# flask, yaml, dnspython, and dateutil are all for our Python 3 management daemon itself.
|
# package manager is too out-of-date -- it doesn't support the newer
|
||||||
# duplicity does backups. python-pip is so we can 'pip install boto' for Python 2, for duplicity, so it can do backups to AWS S3.
|
# S3 api used in some regions, which breaks backups to those regions.
|
||||||
apt_install python3-flask links duplicity libyaml-dev python3-dnspython python3-dateutil python-pip
|
# See #627, #653.
|
||||||
|
apt_install duplicity python-pip
|
||||||
|
hide_output pip2 install --upgrade boto
|
||||||
|
|
||||||
# These are required to pip install cryptography.
|
# These are required to build/install the cryptography Python package
|
||||||
apt_install build-essential libssl-dev libffi-dev python3-dev
|
# used by our management daemon.
|
||||||
|
apt_install python-virtualenv build-essential libssl-dev libffi-dev python3-dev
|
||||||
|
|
||||||
# pip<6.1 + setuptools>=34 have a problem with packages that
|
# Create a virtualenv for the installation of Python 3 packages
|
||||||
|
# used by the management daemon.
|
||||||
|
inst_dir=/usr/local/lib/mailinabox
|
||||||
|
mkdir -p $inst_dir
|
||||||
|
venv=$inst_dir/env
|
||||||
|
if [ ! -d $venv ]; then
|
||||||
|
virtualenv -ppython3 $venv
|
||||||
|
fi
|
||||||
|
|
||||||
|
# pip<6.1 + setuptools>=34 had a problem with packages that
|
||||||
# try to update setuptools during installation, like cryptography.
|
# try to update setuptools during installation, like cryptography.
|
||||||
# See https://github.com/pypa/pip/issues/4253. The Ubuntu 14.04
|
# See https://github.com/pypa/pip/issues/4253. The Ubuntu 14.04
|
||||||
# package versions are pip 1.5.4 and setuptools 3.3. When we
|
# package versions are pip 1.5.4 and setuptools 3.3. When we used to
|
||||||
# install cryptography under those versions, it tries to update
|
# instal cryptography system-wide under those versions, it updated
|
||||||
# setuptools to version 34, which now creates the conflict, and
|
# setuptools to version 34, which created the conflict, and
|
||||||
# then pip gets permanently broken with errors like
|
# then pip gets permanently broken with errors like
|
||||||
# "ImportError: No module named 'packaging'".
|
# "ImportError: No module named 'packaging'".
|
||||||
#
|
#
|
||||||
@@ -35,8 +47,8 @@ fi
|
|||||||
# The easiest work-around on systems that aren't already broken is
|
# The easiest work-around on systems that aren't already broken is
|
||||||
# to upgrade pip (to >=9.0.1) and setuptools (to >=34.1) individually
|
# to upgrade pip (to >=9.0.1) and setuptools (to >=34.1) individually
|
||||||
# before we install any package that tries to update setuptools.
|
# before we install any package that tries to update setuptools.
|
||||||
hide_output pip3 install --upgrade pip
|
hide_output $venv/bin/pip install --upgrade pip
|
||||||
hide_output pip3 install --upgrade setuptools
|
hide_output $venv/bin/pip install --upgrade setuptools
|
||||||
|
|
||||||
# Install other Python 3 packages used by the management daemon.
|
# Install other Python 3 packages used by the management daemon.
|
||||||
# The first line is the packages that Josh maintains himself!
|
# The first line is the packages that Josh maintains himself!
|
||||||
@@ -44,14 +56,10 @@ hide_output pip3 install --upgrade setuptools
|
|||||||
# Force acme to be updated because it seems to need it after the
|
# Force acme to be updated because it seems to need it after the
|
||||||
# pip/setuptools breakage (see above) and the ACME protocol may
|
# pip/setuptools breakage (see above) and the ACME protocol may
|
||||||
# have changed (I got an error on one of my systems).
|
# have changed (I got an error on one of my systems).
|
||||||
hide_output pip3 install --upgrade \
|
hide_output $venv/bin/pip install --upgrade \
|
||||||
rtyaml "email_validator>=1.0.0" "free_tls_certificates>=0.1.3" "exclusiveprocess" \
|
rtyaml "email_validator>=1.0.0" "free_tls_certificates>=0.1.3" "exclusiveprocess" \
|
||||||
"idna>=2.0.0" "cryptography>=1.0.2" acme boto psutil
|
flask dnspython python-dateutil \
|
||||||
|
"idna>=2.0.0" "cryptography>=1.0.2" "acme==0.20.0" boto psutil
|
||||||
# duplicity uses python 2 so we need to get the python 2 package of boto to have backups to S3.
|
|
||||||
# boto from the Ubuntu package manager is too out-of-date -- it doesn't support the newer
|
|
||||||
# S3 api used in some regions, which breaks backups to those regions. See #627, #653.
|
|
||||||
hide_output pip2 install --upgrade boto
|
|
||||||
|
|
||||||
# CONFIGURATION
|
# CONFIGURATION
|
||||||
|
|
||||||
@@ -65,7 +73,7 @@ fi
|
|||||||
# Download jQuery and Bootstrap local files
|
# Download jQuery and Bootstrap local files
|
||||||
|
|
||||||
# Make sure we have the directory to save to.
|
# Make sure we have the directory to save to.
|
||||||
assets_dir=/usr/local/lib/mailinabox/vendor/assets
|
assets_dir=$inst_dir/vendor/assets
|
||||||
rm -rf $assets_dir
|
rm -rf $assets_dir
|
||||||
mkdir -p $assets_dir
|
mkdir -p $assets_dir
|
||||||
|
|
||||||
@@ -82,16 +90,19 @@ bootstrap_url=https://github.com/twbs/bootstrap/releases/download/v$bootstrap_ve
|
|||||||
|
|
||||||
# Get Bootstrap
|
# Get Bootstrap
|
||||||
wget_verify $bootstrap_url e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a /tmp/bootstrap.zip
|
wget_verify $bootstrap_url e6b1000b94e835ffd37f4c6dcbdad43f4b48a02a /tmp/bootstrap.zip
|
||||||
unzip -q /tmp/bootstrap.zip -d /usr/local/lib/mailinabox/vendor/assets
|
unzip -q /tmp/bootstrap.zip -d $assets_dir
|
||||||
mv /usr/local/lib/mailinabox/vendor/assets/bootstrap-$bootstrap_version-dist /usr/local/lib/mailinabox/vendor/assets/bootstrap
|
mv $assets_dir/bootstrap-$bootstrap_version-dist $assets_dir/bootstrap
|
||||||
rm -f /tmp/bootstrap.zip
|
rm -f /tmp/bootstrap.zip
|
||||||
|
|
||||||
# Link the management server daemon into a well known location.
|
|
||||||
rm -f /usr/local/bin/mailinabox-daemon
|
|
||||||
ln -s `pwd`/management/daemon.py /usr/local/bin/mailinabox-daemon
|
|
||||||
|
|
||||||
# Create an init script to start the management daemon and keep it
|
# Create an init script to start the management daemon and keep it
|
||||||
# running after a reboot.
|
# running after a reboot.
|
||||||
|
rm -f /usr/local/bin/mailinabox-daemon # old path
|
||||||
|
cat > $inst_dir/start <<EOF;
|
||||||
|
#!/bin/bash
|
||||||
|
source $venv/bin/activate
|
||||||
|
exec python `pwd`/management/daemon.py
|
||||||
|
EOF
|
||||||
|
chmod +x $inst_dir/start
|
||||||
rm -f /etc/init.d/mailinabox
|
rm -f /etc/init.d/mailinabox
|
||||||
ln -s $(pwd)/conf/management-initscript /etc/init.d/mailinabox
|
ln -s $(pwd)/conf/management-initscript /etc/init.d/mailinabox
|
||||||
hide_output update-rc.d mailinabox defaults
|
hide_output update-rc.d mailinabox defaults
|
||||||
|
|||||||
@@ -38,8 +38,10 @@ chown munin. /var/log/munin/munin-cgi-html.log
|
|||||||
chown munin. /var/log/munin/munin-cgi-graph.log
|
chown munin. /var/log/munin/munin-cgi-graph.log
|
||||||
|
|
||||||
# ensure munin-node knows the name of this machine
|
# ensure munin-node knows the name of this machine
|
||||||
|
# and reduce logging level to warning
|
||||||
tools/editconf.py /etc/munin/munin-node.conf -s \
|
tools/editconf.py /etc/munin/munin-node.conf -s \
|
||||||
host_name=$PRIMARY_HOSTNAME
|
host_name=$PRIMARY_HOSTNAME \
|
||||||
|
log_level=1
|
||||||
|
|
||||||
# Update the activated plugins through munin's autoconfiguration.
|
# Update the activated plugins through munin's autoconfiguration.
|
||||||
munin-node-configure --shell --remove-also 2>/dev/null | sh
|
munin-node-configure --shell --remove-also 2>/dev/null | sh
|
||||||
|
|||||||
@@ -107,12 +107,12 @@ InstallOwncloud() {
|
|||||||
rm -rf /usr/local/lib/owncloud
|
rm -rf /usr/local/lib/owncloud
|
||||||
|
|
||||||
# Download and verify
|
# Download and verify
|
||||||
wget_verify https://download.owncloud.org/community/owncloud-$version.zip $hash /tmp/owncloud.zip
|
wget_verify https://download.owncloud.org/community/owncloud-$version.tar.bz2 $hash /tmp/owncloud.tar.bz2
|
||||||
|
|
||||||
|
|
||||||
# Extract ownCloud
|
# Extract ownCloud
|
||||||
unzip -q /tmp/owncloud.zip -d /usr/local/lib
|
tar xjf /tmp/owncloud.tar.bz2 -C /usr/local/lib
|
||||||
rm -f /tmp/owncloud.zip
|
rm -f /tmp/owncloud.tar.bz2
|
||||||
|
|
||||||
# The two apps we actually want are not in Nextcloud core. Download the releases from
|
# The two apps we actually want are not in Nextcloud core. Download the releases from
|
||||||
# their github repositories.
|
# their github repositories.
|
||||||
@@ -154,8 +154,8 @@ InstallOwncloud() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
owncloud_ver=12.0.3
|
owncloud_ver=12.0.5
|
||||||
owncloud_hash=beab41f6a748a43f0accfa6a9808387aef718c61
|
owncloud_hash=d25afbac977a4e331f5e38df50aed0844498ca86
|
||||||
|
|
||||||
# Check if Nextcloud dir exist, and check if version matches owncloud_ver (if either doesn't - install/upgrade)
|
# Check if Nextcloud dir exist, and check if version matches owncloud_ver (if either doesn't - install/upgrade)
|
||||||
if [ ! -d /usr/local/lib/owncloud/ ] \
|
if [ ! -d /usr/local/lib/owncloud/ ] \
|
||||||
@@ -183,13 +183,13 @@ if [ ! -d /usr/local/lib/owncloud/ ] \
|
|||||||
# We only need to check if we do upgrades when owncloud/Nextcloud was previously installed
|
# We only need to check if we do upgrades when owncloud/Nextcloud was previously installed
|
||||||
if [ -e /usr/local/lib/owncloud/version.php ]; then
|
if [ -e /usr/local/lib/owncloud/version.php ]; then
|
||||||
if grep -q "OC_VersionString = '8\.1\.[0-9]" /usr/local/lib/owncloud/version.php; then
|
if grep -q "OC_VersionString = '8\.1\.[0-9]" /usr/local/lib/owncloud/version.php; then
|
||||||
echo "We are running 8.1.x, upgrading to 8.2.3 first"
|
echo "We are running 8.1.x, upgrading to 8.2.11 first"
|
||||||
InstallOwncloud 8.2.3 bfdf6166fbf6fc5438dc358600e7239d1c970613
|
InstallOwncloud 8.2.11 e4794938fc2f15a095018ba9d6ee18b53f6f299c
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# If we are upgrading from 8.2.x we should go to 9.0 first. Owncloud doesn't support skipping minor versions
|
# If we are upgrading from 8.2.x we should go to 9.0 first. Owncloud doesn't support skipping minor versions
|
||||||
if grep -q "OC_VersionString = '8\.2\.[0-9]" /usr/local/lib/owncloud/version.php; then
|
if grep -q "OC_VersionString = '8\.2\.[0-9]" /usr/local/lib/owncloud/version.php; then
|
||||||
echo "We are running version 8.2.x, upgrading to 9.0.2 first"
|
echo "We are running version 8.2.x, upgrading to 9.0.11 first"
|
||||||
|
|
||||||
# We need to disable memcached. The upgrade and install fails
|
# We need to disable memcached. The upgrade and install fails
|
||||||
# with memcached
|
# with memcached
|
||||||
@@ -207,8 +207,8 @@ if [ ! -d /usr/local/lib/owncloud/ ] \
|
|||||||
EOF
|
EOF
|
||||||
chown www-data.www-data $STORAGE_ROOT/owncloud/config.php
|
chown www-data.www-data $STORAGE_ROOT/owncloud/config.php
|
||||||
|
|
||||||
# We can now install owncloud 9.0.2
|
# We can now install owncloud 9.0.11
|
||||||
InstallOwncloud 9.0.2 72a3d15d09f58c06fa8bee48b9e60c9cd356f9c5
|
InstallOwncloud 9.0.11 fc8bad8a62179089bc58c406b28997fb0329337b
|
||||||
|
|
||||||
# The owncloud 9 migration doesn't migrate calendars and contacts
|
# The owncloud 9 migration doesn't migrate calendars and contacts
|
||||||
# The option to migrate these are removed in 9.1
|
# The option to migrate these are removed in 9.1
|
||||||
@@ -224,20 +224,26 @@ EOF
|
|||||||
|
|
||||||
# If we are upgrading from 9.0.x we should go to 9.1 first.
|
# If we are upgrading from 9.0.x we should go to 9.1 first.
|
||||||
if grep -q "OC_VersionString = '9\.0\.[0-9]" /usr/local/lib/owncloud/version.php; then
|
if grep -q "OC_VersionString = '9\.0\.[0-9]" /usr/local/lib/owncloud/version.php; then
|
||||||
echo "We are running ownCloud 9.0.x, upgrading to ownCloud 9.1.4 first"
|
echo "We are running ownCloud 9.0.x, upgrading to ownCloud 9.1.7 first"
|
||||||
InstallOwncloud 9.1.4 e637cab7b2ca3346164f3506b1a0eb812b4e841a
|
InstallOwncloud 9.1.7 1307d997d0b23dc42742d315b3e2f11423a9c808
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# If we are upgrading from 9.1.x we should go to Nextcloud 10.0 first.
|
# Newer ownCloud 9.1.x versions cannot be upgraded to Nextcloud 10 and have to be
|
||||||
|
# upgraded to Nextcloud 11 straight away, see:
|
||||||
|
# https://github.com/nextcloud/server/issues/2203
|
||||||
|
# However, for some reason, upgrading to the latest Nextcloud 11.0.7 doesn't
|
||||||
|
# work either. Therefore, we're upgrading to Nextcloud 11.0.0 in the interim.
|
||||||
|
# This should not be a problem since we're upgrading to the latest Nextcloud 12
|
||||||
|
# in the next step.
|
||||||
if grep -q "OC_VersionString = '9\.1\.[0-9]" /usr/local/lib/owncloud/version.php; then
|
if grep -q "OC_VersionString = '9\.1\.[0-9]" /usr/local/lib/owncloud/version.php; then
|
||||||
echo "We are running ownCloud 9.1.x, upgrading to Nextcloud 10.0.5 first"
|
echo "We are running ownCloud 9.1.x, upgrading to Nextcloud 11.0.0 first"
|
||||||
InstallNextcloud 10.0.5 686f6a8e9d7867c32e3bf3ca63b3cc2020564bf6
|
InstallNextcloud 11.0.0 e8c9ebe72a4a76c047080de94743c5c11735e72e
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# If we are upgrading from 10.0.x we should go to Nextcloud 11.0 first.
|
# If we are upgrading from 10.0.x we should go to Nextcloud 11.0 first.
|
||||||
if grep -q "OC_VersionString = '10\.0\.[0-9]" /usr/local/lib/owncloud/version.php; then
|
if grep -q "OC_VersionString = '10\.0\.[0-9]" /usr/local/lib/owncloud/version.php; then
|
||||||
echo "We are running Nextcloud 10.0.x, upgrading to Nextcloud 11.0.3 first"
|
echo "We are running Nextcloud 10.0.x, upgrading to Nextcloud 11.0.7 first"
|
||||||
InstallNextcloud 11.0.3 a396aaa1c9f920099a90a86b4a9cd0ec13083c99
|
InstallNextcloud 11.0.7 f936ddcb2ae3dbb66ee4926eb8b2ebbddc3facbe
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,9 @@ if [ -z "$NONINTERACTIVE" ]; then
|
|||||||
apt_get_quiet install dialog python3 python3-pip || exit 1
|
apt_get_quiet install dialog python3 python3-pip || exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# email_validator is repeated in setup/management.sh
|
# Installing email_validator is repeated in setup/management.sh, but in setup/management.sh
|
||||||
|
# we install it inside a virtualenv. In this script, we don't have the virtualenv yet
|
||||||
|
# so we install the python package globally.
|
||||||
hide_output pip3 install "email_validator>=1.0.0" || exit 1
|
hide_output pip3 install "email_validator>=1.0.0" || exit 1
|
||||||
|
|
||||||
message_box "Mail-in-a-Box Installation" \
|
message_box "Mail-in-a-Box Installation" \
|
||||||
@@ -49,7 +51,7 @@ you really want.
|
|||||||
# user hit ESC/cancel
|
# user hit ESC/cancel
|
||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
while ! management/mailconfig.py validate-email "$EMAIL_ADDR"
|
while ! python3 management/mailconfig.py validate-email "$EMAIL_ADDR"
|
||||||
do
|
do
|
||||||
input_box "Your Email Address" \
|
input_box "Your Email Address" \
|
||||||
"That's not a valid email address.\n\nWhat email address are you setting this box up to manage?" \
|
"That's not a valid email address.\n\nWhat email address are you setting this box up to manage?" \
|
||||||
|
|||||||
@@ -61,10 +61,11 @@ tools/editconf.py /etc/default/spampd \
|
|||||||
# content or execute scripts, and it is probably confusing to most users.
|
# content or execute scripts, and it is probably confusing to most users.
|
||||||
#
|
#
|
||||||
# Tell Spamassassin not to modify the original message except for adding
|
# Tell Spamassassin not to modify the original message except for adding
|
||||||
# the X-Spam-Status mail header and related headers.
|
# the X-Spam-Status & X-Spam-Score mail headers and related headers.
|
||||||
tools/editconf.py /etc/spamassassin/local.cf -s \
|
tools/editconf.py /etc/spamassassin/local.cf -s \
|
||||||
report_safe=0 \
|
report_safe=0 \
|
||||||
add_header="all Report _REPORT_"
|
add_header="all Report _REPORT_" \
|
||||||
|
add_header="all Score _SCORE_"
|
||||||
|
|
||||||
# Bayesean learning
|
# Bayesean learning
|
||||||
# -----------------
|
# -----------------
|
||||||
|
|||||||
@@ -96,6 +96,12 @@ echo Updating system packages...
|
|||||||
hide_output apt-get update
|
hide_output apt-get update
|
||||||
apt_get_quiet upgrade
|
apt_get_quiet upgrade
|
||||||
|
|
||||||
|
# Old kernels pile up over time and take up a lot of disk space, and because of Mail-in-a-Box
|
||||||
|
# changes there may be other packages that are no longer needed. Clear out anything apt knows
|
||||||
|
# is safe to delete.
|
||||||
|
|
||||||
|
apt_get_quiet autoremove
|
||||||
|
|
||||||
# ### Install System Packages
|
# ### Install System Packages
|
||||||
|
|
||||||
# Install basic utilities.
|
# Install basic utilities.
|
||||||
@@ -123,12 +129,13 @@ apt_install python3 python3-dev python3-pip \
|
|||||||
|
|
||||||
# Nextcloud requires PHP7, we will install the ppa from ubuntu php maintainer Ondřej Surý
|
# Nextcloud requires PHP7, we will install the ppa from ubuntu php maintainer Ondřej Surý
|
||||||
# The PPA is located here https://launchpad.net/%7Eondrej/+archive/ubuntu/php
|
# The PPA is located here https://launchpad.net/%7Eondrej/+archive/ubuntu/php
|
||||||
# Unattended upgrades are activated for the repository
|
# Unattended upgrades are activated for the repository If it appears it's already
|
||||||
|
# installed, don't do it again so we can avoid an unnecessary call to apt-get update.
|
||||||
|
if [ ! -f /etc/apt/sources.list.d/ondrej-php-trusty.list ]; then
|
||||||
hide_output add-apt-repository -y ppa:ondrej/php
|
hide_output add-apt-repository -y ppa:ondrej/php
|
||||||
apt_add_repository_to_unattended_upgrades LP-PPA-ondrej-php:trusty
|
apt_add_repository_to_unattended_upgrades LP-PPA-ondrej-php:trusty
|
||||||
hide_output apt-get update
|
hide_output apt-get update
|
||||||
|
fi
|
||||||
|
|
||||||
# ### Suppress Upgrade Prompts
|
# ### Suppress Upgrade Prompts
|
||||||
# Since Mail-in-a-Box might jump straight to 18.04 LTS, there's no need
|
# Since Mail-in-a-Box might jump straight to 18.04 LTS, there's no need
|
||||||
@@ -241,7 +248,7 @@ cat > /etc/apt/apt.conf.d/02periodic <<EOF;
|
|||||||
APT::Periodic::MaxAge "7";
|
APT::Periodic::MaxAge "7";
|
||||||
APT::Periodic::Update-Package-Lists "1";
|
APT::Periodic::Update-Package-Lists "1";
|
||||||
APT::Periodic::Unattended-Upgrade "1";
|
APT::Periodic::Unattended-Upgrade "1";
|
||||||
APT::Periodic::Verbose "1";
|
APT::Periodic::Verbose "0";
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
# ### Firewall
|
# ### Firewall
|
||||||
|
|||||||
@@ -23,8 +23,7 @@ echo "Installing Roundcube (webmail)..."
|
|||||||
apt_install \
|
apt_install \
|
||||||
dbconfig-common \
|
dbconfig-common \
|
||||||
php7.0-cli php7.0-sqlite php7.0-mcrypt php7.0-intl php7.0-json php7.0-common \
|
php7.0-cli php7.0-sqlite php7.0-mcrypt php7.0-intl php7.0-json php7.0-common \
|
||||||
php-auth php-net-smtp php-net-socket php-net-sieve php-mail-mime php-crypt-gpg \
|
php7.0-gd php7.0-pspell tinymce libjs-jquery libjs-jquery-mousewheel libmagic1 php7.0-mbstring
|
||||||
php7.0-gd php7.0-pspell tinymce libjs-jquery libjs-jquery-mousewheel libmagic1
|
|
||||||
|
|
||||||
apt_get_quiet remove php-mail-mimedecode # no longer needed since Roundcube 1.1.3
|
apt_get_quiet remove php-mail-mimedecode # no longer needed since Roundcube 1.1.3
|
||||||
|
|
||||||
@@ -36,8 +35,8 @@ apt-get purge -qq -y roundcube* #NODOC
|
|||||||
# Install Roundcube from source if it is not already present or if it is out of date.
|
# Install Roundcube from source if it is not already present or if it is out of date.
|
||||||
# Combine the Roundcube version number with the commit hash of plugins to track
|
# Combine the Roundcube version number with the commit hash of plugins to track
|
||||||
# whether we have the latest version of everything.
|
# whether we have the latest version of everything.
|
||||||
VERSION=1.3.1
|
VERSION=1.3.6
|
||||||
HASH=d680f2914a0bff5314d8dda618d55937a13d1c5f
|
HASH=ece5cfc9c7af0cbe90c0065ef33e85ed42991830
|
||||||
PERSISTENT_LOGIN_VERSION=dc5ca3d3f4415cc41edb2fde533c8a8628a94c76
|
PERSISTENT_LOGIN_VERSION=dc5ca3d3f4415cc41edb2fde533c8a8628a94c76
|
||||||
HTML5_NOTIFIER_VERSION=4b370e3cd60dabd2f428a26f45b677ad1b7118d5
|
HTML5_NOTIFIER_VERSION=4b370e3cd60dabd2f428a26f45b677ad1b7118d5
|
||||||
CARDDAV_VERSION=2.0.4
|
CARDDAV_VERSION=2.0.4
|
||||||
@@ -106,7 +105,7 @@ cat > $RCM_CONFIG <<EOF;
|
|||||||
*/
|
*/
|
||||||
\$config = array();
|
\$config = array();
|
||||||
\$config['log_dir'] = '/var/log/roundcubemail/';
|
\$config['log_dir'] = '/var/log/roundcubemail/';
|
||||||
\$config['temp_dir'] = '/tmp/roundcubemail/';
|
\$config['temp_dir'] = '/var/tmp/roundcubemail/';
|
||||||
\$config['db_dsnw'] = 'sqlite:///$STORAGE_ROOT/mail/roundcube/roundcube.sqlite?mode=0640';
|
\$config['db_dsnw'] = 'sqlite:///$STORAGE_ROOT/mail/roundcube/roundcube.sqlite?mode=0640';
|
||||||
\$config['default_host'] = 'ssl://localhost';
|
\$config['default_host'] = 'ssl://localhost';
|
||||||
\$config['default_port'] = 993;
|
\$config['default_port'] = 993;
|
||||||
@@ -159,8 +158,8 @@ cat > ${RCM_PLUGIN_DIR}/carddav/config.inc.php <<EOF;
|
|||||||
EOF
|
EOF
|
||||||
|
|
||||||
# Create writable directories.
|
# Create writable directories.
|
||||||
mkdir -p /var/log/roundcubemail /tmp/roundcubemail $STORAGE_ROOT/mail/roundcube
|
mkdir -p /var/log/roundcubemail /var/tmp/roundcubemail $STORAGE_ROOT/mail/roundcube
|
||||||
chown -R www-data.www-data /var/log/roundcubemail /tmp/roundcubemail $STORAGE_ROOT/mail/roundcube
|
chown -R www-data.www-data /var/log/roundcubemail /var/tmp/roundcubemail $STORAGE_ROOT/mail/roundcube
|
||||||
|
|
||||||
# Ensure the log file monitored by fail2ban exists, or else fail2ban can't start.
|
# Ensure the log file monitored by fail2ban exists, or else fail2ban can't start.
|
||||||
sudo -u www-data touch /var/log/roundcubemail/errors
|
sudo -u www-data touch /var/log/roundcubemail/errors
|
||||||
|
|||||||
@@ -22,27 +22,27 @@ apt_install \
|
|||||||
phpenmod -v php7.0 imap
|
phpenmod -v php7.0 imap
|
||||||
|
|
||||||
# Copy Z-Push into place.
|
# Copy Z-Push into place.
|
||||||
TARGETHASH=aae5093212ac0b7d8bf2d79fd5b87ca5bbf091cb
|
VERSION=2.3.9
|
||||||
VERSION=2.3.8
|
|
||||||
needs_update=0 #NODOC
|
needs_update=0 #NODOC
|
||||||
if [ ! -f /usr/local/lib/z-push/version ]; then
|
if [ ! -f /usr/local/lib/z-push/version ]; then
|
||||||
needs_update=1 #NODOC
|
needs_update=1 #NODOC
|
||||||
elif [[ $TARGETHASH != `cat /usr/local/lib/z-push/version` ]]; then
|
elif [[ $VERSION != `cat /usr/local/lib/z-push/version` ]]; then
|
||||||
# checks if the version
|
# checks if the version
|
||||||
needs_update=1 #NODOC
|
needs_update=1 #NODOC
|
||||||
fi
|
fi
|
||||||
if [ $needs_update == 1 ]; then
|
if [ $needs_update == 1 ]; then
|
||||||
wget_verify http://download.z-push.org/final/2.3/z-push-$VERSION.tar.gz $TARGETHASH /tmp/z-push.tar.gz
|
|
||||||
|
|
||||||
rm -rf /usr/local/lib/z-push
|
rm -rf /usr/local/lib/z-push
|
||||||
tar -xzf /tmp/z-push.tar.gz -C /usr/local/lib/
|
|
||||||
rm /tmp/z-push.tar.gz
|
git_clone https://stash.z-hub.io/scm/zp/z-push.git $VERSION '' /tmp/z-push
|
||||||
mv /usr/local/lib/z-push-$VERSION /usr/local/lib/z-push
|
|
||||||
|
mkdir /usr/local/lib/z-push
|
||||||
|
cp -r /tmp/z-push/src/* /usr/local/lib/z-push
|
||||||
|
rm -rf /tmp/z-push
|
||||||
|
|
||||||
rm -f /usr/sbin/z-push-{admin,top}
|
rm -f /usr/sbin/z-push-{admin,top}
|
||||||
ln -s /usr/local/lib/z-push/z-push-admin.php /usr/sbin/z-push-admin
|
ln -s /usr/local/lib/z-push/z-push-admin.php /usr/sbin/z-push-admin
|
||||||
ln -s /usr/local/lib/z-push/z-push-top.php /usr/sbin/z-push-top
|
ln -s /usr/local/lib/z-push/z-push-top.php /usr/sbin/z-push-top
|
||||||
echo $TARGETHASH > /usr/local/lib/z-push/version
|
echo $VERSION > /usr/local/lib/z-push/version
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Configure default config.
|
# Configure default config.
|
||||||
|
|||||||
@@ -61,9 +61,9 @@ common_opts = ["--sslv2", "--sslv3", "--tlsv1", "--tlsv1_1", "--tlsv1_2", "--ren
|
|||||||
# Assumes TLSv1, TLSv1.1, TLSv1.2.
|
# Assumes TLSv1, TLSv1.1, TLSv1.2.
|
||||||
#
|
#
|
||||||
# The 'old' ciphers bring compatibility back to Win XP IE 6.
|
# The 'old' ciphers bring compatibility back to Win XP IE 6.
|
||||||
MOZILLA_CIPHERS_MODERN = "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK"
|
MOZILLA_CIPHERS_MODERN = "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256"
|
||||||
MOZILLA_CIPHERS_INTERMEDIATE = "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA"
|
MOZILLA_CIPHERS_INTERMEDIATE = "ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS"
|
||||||
MOZILLA_CIPHERS_OLD = "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA"
|
MOZILLA_CIPHERS_OLD = "ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:DES-CBC3-SHA:HIGH:SEED:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!RSAPSK:!aDH:!aECDH:!EDH-DSS-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA:!SRP"
|
||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
|
|
||||||
|
|||||||
@@ -93,9 +93,9 @@ PORT 25
|
|||||||
* SSLV3 Cipher Suites:
|
* SSLV3 Cipher Suites:
|
||||||
Server rejected all cipher suites.
|
Server rejected all cipher suites.
|
||||||
|
|
||||||
Should Not Offer: DHE-RSA-SEED-SHA, EDH-RSA-DES-CBC3-SHA, SEED-SHA
|
Should Not Offer: (none -- good)
|
||||||
Could Also Offer: DH-DSS-AES128-GCM-SHA256, DH-DSS-AES128-SHA, DH-DSS-AES128-SHA256, DH-DSS-AES256-GCM-SHA384, DH-DSS-AES256-SHA, DH-DSS-AES256-SHA256, DH-DSS-CAMELLIA128-SHA, DH-DSS-CAMELLIA256-SHA, DH-DSS-DES-CBC3-SHA, DH-RSA-AES128-GCM-SHA256, DH-RSA-AES128-SHA, DH-RSA-AES128-SHA256, DH-RSA-AES256-GCM-SHA384, DH-RSA-AES256-SHA, DH-RSA-AES256-SHA256, DH-RSA-CAMELLIA128-SHA, DH-RSA-CAMELLIA256-SHA, DH-RSA-DES-CBC3-SHA, DHE-DSS-AES128-GCM-SHA256, DHE-DSS-AES128-SHA, DHE-DSS-AES128-SHA256, DHE-DSS-AES256-GCM-SHA384, DHE-DSS-AES256-SHA, DHE-DSS-AES256-SHA256, DHE-DSS-CAMELLIA128-SHA, DHE-DSS-CAMELLIA256-SHA, ECDHE-ECDSA-AES128-GCM-SHA256, ECDHE-ECDSA-AES128-SHA, ECDHE-ECDSA-AES128-SHA256, ECDHE-ECDSA-AES256-GCM-SHA384, ECDHE-ECDSA-AES256-SHA, ECDHE-ECDSA-AES256-SHA384, ECDHE-ECDSA-DES-CBC3-SHA, SRP-3DES-EDE-CBC-SHA, SRP-AES-128-CBC-SHA, SRP-AES-256-CBC-SHA, SRP-DSS-3DES-EDE-CBC-SHA, SRP-DSS-AES-128-CBC-SHA, SRP-DSS-AES-256-CBC-SHA, SRP-RSA-3DES-EDE-CBC-SHA, SRP-RSA-AES-128-CBC-SHA, SRP-RSA-AES-256-CBC-SHA
|
Could Also Offer: DHE-DSS-AES128-GCM-SHA256, DHE-DSS-AES128-SHA, DHE-DSS-AES128-SHA256, DHE-DSS-AES256-GCM-SHA384, DHE-DSS-AES256-SHA, DHE-DSS-AES256-SHA256, DHE-DSS-CAMELLIA128-SHA, DHE-DSS-CAMELLIA256-SHA, DHE-DSS-SEED-SHA, ECDHE-ECDSA-AES128-GCM-SHA256, ECDHE-ECDSA-AES128-SHA, ECDHE-ECDSA-AES128-SHA256, ECDHE-ECDSA-AES256-GCM-SHA384, ECDHE-ECDSA-AES256-SHA, ECDHE-ECDSA-AES256-SHA384, ECDHE-ECDSA-DES-CBC3-SHA
|
||||||
Supported Clients: OpenSSL/1.0.2, OpenSSL/1.0.1l, BingPreview/Jan 2015, Yahoo Slurp/Jan 2015, YandexBot/Jan 2015, Android/4.4.2, Safari/7/iOS 7.1, Safari/8/OS X 10.10, Safari/8/iOS 8.1.2, Safari/7/OS X 10.9, Safari/6/iOS 6.0.1, Firefox/31.3.0 ESR/Win 7, Baidu/Jan 2015, IE/11/Win 8.1, IE/11/Win 7, IE Mobile/11/Win Phone 8.1, Android/5.0.0, Java/8u31, Chrome/42/OS X, Googlebot/Feb 2015, Android/4.1.1, Android/4.0.4, Safari/6.0.4/OS X 10.8.4, Android/4.2.2, Android/4.3, Safari/5.1.9/OS X 10.6.8, Firefox/37/OS X, OpenSSL/0.9.8y, Java/7u25, IE/8-10/Win 7, IE/7/Vista, IE Mobile/10/Win Phone 8.0, Android/2.3.7, Java/6u45, IE/8/XP
|
Supported Clients: BingPreview/Jan 2015, OpenSSL/1.0.2, Yahoo Slurp/Jan 2015, OpenSSL/1.0.1l, YandexBot/Jan 2015, Android/4.4.2, Safari/7/iOS 7.1, Safari/8/iOS 8.1.2, Safari/6/iOS 6.0.1, Safari/7/OS X 10.9, Safari/8/OS X 10.10, Baidu/Jan 2015, Firefox/31.3.0 ESR/Win 7, IE/11/Win 7, IE/11/Win 8.1, IE Mobile/11/Win Phone 8.1, Java/8u31, Android/5.0.0, Googlebot/Feb 2015, Chrome/42/OS X, Android/4.1.1, Android/4.3, Android/4.0.4, Android/4.2.2, Safari/5.1.9/OS X 10.6.8, Safari/6.0.4/OS X 10.8.4, Firefox/37/OS X, OpenSSL/0.9.8y, Java/7u25, IE Mobile/10/Win Phone 8.0, IE/8-10/Win 7, IE/7/Vista, Android/2.3.7, Java/6u45, IE/8/XP
|
||||||
|
|
||||||
PORT 587
|
PORT 587
|
||||||
--------
|
--------
|
||||||
@@ -183,9 +183,9 @@ PORT 587
|
|||||||
* SSLV3 Cipher Suites:
|
* SSLV3 Cipher Suites:
|
||||||
Server rejected all cipher suites.
|
Server rejected all cipher suites.
|
||||||
|
|
||||||
Should Not Offer: AES128-GCM-SHA256, AES128-SHA, AES128-SHA256, AES256-GCM-SHA384, AES256-SHA, AES256-SHA256, CAMELLIA128-SHA, CAMELLIA256-SHA, DHE-RSA-CAMELLIA128-SHA, DHE-RSA-CAMELLIA256-SHA, DHE-RSA-SEED-SHA, SEED-SHA
|
Should Not Offer: AES128-GCM-SHA256, AES128-SHA, AES128-SHA256, AES256-GCM-SHA384, AES256-SHA, AES256-SHA256, CAMELLIA128-SHA, CAMELLIA256-SHA, DHE-RSA-AES128-GCM-SHA256, DHE-RSA-AES128-SHA, DHE-RSA-AES128-SHA256, DHE-RSA-AES256-GCM-SHA384, DHE-RSA-AES256-SHA, DHE-RSA-AES256-SHA256, DHE-RSA-CAMELLIA128-SHA, DHE-RSA-CAMELLIA256-SHA, DHE-RSA-SEED-SHA, ECDHE-RSA-AES128-SHA, ECDHE-RSA-AES256-SHA, SEED-SHA
|
||||||
Could Also Offer: DHE-DSS-AES128-GCM-SHA256, DHE-DSS-AES128-SHA256, DHE-DSS-AES256-GCM-SHA384, DHE-DSS-AES256-SHA, ECDHE-ECDSA-AES128-GCM-SHA256, ECDHE-ECDSA-AES128-SHA, ECDHE-ECDSA-AES128-SHA256, ECDHE-ECDSA-AES256-GCM-SHA384, ECDHE-ECDSA-AES256-SHA, ECDHE-ECDSA-AES256-SHA384
|
Could Also Offer: ECDHE-ECDSA-AES128-GCM-SHA256, ECDHE-ECDSA-AES128-SHA256, ECDHE-ECDSA-AES256-GCM-SHA384, ECDHE-ECDSA-AES256-SHA384
|
||||||
Supported Clients: OpenSSL/1.0.2, OpenSSL/1.0.1l, BingPreview/Jan 2015, Yahoo Slurp/Jan 2015, YandexBot/Jan 2015, Android/4.4.2, Safari/7/iOS 7.1, IE/11/Win 8.1, Safari/8/iOS 8.1.2, IE/11/Win 7, IE Mobile/11/Win Phone 8.1, Safari/8/OS X 10.10, Safari/7/OS X 10.9, Safari/6/iOS 6.0.1, Firefox/31.3.0 ESR/Win 7, Baidu/Jan 2015, Chrome/42/OS X, Android/5.0.0, Java/8u31, Googlebot/Feb 2015, Firefox/37/OS X, Android/4.0.4, Android/4.1.1, Safari/6.0.4/OS X 10.8.4, Android/4.2.2, Android/4.3, Safari/5.1.9/OS X 10.6.8, IE/8-10/Win 7, IE/7/Vista, IE Mobile/10/Win Phone 8.0, OpenSSL/0.9.8y, Java/7u25, Java/6u45, Android/2.3.7
|
Supported Clients: BingPreview/Jan 2015, OpenSSL/1.0.2, Yahoo Slurp/Jan 2015, OpenSSL/1.0.1l, YandexBot/Jan 2015, Android/4.4.2, Safari/7/iOS 7.1, IE/11/Win 7, IE/11/Win 8.1, Safari/8/iOS 8.1.2, Safari/6/iOS 6.0.1, Safari/7/OS X 10.9, IE Mobile/11/Win Phone 8.1, Safari/8/OS X 10.10, Baidu/Jan 2015, Firefox/31.3.0 ESR/Win 7, Java/8u31, Android/5.0.0, Chrome/42/OS X, Googlebot/Feb 2015, Firefox/37/OS X, Android/4.1.1, Android/4.3, Android/4.0.4, Android/4.2.2, Safari/5.1.9/OS X 10.6.8, Safari/6.0.4/OS X 10.8.4, OpenSSL/0.9.8y, IE Mobile/10/Win Phone 8.0, IE/8-10/Win 7, IE/7/Vista, Java/7u25, Android/2.3.7, Java/6u45
|
||||||
|
|
||||||
PORT 443
|
PORT 443
|
||||||
--------
|
--------
|
||||||
@@ -200,16 +200,16 @@ PORT 443
|
|||||||
* OpenSSL Heartbleed:
|
* OpenSSL Heartbleed:
|
||||||
OK - Not vulnerable to Heartbleed
|
OK - Not vulnerable to Heartbleed
|
||||||
|
|
||||||
* Session Resumption:
|
|
||||||
With Session IDs: OK - Supported (5 successful, 0 failed, 0 errors, 5 total attempts).
|
|
||||||
With TLS Session Tickets: OK - Supported
|
|
||||||
|
|
||||||
* HTTP Strict Transport Security:
|
* HTTP Strict Transport Security:
|
||||||
OK - HSTS header received: max-age=31536000
|
OK - HSTS header received: max-age=15768000
|
||||||
|
|
||||||
Unhandled exception when processing --chrome_sha1:
|
Unhandled exception when processing --chrome_sha1:
|
||||||
exceptions.TypeError - Incorrect padding
|
exceptions.TypeError - Incorrect padding
|
||||||
|
|
||||||
|
* Session Resumption:
|
||||||
|
With Session IDs: OK - Supported (5 successful, 0 failed, 0 errors, 5 total attempts).
|
||||||
|
With TLS Session Tickets: OK - Supported
|
||||||
|
|
||||||
* SSLV2 Cipher Suites:
|
* SSLV2 Cipher Suites:
|
||||||
Server rejected all cipher suites.
|
Server rejected all cipher suites.
|
||||||
|
|
||||||
@@ -223,12 +223,20 @@ exceptions.TypeError - Incorrect padding
|
|||||||
DHE-RSA-AES256-SHA256 DH-2048 bits 256 bits HTTP 200 OK
|
DHE-RSA-AES256-SHA256 DH-2048 bits 256 bits HTTP 200 OK
|
||||||
DHE-RSA-AES256-SHA DH-2048 bits 256 bits HTTP 200 OK
|
DHE-RSA-AES256-SHA DH-2048 bits 256 bits HTTP 200 OK
|
||||||
DHE-RSA-AES256-GCM-SHA384 DH-2048 bits 256 bits HTTP 200 OK
|
DHE-RSA-AES256-GCM-SHA384 DH-2048 bits 256 bits HTTP 200 OK
|
||||||
|
AES256-SHA256 - 256 bits HTTP 200 OK
|
||||||
|
AES256-SHA - 256 bits HTTP 200 OK
|
||||||
|
AES256-GCM-SHA384 - 256 bits HTTP 200 OK
|
||||||
ECDHE-RSA-AES128-SHA256 ECDH-256 bits 128 bits HTTP 200 OK
|
ECDHE-RSA-AES128-SHA256 ECDH-256 bits 128 bits HTTP 200 OK
|
||||||
ECDHE-RSA-AES128-SHA ECDH-256 bits 128 bits HTTP 200 OK
|
ECDHE-RSA-AES128-SHA ECDH-256 bits 128 bits HTTP 200 OK
|
||||||
ECDHE-RSA-AES128-GCM-SHA256 ECDH-256 bits 128 bits HTTP 200 OK
|
ECDHE-RSA-AES128-GCM-SHA256 ECDH-256 bits 128 bits HTTP 200 OK
|
||||||
DHE-RSA-AES128-SHA256 DH-2048 bits 128 bits HTTP 200 OK
|
DHE-RSA-AES128-SHA256 DH-2048 bits 128 bits HTTP 200 OK
|
||||||
DHE-RSA-AES128-SHA DH-2048 bits 128 bits HTTP 200 OK
|
DHE-RSA-AES128-SHA DH-2048 bits 128 bits HTTP 200 OK
|
||||||
DHE-RSA-AES128-GCM-SHA256 DH-2048 bits 128 bits HTTP 200 OK
|
DHE-RSA-AES128-GCM-SHA256 DH-2048 bits 128 bits HTTP 200 OK
|
||||||
|
AES128-SHA256 - 128 bits HTTP 200 OK
|
||||||
|
AES128-SHA - 128 bits HTTP 200 OK
|
||||||
|
AES128-GCM-SHA256 - 128 bits HTTP 200 OK
|
||||||
|
ECDHE-RSA-DES-CBC3-SHA ECDH-256 bits 112 bits HTTP 200 OK
|
||||||
|
EDH-RSA-DES-CBC3-SHA DH-2048 bits 112 bits HTTP 200 OK
|
||||||
DES-CBC3-SHA - 112 bits HTTP 200 OK
|
DES-CBC3-SHA - 112 bits HTTP 200 OK
|
||||||
|
|
||||||
* TLSV1_1 Cipher Suites:
|
* TLSV1_1 Cipher Suites:
|
||||||
@@ -237,8 +245,12 @@ exceptions.TypeError - Incorrect padding
|
|||||||
Accepted:
|
Accepted:
|
||||||
ECDHE-RSA-AES256-SHA ECDH-256 bits 256 bits HTTP 200 OK
|
ECDHE-RSA-AES256-SHA ECDH-256 bits 256 bits HTTP 200 OK
|
||||||
DHE-RSA-AES256-SHA DH-2048 bits 256 bits HTTP 200 OK
|
DHE-RSA-AES256-SHA DH-2048 bits 256 bits HTTP 200 OK
|
||||||
|
AES256-SHA - 256 bits HTTP 200 OK
|
||||||
ECDHE-RSA-AES128-SHA ECDH-256 bits 128 bits HTTP 200 OK
|
ECDHE-RSA-AES128-SHA ECDH-256 bits 128 bits HTTP 200 OK
|
||||||
DHE-RSA-AES128-SHA DH-2048 bits 128 bits HTTP 200 OK
|
DHE-RSA-AES128-SHA DH-2048 bits 128 bits HTTP 200 OK
|
||||||
|
AES128-SHA - 128 bits HTTP 200 OK
|
||||||
|
ECDHE-RSA-DES-CBC3-SHA ECDH-256 bits 112 bits HTTP 200 OK
|
||||||
|
EDH-RSA-DES-CBC3-SHA DH-2048 bits 112 bits HTTP 200 OK
|
||||||
DES-CBC3-SHA - 112 bits HTTP 200 OK
|
DES-CBC3-SHA - 112 bits HTTP 200 OK
|
||||||
|
|
||||||
* TLSV1 Cipher Suites:
|
* TLSV1 Cipher Suites:
|
||||||
@@ -247,16 +259,20 @@ exceptions.TypeError - Incorrect padding
|
|||||||
Accepted:
|
Accepted:
|
||||||
ECDHE-RSA-AES256-SHA ECDH-256 bits 256 bits HTTP 200 OK
|
ECDHE-RSA-AES256-SHA ECDH-256 bits 256 bits HTTP 200 OK
|
||||||
DHE-RSA-AES256-SHA DH-2048 bits 256 bits HTTP 200 OK
|
DHE-RSA-AES256-SHA DH-2048 bits 256 bits HTTP 200 OK
|
||||||
|
AES256-SHA - 256 bits HTTP 200 OK
|
||||||
ECDHE-RSA-AES128-SHA ECDH-256 bits 128 bits HTTP 200 OK
|
ECDHE-RSA-AES128-SHA ECDH-256 bits 128 bits HTTP 200 OK
|
||||||
DHE-RSA-AES128-SHA DH-2048 bits 128 bits HTTP 200 OK
|
DHE-RSA-AES128-SHA DH-2048 bits 128 bits HTTP 200 OK
|
||||||
|
AES128-SHA - 128 bits HTTP 200 OK
|
||||||
|
ECDHE-RSA-DES-CBC3-SHA ECDH-256 bits 112 bits HTTP 200 OK
|
||||||
|
EDH-RSA-DES-CBC3-SHA DH-2048 bits 112 bits HTTP 200 OK
|
||||||
DES-CBC3-SHA - 112 bits HTTP 200 OK
|
DES-CBC3-SHA - 112 bits HTTP 200 OK
|
||||||
|
|
||||||
* SSLV3 Cipher Suites:
|
* SSLV3 Cipher Suites:
|
||||||
Server rejected all cipher suites.
|
Server rejected all cipher suites.
|
||||||
|
|
||||||
Should Not Offer: (none -- good)
|
Should Not Offer: (none -- good)
|
||||||
Could Also Offer: AES128-GCM-SHA256, AES128-SHA, AES128-SHA256, AES256-GCM-SHA384, AES256-SHA, AES256-SHA256, CAMELLIA128-SHA, CAMELLIA256-SHA, DH-DSS-AES128-GCM-SHA256, DH-DSS-AES128-SHA, DH-DSS-AES128-SHA256, DH-DSS-AES256-GCM-SHA384, DH-DSS-AES256-SHA, DH-DSS-AES256-SHA256, DH-DSS-CAMELLIA128-SHA, DH-DSS-CAMELLIA256-SHA, DH-RSA-AES128-GCM-SHA256, DH-RSA-AES128-SHA, DH-RSA-AES128-SHA256, DH-RSA-AES256-GCM-SHA384, DH-RSA-AES256-SHA, DH-RSA-AES256-SHA256, DH-RSA-CAMELLIA128-SHA, DH-RSA-CAMELLIA256-SHA, DHE-DSS-AES128-GCM-SHA256, DHE-DSS-AES128-SHA, DHE-DSS-AES128-SHA256, DHE-DSS-AES256-GCM-SHA384, DHE-DSS-AES256-SHA, DHE-DSS-AES256-SHA256, DHE-DSS-CAMELLIA128-SHA, DHE-DSS-CAMELLIA256-SHA, DHE-RSA-CAMELLIA128-SHA, DHE-RSA-CAMELLIA256-SHA, ECDHE-ECDSA-AES128-GCM-SHA256, ECDHE-ECDSA-AES128-SHA, ECDHE-ECDSA-AES128-SHA256, ECDHE-ECDSA-AES256-GCM-SHA384, ECDHE-ECDSA-AES256-SHA, ECDHE-ECDSA-AES256-SHA384, SRP-AES-128-CBC-SHA, SRP-AES-256-CBC-SHA, SRP-DSS-AES-128-CBC-SHA, SRP-DSS-AES-256-CBC-SHA, SRP-RSA-AES-128-CBC-SHA, SRP-RSA-AES-256-CBC-SHA
|
Could Also Offer: ECDHE-ECDSA-AES128-GCM-SHA256, ECDHE-ECDSA-AES128-SHA, ECDHE-ECDSA-AES128-SHA256, ECDHE-ECDSA-AES256-GCM-SHA384, ECDHE-ECDSA-AES256-SHA, ECDHE-ECDSA-AES256-SHA384, ECDHE-ECDSA-DES-CBC3-SHA
|
||||||
Supported Clients: OpenSSL/1.0.2, OpenSSL/1.0.1l, BingPreview/Jan 2015, YandexBot/Jan 2015, Yahoo Slurp/Jan 2015, Android/4.4.2, Safari/7/iOS 7.1, Safari/8/OS X 10.10, Safari/8/iOS 8.1.2, Safari/7/OS X 10.9, Safari/6/iOS 6.0.1, Chrome/42/OS X, IE/11/Win 8.1, IE/11/Win 7, Android/5.0.0, Java/8u31, IE Mobile/11/Win Phone 8.1, Googlebot/Feb 2015, Firefox/31.3.0 ESR/Win 7, Firefox/37/OS X, Android/4.1.1, Android/4.0.4, Baidu/Jan 2015, Safari/6.0.4/OS X 10.8.4, Android/4.2.2, Android/4.3, Safari/5.1.9/OS X 10.6.8, IE/8-10/Win 7, IE/7/Vista, OpenSSL/0.9.8y, IE Mobile/10/Win Phone 8.0, Java/7u25, Android/2.3.7, Java/6u45, IE/8/XP
|
Supported Clients: BingPreview/Jan 2015, OpenSSL/1.0.2, YandexBot/Jan 2015, OpenSSL/1.0.1l, Yahoo Slurp/Jan 2015, Android/4.4.2, Safari/7/iOS 7.1, Safari/8/iOS 8.1.2, Safari/6/iOS 6.0.1, Safari/7/OS X 10.9, Safari/8/OS X 10.10, IE/11/Win 7, IE/11/Win 8.1, IE Mobile/11/Win Phone 8.1, Java/8u31, Android/5.0.0, Googlebot/Feb 2015, Firefox/31.3.0 ESR/Win 7, Chrome/42/OS X, Baidu/Jan 2015, Android/4.1.1, Android/4.3, Android/4.0.4, Android/4.2.2, Safari/5.1.9/OS X 10.6.8, Safari/6.0.4/OS X 10.8.4, Firefox/37/OS X, OpenSSL/0.9.8y, Java/7u25, IE Mobile/10/Win Phone 8.0, IE/8-10/Win 7, IE/7/Vista, Java/6u45, Android/2.3.7, IE/8/XP
|
||||||
|
|
||||||
PORT 993
|
PORT 993
|
||||||
--------
|
--------
|
||||||
@@ -270,64 +286,73 @@ _nassl.OpenSSLError - error:140940F5:SSL routines:ssl3_read_bytes:unexpected rec
|
|||||||
* OpenSSL Heartbleed:
|
* OpenSSL Heartbleed:
|
||||||
OK - Not vulnerable to Heartbleed
|
OK - Not vulnerable to Heartbleed
|
||||||
|
|
||||||
|
* SSLV2 Cipher Suites:
|
||||||
|
Server rejected all cipher suites.
|
||||||
|
|
||||||
* Session Resumption:
|
* Session Resumption:
|
||||||
With Session IDs: NOT SUPPORTED (0 successful, 5 failed, 0 errors, 5 total attempts).
|
With Session IDs: NOT SUPPORTED (0 successful, 5 failed, 0 errors, 5 total attempts).
|
||||||
With TLS Session Tickets: NOT SUPPORTED - TLS ticket assigned but not accepted.
|
With TLS Session Tickets: NOT SUPPORTED - TLS ticket assigned but not accepted.
|
||||||
|
|
||||||
* SSLV2 Cipher Suites:
|
|
||||||
Server rejected all cipher suites.
|
|
||||||
|
|
||||||
* TLSV1_2 Cipher Suites:
|
* TLSV1_2 Cipher Suites:
|
||||||
Preferred:
|
Preferred:
|
||||||
ECDHE-RSA-AES256-SHA ECDH-384 bits 256 bits
|
ECDHE-RSA-AES128-GCM-SHA256 ECDH-384 bits 128 bits
|
||||||
Accepted:
|
Accepted:
|
||||||
|
ECDHE-RSA-AES256-SHA384 ECDH-384 bits 256 bits
|
||||||
ECDHE-RSA-AES256-SHA ECDH-384 bits 256 bits
|
ECDHE-RSA-AES256-SHA ECDH-384 bits 256 bits
|
||||||
DHE-RSA-CAMELLIA256-SHA DH-1024 bits 256 bits
|
ECDHE-RSA-AES256-GCM-SHA384 ECDH-384 bits 256 bits
|
||||||
DHE-RSA-AES256-SHA DH-1024 bits 256 bits
|
DHE-RSA-AES256-SHA256 DH-2048 bits 256 bits
|
||||||
CAMELLIA256-SHA - 256 bits
|
DHE-RSA-AES256-SHA DH-2048 bits 256 bits
|
||||||
|
DHE-RSA-AES256-GCM-SHA384 DH-2048 bits 256 bits
|
||||||
|
AES256-SHA256 - 256 bits
|
||||||
AES256-SHA - 256 bits
|
AES256-SHA - 256 bits
|
||||||
|
AES256-GCM-SHA384 - 256 bits
|
||||||
|
ECDHE-RSA-AES128-SHA256 ECDH-384 bits 128 bits
|
||||||
ECDHE-RSA-AES128-SHA ECDH-384 bits 128 bits
|
ECDHE-RSA-AES128-SHA ECDH-384 bits 128 bits
|
||||||
DHE-RSA-CAMELLIA128-SHA DH-1024 bits 128 bits
|
ECDHE-RSA-AES128-GCM-SHA256 ECDH-384 bits 128 bits
|
||||||
DHE-RSA-AES128-SHA DH-1024 bits 128 bits
|
DHE-RSA-AES128-SHA256 DH-2048 bits 128 bits
|
||||||
CAMELLIA128-SHA - 128 bits
|
DHE-RSA-AES128-SHA DH-2048 bits 128 bits
|
||||||
|
DHE-RSA-AES128-GCM-SHA256 DH-2048 bits 128 bits
|
||||||
|
AES128-SHA256 - 128 bits
|
||||||
AES128-SHA - 128 bits
|
AES128-SHA - 128 bits
|
||||||
|
AES128-GCM-SHA256 - 128 bits
|
||||||
|
ECDHE-RSA-DES-CBC3-SHA ECDH-384 bits 112 bits
|
||||||
|
EDH-RSA-DES-CBC3-SHA DH-2048 bits 112 bits
|
||||||
|
DES-CBC3-SHA - 112 bits
|
||||||
|
|
||||||
* TLSV1_1 Cipher Suites:
|
* TLSV1_1 Cipher Suites:
|
||||||
Preferred:
|
Preferred:
|
||||||
ECDHE-RSA-AES256-SHA ECDH-384 bits 256 bits
|
ECDHE-RSA-AES128-SHA ECDH-384 bits 128 bits
|
||||||
Accepted:
|
Accepted:
|
||||||
ECDHE-RSA-AES256-SHA ECDH-384 bits 256 bits
|
ECDHE-RSA-AES256-SHA ECDH-384 bits 256 bits
|
||||||
DHE-RSA-CAMELLIA256-SHA DH-1024 bits 256 bits
|
DHE-RSA-AES256-SHA DH-2048 bits 256 bits
|
||||||
DHE-RSA-AES256-SHA DH-1024 bits 256 bits
|
|
||||||
CAMELLIA256-SHA - 256 bits
|
|
||||||
AES256-SHA - 256 bits
|
AES256-SHA - 256 bits
|
||||||
ECDHE-RSA-AES128-SHA ECDH-384 bits 128 bits
|
ECDHE-RSA-AES128-SHA ECDH-384 bits 128 bits
|
||||||
DHE-RSA-CAMELLIA128-SHA DH-1024 bits 128 bits
|
DHE-RSA-AES128-SHA DH-2048 bits 128 bits
|
||||||
DHE-RSA-AES128-SHA DH-1024 bits 128 bits
|
|
||||||
CAMELLIA128-SHA - 128 bits
|
|
||||||
AES128-SHA - 128 bits
|
AES128-SHA - 128 bits
|
||||||
|
ECDHE-RSA-DES-CBC3-SHA ECDH-384 bits 112 bits
|
||||||
|
EDH-RSA-DES-CBC3-SHA DH-2048 bits 112 bits
|
||||||
|
DES-CBC3-SHA - 112 bits
|
||||||
|
|
||||||
* TLSV1 Cipher Suites:
|
* TLSV1 Cipher Suites:
|
||||||
Preferred:
|
Preferred:
|
||||||
ECDHE-RSA-AES256-SHA ECDH-384 bits 256 bits
|
ECDHE-RSA-AES128-SHA ECDH-384 bits 128 bits
|
||||||
Accepted:
|
Accepted:
|
||||||
ECDHE-RSA-AES256-SHA ECDH-384 bits 256 bits
|
ECDHE-RSA-AES256-SHA ECDH-384 bits 256 bits
|
||||||
DHE-RSA-CAMELLIA256-SHA DH-1024 bits 256 bits
|
DHE-RSA-AES256-SHA DH-2048 bits 256 bits
|
||||||
DHE-RSA-AES256-SHA DH-1024 bits 256 bits
|
|
||||||
CAMELLIA256-SHA - 256 bits
|
|
||||||
AES256-SHA - 256 bits
|
AES256-SHA - 256 bits
|
||||||
ECDHE-RSA-AES128-SHA ECDH-384 bits 128 bits
|
ECDHE-RSA-AES128-SHA ECDH-384 bits 128 bits
|
||||||
DHE-RSA-CAMELLIA128-SHA DH-1024 bits 128 bits
|
DHE-RSA-AES128-SHA DH-2048 bits 128 bits
|
||||||
DHE-RSA-AES128-SHA DH-1024 bits 128 bits
|
|
||||||
CAMELLIA128-SHA - 128 bits
|
|
||||||
AES128-SHA - 128 bits
|
AES128-SHA - 128 bits
|
||||||
|
ECDHE-RSA-DES-CBC3-SHA ECDH-384 bits 112 bits
|
||||||
|
EDH-RSA-DES-CBC3-SHA DH-2048 bits 112 bits
|
||||||
|
DES-CBC3-SHA - 112 bits
|
||||||
|
|
||||||
* SSLV3 Cipher Suites:
|
* SSLV3 Cipher Suites:
|
||||||
Server rejected all cipher suites.
|
Server rejected all cipher suites.
|
||||||
|
|
||||||
Should Not Offer: AES128-SHA, AES256-SHA, CAMELLIA128-SHA, CAMELLIA256-SHA, DHE-RSA-CAMELLIA128-SHA, DHE-RSA-CAMELLIA256-SHA
|
Should Not Offer: AES128-GCM-SHA256, AES128-SHA, AES128-SHA256, AES256-GCM-SHA384, AES256-SHA, AES256-SHA256, DES-CBC3-SHA, DHE-RSA-AES128-GCM-SHA256, DHE-RSA-AES128-SHA, DHE-RSA-AES128-SHA256, DHE-RSA-AES256-GCM-SHA384, DHE-RSA-AES256-SHA, DHE-RSA-AES256-SHA256, ECDHE-RSA-AES128-SHA, ECDHE-RSA-AES256-SHA, ECDHE-RSA-DES-CBC3-SHA, EDH-RSA-DES-CBC3-SHA
|
||||||
Could Also Offer: DHE-DSS-AES128-GCM-SHA256, DHE-DSS-AES128-SHA256, DHE-DSS-AES256-GCM-SHA384, DHE-DSS-AES256-SHA, DHE-RSA-AES128-GCM-SHA256, DHE-RSA-AES128-SHA256, DHE-RSA-AES256-GCM-SHA384, DHE-RSA-AES256-SHA256, ECDHE-ECDSA-AES128-GCM-SHA256, ECDHE-ECDSA-AES128-SHA, ECDHE-ECDSA-AES128-SHA256, ECDHE-ECDSA-AES256-GCM-SHA384, ECDHE-ECDSA-AES256-SHA, ECDHE-ECDSA-AES256-SHA384, ECDHE-RSA-AES128-GCM-SHA256, ECDHE-RSA-AES128-SHA256, ECDHE-RSA-AES256-GCM-SHA384, ECDHE-RSA-AES256-SHA384
|
Could Also Offer: ECDHE-ECDSA-AES128-GCM-SHA256, ECDHE-ECDSA-AES128-SHA256, ECDHE-ECDSA-AES256-GCM-SHA384, ECDHE-ECDSA-AES256-SHA384
|
||||||
Supported Clients: OpenSSL/1.0.2, Firefox/31.3.0 ESR/Win 7, OpenSSL/1.0.1l, BingPreview/Jan 2015, Yahoo Slurp/Jan 2015, Baidu/Jan 2015, Safari/7/iOS 7.1, Chrome/42/OS X, Googlebot/Feb 2015, Android/4.0.4, Safari/8/iOS 8.1.2, Android/4.1.1, Android/5.0.0, Safari/6/iOS 6.0.1, YandexBot/Jan 2015, Safari/6.0.4/OS X 10.8.4, Android/4.2.2, Safari/8/OS X 10.10, Firefox/37/OS X, Safari/7/OS X 10.9, Android/4.3, Safari/5.1.9/OS X 10.6.8, Android/4.4.2, IE/8-10/Win 7, IE/7/Vista, IE/11/Win 8.1, IE/11/Win 7, OpenSSL/0.9.8y, IE Mobile/10/Win Phone 8.0, IE Mobile/11/Win Phone 8.1, Java/7u25, Java/8u31, Java/6u45, Android/2.3.7
|
Supported Clients: BingPreview/Jan 2015, OpenSSL/1.0.2, YandexBot/Jan 2015, OpenSSL/1.0.1l, Yahoo Slurp/Jan 2015, Android/4.4.2, Safari/7/iOS 7.1, Safari/8/iOS 8.1.2, Safari/6/iOS 6.0.1, Safari/7/OS X 10.9, Safari/8/OS X 10.10, IE/11/Win 7, IE/11/Win 8.1, IE Mobile/11/Win Phone 8.1, Java/8u31, Android/5.0.0, Googlebot/Feb 2015, Firefox/31.3.0 ESR/Win 7, Chrome/42/OS X, Baidu/Jan 2015, Android/4.1.1, Android/4.3, Android/4.0.4, Android/4.2.2, Safari/5.1.9/OS X 10.6.8, Safari/6.0.4/OS X 10.8.4, Firefox/37/OS X, OpenSSL/0.9.8y, Java/7u25, IE Mobile/10/Win Phone 8.0, IE/8-10/Win 7, IE/7/Vista, Java/6u45, Android/2.3.7, IE/8/XP
|
||||||
|
|
||||||
PORT 995
|
PORT 995
|
||||||
--------
|
--------
|
||||||
@@ -341,62 +366,71 @@ _nassl.OpenSSLError - error:140940F5:SSL routines:ssl3_read_bytes:unexpected rec
|
|||||||
* OpenSSL Heartbleed:
|
* OpenSSL Heartbleed:
|
||||||
OK - Not vulnerable to Heartbleed
|
OK - Not vulnerable to Heartbleed
|
||||||
|
|
||||||
|
* SSLV2 Cipher Suites:
|
||||||
|
Server rejected all cipher suites.
|
||||||
|
|
||||||
* Session Resumption:
|
* Session Resumption:
|
||||||
With Session IDs: NOT SUPPORTED (0 successful, 5 failed, 0 errors, 5 total attempts).
|
With Session IDs: NOT SUPPORTED (0 successful, 5 failed, 0 errors, 5 total attempts).
|
||||||
With TLS Session Tickets: NOT SUPPORTED - TLS ticket assigned but not accepted.
|
With TLS Session Tickets: NOT SUPPORTED - TLS ticket assigned but not accepted.
|
||||||
|
|
||||||
* SSLV2 Cipher Suites:
|
|
||||||
Server rejected all cipher suites.
|
|
||||||
|
|
||||||
* TLSV1_2 Cipher Suites:
|
* TLSV1_2 Cipher Suites:
|
||||||
Preferred:
|
Preferred:
|
||||||
ECDHE-RSA-AES256-SHA ECDH-384 bits 256 bits
|
ECDHE-RSA-AES128-GCM-SHA256 ECDH-384 bits 128 bits
|
||||||
Accepted:
|
Accepted:
|
||||||
|
ECDHE-RSA-AES256-SHA384 ECDH-384 bits 256 bits
|
||||||
ECDHE-RSA-AES256-SHA ECDH-384 bits 256 bits
|
ECDHE-RSA-AES256-SHA ECDH-384 bits 256 bits
|
||||||
DHE-RSA-CAMELLIA256-SHA DH-1024 bits 256 bits
|
ECDHE-RSA-AES256-GCM-SHA384 ECDH-384 bits 256 bits
|
||||||
DHE-RSA-AES256-SHA DH-1024 bits 256 bits
|
DHE-RSA-AES256-SHA256 DH-2048 bits 256 bits
|
||||||
CAMELLIA256-SHA - 256 bits
|
DHE-RSA-AES256-SHA DH-2048 bits 256 bits
|
||||||
|
DHE-RSA-AES256-GCM-SHA384 DH-2048 bits 256 bits
|
||||||
|
AES256-SHA256 - 256 bits
|
||||||
AES256-SHA - 256 bits
|
AES256-SHA - 256 bits
|
||||||
|
AES256-GCM-SHA384 - 256 bits
|
||||||
|
ECDHE-RSA-AES128-SHA256 ECDH-384 bits 128 bits
|
||||||
ECDHE-RSA-AES128-SHA ECDH-384 bits 128 bits
|
ECDHE-RSA-AES128-SHA ECDH-384 bits 128 bits
|
||||||
DHE-RSA-CAMELLIA128-SHA DH-1024 bits 128 bits
|
ECDHE-RSA-AES128-GCM-SHA256 ECDH-384 bits 128 bits
|
||||||
DHE-RSA-AES128-SHA DH-1024 bits 128 bits
|
DHE-RSA-AES128-SHA256 DH-2048 bits 128 bits
|
||||||
CAMELLIA128-SHA - 128 bits
|
DHE-RSA-AES128-SHA DH-2048 bits 128 bits
|
||||||
|
DHE-RSA-AES128-GCM-SHA256 DH-2048 bits 128 bits
|
||||||
|
AES128-SHA256 - 128 bits
|
||||||
AES128-SHA - 128 bits
|
AES128-SHA - 128 bits
|
||||||
|
AES128-GCM-SHA256 - 128 bits
|
||||||
|
ECDHE-RSA-DES-CBC3-SHA ECDH-384 bits 112 bits
|
||||||
|
EDH-RSA-DES-CBC3-SHA DH-2048 bits 112 bits
|
||||||
|
DES-CBC3-SHA - 112 bits
|
||||||
|
|
||||||
* TLSV1_1 Cipher Suites:
|
* TLSV1_1 Cipher Suites:
|
||||||
Preferred:
|
Preferred:
|
||||||
ECDHE-RSA-AES256-SHA ECDH-384 bits 256 bits
|
ECDHE-RSA-AES128-SHA ECDH-384 bits 128 bits
|
||||||
Accepted:
|
Accepted:
|
||||||
ECDHE-RSA-AES256-SHA ECDH-384 bits 256 bits
|
ECDHE-RSA-AES256-SHA ECDH-384 bits 256 bits
|
||||||
DHE-RSA-CAMELLIA256-SHA DH-1024 bits 256 bits
|
DHE-RSA-AES256-SHA DH-2048 bits 256 bits
|
||||||
DHE-RSA-AES256-SHA DH-1024 bits 256 bits
|
|
||||||
CAMELLIA256-SHA - 256 bits
|
|
||||||
AES256-SHA - 256 bits
|
AES256-SHA - 256 bits
|
||||||
ECDHE-RSA-AES128-SHA ECDH-384 bits 128 bits
|
ECDHE-RSA-AES128-SHA ECDH-384 bits 128 bits
|
||||||
DHE-RSA-CAMELLIA128-SHA DH-1024 bits 128 bits
|
DHE-RSA-AES128-SHA DH-2048 bits 128 bits
|
||||||
DHE-RSA-AES128-SHA DH-1024 bits 128 bits
|
|
||||||
CAMELLIA128-SHA - 128 bits
|
|
||||||
AES128-SHA - 128 bits
|
AES128-SHA - 128 bits
|
||||||
|
ECDHE-RSA-DES-CBC3-SHA ECDH-384 bits 112 bits
|
||||||
|
EDH-RSA-DES-CBC3-SHA DH-2048 bits 112 bits
|
||||||
|
DES-CBC3-SHA - 112 bits
|
||||||
|
|
||||||
* TLSV1 Cipher Suites:
|
* TLSV1 Cipher Suites:
|
||||||
Preferred:
|
Preferred:
|
||||||
ECDHE-RSA-AES256-SHA ECDH-384 bits 256 bits
|
ECDHE-RSA-AES128-SHA ECDH-384 bits 128 bits
|
||||||
Accepted:
|
Accepted:
|
||||||
ECDHE-RSA-AES256-SHA ECDH-384 bits 256 bits
|
ECDHE-RSA-AES256-SHA ECDH-384 bits 256 bits
|
||||||
DHE-RSA-CAMELLIA256-SHA DH-1024 bits 256 bits
|
DHE-RSA-AES256-SHA DH-2048 bits 256 bits
|
||||||
DHE-RSA-AES256-SHA DH-1024 bits 256 bits
|
|
||||||
CAMELLIA256-SHA - 256 bits
|
|
||||||
AES256-SHA - 256 bits
|
AES256-SHA - 256 bits
|
||||||
ECDHE-RSA-AES128-SHA ECDH-384 bits 128 bits
|
ECDHE-RSA-AES128-SHA ECDH-384 bits 128 bits
|
||||||
DHE-RSA-CAMELLIA128-SHA DH-1024 bits 128 bits
|
DHE-RSA-AES128-SHA DH-2048 bits 128 bits
|
||||||
DHE-RSA-AES128-SHA DH-1024 bits 128 bits
|
|
||||||
CAMELLIA128-SHA - 128 bits
|
|
||||||
AES128-SHA - 128 bits
|
AES128-SHA - 128 bits
|
||||||
|
ECDHE-RSA-DES-CBC3-SHA ECDH-384 bits 112 bits
|
||||||
|
EDH-RSA-DES-CBC3-SHA DH-2048 bits 112 bits
|
||||||
|
DES-CBC3-SHA - 112 bits
|
||||||
|
|
||||||
* SSLV3 Cipher Suites:
|
* SSLV3 Cipher Suites:
|
||||||
Server rejected all cipher suites.
|
Server rejected all cipher suites.
|
||||||
|
|
||||||
Should Not Offer: AES128-SHA, AES256-SHA, CAMELLIA128-SHA, CAMELLIA256-SHA, DHE-RSA-CAMELLIA128-SHA, DHE-RSA-CAMELLIA256-SHA
|
Should Not Offer: AES128-GCM-SHA256, AES128-SHA, AES128-SHA256, AES256-GCM-SHA384, AES256-SHA, AES256-SHA256, DES-CBC3-SHA, DHE-RSA-AES128-GCM-SHA256, DHE-RSA-AES128-SHA, DHE-RSA-AES128-SHA256, DHE-RSA-AES256-GCM-SHA384, DHE-RSA-AES256-SHA, DHE-RSA-AES256-SHA256, ECDHE-RSA-AES128-SHA, ECDHE-RSA-AES256-SHA, ECDHE-RSA-DES-CBC3-SHA, EDH-RSA-DES-CBC3-SHA
|
||||||
Could Also Offer: DHE-DSS-AES128-GCM-SHA256, DHE-DSS-AES128-SHA256, DHE-DSS-AES256-GCM-SHA384, DHE-DSS-AES256-SHA, DHE-RSA-AES128-GCM-SHA256, DHE-RSA-AES128-SHA256, DHE-RSA-AES256-GCM-SHA384, DHE-RSA-AES256-SHA256, ECDHE-ECDSA-AES128-GCM-SHA256, ECDHE-ECDSA-AES128-SHA, ECDHE-ECDSA-AES128-SHA256, ECDHE-ECDSA-AES256-GCM-SHA384, ECDHE-ECDSA-AES256-SHA, ECDHE-ECDSA-AES256-SHA384, ECDHE-RSA-AES128-GCM-SHA256, ECDHE-RSA-AES128-SHA256, ECDHE-RSA-AES256-GCM-SHA384, ECDHE-RSA-AES256-SHA384
|
Could Also Offer: ECDHE-ECDSA-AES128-GCM-SHA256, ECDHE-ECDSA-AES128-SHA256, ECDHE-ECDSA-AES256-GCM-SHA384, ECDHE-ECDSA-AES256-SHA384
|
||||||
Supported Clients: OpenSSL/1.0.2, Firefox/31.3.0 ESR/Win 7, OpenSSL/1.0.1l, BingPreview/Jan 2015, Yahoo Slurp/Jan 2015, Baidu/Jan 2015, Safari/7/iOS 7.1, Chrome/42/OS X, Googlebot/Feb 2015, Android/4.0.4, Safari/8/iOS 8.1.2, Android/4.1.1, Android/5.0.0, Safari/6/iOS 6.0.1, YandexBot/Jan 2015, Safari/6.0.4/OS X 10.8.4, Android/4.2.2, Safari/8/OS X 10.10, Firefox/37/OS X, Safari/7/OS X 10.9, Android/4.3, Safari/5.1.9/OS X 10.6.8, Android/4.4.2, IE/8-10/Win 7, IE/7/Vista, IE/11/Win 8.1, IE/11/Win 7, OpenSSL/0.9.8y, IE Mobile/10/Win Phone 8.0, IE Mobile/11/Win Phone 8.1, Java/7u25, Java/8u31, Java/6u45, Android/2.3.7
|
Supported Clients: BingPreview/Jan 2015, OpenSSL/1.0.2, YandexBot/Jan 2015, OpenSSL/1.0.1l, Yahoo Slurp/Jan 2015, Android/4.4.2, Safari/7/iOS 7.1, Safari/8/iOS 8.1.2, Safari/6/iOS 6.0.1, Safari/7/OS X 10.9, Safari/8/OS X 10.10, IE/11/Win 7, IE/11/Win 8.1, IE Mobile/11/Win Phone 8.1, Java/8u31, Android/5.0.0, Googlebot/Feb 2015, Firefox/31.3.0 ESR/Win 7, Chrome/42/OS X, Baidu/Jan 2015, Android/4.1.1, Android/4.3, Android/4.0.4, Android/4.2.2, Safari/5.1.9/OS X 10.6.8, Safari/6.0.4/OS X 10.8.4, Firefox/37/OS X, OpenSSL/0.9.8y, Java/7u25, IE Mobile/10/Win Phone 8.0, IE/8-10/Win 7, IE/7/Vista, Java/6u45, Android/2.3.7, IE/8/XP
|
||||||
|
|
||||||
|
|||||||
@@ -1,24 +0,0 @@
|
|||||||
#!/usr/bin/python3
|
|
||||||
# Updates subresource integrity attributes in management/templates/index.html
|
|
||||||
# to prevent CDN-hosted resources from being used as an attack vector. Run this
|
|
||||||
# after updating the Bootstrap and jQuery <link> and <script> to compute the
|
|
||||||
# appropriate hash and insert it into the template.
|
|
||||||
|
|
||||||
import re, urllib.request, hashlib, base64
|
|
||||||
|
|
||||||
fn = "management/templates/index.html"
|
|
||||||
|
|
||||||
with open(fn, 'r') as f:
|
|
||||||
content = f.read()
|
|
||||||
|
|
||||||
def make_integrity(url):
|
|
||||||
resource = urllib.request.urlopen(url).read()
|
|
||||||
return "sha256-" + base64.b64encode(hashlib.sha256(resource).digest()).decode('ascii')
|
|
||||||
|
|
||||||
content = re.sub(
|
|
||||||
r'<(link rel="stylesheet" href|script src)="(.*?)" integrity="(.*?)"',
|
|
||||||
lambda m : '<' + m.group(1) + '="' + m.group(2) + '" integrity="' + make_integrity(m.group(2)) + '"',
|
|
||||||
content)
|
|
||||||
|
|
||||||
with open(fn, 'w') as f:
|
|
||||||
f.write(content)
|
|
||||||
Reference in New Issue
Block a user