LoginSignup
4
4

More than 3 years have passed since last update.

社内プロキシに打ち勝つリバースプロキシに苦戦した話(node + http-proxy)

Last updated at Posted at 2018-01-26

はじめに

社内でフロント向け開発ツールを作成していた時、クロスドメイン問題を回避するためにフォワードプロキシが必要になった。

やりたいこと

クライアントからのHTTPリクエストを受け、認証付き社内プロキシを経由して別サーバへフォワードする。
リクエストとレスポンスは改変しない。そのまま横流しするだけ。

使ったもの

修正前ソース

server.js
const httpProxy = require('http-proxy');
const http = require('http');

var proxy = httpProxy.createProxyServer({});

// http server
var httpServer = http.createServer(function (req, res) {
    res.setHeader('tekitou', 'tekitou');
    var opt = {target:'http://tekitou.com'};
    proxy.web(req, res, opt, function (err) {
        console.log(" !! translate error. ");
        console.log(err);
        res.write("<p> Translate error.</p>");
        res.write("<p>Host name : " + req.headers.host + "</p>");
        res.end();
        return;
    });
    return;
});
var port=1234
httpServer.listen(port, function () {
    console.log("-- start forward proxy server(http) . listen " + port + " port. --");
});

はまったところ

  • 認証付きの社内プロキシが通らない

そのままhttp-proxyでプロキシを作っても、認証付きの社内プロキシは通してくれない。
tunnnelを使って認証プロキシのagentをoptionに付与する必要あり。
<改変後>

server.js
const httpProxy = require('http-proxy');
const http = require('http');
// new!
const tunnel = require('tunnel');

var tunnelingAgent = tunnel.httpOverHttp({
    proxy: {
        host: 'hoge,co.jp',
        port: 1111,
        proxyAuth: 'proxyid:proxypass'
    }
});

var proxy = httpProxy.createProxyServer({});


// http server
var httpServer = http.createServer(function (req, res) {
    res.setHeader('tekitou', 'tekitou');
// new!
    var opt = {target:'http://tekitou.com' , agent:tunnelingAgent };
    proxy.web(req, res, opt, function (err) {
        console.log(" !! translate error. ");
        console.log(err);
        res.write("<p> Translate error.</p>");
        res.write("<p>Host name : " + req.headers.host + "</p>");
        res.end();
        return;
    });
    return;
});
var port=1234
httpServer.listen(port, function () {
    console.log("-- start forward proxy server(http) . listen " + port + " port. --");
});
  • フォワード先をhttpsに向けると通らない

optionにsecure=falseとchangeOrigin=trueを付与したら通った。
さらに、tunnnelのhttpOverHttpsのagentが必要。
<改変後>

server.js
const httpProxy = require('http-proxy');
const http = require('http');
const tunnel = require('tunnel');

var tunnelingAgent = tunnel.httpOverHttp({
    proxy: {
        host: 'hoge,co.jp',
        port: 1111,
        proxyAuth: 'proxyid:proxypass'
    }
});

// new!!
var tunnelingAgentForHttps = tunnel.httpOverHttps({
    proxy: {
        host: 'hoge,co.jp',
        port: 1111,
        proxyAuth: 'proxyid:proxypass'
    }
});

var proxy = httpProxy.createProxyServer({});


// http server to https
var httpServer = http.createServer(function (req, res) {
    res.setHeader('tekitou', 'tekitou');
    var opt = 
            { target:'https://tekitou.com',
              agent : tunnelingAgentForHttps ,
              secure : false,
              changeOrigin : true
             };
    proxy.web(req, res, opt, function (err) {
        console.log(" !! translate error. ");
        console.log(err);
        res.write("<p> Translate error.</p>");
        res.write("<p>Host name : " + req.headers.host + "</p>");
        res.end();
        return;
    });
    return;
});
var port=1234
httpServer.listen(port, function () {
    console.log("-- start forward proxy server(http) . listen " + port + " port. --");
});

さいごに

踏み込んだ説明がなくてごめんなさい。
スマートな方法があったら教えてください。

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4