Is play-mailer an smtp server - playframework-2.6

I need the functionality to send emails from my Play 2.6.x server. I found that I could use play-mailer (https://github.com/playframework/play-mailer#usage)
Question 1 - Do I need a separate smtp server or is play-mailer an smtp server itself.
Question 2 - At the moment, I am running the application on localhost but I'll eventually deploy it. Would my application work if I just use localhost in the configuration below?
play.mailer {
host = localhost // (mandatory)
port = 25 // (defaults to 25)
ssl = no // (defaults to no)
tls = no // (defaults to no)
tlsRequired = no // (defaults to no)
user = null // (optional)
password = null // (optional)
debug = no // (defaults to no, to take effect you also need to set the log level to "DEBUG" for the application logger)
timeout = null // (defaults to 60s in milliseconds)
connectiontimeout = null // (defaults to 60s in milliseconds)
mock = true// (defaults to no, will only log all the email properties instead of sending an email)
}
Question 3 - Once I deploy the application in the cloud (say AWS), do I just need to change host in the above configuration to make it work?
Question 4 - I am suppose to pass username and password in the play.mailer config. Considering that I version-control my application.conf, is it safe to enter the username and password in the file?

Answer 1:
You will need an smtp server for play.mailer to connect to. This is generally what you'll put in your host in production.
Answer 2:
Yes it should work just like that, I think you'll have to set mock = yes though.
Answer 3:
If you decide to use aws (https://aws.amazon.com/ses/), your conf will look something like this.
play.mailer {
host = "email-smtp.us-east-1.amazonaws.com" // (mandatory) - url from amazon
port = 465 // (defaults to 25)
ssl = yes // (defaults to no)
tls = no // (defaults to no)
tlsRequired = no // (defaults to no)
user = "id_from_amazon"
password = "password_from_amazon"
debug = no // (defaults to no)
timeout = null // (defaults to 60s in milliseconds)
connectiontimeout = null // (defaults to 60s in milliseconds)
mock = no // for actually sending emails. set it to yes if you want to mock.
}
Answer 4:
So the security aspect depends on what environment you're using your play server in. If application.conf is likely to be seen by somebody then you could use environment variables instead of writing it in the application.conf
password = ${APP_MAILER_PASSWORD}
and then set APP_MAILER_PASSWORD as an environment variable. Again, this isn't secure if someone can access the console of your server - but not much is at that point.

Related

Trying to set up a mail server in OpenBSD: doveadm auth login fails

I set up an OpenBSD 7.0 instance on Vultr in order to get a mail server running with Dovecot and OpenSMTPD. I (mostly) followed the instructions here and here and a bit here.
I set it up to use with virtual mail, creating files in '/etc/mail/virtual' and '/etc/mail/credentials' with a single virtual user: 'user#domain.ca::vmail:2000:2000:/var/vmail/domain.ca/user::userdb_mail=maildir:/var/vmail/domain.ca/user'
I created the encrypted password with 'smtpctl encrypt' and pasted it where it should be in the credentials file.
However, running 'doveadm auth login user#domain.ca' fails.
In /var/log/maillog I get:
Jan 25 14:06:58 vultrBSD dovecot: auth-worker(165): conn unix:auth-worker (pid=44111,uid=518): auth-worker<1>: bsdauth(user#domain.ca): unknown user
Jan 25 14:06:58 vultrBSD dovecot: auth: passwd-file(user#domain.ca): Password mismatch
I know the password is correct, and I tried changing it and pasting in a new one that I created with 'smtpctl encrypt', but still the same error. The '/etc/mail/credentials' file is set to 0440 and owned by _smtpd:_dovecot. Even temporarily setting it to 0777 doesn't work.
I can send mail to the server from another account, I see that is shows up in '/var/vmail/domain.ca/user/new' but I am unable to connect my Thunderbird client to the server. Attempting to set up a new mail account in Thunderbird doesn't seem to work, Thunderbird rejects the password (although it does detect the correct protocols and ports, IMAP/SMTP).
Here is the local.conf file in /etc/dovecot:
auth_debug_passwords = yes
auth_mechanisms = plain
first_valid_uid = 2000
first_valid_gid = 2000
mail_location = maildir:/var/vmail/%d/%n
mail_plugin_dir = /usr/local/lib/dovecot
managesieve_notify_capability = mailto
managesieve_sieve_capability = fileinto reject envelope encoded-character vacation subaddress comparator-i;ascii-numeric relational regex imap4flags copy include variables body enotify environment mailbox date index ihave duplicate mime foreverypart extracttext imapsieve vnd.dovecot.imapsieve
mbox_write_locks = fcntl
mmap_disable = yes
namespace inbox {
inbox = yes
location =
mailbox Archive {
auto = subscribe
special_use = \Archive
}
mailbox Drafts {
auto = subscribe
special_use = \Drafts
}
mailbox Junk {
auto = subscribe
special_use = \Junk
}
mailbox Sent {
auto = subscribe
special_use = \Sent
}
mailbox Trash {
auto = subscribe
special_use = \Trash
}
prefix =
}
plugin {
imapsieve_mailbox1_before = file:/usr/local/lib/dovecot/sieve/report-spam.sieve
imapsieve_mailbox1_causes = COPY
imapsieve_mailbox1_name = Junk
imapsieve_mailbox2_before = file:/usr/local/lib/dovecot/sieve/report-ham.sieve
imapsieve_mailbox2_causes = COPY
imapsieve_mailbox2_from = Junk
imapsieve_mailbox2_name = *
sieve = file:~/sieve;active=~/.dovecot.sieve
sieve_global_extensions = +vnd.dovecot.pipe +vnd.dovecot.environment
sieve_pipe_bin_dir = /usr/local/lib/dovecot/sieve
sieve_plugins = sieve_imapsieve sieve_extprograms
}
protocols = imap sieve
service imap-login {
inet_listener imaps {
port = 993
}
}
service managesieve-login {
inet_listener sieve {
port = 4190
}
inet_listener sieve_deprecated {
port = 2000
}
}
ssl_cert = </etc/ssl/domain.ca.fullchain.pem
ssl_key = </etc/ssl/private/domain.ca.key
userdb {
args = username_format=%u /etc/mail/credentials
driver = passwd-file
name =
}
passdb {
args = scheme=CRYPT username_format=%u /etc/mail/credentials
driver = passwd-file
name =
}
protocol imap {
mail_plugins = " imap_sieve"
}
Has anyone else experienced this and know of a fix?
Thanks.
Hashed strings, including passwords, typically use several layers besides the base hashing algorithm. Two different implementations (dovecot vs smtpd) using the same hashing algorithm will output two different hashes given the same input (password.)
This is due to what is called salt and pepper. Salt is a randomly generated string usually based on some user data as the seed. This salt is then inserted into the password in a way dictated by the implementation (dovecot or smtpd) before hashing the password.
Similarly, pepper is a string dictated by the implementation and inserted into the password before hashing. This combination of salting and peppering creates a unique hash per implementation which makes storing passwords safer. This makes it so that a cracker can't easily compare hashes from several sites or programs to crack user passwords and break into all instances of that password simultaneously.
This is why you can't reuse a password hash stored by one program to unlock the same password when used by another program. Even if both programs use identical hashing algorithms.
The fix should be to set up the credentials individually for each program and not reuse each other's hashes.

MQTT block specific client from connecting via TLS

I have MQTT (VerneMQ) setup with TLS authentication. Also I have setup frequent pulling
CRL (certificate revocation list) from CA (Private). I am able to revoke the specific client certificate to blocking it from connecting to MQTT.
There is one certificate which is shared & I don't want to revoke but also don't want client to be able to authenticate with MQTT. Following is my configuration
DOCKER_VERNEMQ_ACCEPT_EULA = "yes"
MY_POD_NAME = "vernemq"
DOCKER_VERNEMQ_KUBERNETES_APP_LABEL = "vernemq"
DOCKER_VERNEMQ_LOG__CONSOLE__LEVEL = "debug"
DOCKER_VERNEMQ_KUBERNETES_LABEL_SELECTOR = "app=vernemq"
DOCKER_VERNEMQ_LISTENER__TCP__ALLOWED_PROTOCOL_VERSIONS = "3,4,5"
DOCKER_VERNEMQ_ALLOW_ANONYMOUS = "on"
DOCKER_VERNEMQ_KUBERNETES_INSECURE = "1"
DOCKER_VERNEMQ_MAX_ONLINE_MESSAGES = "-1"
DOCKER_VERNEMQ_MAX_OFFLINE_MESSAGES = "-1"
DOCKER_VERNEMQ_MAX_INFLIGHT_MESSAGES = "0"
DOCKER_VERNEMQ_LISTENER__TCP__DEFAULT = "0.0.0.0:1883"
DOCKER_VERNEMQ_LISTENER__SSL__DEFAULT = "0.0.0.0:8883"
DOCKER_VERNEMQ_LISTENER__WS__DEFAULT = "0.0.0.0:8080"
DOCKER_VERNEMQ_LISTENER__HTTP__METRICS = "0.0.0.0:8888"
DOCKER_VERNEMQ_LISTENER__HTTP__DEFAULT = "0.0.0.0:8888"
DOCKER_VERNEMQ_LISTENER__SSL__REQUIRE_CERTIFICATE = "on"
# DOCKER_VERNEMQ_LISTENER__SSL__USE_IDENTITY_AS_USERNAME = "on"
DOCKER_VERNEMQ_LISTENER__SSL__CAFILE = "/vernemq/cert/ca.crt"
DOCKER_VERNEMQ_LISTENER__SSL__CERTFILE = "/vernemq/cert/server.crt"
DOCKER_VERNEMQ_LISTENER__SSL__KEYFILE = "/vernemq/cert/server.key"
DOCKER_VERNEMQ_LISTENER__SSL__CRLFILE = "/tmp/shared/ca.crl"
DOCKER_VERNEMQ_ALLOW_REGISTER_DURING_NETSPLIT = "on"
DOCKER_VERNEMQ_ALLOW_PUBLISH_DURING_NETSPLIT = "on"
DOCKER_VERNEMQ_ALLOW_SUBSCRIBE_DURING_NETSPLIT = "on"
DOCKER_VERNEMQ_ALLOW_UNSUBSCRIBE_DURING_NETSPLIT = "on"
Any way I can block the specific client certificate ?
I'm not familiar with vernemq's specific options but why not just set up the ACL to block the user represented by that certificate from being able to subscribe or publish to any topics.
Clients would still be able to connect with that shared certificate, but would not be able to receive or publish any messages.
To make this work you would probably have to use the Certificate identity as the User name (but you appear to have commented that out of the env vars you have shown in the question)

Contao: How can I change the protocol of the base url?

In Contao 3.5.9
I have uploaded to new server and am using a different domain from the original installation. I am also using https://
Many of the resources needed are not being loaded because the system has the base url set to http://
It is using the correct domain name in the base url, but the wrong protocol.
I cannot login to the admin.
I searched Google (not much there about Contao) and found this: http://blog.qzminski.com/article/move-the-contao-to-another-server.html
reading it, it seems that the base url is set in the admin, which means it can be found somewhere in the db.
I have search the DB dump but cannot find it.
How can I change the protocol of the base url?
Contao uses the following to determine whether the current request is done via SSL or not ยป \Environment::get('ssl'):
/**
* Return true if the current page was requested via an SSL connection
*
* #return boolean True if SSL is enabled
*/
protected static function ssl()
{
return ($_SERVER['SSL_SESSION_ID'] || $_SERVER['HTTPS'] == 'on' || $_SERVER['HTTPS'] == 1);
}
It is possible that your server environment does not set either of these $_SERVER globals. This can be the case if you are using an SSL proxy for example.
If that is the case for you, then you can extend the SSL detection by inserting
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && 'https' === $_SERVER['HTTP_X_FORWARDED_PROTO'])
{
$_SERVER['HTTPS'] = 1;
}
into your /system/config/initconfig.php. See https://github.com/contao/core/issues/7542 for example (only German though).

How to config Redis cache expiration with RedisSessionStateProvider?

I create a MVC sample app uses RedisSessionStateProvider as a custom session state. I set a variable into session state and it works great. But I do not know how to synchronize expiration of items in the session and Redis. Could anyone please help?
This is parameters from web.config
<!--
<add name="MySessionStateStore"
host = "127.0.0.1" [String]
port = "" [number]
accessKey = "" [String]
ssl = "false" [true|false]
throwOnError = "true" [true|false]
retryTimeoutInMilliseconds = "5000" [number]
databaseId = "0" [number]
applicationName = "MvcTestApp" [String]
connectionTimeoutInMilliseconds = "5000" [number]
operationTimeoutInMilliseconds = "1000" [number]
connectionString = "<Valid StackExchange.Redis connection string>" [String]
loggingClassName = "<Assembly qualified class name that contains logging method specified below>" [String]
loggingMethodName = "<Logging method should be defined in loggingClass. It should be public, static, does not take any parameters and should have a return type of System.IO.TextWriter.>" [String]
/>
-->
I am using lateset versions:
RedisSessionStateProvider version 1.6.4
Redis version 2.8.21
The expiration of the session items set in Redis will expire when Session will expire, you don't need to do anything about it. It will be handled by the RedisSessionStateProvider
All session state providers have no attribute about expiration. There is a HttpSessionState.Timeout
Gets and sets the amount of time, in minutes, allowed between requests before the session-state provider terminates the session.
The Timeout property cannot be set to a value greater than 525,600 minutes (1 year). The default value is 20 minutes.
So, asp.net manages for us this logic, we don't need to worry about it.
On redis client, you can use two commands keys * to see all keys, ttl <key> to see when it will be expired.

grails external configuration values are not read

I want to use external configuration in my application. Along with it I use mail plugin and want to store its configuration in external .property file. I've chaged my Config.groovy so now it looks for external configuration under USER_HOME/.grails/APP_NAME-configuration.properties:
environments {
development {
grails.logging.jul.usebridge = true
if (new File("${userHome}/.grails/${appName}-config.properties").exists()) {
println "*** User defined config ***"
grails.config.locations = ["file:${userHome}/.grails/${appName}-config.properties"]
}
}
.....
}
As you can see there is if statement which tests is the configuration file exists. It exists so every time I see "* User defined config *" message when application starts.
I'm running application in development mode. After that configuration of my mail plugin goes:
grails {
mail {
host = grailsApplication.config['mail']['host']
port = grailsApplication.config['mail']['host']
username = grailsApplication.config['mail']['username']
password = grailsApplication.config['mail']['password']
props = ["mail.smtp.auth": "true",
"mail.smtp.socketFactory.port": "465",
"mail.smtp.socketFactory.class": "javax.net.ssl.SSLSocketFactory",
"mail.smtp.socketFactory.fallback": "false"]
}
}
When I tried to send a message with email plugin it appeared that configuration of email plugin is not initialized - username, password = null and host, port have default values (localhost and -1). So it seemed to me that config.properties file is simply not loaded. I decided to check if config.properties had been loaded and found out that grailsApplication.config object contained all properties that I'd defined in config.properties: mail.host, mail.port, mail.username, mail.password. I checked if it's possible to get corresponding properties using grailsApplication.config['property']['name'] expression (in debug mode). This expression gave proper values for all mail.host, mail.port, mail.username and mail.password. I also tried to use just grailsApplication.config['property.name'] (with one pair of brackets and '.') but this variant didn't work.
Can someone help me handle this situation? I've spent almost 3 trying different variants and still don't have a solution. Thank you.
You cannot load maps from .properties file. You should use .groovy file instead of .properties.
You can load configuration from external *.groovy file where you can have maps etc. create a file with contents below...
grails {
mail {
host = smtp.gmail.com
port = 465
username = username
password = password
props = ["mail.smtp.auth" : "true",
"mail.smtp.socketFactory.port" : "465",
"mail.smtp.socketFactory.class" : "javax.net.ssl.SSLSocketFactory",
"mail.smtp.socketFactory.fallback": "false"]
}
}
And use this in your config.groovy,
grails.config.locations = ["classpath:mail-config.groovy"]

Resources