利用ssh端口转发实现邮件转发

零點 2010-01-13

服务器上架设了wiki,需要根据页面修改情况向各个watch其界面的用户提交邮件报告。而该服务器位于BSO后面,级别是restrictive,即:服务器不能发起任何向外部的连接。解决此问题可以有两种方案,一种是降低BSO级别,带来的问题是需要做大量的patch工作,手续流程比较麻烦。二是利用一些tip进行。这里使用了ssh的隧道技术

1. smtp服务
wiki本身有发送邮件的功能,需要调用PHP的mail()函数,此函数是PHP默认支持的,需要OS有sendmail binary文件,并提供smtp功能。
在rhel中,默认安装sendmail作为邮件服务器,可以通过开启sendmail服务即可使用smtp服务(在以前的Red Hat版本中,smtp是不需要sendmail支持的,不过现在的OS中,必须开启sendmail服务?)。smtp服务端口是25。可以通过下述方法来进行测试:
#mail [email protected]
Subject: hello from the server
this is the body of the e-mail.
.
Cc:
其中Subject是标题,之后是邮件正文,用“.”结束正文编写。最后是抄送地址。
如果smtp功能正常,你可以在你的邮箱里面收到自己的邮件。

2. ssh隧道
ssh可以建立隧道,进行ip包转发功能。详细参见man ssh。其中需要注意的需亚打开OS中ip转发功能(?)。两个比较重要的隧道建立命令是:

ssh -C -f -N -g -R remote_port:local:port user@remotehost
可以将远端服务器一个端口remote_port绑定到本地端口port,其中-C是进行数据压缩,-f是后台操作,只有当提示用户名密码的时候才转向前台。-N是不执行远端命令,在只是端口转发时这条命令很有用处。-g 是允许远端主机连接本地转发端口。-R表明是将远端主机端口映射到本地端口。如果是-L,则是将本地端口映射到远端主机端口。

ssh -L 。。。。。。。。这个命令网上很多,大家可以参考其他地方。

两个命令主要的不同就是:-L参数用于将本地端口转发到远端主机,而-R是将远端主机端口转发到本地。


注意事项:
1. ssh隧道应该在sendmail服务之前启动,提前监听25端口。这时服务器上sendmail会提示绑定socket失败,不用理会,如果被他绑定了你就不能干活了。
2. 需要指定sendmail的realy host,修改/etc/mail/sendmail.cf 和 /etc/mail/submit.cf,其中DS字段加入自己的域名。这样sendmail不会自己乱找relay host。
3. 在/etc/sysconfig/sendmail里面可以指定sendmail为daemon状态,这里应该daemon状态,否则php不会调用sendmail。

由于我们的主机位于BSO之后,只能接受连接,因此我在自己的thinkcentre上建立到服务器上的隧道,将服务器的端口25转发到本地端口25。远端主机和本地都开启25端口及smtp服务,这样服务器中一旦apache发送邮件,则该邮件通过远端25端口转发到本地25端口,然后由本地smtp服务进行转发,从此绕开防火墙限制。

NOTEs:
某些情况下,比如其中一端机器出现异常,需要重启双方sendmail服务。这时会在转接方出现25端口无法绑定的错误。这是由于server方25端口被上一个ssh隧道占用的问题。
解决的方法是重启server方sshd服务,然后停止server sendmail服务,在转接方重新建立ssh转接,server和本地重启sendmail服务

相关推荐