今天在做concourse发邮件这部分,一看官网上有开箱即用的resource, 心想今天能早点下班了。官方地址如下:
问题
- 根据README.md配置了关于邮件发送这块的resource,发现一直卡Dial状态,接着就超时了。
我想是官方pivotal-cf group下的,再怎么也不会出问题吧,应该是我哪里配置配的有问题,然后我又捣鼓了一个小时,还是没搞定。
pipeline配置
1 | resources: |
我的pipeline resource定义完全就是照搬的github上的样例,就是把他的587端口修改成了465,因为我司是用的阿里云邮箱,使用的是465端口,为什么就无法发送了呢?
原因分析
- 接着我选了个587端口的邮箱,gmail,发现是可以正常发送的。
- 难道是被阿里云禁止? 这个应该不可能,因为换成用python的脚本是可以正常发送,而且阿里云只禁止25端口
465端口和587端口的区别
好好的为什么会有两个端口,我就去谷歌上查了下。
- 465端口可以理解为全程走TLS,在你的本地mail sender和mail server建联的时候就是采用了TLS。
- 而587不是,587端口你可以通过明文,如果可能,则可以升级使用TLS方式发送邮件。采用的是STARTTLS协议
- 两者在行为上还是存在区别。
源码分析
https://github.com/pivotal-cf/email-resource/blob/master/out/sender.go
1 | c, err = smtp.Dial(fmt.Sprintf("%s:%s", s.host, s.port)) |
可以看到他用smtp.Dial方法去连接,然后调用StartTLS方法传入配置
如果查看smtp.Dial方法的源码,可以看到其方法是调用的net.Dial方法,这个方法并不是用来建立SSL连接的
1 |
|
解决方法
既然知道了465的行为,也就是在一开始的时候就需要去做ssl的建联,而非通过smtp.Dial,所以将代码修改如下:
https://github.com/huangyisan/email-resource/blob/master/out/sender.go
1 | if s.port == "465" { |
在建联初期,使用tls.Dial方法,传入tls的配置进行建联,得到一个conn对象,然后使用smtp.NewClient方法传入conn对象,得到*smtp.Client对象, 让该对象进行邮件发送处理。
refer
https://stackoverflow.com/questions/15796530/what-is-the-difference-between-ports-465-and-587
https://sendgrid.com/blog/whats-the-difference-between-ports-465-and-587/