使用nginx提供https端点,实现不修改浏览器地址(不触发重定向)转发网络流量,附生成自签ssl证书最简单的方法(2个命令)

近日笔者需要实现一个网络流量转发的需求。要求很简单:将浏览器的请求转发到一个指定的域名,需要提供一个https端口并且把http端口转发到https端口。由于笔者对nginx的认知有限,因此磕磕绊绊研究了一阵,将结果写出来,以供其他有类似需求的同学参考对照。

1. 使用docker拉起nginx服务

nginx的官方docker在这里。拉起nginx就一个命令:

sudo docker run -d -v /home/linmao/nginx/nginx.conf:/etc/nginx/nginx.conf -v /home/linmao/nginx/cert:/cert/ -p 8000:80 -p 4443:443 nginx

这里解释一下几个参数:

参数 说明
-v /home/linmao/nginx/nginx.conf:/etc/nginx/nginx.conf nginx 的配置文件
-v /home/linmao/nginx/cert:/cert/ 适配https端的密钥
-p 8000:80 把本机的8000端口映射到nginx的http端口80
-p 4443:443 把本机的4443端口映射到nginx的https端443

2. nginx配置文件

nginx.conf

work_processes 1;

events {
    worker_connections 64;
}

http {
	# 提供一个http端口
    server {
    	# 监听80端口
        listen 80;
        # 重定向到https端口,这个操作会引起浏览器地址变成localhost,
        # 但因为我们后边提供了https端口,因此并不会引起浏览器真的去请求localhost。
        rewrite ^(.*) https://localhost$1 permanent;
    }
	# 提供一个https端口
    server {
    	# 监听443端口,注意后边要加ssl
        listen 443 ssl;
		# 设置https所需的密钥
        ssl_certificate /cert/self_cert.pem;
        ssl_certificate_key /cert/self_cert_key.pem;
		# 设置一个后端,可根据uri匹配不同的后端
		# uri匹配规则 ~ /(.*)$
		# 	~: 以正则表达式进行匹配。
		#	^/(.*)$: 匹配的正则表达式,匹配uri中的/xxxxxx。uri中后边这一段xxxxx可以通过$1获取。
	    location ~ ^/(.*)$ {
	    	# 把流量转发到https://www.baidu.com/xxxxx。
	        proxy_pass https://www.baidu.com/$1;
	        # 后边这些配置可避免触发重定向,全都要写。
	        proxy_redirect off;
	        # 使用proxy_set_header可以修改请求头,nginx提供一些变量可以使用。
	        # $scheme:客户端请求nginx时使用的协议,可为http或https。
	        # $host: 客户端请求nginx时使用的ip地址或域名,取决于客户端通过ip还是域名发请求给nginx。
	        # $port: 客户端请求nginx时使用的端口。
	        # $http_host: 等同于$host:$port
	        # $proxy_host: 目标服务器,有些上游服务器会检查该头,把Host头改为$proxy_host可以避免触发一些安全机制。
	        proxy_set_header Host $proxy_host;
	        # $remote_addr:客户端ip地址或者上一个nginx的ip地址(如果请求是由nginx转发过来的)。
	        proxy_set_header X-Real-IP $remote_addr;
	        # $proxy_add_x_forwarded_for: 与X-Forwarded-For配合使用,
	        # 相当于把X-Forwarded-For中的内容再加上$remote_addr,形成一个跳转链。
	        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
	    }
	}
}

更多的nginx变量可以参考这里。启动之后就可以愉快地玩耍了。

3. 自签https证书

上边用到了https端点,需要用到ssl证书,到阿里云买一个证书要一年几百块,所以自己签一个,要多少有多少,缺点就是浏览器一看这证书感觉没什么权威性,会让用户先进一个安全警告页面。不过先凑合用着吧。下边的方法是笔者见过的最快生成证书的方法(仅需两个命令)。

首先,生成一个根密钥和csr,根据提示填写相应的信息:

$ openssl req  -newkey rsa:2048 -nodes -keyout self_key.pem  -out self_csr.pem
Generating a RSA private key
................................................+++++
.............................+++++
writing new private key to 'self_key.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:CN
State or Province Name (full name) [Some-State]:Guangdong
Locality Name (eg, city) []:guangzhou
Organization Name (eg, company) [Internet Widgits Pty Ltd]:haha
Organizational Unit Name (eg, section) []:haha
Common Name (e.g. server FQDN or YOUR name) []:haha
Email Address []:[email protected]

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

$ ls
self_csr.pem  self_key.pem

接着给csr签名:

$ openssl x509 -signkey self_key.pem -in self_csr.pem  -req -days 365 -out self_cert.pem
Signature ok
subject=C = CN, ST = Guangdong, L = guangzhou, O = haha, OU = haha, CN = haha, emailAddress = [email protected]
Getting Private key

$ ls
self_cert.pem  self_csr.pem  self_key.pem

根密钥就是self_key.pem,证书就是self_cert.pem,这两个要映射到nginx容器里给https端口使用,那个self_csr.pem可以扔了。

999. Nginx踩坑记录

下边记录笔者爬出来的坑。

  1. 关闭nginx容器之后,再次启动,原来宿主机映射的端口失效的问题解决
  2. 。。。

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