Ни для кого не секрет, что технология RemoteApp внедрённая в Windows 2008 это ответ Microsoft технологиям доступа к приложениям компании Citrix. Всё бы ничего, но для использования данной технологии в повседневной жизни, без наличия RD Gateway, нужен открытый наружу RDP Port tcp/3389. Наблюдая за своими терминальными серверами, я обнаружил что сервера постоянно подвергаются brute-force атакам подбора паролей различных пользователей.
Дабы не испытывать судьбу я немного модифицировал схему доступа к RDP.
Так как сервера в большинстве случаев находятся за роутером с которого пробрасывается порт на терминальный сервер, сделаем ход конём и будем динамически открывать порт 3389 для тех, кто корректно авторизовался.
Для этого правим файл Windows\Web\RDWeb\Pages\Default.aspx, добавляя ему внутрь некоторый новый функционал.
При загрузке страницы портала со списком Remote Application используется внутренняя аутентификация iis. Вышеуказанный скрипт выполнится только в случае корректной авторизации.
На роутере устанавливаем «net-mgmt/pftabled».
создаём ключ
и активируем сервис в rc.conf
Далее поднимаем thttpd и создаём в cgi-bin скрипт open.cgi
Теперь можно поправить конфигурацию pf.
При удачной аутентификации скрипту передаются имя зашедшего пользователя и IP адрес с которого осуществлялся запрос. Информация о IP адресе помещается в таблицу RDP и пользователь получает доступ к RDP подключению.
Включить windows аутентификацию на RDP сервере можно в файле C:\Windows\Web\RDWeb\Pages\Web.config
При желании можно задействовать custom errorpages и таким же образом блокировать адреса злоумышленников при нескольких неудачных попытках ввода логина пароля. Правда могут быть FP. Но без этого никуда не денешься.
Aborche 2013

Дабы не испытывать судьбу я немного модифицировал схему доступа к 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
