由于RDP远程桌面功能非常方便,但又存在较高风险,只能通过提高安全防护,避免造成损失。
本文记录一种邮件提醒远程登陆的方法和过程。
工作原理:
1.利用windows的计划任务功能,当远程登陆的时候,调用指定的程序;
2.此处调用的是python脚本,利用python来完成发送邮件的功能;
3.在python脚本中调用一个EXE小程序来获取登陆信息(用户名,客户端名称等信息),


第一步:

写一个EXE小工具,获取远程登陆信息
使用C语言编写,通过win32底层API读取客户端信息;
并把信息打印到标准输出以便后面python读取。
这个方法不能获取到准确的客户端IP地址,这里的IP地址其实是内网地址。
暂时还没有找到如何获取客户端公网IP的办法。
完整的C语言源码如下(只支持Windows Vista及以上系统版本):

#include <stdio.h>
#include <Windows.h>
#include <wtsapi32.h>

#pragma comment(lib, "wtsapi32.lib")

static const char *af_str[]=
{
"AF_UNSPEC",
"AF_UNIX",
"AF_INET",
"AF_IMPLINK",
"AF_PUP",
"AF_CHAOS",
"AF_IPX",
"AF_NS",
"AF_ISO",
"AF_OSI",
"AF_ECMA",
"AF_DATAKIT",
"AF_CCITT",
"AF_SNA",
"AF_DECnet",
"AF_DLI",
"AF_LAT",
"AF_HYLINK",
"AF_APPLETALK",
"AF_NETBIOS",
"AF_VOICEVIEW",
"AF_FIREFOX",
"AF_UNKNOWN1",
"AF_BAN",
};

void main(void)
{
	DWORD cbReturned; 
	PWTSCLIENTA pData;
	if(WTSQuerySessionInformationA(WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, WTSClientInfo, (LPSTR*)&pData, &cbReturned))
	{
		printf("UserName:%s\r\n", pData->UserName);
		printf("ClientName:%s\r\n", pData->ClientName);
		printf("ClientBuildNumber:%d\r\n", pData->ClientBuildNumber);
		printf("ClientAddressFamily:%s\r\n", af_str[pData->ClientAddressFamily]);
		printf("ClientAddress(raw):%d.%d.%d.%d\r\n", pData->ClientAddress[0],pData->ClientAddress[1],pData->ClientAddress[2],pData->ClientAddress[3]);
		printf("ClientAddress(str):%ls\r\n", pData->ClientAddress);
		WTSFreeMemory(pData);
		return;
	}
	printf("WTSQuerySessionInformationA Failed!\r\n");
	printf("Error:%08X\r\n", GetLastError());
	//system("pause");
}

第二步:

写一个python脚本,调用上面的小工具,并读取输出,然后发送邮件。
发送邮件使用了网易的STMP服务,用自己的邮箱账号给自己的另一个邮箱发。
接收邮件最好用QQ邮箱,QQ邮件手机可以及时接收到邮件。
完整python源码如下:

#!python
#获取RDP登陆信息,并发送邮件
#蒋晓岗<kerndev@foxmail.com>

import io
import os
import time
import smtplib
import email.mime.text
import email.mime.multipart

#指定EXE小工具的路径
RDPINFO_EXEPATH="rdp_info.exe"

#获取当前时间
def get_local_time():
	str = time.strftime("%Y-%m-%d %X", time.localtime(time.time()))
	return str
	
#获取登陆信息
def get_login_info():
	out = subprocess.check_output(RDPINFO_EXEPATH, timeout=3)
	return out.decode("utf8")
	
#网易SMTP服务
def send_mail(title, text):
	print("发送邮件...")
	mail_host = "smtp.163.com"            #设置服务器
	mail_port = 25                        #服务器SMTP端口号
	mail_user = "123456789012@163.com"    #用户名
	mail_pass = "1234567890123456"        #口令(授权码)
	mail_recv = ["123456789@qq.com"]      #接收者
	mail_subject = title                  #邮件主题
	mail_content = text                   #邮件正文

	msg = email.mime.multipart.MIMEMultipart()
	msg["From"] = mail_user
	msg["To"] = mail_recv[0]
	msg["Subject"] = mail_subject
	msg.attach(email.mime.text.MIMEText(mail_content))
	
	try:
		smtp_obj = smtplib.SMTP()
		print ("正在连接...")
		smtp_obj.connect(mail_host, mail_port)    
		print ("正在登陆...")
		smtp_obj.login(mail_user, mail_pass)
		print ("正在发送...")
		smtp_obj.sendmail(mail_user, mail_recv, msg.as_string())
		print ("发送成功.")
		return True
	except BaseException as e:
		print ("发送失败!", e)
		return False

#程序入口
time_str = get_local_time()
info_str = get_login_info()
head = "远程登陆提醒"
text = "登陆时间:" + time_str + "\r\n" + "登陆信息:\r\n" + info_str
send_mail(head, text)

第三步:

在windows计划任务里面添加任务,当远程登陆时调用我们的python脚本。

1.打开“计算机管理”,找到"任务计划程序",点击“创建任务”

2.名称随便写,比如“远程登陆提醒”

3.设置“触发器”,如下图所示,选择“当连接到用户会话时”,“远程计算机的连接”

python连接windows远程桌面 python远程桌面控制_发送邮件


4.设置“操作”,如下图所示,输入python.exe的路径和脚本的完整路径

python连接windows远程桌面 python远程桌面控制_远程桌面连接_02


5.最后点击“确定”,计划任务就添加好了。


最后测试用不同的客户端进行远程登陆,可以正常收到提醒邮件。
不过有时候手机QQ邮箱提醒会有1-10秒不等的延迟。