默认地,Apache使用80端口,而Nginx也是使用80端口。为减少防火墙开放端口,同时也便于用户识别和输入,通常只开放默认80端口。所以,可以通过Nginx来反向代理Apache。但是,在修改Apache端口时却有些坑。
Apache/httpd端口修改
1. 修改/etc/httpd/conf/httpd.conf 文件
#把默认80改为你设置的端口,我设置端口为8080
Listen 8080
2.重新加载配置文件
service httpd reload
此时,却发现Apache无法正常启用。搜索了下,原来是 SELinux 安全机制的作用,对于非标准端口有限制。网上也有很多解决方案。
方案1:临时解决方案
参考文章:centos6.5查看SELinux状态及关闭 -- https://blog.csdn.net/weixin_43976137/article/details/100633062
1. 查看SELinux 状态
[dotnba@centos8 selinux]$ sestatus
SELinux status: enabled
SELinuxfs mount: /sys/fs/selinux
SELinux root directory: /etc/selinux
Loaded policy name: targeted
Current mode: enforcing
Mode from config file: permissive
Policy MLS status: enabled
Policy deny_unknown status: allowed
Memory protection checking: actual (secure)
Max kernel policy version: 31
或者
[dotnba@centos8 nginx]$ getenforce
Enforcing
2.关闭SELinux
[dotnba@centos8 nginx]$ sudo setenforce 0
3.查看SELinux 状态
[dotnba@centos8 nginx]$ getenforce
Permissive
4.重启httpd
[dotnba@centos8 nginx]$ service httpd restart
Redirecting to /bin/systemctl restart httpd.service
[dotnba@centos8 nginx]$ service httpd status
Redirecting to /bin/systemctl status httpd.service
● httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
Active: active (running) since Sun 2020-02-02 17:26:44 CST; 6s ago
Docs: man:httpd.service(8)
Main PID: 8559 (httpd)
Status: "Started, listening on: port 443, port 8080"
Tasks: 214 (limit: 23832)
Memory: 27.6M
CGroup: /system.slice/httpd.service
├─8559 /usr/sbin/httpd -DFOREGROUND
├─8566 /usr/sbin/httpd -DFOREGROUND
├─8567 /usr/sbin/httpd -DFOREGROUND
├─8568 /usr/sbin/httpd -DFOREGROUND
├─8569 /usr/sbin/httpd -DFOREGROUND
└─8570 /usr/sbin/httpd -DFOREGROUND
2月 02 17:26:44 centos8 systemd[1]: Stopped The Apache HTTP Server.
2月 02 17:26:44 centos8 systemd[1]: Starting The Apache HTTP Server...
2月 02 17:26:44 centos8 httpd[8559]: AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using fe80::3ab8:1773:479e:e212. Set the 'ServerName' directive >
2月 02 17:26:44 centos8 systemd[1]: Started The Apache HTTP Server.
2月 02 17:26:44 centos8 httpd[8559]: Server configured, listening on: port 443, port 8080
方案2:修改配置文件
方案1的问题是重启后,设置就无效了。如果需要重启有效,那么就需要修改配置文件:/etc/selinux/config 。
将SELINUX=enforcing改为SELINUX=disabled或者SELINUX=permissive。config文件内容如下:
# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
# enforcing - SELinux security policy is enforced.
# permissive - SELinux prints warnings instead of enforcing.
# disabled - No SELinux policy is loaded.
SELINUX=permissive
# SELINUXTYPE= can take one of these three values:
# targeted - Targeted processes are protected,
# minimum - Modification of targeted policy. Only selected processes are protected.
# mls - Multi Level Security protection.
SELINUXTYPE=targeted
通常,网上的方案是这样。但是,既然SELinux 有其安全作用,那么是不是可以不轻易关闭这一机制,而是为其增加相应的端口呢?
方案3:增加SELinux 中的http端口
参考文章:Selinux下httpd端口的设置 -- https://blog.csdn.net/weixin_44783160/article/details/99699289
1. 增加端口
[dotnba@centos8 nginx]$ sudo semanage port -a -t http_port_t -p tcp 8080
[sudo] dotnba 的密码:
ValueError: 已定义端口 tcp/8080
2.查看端口
[dotnba@centos8 nginx]$ sudo semanage port -l | grep http
http_cache_port_t tcp 8080, 8118, 8123, 10001-10010
http_cache_port_t udp 3130
http_port_t tcp 80, 81, 443, 488, 8008, 8009, 8443, 9000
pegasus_http_port_t tcp 5988
pegasus_https_port_t tcp 5989
此时,重启httpd正常。但是,坑也就来了,此前正常工作的Nginx不能访问了。因为对Linux也不熟,折腾了很长时间,甚至把Nginx卸载了重装,Nginx本身运行正常。后来,想到查看下Nginx的日志,发现 /var/log/nginx/error.log 有如下记录:
2020/02/01 20:54:42 [crit] 7854#0: *14 connect() to [::1]:8080 failed (13: Permission denied) while connecting to upstream, client: 127.0.0.1, server: _, request: "GET / HTTP/1.1", upstream: "http://[::1]:8080/", host: "localhost"
解决 Permission denied
参考文章:解决Nginx的connect() to 127.0.0.1:8080 failed (13: Permission denied) while connect -- https://blog.csdn.net/oydaybreak/article/details/46594639
需要执行下面的命令:
setsebool -P httpd_can_network_connect 1
至此,相关问题基本都已经解决。但是,至于为何Apache/httpd端口修改成功,服务正常,Nginx服务也正常的情况下,为何不能反向代理,需要执行setsebool 的具体原因我就不清楚了。不过,查看 setsebool 的帮助可以知道也是SELinux相关的。setsebool 文档参考:https://ipcmen.com/setsebool