vbox共享目录权限问题
主机是win10,客机是debian7,主机共享文件夹给客机。通常该共享目录会映射到/media目录下。但是使用dolphin无权打开改文件夹。
需要手工将当前用户(mss)加入vboxsf组:
sudo usermod -a -G vboxsf mss
注销当前用户再重新登陆后,即可正常使用共享文件夹。
修改完用户组信息后,可以使用以下命令查询用户的组信息:
groups mss
主机是win10,客机是debian7,主机共享文件夹给客机。通常该共享目录会映射到/media目录下。但是使用dolphin无权打开改文件夹。
需要手工将当前用户(mss)加入vboxsf组:
sudo usermod -a -G vboxsf mss
注销当前用户再重新登陆后,即可正常使用共享文件夹。
修改完用户组信息后,可以使用以下命令查询用户的组信息:
groups mss
最近做一个测试,模拟收发和解析一些SIP消息。方式方法很简单:将消息存在一个文本文件(.txt)中,读取该文件,然后解析、发送等操作即可。
因为是文本文件,因此想当然地就调用fopen函数”r”模式读取好了:
fopen("d:/demo.txt", "r");
然而让人惊讶的是:读取的结果和实际消息居然有差异,直接导致消息解析失败。百思不解之下不得不进行调试,结果发现丢掉了所有的’\r’符号。
从问题的现象看,感觉是windows平台的C库在读取文本文件时,擅自判断了CRLF(’\r\n’),并错误认为CR符号多余,从而跳过了所有该符号。这个处理只是猜测,对一般的文本处理当然没有问题。而对绝大部分基于文本的互联网协议而言,例如SIP、HTTP、EMAIL等,CRLF有非常重要意义,丢失CR符号无疑会产生非常严重的问题。
解决方法也很简单,就是不再当成文本文件读取,而采用二进制文件读取模式,无差别读取所有内容即可:
fopen("d:/demo.txt", "rb");
补充:在Debian中做了同样的测试。结果表明:linux系统的C库以’r’方式打开文本文件时,不会自作主张地将CR符号去掉,与预期结果一致。
Debian系统中的Dovecot套件升级了,一直工作正常,没怎么在意升级的影响。今天在syslog中看到一些告警:
dovecot: config: Warning: NOTE: You can get a new clean config file with: doveconf -n > dovecot-new.conf dovecot: config: Warning: Obsolete setting in /etc/dovecot/conf.d/auth-system.conf.ext:77: add auth_ prefix to all settings inside auth {} and remove the auth {} section completely
从告警信息看,“/etc/dovecot/conf.d/auth-system.conf.ext”有一些变化,重新修改后可以去除这个告警。比如,原文件中内容为:
auth default { socket listen { client { path = /var/spool/postfix/private/auth-dovecot mode = 0660 user = postfix group = postfix } } }
新配置修改为以下内容:
service auth { unix_listener /var/spool/postfix/private/auth-dovecot { mode = 0660 user = postfix group = postfix } }
最近在优化“语音邮箱”业务时,发现采用python-smtplib库虽然能满足需要,但是还是有很多不足,因此决定自己重新写一个库,当然仅仅实现发送email(包含附件)即可。实现一个完整的SMTP服务可能比较复杂,而实现一个单纯的、高性能的SMTP客户端发送库却比较容易。
与SIP、HTTP等协议类似,SMTP也采用文本方式定义消息格式,而附件等二进制内容,则采用base64转码成文本,这样就极为方便开发和调试。以下是SMTP最基础的几个RFC文档:
RFC5321: SMTP
RFC5322: Internet message format
RFC4954: SMTP Service Extension for Authentication
RFC3207: SMTP Service Extension for Secure SMTP over Transport Layer Security
RFC2035: Multipurpose Internet Mail Extensions
我们结合SMTP的流程,来简要说明SMTP协议中的各个关键点。
SMTP基于TCP连接,SMTP服务器默认打开的端口是25、587或者465。通常是采用25端口,后期设计加密SMTP(即SMTPS)时采用了465端口。而IANA在新业务端口规划时占用了465端口,因此将587端口定义为TLS加密的SMTP端口。
目前各email服务商通常都会同时打开25和587端口,有些为了和以前老客户端程序兼容,也会打开465端口。
这里面其实可能存在一个误解,似乎25端口就是不加密的SMTP,而587、465就是加密的SMTP。实际上不是这样,现代SMTP服务器一般都已经支持STARTTLS(即RFC3207),因此在25端口也可以启动SSL/TLS加密,这取决于客户端是否具备SSL/TLS加密、解密能力,这点在后续流程中会详细描述。
建立TCP连接,连接到服务器的25端口或者587端口。如果是25端口,则是建立普通TCP连接即可。如果是587端口,通常可以直接建立SSL/TLS连接。需要注意的是,有些SMTP服务器的587端口也是要求普通TCP连接,后续STARTTLS流程中再启动SSL/TLS加密。这种情况下,587端口的流程与25端口的流程一致。
我们的示例流程中,采用QQMail的SMTP服务器做参考,因此我们首先向“smtp.qq.com”服务器的25端口建立连接。连接成功后,服务器应返回220消息,告诉客户端连接成功:
220 smtp.qq.com Esmtp QQ Mail Server
SMTP客户端发送EHLO命令给服务器,进行初次握手协商:
EHLO 192.168.1.101
“EHLO”实际是ESMTP(Extended SMTP)的指令,意思是要进行用户名和密码的鉴权。远古时代的SMTP不需要鉴权的情况下,可以直接发送HELO命令进行握手。目前的SMTP服务器基本都是支持ESMTP,因此如果不刻意区分的话,后续的SMTP实际就是指ESMTP。
SMTP服务器器收到上述消息后,返回本服务器的一些能力信息给客户端:
250-smtp.qq.com
250-PIPELINING
250-SIZE 73400320
250-STARTTLS
250-AUTH LOGIN PLAIN
250-AUTH=LOGIN
250-MAILCOMPRESS
250 8BITMIME
其中最关键的就是STARTTLS能力,也就是该SMTP服务器具备加密连接能力。通常都建议采用加密连接以确保数据安全,毕竟互联网上总有一些黑暗势力在窥探您的信息。
如果客户端不具备SSL/TLS能力,则直接跳到“账户鉴权”流程即可。此时就不能采用PLAIN鉴权模式,必须采用MD5等加密鉴权模式。
既然服务器明确了SSL/TLS能力,因此客户端只要启动SSL/TLS加密TCP连接即可。客户端发送STARTTLS命令,通知服务器准备加密:
STARTTLS
服务器返回响应消息,通知客户端可以开始加密:
220 Ready to start TLS
接下来就是在TCP连接上建立SSL/TLS加密连接,后续通信以后都基于SSL/TLS连接。
请注意,QQMail服务器目前似乎只支持SSLv2、SSLv3加密,不支持TLSv1.0,TLSv1.1和TLSv1.2加密,其他的SMTP服务器(例如outlook、gmail等)则支持全部加密方式。
加密连接建立后,再次发送EHLO命令进行握手:
EHLO 192.168.1.101
同样,服务器返回相应能力进行响应。此时,通常不再包含STARTTLS指令了:
250-smtp.qq.com 250-PIPELINING 250-SIZE 73400320 250-AUTH LOGIN PLAIN 250-AUTH=LOGIN 250-MAILCOMPRESS 250 8BITMIME
鉴权有多种方式,其中PLAIN方式是要求所有SMTP服务器都必须具备的。在未加密的情况下,采用PLAIN方式无疑会泄露账户密码信息。而在已经加密的SSL/TLS连接里,则不存在这个问题,因此我们采用了最简单的PLAIN方式传递账户密码信息进行鉴权。
PLAIN方式很简单,采用”\0user name\0password”进行编码,然后base64转化成文本格式即可。
客户端发送以下鉴权命令:
AUTH PLAIN my_demo_base64_string_here
服务器鉴权成功,返回响应消息:
235 Authentication successful
鉴权成功后,客户端可以开始告诉服务器邮件地址信息,例如发送者、接收者等。此类消息不一一累述,请直接参考以下消息流:
MAIL From:<Iloveu@foxmail.com>
250 Ok
RCPT To:<Iloveu2@msn.com>
250 Ok
客户端发送DATA命令,告诉服务器准备提交内容:
DATA
服务器返回响应消息,通知客户端可以开始发送数据:
354 End data with <CR><LF>.<CR><LF>
由于后续数据都采用文本编码,因此标准规定用“\r\n.\r\n”标识数据发送结束,也就是SMTP服务器在上述响应消息中指示的“<CR><LF>.<CR><LF>”。
邮件采用文本格式,附件采用base64编码,可以分多次发送,以下为一个简单示例:
From: <Ilovu@foxmail.com> To: <Iloveu2@msn.com> Subject: You have a new voice mail: From 301 Day 2015-12-14 Time 10.29.7 MIME-Version: 1.0 Content-type: multipart/mixed; boundary="==491D4D07305F440E009A0125==" --==491D4D07305F440E009A0125== Content-Type: application/octet-stream Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="From 301 Day 2015-12-14 Time 10.29.7.wav" UklGRpKaAABXQVZFZm10IBIAAAAGAAEAQB8AAEAfA...... --==491D4D07305F440E009A0125==-- .
对于有附件的情况,应在Content-Type中指明boundary参数,例如本例中的“==491D4D07305F440E009A0125==”。而附件内容起始处用“–boundary参数”标识,附件结尾用“–boundary参数–”标识。
发送完数据后,服务器响应消息:
250 Ok: queued as
发送完邮件后,客户端友好地向服务器告别:
QUIT
服务器也友好地告别:
221 Bye
最后关闭TCP连接,完成整个流程。
Qt无疑是个非常好的framework,我们一直用TA。虽然不敢说已经是行家里手,不过好歹也开发这么久程序了,渐渐地有些自负起来,因此掉坑里了。
坑来自Qt最经典的设计:signal-slot。我以前的理解这是异步的,常用于模块间解耦。在windows平台,这个理解似乎没错,signal-slot底层依赖window的message机制。而在linux平台,其实现方式默认仍然是callback机制。
callback机制在多线程编程里最容易出问题的就是“锁”。这次掉坑里,就是在slot中应用“锁”时不小心,导致了死锁。
这次竟然忘了这点! :-(
简单记录一下各大常用电子邮箱服务商的SMTP服务器地址。以下邮件服务器默认都没有打开SMTP/POP功能,需要在账户设置中明确打开该项功能。
1、outlook.com,端口25或者587。用户名应为邮箱地址的全称,例如demo@msn.com等。
smtp-mail.outlook.com
2、gmail.com,端口25或者587。用户名应为邮箱地址全称,例如demo@gmail.com等。
smtp.gmail.com
gmail还要允许低安全度程序接入。似乎在google看来,SMTP属于安全度比较低的技术,尽管SMTP也是支持同样的TLS加密连接。
3、qq.com,端口为25或者587。用户名应为邮箱地址全称,例如demo@foxmail.com。
smtp.qq.com
一篇大陆学生在台湾FB发表的文章,挺有意思。新闻链接如下:
Ubuntu软件中心在安装deb软件时,对一些细节的检查比Debian要严格一些。例如,我们的软件安装包在Debian系统安装时不会提示错误,而在Ubuntu系统中则会提示错误。当然,用户可以选择忽略这些告警提示并继续安装过程,但这样始终观感不佳,因此在网上搜了一下(感谢google,鄙视百度和bing)解决方法,希望能帮到有类似问题的朋友。
这个错误最初让人感觉困惑,因为在control文件中是设置了maintainer字段的:
Maintainer: iloveu@myvoipapp.com
查到了Debian的资料,要求Maintainer字段的内容遵循RFC822规范,只写一个email地址是不对的。标准格式应当是“用户名”+email地址,例如以下格式:
Maintainer: MYVOIPAPP <iloveu@myvoipapp.com>
这个错误很容易理解,就是用户的系统中没有安装包文件的用户ID和组ID。例如,制作deb安装包的用户是John,而用户系统中没有“John”用户,则会提示这个错误。解决方法有多种,例如在制作deb安装包时切换到root用户,或者post-script中重置相关文件的用户ID和组ID等。
这些方式都有些繁琐,最简单的方式是制作deb包时使用fakeroot命令。在dpkg-deb命令前添加fakeroot即可:
fakeroot dpkg-deb -b ......
最近查看log,感觉有些无聊人士尝试干扰或者攻击FTP服务器,因此有必要将FTP服务修改为加密方式。最简单的方法就是采用TLS进行传输(即FTPS),确保传输过程是加密的。
目前系统为Debian7,已部署pureFTPd作为FTP服务器。打开TLS支持方法比较简单,请参考pureFTP over TLS文档。主要步骤如下(假定pureFTPd已经部署):
执行命令:
echo 1 > /etc/pure-ftpd/conf/TLS
设置TLS为1,运行采用overTLS以及普通不加密方式。如果要求必须使用TLS加密方式,则应设置TLS为2。实际部署中,建议设置为2。
使用openssl创建即可:
openssl req -x509 -nodes -days 7200 -newkey rsa:2048 -keyout /etc/ssl/private/pure-ftpd.pem -out /etc/ssl/private/pure-ftpd.pem
会提示各项信息输入,照着填写即可。同时,修改pem文件的属性:
chmod 600 /etc/ssl/private/pure-ftpd.pem
完成上述配置后,重启pureFTPd即可:
service pure-ftpd restart
在FileZilla的站点管理配置中,“通用 – 加密”项必须配置为“要求显式的FTP over TLS”,如附图所示即可。