获取HTTP / 2在Apache上工作

我现在更像是一个nginx头(我没有任何问题让HTTP / 2能够正常工作),但是我完全被Apache搞糊涂了,似乎无法让它通过HTTP / 2服务于一个站点。

服务器是Debian 8.我已经安装了Apache 2.4.27和openssl1.1.0f,启用了Debian的“testing”回购。

这里有一些有用的信息和服务器configuration:

Apache版本

root@server:~# apachectl -V Server version: Apache/2.4.27 (Debian) Server built: 2017-07-16T21:01:10 Server's Module Magic Number: 20120211:68 Server loaded: APR 1.5.1, APR-UTIL 1.5.4 Compiled using: APR 1.5.2, APR-UTIL 1.5.4 Architecture: 64-bit Server MPM: prefork threaded: no forked: yes (variable process count) Server compiled with.... -D APR_HAS_SENDFILE -D APR_HAS_MMAP -D APR_HAVE_IPV6 (IPv4-mapped addresses enabled) -D APR_USE_SYSVSEM_SERIALIZE -D APR_USE_PTHREAD_SERIALIZE -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT -D APR_HAS_OTHER_CHILD -D AP_HAVE_RELIABLE_PIPED_LOGS -D DYNAMIC_MODULE_LIMIT=256 -D HTTPD_ROOT="/etc/apache2" -D SUEXEC_BIN="/usr/lib/apache2/suexec" -D DEFAULT_PIDLOG="/var/run/apache2.pid" -D DEFAULT_SCOREBOARD="logs/apache_runtime_status" -D DEFAULT_ERRORLOG="logs/error_log" -D AP_TYPES_CONFIG_FILE="mime.types" -D SERVER_CONFIG_FILE="apache2.conf" 

Apache模块

 root@server:~# apachectl -M Loaded Modules: core_module (static) so_module (static) watchdog_module (static) http_module (static) log_config_module (static) logio_module (static) version_module (static) unixd_module (static) access_compat_module (shared) alias_module (shared) auth_basic_module (shared) authn_core_module (shared) authn_file_module (shared) authz_core_module (shared) authz_host_module (shared) authz_user_module (shared) autoindex_module (shared) deflate_module (shared) dir_module (shared) env_module (shared) expires_module (shared) filter_module (shared) headers_module (shared) http2_module (shared) mime_module (shared) mpm_prefork_module (shared) negotiation_module (shared) php5_module (shared) reqtimeout_module (shared) rewrite_module (shared) setenvif_module (shared) socache_shmcb_module (shared) ssl_module (shared) status_module (shared) 

OpenSSL版本

 root@server:/root# openssl version OpenSSL 1.1.0f 25 May 2017 

Apache基本configuration

 root@server:~# cat /etc/apache2/apache2.conf DefaultRuntimeDir ${APACHE_RUN_DIR} PidFile ${APACHE_PID_FILE} Timeout 300 KeepAlive On MaxKeepAliveRequests 100 KeepAliveTimeout 5 User ${APACHE_RUN_USER} Group ${APACHE_RUN_GROUP} HostnameLookups Off ErrorLog ${APACHE_LOG_DIR}/error.log LogLevel warn IncludeOptional mods-enabled/*.load IncludeOptional mods-enabled/*.conf Include ports.conf <Directory /> Options FollowSymLinks AllowOverride None Require all denied </Directory> <Directory /usr/share> AllowOverride None Require all granted </Directory> <Directory /var/www/> Options Indexes FollowSymLinks AllowOverride None Require all granted </Directory> AccessFileName .htaccess <FilesMatch "^\.ht"> Require all denied </FilesMatch> LogFormat "%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined LogFormat "%h %l %u %t \"%r\" %>s %O" common LogFormat "%{Referer}i -> %U" referer LogFormat "%{User-agent}i" agent IncludeOptional conf-enabled/*.conf IncludeOptional sites-enabled/*.conf 

Apache SSLconfiguration

 root@server:~# cat /etc/apache2/mods-available/ssl.conf <IfModule mod_ssl.c> SSLRandomSeed startup builtin SSLRandomSeed startup file:/dev/urandom 512 SSLRandomSeed connect builtin SSLRandomSeed connect file:/dev/urandom 512 AddType application/x-x509-ca-cert .crt AddType application/x-pkcs7-crl .crl SSLPassPhraseDialog exec:/usr/share/apache2/ask-for-passphrase SSLSessionCache shmcb:${APACHE_RUN_DIR}/ssl_scache(512000) SSLSessionCacheTimeout 300 SSLCipherSuite 'EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA !RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS' SSLHonorCipherOrder on SSLProtocol all -SSLv3 SSLCompression off SSLSessionTickets off SSLUseStapling on SSLStaplingResponderTimeout 5 SSLStaplingReturnResponderErrors off SSLStaplingCache shmcb:/var/run/ocsp(128000) SSLOpenSSLConfCmd DHParameters "/etc/apache2/ssl/dhparam.pem" <FilesMatch "\.php$"> SSLOptions +StdEnvVars </FilesMatch> BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown </IfModule> 

Apache HTTP2configuration

 root@server:~# cat /etc/apache2/mods-enabled/http2.conf H2Push on H2PushPriority * after H2PushPriority text/css before H2PushPriority image/jpeg after 32 H2PushPriority image/png after 32 H2PushPriority application/javascript interleaved 

Apache安全configuration

 root@server:~# cat /etc/apache2/conf-available/security.conf ServerTokens Prod ServerSignature Off TraceEnable Off <IfModule mod_headers.c> Header set X-UA-Compatible "IE=Edge" Header always set Strict-Transport-Security "max-age=15768000" <FilesMatch "\.(appcache|atom|bbaw|bmp|crx|css|cur|eot|f4[abpv]|flv|geojson|gif|htc|ico|jpe?g|js|json(ld)?|m4[av]|manifest|map|mp4|oex|og[agv]|opus|otf|pdf|png|rdf|rss|safariextz|svgz?|swf|topojson|tt[cf]|txt|vcard|vcf|vtt|webapp|web[mp]|webmanifest|woff2?|xloc|xml|xpi)$"> Header unset X-UA-Compatible </FilesMatch> Header always append X-Frame-Options SAMEORIGIN Header set X-Content-Type-Options nosniff Header set X-XSS-Protection "1; mode=block" </IfModule> <IfModule mod_setenvif.c> SetEnvIf Request_URI "^/(browserconfig\.xml|manifest\.json|robots\.txt|sitemap\.xml|.well-known/.*)$" dontlog </IfModule> <IfModule mod_rewrite.c> <FilesMatch "^/(browserconfig\.xml|manifest\.json|robots\.txt|sitemap\.xml)$"> RewriteEngine on RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L] </FilesMatch> </IfModule> <FilesMatch "(?:^|/)\."> Require all denied </FilesMatch> <FilesMatch "(?:\.(?:bak|config|sql|fla|psd|ini|log|sh|inc|swp|dist)|~)$"> Require all denied </FilesMatch> 

Apache VirtualHostconfiguration

 root@server:~# cat /etc/apache2/sites-available/www_xxxxxx_com.conf ServerName server <VirtualHost *:80> ServerName xxxxxx.com Redirect 301 / https://www.xxxxxx.com/ </VirtualHost> <VirtualHost *:80> ServerName www.xxxxxx.com Redirect 301 / https://www.xxxxxx.com/ </VirtualHost> <VirtualHost *:443> ServerName xxxxxx.com Redirect 301 / https://www.xxxxxx.com/ SSLEngine on SSLCertificateFile /etc/letsencrypt/live/xxxxxx.com/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/xxxxxx.com/privkey.pem SSLCertificateChainFile /etc/letsencrypt/live/xxxxxx.com/fullchain.pem SSLCACertificateFile /etc/letsencrypt/live/xxxxxx.com/fullchain.pem Protocols h2 http/1.1 </VirtualHost> <VirtualHost *:443> ServerName www.xxxxxx.com ServerAdmin webmaster@localhost DocumentRoot /data/www_xxxxxx_com/public_html ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined env=!dontlog SSLEngine on SSLCertificateFile /etc/letsencrypt/live/xxxxxx.com/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/xxxxxx.com/privkey.pem SSLCertificateChainFile /etc/letsencrypt/live/xxxxxx.com/fullchain.pem SSLCACertificateFile /etc/letsencrypt/live/xxxxxx.com/fullchain.pem Protocols h2 http/1.1 <Directory /data/www_xxxxxx_com/public_html/> AllowOverride All Require all granted </Directory> </VirtualHost> 

我testing了所有这些使用https://tools.keycdn.com/http2-test出现负面,加上使用curl(版本7.55.1 – 与HTTP2支持):

 ➜ ~ curl -v --http2 https://www.xxxxxx.com * Rebuilt URL to: https://www.xxxxxx.com/ * Trying XXX.XXX.XXX.XXX... * TCP_NODELAY set * Connected to www.xxxxxx.com (XXX.XXX.XXX.XXX) port 443 (#0) * ALPN, offering h2 * ALPN, offering http/1.1 * Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH * successfully set certificate verify locations: * CAfile: /usr/local/etc/openssl/cert.pem CApath: /usr/local/etc/openssl/certs * TLSv1.2 (OUT), TLS header, Certificate Status (22): * TLSv1.2 (OUT), TLS handshake, Client hello (1): * TLSv1.2 (IN), TLS handshake, Server hello (2): * TLSv1.2 (IN), TLS handshake, Certificate (11): * TLSv1.2 (IN), TLS handshake, Server key exchange (12): * TLSv1.2 (IN), TLS handshake, Server finished (14): * TLSv1.2 (OUT), TLS handshake, Client key exchange (16): * TLSv1.2 (OUT), TLS change cipher, Client hello (1): * TLSv1.2 (OUT), TLS handshake, Finished (20): * TLSv1.2 (IN), TLS change cipher, Client hello (1): * TLSv1.2 (IN), TLS handshake, Finished (20): * SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384 * ALPN, server accepted to use http/1.1 * Server certificate: * subject: CN=xxxxxx.com * start date: Aug 24 11:07:00 2017 GMT * expire date: Nov 22 11:07:00 2017 GMT * subjectAltName: host "www.xxxxxx.com" matched cert's "www.xxxxxx.com" * issuer: C=US; O=Let's Encrypt; CN=Let's Encrypt Authority X3 * SSL certificate verify ok. HTTP/1.1 200 OK Date: Thu, 24 Aug 2017 15:30:35 GMT Server: Apache Strict-Transport-Security: max-age=15768000 X-Frame-Options: SAMEORIGIN Upgrade: h2 Connection: Upgrade Set-Cookie: PHPSESSID=knqh31ge9fqd60g4r40r7ngum4; path=/ Expires: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Pragma: no-cache X-UA-Compatible: IE=Edge X-Content-Type-Options: nosniff X-XSS-Protection: 1; mode=block Content-Type: text/html; charset=UTF-8 

有没有人有任何想法,我在这里失踪,因为这是驱使我疯狂?

干杯!

哦,为了上帝的缘故 – 为什么我几乎总是像这样的事情之后,我发布的问题。 噢 – 希望这可以帮助别人。

答案在于错误日志:

 [Thu Aug 24 17:55:09.795729 2017] [http2:info] [pid 16949] AH03090: mod_http2 (v1.10.7, feats=CHPRIO+SHA256+INVHD+DWINS, nghttp2 1.24.0), initializing... [Thu Aug 24 17:55:09.795846 2017] [http2:warn] [pid 16949] AH10034: The mpm module (prefork.c) is not supported by mod_http2. The mpm determines how things are processed in your server. HTTP/2 has more demands in this regard and the currently selected mpm will just not do. This is an advisory warning. Your server will continue to work, but the HTTP/2 protocol will be inactive. [Thu Aug 24 17:55:09.827124 2017] [mpm_prefork:notice] [pid 16949] AH00163: Apache/2.4.27 (Debian) OpenSSL/1.0.2l configured -- resuming normal operations 

所以我们就去 – 只要使用'事件'或'工人'MPM而不是prefork。