HTTPS導致的HTTP協議升級

HTTPS導致的HTTP協議升級

依稀還記得大約兩年前搞過一手Nginx加殼打造https的操作,裏面涉及ws協議自動升級到wss。

如今又遇到https下http的協議自動升級成https的情況,如果頁面是https的,那麼頁面內容中http地址協議會自動升級到https,最容易遇到的,也是我遇到的問題是html頁面上img標籤的src,圖片路徑是http的,但是我們頁面的協議是https,導致這個圖片的協議直接重http升級到https,然後圖片的就訪問不到了。

解決這個問題比較簡單,最容易的方式就是直接把圖片服務器給搞成HTTPS,然後問題就解決了,好了,就寫到這兒吧?

當然,既然來了, 就要扯會兒犢子。

項目中你會遇到對接外部系統吧?那如果這個對象存儲服務是對方的,你沒辦法控制,別個就要用http,那這個時候就得我們自己出手了,其實也很簡單。

我們首先要明白的就是如何把這個http給他換成https就好了,也就是說我們頁面上要通過https去訪問到別人的http的對象服務器拿資源,我想正常有開發經驗的人很直接就能想到走代理,哈哈,如果你看過我那篇<通過Nginx加殼打造https>的文章,我想這個問題對你來講很簡單了。

解決這個問題有很多種方式,我列舉一下我處理過的幾種,都是沒有問題的。

1. nginx,nginx套殼,前端https打到nginx, nginx通過http代理到target
2. 如果是k8s, k8s增加service和自定義的endPoints(這個endPoints指向target), 通過traefik或者其他負載均衡工具直接增加新的https的域名規則,通過service, endPoints打出去
3. 前兩種在target爲域名時不會存在問題,但是如果是多IP的情況,就稍微有點點麻煩,但還是能解決問題。
   3.1 通用型,直接部署代理服務,類似對象存儲的回源操作,內部部署一個https的代理服務,接口入參爲需要代理的圖片地址http://xxx/xx.jpg, 代理服務拉取圖片信息,然後直接返回
   3.2 demo, https://domain.com/proxy?url=http://xxx/xx.jpg,代理服務拿到參數url,訪問並返回內容

第三種方式雖然方便,但是需要多部署一個服務,適當選擇吧,各有優勢,如果對方IP固定,那我認爲第二種是最簡單,最快速的。我們目前也是用的這種方式。如果有自己的域名,那我任務nginx代理最簡單,如果最求通用,那就第三種吧,到哪裏都能用。

第一種加殼代理的我就不解釋了,和之前打造https類似。

K8S Service

這個玩意兒比較簡單,不好演示得,懂的都懂,我貼個配置吧。

比如圖片地址是http://123.123.123.123:8882/xxx/xxx.png

k8s yaml資源文件

kind: Service
metadata:
  name: obj-proxy
  namespace: xxx
  labels:
    k8s-app: obj-proxy
spec:
  type: ClusterIP
  clusterIP: None
  ports:
  - name: port
    port: 3102   ## service的集羣端口
    protocol: TCP
---
apiVersion: v1
kind: Endpoints
metadata:
  name: obj-proxy
  namespace: xxx
  labels:
    k8s-app: obj-proxy
subsets:
- addresses:
  - ip: 123.123.123.123            ## 目標服務地址
    nodeName: 123.123.123.123
  ports:
  - name: port
    port: 8882            ## 目標端口
    protocol: TCP

traefik的規則部分

    - kind: Rule
      match: Host(`www.inner.com`) && PathPrefix(`/`)
      services:
        - name: obj-proxy     ## 指向上面的service
          namespace: xxx      ## service所在的命名空間
          port: 3102          ## service的端口

我們通過內部域名https://www.inner.com打到traefik,traefik根據這個路由規則,打到叫做obj-proxy的service,然後service從它對應的endPoints指定的目標地址(123.123.123.123)打出去,看吧,是不是跟nignx加差不多,只是方式變了而已。

代理鏡像構建

這裏簡單來操作一下第三種方式,代理服務隨便寫,java,go等等都可以,主要邏輯就是拿到圖片的url,然後獲取到圖片流,返回,是不是很簡單?我屬實不想寫這玩意兒了,用個運維老大哥寫的python腳本吧(感謝某某運維老大哥),嘻嘻。

程序代理的python腳本

pyproxy.py

from flask import Flask, abort, Response, request
import os
import requests

app = Flask(__name__)
app.config["DEBUG"]  = False

file_obj = None

def generate(file_obj):
    while True:
        content = file_obj.raw.read(102400)
        if content:
            yield content
        else:
            break

@app.route('/proxy', methods=['GET'])
def download_file():
    try:
        url = request.args.get('url').encode('utf-8')
        print(url)
        filename = os.path.basename(url)
        file_obj = requests.get(url, stream=True)
        headers = file_obj.headers

        s = Response(generate(file_obj), content_type=headers.get('Content-Type'))

        for k, v in headers.items():
            s.headers[k] = v
        s.headers['Content-Disposition'] = "attachment; filename={}".format(filename)
        return s

    except Exception as e:
        if file_obj is not None:
            file_obj.close()
        Response.close()
        abort(404)

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8000)

Dockerfile

FROM  rackspacedot/python37:32
RUN pip3 install requests flask
COPY pyproxy.py /pyproxy.py
CMD ["python3","/pyproxy.py"]

構建運行

[root@master1 pyproxy]# docker build -t pyproxy:v1 .
[root@master1 pyproxy]# docker run -p 8000:8000 pyproxy:v1
 * Serving Flask app 'pyproxy' (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on all addresses.
   WARNING: This is a development server. Do not use it in a production deployment.
 * Running on http://172.17.0.2:8000/ (Press CTRL+C to quit)

我就不去搭建https了,驗證一下這個服務正常吧。轉發一張OSChina的圖。

test.html

...
<img src="http://192.168.2.14:8000/proxy?url=https://oscimg.oschina.net/oscnet/up-3d152f8f91bd03bc979d17d6d398779c8b1.png"/>
...

圖太佔空間就不貼了,沒有問題的,已驗證。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章