<?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, 19 Jan 2012 12:18:51 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Заголовки HTTP для обеспечения безопасности сайта</title>
		<link>http://blog.sjinks.pro/security/884-http-headers-to-secure-website/</link>
		<comments>http://blog.sjinks.pro/security/884-http-headers-to-secure-website/#comments</comments>
		<pubDate>Mon, 03 Jan 2011 12:28:06 +0000</pubDate>
		<dc:creator>Wandering Soul</dc:creator>
				<category><![CDATA[Безопасность]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[XSS]]></category>
		<category><![CDATA[атака]]></category>
		<category><![CDATA[безопасность]]></category>

		<guid isPermaLink="false">http://blog.sjinks.pro/?p=884</guid>
		<description><![CDATA[Активация средств защиты, встроенных в современные бразуеры, для обеспечения дополнительной безопасности пользователей Безопасность сайта — это бесконечная битва между веб-мастерами и хакерами. В &#60;/xssed&#62; зарегистрировано около 40,000 сайтов, подверженных атакам XSS. XSS-атаки позволяют злоумышленникам красть cookie, личную информацию, взламывать аккаунты и многие другие вещи. Существует множество способов для защиты сайта, но ни один из них не может гарантировать [...]<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/security/884-http-headers-to-secure-website/">источник</a> обязательно.</p>]]></description>
			<content:encoded><![CDATA[<h2><em>Активация средств защиты, встроенных в современные бразуеры, для обеспечения дополнительной безопасности пользователей</em></h2>
<p><a href="http://blog.sjinks.pro/tag/tag-security/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  безопасность">Безопасность</a> сайта — это бесконечная битва между веб-мастерами и хакерами. В <a href="http://xssed.com/">&lt;/xssed&gt;</a> зарегистрировано около 40,000 сайтов, подверженных атакам <a href="http://blog.sjinks.pro/tag/xss/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  XSS">XSS</a>. <a href="http://blog.sjinks.pro/tag/xss/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  XSS">XSS</a>-атаки позволяют злоумышленникам красть cookie, личную информацию, взламывать аккаунты и многие другие вещи.</p>
<p>Существует множество способов для защиты сайта, но ни один из них не может гарантировать абсолютную безопасность. Как следствие, нужно использовать многоуровневую эшелонную зашиту для обеспечения безопасности сайта.</p>
<p>В данной статье будет показан один из вариантов защиты — основанный на использовании заголовков HTTP.<span id="more-884"></span></p>
<p>Современные браузеры сами предоставляют довольно мощную защиту для своих пользователей… Единственное «но» — сайт должен попросить браузер включить эту защиту. К счастью, это довольно просто.</p>
<p>Для <a href="http://blog.sjinks.pro/tag/apache/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  Apache">Apache</a>:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p8844">
        <div class="code apache" id="p884code4">
<span class="co1"># Запретить всем сайтам загружать страницу через &lt;frame&gt;/&lt;iframe&gt;</span><br />
<span class="kw1">Header</span> set X-Frame-<span class="kw1">Options</span> <span class="kw1">DENY</span><br />
<br />
<span class="co1"># Разрешить выполнение JavaScript, загруженного только с нашего домена.</span><br />
<span class="co1"># Не выполнять встроенный (inline) JavaScript</span><br />
<span class="kw1">Header</span> set X-Content-Security-Policy <span class="st0">&quot;allow 'self';&quot;</span><br />
<br />
<span class="co1"># Включение предотвращения XSS-атак в IE 8</span><br />
<span class="kw1">Header</span> set X-XSS-Protection <span class="st0">&quot;1; mode=block&quot;</span>
        </div>
    </div>
</div>

<p>Для <a href="http://blog.sjinks.pro/tag/nginx/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  nginx">nginx</a>:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p8845">
        <div class="code nginx" id="p884code5">
<span class="kw1">add_header</span> X-Frame-Options DENY;<br />
<span class="kw1">add_header</span> X-Content-Security-Policy <span class="st0">&quot;allow 'self';&quot;</span>;<br />
<span class="kw1">add_header</span> X-XSS-Protection <span class="st0">&quot;1; mode=block&quot;</span>;
        </div>
    </div>
</div>

<p><strong>X-Frame-Options</strong></p>
<p>Данный заголовок указывает браузеру, можно ли загружать страницы сайта через <span class="codebox"><code class="html"><span class="sc2">&lt;<span class="kw2">frame</span>&gt;</span></code></span>/<span class="codebox"><code class="html"><span class="sc2">&lt;<span class="kw2">iframe</span>&gt;</span></code></span>.</p>
<p>Значение <code>DENY</code> запретит загрузку через фреймы, значение <code>SAMEORIGIN</code> разрешит загрузку через фреймы, но только если и фрейм, и страница, его загружающая, находятся на одном домене (<a href="http://en.wikipedia.org/wiki/Same_origin_policy">Same Origin Policy</a>).</p>
<p>основная функция данной защиты — предотвращение <a href="http://ru.wikipedia.org/wiki/%D0%9A%D0%BB%D0%B8%D0%BA%D0%B4%D0%B6%D0%B5%D0%BA%D0%B8%D0%BD%D0%B3">кликджекинга</a>; в качестве дополнительного бонуса это позволит предотвратить атаку, описанную <a href="http://spareclockcycles.org/2010/12/19/d0z-me-the-evil-url-shortener/">Ben Schmidt</a>.</p>
<p>Заголовок воспринимается Internet Explorer 8.0+, Firefox 3.6.9+ (Gecko 1.9.2.9+), Opera 10.50+, Safari 4.0+, Chrome 4.1.249.1042+.</p>
<p>Подробное описание приведено <a href="https://developer.mozilla.org/en/the_x-frame-options_response_header">здесь</a>.</p>
<p><strong>X-Content-Security-Policy</strong></p>
<p>Данный заголовок указывает, как контент на сайте взаимодействует с самим сайтом. При помощи данного заголовка можно указывать, откуда можно загружать картинки, <a href="http://blog.sjinks.pro/tag/javascript/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  JavaScript">JavaScript</a>, фреймы, шрифты, объекты, таблицы стилей, медиаконтент и многое другое.</p>
<p>Приведённый в примере выше заголовок разрешает загрузку контента только с того же домена, на котором располагается загружаемая страница. При этом браузеру запрещается выполнение встроенного JavaScript (скрипты внутри блоков <span class="codebox"><code class="html"><span class="sc2">&lt;<span class="kw2">script</span>&gt;</span>…<span class="sc2">&lt;<span class="sy0">/</span><span class="kw2">script</span>&gt;</span></code></span>, обработчики событий и т.п.), создание кода из строк (например, через функцию eval(), а также передача строк в функции <code>setTimeout()</code>, <code>setInterval()</code> и т.п.), использование протокола <code>data:</code>.</p>
<p>Данный заголовок можно использовать на <a href="http://blog.sjinks.pro/tag/https/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  HTTPS">HTTPS</a>-страницах для запрета загрузки небезопасного контента:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p8846">
        <div class="code text" id="p884code6">
X-Content-Security-Policy: allow https://*:443
        </div>
    </div>
</div>

<p>Подробнее о заголовке и поддерживаемых параметрах можно прочитать <a href="https://wiki.mozilla.org/Security/CSP/Specification">здесь</a>.</p>
<p><strong>X-XSS-Protection</strong></p>
<p>Данный заголовок работает исключительно в Internet Explorer: он включает встроенную в браузер защиту от XSS-атак (по умолчанию она отключена, так как может некорректно работать с некоторыми сайтами). Подробная информация о принципах работы защиты от XSS-атак в IE приведена в <a href="http://blogs.msdn.com/b/ie/archive/2008/07/01/ie8-security-part-iv-the-xss-filter.aspx">The Windows Internet Explorer Weblog</a>.</p>
<p>В заключение стоит отметить, что хоть данный способ и хорош, он должен использоваться вкупе с другими средствами защиты и быть частью комплексной системы безопасности. Безопасность лишней не бывает!</p>
<p><a href="http://community.developer.authorize.net/t5/The-Authorize-Net-Developer-Blog/HTTP-Headers-to-Help-Secure-Your-Website/ba-p/8604">Оригинал статьи</a>.</p>
<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/security/884-http-headers-to-secure-website/">источник</a> обязательно.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.sjinks.pro/security/884-http-headers-to-secure-website/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>WordPress: кэширование средствами nginx</title>
		<link>http://blog.sjinks.pro/wordpress/877-wordpress-caching-with-nginx/</link>
		<comments>http://blog.sjinks.pro/wordpress/877-wordpress-caching-with-nginx/#comments</comments>
		<pubDate>Fri, 10 Dec 2010 12:08:15 +0000</pubDate>
		<dc:creator>Vladimir</dc:creator>
				<category><![CDATA[nginx]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[FastCGI]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[кэш]]></category>
		<category><![CDATA[производительность]]></category>

		<guid isPermaLink="false">http://blog.sjinks.pro/?p=877</guid>
		<description><![CDATA[Уменьшение потребления ресурсов во много раз Много было сказано про кэширование в WordPress… Сегодня я хочу рассказать о действительно эффективном методе, позволяющем сильно снизить нагрузку. Метод основан на использовании кэша FastCGI web-сервера nginx. Идея состоит в генерации статических страниц и отдачи их пользователям, не имеющим cookie комментатора. Зарегистрированным пользователям, а также комментаторам всегда отдаётся свежая [...]<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/wordpress/877-wordpress-caching-with-nginx/">источник</a> обязательно.</p>]]></description>
			<content:encoded><![CDATA[<h2><em>Уменьшение потребления ресурсов во много раз</em></h2>
<p>Много было сказано про <a href="http://blog.sjinks.pro/?s=WordPress%20cache">кэширование в WordPress</a>… Сегодня я хочу рассказать о действительно эффективном методе, позволяющем сильно снизить нагрузку.</p>
<p>Метод основан на использовании кэша <a href="http://blog.sjinks.pro/tag/fastcgi/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  FastCGI">FastCGI</a> web-сервера <a href="http://blog.sjinks.pro/tag/nginx/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  nginx">nginx</a>.</p>
<p>Идея состоит в генерации статических страниц и отдачи их пользователям, не имеющим cookie комментатора. Зарегистрированным пользователям, а также комментаторам всегда отдаётся свежая страница. Так как читателей, ни разу не оставлявших комментарий, как правило, гораздо больше, чем комментаторов, то подобный использование кэша позволяет значительно снизить нагрузку на <a href="http://blog.sjinks.pro/tag/wordpress/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  WordPress">WordPress</a>/<a href="http://blog.sjinks.pro/tag/php/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  PHP">PHP</a>. Знакомые с принципом работы <a href="http://blog.sjinks.pro/tag/wp-super-cache/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  WP Super Cache">WP Super Cache</a> заметят, что WPSC использует тот же принцип работы.<span id="more-877"></span></p>
<p>В чем же преимущество перекладывания работы на Web-сервер (nginx)?</p>
<ol>
<li>PHP — интерпретируемый язык. Как следствие, аналогичный код на компилируемом языке будет во много раз быстрее.</li>
<li>WordPress во многом bloatware <img src='http://static.sjinks.info/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  От момента начала загрузки страницы до окончания выполнения стадии <code>init</code> выполняется очень много «лишнего» кода.</li>
<li>В зависимости от нагрузки на сервер от запроса страницы до выполнения PHP-кода может пройти некоторое время: всё зависит от загруженности PHP (если все дочерние процессы PHP заняты обработкой запроса, новому запросу придётся ждать освобождения одного из процессов. Если за приемлемое время ни один процесс не освободился, пользователь видит сообщение о печально знаменитой ошибке 504).</li>
<li>Когда обслуживанием кэша занимается web-сервер, шансы на возникновение <a href="http://blog.sjinks.pro/wordpress/521-wp-super-cache-under-high-load/">подобной ситуации</a></li>
 (когда даже автор не может понять, в чём дело) значительно снижаются: реализация синхронизации/блокировок средствами PHP — неблагодарное дело.
</ol>
<p>Теперь переходим от теории к практике.</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p8779">
        <div class="code nginx" id="p877code9">
<ol class="nginx" style="font-family:monospace;"><li class="li1"><div class="de1"><span class="kw1">fastcgi_cache_path</span> /var/lib/nginx/myblog levels=2 keys_zone=myblog:10m max_size=512m inactive=20m;</div></li>
<li class="li1"><div class="de1"><span class="kw1">server</span> {</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw1">server_name</span> example.com;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw1">root</span> /path/to/blog;</div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw1">index</span> <span class="kw1">index</span>.php;</div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw1">if</span> ($http_cookie ~* <span class="st0">&quot;comment_author_|wordpress_(?!test_cookie)|wp-postpass_&quot;</span> ) {</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">set</span> $do_not_cache <span class="nu0">1</span>;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; }</div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; fastcgi_cache_bypass $do_not_cache;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; fastcgi_no_cache $do_not_cache;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw1">fastcgi_pass_header</span> Cookie;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw1">fastcgi_cache</span> myblog;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw1">fastcgi_cache_key</span> $request_method|$host|$request_uri;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw1">fastcgi_cache_valid</span> 301 8h;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw1">fastcgi_cache_valid</span> 404 1h;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw1">fastcgi_cache_valid</span> 200 15m;</div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw1">if</span> ($http_user_agent !~ FeedBurner) {</div></li>
<li class="li1"><div class="de1"><span class="co1"># Здесь идут перенаправления для FeedBurner</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; }</div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw1">error_page</span> 404 = @wordpress;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw1">log_not_found</span> <span class="kw2">off</span>;</div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw1">location</span> ^~ /files/ {</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">rewrite</span> /files/(.+) /wp-includes/ms-files.php?file=$1 last;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; }</div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw1">location</span> ~ ^/(wp-admin/.*\.php|wp-login\.php|wp-register\.php|(feed|comment/feed)(/.*)?)$ {</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">try_files</span> $uri @wordpress;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">set</span> $do_not_cache <span class="nu0">1</span>;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; fastcgi_cache_bypass <span class="nu0">1</span>;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; fastcgi_no_cache <span class="nu0">1</span>;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">fastcgi_pass</span> unix:/dev/shm/php-fcgi.sock;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">fastcgi_index</span> <span class="kw1">index</span>.php;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">include</span> /etc/nginx/fastcgi_params;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">fastcgi_param</span> SCRIPT_FILENAME $document_root$fastcgi_script_name;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; }</div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw1">location</span> @wordpress {</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">include</span> /etc/nginx/fastcgi_params;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">fastcgi_param</span> SCRIPT_NAME /<span class="kw1">index</span>.php;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">fastcgi_param</span> SCRIPT_FILENAME $document_root/<span class="kw1">index</span>.php;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">fastcgi_index</span> <span class="kw1">index</span>.php;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">fastcgi_pass</span> unix:/dev/shm/php-fcgi.sock;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> ($do_not_cache != <span class="st0">&quot;1&quot;</span>) {</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">add_header</span> Vary Cookie;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; }</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; }</div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw1">location</span> ~ \.php$ {</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">include</span> /etc/nginx/fastcgi_params;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">fastcgi_index</span> <span class="kw1">index</span>.php;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">fastcgi_param</span> SCRIPT_FILENAME $document_root$fastcgi_script_name;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">try_files</span> $uri @wordpress;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">fastcgi_pass</span> unix:/dev/shm/php-fcgi.sock;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> ($do_not_cache != <span class="st0">&quot;1&quot;</span>) {</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">add_header</span> Vary Cookie;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; }</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; }</div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw1">location</span> ^~ /blogs.dir/ {</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">internal</span>;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">root</span> /path/to/blog/wp-content/;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; }</div></li>
<li class="li1"><div class="de1">}</div></li>
</ol>
        </div>
    </div>
</div>

<p>Документация по использованию FastCGI в nginx приведена <a href="http://sysoev.ru/nginx/docs/http/ngx_http_fastcgi_module.html">здесь</a>, поэтому я не буду подробно останавливаться на том, что конкретно каждая директива делает.</p>
<p>Основная магия происходит в строка 8—10: здесь определяются условия, при которых отдаётся свежая страница. В данном случае проверяется наличие авторизационных cookie и cookie комментатора. Важно, чтобы в случае отказа от кэширования переменная $<code>do_not_cache</code> устанавливалась в 1.</p>
<p>Строка 16 задаёт ключ, по которому страница доступна в кэше. В ключе присутствует <code>$request_method</code>, чтобы различать запросы GET и HEAD (для HEAD данные не возвращаются, только заголовки).</p>
<p>Строки 17—19 задают время жизни кэша в зависимости от кода ответа. Чем больше время жизни, тем реже будет обновляться информация для незарегистрированных пользователей.</p>
<p>В строке 32 задаётся маска для страниц, которые не должны кэшироваться (например, админка, страницы логина и регистрации, фиды).</p>
<p>Так как содержимое страницы <em>может</em> отличаться в зависимости от cookie пользователя, в строках 49 и 59 для закэшированных страниц принудительно выставляется заголовок <code>Vary: Cache</code>. Если используются другие правила (например, фильтрация по User-Agent), нужно добавлять соответствующее правило.</p>
<p>Строки 21—23: подробнее описано в статье <strong>«<a href="http://blog.sjinks.pro/wordpress/691-redirect-rss-feeds-to-feedburner-with-nginx/">Перенаправление RSS в WordPress на FeedBurner для nginx</a>»</strong></p>
<p>Строки 28—30, 63—66 подробнее описаны в статье <strong>«<a href="http://blog.sjinks.pro/wordpress/874-wpms-nginx-accel-redirect/">WordPress MultiSite, nginx и X-Accel-Redirect</a>»</strong></p>
<p>Вроде бы ничего не забыл. Теперь о том, какую <a href="http://blog.sjinks.pro/tag/performance/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  производительность">производительность</a> мы получаем:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p87710">
        <div class="code text" id="p877code10">
$ ab -n 10000 -c 100 http://blog.sjinks.pro/<br />
Server Software: &nbsp; &nbsp; &nbsp; &nbsp;nginx<br />
Server Hostname: &nbsp; &nbsp; &nbsp; &nbsp;blog.sjinks.pro<br />
Server Port: &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;80<br />
<br />
Document Path: &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;/<br />
Document Length: &nbsp; &nbsp; &nbsp; &nbsp;50294 bytes<br />
<br />
Concurrency Level: &nbsp; &nbsp; &nbsp;100<br />
Time taken for tests: &nbsp; 46.925 seconds<br />
Complete requests: &nbsp; &nbsp; &nbsp;10000<br />
Failed requests: &nbsp; &nbsp; &nbsp; &nbsp;0<br />
Write errors: &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 0<br />
Total transferred: &nbsp; &nbsp; &nbsp;504940000 bytes<br />
HTML transferred: &nbsp; &nbsp; &nbsp; 502940000 bytes<br />
Requests per second: &nbsp; &nbsp;213.10 [#/sec] (mean)<br />
Time per request: &nbsp; &nbsp; &nbsp; 469.254 [ms] (mean)<br />
Time per request: &nbsp; &nbsp; &nbsp; 4.693 [ms] (mean, across all concurrent requests)<br />
Transfer rate: &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;10508.28 [Kbytes/sec] received<br />
<br />
Connection Times (ms)<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; min &nbsp;mean[+/-sd] median &nbsp; max<br />
Connect: &nbsp; &nbsp; &nbsp; 16 &nbsp; 94 &nbsp;76.9 &nbsp; &nbsp; 94 &nbsp; &nbsp;3125<br />
Processing: &nbsp; 118 &nbsp;373 &nbsp;81.7 &nbsp; &nbsp;360 &nbsp; &nbsp;1334<br />
Waiting: &nbsp; &nbsp; &nbsp; 17 &nbsp; 69 &nbsp;38.5 &nbsp; &nbsp; 57 &nbsp; &nbsp; 422<br />
Total: &nbsp; &nbsp; &nbsp; &nbsp;156 &nbsp;467 105.0 &nbsp; &nbsp;445 &nbsp; &nbsp;3535<br />
<br />
Percentage of the requests served within a certain time (ms)<br />
&nbsp; 50% &nbsp; &nbsp;445<br />
&nbsp; 66% &nbsp; &nbsp;454<br />
&nbsp; 75% &nbsp; &nbsp;471<br />
&nbsp; 80% &nbsp; &nbsp;494<br />
&nbsp; 90% &nbsp; &nbsp;541<br />
&nbsp; 95% &nbsp; &nbsp;589<br />
&nbsp; 98% &nbsp; &nbsp;655<br />
&nbsp; 99% &nbsp; &nbsp;768<br />
&nbsp;100% &nbsp; 3535 (longest request)
        </div>
    </div>
</div>

<p>Сервер зафлудили 10,000 запросами в 100 <strong>параллельных</strong> потоков. Сервер выдал практически полгигабайта за 47 секунд; в среднем сервер обрабатывал <strong>213 запросов в секунду</strong>, при этом <strong>99% запросов были обработаны за 768 мс</strong> (при том, что на сервере несколько сайтов в Alexa Top 100,000)! Нагрузка на сервер была минимальной (изменений Load Average замечено не было).</p>
<p><strong style="color: red">UPDATE:</strong> есть один небольшой нюанс: CAPTCHA. Если вы их используете, убедитесь, что они работают. Дело в том, что страница со статьёй будет отдаваться непосредственно из кэша nginx, PHP загружаться не будет. Поэтому если CAPTCHA полагается на использование сессии, она может работать неправильно. Здесь всё зависит от используемого плагина.</p>
<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/wordpress/877-wordpress-caching-with-nginx/">источник</a> обязательно.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.sjinks.pro/wordpress/877-wordpress-caching-with-nginx/feed/</wfw:commentRss>
		<slash:comments>61</slash:comments>
		</item>
		<item>
		<title>WordPress MultiSite, nginx и X-Accel-Redirect</title>
		<link>http://blog.sjinks.pro/wordpress/874-wpms-nginx-accel-redirect/</link>
		<comments>http://blog.sjinks.pro/wordpress/874-wpms-nginx-accel-redirect/#comments</comments>
		<pubDate>Sat, 04 Dec 2010 09:25:34 +0000</pubDate>
		<dc:creator>Vladimir</dc:creator>
				<category><![CDATA[nginx]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[FastCGI]]></category>
		<category><![CDATA[multisite]]></category>

		<guid isPermaLink="false">http://blog.sjinks.pro/?p=874</guid>
		<description><![CDATA[Ускорение загрузки файлов с дочерних блогов Одна из основных особенностей WordPress 3.0 — поддержка конфигурации MultiSite. При использовании FastCGI с WordPress MultiSite может выявиться одно слабое место: загруженные файлы (которые uploads) дочерних блогов отдаются PHP-скриптом (wp-includes/ms-files.php). Если количество процессов FastCGI небольшое, а загружаемые файлы большие и при этом имеется медленные клиенты, проблемы с производительностью гарантированы: дело в том, [...]<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/wordpress/874-wpms-nginx-accel-redirect/">источник</a> обязательно.</p>]]></description>
			<content:encoded><![CDATA[<h2><em>Ускорение загрузки файлов с дочерних блогов</em></h2>
<p>Одна из основных особенностей <a href="http://blog.sjinks.pro/tag/wordpress/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  WordPress">WordPress</a> 3.0 — поддержка конфигурации <a href="http://blog.sjinks.pro/tag/multisite/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  multisite">MultiSite</a>.</p>
<p>При использовании <a href="http://blog.sjinks.pro/tag/fastcgi/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  FastCGI">FastCGI</a> с WordPress MultiSite может выявиться одно слабое место: загруженные файлы (которые uploads) дочерних блогов отдаются <a href="http://blog.sjinks.pro/tag/php/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  PHP">PHP</a>-скриптом (<code>wp-includes/ms-files.php</code>). Если количество процессов FastCGI небольшое, а загружаемые файлы большие и при этом имеется медленные клиенты, проблемы с производительностью гарантированы: дело в том, что один процесс FastCGI в один момент времени может обслуживать только одного клиента. Если запущено 5 процессов php-cgi, и имеется пять медленных клиентов, качающих файлы, все остальные клиенты будут ждать освобождения процессов PHP. Если клиенты медленные, а файлы большие, ждущие клиенты будут получать ошибку 504.</p>
<p>К счастью, при использовании <a href="http://blog.sjinks.pro/tag/nginx/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  nginx">nginx</a> проблема легко решается.<span id="more-874"></span></p>
<p>nginx поддерживает <a href="http://wiki.nginx.org/XSendfile">метод</a>, при котором приложение (в данном случае WordPress) может переложить ответственность за отдачу файла клиенту на nginx. Это достигается путём использования специального заголовка, <code>X-Accel-Redirect</code> (интересующимся подробностями рекомендую <a href="http://kovyrin.net/2006/11/01/nginx-x-accel-redirect-php-rails/">статью Алексея Ковырина</a>). <strong>WordPress полностью поддерживает данный метод.</strong> Но по умолчанию данный метод не используется, так как сначала нужно правильно настроить nginx.</p>
<p>Базовая настройка nginx для использования с WordPress приведена в <a href="http://blog.sjinks.pro/wordpress-plugins/nginx-compatibility/">соответствующей статье</a>, здесь же мы рассмотрим изменения, необходимые для поддержки multisite.</p>
<p>Загруженные файлы дочерних блогов располагаются в каталогах <span class="codebox"><code class="text">/wp-content/blog.dir/&lt;blog_id&gt;/</code></span>; WordPress же для отдачи файлов использует URL вида <span class="codebox"><code class="text">http://site.blog.com/files/&lt;filename&gt;</code></span>. Отдачей файла <span class="codebox"><code class="text">&lt;filename&gt;</code></span> клиенту занимается файл <code>/wp-includes/ms-files.php</code>:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p87414">
        <div class="code nginx" id="p874code14">
<span class="kw1">server</span> {<br />
<span class="co1">#...</span><br />
<br />
&nbsp; &nbsp; <span class="kw1">location</span> ^~ /files/ {<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">rewrite</span> /files/(.+) /wp-includes/ms-files.php?file=$1 last;<br />
&nbsp; &nbsp; }<br />
<br />
<span class="co1">#...</span><br />
}
        </div>
    </div>
</div>

<p>В такой конфигурации отдавать файл клиенту будет сам WordPress (PHP), и при достаточной нагрузке мы столкнёмся с проблемами производительности. Поэтому настроим возможность отдачи файлов клиенту средствами nginx:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p87415">
        <div class="code nginx" id="p874code15">
<span class="kw1">server</span> {<br />
<span class="co1">#...</span><br />
<br />
&nbsp; &nbsp; <span class="kw1">location</span> ^~ /files/ {<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">rewrite</span> /files/(.+) /wp-includes/ms-files.php?file=$1 last;<br />
&nbsp; &nbsp; }<br />
<br />
&nbsp; &nbsp; <span class="kw1">location</span> ^~ /blogs.dir/ {<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">internal</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">root</span> /path/to/blog/wp-content/;<br />
&nbsp; &nbsp; }<br />
<br />
<span class="co1">#...</span><br />
}
        </div>
    </div>
</div>

<p>Директива <code>internal</code> защищает файлы от прямых обращений, минуя <code>/wp-includes/ms-files.php</code>.</p>
<p>После внесения изменений в конфигурацию nginx, его необходимо перезапустить.</p>
<p>Затем добавляем следующую строку в <code>/wp-config.php</code>:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p87416">
        <div class="code php" id="p874code16">
<span class="kw1">define</span><span class="br0">&#40;</span><span class="st_h">'WPMU_ACCEL_REDIRECT'</span><span class="sy0">,</span> <span class="kw4">true</span><span class="br0">&#41;</span><span class="sy0">;</span>
        </div>
    </div>
</div>

<p>После этого WordPress будет передавать заголовок X-Accel-Redirect с именем файла nginx, а nginx будет отдавать его клиенту. В результате скрипт PHP будет завершаться очень быстро и сможет обслуживать других клиентов.</p>
<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/wordpress/874-wpms-nginx-accel-redirect/">источник</a> обязательно.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.sjinks.pro/wordpress/874-wpms-nginx-accel-redirect/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Конфигурация nginx для работы с Simple Machines Forum</title>
		<link>http://blog.sjinks.pro/seo/823-nginx-configuration-simple-machines-forum/</link>
		<comments>http://blog.sjinks.pro/seo/823-nginx-configuration-simple-machines-forum/#comments</comments>
		<pubDate>Thu, 23 Sep 2010 01:32:18 +0000</pubDate>
		<dc:creator>Wandering Soul</dc:creator>
				<category><![CDATA[nginx]]></category>
		<category><![CDATA[SEO]]></category>
		<category><![CDATA[Simple Machines Forum]]></category>
		<category><![CDATA[SMF]]></category>

		<guid isPermaLink="false">http://blog.sjinks.pro/?p=823</guid>
		<description><![CDATA[Настройка pretty permalinks в Simple Machines Forum при использовании nginx Simple Machines Forum (SMF) — бесплатный интернет-форум, написанный на PHP и использующий базу данных MySQL. «Дружественные URL» (ЧПУ) поддерживает только для Apache; для nginx, как водится, официальной поддержки нет. Поэтому в данной статье пойдёт речь именно о том, как заставить работать ЧПУ в nginx. Начнём с [...]<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/seo/823-nginx-configuration-simple-machines-forum/">источник</a> обязательно.</p>]]></description>
			<content:encoded><![CDATA[<h2><em>Настройка pretty permalinks в Simple Machines Forum при использовании <a href="http://blog.sjinks.pro/tag/nginx/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  nginx">nginx</a></em></h2>
<p>Simple Machines Forum (<a href="http://blog.sjinks.pro/tag/simple-machines-forum/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  SMF">SMF</a>) — бесплатный интернет-форум, написанный на <a href="http://blog.sjinks.pro/tag/php/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  PHP">PHP</a> и использующий базу данных MySQL.</p>
<p>«Дружественные URL» (ЧПУ) поддерживает только для <a href="http://blog.sjinks.pro/tag/apache/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  Apache">Apache</a>; для nginx, как водится, официальной поддержки нет. Поэтому в данной статье пойдёт речь именно о том, как заставить работать ЧПУ в nginx.<span id="more-823"></span></p>
<p>Начнём с того, что ЧПУ в SMF работают только через PATHINFO (ссылки вида <code>index.php/something/goes/here</code>). Это досадное недоразумение, к счастью, лечится.</p>
<p>Начнём с конфигурации виртуального хоста:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p82322">
        <div class="code nginx" id="p823code22">
<span class="kw1">server</span> {<br />
&nbsp; &nbsp; <span class="kw1">server_name</span> forum.example.com;<br />
<br />
&nbsp; &nbsp; <span class="kw1">root</span> /var/www/forum.example.com;<br />
&nbsp; &nbsp; <span class="kw1">index</span> <span class="kw1">index</span>.php;<br />
<br />
&nbsp; &nbsp; <span class="kw1">rewrite</span> ^/<span class="kw1">index</span>\.php/([a-z]+),([0-9]+)\.(\w+)/(\w+),(\w+)/(\w+)\.html /<span class="kw1">index</span>.php?$1=$2.$3&amp;$4=$5&amp;$6 last;<br />
&nbsp; &nbsp; <span class="kw1">rewrite</span> ^/<span class="kw1">index</span>\.php/([a-z]+),([0-9]+)\.(\w+)/(\w+),(\w+)\.html /<span class="kw1">index</span>.php?$1=$2.$3&amp;$4=$5 last;<br />
&nbsp; &nbsp; <span class="kw1">rewrite</span> ^/<span class="kw1">index</span>\.php/([a-z]+),([0-9]+)\.(\w+)/(\w+)/(\w+)\.html /<span class="kw1">index</span>.php?$1=$2.$3&amp;$4&amp;$5 last;<br />
&nbsp; &nbsp; <span class="kw1">rewrite</span> ^/<span class="kw1">index</span>\.php/([a-z]+),([0-9]+)\.(\w+)/(\w+)\.html /<span class="kw1">index</span>.php?$1=$2.$3&amp;$4 last;<br />
&nbsp; &nbsp; <span class="kw1">rewrite</span> ^/<span class="kw1">index</span>\.php/([a-z]+),([0-9]+)\.(\w+)\.html /<span class="kw1">index</span>.php?$1=$2.$3 last;<br />
<br />
&nbsp; &nbsp; <span class="kw1">rewrite</span> ^/([a-z]+),([0-9]+)\.(\w+)/(\w+),(\w+)/(\w+)\.html /<span class="kw1">index</span>.php?$1=$2.$3&amp;$4=$5&amp;$6 last;<br />
&nbsp; &nbsp; <span class="kw1">rewrite</span> ^/([a-z]+),([0-9]+)\.(\w+)/(\w+),(\w+)\.html /<span class="kw1">index</span>.php?$1=$2.$3&amp;$4=$5 last;<br />
&nbsp; &nbsp; <span class="kw1">rewrite</span> ^/([a-z]+),([0-9]+)\.(\w+)/(\w+)/(\w+)\.html /<span class="kw1">index</span>.php?$1=$2.$3&amp;$4&amp;$5 last;<br />
&nbsp; &nbsp; <span class="kw1">rewrite</span> ^/([a-z]+),([0-9]+)\.(\w+)/(\w+)\.html /<span class="kw1">index</span>.php?$1=$2.$3&amp;$4 last;<br />
&nbsp; &nbsp; <span class="kw1">rewrite</span> ^/([a-z]+),([0-9]+)\.(\w+)\.html /<span class="kw1">index</span>.php?$1=$2.$3 last;<br />
<br />
&nbsp; &nbsp; <span class="kw1">location</span> ~ \.php$ {<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_pass</span> unix:/dev/shm/php-fcgi.sock;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">fastcgi_param</span> SCRIPT_FILENAME $document_root$fastcgi_script_name;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">include</span> /etc/nginx/fastcgi_params;<br />
&nbsp; &nbsp; }<br />
}
        </div>
    </div>
</div>

<p>Я сознательно сделал два блока <code>rewrite</code>: первый (который содержит <code>index\.php</code>) предназначен для PATHINFO-ссылок; второй блок предназначен для нормальных ЧПУ. В принципе, достаточно только одного из блоков — в зависимости от того, какой тип ссылок планируется использовать.</p>
<p>Тем не менее, после конфигурирования nginx и включения «Дружественных URL» в панели управления форумом SMF всё равно продолжает использовать «человеконепонятные» URL. В чём причина? В движке форума: разработчики постарались, чтобы «Дружественные URL» работали только в Apache. Чтобы решить проблему, нужно немного подправить исходный код форума.</p>
<p>Открываем файл <code>Sources/QueryString.php</code>, в нём ищем функцию <code>ob_sessrewrite</code> (в 1.1.11 это самая последняя функция, располагается в конце файла).</p>
<p>В файле ищем такие строки:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p82323">
        <div class="code php" id="p823code23">
<ol class="php" style="font-family:monospace;" start="450"><li class="li1"><div class="de1">&nbsp; &nbsp; <span class="co1">// This should work even in 4.2.x, just not CGI without cgi.fix_pathinfo.</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy0">!</span><span class="kw1">empty</span><span class="br0">&#40;</span><span class="re0">$modSettings</span><span class="br0">&#91;</span><span class="st_h">'queryless_urls'</span><span class="br0">&#93;</span><span class="br0">&#41;</span> <span class="sy0">&amp;&amp;</span> <span class="br0">&#40;</span><span class="sy0">!</span><span class="re0">$context</span><span class="br0">&#91;</span><span class="st_h">'server'</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st_h">'is_cgi'</span><span class="br0">&#93;</span> <span class="sy0">||</span> <span class="sy0">@</span><span class="kw3">ini_get</span><span class="br0">&#40;</span><span class="st_h">'cgi.fix_pathinfo'</span><span class="br0">&#41;</span> <span class="sy0">==</span> 1<span class="br0">&#41;</span> <span class="sy0">&amp;&amp;</span> <span class="re0">$context</span><span class="br0">&#91;</span><span class="st_h">'server'</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st_h">'is_apache'</span><span class="br0">&#93;</span><span class="br0">&#41;</span></div></li>
</ol>
        </div>
    </div>
</div>

<p>Исправляем условие в <code>if</code>:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p82324">
        <div class="code php" id="p823code24">
<ol class="php" style="font-family:monospace;" start="450"><li class="li1"><div class="de1">&nbsp; &nbsp; <span class="co1">// This should work even in 4.2.x, just not CGI without cgi.fix_pathinfo.</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw4">true</span> <span class="sy0">||</span> <span class="sy0">!</span><span class="kw1">empty</span><span class="br0">&#40;</span><span class="re0">$modSettings</span><span class="br0">&#91;</span><span class="st_h">'queryless_urls'</span><span class="br0">&#93;</span><span class="br0">&#41;</span> <span class="sy0">&amp;&amp;</span> <span class="br0">&#40;</span><span class="sy0">!</span><span class="re0">$context</span><span class="br0">&#91;</span><span class="st_h">'server'</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st_h">'is_cgi'</span><span class="br0">&#93;</span> <span class="sy0">||</span> <span class="sy0">@</span><span class="kw3">ini_get</span><span class="br0">&#40;</span><span class="st_h">'cgi.fix_pathinfo'</span><span class="br0">&#41;</span> <span class="sy0">==</span> 1<span class="br0">&#41;</span> <span class="sy0">&amp;&amp;</span> <span class="re0">$context</span><span class="br0">&#91;</span><span class="st_h">'server'</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st_h">'is_apache'</span><span class="br0">&#93;</span><span class="br0">&#41;</span></div></li>
</ol>
        </div>
    </div>
</div>

<p>Сохраняем; после этого форум будет генерировать PATHINFO-ссылки. Если же index.php в ссылках смотрится некрасиво, то код нужно еще немного поправить:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p82325">
        <div class="code php" id="p823code25">
<ol class="php" style="font-family:monospace;" start="450"><li class="li1"><div class="de1">&nbsp; &nbsp; <span class="co1">// This should work even in 4.2.x, just not CGI without cgi.fix_pathinfo.</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw4">true</span> <span class="sy0">||</span> <span class="sy0">!</span><span class="kw1">empty</span><span class="br0">&#40;</span><span class="re0">$modSettings</span><span class="br0">&#91;</span><span class="st_h">'queryless_urls'</span><span class="br0">&#93;</span><span class="br0">&#41;</span> <span class="sy0">&amp;&amp;</span> <span class="br0">&#40;</span><span class="sy0">!</span><span class="re0">$context</span><span class="br0">&#91;</span><span class="st_h">'server'</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st_h">'is_cgi'</span><span class="br0">&#93;</span> <span class="sy0">||</span> <span class="sy0">@</span><span class="kw3">ini_get</span><span class="br0">&#40;</span><span class="st_h">'cgi.fix_pathinfo'</span><span class="br0">&#41;</span> <span class="sy0">==</span> 1<span class="br0">&#41;</span> <span class="sy0">&amp;&amp;</span> <span class="re0">$context</span><span class="br0">&#91;</span><span class="st_h">'server'</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st_h">'is_apache'</span><span class="br0">&#93;</span><span class="br0">&#41;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Let's do something special for session ids!</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw3">defined</span><span class="br0">&#40;</span><span class="st_h">'SID'</span><span class="br0">&#41;</span> <span class="sy0">&amp;&amp;</span> SID <span class="sy0">!=</span> <span class="st_h">''</span><span class="br0">&#41;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$buffer</span> <span class="sy0">=</span> <span class="kw3">preg_replace</span><span class="br0">&#40;</span><span class="st_h">'/&quot;'</span> <span class="sy0">.</span> <span class="kw3">preg_quote</span><span class="br0">&#40;</span><span class="re0">$scripturl</span><span class="sy0">,</span> <span class="st_h">'/'</span><span class="br0">&#41;</span> <span class="sy0">.</span> <span class="st_h">'\?(?:'</span> <span class="sy0">.</span> SID <span class="sy0">.</span> <span class="st_h">';)((?:board|topic)=[^#&quot;]+?)(#[^&quot;]*?)?&quot;/e'</span><span class="sy0">,</span> <span class="st0">&quot;'<span class="es1">\&quot;</span>' . <span class="es1">\$</span>scripturl . '/' . strtr('<span class="es1">\$</span>1', '&amp;;=', '//,') . '.html?' . SID . '<span class="es1">\$</span>2<span class="es1">\&quot;</span>'&quot;</span><span class="sy0">,</span> <span class="re0">$buffer</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$buffer</span> <span class="sy0">=</span> <span class="kw3">preg_replace</span><span class="br0">&#40;</span><span class="st_h">'/&quot;'</span> <span class="sy0">.</span> <span class="kw3">preg_quote</span><span class="br0">&#40;</span><span class="re0">$scripturl</span><span class="sy0">,</span> <span class="st_h">'/'</span><span class="br0">&#41;</span> <span class="sy0">.</span> <span class="st_h">'\?((?:board|topic)=[^#&quot;]+?)(#[^&quot;]*?)?&quot;/e'</span><span class="sy0">,</span> <span class="st0">&quot;'<span class="es1">\&quot;</span>' . <span class="es1">\$</span>scripturl . '/' . strtr('<span class="es1">\$</span>1', '&amp;;=', '//,') . '.html<span class="es1">\$</span>2<span class="es1">\&quot;</span>'&quot;</span><span class="sy0">,</span> <span class="re0">$buffer</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div></li>
</ol>
        </div>
    </div>
</div>

<p>Перед закрывающей скобкой нужно дописать две строчки:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p82326">
        <div class="code php" id="p823code26">
<ol class="php" style="font-family:monospace;" start="450"><li class="li1"><div class="de1">&nbsp; &nbsp; <span class="co1">// This should work even in 4.2.x, just not CGI without cgi.fix_pathinfo.</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw4">true</span> <span class="sy0">||</span> <span class="sy0">!</span><span class="kw1">empty</span><span class="br0">&#40;</span><span class="re0">$modSettings</span><span class="br0">&#91;</span><span class="st_h">'queryless_urls'</span><span class="br0">&#93;</span><span class="br0">&#41;</span> <span class="sy0">&amp;&amp;</span> <span class="br0">&#40;</span><span class="sy0">!</span><span class="re0">$context</span><span class="br0">&#91;</span><span class="st_h">'server'</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st_h">'is_cgi'</span><span class="br0">&#93;</span> <span class="sy0">||</span> <span class="sy0">@</span><span class="kw3">ini_get</span><span class="br0">&#40;</span><span class="st_h">'cgi.fix_pathinfo'</span><span class="br0">&#41;</span> <span class="sy0">==</span> 1<span class="br0">&#41;</span> <span class="sy0">&amp;&amp;</span> <span class="re0">$context</span><span class="br0">&#91;</span><span class="st_h">'server'</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st_h">'is_apache'</span><span class="br0">&#93;</span><span class="br0">&#41;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="br0">&#123;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1">// Let's do something special for session ids!</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw3">defined</span><span class="br0">&#40;</span><span class="st_h">'SID'</span><span class="br0">&#41;</span> <span class="sy0">&amp;&amp;</span> SID <span class="sy0">!=</span> <span class="st_h">''</span><span class="br0">&#41;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$buffer</span> <span class="sy0">=</span> <span class="kw3">preg_replace</span><span class="br0">&#40;</span><span class="st_h">'/&quot;'</span> <span class="sy0">.</span> <span class="kw3">preg_quote</span><span class="br0">&#40;</span><span class="re0">$scripturl</span><span class="sy0">,</span> <span class="st_h">'/'</span><span class="br0">&#41;</span> <span class="sy0">.</span> <span class="st_h">'\?(?:'</span> <span class="sy0">.</span> SID <span class="sy0">.</span> <span class="st_h">';)((?:board|topic)=[^#&quot;]+?)(#[^&quot;]*?)?&quot;/e'</span><span class="sy0">,</span> <span class="st0">&quot;'<span class="es1">\&quot;</span>' . <span class="es1">\$</span>scripturl . '/' . strtr('<span class="es1">\$</span>1', '&amp;;=', '//,') . '.html?' . SID . '<span class="es1">\$</span>2<span class="es1">\&quot;</span>'&quot;</span><span class="sy0">,</span> <span class="re0">$buffer</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$buffer</span> <span class="sy0">=</span> <span class="kw3">preg_replace</span><span class="br0">&#40;</span><span class="st_h">'/&quot;'</span> <span class="sy0">.</span> <span class="kw3">preg_quote</span><span class="br0">&#40;</span><span class="re0">$scripturl</span><span class="sy0">,</span> <span class="st_h">'/'</span><span class="br0">&#41;</span> <span class="sy0">.</span> <span class="st_h">'\?((?:board|topic)=[^#&quot;]+?)(#[^&quot;]*?)?&quot;/e'</span><span class="sy0">,</span> <span class="st0">&quot;'<span class="es1">\&quot;</span>' . <span class="es1">\$</span>scripturl . '/' . strtr('<span class="es1">\$</span>1', '&amp;;=', '//,') . '.html<span class="es1">\$</span>2<span class="es1">\&quot;</span>'&quot;</span><span class="sy0">,</span> <span class="re0">$buffer</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp;</div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$buffer</span> <span class="sy0">=</span> <span class="kw3">str_replace</span><span class="br0">&#40;</span><span class="st_h">'index.php/'</span><span class="sy0">,</span> <span class="st_h">''</span><span class="sy0">,</span> <span class="re0">$buffer</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$buffer</span> <span class="sy0">=</span> <span class="kw3">str_replace</span><span class="br0">&#40;</span><span class="st_h">'index.php'</span><span class="sy0">,</span> <span class="st_h">''</span><span class="sy0">,</span> <span class="re0">$buffer</span><span class="br0">&#41;</span><span class="sy0">;</span></div></li>
<li class="li1"><div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div></li>
</ol>
        </div>
    </div>
</div>

<p>После этого можно использовать нормальные ЧПУ.</p>
<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/seo/823-nginx-configuration-simple-machines-forum/">источник</a> обязательно.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.sjinks.pro/seo/823-nginx-configuration-simple-machines-forum/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Конфигурация nginx для работы с FUDforum</title>
		<link>http://blog.sjinks.pro/seo/820-nginx-configuration-fudforum/</link>
		<comments>http://blog.sjinks.pro/seo/820-nginx-configuration-fudforum/#comments</comments>
		<pubDate>Mon, 13 Sep 2010 02:32:01 +0000</pubDate>
		<dc:creator>Wandering Soul</dc:creator>
				<category><![CDATA[nginx]]></category>
		<category><![CDATA[SEO]]></category>
		<category><![CDATA[FUDforum]]></category>

		<guid isPermaLink="false">http://blog.sjinks.pro/?p=820</guid>
		<description><![CDATA[Настройка PATHINFO и pretty permalinks в FUDforum при использовании nginx FUDforum (Fast Uncompromising Discussion forum, Быстрый бескомпромиссный дискуссионный форум) — бесплатный интернет-форум с открытым кодом, обладающий широкими возможностями настройки и имеющий большой набор всяких плюшек и вкусностей. В данной статье пойдёт речь о том, как подружить форум с nginx. Официальный FAQ говорит о том, что FUDforum поддерживает [...]<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/seo/820-nginx-configuration-fudforum/">источник</a> обязательно.</p>]]></description>
			<content:encoded><![CDATA[<h2><em>Настройка PATHINFO и pretty permalinks в <a href="http://blog.sjinks.pro/tag/fudforum/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  FUDforum">FUDforum</a> при использовании <a href="http://blog.sjinks.pro/tag/nginx/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  nginx">nginx</a></em></h2>
<p><a href="http://fudforum.org/forum/">FUDforum</a> (Fast Uncompromising Discussion forum, Быстрый бескомпромиссный дискуссионный форум) — бесплатный интернет-форум с открытым кодом, обладающий  широкими возможностями настройки и имеющий большой набор всяких плюшек и вкусностей.</p>
<p>В данной статье пойдёт речь о том, как подружить форум с nginx.<span id="more-820"></span></p>
<p><a href="http://cvs.prohost.org/index.php/Frequently_Asked_Questions#Can_I_change_the_URL_format.2F_use_SEO_.28search_engine_friendly.29_URLs.3F" rel="nofollow">Официальный <abbr title="Frequently Asked Questions">FAQ</abbr></a> говорит о том, что FUDforum поддерживает как традиционные (со строкой запроса), так и PATHINFO-ссылки (то есть ссылки вида <code>index.<a href="http://blog.sjinks.pro/tag/php/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  PHP">php</a>/something/goes/here</code>).</p>
<p>Традиционные ссылки используются для максимальной совместимости с различными web-серверами и, как следствие, никакие изменения в конфигурации nginx не требуются. Но <a href="http://blog.sjinks.pro/tag/seo/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  SEO">SEO</a>&#8217;шники не любят некрасивые ссылки, поэтому в FUDforum встроена «изкоробочная» поддержка красивых ссылок. В простейшем случае при использовании PATHINFO-ссылок для <a href="http://blog.sjinks.pro/tag/apache/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  Apache">Apache</a> ничего не нужно настраивать — всё работает из коробки, а для nginx нужно приложить некоторые усилия.</p>
<p>Итак, пусть у нас есть такая начальная конфигурация виртуального хоста форума:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p82030">
        <div class="code nginx" id="p820code30">
<span class="kw1">server</span> {<br />
&nbsp; &nbsp; <span class="kw1">server_name</span> forum.site.com;<br />
<br />
&nbsp; &nbsp; <span class="kw1">root</span> /home/site.com/forum;<br />
&nbsp; &nbsp; <span class="kw1">index</span> <span class="kw1">index</span>.php;<br />
<br />
&nbsp; &nbsp; <span class="kw1">location</span> ~ \.php$ {<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_pass</span> unix:/dev/shm/php-fcgi.sock;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">fastcgi_param</span> SCRIPT_FILENAME $document_root$fastcgi_script_name;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">include</span> /etc/nginx/fastcgi_params;<br />
&nbsp; &nbsp; }<br />
}
        </div>
    </div>
</div>

<p>Для того, чтобы добавить поддержку PATHINFO, придётся переписать блок <code>location</code>. Дело в том, что nginx придётся <a href="http://sysoev.ru/nginx/docs/http/ngx_http_fastcgi_module.html#fastcgi_split_path_info" rel="nofollow">явно указывать</a>, где заканчивается имя скрипта и начинается PATHINFO.</p>
<p>Блок <code>location</code> будет выглядеть примерно так:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p82031">
        <div class="code nginx" id="p820code31">
&nbsp; &nbsp; <span class="kw1">location</span> ~ ^(.+\.php)(.*)$ {<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">fastcgi_split_path_info</span> ^(.+\.php)(.*)$;<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_pass</span> unix:/dev/shm/php-fcgi.sock;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">fastcgi_param</span> SCRIPT_FILENAME $document_root$fastcgi_script_name;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">fastcgi_param</span> PATH_INFO $fastcgi_path_info;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">include</span> /etc/nginx/fastcgi_params;<br />
&nbsp; &nbsp; }
        </div>
    </div>
</div>

<p>Изменилось регулярное выражение в <code>location</code> (так как в случае PATHINFO-ссылок имя php-скрипта будет находиться в середине URL), добавились директивы <code><a href="http://blog.sjinks.pro/tag/fastcgi/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  FastCGI">fastcgi</a>_split_path_info</code> и <code>fastcgi_param PATH_INFO $fastcgi_path_info</code> (первая указывает, как разбить URL на имя скрипта и PATHINFO, вторая передаёт PATHINFO php-скрипту).</p>
<p>Перезапускаем nginx, устанавливаем теме набор шаблонов path_info, перестраиваем тему, получаем красивые ссылки. Но index.php в URL выглядит не очень красиво, было бы неплохо убрать и его.</p>
<p>Это сложнее, но решаемо:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p82032">
        <div class="code nginx" id="p820code32">
<span class="kw1">server</span> {<br />
&nbsp; &nbsp; <span class="kw1">server_name</span> forum.site.com;<br />
<br />
&nbsp; &nbsp; <span class="kw1">root</span> /home/site.com/forum;<br />
&nbsp; &nbsp; <span class="kw1">index</span> <span class="kw1">index</span>.php;<br />
<br />
&nbsp; &nbsp; <span class="kw1">log_not_found</span> <span class="kw2">off</span>;<br />
&nbsp; &nbsp; <span class="kw1">error_page</span> 404 = @forum;<br />
<br />
&nbsp; &nbsp; <span class="kw1">location</span> ~ ^(.+\.php)(.*)$ {<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">try_files</span> $uri @forum;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">fastcgi_split_path_info</span> ^(.+\.php)(.*)$;<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_pass</span> unix:/dev/shm/php-fcgi.sock;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">fastcgi_param</span> SCRIPT_FILENAME $document_root$fastcgi_script_name;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">fastcgi_param</span> PATH_INFO $fastcgi_path_info;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">include</span> /etc/nginx/fastcgi_params;<br />
&nbsp; &nbsp; }<br />
<br />
&nbsp; &nbsp; <span class="kw1">location</span> @forum {<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">fastcgi_pass</span> unix:/dev/shm/php-fcgi.sock;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">fastcgi_param</span> SCRIPT_FILENAME $document_root/<span class="kw1">index</span>.php;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">include</span> /etc/nginx/fastcgi_params;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">fastcgi_param</span> PATH_INFO $uri;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">fastcgi_param</span> SCRIPT_NAME /<span class="kw1">index</span>.php;<br />
&nbsp; &nbsp; }<br />
}
        </div>
    </div>
</div>

<p>После этого открываем файл <code>FUDdata/include/compiler.inc</code> (где FUDdata — каталог с внутренними данными форума — задаётся при инсталляции), ищем строку</p>
<p><span class="codebox"><code class="php"><span class="re0">$cmpl</span><span class="br0">&#91;</span><span class="st_h">'ROOT'</span><span class="br0">&#93;</span> <span class="sy0">=</span> <span class="st_h">'index.php'</span><span class="sy0">;</span></code></span></p>
<p>изменяем на</p>
<p><span class="codebox"><code class="php"><span class="re0">$cmpl</span><span class="br0">&#91;</span><span class="st_h">'ROOT'</span><span class="br0">&#93;</span> <span class="sy0">=</span> <span class="st_h">'.'</span><span class="sy0">;</span></code></span></p>
<p>После чего сохраняем, перестраиваем тему и любуемся красивыми ссылками.</p>
<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/seo/820-nginx-configuration-fudforum/">источник</a> обязательно.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.sjinks.pro/seo/820-nginx-configuration-fudforum/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>FogBugz 7 и nginx</title>
		<link>http://blog.sjinks.pro/nginx/799-fogbugz-7-nginx/</link>
		<comments>http://blog.sjinks.pro/nginx/799-fogbugz-7-nginx/#comments</comments>
		<pubDate>Sun, 25 Apr 2010 17:52:23 +0000</pubDate>
		<dc:creator>Vladimir</dc:creator>
				<category><![CDATA[nginx]]></category>
		<category><![CDATA[Администрирование]]></category>
		<category><![CDATA[Apache]]></category>
		<category><![CDATA[FogBugz]]></category>

		<guid isPermaLink="false">http://blog.sjinks.pro/?p=799</guid>
		<description><![CDATA[Рабочая конфигурация nginx для FogBugz 7 На днях переводил один сервер с 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 [...]<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/nginx/799-fogbugz-7-nginx/">источник</a> обязательно.</p>]]></description>
			<content:encoded><![CDATA[<h2><em>Рабочая конфигурация <a href="http://blog.sjinks.pro/tag/nginx/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  nginx">nginx</a> для <a href="http://blog.sjinks.pro/tag/fogbugz/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  FogBugz">FogBugz</a> 7</em></h2>
<p>На днях переводил один сервер с <a href="http://blog.sjinks.pro/tag/apache/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  Apache">Apache</a> 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="p79935">
        <div class="code apache" id="p799code35">
&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="p79936">
        <div class="code nginx" id="p799code36">
<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>
<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/nginx/799-fogbugz-7-nginx/">источник</a> обязательно.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.sjinks.pro/nginx/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), на котором ни операционная система, ни программное обеспечение не были специально [...]<p>© 2012 <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> обязательно.</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>В предыдущей части я сравнивал поведение <a href="http://blog.sjinks.pro/tag/maxsite-cache/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  MaxSite Cache">MaxSite Cache</a> и <a href="http://blog.sjinks.pro/tag/wp-super-cache/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  WP Super Cache">WP Super Cache</a> на тестовом VDS (512 MiB RAM, 10 GB HD, Intel Xeon X3320 (1 ядро), 2.5 GHz), на котором ни операционная система, ни программное обеспечение не были специально настроены — бралась конфигурация «из коробки» и тестировалась. Одним словом, «VDS абсолютного чайника».</p>
<p>В этой части изменилась только конфигурация программного обеспечения: сервер настраивался на максимальную <a href="http://blog.sjinks.pro/tag/performance/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  производительность">производительность</a>.</p>
<p>В частности:</p>
<ul>
<li>отказ от <a href="http://blog.sjinks.pro/tag/apache/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  Apache">Apache</a> в пользу <a href="http://blog.sjinks.pro/tag/nginx/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  nginx">nginx</a> и от <code>mod_<a href="http://blog.sjinks.pro/tag/php/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  PHP">php</a>5</code> в пользу <code>php-fcgi</code> (количество <a href="http://blog.sjinks.pro/tag/fastcgi/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  FastCGI">FastCGI</a>-процессов выбиралось таким образом, чтобы избежать использования файла подкачки);</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>Голый <a href="http://blog.sjinks.pro/tag/wordpress/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  WordPress">WordPress</a></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 обращения к PHP-страницам в сутки.</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>
<p>© 2012 <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> обязательно.</p>]]></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[nginx]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[Безопасность]]></category>
		<category><![CDATA[HTTPS]]></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); Добавляем одну из этих двух строк [...]<p>© 2012 <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> обязательно.</p>]]></description>
			<content:encoded><![CDATA[<h2><em>Лишние плагины не нужны</em></h2>
<p><a href="http://blog.sjinks.pro/tag/wordpress/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  WordPress">WordPress</a>, начиная с версии 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="Записи, помеченные с  HTTPS">HTTPS</a>.</p>
<p>У администратора есть две возможности:</p>
<ol>
<li>Использование HTTPS для работы в панели управления (<code>wp-admin</code>).</li>
<li>Использование HTTPS только для входа в систему.</li>
</ol>
<p>Первое достигается путём добавления строки</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p71643">
        <div class="code php" id="p716code43">
<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="Записи, помеченные с  PHP">php</a></code>, второе — путём добавления строки</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p71644">
        <div class="code php" id="p716code44">
<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.php</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-форма, передающая данные на HTTPS-страницу, должна также находиться на HTTPS-странице. Связано это с тем, что соединение, по которому передаются данные, может прослушиваться. В случае обычного HTTP-соединения злоумышленник может модифицировать передаваемую от сервера форму, заменив <code>https</code> на <code>http</code>, что приведёт к тому, что форма будет отправлена по обычному (не зашифрованному) соединению, и злоумышленник сможет перехватить всю ценную информацию. Усугубляется это всё тем, что пользователь не может сказать, куда передаётся форма, не открыв исходный код страницы.</p>
<p>Для предотвращения подобного безобразия сама форма должна находиться на HTTPS-страницы: злоумышленник не сможет изменить данные, передаваемые по зашифрованному каналу.</p>
<p>Казалось бы, при чём тут <s>Лужков</s> WordPress? Во-первых, WordPress даже при включённом <code>FORCE_<a href="http://blog.sjinks.pro/tag/ssl/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  SSL">SSL</a>_LOGIN</code> не перенаправляет пользователя с <code>http://.../wp-login.php</code> на <code>https://.../wp-login.php</code>. А во-вторых, WordPress — это не только платформа для блоггинга, это еще и <a href="http://wordpress.org/development/2009/11/wordpress-wins-cms-award/">CMS</a>, на основе которой делаются всякие магазины и даже целые панели управления сайтами (да, я принимал участие в создании одной из таких панелей). Иными словами, платформы, где успешный перехват логина и пароля может привести к очень печальным последствиям.</p>
<p>Какие есть варианты? Самый простой — написать простой плагин, который сделает перенаправление с HTTP на HTTPS для <code>wp-login.php</code>. Но лишний PHP-код скорости работы не прибавляет, а потому не наш метод. Тем более, когда всё можно сделать на уровне сервера.</p>
<p>Рассмотрим на примере <a href="http://blog.sjinks.pro/tag/nginx/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  nginx">nginx</a>.</p>
<p>В nginx есть две возможности настроить HTTPS-сервер. <strong>Первая</strong> (она же наиболее часто используемая) — это задание отдельного виртуального хоста для HTTP- и HTTPS-версий сайта. Что-то вида</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p71645">
        <div class="code nginx" id="p716code45">
<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="p71646">
        <div class="code nginx" id="p716code46">
<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- и HTTPS-версию сайта в одном виртуальном хосте:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p71647">
        <div class="code nginx" id="p716code47">
<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="p71648">
        <div class="code nginx" id="p716code48">
<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><a href="http://blog.sjinks.pro/tag/fastcgi/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  FastCGI">fastcgi</a>_xxx</code> нужно указать свои пути.</p>
<p>После этого nginx будет автоматически перенаправлять посетителя с <code>http://.../wp-login.php</code> на <code>https://.../wp-login.php</code>. Таким образом и форма, и адрес отправления формы будут находиться на защищённых страницах.</p>
<p>© 2012 <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> обязательно.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.sjinks.pro/security/716-secure-wordpress-login-with-nginx/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Профиль AppArmor для nginx</title>
		<link>http://blog.sjinks.pro/nginx/700-apparmor-profile-for-nginx/</link>
		<comments>http://blog.sjinks.pro/nginx/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[nginx]]></category>
		<category><![CDATA[Администрирование]]></category>
		<category><![CDATA[AppArmor]]></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 находятся [...]<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/nginx/700-apparmor-profile-for-nginx/">источник</a> обязательно.</p>]]></description>
			<content:encoded><![CDATA[<h2><em>Экспериментальный профиль <a href="http://blog.sjinks.pro/tag/apparmor/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  AppArmor">AppArmor</a> для <a href="http://blog.sjinks.pro/tag/nginx/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  nginx">nginx</a> в Ubuntu Linux</em></h2>
<p>Данный профиль AppArmor предназначается тем, кто знает, что такое AppArmor и сознательно решил использовать профиль для 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/<a href="http://blog.sjinks.pro/tag/ssl/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  SSL">ssl</a></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>Получился такой профиль AppArmor:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p70051">
        <div class="code apparmor" id="p700code51">
#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="p70052">
        <div class="code text" id="p700code52">
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>
<p>© 2012 <a href="http://blog.sjinks.pro">Ars Longa, Vita Brevis</a>. Все права защищены. Перепубликация материалов без разрешения автора запрещена.</p>
<p>При использовании материалов блога наличие активной не закрытой от индексирования ссылки на <a href="http://blog.sjinks.pro/nginx/700-apparmor-profile-for-nginx/">источник</a> обязательно.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.sjinks.pro/nginx/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[nginx]]></category>
		<category><![CDATA[WordPress]]></category>
		<category><![CDATA[Feedburner]]></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 [...]<p>© 2012 <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> обязательно.</p>]]></description>
			<content:encoded><![CDATA[<h2><em>Выполнение перенаправления без плагинов</em></h2>
<p>Хотя для перенаправления фидов <a href="http://blog.sjinks.pro/tag/wordpress/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  WordPress">WordPress</a> на <a href="http://blog.sjinks.pro/tag/feedburner/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  Feedburner">Feedburner</a> существует несколько плагинов, справиться с этой задачей можно и силами web-сервера. Рассмотрим на примере <a href="http://blog.sjinks.pro/tag/nginx/" class="st_tag internal_tag" rel="tag" title="Записи, помеченные с  nginx">nginx</a>.<span id="more-691"></span></p>
<p>С использованием постоянных ссылок:</p>
          
<div class="codebox">
    <div class="the_code" style="" id="p69155">
        <div class="code nginx" id="p691code55">
<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="p69156">
        <div class="code nginx" id="p691code56">
<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>
<p>© 2012 <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> обязательно.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.sjinks.pro/wordpress/691-redirect-rss-feeds-to-feedburner-with-nginx/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>

