内网邮件API服务部署

开源MailServer

https://www.hmailserver.com/download (for windows)
https://modoboa.org/en/ (基于Django Bootstrap Jquery for Linux)

本次部署hmailserver服务!

部署环境
  • Windows Server 2012 R2 X64
  • Mysql 5.7 https://dev.mysql.com/downloads/installer/
  • Apache2.4 https://www.apachehaus.com/cgi-bin/download.plx
  • hMailServer-5.6.7-B2425 https://cdn.mysql.com//Downloads/MySQLInstaller/mysql-installer-web-community-8.0.12.0.msi
  • PHP 7.1 https://windows.php.net/downloads/releases/php-7.1.22-Win32-VC14-x64.zip
  • MS VC14
  • libmysql
安装包准备
  • Apache httpd-2.4.34-o102o-x64-vc14.zip
  • MS VC14 vc_redist.x64.rar
  • hmailserver hmailserver-5.6.7-b2425.rar
  • php php-7.1.22-win32-vc14-x64.zip
  • Webmail webmail-lite-php-8.zip
  • libmysql libmysql.zip
  • \\xx\xx\SoftWare\开发工具\Windows平台\mysql-installer-community-5.7.17.0.msi
安装Mysql

upload successful

安装Net3
C:\Users\Administrator>dism.exe /online /enable-feature /all  /featurename:netfx3 /Source:D:\sources\sxs

upload successful

安装Hmailserver

upload successful
upload successful
upload successful
upload successful
upload successful
upload successful
upload successful
upload successful
upload successful
upload successful
upload successful
upload successful
upload successful
upload successful
upload successful

上传 libmysql.dll 32bit至如下目录C:\Program Files (x86)\hMailServer\Bin

upload successful

upload successful

upload successful

安装中文包

https://www.hmailserver.com/devnet/translation_getlanguage.php?language=chinese zh-hans.rar

C:\Program Files (x86)\hMailServer\Bin\hMailServer.INI

重启hmail服务,生效

upload successful

upload successful

upload successful

安装Apache

将下载的zip文件解压到指定目录(D:\soft\apache24)

upload successful

修改ServerRoot

Define SRVROOT "D:/Apache24"
ServerRoot "${SRVROOT}"

修改DocumentRoot

DocumentRoot "D:/Apache24/htdocs"

安装Apache

cd D:\soft\apache24\bin
httpd.exe -k install
The "Apache2.4" is successfuly installed .
Testing httpd.conf
Error: reported here must be corrected before the service can be started.

启动Apache服务

cd D:\soft\apache24\bin
net start Apache2.4
Apache2.4 服务正在启动...
Apache2.4 服务启动成功。

安装PHP

将下载的zip文件解压到指定目录(D:\soft\php-7.1.22)

upload successful

配置httpd.conf,添加PHP模块

LoadModule php7_module "D:/soft/php-7.1.22/php7apache2_4.dll"

添加扩展名

AddType application/x-httpd-php .php
AddType application/x-httpd-php-source .phps

指定php.ini配置文件路径

PHPIniDir "D:/soft/php-7.1.22"

配置php.ini.将php安装目录下的php.ini-production改名为php.ini

# 指定EXT目录,相对目录会出错!
extension_dir = "D:/soft/php-7.1.22/ext"

# 开启常用的php扩展
extension=php_mbstring.dll(php多字节字符串扩展)
extension=php_curl.dll(webmail依赖)
extension=php_mbstring.dll
extension=php_mysqli.dll(mysqli库扩展)
extension=php_openssl.dll
extension=php_pdo_mysql.dll(webmail依赖)

# 开启COM组件
com.allow_dcom = true
extension=php_com_dotnet.dll

# 设置默认时区
date.timezone = Asia/Shanghai

测试PHP,将如下代码放置网站/目录测试

<?php
phpinfo();
?>

upload successful

upload successful


Call to undefined function curl_init()错误
将php.ini中的;extension=php_curl.dll的注释去掉后,重启apache后仍然报Call to undefined function curl_init()的错误,只php安装目录下的libssh2.dll复制到apache的bin目录,并重新启动apache。
  • https://windows.php.net/download#php-7.2
  • https://www.jianshu.com/p/9d5c3a81c7ef
  • https://www.jianshu.com/p/63195ff92062
  • https://danielarancibia.wordpress.com/2015/09/27/installing-apache-2-4-and-php-7-for-development-on-windows/
安装PHPWebAdmin

https://www.hmailserver.com/documentation/latest/?page=howto_install_phpwebadmin

  • Apache or IIS (or any other PHP compatible web server)
  • PHP >= 4.3.11 or PHP >= 5.0.3. Due to bugs in PHP 4.3.10, hMailServer does not work with that version.For php version 5.3.15 / 5.4.5 and higher the COM API has been disabled as a module. The error probably will be PHP Fatal error: Class ‘COM’ not found in \phpwebadmin\initialize.php on line xx. Make sure you edit the php.ini file has been edited with the value extension=php_com_dotnet.dll in the extentions.
  • For IIS , install PHP from the Web Platform Installer, and then enable php_com_dotnet.dll from there.
  • In the PHP configuration, the following settings must be configured for PHPWebAdmin to work properly:
    • register_globals must be set to off (register_globals was deprecated and doesn’t exist from PHP 7.x)
    • display_errors must be set to off
  • For IIS 8.5 and higher, IIS App pool runs under Network Service. Network Service needs full rights to PHPWebAdmin folder which is an alternative to granting ‘read and execute’ permissions to IIS_IUSRS.
配置虚拟主机
<VirtualHost *:80>
ServerAdmin jianhu.yong@genewiz.com.cn
ServerName njmail.local.genewiz.com
DocumentRoot "C:/Program Files (x86)/hMailServer/PHPWebAdmin"
ErrorLog "logs/njmail.local.genewniz.com-error.log"
CustomLog "logs/njmail.local.genewniz.com-access.log" common

<Directory "C:/Program Files (x86)/hMailServer/PHPWebAdmin">
#
# Possible values for the Options directive are "None", "All",
# or any combination of:
# Indexes Includes FollowSymLinks SymLinksifOwnerMatch ExecCGI MultiViews
#
# Note that "MultiViews" must be named *explicitly* --- "Options All"
# doesn't give it to you.
#
# The Options directive is both complicated and important. Please see
# http://httpd.apache.org/docs/2.4/mod/core.html#options
# for more information.
#
Options Indexes FollowSymLinks

#
# AllowOverride controls what directives may be placed in .htaccess files.
# It can be "All", "None", or any combination of the keywords:
# Options FileInfo AuthConfig Limit
#
AllowOverride None

#
# Controls who can get stuff from this server.
#
Require all granted
</Directory>
</VirtualHost>
配置config.php

Please rename config-dist.php to config.php. The file is found in the PHPWebAdmin root folder.

upload successful

访问登录页 http://njmail.local.genewiz.com/phpwebadmin/

安装WebMail
  • https://afterlogic.com/docs/webmail-lite-8
  • https://afterlogic.com/docs/webmail-lite-8/configuring-webmail

将下载的webmail-lite-php-8压缩包解压后,重命名为webmail

配置虚拟主机

Alias "/webmail/" "D:/soft/webmail/"
<Directory "D:/soft/webmail/">
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
</Directory>

配置Webmail

默认账号密码
user:superadmin
password:空

检测依赖项目 http://njmail.local.genewiz.com/webmail/?install

upload successful

修改默认用户密码

upload successful

数据库设置

upload successful

开启日志监控

upload successful

添加HmailServer

upload successful


邮件API部署

upload successful

URL
# 内网邮件API
url(r'^email/', include('njemail.urls', namespace='email')),
from django.conf.urls import url
from .views import EmailApiIndexView, EmailApiView

urlpatterns = [
# 首页
url(r'^index/$', EmailApiIndexView.as_view(), name="email_index"),

# 邮件接口
url(r'^api/$', EmailApiView.as_view(), name="email_api"),
]
CODE
class EmailApiIndexView(View):
def get(self, request):
current_year = datetime.now().year
return render(request, "email-api-index.html", {
'current_year': current_year
})

def post(self,request):
current_year = datetime.now().year
email_api_test_form = EmailApiTestForm(request.POST)
if email_api_test_form.is_valid():
if request.META.has_key('HTTP_X_FORWARDED_FOR'):
ip = request.META['HTTP_X_FORWARDED_FOR']
else:
ip = request.META['REMOTE_ADDR']
email = request.POST.get('email','')
data = {
'ip': ip,
'email': [email],
'current_year': current_year
}
if SendMail(data=data, send_type='api_test'):
res = {
'status': 'success',
'msg': '测试邮件已发送!'
}
return HttpResponse(json.dumps(res, indent=4), content_type='application/json')
else:
res = {
'status': 'failer',
'msg': '邮件地址格式有误!'
}
return HttpResponse(json.dumps(res, indent=4), content_type='application/json')

class EmailApiView(CSRFExemptMixin, LoginRequiredMixin, View):
def get(self, request):
return HttpResponseRedirect(reverse("email:email_index"))

def post(self, request):
info = json.loads(request.body)
email_api_form = EmailApiForm(info)
if email_api_form.is_valid():
receivers = info['receivers']
subject = info['subject']
content = info['content']
data = {
'receivers': receivers,
'subject': subject,
'content': content
}
if SendMail(data,send_type="email_api"):
res = {
'status': 'success',
'msg': '邮件发送成功!'
}
return HttpResponse(json.dumps(res, indent=4, ensure_ascii=False), content_type='application/json')
else:
res = {
'status': 'failer',
'msg': '邮件发送失败,请联系管理员!'
}
return HttpResponse(json.dumps(res, indent=4, ensure_ascii=False), content_type='application/json')
else:
res = {
'status': 'failer',
'msg': '邮件发送失败!'
}
for i, j in email_api_form.errors.items():
res[i] = j[0]
return HttpResponse(json.dumps(res, indent=4, ensure_ascii=False), content_type='application/json')
客户端调用
# API地址
http://xx.local.genewiz.com/email/api/

# 登陆验证
login_data = {
    'username': 'username',
    'password': 'password'
}

# 获取token
res = requests.get('http://xx.local.genewiz.com/login/')
login_data['csrfmiddlewaretoken'] = res.cookies['csrftoken']

# 获取sessionid
cookies = {}
cookies['csrftoken'] = res.cookies['csrftoken']
res = requests.post('http://njops.local.genewiz.com/login/', data=login_data, cookies=cookies)
cookies['sessionid'] = res.history[0].cookies['sessionid']

# POST数据
email_data = {
    "receivers": ["test1@example.com", "test2@example.com"],
    "content": "test",
    "subject": "test"
}

# 构造请求头
headers = {'Content-Type': 'application/json'}

# 发送邮件
res = requests.post('http://xx.local.genewiz.com/email/api/', data=json.dumps(email_data), cookies=cookies, headers=headers)
# API地址
http://xx.local.genewiz.com/email/api/

# 登陆验证
login_data = {
    'username': 'username',
    'password': 'password'
}

# 获取token
res = requests.get('http://njops.local.genewiz.com/login/')
login_data['csrfmiddlewaretoken'] = res.cookies['csrftoken']

# 构造请求头
headers = {}
headers['Cookie'] = 'csrftoken='+res.cookies['csrftoken']

# 获取sessionid
res = requests.post('http://xx.local.genewiz.com/login/',data=login_data,headers=headers)
headers['Cookie'] = headers['Cookie'] + ';' + ('sessionid='+res.history[0].cookies['sessionid'])

headers['Content-Type'] = 'application/json'

# POST数据
email_data = {
    "receivers": ["test1@example.com", "test2@example.com"],
    "content": "test",
    "subject": "test"
}

# 发送邮件
res = requests.post('http://xx.local.genewiz.com/email/api', data=json.dumps(email_data), headers=headers)
# API地址
http://xx.local.genewiz.com/email/api/

# 登陆验证
login_data = {
    'username': 'username',
    'password': 'password'
}

s = requests.Session()
res = s.get('http://xx.local.genewiz.com/login/')
login_data['csrfmiddlewaretoken'] = res.cookies['csrftoken']

# 登录获取登录后的session
res = s.post('http://njops.local.genewiz.com/login/', data=login_data)

# POST数据
email_data = {
    "receivers": ["test1@example.com", "test2@example.com"],
    "content": "test",
    "subject": "test"
}

# 发送邮件
headers = {}
headers['Content-Type'] = 'application/json'
res = s.post('http://xx.local.genewiz.com/email/api/', data=json.dumps(email_data), headers=headers)
$request = new HttpRequest();
$request->setUrl('http://xx.local.genewiz.com/email/api/');
$request->setMethod(HTTP_METH_POST);

# 需要先登陆获取csrftoken sessionid(此处省略)
$request->setHeaders(array(
  'cache-control' => 'no-cache',
  'cookie' => 'csrftoken=eIWN96HiOCrxv63cUZmMV4RH91cTBWy4aKPpWrYljnu348xEfaImV67KSZAzEPR2;sessionid=u7hmxhlz3nba7sagf6sbwqhw64a7of65',
  'content-type' => 'application/json'
));

$request->setBody('{
  "receivers": ["test1@example.com", "test2@example.com"],
  "content": "test",
  "subject": "test"
}');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}
# 需要先登陆获取csrftoken sessionid(此处省略)
curl -X POST \
http://xx.local.genewiz.com/email/api/ \
-H ‘cache-control: no-cache’ \
-H ‘content-type: application/json‘ \
-H ‘cookie: csrftoken=eIWN96HiOCrxv63cUZmMV4RH91cTBWy4aKPpWrYljnu348xEfaImV67KSZAzEPR2;sessionid=u7hmxhlz3nba7sagf6sbwqhw64a7of65‘ \
-b ‘csrftoken=eIWN96HiOCrxv63cUZmMV4RH91cTBWy4aKPpWrYljnu348xEfaImV67KSZAzEPR2;sessionid=u7hmxhlz3nba7sagf6sbwqhw64a7of65‘ \
-d ‘{
“receivers”: [test1@example.com, test2@example.com],
“content”: “test”,
“subject”: “test”
}
0%