Просмотр полной версии : политика безопасности flashSocket
Здравствуйте, имеется сервер node.js с модулем socket.io и policefile . И имеется флешка с подключенной библиотекой flashSocket https://github.com/simb/FlashSocket.IO . Проблема возникла с файлом безопасности. сервер отдаёт на 843 порту:
<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy><allow-access-from domain="*" to-ports="*"/>
</cross-domain-policy>
Но при загрузке флешки firebug показывает запрос файла с порта 8080, к которому конектится сам flashSocket, на что получает ответ "Welcome to socket.io."
При этом почему он ищет его именно там не ясно, потому что в классе flashSocket явно указано
var policyUrl:String = "xmlsocket://" + URLUtil.getServerName(wsUrl) + ":843";
Security.loadPolicyFile(policyUrl);
впрочем закоментирование этой строки ни на что не влияет. в чем может быть дело?
caseyryan
16.02.2013, 18:12
Security.loadPolicyFile(policyUrl);
При коннекте к сокету, флешка сама постучится на 843 порт, не нужно ей этого указывать. Сервер примет подключение и сразу отправит ей файл политики. После этого соединение должно закрываться. После получения файла флешка уже может коннектиться на любой другой порт.
Я и так не указываю, но firebug показывает что идет запрос на crossdomain.xml на 8080 порт. Флешка из браузера не подключается. 5.187.4.231:843 вот ссылка которая передаётся сюда Security.loadPolicyFile(policyUrl);
iflamberg
16.02.2013, 19:41
У меня тоже были подобные проблемы. Я решил не заморачиваться, тем более слушать еще один лишний порт, зачем? С тех пор мои демоны отдают файл политики по основному порту, вот и все.
а как его отдать, если основной порт сокет-соединение, а флешка долбит http гет запрос.
Firebug вам ничего не покажет скорее всего. Флеш-плеер за policy-file ходит не через http-соединение, а через обычный сокет. А вот в том, что у вас crossdomain для сокета отдается правильно (на 843), я сильно сомневаюсь. У меня httpfox показывает какой-то status-line в ответе. И online-telnet на подключение какую-то мелкую html выдает. Вы веб-сервером что ли пытаетесь отдать policy-file? Не выйдет. Совсем не выйдет. Нужно простенький socket-сервер писать.
iflamberg
16.02.2013, 22:29
а как его отдать, если основной порт сокет-соединение, а флешка долбит http гет запрос.
Почему http гет запрос? Не знаю, у меня сокет-клиент коннектится и отправляет текстом "<policy-file-request/>".
А, слушай. Так сокет-соединения запрос ты в фаербаге и не увидишь. Это надо снифферм смотреть. А http get запрос, то он на веб-сервер отправляет, ищет crossdomain.xml в папке. Это разные вещи же.
Спасибо, но все равно странно что ищет crossdomain.xml не на 80 порту, а порт 8080 указан у меня только в инициализации сокета.
так а как с сокетом осущесnвляется проверка политики? если я при коннекте отправляю сообщение на получение policefile, то что должен вренуть сервер? как я понимаю отправить ему этот файл как message - не правильная идея.
Идея как раз правильная. После получения <policy-file-request/> нужно отправить ему ответ и закрыть соединение. Единственный неочевидный момент - в конце сообщения еще нулевой байт нужно добавить.
Официальная справка (http://help.adobe.com/en_US/as3/dev/WS5b3ccc516d4fbf351e63e3d118a9b90204-7c60.html#WS5b3ccc516d4fbf351e63e3d118a9b90204-7c63) по этому поводу (ближе к концу секции Connecting to sockets описано). Можете еще мой пример здесь (http://www.flasher.ru/forum/showpost.php?p=1108077&postcount=12) посмотреть, там тоже есть выдача policy file.
Что то так и не получилось разобраться.
Как я понимаю https://github.com/3rd-Eden/FlashPolicyFileServer этот модуль и занимается отправкой файла политики с нулевым байтом при первом коннекте, висит он при этом на 843 порту и работает нормально 5.187.4.231:843 .
Он же грузится классом FlashSocket перед коннектом xmlsocket://5.187.4.231:843
Однако консоль сервера показывает что файл не отдается при коннекте из флеша(из браузера ок)
Консоль браузера же не выбивает ошибку безопасности:
dataChanel.addEventListener(FlashSocketEvent.SECURITY_ERROR, function (e:FlashSocketEvent) { Console.log('err'); } );
на основной 8080 порт, запроса <policy-file-request/> так же нет, то есть сервер вообще не видит нового подключения.
Вопрос почему флешка ищет кроссдоменник здесь 5.187.4.231:8080 , также остаётся не понятным, даже если он не для сокета.
caseyryan
17.02.2013, 11:16
Однако консоль сервера показывает что файл не отдается при коннекте из флеша(из браузера ок)
Потому что отладочный stand alone плеер и не будет запрашивать этот файл, ему вообще пофиг файл политик. Я как-то тоже на этом споткнулся, когда свой сервер писал. Все перерыл, а оказлось ларчик просто открывался. Так что если в браузер отдается, значит все ок.
Вопрос почему флешка ищет кроссдоменник здесь 5.187.4.231:8080 , также остаётся не понятным, даже если он не для сокета.
Видимо дело в этой сторонней библиотеке. Советую написать свой простенький коннектор и проверить все на нем. Там строк-то будет штук 30 всего.
Вот чего-чего, а нулевого байта при ответе в том коде я не вижу. Поэтому файл он, может, и отдает, а вот нулевой байт - нет. Это же подтверждается и средствами объективного контроля:
maxkar@... ~/test $ nc -o hex 5.187.4.231 843 > /dev/null && tail hex
< 00000030 63 79 20 53 59 53 54 45 4d 20 22 68 74 74 70 3a # cy SYSTEM "http:
< 00000040 2f 2f 77 77 77 2e 6d 61 63 72 6f 6d 65 64 69 61 # //www.macromedia
< 00000050 2e 63 6f 6d 2f 78 6d 6c 2f 64 74 64 73 2f 63 72 # .com/xml/dtds/cr
< 00000060 6f 73 73 2d 64 6f 6d 61 69 6e 2d 70 6f 6c 69 63 # oss-domain-polic
< 00000070 79 2e 64 74 64 22 3e 3c 63 72 6f 73 73 2d 64 6f # y.dtd"><cross-do
< 00000080 6d 61 69 6e 2d 70 6f 6c 69 63 79 3e 3c 61 6c 6c # main-policy><all
< 00000090 6f 77 2d 61 63 63 65 73 73 2d 66 72 6f 6d 20 64 # ow-access-from d
< 000000a0 6f 6d 61 69 6e 3d 22 2a 22 20 74 6f 2d 70 6f 72 # omain="*" to-por
< 000000b0 74 73 3d 22 2a 22 2f 3e 3c 2f 63 72 6f 73 73 2d # ts="*"/></cross-
< 000000c0 64 6f 6d 61 69 6e 2d 70 6f 6c 69 63 79 3e # domain-policy>
Однако консоль сервера показывает что файл не отдается при коннекте из флеша(из браузера ок)
В том коде я не вижу никаких отладочных сообщений на прием/отправку.
Консоль браузера же не выбивает ошибку безопасности:
А здесь я вообще не знаю, кто, как и где обрабатывает ту ошибку. Вот здесь (https://github.com/simb/web-socket-js/blob/master/flash-src/WebSocket.as) вроде бы все ошибки сбрасываются в одну неразобранную кучу. Поэтому и вас FlashSocket.IO ничего хорошего не скажет.
Вопрос почему флешка ищет кроссдоменник здесь 5.187.4.231:8080 , также остаётся не понятным, даже если он не для сокета.
Видимо, потому, что FlashSocket.IO еще и по http/https куда-то ходит в самом начале.
Я вам рекомендую сначала разобраться с основами и поставить в качестве policy-file сервера мой. Или мой клиент попробовать с вашим policy-server'ом. И убедиться, что "на нижнем уровне" все работает. А затем выбросить библиотеки и написать свои транспорты для клиента и сервера на базе xmlsocket или socket. Это на самом деле проще и гораздо быстрее, чем разбираться в чужих библиотеках (т.е. если не заработало, то на "написать" времени нужно строго не больше, чем "исправить библиотеку"). Ну или сначала разобраться в основах, а потом смотреть, какие фреймворки/библиотеки можно взять (но это вам уже вряд ли захочется). Или вам так сильно нужно ручное управление proxy (только тогда имеет смысл смотреть что-то готовое)?
На запрос от клиента <policy-file-request/>, ваш сервер должен отправить в ответ строку вашей политики безопасности. Например такой(с нулевым байтом на конце): <cross-domain-policy><allow-access-from domain=\"*\" to-ports=\"*\"/></cross-domain-policy>\0 это даст доступ на любой домен и порты)
После отправки этого файла, клиент сам разорвет соединение и подключится заново уже полностью работоспособный.
Это вроде как все в документации есть.
caseyryan
17.02.2013, 14:16
Это вроде как все в документации есть.
Это вроде бы и так всем ясно ) Неплохо бы тему для начала почитать, а потом уже и ответ придумывать ;)
maxkar, спасибо, попробовал использовать ваш клиент:
public function Test() {
Security.loadPolicyFile("http://5.187.4.231:8080");
sock = new XMLSocket("5.187.4.231", 8080);
sock.addEventListener(Event.CONNECT, connected);
sock.addEventListener(DataEvent.DATA, receive);
addChild(tf);
}
private function connected(e : Event) : void {
tf.text = "COnnected";
sock.send(<test/>);
}
private function receive(e : DataEvent) : void {
tf.text = e.data.toString();
sock.send(<quit/>);
}
при этом сервер на socket.io:
var chanel = require('socket.io').listen(8080);
chanel.set('transports', [ 'flashsocket' ]);
chanel.set('flashPolicyServer',true);
chanel.set('log level', 2);
chanel.sockets.on('connection', function (socket) {
console.log('connect');
socket.on('message', function(msg){
console.log(msg);
if (msg=='<policy-file-request/>'){
chanel.send("<cross-domain-policy><allow-access-from domain=\"*\" to-ports=\"*\"/></cross-domain-policy>");
}
});
});
Но консоль сервера молчит как с локальной флешки так и из запущенной на сервере. При этом локально выбивает ошибку
Игнорирование файла политики на http://5.187.4.231:8080/ из-за отсутствия типа содержимого
Если же использовать в качестве сервера:
var net = require('net'),
sys = require('util');
console.log("Secur server started");
var server = net.createServer(function(stream) {
stream.setEncoding('utf8');
stream.addListener('data', function(msg) {
if (msg=='<policy-file-request/>'){
var polic = "<cross-domain-policy><allow-access-from domain=\"*\" to-ports=\"*\"/></cross-domain-policy>"
stream.write(polic);
console.log('policeSend');
}
console.log(msg);
});
});
server.listen('8080', '5.187.4.231');
то при запуске локально в консоль сервера пишется:
Secur server started
<test/>
GET / HTTP/1.1
Accept: text/xml, application/xml, application/xhtml+xml, text/html;q=0.9, text/plain;q=0.8, text/css, image/png, image/jpeg, image/gif;q=0.8, application/x-shockwave-flash, video/mp4;q=0.9, flv-application/octet-stream;q=0.8, video/x-flv;q=0.7, audio/mp4, application/futuresplash, */*;q=0.5
x-flash-version: 10,3,183,25
User-Agent: Shockwave Flash
Host: 5.187.4.231:8080
А если с сервера, то:
GET / HTTP/1.1
Host: 5.187.4.231:8080
Connection: keep-alive
<policy-file-request/>
Но коннект все равно не устанавливается.
Сравните:
Security.loadPolicyFile("xmlsocket://127.0.0.1:3128"); // у меня
Security.loadPolicyFile("http://5.187.4.231:8080"); // у вас
Видите разницу в протоколах? Она существенна. Для сокетов протокол должен обязательно быть xmlsocket. По http/https грузятся политики для обычного содержимого (Loader, URLLoader).
Но консоль сервера молчит как с локальной флешки так и из запущенной на сервере.
А вот это я не знаю, почему. Судя по вашей локальной ошибке, в случае socket.io кто-то все-таки отдает содержимое файла политики. Причем не устанавливает ему content-type. Может быть, ваш сервер в лог ничего не пишет или перенаправление работает "не туда"? Или кто-то другой в то время на порту слушает? В общем, не совсем понятно, ваш ли это сервер (хотя бы connect должен в лог вывести) или нет. Если ваш, наверное, плеер ругается на "пустой ответ" (content-type, там, естественно, тоже нет). Но это все не важно, протокол в клиенте нужно другой указать.
И проверьте, во всех сообщениях (и на входе, и на выходе) в конце должен быть нулевой байт (\0 или как он в вашем языке записывается).
В общем таки добился успешной отправки файла политики и коннекта в лабораторных условиях.
клиент:
Security.loadPolicyFile("xmlsocket://5.187.4.231:843");
sock = new XMLSocket("5.187.4.231", 8080);
sock.addEventListener(Event.CONNECT, connected);
сервер:
var pf = require('policyfile').createServer();
pf.listen(843, function(){console.log('policeSend')});
var net = require('net');
console.log("Server started");
var server = net.createServer(function(stream) {
stream.setEncoding('utf8');
stream.addListener('data', function(msg) {
console.log(msg);
});
});
server.listen('8080');
Но теперь получается прийдётся переписывать и клиент и сервер, почему-то socket-io и FlashSocket.as оказались не совместимы, то ли я чего то недопонимаю... Дело в том, что XMLSocket и socket.io не дружат, так же как и net.createServer с FlashSocket.as в связи с разными handshaking , в свою очередь XMLSocket и net.createServer , помимо того что требуют переписывания, клиента и сервера, еще и имеют совершенно другие принципы работы(не передают json, из server нет доступа к отдельным стримам, добавлять везде нулевые байты). То есть всё таки очень желательно заставить работать именно связку flashSocket.as с Socket.IO.
Не могу понять почему если с XMLSocket Security.loadPolicyFile("xmlsocket://5.187.4.231:843"); подключение идет номрально, а с FLASHSocket нет, ведь принцип должен быть тот же самый и те же порты. сервер socket.io:
var chanel = require('socket.io').listen(8080);
chanel.set('transports', [ 'flashsocket' ]);
chanel.set('flashPolicyServer',true);
chanel.set('log level', 2);
chanel.sockets.on('connection', function (socket) {
console.log('connect');
socket.on('message', function(msg){
console.log(msg);
});
});
Не могу понять почему если с XMLSocket Security.loadPolicyFile("xmlsocket://5.187.4.231:843"); подключение идет номрально, а с FLASHSocket нет, ведь принцип должен быть тот же самый и те же порты. сервер socket.io
А чего у вас сервер на wget --post-data="" http://5.187.4.231:8080/socket.io/1/?time=123 ничего не отвечает (за разумное время, мне ждать надоело)? Там что-то интересное должно быть. Ведь у вас же есть исходный код этого FlashSocket.as. А там черным по белому написано, что он на подобный адрес по http ходит и чего-то интересного оттуда хочет (парсит ответ, чего-то выдирает и т.п.). Да и используемая этим FlashSocket.as библиотека (какой-то websocket) тоже имеет исходники и они доступны. В общем, дальше обычный процесс отладки чужого кода. При необходимости - его правка, вставление трейсов и т.п.
помимо того что требуют переписывания, клиента и сервера
Так в норме это вообще копейки. Транспорт поменять. По большей части на клиенте это ровно один метод при правильной архитектуре (максимум - два, инжектятся везде, где нужно). Для сервера на транспортном уровне тоже разница не слишком большая. И json можно через xmlsocket передавать. Он только называется XML, а передаются строки. Ну да, в транспортах придется в/из json конвертировать. В общем, это тоже не такая большая беда (там пара десятков строчек будет на каждой стороне, и это уже с обработкой ошибок парсинга json).
Использование сторонних библиотек может быть сильно не просто. Его нужно аккуратно продумать. Вот вдруг там где-то внутри в определнном сценарии какие-то баги обнаружатся. Что будете делать? Поменять у вас вроде архитектура так просто не позволяет. Отлаживать? Можно потренироваться уже сейчас :).
Переписывать транспорт конечно вариант, но это уже на крайни случай, и судя по этому, заставить работать их все таки можно:
http://stackoverflow.com/questions/14093429/how-to-fix-this-probably-cross-domain-policy-error-using-flash-socket-io-and/14093590#14093590
http://stackoverflow.com/questions/14368576/sending-data-from-flash-to-node-js-server-with-socket-io
http://5.187.4.231:8080/socket.io/1/?time=123 не отвечал так как серв был отключен, сейчас ок, возвращает 4677074091530925175:60:60:websocket,flashsocket
Как выяснилось у socket.io есть директива установки police server port, которая по умолчанию выставлена в 10843, изменил вручную, и теперь сервер сократился до:
var chanel = require('socket.io').listen(8080);
chanel.set('transports', ['websocket','flashsocket']);
chanel.set('flash policy port', 843);
chanel.sockets.on('connection', function (socket) {
console.log('connect');
});
но по прежнему глухо, хотя теперь http://5.187.4.231:843 по идее файл политики должен возвращаться точно правильный.
Просмотрел библиотеки FlashSocket и WebSocket в каждом из них есть запрос фала политик и оба xmlsocket://5.187.4.231:843 правильные. хотя здесь https://github.com/simb/web-socket-js что-то сказано про 10081 порт.
Так... Возвращаемся к
Но при загрузке флешки firebug показывает запрос файла с порта 8080, к которому конектится сам flashSocket, на что получает ответ "Welcome to socket.io."
Вот "welcome to socket.io" на crossdomain.xml неправильно :). Там таки должен быть валидный crossdomain.xml для loader/urlloader. Внутри ничего сложного не нужно (т.е. он вполне обычный). Там сейчас происходит следующее:
* Запрос http://5.187.4.231:8080/crossdomain.xml
* Запрос на http://.../socket.io/1/?time=...
* Запрос на socket policy
* Запрос на соединение
Пункт 1 выполняется в момент программного запроса из п. 2 (это в коде FlashSocket). Пункт 3 может, выполняется вами вручную или автоматически в результате п. 4. Т.е. без loader/urllloader цепочка дальше не работает. Да, вам нужно два crossdomain. Один выдается по http (на порту 8080, обычным http-server'ом), второй - как socket policy file socket-сервер'ом. Ну и дальше можно обычные соединения отлаживать/тестировать/смотреть.
Вообще, попробуйте все-таки сами собрать и подобавлять отладку во FlashSocket (т.е. ответы на IOError/SecurityError). Так будет быстрее. И ошбики будет проще отслеживать (про crossdomain.xml на 8080 я далеко не сразу подумал, а вот с сообщением про security error все бы стало ясно).
maxkar, Большое спасибо за помощь, наконец таки всё заработало) Проблема была и правда в crossdomain.xml Конечный вариант сервера, на будущее:
var server = require('http').createServer(function(req, res){
if (req.url=='/crossdomain.xml'){
var crossD='';
res.writeHead(200,{ 'Content-Type': 'text/xml' });
crossD+='<?xml version="1.0"?>';
crossD+='<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">';
crossD+='<cross-domain-policy>';
crossD+='<site-control permitted-cross-domain-policies="all"/>';
crossD+='<allow-access-from domain="*" to-ports="*" />';
crossD+='<allow-http-request-headers-from domain="*" headers="*"/>';
crossD+='</cross-domain-policy>\0';
res.write(crossD);
res.end();
}
});
server.listen(8080);
var chanel = require('socket.io').listen(server);
chanel.set('transports', ['websocket','flashsocket']);
chanel.set('flash policy port', 843);
chanel.sockets.on('connection', function (socket) {
console.log('connect');
});
Добавлено через 1 час 20 минут
И еще вдогонку вопрос, почему могут с сервера не грузится картинки? В корне лежит файл http://5.187.4.231/crossdomain.xml , кратинки отдаются nginx-ом на 80-м порту, загружать файл поkитики указано явно в Loader
img.load(new URLRequest(Main.server+'/photos/s/'+users[i].photo),new LoaderContext(true)); , и картинки загружаются, но доступа к img.content нету, то есть политика снова игнорируется( firebug так же показывает загрузку только кроссдоменника с 8080 порта.
Добрый день. Какие есть варианты обхода файла политики? У меня сервер и клиент лежат на одном хосте, но на разных портах.
Можно на C++ написать перенаправление? Который в случаи запроса политики - отдает политику, в ином ломится на сервак с нужным портом.
Получится ли такая идея обхода?
Работает на vBulletin ® версия 3.7.3. Copyright ©2000-2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Copyright © 1999-2008 Flasher.ru. All rights reserved.