Exim: Force email auth for users of local domains - linux

I'm configuring exim4 for virutal users with dovecot and postgresql and I got a problem I cannot resolve, the situation is this:
I need that when a 'localdomain' user tries to send a email to another 'localdomain' user or foreign user, needs to authenticate, otherwise refuse the operation.
Practically I'm trying to avoid any type of smtp open relay.
Actually the smtp works fine, just need to set that requirement, and I can't find the correct way of how I can to configure exim correctly for get this behavior (Is a acl or route or transport rule?)
How could I define this configuration?
Example:
220 my-server ESMTP Exim 4.84 Thu, 31 Mar 2016 22:26:28 +0000
ehlo localhost
250-my-server Hello localhost [192.168.1.X]
250-SIZE 52428800
250-8BITMIME
250-PIPELINING
250-AUTH PLAIN LOGIN
250 HELP
mail from: a#my-server.com
250 OK
rcpt to: b#my-server.com
250 Accepted
data
354 Enter message, ending with "." on a line by itself
this must not happen, the user 'a#my-server.com' is not authenticated,
he must not be able to send any message yet until of use
of 'auth login' or 'auth plain' because is a user of local domains.
.
250 OK id=1all3Q-0004l2-V4
Example 2
220 my-server ESMTP Exim 4.84 Thu, 31 Mar 2016 22:58:56 +0000
ehlo localhost
250-my-server Hello localhost [192.168.1.X]
250-SIZE 52428800
250-8BITMIME
250-PIPELINING
250-AUTH PLAIN LOGIN
250 HELP
mail from: a#anotherserver.com
250 OK
rcpt to: user#my-server.com
250 Accepted
data
354 Enter message, ending with "." on a line by itself
this is already valid.
.
250 OK id=1allZR-00050E-Sq
ACL Config File:
acl_check_rcpt:
accept
hosts = :
control = dkim_disable_verify
.ifdef CHECK_RCPT_LOCAL_LOCALPARTS
deny
domains = +local_domains
local_parts = CHECK_RCPT_LOCAL_LOCALPARTS
message = restricted characters in address
.endif
deny
domains = !+local_domains
local_parts = CHECK_RCPT_REMOTE_LOCALPARTS
message = restricted characters in address
.endif
accept
.ifndef CHECK_RCPT_POSTMASTER
local_parts = postmaster
.else
local_parts = CHECK_RCPT_POSTMASTER
.endif
domains = +local_domains : +relay_to_domains
.ifdef CHECK_RCPT_VERIFY_SENDER
deny
message = Failed!
!acl = acl_local_deny_exceptions
!verify = sender
.endif
deny
!acl = acl_local_deny_exceptions
senders = ${if exists{CONFDIR/local_sender_callout}\
{CONFDIR/local_sender_callout}\
{}}
!verify = sender/callout
accept
hosts = +relay_from_hosts
control = submission/sender_retain
control = dkim_disable_verify
accept
authenticated = *
control = submission/sender_retain
control = dkim_disable_verify
require
message = Relay denied!
domains = +local_domains : +relay_to_domains
require
verify = recipient
deny
!acl = acl_local_deny_exceptions
recipients = ${if exists{CONFDIR/local_rcpt_callout}\
{CONFDIR/local_rcpt_callout}\
{}}
!verify = recipient/callout
deny
message = sender envelope address $sender_address is locally blacklisted here. If you think this is wrong, get in touch with postmaster
!acl = acl_local_deny_exceptions
senders = ${if exists{CONFDIR/local_sender_blacklist}\
{CONFDIR/local_sender_blacklist}\
{}}
deny
message = sender IP address $sender_host_address is locally blacklisted here. If you think this is wrong, get in touch with postmaster
!acl = acl_local_deny_exceptions
hosts = ${if exists{CONFDIR/local_host_blacklist}\
{CONFDIR/local_host_blacklist}\
{}}
accept
domains = +relay_to_domains
endpass
verify = recipient
accept

Related

Can't get the public IP of a connected client on my server

I have a very basic server written in Python as follows:
import socket
from time import sleep
import requests
c = None #Client socket1
addr = None #Client address1
server_socket1 = socket.socket() #by default it is SOCK_STREAM (TCP) and has porotocal AF_INET (IPv4)
server_socket1.bind(('127.0.0.1',9999)) #server machine's ip and port on which it will send and recieve connections from
server_socket1.listen(2) #We will only accept two connections as of now , one for each client
print("Server started successfully!!!")
print("Waiting for connections...\n\n")
while (((c is None)and(addr is None))):
if((c is None) and (addr is None)):
c,addr = server_socket1.accept()
print("Intrusion detected at address 127.0.0.1:9999 ")
print("Client connected with ip address "+str(addr))
client_ip=str(addr)
while True:
msg = c.recv(4096)
if(msg!=None):
#print(msg)
headers, sep, body = msg.partition(b'\r\n\r\n')
headers = headers.decode('utf-8')
print(headers)
html_body = "<html><body><h1>You are not authorized to acces this Page!</p><br><p>3 more attemps and your ip will be jailed!</p></body></html>"
response_headers = {
'Content-Type': 'text/html; encoding=utf8',
'Content-Length': len(html_body),
'Connection': 'close',
}
response_headers_raw = ''.join('%s: %s\r\n' % (k, v) for k, v in response_headers.items())
response_proto = 'HTTP/1.1'
response_status = '200'
response_status_text = 'OK' # this can be random
# sending all this stuff
r = '%s %s %s\r\n' % (response_proto, response_status, response_status_text)
c.sendall(r.encode())
c.sendall(response_headers_raw.encode())
c.sendall(b'\r\n') # to separate headers from body
c.send(html_body.encode(encoding="utf-8"))
I have then used ngrok to forward my port 9999 on the web. Then I execute the server.
Now, when I connect to the ngrok's provided link via my mobile phone, I get the response from my server, that is a single lined HTML content, as seen in the code itself.
But, the c,addr = socket.accept() should return the IP of the connected client. In my case, I have used my phone to connect to ngrok, which should use my phone's public IP to connect to it, still on my server side, it shows something like this:
Can someone please tell me what am I doing wrong here?
What you are seeing makes perfect sense, as the phone is not directly connected to your server (it can't be, since your server is listening on 127.0.0.1 aka localhost, so it can only accept connections that originate from the same machine).
The phone is connected to ngrok, and then ngrok is connected to your server. So you are seeing the IP that ngrok is connecting to your server from. There is simply no way for your server to get the IP of the phone, unless ngrok includes the phone's IP in the HTTP request it sends to your server, such as in an X-Forwarded-For, X-Original-Forwarded-For, X-Real-IP, etc kind of request header, which are common for proxies to send (but which I don't see in your screenshot, but it is incomplete).
--------- --------- ----------
| phone | <-> | ngrok | <-> | server |
--------- --------- ----------
^ ^
| |
desired IP is here but you are getting IP from here

How to send email with Gmail on a EC2 server

Hello I would like to send a mail from gmail with a EC2 server,
here is my python script :
#!/usr/bin/python3
# -*- coding: utf­-8 ­-*-
import smtplib
gmail_user = 'libra.corp.services#gmail.com'
gmail_password = 'pwd'
sent_from = gmail_user
to = ['aao2010#hotmail.fr']
subject = 'Value bet'
body = 'Hey, what'
email_text = """\
From: %s
To: %s
Subject: %s
%s
""" % (sent_from, ", ".join(to), subject, body)
try:
server = smtplib.SMTP_SSL('smtp.gmail.com', 465)
server.ehlo()
server.login(gmail_user, gmail_password)
server.sendmail(sent_from, to, email_text)
server.close()
print('Email sent')
except:
print('Something went wrong...')
I indicate my outbound rules on EC2 server :
SMTPS TCP 465 0.0.0.0/0 -
SMTPS TCP 465 ::/0 -
TCP personnalisé TCP 587 0.0.0.0/0 -
TCP personnalisé TCP 587 ::/0 -
Plus my gmail account is setting on "Access for less secure apps to On"
Here is the output :
Something went wrong...
in my own Python app I use the port 587 with TLS, also with smtplib. That is my only difference with your setup. Did you also try that? The e-mail sending code would boil down to this:
server = smtplib.SMTP('smtp.gmail.com:587')
server.ehlo()
server.starttls()
server.login(gmail_user, gmail_password)
server.sendmail(sent_from, to, email_text)
server.close()

O365 smtp as relay implementation

I am using the below lines of code to send an email but I get the error as 'smtplib.SMTPAuthenticationError: (535, b'5.7.3 Authentication unsuccessful' . This must be due to MFA. what can I do to authenticate?
import smtplib, ssl
port = 587 # For starttls
smtp_server = "smtp.office365.com"
sender_email = "myemail#companycom"
receiver_email = "myemail#companycom"
password = input("Type your password and press enter:")
message = """\
Subject: Hi there
This message is sent from Python."""
context = ssl.create_default_context()
with smtplib.SMTP(smtp_server, port) as server:
server.ehlo() # Can be omitted
server.starttls(context=context)
server.ehlo() # Can be omitted
server.login(sender_email, password)
server.sendmail(sender_email, receiver_email, message)
The solution to this issue is to manage the app password in your account or request for service accounts to your admin which doesn't have MFA.

"Connection unexpectedly closed" error while sending email using SES from AWS

So I'm trying to send an email to my self using SMTP and AWS. The email I'm using on my configuration is verified since I'm still using sandbox mode in SES. While running the script I keep getting the error Connection unexpectedly closed even dough I tried to connect with OpenSSL and it connected but it showed a Didn't find STARTTLS in server response, trying anyway... error after connecting.
Here is my code:
MAIL = {}
MAIL['USERNAME'] = 'AKIAXARHTFGFKCDAO7PD'
MAIL['PASSWORD'] = 'BE0tXPq8wteiKZYtgD2TgtfFTGhgFGOhUp3F0lG0uqn'
MAIL['HOST'] = 'email-smtp.eu-central-1.amazonaws.com'
MAIL['PORT'] = 465
# Set user code
code = random.randrange(000000, 999999)
# Send email to user
print(code)
print(current_user.email)
msg = MIMEMultipart('alternative')
msg['Subject'] = 'Ruby - Verification code'
msg['From'] = 'amng835#gmail.com'
msg['To'] = current_user.email
msg.attach(MIMEText(f'Your verification code is: {code}', 'plain'))
try:
server = smtplib.SMTP(MAIL['HOST'], MAIL['PORT'])
server.ehlo()
server.starttls()
server.ehlo()
server.login(MAIL('MAIL_USERNAME'), MAIL('MAIL_PASSWORD'))
server.sendmail('amng835#gmail.com', current_user.email, msg.as_string())
server.close()
except Exception as error:
print('Failed to send message to user')
print(error)
OpenSSL output:
The command:
openssl s_client -connect email-smtp.eu-central-1.amazonaws.com:465 -starttls smtp
The output:
CONNECTED(00000005)
Didn't find STARTTLS in server response, trying anyway...
write:errno=0
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 372 bytes
Verification: OK
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)
---
My documentation source:
https://docs.aws.amazon.com/ses/latest/DeveloperGuide/examples-send-using-smtp.html
There seems to have some issue with port 465.Change the code to below and it will work fine.
MAIL['PORT'] = 587

PHPMailer XOAUTH2 with gMail - SMTP Could not authenticate

I'm stuck with the following bizarre situation.
Trying to use phpMailer with gMail and xoauth2, and while the connection succeeds, just after sending the "request AUTH" command, I get back a response of "SMTP Error: Could not authenticate".
Using phpmailer 5.2.21, with oauth2 league 1.4.1 (all loaded via composer)
PHP Version: 7.0.1 (openssl is loaded)
The configuration is the following
$mailer = new PHPMailer();
$mailer->isSMTP();
$mailer->Host = 'smtp.gmail.com';
$mailer->SMTPAuth = true;
$mailer->AuthType = 'XOAUTH2';
$mailer->oauthUserEmail = $userEmail;
$mailer->oauthClientId = $clientId;
$mailer->oauthClientSecret = $clientSecret;
$mailer->oauthRefreshToken = $token;
$mailer->SMTPSecure = 'tls';
$mailer->Port = 587;
$mailer->setFrom($email);
$mailer->addAddress($recipient);
$mailer->Subject = $subject;
$mailer->Body = $message;
if (! $mailer->send())
throw new RuntimeException('Mail submission failed! ' . $mailer->ErrorInfo);
And the debug output is the following:
2017-01-05 08:14:47 Connection: opening to smtp.gmail.com:587, timeout=300, options=array ()
2017-01-05 08:14:47 Connection: opened
2017-01-05 08:14:47 SERVER -> CLIENT: 220 smtp.gmail.com ESMTP e7sm325303lfb.10 - gsmtp
2017-01-05 08:14:47 CLIENT -> SERVER: EHLO domain.tld
250-SIZE 35882577
250-8BITMIME
250-STARTTLS
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-CHUNKING
250 SMTPUTF8
2017-01-05 08:14:47 CLIENT -> SERVER: STARTTLS
2017-01-05 08:14:47 SERVER -> CLIENT: 220 2.0.0 Ready to start TLS
2017-01-05 08:14:47 CLIENT -> SERVER: EHLO domain.tld
250-SIZE 35882577
250-8BITMIME
250-AUTH LOGIN PLAIN XOAUTH2 PLAIN-CLIENTTOKEN OAUTHBEARER XOAUTH
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-CHUNKING
250 SMTPUTF8
2017-01-05 08:14:47 Auth method requested: XOAUTH2
2017-01-05 08:14:47 Auth methods available on the server: LOGIN,PLAIN,XOAUTH2,PLAIN-CLIENTTOKEN,OAUTHBEARER,XOAUTH
2017-01-05 08:14:47 SMTP Error: Could not authenticate.
2017-01-05 08:14:47 CLIENT -> SERVER: QUIT
The google app is authorized to use gmail (https://mail.google.com) and the whole process of setting up the app and getting the refresh token is successful. Moreover, I've gone over the whole phpmailer troubleshooting guide with no luck.
I'm probably missing something obvious here, but any ideas?
Thanks in advance
Yep, something simple - wrong class:
$mail = new PHPMailerOAuth;
Look at the gmail_xoauth.phps example provided with PHPMailer. Note that OAuth support will be substantially improved in PHPMailer 6.0.

Resources