Nginx-正向代理HTTPS

文章目录

  • 前言
  • 1. Nginx简介
  • 2. Nginx安装
    • 2.1 需求
    • 2.2 实验环境
    • 2.3 搭建环境
      • 安装nginx和所需的模块
    • 2.4 配置文件
    • 2.5 防火墙配置
  • 3. 客户端(被代理主机)配置
  • 4. 结果测试
  • 5. 坑点
    • 5.1 配置文件问题
    • 5.2 使用systemctl启动

前言

       最近要帮同学弄一个正向代理环境,需要将内网80、443端口的流量转发出去,在解决的途中遇到了很多问题,有很多的坑。想起以前学习Nginx感觉没这么难,现在感觉以前的很多东西都没学深。
       在自己的印象中Nginx可以用来作web服务器,但只能处理静态页面,支持CGI协议的动态语言。可作为代理服务器,如果面向的对象是客户端那么它应该是一个反向代理,如果是面对的是服务器那么它应该是一个正向代理。以及和keepalived组建高可用的环境。

1. Nginx简介

       Nginx是异步框架的网页服务器、正向代理、反向代理、负载均衡和动静分离服务器。是开源软件,其实大部分使用nginx的机器主要是作为负载均衡服务,nginx在官方测试的结果中能够支持五万个并发,当然在实际环境中估计也就三万左右。
       更多内容请访问<维基百科>

2. Nginx安装

2.1 需求

       本文主要是基于nginx的正向代理,在A搭建代理服务器,让内网主机B能利用A的代理(HTTP)S出网。

2.2 实验环境

CentOS 8 两台
nginx-1.18.0
nginx安装包获取:http://nginx.org/download/
访问链接可根据需求下载需要的版本
实验拓扑如下:
Nginx-正向代理HTTPS_第1张图片

2.3 搭建环境

安装nginx和所需的模块

       由于本人需要代理https的流量,需要使用一个模块用于隧道SSL请求。正常的安装流程和模块地址
相关版本对应表:
Nginx-正向代理HTTPS_第2张图片
       安装步骤

$ wget http://nginx.org/download/nginx-1.18.0.tar.gz
$ tar -xzvf nginx-1.18.0.tar.gz
$ cd nginx-1.18.0
$  patch -p1 < /root/ngx_http_proxy_connect_module/patch/proxy_connect_rewrite_1018.patch
$ ./configure  \
--user=www \
--group=www \
--prefix=/usr/local/nginx \
--with-http_ssl_module \
--with-http_stub_status_module \
--with-threads \
--add-module=/root/ngx_http_proxy_connect_module
$ make && make install # 编译安装

       验证安装结果

$ /usr/local/nginx/sbin/nginx -V

Nginx-正向代理HTTPS_第3张图片

2.4 配置文件

       至于详细的配置文件解读除了查看官方文档外还可以查看【冯insist】的博客,该文全面而详细的讲解了nginx。

user  www www;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
     
    worker_connections  1024;
}


http {
     
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

    server {
     
        listen       8080;
        resolver     114.114.114.114;
        #server_name  192.168.204.146;
        location / {
     
            #root   html;
            #index  index.html index.htm;
            proxy_pass http://$http_host$request_uri;
            proxy_set_header HOST $http_host;
            proxy_buffers 256 4k;
            proxy_max_temp_file_size 0k; 
            proxy_connect_timeout 30;
            proxy_send_timeout 60;
            proxy_read_timeout 60;
            proxy_next_upstream error timeout invalid_header http_502;
        }
	}	
		
    server {
     
         listen     8443;

         # dns resolver used by forward proxying
         resolver  114.114.114.114;
         # forward proxy for CONNECT request
         proxy_connect;
         proxy_connect_allow            443 563;
         proxy_connect_connect_timeout  10s;
         proxy_connect_read_timeout     10s;
         proxy_connect_send_timeout     10s;
         # forward proxy for non-CONNECT request
         location / {
     
             proxy_pass http://$host;    
             proxy_set_header Host $host;
         }
    }
}

       配置文件修改完毕重启nginx服务。

2.5 防火墙配置

       需要开启http/https相关端口,使用以下命令查看开放的端口

firewall-cmd --list-ports

       开启端口

firewall-cmd --permanent --add-port=8080/tcp
firewall-cmd --permanent --add-port=8443/tcp
firewall-cmd --reload # !!!修改配置后要重启防火墙

3. 客户端(被代理主机)配置

       本次实验代理服务器采用两张网卡充当网关设备,其中内网IP为(192.168.54.4)

export http_proxy=192.168.54.4:8080 # 需要代理的http访问地址
export https_proxy=192.168.54.4:8443 # 需要代理的https访问地址

export no_proxy=192.168.54.4,域名 # 访问地址时不需要进行代理的是哪些

4. 结果测试

       7层需要通过HTTP CONNECT来建立隧道,属于客户端有感知的普通代理方式,需要在客户端手动配置(HTTP)S代理端IP和端口,在客户端进行测试结果如下:
HTTP

[root@localhost ~]# curl http://baidu.com -svo /dev/null -x 192.168.54.4:8080
* Rebuilt URL to: http://baidu.com/
*   Trying 192.168.54.4...
* TCP_NODELAY set
* Connected to 192.168.54.4 (192.168.54.4) port 8080 (#0)
> GET http://baidu.com/ HTTP/1.1
> Host: baidu.com
> User-Agent: curl/7.61.1
> Accept: */*
> Proxy-Connection: Keep-Alive
> 
< HTTP/1.1 200 OK
< Server: nginx/1.18.0
< Date: Fri, 08 Jan 2021 07:26:01 GMT
< Content-Type: text/html
< Content-Length: 81
< Connection: keep-alive
< Last-Modified: Tue, 12 Jan 2010 13:48:00 GMT
< ETag: "51-47cf7e6ee8400"
< Accept-Ranges: bytes
< Cache-Control: max-age=86400
< Expires: Sat, 09 Jan 2021 07:26:01 GMT
< 
{ [81 bytes data]
* Connection #0 to host 192.168.54.4 left intact

HTTPS

[root@localhost ~]# curl https://baidu.com -svo /dev/null -x 192.168.54.4:8443
* Rebuilt URL to: https://baidu.com/
*   Trying 192.168.54.4...
* TCP_NODELAY set
* Connected to 192.168.54.4 (192.168.54.4) port 8443 (#0)
* allocate connect buffer!
* Establish HTTP proxy tunnel to baidu.com:443
> CONNECT baidu.com:443 HTTP/1.1
> Host: baidu.com:443
> User-Agent: curl/7.61.1
> Proxy-Connection: Keep-Alive
> 
< HTTP/1.1 200 Connection Established
< Proxy-agent: nginx
< 
* Proxy replied 200 to CONNECT request
* CONNECT phase completed!
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
} [5 bytes data]
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
} [512 bytes data]
* CONNECT phase completed!
* CONNECT phase completed!
{
      [5 bytes data]
* TLSv1.3 (IN), TLS handshake, Server hello (2):
{
      [104 bytes data]
* TLSv1.2 (IN), TLS handshake, Certificate (11):
{
      [3023 bytes data]
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
{
      [333 bytes data]
* TLSv1.2 (IN), TLS handshake, Server finished (14):
{
      [4 bytes data]
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
} [70 bytes data]
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
} [1 bytes data]
* TLSv1.2 (OUT), TLS handshake, Finished (20):
} [16 bytes data]
* TLSv1.2 (IN), TLS handshake, Finished (20):
{
      [16 bytes data]
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* ALPN, server accepted to use http/1.1
* Server certificate:
*  subject: C=CN; ST=Beijing; O=BeiJing Baidu Netcom Science Technology Co., Ltd; OU=service operation department; CN=www.baidu.cn
*  start date: Feb 27 00:00:00 2020 GMT
*  expire date: Feb 26 12:00:00 2021 GMT
*  subjectAltName: host "baidu.com" matched cert's "baidu.com"
*  issuer: C=US; O=DigiCert Inc; CN=DigiCert SHA2 Secure Server CA
*  SSL certificate verify ok.
} [5 bytes data]
> GET / HTTP/1.1
> Host: baidu.com
> User-Agent: curl/7.61.1
> Accept: */*
> 
{ [5 bytes data]
< HTTP/1.1 302 Moved Temporarily
< Server: bfe/1.0.8.18
< Date: Fri, 08 Jan 2021 07:31:48 GMT
< Content-Type: text/html
< Content-Length: 161
< Connection: keep-alive
< Location: http://www.baidu.com/
< 
{ [161 bytes data]
* Connection #0 to host 192.168.54.4 left intact

       通过上面的详细情况可以了解客户端和代理服务器建立HTTP CONNECT隧道的详细情况,代理服务器回复HTTP/1.1 200 Connection Established后就开始交互TLS/SSL握手和流量交互。

5. 坑点

       在使用源码安装nginx后使用systemctl start控制nginx启动问题

5.1 配置文件问题

       在nginx安装完成后,会根据需求对配置文件进行配置,往往对于新手或者不熟悉nginx的人来说,可能会输入错误和忘记一些特殊符号造成语法错误,在这个时候需要检查配置文件是否存在语法错误,使用命令来检查配置文件。测试通过截图如下:
在这里插入图片描述

5.2 使用systemctl启动

       在使用源码安装后,会新建/etc/init.d/nginx文件来设置开机自启,当使用systemctl start nginx来控制启动nginx服务时,无法启动使用journalctl -ex查看,出现下图所示的告警:
Nginx-正向代理HTTPS_第4张图片
       解决方法,进入 /lib/systemd/system该目录下新建nginx.service文件,在文件内添加内容如下:

[Unit]
Description=nginx
After=network.target
 
[Service]
Type=forking
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/usr/local/nginx/sbin/nginx -s reload
ExecStop=/usr/local/nginx/sbin/nginx -s quit
PrivateTmp=true
 
[Install]
WantedBy=multi-user.target

参考连接:https://blog.csdn.net/u012463871/article/details/90573545
参考连接:https://www.cnblogs.com/stulzq/p/9291223.html?spm=a2c4e.10696291.0.0.12e019a4a0Ldkl

你可能感兴趣的:(Nginx,nginx)