当使用来自oracle XE和utl_http的httpd(apache)作为反向代理时出现问题

时间:2018-02-20 17:35:13

标签: oracle apache fiddler

我正在尝试使用反向代理连接到需要https的restful webservice。 由于我在Oracle XE数据库中使用该服务,因为新版本的https存在问题,我正在尝试使用反向代理,以便oracle可以使用http进行连接。我决定使用apache并尝试遵循此guide。 我的httpd.conf包含以下条目:

Listen 8086

RewriteEngine On
ProxyVia On

ProxyRequests Off
SSLProxyEngine On
SSLProxyVerify none 
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off
SSLProxyCheckPeerExpire off

<proxy *="">
  Order deny,allow
  Allow from all
</proxy>

ProxyPass        /earthquakes_allday/     https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_day.geojson
ProxyPassReverse /earthquakes_allday/     https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_day.geojson
ProxyRemote https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_day.geojson http://revprox-ip.here:8086

通过此条目,我可以使用http://revprox-ip:8086/earthquakes_allday/的其他客户端扩展程序从Firefox发出请求,并且它没有任何缺陷。

Status Code: 200 OK
Access-Control-Allow-Headers: accept,origin,authorization,content-type
Access-Control-Allow-Methods: *
...

在oracle内部,我创建了以下函数来发出请求:

FUNCTION make_request (
        p_url            VARCHAR2,
        p_request_type   VARCHAR2,
        p_request_body   CLOB
    ) RETURN CLOB IS

        utl_req         utl_http.req;
        utl_resp        utl_http.resp;
        req_length      BINARY_INTEGER;
        response_body   CLOB;
        resp_length     BINARY_INTEGER;
        buffer          VARCHAR2(2000);
        amount          PLS_INTEGER := 2000;
        offset          PLS_INTEGER := 1;
        ret_code        INTEGER;
        res_clob        CLOB;
    BEGIN
        DBMS_LOB.CREATETEMPORARY(RES_CLOB,TRUE);
        utl_req := utl_http.begin_request(p_url,p_request_type,'http/1.1');
        utl_http.set_cookie_support(true);
        utl_http.set_header(utl_req,'user-agent',user_agent);
        utl_http.set_header(utl_req,'content-type',content_type);
        req_length := dbms_lob.getlength(p_request_body);
        IF
            req_length <= 32767
        THEN
            utl_http.set_header(utl_req,'Content-Length',req_length);
            utl_http.write_text(utl_req,p_request_body);
            -- If Message data more than 32kb   
        ELSIF req_length > 32767 THEN
            utl_http.set_header(utl_req,'transfer-encoding','chunked');
            WHILE ( offset < req_length ) LOOP
                dbms_lob.read(p_request_body,amount,offset,buffer);
                utl_http.write_text(utl_req,buffer);
                offset := offset + amount;
            END LOOP;

        END IF;

        utl_resp := utl_http.get_response(utl_req);
        BEGIN
            LOOP
                utl_http.read_text(utl_resp,buffer);
                dbms_lob.writeappend(res_clob,length(buffer),buffer);
                dbms_output.put_line(buffer);
            END LOOP;

            utl_http.end_response(utl_resp);
        EXCEPTION
            WHEN utl_http.end_of_body THEN
                utl_http.end_response(utl_resp);
            WHEN OTHERS THEN
                utl_http.end_response(utl_resp);
                    --utl_tcp.close_all_connection();
                RAISE;
                ret_code := utl_resp.status_code;
                utl_http.end_response(utl_resp);
                --analyze_response_code(ret_code);
        END;

        RETURN res_clob;
    END;

当我这样调用函数时:

DECLARE
    my_clob clob;
BEGIN
    MY_CLOB := make_request('http://revprox-ip.here:8086/earthquakes_allday/', 'GET', NULL);
END;

这只给出了以下输出:

<html>
<head><title>400 Bad Request</title></head>
<body bgcolor="white">
<center><h1>400 Bad Request</h1></center>
<hr><center>nginx/1.13.9</center>
</body>
</html>

然后我尝试在其间使用Fiddler,在fiddler的规则中添加以下内容:

if (oSession.host == "fiddlerhost:8888") {
            oSession.host ="http://revprox-ip.here:8086";
        }

将fiddler添加到链中导致从oracle调用web服务工作(让我想起观察者效果)。那我怎么解决这个问题呢?在生产环境中,除了反向代理之外,我还无法安装fiddler。

1 个答案:

答案 0 :(得分:0)

代替使用Apache作为反向代理,也许可以使用stunnel。您无需仅运行完整的Web服务器即可获得功能齐全的TLS客户端。

如果将其作为inetd样式的服务(xinetd或systemd套接字激活)运行,则可以使用最小的配置文件:

setuid  =   nobody
setgid  =   nobody
chroot  =   /var/empty/stunnel

client  =   yes
connect =   your.target.com:1234

您还可以使用其他一些全局选项来加强安全性:

sslVersion  =   TLSv1.2

; https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/

ciphers = ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:RSA+AESGCM:RSA+AES:!aNULL:!MD5:!DSS

curve   =   secp521r1

如果您正在与stunnel侦听器在同一服务器上运行XE数据库,则用于utl_http的基本URL将是http://127.0.0.1:5678;否则,您将在单独的主机上使用隧道端点。