Дабы не испытывать судьбу я немного модифицировал схему доступа к RDP.
Так как сервера в большинстве случаев находятся за роутером с которого пробрасывается порт на терминальный сервер, сделаем ход конём и будем динамически открывать порт 3389 для тех, кто корректно авторизовался.
Для этого правим файл Windows\Web\RDWeb\Pages\Default.aspx, добавляя ему внутрь некоторый новый функционал.
void goToFolder(string getLangVal) { Response.Redirect(getLangVal + "/Default.aspx" + Request.Url.Query,true); } private float getInternetExplorerVersion() { // Returns the version of Internet Explorer or a -1 // (indicating the use of another browser). float rv = -1; System.Web.HttpBrowserCapabilities browser = Request.Browser; if (browser.Browser == "IE") rv = (float)(browser.MajorVersion + browser.MinorVersion); return rv; } void Page_Load(Object sender, EventArgs e) { string UserIPAddress = Request.ServerVariables["REMOTE_ADDR"]; string UserName = Request.ServerVariables["AUTH_USER"]; string safeString = System.Security.SecurityElement.Escape(UserName); string url = "http://myrouter/cgi-bin/open.cgi?ip=" + UserIPAddress + "&user=" + safeString ; HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url); request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"; request.AllowAutoRedirect = false; request.KeepAlive = true; HttpWebResponse response = (HttpWebResponse)request.GetResponse(); double ver = getInternetExplorerVersion(); if (ver > 0.0) { if (ver < 7.0) Response.Redirect("TSWeb/Default.asp",true); } else { Response.Redirect("Unsupported/Default.asp",true); } string langCode = null; System.Globalization.CultureInfo culture; // For each request initialize the culture values with // the user language as specified by the browser.
При загрузке страницы портала со списком Remote Application используется внутренняя аутентификация iis. Вышеуказанный скрипт выполнится только в случае корректной авторизации.
На роутере устанавливаем «net-mgmt/pftabled».
создаём ключ
dd if=/dev/random bs=20 count=1 | md5 | cut -c 1-19 > /etc/pftabled.key
и активируем сервис в rc.conf
pftabled_enable="YES" pftabled_flags="-d -k /etc/pftabled.key -t 432000"
Далее поднимаем thttpd и создаём в cgi-bin скрипт open.cgi
#!/usr/bin/perl use strict; use warnings; use CGI qw/:standard/; use IO::Socket; use Digest::HMAC_SHA1 qw(hmac_sha1); use Net::SMTP; use vars qw/%macs $pftabled $key %mac_ip/; use constant PFTBLPORT => 56789; use constant pfip => "127.0.0.1"; use constant PFTBLVERSION => 2; use constant PFTABLED_CMD_ADD => 1; use constant PFTABLED_CMD_DEL => 2; use constant PFTABLED_CMD_FLUSH => 3; use constant PFTBLCOMMAND => 1; use constant PFTBLMASK => 32; use constant SHA1_DIGEST_LENGTH => 20; use constant PFTBLNAME => "RDP"; my $keyfile = "/etc/pftabled.key"; if (! -r $keyfile) { print STDERR "Cannot Read KeyFile $keyfile\n"; exit 1; } open(KEY, "<$keyfile"); sysread KEY, $key, SHA1_DIGEST_LENGTH; close KEY; $pftabled = IO::Socket::INET->new(Proto => 'udp', PeerPort => PFTBLPORT, PeerAddr => pfip) or die "Creating socket: $!\n"; #prepare struct for pftabled my $command = '1'; my $iparray = param("ip"); #print @iparray; my $addr = inet_aton($iparray); my $time = time(); my $block = pack("C1 S1 C1",PFTBLVERSION,$command,PFTBLMASK).$addr.pack("a32 N*",PFTBLNAME,$time); my $digest = hmac_sha1($block, $key); $block .= $digest; $pftabled->send($block); print header(); my $smtp = Net::SMTP->new('mysmtpserver.mydomain.ru'); $smtp->mail('terminal_guard@mydomain.ru'); $smtp->to('account_admin@mydomain.ru'); $smtp->data(); $smtp->datasend("To: account_admin\@mydomain.ru\n"); $smtp->datasend("Subject: Terminal server logon detected\n"); $smtp->datasend("\n"); $smtp->datasend("User ".param("user")." logged on from ".param("ip")."\n"); $smtp->dataend(); $smtp->quit; exit(0);
Теперь можно поправить конфигурацию pf.
external_addr="1.1.1.1" terminal_server_addr="192.168.1.1" table <RDP> persist { } rdr on $ext_if proto tcp from <RDP> to $external_addr port 3389 -> $terminal_server_addr port 3389 # terminal pass in on $ext_if proto tcp from <RDP> to { $external_addr, $terminal_server_addr } port { 3389 } flags S/SA keep state
При удачной аутентификации скрипту передаются имя зашедшего пользователя и IP адрес с которого осуществлялся запрос. Информация о IP адресе помещается в таблицу RDP и пользователь получает доступ к RDP подключению.
Включить windows аутентификацию на RDP сервере можно в файле C:\Windows\Web\RDWeb\Pages\Web.config
При желании можно задействовать custom errorpages и таким же образом блокировать адреса злоумышленников при нескольких неудачных попытках ввода логина пароля. Правда могут быть FP. Но без этого никуда не денешься.
© Aborche 2013
ссылка на оригинал статьи http://habrahabr.ru/post/176657/
Добавить комментарий