Open ourfor opened 5 years ago
由于刚接触很久没有接触Apache
,我打算在虚拟机上面熟悉以后再搬到生产环境上面去。接下来的笔记将会从以下几个方面来记录:
Apache
安装包括编译安装Apache
配置文件位置,熟悉配置文件macOS下面,httpd.conf
里面设置User
为自己系统里面的用户名,可以解决没有搜索权限
Listen 80
<VirtualHost *:80>
DocumentRoot /Users/sagit/Documents/wwwroot/Blog/public
ServerName blog.ourfor.com
<Directory "/Users/sagit/Documents/wwwroot/Blog/public">
Options FollowSymLinks
AllowOverride None
Order allow,deny
Require all granted
Allow from all
</Directory>
ErrorLog "/usr/local/var/log/httpd/blog.ourfor.com.com-error_log"
</VirtualHost>
如果页面提示禁止没有权限,那么不要忘了<Directory>
里面的内容:
<Directory "/Users/sagit/Documents/wwwroot/Blog/public">
Options FollowSymLinks
AllowOverride None
Order allow,deny
Require all granted
Allow from all
</Directory>
打开目录浏览功能需要在在Options后面添加: Indexes
,即Options Indexes FollowSymLinks
,文件图标显示,需要Include
那个配置autoindex
的配置文件(httpd-autoindex.conf
)
macOS编译mod_jk
,安装好httpd
-apache
编译命令:
./configure CFLAGS='-arch x86_64' APXSLDFLAGS='-arch x86_64' --with-apxs=/usr/local/bin/apxs
make
有些脚本是在window下面写的,在unix上面有些不可见字符,可以用vi打开后设置fileformat
,即:set fileformat=unix
或者:set ff=unix
apache httpd
服务器连接tomcat
演示系统环境
macOS Majave 10.14.4
mod_jk
模块,我已经编译好了最新的,适用于Apache版本Server version: Apache/2.4.39 (Unix)
在httpd
的配置文件中添加一个名为httpd-jk.conf
(名字可以随便取),同时在httpd.conf
里面导入这个配置文件:
# Virtual hosts
Include /usr/local/etc/httpd/extra/httpd-vhosts.conf
顺便把User
改成你的登录用户名,原本为_www
User sagit
Group _www
这样的话网站更目录就不需要放在默认的位置了
httpd-jk.conf
文件,该文件负责导入mod_jk
,将下载好的mod_jk.so
文件放到httpd的模块文件夹里面,然后编辑httpd-jk.conf
文件:主要注意下面几个位置
LoadModule jk_module lib/httpd/modules/mod_jk.so
<IfModule jk_module>
# and in the global server
JkWorkersFile /usr/local/etc/httpd/extra/workers.properties
# Our JK error log
# You can (and should) use rotatelogs here
JkLogFile /usr/local/var/log/httpd/mod_jk.log
# Our JK shared memory file
JkShmFile /usr/local/var/log/httpd//mod_jk.shm
加载mod_jk
的路径,这里的路径跟随httpd.conf
里面写,因为这个文件会被原封不动的include到httpd.conf
里面,只需要修改一下最后的模块文件名,即mod_jk.so
接下来这个JkWorkersFile
指明workers.properties
的位置,这个worker.properties
文件最好放在和httpd-jk.conf
同一目录下面,并且按照httpd.conf
里面导入额外的配置文件的父路径一致,JkLogFile
和JkShmFile
这两个文件的父路径和httpd.conf
里面存放日志文件的父路径一致
workers.properties
里面写什么
worker.list=jk-manager,tomcatA
worker.jk-manager.type=status
worker.tomcatA.type=ajp13 worker.tomcatA.host=localhost worker.tomcatA.port=8009
主要注意` worker.list `,这里面写了几个东西,下面就要配置几个
- 接下来是tomcat的` server.xml `文件
https://github.com/ourfor/Blog/blob/d8b3eb027971e15ce854055dc1348de2367009be/tomcat/mod_jk/server.xml#L128-L133
- Apache里面配置虚拟主机就行了
<VirtualHost :80> DocumentRoot /usr/local/Cellar/tomcat/9.0.17/libexec/webapps/lab_war_exploded ServerName file.ourfor.com JkMount / tomcatA DirectoryIndex index.html index.jsp <Directory "/usr/local/Cellar/tomcat/9.0.17/libexec/webapps/lab_war_exploded"> Options FollowSymLinks AllowOverride None Order allow,deny Allow from all
其中` jkMount `是匹配规则,匹配到什么路径才交给` tomcat `处理,以及交给谁处理
如果需要在一个服务器上面部署配置多个tomcat的webapp
的话,只需要在httpd-vhosts.conf
和server.xml
里面添加就可以了.
server.xml
httpd-vhosts.conf
如果使用idea
开发的话,这里server.xml
里面的docBase
也写成绝对路径,或者将appbase
写成绝对路径,二选一
<Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcatA">
<Host name="file.ourfor.com" appBase="/Users/sagit/Desktop/www"
unpackWARs="true" autoDeploy="true"
xmlValidation="false" xmlNamespaceAware="false">
<Context path="" docBase="lab_war_exploded" />
</Host>
<Host name="doc.ourfor.com" appBase="webapps"
unpackWARs="true" autoDeploy="true"
xmlValidation="false" xmlNamespaceAware="false">
<Context path="" docBase="/Users/sagit/Desktop/www/demo" />
</Host>
可以考虑将数据源配置到tomcat的server.xml
里面,但是我更推荐下面这种:
在web程序的web.xml
里面添加:
<resource-ref>
<res-ref-name>jdbc/shop</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
然后将context.xml
复制为$CATALINA_BASE/conf/[enginename]/[hostname]/context.xml.default
具体原因查看官方文档
When autoDeploy or deployOnStartup operations are performed by a Host, the name and context path of the web application are derived from the name(s) of the file(s) that define(s) the web application. Consequently, the context path may not be defined in a META-INF/context.xml embedded in the application and there is a close relationship between the context name, context path, context version and the base file name (the name minus any .war or .xml extension) of the file.
If no version is specified then the context name is always the same as the context path. If the context path is the empty string then the base name will be ROOT (always in upper case) otherwise the base name will be the context path with the leading '/' removed and any remaining '/' characters replaced with '#'.
If a version is specified then the context path remains unchanged and both the context name and the base name have the string '##' appended to them followed by the version identifier. Some examples of these naming conventions are given below.
一些网友的解决方案
apachectl -help # 查看apachectl的命令参数
apachectl -V # 查看编译时的设置
查看Httpd_ROOT目录,就可以得出模块目录和配置的目录,同时配合一些语法检查命令
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 220.250.64.26. Set the 'ServerName' directive globally to suppress this message
在httpd.conf
文件中添加ServerName localhost:80
配置php
使用httpd -t -D DUMP_INCLUDES
看了下,没有加载php的模块,于是在模块配置文件/etc/httpd/conf.modules.d/15-php.conf
里面取消了注释
LoadModule php7_module modules/libphp7-zts.so
配置文件写成这样就可以了,最好在php-fpm中监听9000端口
AddType application/x-httpd-php .php
<VirtualHost *:5200>
DocumentRoot /var/www/test
ServerName cloud.ourfor.top
<Directory "/var/www/test">
Options FollowSymLinks
AllowOverride None
Order allow,deny
Require all granted
Allow from all
</Directory>
<IfModule proxy_module>
ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/var/www/test/$1
</IfModule>
ErrorLog "/var/log/httpd/cloud.ourfor.top.log"
</VirtualHost>
上面的匹配规则说明,当匹配到php后缀的文件时交给php处理
/var/www/test/index.php
内容如下
<?php
phpinfo()
?>
没有申请证书之前使用https
会报ssl错误,访问不了页面的
申请ssl证书
教程来自Let's Encrypt官网,我的是Fedora 30 + Apache
,详见
sudo dnf install certbot certbot-apache -y
安装好以后,确保apache以及监听了80
端口,配置文件里面就绑定虚拟主机域名,接下来执行:
sudo certbot --apache
上面这条命令,会让我们输入一些东西,输入完后还会帮我们配置文件,非常好,但是如果你不希望它帮我们配置文件,只是想得到证书文件,你执行下面这条命令好了:
sudo certbot certonly --apache
接下来,你就可以打开浏览器访问网站了。
每次申请的证书有效期是90天,过期了就需要重新申请,官方想的也很周到,提供了自动申请证书的命令,这里用到了cron的定时函数,还用到了python,你自己😏安装python吧。
echo "0 0,12 * * * root python -c 'import random; import time; time.sleep(random.random() * 3600)' && certbot renew" | sudo tee -a /etc/crontab > /dev/null
配置Cockpit
按照官方教程来就行了.
首先编辑配置文件: vhost-ip.conf
<VirtualHost *:80>
ServerName ip.ourfor.top
ProxyPreserveHost On
ProxyRequests Off
# allow for upgrading to websockets
RewriteEngine On
RewriteCond %{HTTP:Upgrade} =websocket [NC]
RewriteRule /(.*) ws://127.0.0.1:9090/$1 [P,L]
RewriteCond %{HTTP:Upgrade} !=websocket [NC]
RewriteRule /(.*) http://127.0.0.1:9090/$1 [P,L]
# Proxy to your local cockpit instance
ProxyPass / http://127.0.0.1:9090/
ProxyPassReverse / http://127.0.0.1:9090/
</VirtualHost>
然后执行 certbot
就行了
登录后出现白屏:
Apache启用FORM-base验证
在配置文件中加入SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
, 一些webdav
的服务采用的就是FORM-base
的验证类型,比如Filerun
等
配置单页应用路由
<VirtualHost *:80>
DocumentRoot "/var/www/blog"
ServerName blog.ourfor.top
<Directory "/var/www/blog">
Options FollowSymLinks
AllowOverride none
Order allow,deny
Require all granted
Allow from all
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^ index.html [L]
</IfModule>
</Directory>
ErrorLog "/var/log/httpd/blog.ourfor.top"
</VirtualHost>
使用ajp
连接tomcat和apache
应用场景一:
开发多个api程序,希望使用一个证书,用不同目录表示应用blog
、shop
、game
<VirtualHost *:80>
ServerName api.ourfor.sh
Header set Access-Control-Allow-Origin *
<IfModule proxy_module>
ProxyRequests Off
ProxyPreserveHost On
RewriteEngine on
ProxyPass / ajp://localhost:8009/
ProxyPassReverse / ajp://localhost:8009/
</IfModule>
ErrorLog "/var/log/httpd/api.ourfor.sh.log"
</VirtualHost>
这样可以通过api.ourfor.sh/blog
、api.ourfor.sh/game
来访问不同的api,只需要一个ssl证书
有时有个别需要,比如同样部署在Tomcat下面,但是希望通过shop.ourfor.sh来访问shop
里面的内容,这种需要,我建议你还是用jk连接器吧
出现AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using fe80::6338:b179:ba7e:cb0. Set the 'ServerName' directive globally to suppress this message Syntax OK
这样的警告⚠️,一般在httpd.conf
里面添加一个ServerName
,比如ServerName localhost
权限问题,大部分是有selinux
引起的,但是我又不希望把它关掉,一些参考的资料. Apache Wiki
配置mod_jk出现:
[Wed Nov 06 13:08:01.749356 2019] [core:notice] [pid 8395:tid 140500041136384] SELinux policy enabled; httpd running as context system_u:system_r:httpd_t:s0
[Wed Nov 06 13:08:01.750240 2019] [suexec:notice] [pid 8395:tid 140500041136384] AH01232: suEXEC mechanism enabled (wrapper: /usr/sbin/suexec)
[Wed Nov 06 13:08:01.750251 2019] [ssl:warn] [pid 8395:tid 140500041136384] AH01882: Init: this version of mod_ssl was compiled against a newer library (OpenSSL 1.1.1c FIPS 28 May 2019, version currently loaded is OpenSSL 1.1.1 FIPS 11 Sep 2018) - may result in undefined or erroneous behavior
[Wed Nov 06 13:08:01.751967 2019] [jk:emerg] [pid 8395:tid 140500041136384] Initializing shm:/var/log/httpd/mod_jk.shm.8395 errno=13. Unable to start due to shared memory failure.
[Wed Nov 06 13:08:01.751976 2019] [jk:emerg] [pid 8395:tid 140500041136384] Initializing shm:/var/log/httpd/mod_jk.shm.8395 errno=13. Unable to start due to shared memory failure.
查看mod_jk权限
➜ modules ls -lZ mod_jk.so
-rwxr-xr-x. 1 root root system_u:object_r:httpd_modules_t:s0 1839160 11月 6 10:33 mod_jk.so
查看哪些位置有写入权限:
semanage fcontext -l | grep httpd_modules_t
也就是需要执行下面的两条命令:
grep httpd /var/log/audit/audit.log | audit2allow -M mypol
semodule -i mypol.pp
➜ grep httpd /var/log/audit/audit.log | audit2allow -M mypol
******************** 重要 ***********************
要激活这个策略包,执行
semodule -i mypol.pp
➜ semodule -i mypol.pp
CentOS7 中安装certbot是显示urllib3安装失败。
python-urllib3-1.10.2-7.el7.noarch.rpm | 103 kB 00:00:00
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
正在安装 : python-urllib3-1.10.2-7.el7.noarch 1/1
Error unpacking rpm package python-urllib3-1.10.2-7.el7.noarch
error: unpacking of archive failed on file /usr/lib/python2.7/site-packages/urllib3/packages/ssl_match_hostname: cpio: rename
验证中 : python-urllib3-1.10.2-7.el7.noarch 1/1
失败:
python-urllib3.noarch 0:1.10.2-7.el7
完毕!
解决办法: 卸载自带的urllib3
pip uninstall urllib3
启动我构建的tomcat镜像
docker run --privileged --name tomcat -d \
-v /sys/fs/cgroup:/sys/fs/cgroup:ro \
-v $PWD:/root:rw \
-h docker.server -p 4040:8080 \
-p 8009:8009 \
-t ourfor/tomcat
podman
podman run --privileged --name tomcat -d \
-v /sys/fs/cgroup:/sys/fs/cgroup:ro \
-v /var/lib/tomcat/webapps:/var/lib/tomcat/webapps:Z \
-p 8009:8009 -p 8080:8080 \
-t ourfor/tomcat:latest
websocket配置:
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:8080/
ProxyPassReverse / http://127.0.0.1:8080/
ProxyRequests Off
RewriteEngine on
RewriteCond %{HTTP:Upgrade} =websocket [NC]
RewriteRule /(.*) ws://127.0.0.1:8080/$1 [P,L]
RewriteCond %{HTTP:Upgrade} !=websocket [NC]
RewriteRule /(.*) http://127.0.0.1:8080/$1 [P,L]
ProxyPassReverse / http://127.0.0.1:8080/
Apache官网
为什么更换为Apache的服务端软件?
主要想要做到以下几点:
https
代理
设置比较方便,配置文件比较好设置目录浏览
这个我打算自己写一个好的