albertito / chasquid Goto Github PK
View Code? Open in Web Editor NEWSMTP (email) server with a focus on simplicity, security, and ease of operation [mirror]
Home Page: https://blitiri.com.ar/p/chasquid/
License: Other
SMTP (email) server with a focus on simplicity, security, and ease of operation [mirror]
Home Page: https://blitiri.com.ar/p/chasquid/
License: Other
The 'drop_characters' config option defaults to 'drop_characters: "."' but when left empty (drop_characters: "") still drops the '.'
If we have an alias pointing to a non-existent local account Chasquid will accept the email and pass it to the MDA. Coming from Exim I was expecting that we'd notice that the resolved alias is not a valid local account and reject the email with a 550 as we'd when sending directly to such a non-existent address.
A downside of the current behavior is that by accepting the email we now have the responsibility to generate the eventual DSN.
To illustrate, let's say that we have the following in aliases:
myalias: boguslocal
where boguslocal
does not exist as a local account.
If I execute an RCPT To: [email protected]
I get the 550 as expected. However If I RCPT To: [email protected]
the email will be accepted and eventually results in a bounce message when the MDA fails to deliver it.
If chasquid.conf
contain an entry like submission_address: ""
, then chasquid will use a random port for listening for submissions.
While that is a misconfiguration, it is an easy mistake to make (by users who don't want to listen on any ports), and the result of chasquid listening on a random port can be unexpectedly dangerous.
I will add some code to make chasquid reject empty addresses, to prevent this misconfiguration from happening.
Thanks to xavierg who reported this via IRC!
I appreciate how detailed is the how-to guide to set up chasquid as an SMTP server from scratch. However, I haven't been able to get the setup to work. My smtp-check
passes successfully with chasquid running on the target server:
smtp-check example.com
2023/09/01 20:21:13 === STS policy
2023/09/01 20:21:15 Not available (lookup _mta-sts.example.com on 1.2.3.4:53: no such host)
2023/09/01 20:21:15
2023/09/01 20:21:15 === MX: 10 mail.example.com.
2023/09/01 20:21:17 SPF pass for 1.2.3.4: matched mx
2023/09/01 20:21:17 TLS OK: TLS-1.3 - TLS_AES_128_GCM_SHA256
2023/09/01 20:21:17
2023/09/01 20:21:17 === Success
Yet I've tried with a variety of email clients, including an nodejs smtp client, but get errors like the following:
When sending without encryption to port 25:
Error: SMTP server does not support the LOGIN authentication mechanism
at exports.SMTPClient.authLogin (.../node_modules/smtp-client/src/index.js:375:13)
at send (.../smtp.js:51:11)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
When submitting without security enabled to port 25:
node smtp.js
[Error: 40D82ECC117F0000:error:0A00010B:SSL routines:ssl3_get_record:wrong version number:../deps/openssl/openssl/ssl/record/ssl3_record.c:354:
] {
library: 'SSL routines',
reason: 'wrong version number',
code: 'ERR_SSL_WRONG_VERSION_NUMBER'
}
Server side:
conn.go:178 SMTP.Conn 1.2.3.4:30357: Connected, mode: SMTP
. conn.go:241 SMTP.Conn 1.2.3.4:30357: -> EHLO example.com
. conn.go:294 SMTP.Conn 1.2.3.4:30357: <- 250 poweredge - Your hour of destiny has come.\n8BITMIME\nPIPELINING\nSMTPUTF8\nENHANCEDSTATUSCODES\nSIZE 52428800\nSTARTTLS\nHELP\n
. domaininfo.go:74 DomainInfo.Reload reload: loaded 0 domains
When submitting with security enabled to port 25:
[Error: 40B8AC55587F0000:error:0A00010B:SSL routines:ssl3_get_record:wrong version number:../deps/openssl/openssl/ssl/record/ssl3_record.c:354:
] {
library: 'SSL routines',
reason: 'wrong version number',
code: 'ERR_SSL_WRONG_VERSION_NUMBER'
}
Server side:
conn.go:178 SMTP.Conn 8.8.8.8:61172: Connected, mode: SMTP
. conn.go:241 SMTP.Conn 8.8.8.8:61172: -> \x16\x03\x01\x01X\x01\x00\x01T\x03\x03]\x056�2X\t��0\x1e%\b��\x06N��퀣�
V��\b�� \xdd\xe9<\xf1K~\xa5tm\x10\xe2\xd3\xf4\x17\x9dzl\xec\xa2\b\x0fѰ9\xb0;U\x92\xbc\xee\xa1a\x00v\x13\x02\x13\x03\x13\x01\xc0/\xc0+\xc00\xc0,\x00\x9e\xc0'\x00g\xc0(\x00k\x00\xa3\x00\x9f̨̩̪\xc0\xaf\xc0\xad\xc0\xa3\xc0\x9f\xc0]\xc0a\xc0W\xc0S\x00\xa2\xc0\xae\xc0\xac\xc0\xa2\xc0\x9e\xc0\\\xc0`\xc0V\xc0R\xc0$\x00j\xc0#\x00@\xc0
. conn.go:294 SMTP.Conn 8.8.8.8:61172: <- 500 5.5.1 Unknown command
_ conn.go:298 SMTP.Conn 8.8.8.8:61172: error: unknown<\"\\x16\\x03\\x01\\x01X\\x01\"> failed: 500 5.5.1 Unknown command
. conn.go:241 SMTP.Conn 8.8.8.8:61172: -> �\x14\x009\x008�\t�\x13\x003\x002\x00������Q\x00������P\x00=\x00<\x005\x00/\x00�\x01\x00\x00�\x00\v\x00\x04\x03\x00\x01\x02\x00
. conn.go:294 SMTP.Conn 8.8.8.8:61172: <- 500 5.5.1 Unknown command
_ conn.go:298 SMTP.Conn 8.8.8.8:61172: error: unknown<\"�\\x14\\x009\\x008\"> failed: 500 5.5.1 Unknown command
. conn.go:241 SMTP.Conn 8.8.8.8:61172: -> \x00\x16\x00\x14\x00\x1d\x00\x17\x00\x1e\x00\x19\x00\x18\x01\x00\x01\x01\x01\x02\x01\x03\x01\x04\x00#\x00\x00\x00\x16\x00\x00\x00\x17\x00\x00\x00\r\x00*\x00(\x04\x03\x05\x03\x06\x03\b\a\b\b\b\t\b
. conn.go:294 SMTP.Conn 8.8.8.8:61172: <- 500 5.5.1 Unknown command
_ conn.go:298 SMTP.Conn 8.8.8.8:61172: error: unknown<\"\\x00\\x16\\x00\\x14\\x00\\x1d\"> failed: 500 5.5.1 Unknown command
_ conn.go:305 SMTP.Conn 8.8.8.8:61172: error: too many errors, breaking connection
When setting listening on port 25 as the submission address instead of as the smtp server, I get a similar error:
. domaininfo.go:74 DomainInfo.Reload reload: loaded 0 domains
E chasquid.go:195 Warning: No SMTP addresses/listeners
E chasquid.go:196 If using systemd, check that you named the sockets
E chasquid.go:195 Warning: No submission+TLS addresses/listeners
E chasquid.go:196 If using systemd, check that you named the sockets
. sts.go:493 STSCache.Refresh /var/lib/chasquid/sts-cache: 0 entries
. sts.go:521 STSCache.Refresh /var/lib/chasquid/sts-cache: refresh done
_ server.go:218 Server listening on :25 (submission)
. conn.go:178 SMTP.Conn 8.8.8.8:28672: Connected, mode: submission . conn.go:241 SMTP.Conn 8.8.8.8:28672: -> \x16\x03\x01\x01X\x01\x00\x01T\x03\x03�^\\��L?�ߝ���;��S \x1bJQa\x00F\xc
e\xf13\x14\xb0\x81\xe5
. conn.go:294 SMTP.Conn 8.8.8.8:28672: <- 500 5.5.1 Unknown command _ conn.go:298 SMTP.Conn 8.8.8.8:28672: error: unknown<\"\\x16\\x03\\x01\\x01X\\x01\"> failed: 500 5.5.1 Unknown
command . conn.go:241 SMTP.Conn 8.8.8.8:28672: -> \xb0\xd7\xf2\xfd\x8d\xdeC\x16ݫ\xf3|V\xaby\xe3b\x10\xcb\xce)BAW\xbfq\x0f\x1b1^ˣ\x00v\x13\x02\x13\x03\x13\x01\xc0/\xc0+\xc00\xc0,\x00\x9e\xc0'\x00g\xc0(\x00k\x00\xa3\x00\x9f̨̩̪\xc0\xaf\xc0\xad\xc0\xa3\
xc0\x9f\xc0]\xc0a\xc0W\xc0S\x00\xa2\xc0\xae\xc0\xac\xc0\xa2\xc0\x9e\xc0\\\xc0`\xc0V\xc0R\xc0$\x00j\xc0#\x00@\xc0
. conn.go:294 SMTP.Conn 8.8.8.8:28672: <- 500 5.5.1 Unknown command
_ conn.go:298 SMTP.Conn 8.8.8.8:28672: error: unknown<\"\"> failed: 500 5.5.1 Unknown command . conn.go:241 SMTP.Conn 8.8.8.8:28672: -> �\x14\x009\x008�\t�\x13\x003\x002\x00������Q\x00������P\x00=\x00<\x005\
x00/\x00�\x01\x00\x00�\x00\v\x00\x04\x03\x00\x01\x02\x00
. conn.go:294 SMTP.Conn 8.8.8.8:28672: <- 500 5.5.1 Unknown command
_ conn.go:298 SMTP.Conn 8.8.8.8:28672: error: unknown<\"�\\x14\\x009\\x008\"> failed: 500 5.5.1 Unknown command
_ conn.go:305 SMTP.Conn 8.8.8.8:28672: error: too many errors, breaking connection
. domaininfo.go:74 DomainInfo.Reload reload: loaded 0 domains
. domaininfo.go:74 DomainInfo.Reload reload: loaded 0 domains
I noticed what appears to be a warning, No submission+TLS addresses/listeners
, No SMTP addresses/listeners
, not sure if this is relevant since the process is indeed listenting on the port specified in the chasquid.conf
file.
Since v1.12, the git tags are not annotated anymore. This may be the reason why there are no container images available for 1.12 and 1.13. Is this intended?
I am trying this on my ubuntu server. I serve several domains from this service, so using certbot does not scare me.
But I want to try it, at first, without messing with the DNS stuff. I will try this and, perhaps, suggest changes to documentation.
I think a bit added to the install/config docs can show:
I think this would be a good thing to add.
There is a new SMTP smuggling attack published recently.
It involves the server incorrectly parsing the end of DATA marker \r\n.\r\n
, which an attacker can exploit to impersonate a server when email is transmitted server-to-server.
There's also more information about it in the Postfix SMTP smuggling page.
Since the attack is already public, I'm filing this issue to track doing a review of chasquid's DATA parsing code to make sure it is not exposed to the problem, and if so, fix it.
I will do a review today, and will update this issue once I know more.
Thanks to Lorenz Schori (@znerol) for notifying me about this!
In the README which was generated inside /etc/chasquid/certs
, it is recommended using a symlink to point to /etc/letsencrypt/live/rapidev.org/{privkey,fullchain}.pem
Note the directory structure matches certbot's structure, so if you use it you can just create symlinks to /etc/letsencrypt/live/.
This is a great idea! Especially since my certs need regen every 90 days. I have a lot of subdomains, which equates to an entire day of headache every few months. Each cuttable corner is a blessing!
The issue is that the very next line in the README states:
Note also that the certificates and private keys must be readable by the chasquid user.
I don't see how these (symlinking and readability) can coexist when we arent allowed to change the modes of the files in /etc/letsencrypt/live. Ive already created softlinks with ln -s
, but soft links look at the original for permissions.
For example, the filemode for my linked files are now 777 ( rwxrwxrwx ), yet cat fullchain.pem
still outputs "permission denied."
The only workaround I can think of is to remove the -s
flag from the ln
command, but this is pointless because then the certs will not auto-update when I update the originals, and that is the only reason for linking in the first place. Is their a way around this?
Thanks in advance for your help! And for the MTA!
Some use cases, like receive-only MTAs, need domain users for receiving emails, but have no real need for passwords since they will never use submission.
Today, that is not supported, and those use-cases require the administrator to come up with a password unnecessarily, adding complexity and possibly risk.
chasquid's userdb could be extended to support users that don't have a valid password, thus exist for the purposes of delivering mail, but always fail authentication. chasquid-util user-add
would also need extending accordingly.
Thanks to xavierg who suggested this feature on IRC.
I just spend some time googling to figure out who Asmodeus is before I realized what the error message is about. For me it was caused by using ssmtp, which always issued a AUTH LOGIN
. Switching to msmtp works just fine for sending my first test emails to chasquid.
So my point is: I love and appreciate the whimsey and wish more projects showed a human touch in their outputs, but for a non-expert in SMTP error codes, I would have also appreciated either a more straight forward error message or, as a compromise, a more clear warning log line on stderr.
Just a suggestion though. ❤️
Thanks for this cool piece of software!
I was trying to get the hooks working, but they seem to be ignored. My /etc/chasquid/hooks
folder looks like this:
-rwxr-xr-x+ 1 chasquid chasquid 116 Feb 5 13:23 alias-exists*
-rwxr-xr-x+ 1 chasquid chasquid 92 Feb 5 13:12 alias-resolve*
-rwxr-xr-x+ 1 chasquid chasquid 2.2K Jan 19 2019 post-data*
alias-exists:
#!/bin/bash
set -e
logger "Called alias-exists"
exit 1
alias-resolve:
#!/bin/bash
set -e
logger "Called alias-resolve"
When I run chasquid-util aliases-resolve "[email protected]"
I expect the syslog to show my two log strings, but it doesn't. When I try to send an email to the server, nothing happens either. What am I missing here?
When the chasquid docker container is restarted, either manually or by docker, the entrypoint.sh echos the configuration option "hostname: < actual hostname >" into the chasquid.conf again resulting in:
Recreating chasquid ... done
Attaching to chasquid
chasquid | _ chasquid.go:70 chasquid starting (version undefined)
chasquid | ☠ chasquid.go:77 Error loading config: parsing config: proto: (line 28:1): non-repeated field "hostname" is repeated
this is simply due to this line in entrypoint.sh:
# Pick the default domain as default hostname for chasquid. This is only used
# in plain text sessions and on very rare cases, and it's mostly for aesthetic
# purposes.
echo "hostname: '$ONE_DOMAIN'" >> /etc/chasquid/chasquid.conf
I get this message when running chasquid tests while building Arch Linux package:
t-11-dovecot ...
Fatal: mkdir(/var/lib/dovecot) failed: Permission denied
FAILED: user does not exist: no: dial unix /tmp/chasquid-dovecot-test/run/auth-userdb: connect: no such file or directory
Dovecot version is 2.3.19.1 (9b53102964)
.
I believe state_dir should be set in dovecot.conf to fix this. I fixed a similar issue in maddy recently.
Given the following config:
$ grep drop_character chasquid.conf
drop_characters: "."
$ grep myself domains/example.com/aliases
me.myself: me
The alias [email protected]
will never be expanded to me
. I guess that drop_characters
gets applied to the recipients address before the alias lookup is performed. In order to work around this, it is currently necessary to specify the alias without any characters specified in drop_characters
. I.e.:
$ grep drop_character chasquid.conf
drop_characters: "."
$ grep myself domains/example.com/aliases
memyself: me
Not sure whether this should be solved in code or maybe in the docs.
I use gmail for receive emails, I just want run a self-host smtp server that I can send emails without limit
I've already configured spf with my own server's ip address
❯ nslookup -type=txt _spf.user.tax
_spf.user.tax text = "v=spf1 ip4:62.171.170.189 ip6:2a02:c207:2098:9386::1 ~all"
❯ nslookup -type=txt user.tax
user.tax text = "[email protected]"
user.tax text = "v=spf1 a mx include:_spf.user.tax include:_spf.google.com include:spf.forwardemail.net ~all"
My question now is how to run chasquid without dovecot?
Is there any tutorial or example code like this How To Install and Configure Postfix as a Send-Only SMTP Server on Ubuntu 22.04
Because I think I don't need to use dovecot.
I want to use chasquid in my cloud environment (k8s) and had a look at the bundled Dockerfile, however, there is an issue:
in entrypoint.sh there is an assumption, that certificates are located inside the Docker container, or created on its filesystem.
However, it's not applicable in my use case: i want the certificates to be managed/renewed by cert-manager and i want just mount them into chasquid's container, but in this case the setfacl
logic is not working.
@albertito Can you suggest here something? Should i use my own version of Dockerfile / entrypoint.sh?
In case of multi-homed servers (having multiple public interfaces, with multiple default routes but using routing policies) it would be useful to have an option to specify the local IP address that should be used to connect from (i.e. bind(local_address)
then connect(remote_address)
).
This should be configurable through the configuration file, for example: smtp_local_address = "9.9.9.9"
.
In fact, by default this IP address should be initialized with the IP from smtp_address
, as most likely the IP used to accept inbound SMTP connections should also be used for outbound SMTP connections. (And in case that is missing, just use 0.0.0.0
as it currently is.)
Looking at the source code, I assume that one could just change:
https://github.com/albertito/chasquid/blob/master/internal/courier/smtp.go#L128
conn, err := net.DialTimeout("tcp", mx+":"+*smtpPort, smtpDialTimeout)
with
localAddress = ...
remoteAddress, err := net.ResolveTCPAddr("tcp", mx+":"+*smtpPort)
...
conn, err := net.DialTcp("tcp", localAddress, remoteAddress)
...
However that loses the smtpDialTimeout
functionality.
Or perhaps using the net.Dialer
type, although that might be somewhat more complex.
Hi
Some sites do not allow the usage of +
in email addresses (they are considered invalid). It'd be great if I could specify that any email[1] should be redirected to another's address:
*: david@mail
[1]: Ideally a * means that any email not matching an existing account (and alias?) gets forwarded, but that is not important for me
os: centos 7
go version: go1.12.7 linux/amd64
git clone https://blitiri.com.ar/repos/chasquid
cd chasquid
make
make install-binaries
make install-config-skeleton
add user
chasquid-util user-add [email protected] --password=123456
I had register a https cert and repalce it
cp 3339730_mail.hyahm.com.key fullchain.pem
cp 3339730_mail.hyahm.com.pem privkey.pem
start service
systemctl restart chasquid
tree of /etc/chasquid
[root@hyahm chasquid]# tree
.
├── certs -> /etc/letsencrypt/live/
├── chasquid.conf
├── domains
│ └── hyahm.com
│ └── users
├── hooks
│ └── post-data
└── README
[root@hyahm certs]# pwd
/etc/chasquid/certs
[root@hyahm certs]# tree
.
└── hyahm.com
├── 3339730_mail.hyahm.com.key
├── 3339730_mail.hyahm.com_nginx.zip
├── 3339730_mail.hyahm.com.pem
├── cert.pem -> ../../archive/hyahm.com/cert2.pem
├── chain.pem -> ../../archive/hyahm.com/chain2.pem
├── fullchain.pem -> ../../archive/hyahm.com/fullchain2.pem
├── privkey.key
└── privkey.pem -> ../../archive/hyahm.com/privkey2.pem
1 directory, 8 files
[root@hyahm domains]# ls
hyahm.com
[root@hyahm domains]# tree
.
└── hyahm.com
└── users
1 directory, 1 file
check
[root@hyahm domains]# smtp-check hyahm.com
2020/01/06 12:11:31 === STS policy
2020/01/06 12:11:31 Not available (MTA-STS TXT record missing)
2020/01/06 12:11:31
2020/01/06 12:11:31 === MX: 1 mail.hyahm.com.
2020/01/06 12:11:33 SPF fail for 120.26.164.125: matched 'all'
2020/01/06 12:11:34 read tcp 120.26.164.125:45182->120.26.164.125:25: read: connection reset by peer
#!/usr/bin/python3
import smtplib
from email.mime.text import MIMEText
from email.header import Header
# 第三方 SMTP 服务
mail_host="mail.hyahm.com" #设置服务器
mail_user="[email protected]" #用户名
mail_pass="123456" #口令
sender = '[email protected]'
receivers = ['[email protected]'] # 接收邮件,可设置为你的QQ邮箱或者其他邮箱
message = MIMEText('Python 邮件发送测试...', 'plain', 'utf-8')
message['From'] = Header("菜鸟教程", 'utf-8')
message['To'] = Header("测试", 'utf-8')
subject = 'Python SMTP 邮件测试'
message['Subject'] = Header(subject, 'utf-8')
try:
smtpObj = smtplib.SMTP()
smtpObj.connect(mail_host, 465) # 25 为 SMTP 端口号
smtpObj.login(mail_user,mail_pass)
smtpObj.sendmail(sender, receivers, message.as_string())
print ("邮件发送成功")
except smtplib.SMTPException as e:
print(e)
print ("Error: 无法发送邮件")
In #46, @erjoalgo kindly pointed out that client configuration can be frustrating and/or require a fair amount of tinkering, in part due to chasquid's tradeoffs (such as selection of auth methods, TLS enforcement, etc.).
We could have a "Clients" section in the documentation with summary of key config options or specific advice to help set up different common clients, to reduce friction when setting up chasquid.
I'm probably going to work on this towards the end of January. If anyone has some suggestions in the meantime, please feel free to comment in this bug! It doesn't have to be tidy or polished, I will do that as needed when writing the document.
Receiving DATA is not necessary for some checks such as greylisting or DNSBL lookup. Please consider adding pre-DATA hooks to avoid wasting traffic for messages that will be discarded anyway.
Hello, I hope 2020 hasn't treated you too horribly.
I've been using chasquid for a while with a custom docker setup, and my only nit left is when my certificate expires, chasquid doesn't reload it on its own.
The solution recommended in the how-to is to use a certbot hook. Unfortunately I can't use that as is because certbot and chasquid run in different containers and only "communicate" via the shared certs directory.
I think adding a FS watcher is overkill (and I'm not even sure it would work across overlayfs/docker volumes), but maybe an HTTP endpoint would be fine.
Because of my setup, the HTTP endpoint wouldn't need to be authenticated as I can not expose it to the internet, just to the docker network. So adding an insecure /api
endpoint disabled by default could be a simple solution.
Would you be willing to merge something like that? Or have a better idea?
Hi,
i have a question about configuration.
For instance, i've already got "foo@mydomain" and "bar@mydomain" addresses defined in my configuration for some specific users, but i want to have a "catch all" rule, which catches mails sent to unresolvable user (e.g. "unknown@mydomain") and delivers them to some configured user (like, mine)?
Is that possible to configure such kind of "catch all" rule for aliases?
This is not necessarily an issue (but could be) but more of a hint for anyone who struggles with spamc not being able to connect to spamd.
At least on Ubuntu SpamAssassin comes (at least on 16.04, don't know how it is with newer versions) per default set up to use a socket. But that's something chasquid seems not to expect and therefor spamc will fail.
The call of spamc in the post-data hook (in the chasquid configs) needs to be adjusted accordingly --socket /YourSocketPath
).
As I said, this was meant primarily for anyone who runs into the same problem, so they don't have to figure it all out themselves.
BUT maybe just as an idea: since chasquid anyways checks whether spamc exists - maybe check whether spamd is running and if so on which port/socket and adjust the call automatically. I don't know how easy this can be done to work on all of the supported platforms (does netstat look everywhere the same? does spamc even call necessarily spamd or could it also call other daemons, or is spamd even called on every system spamd?)
This is forked from issue #17, where @DiederikvandenB reported that chasquid-util aliases-resolve
does not take hooks into account, and that is confusing and misleading.
At minimum, the documentation should mention this fact, and possibly a warning should be emitted if the hooks are present.
There is no way to manually do an alias resolution with hooks for troubleshooting (other than sending an email, of course), which should also be fixed.
Hi,
i was looking for your code and I noticed this piece of code for DNS lookup error handling in file smtp.go
:
if err != nil {
// There was an error. It could be that the domain has no MX, in which
// case we have to fall back to A, or a bigger problem.
// Unfortunately, go's API doesn't let us easily distinguish between
// them. For now, if the error is permanent, we assume it's because
// there was no MX and fall back, otherwise we return.
// TODO: Find a better way to do this.
dnsErr, ok := err.(*net.DNSError)
if !ok {
tr.Debugf("MX lookup error: %v", err)
return nil, err
} else if dnsErr.Temporary() {
tr.Debugf("temporary DNS error: %v", dnsErr)
return nil, err
}
// Permanent error, we assume MX does not exist and fall back to A.
tr.Debugf("failed to resolve MX for %s, falling back to A", domain)
mxs = []string{domain}
According to go docs, DNSError struct has now a IsNotFound
field that can help improve the code accordig to your comment! What do you think?
type DNSError struct {
Err string // description of the error
Name string // name looked for
Server string // server used
IsTimeout bool // if true, timed out; not all timeouts set this
IsTemporary bool // if true, error is temporary; not all errors set this; added in Go 1.6
IsNotFound bool // if true, host could not be found; added in Go 1.13
}
I was looking at your code for inspiration since I'm working on a custom smtp sender! I was wondering what is the correct way to handle temporary DNS error: Maybe I can simply wait some time (e.g., 1 sec) and retry, but I do not understand if there is a better approach to do so!
Ever considered some integration of jmap?
I configured a smtp only chasquid ( with host user.tax
, base on #30 ) , I use forwardemail.net forword email to gmail for receive mail (it already works)
chasquid send to any other email ( for example [email protected] ) address is ok
but send to [email protected]
will cause error :
Can't send mail - all recipients were rejected: 550 5.1.1 Destination address is unknown (user does not exist)
how to config chasquid fix this ?
lib/shared/index.js:629 › [2022-10-08 08:07:23] DEBUG Creating transport: nodemailer (6.8.0; +https://nodemailer.com/; SMTP/6.8.0[client:6.8.0])
lib/shared/index.js:629 › [2022-10-08 08:07:23] DEBUG Sending mail using SMTP/6.8.0[client:6.8.0]
lib/shared/index.js:629 › [2022-10-08 08:07:23] DEBUG [4EQYKNFOGCE] Resolved smtp.user.tax as 62.171.170.189 [cache miss]
lib/shared/index.js:629 › [2022-10-08 08:07:24] INFO [4EQYKNFOGCE] Secure connection established to 62.171.170.189:465
lib/shared/index.js:629 › [2022-10-08 08:07:26] DEBUG [4EQYKNFOGCE] S: 220 smtp.user.tax ESMTP chasquid
lib/shared/index.js:629 › [2022-10-08 08:07:26] DEBUG [4EQYKNFOGCE] C: EHLO mac.local
lib/shared/index.js:629 › [2022-10-08 08:07:29] DEBUG [4EQYKNFOGCE] S: 250-smtp.user.tax - Your hour of destiny has come.
lib/shared/index.js:629 › [2022-10-08 08:07:29] DEBUG [4EQYKNFOGCE] S: 250-8BITMIME
lib/shared/index.js:629 › [2022-10-08 08:07:29] DEBUG [4EQYKNFOGCE] S: 250-PIPELINING
lib/shared/index.js:629 › [2022-10-08 08:07:29] DEBUG [4EQYKNFOGCE] S: 250-SMTPUTF8
lib/shared/index.js:629 › [2022-10-08 08:07:29] DEBUG [4EQYKNFOGCE] S: 250-ENHANCEDSTATUSCODES
lib/shared/index.js:629 › [2022-10-08 08:07:29] DEBUG [4EQYKNFOGCE] S: 250-SIZE 52428800
lib/shared/index.js:629 › [2022-10-08 08:07:29] DEBUG [4EQYKNFOGCE] S: 250-AUTH PLAIN
lib/shared/index.js:629 › [2022-10-08 08:07:29] DEBUG [4EQYKNFOGCE] S: 250 HELP
lib/shared/index.js:629 › [2022-10-08 08:07:29] DEBUG [4EQYKNFOGCE] SMTP handshake finished
lib/shared/index.js:629 › [2022-10-08 08:07:29] DEBUG [4EQYKNFOGCE] C: AUTH PLAIN AGlAdXNlci50YXgALyogc2VjcmV0ICov
lib/shared/index.js:629 › [2022-10-08 08:07:30] DEBUG [4EQYKNFOGCE] S: 235 2.7.0 Authentication successful
lib/shared/index.js:629 › [2022-10-08 08:07:30] INFO [4EQYKNFOGCE] User "[email protected]" authenticated
lib/shared/index.js:629 › [2022-10-08 08:07:30] INFO Sending message <[email protected]> to <[email protected]>
lib/shared/index.js:629 › [2022-10-08 08:07:30] DEBUG [4EQYKNFOGCE] C: MAIL FROM:<[email protected]>
lib/shared/index.js:629 › [2022-10-08 08:07:30] DEBUG [4EQYKNFOGCE] S: 250 2.1.5 You feel like you are being watched
lib/shared/index.js:629 › [2022-10-08 08:07:30] DEBUG [4EQYKNFOGCE] C: RCPT TO:<[email protected]>
lib/shared/index.js:629 › [2022-10-08 08:07:30] DEBUG [4EQYKNFOGCE] S: 550 5.1.1 Destination address is unknown (user does not exist)
lib/shared/index.js:629 › [2022-10-08 08:07:30] DEBUG [4EQYKNFOGCE] Closing connection to the server using "end"
lib/shared/index.js:629 › [2022-10-08 08:07:30] ERROR Send error for <[email protected]>: Can't send mail - all recipients were rejected: 550 5.1.1 Destination address is unk
nown (user does not exist)
The golang net/smtp
package defaults to localhost
for the EHLO
local name unless specified otherwise using the c.Hello func.
Some MTA do reject client connections unless the local name at least looks like an fqdn. Extract from a sample run:
2023/07/14 16:08:19 === MX: 10 [...].
2023/07/14 16:08:19 SPF pass for [...]: matched ip
2023/07/14 16:08:24 TLS error: 550 Server name localhost is not a FQDN.
Please contact your ISP or system adminstrator.
2023/07/14 16:08:24 Allowed by policy
I'm trying to install chasquid-1.6-1 on Arch Linux and i'm getting following error:
==> Starting check()...
? blitiri.com.ar/go/chasquid [no test files]
? blitiri.com.ar/go/chasquid/cmd/chasquid-util [no test files]
? blitiri.com.ar/go/chasquid/cmd/dovecot-auth-cli [no test files]
? blitiri.com.ar/go/chasquid/cmd/mda-lmtp [no test files]
? blitiri.com.ar/go/chasquid/cmd/smtp-check [no test files]
? blitiri.com.ar/go/chasquid/cmd/spf-check [no test files]
ok blitiri.com.ar/go/chasquid/internal/aliases (cached)
ok blitiri.com.ar/go/chasquid/internal/auth (cached)
ok blitiri.com.ar/go/chasquid/internal/config (cached)
ok blitiri.com.ar/go/chasquid/internal/courier (cached)
ok blitiri.com.ar/go/chasquid/internal/domaininfo (cached)
ok blitiri.com.ar/go/chasquid/internal/dovecot (cached)
ok blitiri.com.ar/go/chasquid/internal/envelope (cached)
ok blitiri.com.ar/go/chasquid/internal/expvarom (cached)
ok blitiri.com.ar/go/chasquid/internal/haproxy (cached)
ok blitiri.com.ar/go/chasquid/internal/maillog (cached)
ok blitiri.com.ar/go/chasquid/internal/normalize (cached)
ok blitiri.com.ar/go/chasquid/internal/protoio (cached)
? blitiri.com.ar/go/chasquid/internal/protoio/testpb [no test files]
ok blitiri.com.ar/go/chasquid/internal/queue (cached)
ok blitiri.com.ar/go/chasquid/internal/safeio (cached)
ok blitiri.com.ar/go/chasquid/internal/set (cached)
ok blitiri.com.ar/go/chasquid/internal/smtp (cached)
ok blitiri.com.ar/go/chasquid/internal/smtpsrv (cached)
ok blitiri.com.ar/go/chasquid/internal/sts (cached)
ok blitiri.com.ar/go/chasquid/internal/testlib (cached)
ok blitiri.com.ar/go/chasquid/internal/tlsconst (cached)
? blitiri.com.ar/go/chasquid/internal/trace [no test files]
ok blitiri.com.ar/go/chasquid/internal/userdb (cached)
? blitiri.com.ar/go/chasquid/test/util [no test files]
t-01-simple_local ...
.msmtp-bin: cannot locate host testserver: Name or service not known
.msmtp-bin: could not send mail (account default from msmtprc)
==> ERROR: A failure occurred in check().
Aborting...
So it looks to me like some test is not passing while installation and therefore whole procedure fails.
I've observed that in safeio.WriteFile
, line 41, if err = tmpf.Chown(uid, gid); err != nil {
is called, regardless if the temporary file has the expected UID/GID or not. In practice, as long as one chown
's to the same user / group, nothing usually happens, however,
However, when trying to run chasquid
under systemd
with a strict SECCOMP filter (one that doesn't allow chown
and related functions), chasquid
is killed.
chasquid/internal/safeio/safeio.go
Lines 41 to 47 in 795f2a7
I'm not sure if this is an actual bug, because it's hit only in such corner-cases as when running under SECCOMP. However, I don't think chasquid
should try to touch files in non-standard ways, especially configuration files (that happened to trigger the issue above). (The issue was triggered by a STS state file update.)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.