ourfor / blog

利用GitHub的Issues记录
https://github.com/ourfor/blog/issues
1 stars 0 forks source link

开始使用Apache的web服务器了 #25

Open ourfor opened 5 years ago

ourfor commented 5 years ago

Apache官网

为什么更换为Apache的服务端软件?

主要原因有以下几点:

主要想要做到以下几点:

ourfor commented 5 years ago

由于刚接触很久没有接触Apache,我打算在虚拟机上面熟悉以后再搬到生产环境上面去。接下来的笔记将会从以下几个方面来记录:

ourfor commented 5 years ago

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>
ourfor commented 5 years ago

如果页面提示禁止没有权限,那么不要忘了<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)

ourfor commented 5 years ago

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

ourfor commented 5 years ago

apache httpd服务器连接tomcat

演示系统环境macOS Majave 10.14.4

httpd的配置文件中添加一个名为httpd-jk.conf(名字可以随便取),同时在httpd.conf里面导入这个配置文件:

# Virtual hosts
Include /usr/local/etc/httpd/extra/httpd-vhosts.conf

顺便把User改成你的登录用户名,原本为_www

User sagit
Group _www

这样的话网站更目录就不需要放在默认的位置了

https://github.com/ourfor/Blog/blob/d8b3eb027971e15ce854055dc1348de2367009be/tomcat/mod_jk/httpd-jk.conf#L22-L123

主要注意下面几个位置

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里面导入额外的配置文件的父路径一致,JkLogFileJkShmFile这两个文件的父路径和httpd.conf里面存放日志文件的父路径一致

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 `处理,以及交给谁处理
ourfor commented 5 years ago

如果需要在一个服务器上面部署配置多个tomcat的webapp的话,只需要在httpd-vhosts.confserver.xml里面添加就可以了.

server.xml

https://github.com/ourfor/Blog/blob/e1a974fe623816814c20f87acdd51aefa0234494/tomcat/mod_jk/server.xml#L128-L140

httpd-vhosts.conf

https://github.com/ourfor/Blog/blob/e1a974fe623816814c20f87acdd51aefa0234494/tomcat/mod_jk/httpd-vhosts.conf#L37-L61

ourfor commented 5 years ago

如果使用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>
ourfor commented 5 years ago

通过jk连接器,web应用程序的数据源找不到

可以考虑将数据源配置到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.

一些网友的解决方案

ourfor commented 5 years ago

Apache常见命令

apachectl -help  # 查看apachectl的命令参数
apachectl -V # 查看编译时的设置
查看Httpd_ROOT目录,就可以得出模块目录和配置的目录,同时配合一些语法检查命令
ourfor commented 5 years ago

httpd.conf文件中添加ServerName localhost:80

ourfor commented 5 years ago

配置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错误,访问不了页面的

ourfor commented 5 years ago

申请ssl证书

教程来自Let's Encrypt官网,我的是Fedora 30 + Apache详见

安装好以后,确保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
ourfor commented 5 years ago

配置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就行了

登录后出现白屏:

ourfor commented 5 years ago

Apache启用FORM-base验证

在配置文件中加入SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1, 一些webdav的服务采用的就是FORM-base的验证类型,比如Filerun

ourfor commented 4 years ago

配置单页应用路由

<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>
ourfor commented 4 years ago

使用ajp连接tomcat和apache

应用场景一: 开发多个api程序,希望使用一个证书,用不同目录表示应用blogshopgame


<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/blogapi.ourfor.sh/game来访问不同的api,只需要一个ssl证书

ourfor commented 4 years ago

有时有个别需要,比如同样部署在Tomcat下面,但是希望通过shop.ourfor.sh来访问shop里面的内容,这种需要,我建议你还是用jk连接器吧

ourfor commented 4 years ago

出现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

ourfor commented 4 years ago

权限问题,大部分是有selinux引起的,但是我又不希望把它关掉,一些参考的资料. Apache Wiki

ourfor commented 4 years ago

配置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
ourfor commented 4 years ago

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
ourfor commented 4 years ago

启动我构建的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
ourfor commented 4 years ago

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/