2009年5月7日星期四

使用Postfix TLS突破GFW封锁

使用Postfix TLS突破GFW封锁

您是否遇到过在Google搜索突然出现该网页无法显示;
您是否遇到过突然无法访问自己公司国外的服务器,但是能ping通;
您是遇到过在使用Outlook收取邮件当收取到某一封时Outlook突然报错:
“Your server has unexpectedly terminated the connection. Possible causes for this include server problems, network problems, or a long period of inactivity. Account: 'XXX.com', Server: 'mail.XXX.com', Protocol: POP3, Port: 110, Secure(SSL): No, Socket Error: 10053, Error Number: 0x800CCC0F” 然后无法连接;
……
这一切的一切大部分都是因为GFW引起的。
.......

一、什么是GFW?
GFW是The Great Fire Wall of China的简写,指“中国网络防火墙”(字面意为“中国防火长城”),这是对“国家公共网络监控系统”的俗称,国内简称“防火长城”。
GFW是“金盾工程”的一个子功能。“金盾工程”是以公安信息网络为先导,以各项公安工作信息化为主要内容,建立统一指挥、快速反应、协同作战机制,在全国范围内开展公安信息化的工程,主要包括建设公安综合业务通信网、公安综合信息系统、全国公安指挥调度系统以及全国公共网络监控中心等。该项目2003年开始生效。一般所说的GFW,主要指公共网络监控系统,尤其是指对境外涉及敏感内容的网站、IP地址、关键词、网址等的过滤。

二、GFW工作方式
GFW是专门用来对付国外网站的,但并不是全部国外的网站都会被封锁。那什么样的网站会被GFW封锁?GFW采用什么方法封锁?
GFW主要的工作方式有以下三种:
域名劫持
全球一共有13组根(Root)级别的DNS服务器,目前中国大陆已有多台DNS镜像。但没有一组受中国大陆直接控制,所以中国大陆方面未能从根本上控制网站域名。于是,中国大陆采取域名劫持手段来进行封锁中国大陆以外的“不合规格”的站点。域名劫持就是在劫持的网络范围内拦截域名解析的请求,分析请求的域名,把审查范围以外的请求放行,否则直接返回假的IP地址或者什么也不做使得请求失去响应,其效果就是对特定的网址不能访问或访问的是假网址。
简单的说,域名劫持是阻止人们直接访问某个域名所绑定的网站。GFW采用这种手段来阻止中国大陆网民访问部分中国大陆以外的网站。例如说,一个反对中国XX党的网站地址为www.fg.com,若www.fg.com被劫持了,那么www.fg.com将无法访问。
国家入口网关的IP封锁
这个技术和上面的域名劫持有点相似,只不过域名劫持封锁的是域名,但IP封锁是直接封锁网站所在服务器的IP地址。很多对电脑比较了解的网民开始采取代理服务器的方式访问被封锁的站点,所以GFW也封锁了网民常用的一部份代理服务器的IP地址。
主干路由器关键字过滤阻断
这个技术有点复杂,那么我们来举个例子吧:
当你做飞机的时候,要进行安全检查,若你的行李里有违禁物品的话,将无法通过安检。
GFW相当于安全检查机器。当你访问一个国外网站的时候,必须经过GFW。GFW会检查目标网站的内容,若目标网站内含有敏感的词语的话,GFW将会切断你和目标网站的链接。当你使用海外的搜索引擎的时候,GFW会对你输入进搜索引擎的关键词进行审查,若你输入了敏感的关键词的话,GFW将会切断你和搜索引擎的链接。
对于邮件具体表现为:
如果邮件标题或内容有被GFW认为是所谓的敏感字符,会被GFW将数据包截获并自动抛弃,随即断开源IP与目标IP的连接,断开时间随敏感字符的严重性不等。换而言之如果公司采用NAT上网,使用pop3自动收取邮件,并且邮件服务器在国外,只要有一个被GFW认为带敏感字符的邮件,那么整个公司都将再也无法和这个server联系。

三、具体症状
Queue内出现大量无法发送至国外、HK及TW的邮件,maillog错误如下:
conversation with 111.111.0.0[111.111.0.0] timed out while sending MAIL FROM
lost connection with 111.111.0.0[111.111.0.0] while sending message body
host 111.111.0.0[111.111.0.0] said: 500 error (in reply to MAIL FROM command)

而未能收到邮件的对方却往往会收到一封或多封内容为“aaazzzaaazzzaaazzzaaazzzaaazzz”的无主题邮件

国外、HK及TW发往国内的邮件也会因为GFW而无法投递,退信显示如下错误:
Remote host said: not local; please try
551 User not local; please try

四、解决方案
A. Mail Server与MUA不在同一国家
对于服务器与MUA不在同一国家造成无法正常使用POP3、SMTP收取邮件的情况可以采用加密的Webmail (https)或POP3s、SMTPS解决。

B.国内MTA 发送邮件至国外、HK及台湾地区MTA
1).使用国外的邮件服务,比如hotmail,gmail来发送;
2).绕开GFW,或者加密通信通道。比如使用SSL加密,连接到海外邮件服务器,再转发email。或者使用VPN连接到海外,凡是发出去的emali全部走vpn通道。

本次采用Postfix的TLS实现SSL加密连接到海外邮件服务器,再转发email的方案突破GFW的封锁,经实际环境测试效果非常好。

1.TLS含义
Transport Layer Security (TLS, formerly called SSL) provides certificate-based authentication and encrypted sessions. An encrypted session protects the information that is transmitted with SMTP mail or with SASL authentication.

2.系统要求
Postfix 2.3以上并且编译支持TLS

3.具体实现
假设现有两台安装postfix的Mail Server, 主服务器在国内 (简称CN)有健全的邮件收发功能,转发服务在加拿大(简称CA),且各自拥有MX记录与Internet固IP。

1). Mail flow:
Mail (CN) => yahoo.com => postfix transport_maps (CN) => TLS => postfix (CA) => yahoo.com

2). CN主机配置

main.cf:
# relay setting via TLS
transport_maps = hash:/etc/postfix/transport_maps
smtp_tls_policy_maps = hash:/etc/postfix/tls_policy_maps

transport_maps:
yahoo.com smtp:[CA主机域名]

tls_policy_maps:
[CA主机域名] encrypt

postmap /etc/postfix/transport_maps
postmap /etc/postfix/tls_policy_maps

3). CA主机配置

main.cf:
# TLS relay config
mydestination = $mynetworks
smtpd_banner = $myhostname TLS enabled $mail_name - by extmail.org
smtpd_tls_security_level = encrypt
smtpd_use_tls = yes
smtpd_tls_auth_only = no
smtp_tls_CAfile = /etc/postfix/tls/smtpd.pem
smtp_tls_cert_file = /etc/postfix/tls/smtpd.pem
smtp_tls_key_file = /etc/postfix/tls/smtpd.pem
smtpd_tls_CAfile = /etc/postfix/tls/smtpd.pem
smtpd_tls_cert_file = /etc/postfix/tls/smtpd.pem
smtpd_tls_key_file = /etc/postfix/tls/smtpd.pem
smtpd_tls_received_header = yes
smtpd_tls_loglevel = 0
smtpd_starttls_timeout = 60s
mynetworks = 127.0.0.1 111.111.0.0 (CA主机IP)

4). TLS cert generation (CA)

mkdir /etc/postfix/tls
建立mkcert和smtpd.cnf文件,内容如下:

mkcert:
# package installation routine.
test -x /usr/bin/openssl || exit 0
prefix="/etc/postfix/tls"
if test -f /etc/postfix/tls/smtpd.pem
then
echo "$prefix/smtpd.pem already exists."
exit 1
fi
umask 077
cp /dev/null $prefix/smtpd.pem
chmod 600 $prefix/smtpd.pem
chown root $prefix/smtpd.pem
cleanup() {
rm -f $prefix/smtpd.pem
rm -f $prefix/smtpd.rand
exit 1
}
dd if=/dev/urandom of=$prefix/smtpd.rand count=1 2>/dev/null
/usr/bin/openssl req -new -x509 -days 365 -nodes \
-config $prefix/smtpd.cnf -out $prefix/smtpd.pem -keyout $prefix/smtpd.pem || cleanup
/usr/bin/openssl gendh -rand $prefix/smtpd.rand 512 >>$prefix/smtpd.pem || cleanup
/usr/bin/openssl x509 -subject -dates -fingerprint -noout -in $prefix/smtpd.pem || cleanup
rm -f $prefix/smtpd.rand

smtpd.cnf:
RANDFILE = /etc/postfix/tls/smtpd.rand
[ req ]
default_bits = 1024
encrypt_key = yes
distinguished_name = req_dn
x509_extensions = cert_type
prompt = no
[ req_dn ]
C=CN
ST=SH
L=ShangHai
O=ExtMail Server
OU=Automatically-generated SMTPD SSL key
CN=localhost
emailAddress=postmaster@extmail.org
[ cert_type ]
nsCertType = server

chmod 755 /etc/postfix/tls/mkcert
./mkcert

没有评论:

发表评论