Nginx的四层转发实现多应用共用端口

前面因为wordpress的迁移写了两篇文章,想不到这是与之有关的第三篇文章了,一件事重复三遍,自己都觉得显得有点多余,但有些过程记录下来,也许对碰到类似问题的人有所帮助。

仅仅是一个web应用,自然不存在外部访问的端口问题,但如果是多个web应用或者还有其它应用呢?一个端口只能一个应用进行监听,如果用域名加端口方式,不存在问题,但网络上访问域名后拖个端口是不是显得不怎么高大上,最好是都用默认端口,这里就有共用端口问题。

仅仅是普通的共用端口也没有太大问题,用代理服务器,一般的http或https应用都能得到转发,用代理服务器的虚拟主机可以多个转发共同监听一个443端口,但如果某个应用必须工作在443端口呢,那么代理服务器就不能再用同一个端口。

本人想在一个服务器上布置多个应用,又想共用一个默认端口,碰到这个问题后在网络上找了一圈,直接的资料较少,只能多学习一下有关代理服务器的知识,从大量关于Nginx的四层负载均衡的讨论中得到启发。

Nginx的代理转发有四层和七层之分,七层是应用层的转发,这是一般常用代理模式,而四层转发则工作在网络的TCP层,利用IP和端口来转发客户端的请求,直接进行TCP数据包的转发,与一般的具体应用协议无关,这样有可能利用Nginx来转发各类的应用到同一个端口,从而满足各个应用对默认端口的要求。

1、Nginx加装stream、 stream_ssl_preread模块

Nginx 的四层转发需要利用 stream 模块来实现,较早版本的 Nginx 并不是默认同步安装该模块。

nginx -V 命令可以查看系统中是否已经带有该组件,出现以下–with-stream等文字,说明已经安装。ubbuntu20.04在安装nginx时会自动加入以上模块。

如果没有该模块,需要进行编译安装,网络上有详细教程。

2、配置nginx.conf文件

user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
events {
	worker_connections 1024;
}
stream {  
  map $ssl_preread_server_name $backend_name { 
    aa.cc.com web1; 
    bb.cc.com web2;
  } 
  upstream web1 { 
    server 127.0.0.1:20000; 
  } 
  upstream web2 { 
    server 127.0.0.1:20001;
  } 
  server { 
    listen 443 reuseport; 
    listen [::]:443 reuseport; 
    proxy_pass $backend_name; 
    ssl_preread on; 
  }
}
http {
........

http部分可以保持默认,一般nignx.conf文件只有头部和http两部分,这里需要增加一个stream部分。

3、配置conf.d中的反向代理

新建web1.conf文件

server
{
    listen 20000 ssl;
    server_name aa.cc.com;
    index index.php index.html index.htm default.php default.htm default.html;
    root /var/www/html1;
    ssl_certificate    /etc/ssl/private/aa.cc.com.cer;
    ssl_certificate_key   /etc/ssl/private/aa.cc.com.key;
    ssl_protocols TLSv1.1 TLSv1.2;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;
  
location / {
             proxy_set_header X-Real-IP $remote_addr;
             proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;
             proxy_set_header Host $host;
             proxy_pass http://aa.cc.com:8080;
             proxy_redirect off;

      }
}

4、几点讨论

4.1 以上配置说明,真实的web服务在本地服务器的8080端口,而nginx的反向代理在20000端口进行监听, nginx的四层转发在443端口进行监听。所有的请求从443进入,利用SNI的区别被直接从四层转发到nginx的代理服务器上不同的监听端口,代理服务器再根据对应的IP和端口转发到真实的后端服务器上。

4.2 这里利用四层转发解决共用端口问题,同时利于nginx的反向代理隔离后端服务器,有利用增强安全性。如果不代理,因为四层转发,后端服务器将直接面对客户端的请求,在大型项目上不利于系统的稳定可靠。

4.3 经过多重转发和代理,后端服务正确获得客户端的真实IP是一个问题,网络上有很多的相关讨论,但基本上经以上配置系统能够正常运行。

WordPress的迁移和反向代理

上一篇文章比较系统地讲了如何将wordpress迁移到apache环境下,特别提到apache能较好地完成web服务器任务,后来想到想在服务器上部署多个服务,并共用443端口,这种环境下较好的解决方案是安装Nginx来做反向代理。

一般web服务的反向代理配置较为简单,但wordpress在设计上有大量的动态代码,同时对内部数据的保护机制,使得它不能直接原位进行反向代理,直接反向代理将不能正确解释文件的链接,也不能正确渲染网站的样式。

所以再写一篇补充文章,简单谈谈wordpress手动迁移到apache的web服务器中,并用Nginx进行反向代理。

一、基础环境的搭建

包括操作系统、apache服务器、sql数据库、Nginx服务器等的安装调试,已在前面文章中有交待,可以参考。

另外需要准备域名和证书。

二、原始数据的打包上传

1、网站数据的打包上传

1.1 将原网站整个目录打包成压缩文件,wordpress.zip。

1.2 将 wordpress.zip 上传到服务器的 /var/www目录下

1.3 解压数据

unzip wordpress.zip

2、数据库的恢复

2.1 在原数据库中,将wordpress数据库导出为wordpress.sql文件

2.2 在原数据库中 新建mydb数据库,并将 wordpress.sql 文件导入其中

2.3 修改mydb数据库中的数据

2.3.1 将options字段中的siteurl和home的值修改为新使用的域名 https://aa.bb.com

2.3.2 将mydb 数据库中的网站链接全部替换为新的域名

update wp_posts set post_content=replace(post_content,'https://xxxxxx.com','https://aa.bb.com');

2.3.3 将 mydb 数据库 导出为 mydb.sql文件

2.4 将 mydb.sql文件 上传到服务器的 /home目录下

2.5 在服务器中新建wordpress数据库,并将 mydb.sql文件 导入其中

mysql
CREATE DATABASE wordpress DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
use wordpress
source /home/mydb.sql;

三、apache文件修改

1、修改apache2.conf

在其中增加根目录 /var/www/wordpress

2、修改ports.conf

在其中增加侦听端口 LISTEN 12356

3、修改sites-available目录中000-default.conf文件

在其中增加虚拟主机

4、重启apache2

systemctl restart apache2

四、修改网站设置

1、 修改wp-config.php

在define(‘WP_DEBUG’, false);语句之前,插入一段代码

可以参考附录文件的说明。

2、 修改wp-includes目录中functions.php文件

可以参考附录文件的说明。

五、配置Nginx

1、 创建wordpress反向代理配置文件

server

{

  listen 443 ssl;

    server_name aa.bb.com;

    index index.php index.html index.htm;

    root /var/www/wordpress;

    ssl_certificate    /etc/ssl/private/aa.bb.com.crt;

    ssl_certificate_key   /etc/ssl/private/aa.bb.com.key;

    ssl_protocols TLSv1.1 TLSv1.2;

    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;

    ssl_prefer_server_ciphers on;

location / {

           proxy_pass http://aa.bb.com:123456; 

#以下代码使得web服务正确获得wordpress的链接地址

           proxy_set_header X-Real-IP $remote_addr;

             proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;

             proxy_set_header Host $host;

              proxy_redirect off;

      }

}

2、重启Nginx

systemctl restart nginx

六、浏览器中输入 https://aa.bb.com 验证网站能否正确运行。

上一篇文章是先用apache建好网站,并成功运行,是走一步看一步,这次是直接完成所有配置,一次性以反代方式运行网站。

附录:

1、Nginx反向代理实现Wordpress全站HTTPS TLS 1.3支持

2、Nginx使用Https反代WordPress

WordPress网站的手动迁移

这是我第一次在外部服务器上写文章,前面所有的文章都是在本地服务器完成的,主要是这几天把博客网站转移到了外部,期间的过程觉得非常有必要做个分享,也写几句心得体会。

很早以前就想把博客放到外面去,但一直是拖延症状态,所以就在内网自言自语了很长一段时间,新的一年都开始了,终于下了决心做这件事。网上百度了一番,wordpress的迁移有很多种方法,用专门的插件简单方便,但觉得我也这样做似乎没有乐趣,同时也想搞清网站运行和设置的一些底层原理,决定还是手动进行迁移,由于能借鉴的信息不多,整个过程花费了不少时间,但收获也不少。

几点感受:

1、手动迁移网站涉及的过程比较复杂,也要求多方面的技术,如果没有一些Linux方面的基础,不建议这样做,另外没有太多时间、不想太麻烦的人也不建议这样做,毕竟这个过程还是比较耗时耗力的。当然如果你有折腾的精神,非常值得,能学到不少东西,也是一个成长的经历。

2、任何时候还是要善于学习,网络上还是有许多有意义的教程,当然更要善于自己分析问题,尝试解决问题,由于系统环境不同,同样的问题别人的答案,你未必有用,其中很多问题主要还是要靠自己摸索,所以经验分享出来,也是对学习别人经验的一种回馈吧。

3、wordpress是一个依靠apache和PHP运行的内容管理系统,因此根本不需要另外安装什么面板之类的东西,环境搭建在一般的Linux发行版上几条命令就可以完成,真正有难度的是网络环境配置和wordpress本身数据的更改。

这里主要谈一些系统迁移的基本要求和思路,注意的问题,不详细讲每一条命令。

一、服务器的选择

操作系统环境建议选比较通行的Linux发行版,因为这样发行版有比较好的包管理,一些基本的系统组件,一条命令就能安装好,也能很方便就在网络上搜索到有用的帮助,我选的是Ubuntu。

新的操作系统运行后,首先是更新源,建议安装防火墙,放行80和443端口,主要是考虑安全问题。

系统建设阶段也可直接用root帐户登录,方便一些,网站运行后再用普通用户身份维护。

二、准备域名和证书

域名一般需要购买,也要做好解释,这是建站的基础设施。

证书可以购买,但最好是直接自己申请免费的证书。

以上要求,网络上教程很多,要完全靠自己准备好,没有经验的人也是要花很大精力的。

三、网络基础环境搭建

1、安装Apache2

apt install apache2

安装完成后,apache默认自动启动,通过以下命令查看 apache 运行状态:

systemctl status apache2

输出类似内容,说明已经安装成功并默认运行。

到这里其实就可以依赖apache运行静态的网站了,在浏览器输入 hhtp://ip(域名),将出现apache的示例页面,表示系统安装成功。

2、安装PHP

apt install php

apt install libapache2-mod-php

apt install php-mysql

其中libapache2-mod-php和php-mysql是支持PHP与apache和数据库运行的扩展。

四、数据库环境

wordpress运行时,很多状态和设置信息都需要储存在数据库中,所以系统正常运行还需要配置好数据库环境。

由于是做wordpress的迁移,这里安装的数据库最好与原网站运行的数据库一致,免去不必要的麻烦,我用的是MariaDB。

1、安装数据库

apt install mariadb

可以用systemctl status mysql命令看数据库是否正确安装:

2、 设置数据库帐户密码

MySQL 安装完成后,为安全起见,建议运行 MySQL 的安全配置,设置 root 密码等:

mysql_secure_installation

设置 root 密码,之后一路提示默认输入 y,回车即可。

3、 创建wordpress数据库以及帐户、密码

mysql

CREATE DATABASE aadb DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;

CREATE USER ‘bbuser’@’localhost’ IDENTIFIED BY ‘xxxxxxxx’;

GRANT ALL PRIVILEGES ON *.* TO ‘bbuser’@’localhost’;

使变更生效

FLUSH PRIVILEGES;

这里设置的数据库、用户和密码都在后面wordpress的设置中用到。

五、将原网站文件数据上传到新网站

1、原网站导出数据库

1.1 从原网站导出数据库并保存为本地1234.sql文件

1.2 在原数据库中新建一个数据库,并把上述数据导入

1.3 将1.2新建数据库中的部分字段修改为新网站的链接,并再次导出为5678.sql文件

1.4 将5678.sql文件上传到新网站备用

2、新网站导入数据库

将5678.sql文件导入到新网站的aadb数据库

3、原网站数据打包

将原网站整个主目录用压缩软件压缩为abcd.zip文件,并将abcd.zip文件上传到新网站。

原网站数据一定要进行打包,再在外部服务器解压,因为都是小文件,不打包直接上传可能需要几个小时,而打包再上传可能只要几分钟。

4、新网站主目录解压数据

将abcd.zip文件解压到准备放置新网站的主目录位置,根据apache的文档建议,放置在/var/www目录下比较好,如/var/www/cc 等,如果想放在别的地方也没有问题。

六、设置新网站

原网站数据上传后,数据里面的很多内容还是原有的,并不能在新网站直接使用,比如链接、程序接口等,这些都要进行手工更换。

新网站要运行老网站的内容,新网站的网络门户必须配置好利用原网站的内容,同时原网站中wordpress目录中的基本配置也要修改,使它能正确在新系统环境中运行。

1、wordpress配置数据

进入系统后台,修改主目录下的wp-config.php文件

wordpress启动要连接数据库,以上config文件就配置好了数据库。

2、网络环境配置

涉及修改的文件主要以下几个:

2.1 /etc/apache2/apache2.conf

加入DirectoryIndex index.php index.html语句,因为wordpress直接首页运行php。

加入新网站主目录,并配置好。

2.2 /etc/apache2/mods-available/dir.conf

index.php移动到最前面

2.3 /etc/apache2/sites-available/000-default.conf和/etc/apache2/sites-enlabled/000-default.conf

通过网站环境的配置,就将新网站指向了80端口和自己原数据的主目录

3、验证新网站的运行

浏览器输入 http://域名(ip)将出现wordpress的页面,只是页面上的链接是失效的。

七、为网站使用https连接,并修复链接

到第六步其实已经基本完成网站的迁移,可以在更换链接数据后,从80端口进行访问,但在外网环境这样肯定是不安全的,没有实际意义,所以要为网站设置https访问。

1、修改/etc/apache2/sites-available/default-ssl.conf文件

其中,DirectoryIndex index.php是添加内容,证书位置改为自己上传证书位置

2、 链接上述修改文件到 site-enabled

ln -s /etc/apache2/sites-available/default-ssl.conf /etc/apache2/sites-enabled/000-ssl.conf

只要sites-available/default-ssl.conf做了修改之后sites-enabled/000-ssl.conf也会做相应的修改。

3、 上传证书到指定目录

4、 重启apache2服务

systemctl restart apache2

5、验证https浏览,出现登录页面

6、修复网站中的链接

mysql

use aadb

update wp_posts set post_content=replace(post_content,’http://eeeeee’,’https://fffffff’);

此时进入后台,各项功能应该正常,包括跳转到各个栏目以及进入文章的浏览、修改和写文章。

7、 强制开启SSL连接可以提高网站的安全性

修改/var/www/wordpress/wp-config.php

添加以下文本:

define(‘FORCE_SSL_LOGIN’, true);

define(‘FORCE_SSL_ADMIN’, true);

至此,整个迁移工作就完成了,步骤还是比较多的,很多地方只讲到了原理,细节部分都可以从网络上学习到,这里讲的是整个过程,正确完成需要的是耐心。