用Docker+Davmail換掉你的Outlook
簡(jiǎn)介
不管你喜歡還是不喜歡,有時(shí)候不得不通過(guò)Exchange服務(wù)器去收發(fā)郵件,但是如果你不喜歡微軟系的郵件客戶端(指Outlook),就會(huì)給你帶來(lái)一定的不便,因?yàn)槟憧赡芨鼉A向于在兼容模式下,通過(guò)IMAP收取、SMTP發(fā)送您的郵件。
...好吧,這正是davmail出現(xiàn)的原因。
davmail是一個(gè)Java應(yīng)用程序,它能在標(biāo)準(zhǔn)兼容的客戶端與Exchange服務(wù)器之間建立連接,這是一個(gè)非常棒的工具-這也是唯一的解決方案。它還是單機(jī)的,可以無(wú)狀態(tài)的使用,更有意思的是Java讓它非常適合運(yùn)行在Docker容器里面。
目標(biāo)
把Docker安裝在CenturyLink的云主機(jī)上,獲取一個(gè)無(wú)狀態(tài)的運(yùn)行davmail的容器鏡像,然后讓系統(tǒng)通過(guò)upstart來(lái)管理容器。
附加說(shuō)明
如何獲取一臺(tái)CenturyLink云主機(jī)就作為一項(xiàng)練習(xí)留給讀者。
為了簡(jiǎn)單,我們?cè)赨buntu平臺(tái)使用docker.io包來(lái)安裝docker,然后手動(dòng)配置它;當(dāng)然你還可以使用一種更方便的方式即通過(guò)puppet-git-receiver和docker Puppet Forge module這兩個(gè)工具來(lái)管理Docker安裝包和容器關(guān)于upstart的配置,關(guān)于這兩個(gè)工具的使用會(huì)在以后的教程中講述。
安全是我們最關(guān)心的問(wèn)題,尤其是在一個(gè)企業(yè)的環(huán)境中,所以請(qǐng)注意你的本地的工作站與云主機(jī)之間的連接是否安全。常見(jiàn)的和行之有效的方法包括ssh端口轉(zhuǎn)發(fā)和使用stunnel(一個(gè)不是那么隨意與方便(ad-hoc)的方法)。
無(wú)論你個(gè)人的郵件有多么不重要,也不要以明文的方式收取他們,因?yàn)檫@樣會(huì)影響到整個(gè)郵件服務(wù)器的安全,從而波及其他人。
前期準(zhǔn)備
出于這篇文章的考慮,我們假設(shè)你已經(jīng)做好了充分的準(zhǔn)備,已經(jīng)運(yùn)行了一臺(tái)基于Ubuntu-14.04的云主機(jī);如果沒(méi)有,請(qǐng)接著往下讀你可以非常容易的啟動(dòng)一臺(tái)Ubuntu機(jī)器,然后安裝Vagrant v1.6.x+和VirtualBox并進(jìn)行相關(guān)配置,我的前一篇關(guān)于Chef和Vagrant的教程會(huì)提供一些指導(dǎo),這又是給讀者留下的一個(gè)練習(xí)。
好了,準(zhǔn)備好了嗎,讓我們開(kāi)始吧!
安裝Docker
我們從Ubuntu上從安裝docker開(kāi)始:
- root@trusty:~# apt-get install docker.io
- Reading package lists... Done
- Building dependency tree
- Reading state information... Done
- The following extra packages will be installed:
- aufs-tools cgroup-lite
- Suggested packages:
- btrfs-tools debootstrap lxc rinse
- The following NEW packages will be installed:
- aufs-tools cgroup-lite docker.io
- 0 upgraded, 3 newly installed, 0 to remove and 15 not upgraded.
- Need to get 4,207 kB of archives.
- After this operation, 25.0 MB of additional disk space will be used.
- Do you want to continue? [Y/n]
- Get:1 http://archive.ubuntu.com/ubuntu/ trusty/universe aufs-tools amd64 1:3.2+20130722-1.1 [92.3 kB]
- Get:2 http://archive.ubuntu.com/ubuntu/ trusty-updates/universe docker.io amd64 1.0.1~dfsg1-0ubuntu1~ubuntu0.14.04.1 [4,111 kB]
- Get:3 http://archive.ubuntu.com/ubuntu/ trusty/main cgroup-lite all 1.9 [3,918 B]
- Fetched 4,207 kB in 8s (480 kB/s)
- Selecting previously unselected package aufs-tools.
- (Reading database ... 61703 files and directories currently installed.)
- Preparing to unpack .../aufs-tools_1%3a3.2+20130722-1.1_amd64.deb ...
- Unpacking aufs-tools (1:3.2+20130722-1.1) ...
- Selecting previously unselected package docker.io.
- Preparing to unpack .../docker.io_1.0.1~dfsg1-0ubuntu1~ubuntu0.14.04.1_amd64.deb ...
- Unpacking docker.io (1.0.1~dfsg1-0ubuntu1~ubuntu0.14.04.1) ...
- Selecting previously unselected package cgroup-lite.
- Preparing to unpack .../cgroup-lite_1.9_all.deb ...
- Unpacking cgroup-lite (1.9) ...
- Processing triggers for man-db (2.6.7.1-1) ...
- Processing triggers for ureadahead (0.100.0-16) ...
- Setting up aufs-tools (1:3.2+20130722-1.1) ...
- Setting up docker.io (1.0.1~dfsg1-0ubuntu1~ubuntu0.14.04.1) ...
- Adding group `docker' (GID 114) ...
- Done.
- docker.io start/running, process 2353
- Setting up cgroup-lite (1.9) ...
- cgroup-lite start/running
- Processing triggers for libc-bin (2.19-0ubuntu6.3) ...
- Processing triggers for ureadahead (0.100.0-16) ...
在安裝日志的第33行(注:Adding group `docker' (GID 114) ...這行),我們看到系統(tǒng)創(chuàng)建了一個(gè)docker用戶組;值得一提的是,如果把用戶加入到這個(gè)“docker用戶組”后,此后再通過(guò)命令行與docker服務(wù)(或者說(shuō)是進(jìn)程)交互的時(shí)候就不用每次在命令前面加sudo了,這同樣作為一個(gè)練習(xí)留給讀者。
#p#
創(chuàng)建或者挑選我們需要的鏡像
在Docker hub中有一些可用的davmail鏡像,我們選擇鏡像rsrchboy/davmail-savvis-docker(https://registry.hub.docker.co ... file/)理由很簡(jiǎn)單,它是一個(gè)配置好了的davmail容器:
- 他不需要掛載/綁定其他任何資源,也不需要掛載外部的數(shù)據(jù)卷(volume);
- 他是單機(jī)運(yùn)行的 ;
- 沒(méi)有以root身份運(yùn)行。
你可能需要根據(jù)Exchange的運(yùn)行環(huán)境與配置來(lái)修改此鏡像(rsrchboy/davmail-savvis-docker)中davmail的配置;如果是這樣的話,你就可以把此鏡像作為一個(gè)基礎(chǔ);把對(duì)配置的修改疊加(ADD)到它之上,然后保存成一個(gè)新的鏡像,再在新鏡像的基礎(chǔ)上重新構(gòu)建davmail服務(wù)。
下面是該鏡像的Dockerfile:
- # This software is Copyright (c) 2014 by Chris Weyl <christopher.weyl@centurylink.com>
- (That is, effectively by CenturyLinkLabs.)
- #
- This work is licensed under a Creative Commons Attribution-ShareAlike 4.0
- International License (CC-BY-SA-4.0).
- #
- http://creativecommons.org/licenses/by-sa/4.0/
- FROM gimoh/davmail:latest
- MAINTAINER Chris Weyl <christopher.weyl@centurylink.com>
- RUN mkdir /etc/davmail
- ADD davmail.properties /etc/davmail/
- add a non-root system user
- note we specify a id so as to try to avoid collisions on the host
- RUN adduser --system --uid 500 --group --home /var/lib/davmail davmail
- RUN chmod 0644 /etc/davmail/*
- ...and use it!
- USER davmail
- override default entry point as we've supplied a config
- ENTRYPOINT ["/usr/local/davmail/davmail.sh", "/etc/davmail/davmail.properties"]
實(shí)在是迫不及待了,我們先試運(yùn)行一下:
- root@trusty:~# docker run rsrchboy/davmail-savvis-docker
- 2014-09-26 18:37:32,226 INFO [main] davmail - DavMail Gateway 4.5.0-2292 listening on SMTP port 1025 POP port 1110 IMAP port 1143 CALDAV port 1080 LDAP port 1389
配置容器,通過(guò)upstart讓容器像系統(tǒng)服務(wù)一樣運(yùn)行
upstart是類unix系統(tǒng)中的一種服務(wù)管理方式,最近的Ubuntu發(fā)行版本已經(jīng)默認(rèn)采用upstart來(lái)管理系統(tǒng)服務(wù)了,它可以非常方便的實(shí)現(xiàn)我們的要求。
- Originally created by Gareth Rushgrove's puppetforge docker module
- description "start and stop corporate-davmail in docker"
- author "Chris Weyl <christopher.weyl@centurylink.com>"
- start on (started docker.io)
- stop on stopping docker.io
- setuid root
- respawn
- respawn limit 5 20
- script
- docker run --cidfile=/var/run/docker-corporate-davmail.cid \
- -p 127.0.0.1:11025:1025 \
- -p 127.0.0.1:11110:1110 \
- -p 127.0.0.1:11143:1143 \
- -p 127.0.0.1:11080:1080 \
- -p 127.0.0.1:11389:1389 \
- --net bridge \
- -m 0 \
- rsrchboy/davmail-savvis-docker \
- &&
- exec docker wait "$(cat /var/run/docker-corporate-davmail.cid)"
- end script
- post-stop script
- if [ -e "/var/run/docker-corporate-davmail.cid" ]; then
- docker kill "$(cat /var/run/docker-corporate-davmail.cid)" && \
- rm "/var/run/docker-corporate-davmail.cid"
- fi
- end script
- vim: set ft=upstart :
在這里我們要注意的關(guān)于upstart配置項(xiàng)如下(配置文件):
- 聲明docker.io服務(wù)的依賴項(xiàng)(6-7行)
- 聲明服務(wù)在異常終止時(shí)要重啟服務(wù)(11行)還有建立安全的限定(12行)
- 聲明如何啟動(dòng)(15-27行)和關(guān)閉(30-35行)服務(wù)
毋庸置疑,upstart配置中最核心的還是在docker run命令。
- docker run --cidfile=/var/run/docker-corporate-davmail.cid \
- -p 127.0.0.1:11025:1025 \
- -p 127.0.0.1:11110:1110 \
- -p 127.0.0.1:11143:1143 \
- -p 127.0.0.1:11080:1080 \
- -p 127.0.0.1:11389:1389 \
- --net bridge \
- -m 0 \
- rsrchboy/davmail-savvis-docker
在日志中我們看到,Docker的端口轉(zhuǎn)發(fā)已經(jīng)建立,davmail監(jiān)聽(tīng)的端口有:
- SMTP port 1025
- POP port 1110
- IMAP port 1143
- CALDAV port 1080
- LDAP port 1389
這里要記得 類unix系統(tǒng)中non-privliged的進(jìn)程是無(wú)法啟動(dòng)小于1024的端口的,所以我們重新做了映射。
我們告訴docker在云主機(jī)也就是宿主機(jī)上綁定端口時(shí),只綁定大于10000的端口,且只綁定在loopback上。
這樣,當(dāng)你要訪問(wèn)IMAP時(shí),你就可以再云主機(jī)上通過(guò)127.0.0.1:11143訪問(wèn),這樣就可以阻止攻擊者遠(yuǎn)程的連接你的davmail進(jìn)行攻擊。
現(xiàn)在我們已經(jīng)有了一個(gè)upstart配置文件,剩下就是如果安裝這個(gè)文件了,就是把他復(fù)制到/etc/init下,然后啟動(dòng)服務(wù):
- root@trusty:~# cp docker-corporate-davmail.conf /etc/init/
- root@trusty:~# service docker-corporate-davmail status
- docker-corporate-davmail stop/waiting
- root@trusty:~# service docker-corporate-davmail start
- docker-corporate-davmail start/running, process 4149
- root@trusty:~# docker ps
- CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
- 7f93d3b35b60 rsrchboy/davmail-savvis-docker:latest /usr/local/davmail/d 3 seconds ago Up 2 seconds 127.0.0.1:11025->1025/tcp, 127.0.0.1:11080->1080/tcp, 127.0.0.1:11110->1110/tcp, 127.0.0.1:11143->1143/tcp, 127.0.0.1:11389->1389/tcp kickass_mestorf
這個(gè)容器是無(wú)狀態(tài)的,它只是在標(biāo)準(zhǔn)的客戶端和Exchange之間做一個(gè)轉(zhuǎn)譯(translate),你可以對(duì)容器進(jìn)行啟動(dòng),關(guān)閉,終止,禁用,啟用等操作;現(xiàn)在davmail容器安全的運(yùn)行在云主機(jī)里面,你不用有其他擔(dān)心,除非客戶端到服務(wù)器的連接中斷。因此,我們解決了復(fù)雜的問(wèn)題同時(shí),還節(jié)省了我們成把的時(shí)間。
享受的時(shí)刻
到目前為止,你的davmail已經(jīng)運(yùn)行在容器里面了,通過(guò)正確的端口映射配置,現(xiàn)在你可以選擇你喜歡的客戶端去跟Exchange server 通信收發(fā)郵件了!davmail建議的客戶端是pine,當(dāng)然這只是個(gè)建議而已。