最近在配置 WordPress 的过程中,笔者希望可以做到以下几点:
下面具体说明如何达到这些目标。
有关 cookie-free domains,请参考上一篇文章。
要达到第一点要求,必须在主域之外,使用第二个域作为 cookie-free 域。
要达到第二点和第三点要求,该 cookie-free 域:a)必须能通过 HTTPS 访问;b)不能直接修改 WordPress 源文件中静态资源为 http://cookie-free.domain/...,写死之后在 HTTPS 访问时会出现混合内容警告。
关于a):笔者选择 opoo.org 作为主域,www.opoo.org 作为 cookie-free 域,因为笔者申请的 StartSSL 的证书只支持这两个域,如果读者有其它支持 HTTPS 的域,也可以选择来做 cookie-free 的域。
关于b):笔者主要对 wp-content 目录下的内容做 cookie-free 处理。修改 wp-config.php
文件,添加以下一行
define('WP_CONTENT_URL', 'http://www.opoo.org/wp-content');好处:
https://www.opoo.org/wp-content
;可能会导致部分主题或插件工作不正常。
主题、插件目录中除了静态文件,还有部分 php 文件。这些 php 文件在调用时 url 也变成了 http://www.opoo.org/wp-content/.../x.php 的形式,如果 php 文件运行时需要主域的 cookie,就会出错。
笔者目前发现语法高亮插件 Syntax Highlighter ComPress 就有这个问题,它在后台管理时通过 cookie-free 域访问了一个 php 文件,由于拿不到 Cookie 信息,该 php 直接返回一个错误信息。
解决这个问题的办法是通过 Rewrite 规则重写,将所有的 php 文件或者 非 wp-content 目录下的文件的访问都转发回主域。
# cookie-free 域下所有的 php 访问转发回主域 RewriteCond %{HTTP_HOST} ^www.opoo.org${'$'} [NC] RewriteCond %{REQUEST_URI} (.*).php${'$'} [NC] RewriteRule ^(.*)${'$'} http://opoo.org${'$'}1 [L,R=301] # 除了 wp-content 开头的 url,cookie-free 域下其它访问转发回主域 RewriteCond %{HTTP_HOST} ^www.opoo.org${'$'} [NC] RewriteCond %{REQUEST_URI} !^/wp-content/ RewriteRule ^(.*)${'$'} http://opoo.org${'$'}1 [L,R=301]
另外也需要在 ssl.conf 中配置,将以上内容中的 http 换成 https 即可。
如果读者是超级完美主义者,想将 wp-includes 目录下的静态文件也 cookie-free,那么就要修改 WordPress 源文件。建议修改时判断一下,以保证能同时在 HTTP 和 HTTPS 下访问。
${'$'}url = (is_ssl() ? "https" : "http") . "://www.opoo.org/wp-includes/.../css.css"最后,将已有文章中的图片的 url 替换成 cookie-free domain,执行以下 SQL 语句
update wp_posts set post_content=replace(post_content, 'http://opoo.org/wp-content/uploads', 'http://www.opoo.org/wp-content/uploads') where post_content like '%http://opoo.org/wp-content/uploads%';
这样修改后文章中的所有文章都指向了 http 开头的 cookie-free 域,在 HTTPS 访问主域会出现混合内容警告信息,可建一个插件解决这个问题。插件主要代码如下:
function my_content_manipulator(${'$'}content){ if( is_ssl() ){ ${'$'}content = str_replace('http://www.opoo.org/wp-content/uploads', 'https://www.opoo.org/wp-content/uploads', ${'$'}content); } return ${'$'}content; } add_filter('the_content', 'my_content_manipulator');
通过 HTTPS 访问时,文章在显示之前会被插件替换其中图片 url 的协议。
要实现通过 HTTPS 访问网站,需要购买一个用于 WEB 服务器的 SSL 证书,也可在 StartSSL 免费申请。
如果仅用于测试,也可以通过 openssl 之类的软件生成一个自签名的证书。自签名的证书在访问时会显示网站不受信任,在谷歌浏览器地址栏里有显示一个叉,别的浏览器也会有相应提示。
如果用于正式的生产环境,非常不建议使用自签名证书,不要像某道部的网站一样瞎搞。
在 StartSSL 证书申请过程中,先是保存的密匙文件 ssl.key
,后来又保存了颁发的证书文件 ssl.crt
,在 StartSSL 的安装指引里要求下载文件 ca.pem
和 sub.class1.server.ca.pem
,将这 4 个文件上传到服务器上(如目录 /etc/pki/ssl/),然后修改 Apache 的配置文件(也可以在 conf.d 目录下新建文件 ssl.conf),增加以下内容:
LoadModule ssl_module modules/mod_ssl.so Listen 443 <VirtualHost _default_:443> DocumentRoot /var/www/wordpress_root ErrorLog logs/error_log TransferLog logs/access_log SSLEngine on SSLProtocol all -SSLv2 SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM SSLCertificateFile /etc/pki/ssl/ssl.crt SSLCertificateKeyFile /etc/pki/ssl/ssl.key SSLCertificateChainFile /etc/pki/ssl/sub.class1.server.ca.pem SSLCACertificateFile /etc/pki/ssl/ca.pem CustomLog logs/ssl_request_log \ "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b" </VirtualHost>
这是为 Apache 配置 SSL 最核心的部分。
必须为 Apache 安装 mod_ssl 模块。CentOS 通过 yum install mod_ssl
即可安装该模块,并在 /etc/httpd/conf.d/
下生成配置文件 ssl.conf,修改其内容即可。
在 StartSSL 创建的私匙是加密的,启动 Apache 服务器时,可能提示输入的密码,输入申请过程中填写的密码即可。
如果要去除这个提示,可对私匙进行解密,执行以下命令
#openssl rsa -in ssl.key -out ssl.key #chmod 400 ssl.key
如果网站是通过 HTTPS 访问的,而网页中引用了其它 HTTP 协议访问的资源时,就会出现混合内容的警告,在谷歌浏览器下显示成这样: 点开小三角可以看见一段描述“但是,此网页中包含其他不安全的资源”。而引用资源也全部是 https 时,则显示成这样:
混合内容在 IE 下会导致浏览器直接弹出一个警告框“本页不但包含安全的内容,也包含不安全的内容。是否显示不安全的内容?”,必须选择是才能访问。
b) 如果 HTTPS 页面引用了 HTTP 协议访问的 JavaScript 脚本,那么该脚本会被屏蔽,直接不执行(至少在谷歌浏览器里的表现是这样的)。打开谷歌浏览器的控制台 console 看以看到警告信息,以及被 blocked 的脚本。
基于以上两点,应该尽量确保页面中所有引用资源和页面本身使用同一种访问协议(http 或者 https),起码保证 HTTPS 协议下时应该一致。
HTTP 协议下引用 HTTPS 资源是不会出现警告的,直接将 cookie-free 域下所有资源都改为 https 访问倒是相当省事的做法。但 HTTPS 是一种加密传输的协议,理论上会降低访问速度。所在既然主域使用 HTTP 协议了,cookie-free 域也尽量使用 HTTP 协议。
(完美主义强迫症患者 - -! )
Apache 目录级的配置文件 .htaccess 会降低 Apache 的性能,尽管很小。
Apache 配置 AllowOverride None
时会忽略目录级的配置文件。
WordPress 使用固定链接时,需要 htaccess 的支持,如果不启用 .htaccess, 可以将配置写进 Apache 主配置文件。如下:
<Directory "/var/www/wordpress_root"> <IfModule mod_rewrite.c> RewriteEngine On RewriteBase / RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L] </IfModule> <Files "wp-config.php"> Order allow,deny Deny from all </Files> </Directory>
DocumentRoot /var/www/wordpress_root ServerName opoo.org ServerAlias www.opoo.org RewriteEngine On RewriteCond %{HTTP_HOST} ^www.opoo.org${'$'} [NC] RewriteCond %{REQUEST_URI} (.*).php${'$'} [NC] RewriteRule ^(.*)${'$'} http://opoo.org${'$'}1 [L,R=301] RewriteCond %{HTTP_HOST} ^www.opoo.org${'$'} [NC] RewriteCond %{REQUEST_URI} !^/wp-content/ [NC] RewriteRule ^(.*)${'$'} http://opoo.org${'$'}1 [L,R=301] <Directory "/var/www/wordpress_root"> Options -Indexes FollowSymLinks AllowOverride None Order allow,deny Allow from all <IfModule mod_rewrite.c> RewriteEngine On RewriteBase / RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L] RewriteRule ^wp-admin/includes/ - [F,L] RewriteRule !^wp-includes/ - [S=3] RewriteRule ^wp-includes/[^/]+\.php${'$'} - [F,L] RewriteRule ^wp-includes/js/tinymce/langs/.+\.php - [F,L] RewriteRule ^wp-includes/theme-compat/ - [F,L] </IfModule> <Files "wp-config.php"> Order allow,deny Deny from all </Files> </Directory>
LoadModule ssl_module modules/mod_ssl.so Listen 443 <VirtualHost _default_:443> DocumentRoot /var/www/wordpress_root ServerName opoo.org ServerAlias www.opoo.org ErrorLog /usr/local/apache/logs/ssl-error_log TransferLog /usr/local/apache/logs/ssl-transfer_log CustomLog /usr/local/apache/logs/ssl-access_log \ "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b" SSLEngine on SSLProtocol all -SSLv2 SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM SSLCertificateFile /etc/pki/ssl/ssl.crt SSLCertificateKeyFile /etc/pki/ssl/ssl.key SSLCertificateChainFile /etc/pki/ssl/sub.class1.server.ca.pem SSLCACertificateFile /etc/pki/ssl/ca.pem SetEnvIf User-Agent ".*MSIE.*" \ nokeepalive ssl-unclean-shutdown \ downgrade-1.0 force-response-1.0 RewriteEngine On RewriteCond %{HTTP_HOST} ^www.opoo.org${'$'} [NC] RewriteCond %{REQUEST_URI} (.*).php${'$'} [NC] RewriteRule ^(.*)${'$'} https://opoo.org${'$'}1 [L,R=301] RewriteCond %{HTTP_HOST} ^www.opoo.org${'$'} [NC] RewriteCond %{REQUEST_URI} !^/wp-content/ [NC] RewriteRule ^(.*)${'$'} https://opoo.org${'$'}1 [L,R=301] <Directory "/var/www/wordpress_root"> Options -Indexes FollowSymLinks AllowOverride None Order allow,deny Allow from all <IfModule mod_rewrite.c> RewriteEngine On RewriteBase / RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L] RewriteRule ^wp-admin/includes/ - [F,L] RewriteRule !^wp-includes/ - [S=3] RewriteRule ^wp-includes/[^/]+\.php${'$'} - [F,L] RewriteRule ^wp-includes/js/tinymce/langs/.+\.php - [F,L] RewriteRule ^wp-includes/theme-compat/ - [F,L] </IfModule> <Files "wp-config.php"> Order allow,deny Deny from all </Files> </Directory> </VirtualHost>
/** * 在管理页面全部使用 HTTPS */ define('FORCE_SSL_ADMIN', true); /** * For cookie-free */ define('WP_CONTENT_URL', 'http://www.opoo.org/wp-content');
function my_content_manipulator(${'$'}content){ if( is_ssl() ){ ${'$'}content = str_replace('http://www.opoo.org/wp-content/uploads', 'https://www.opoo.org/wp-content/uploads', ${'$'}content); } return ${'$'}content; } add_filter('the_content', 'my_content_manipulator');
Source |
|