LoginSignup
53
56

More than 5 years have passed since last update.

インターネットに直接出れないホストで yum する方法

Posted at

まれによくある次のような構成。

        +-----+
        | gw  |
        +--+--+
           |
+---+---+  |  +-------+    +-------+
| hostA |--+--| hostB |----| hostC |
+-------+     +-------+    +-------+
  • hostA からは直接インターネットに出れる
  • hostC からは直接インターネットには出られない
  • hostA から hostC には hostB を経由しなければアクセスできない

この状況で hostC で yum する方法。

ProxyCommand

hostA から hostC へは ProxyCommand を使えば簡単に接続できます。ググるといろいろ情報は出てきます。

hostA
$ ssh -o "ProxyCommand ssh hostB nc -w 60 %h %p" hostC

あるいは、

hostA
$ ssh -o "ProxyCommand ssh hostB -W %h:%p" hostC

普通は ~/.ssh/config に書いておくのでしょうね。

この hostA → hostC の接続を使って hostC から hostA を経由して yum します。

SOCKS Proxy

hostC の libcurl が比較的新しいバージョンであれば ALL_PROXY 環境変数で SOCKS プロキシが指定できるので簡単です。

まずは hostA に SOCKS プロキシを立てます。

hostA
$ ssh -D 1080 localhost

次に ssh の -R で「hostC → hostA」の方向でポートフォワードしつつ hostC にログインします。

hostA
$ ssh -R 1080:localhost:1080 -o "ProxyCommand ssh hostB -W %h:%p" hostC

hostC の 1080 ポートが hostA の 1080 ポートに転送されているので ALL_PROXY 環境変数で SOCKS プロキシとして指定しつつ yum します。

hostC
$ ALL_PROXY=socks5h://localhost:1080 yum list

socks5:// と指定すると名前解決が hostC で行なわれます。socks5h:// と指定すれば名前解決も SOCKS プロキシ(つまり hostA)で行われます。

HTTP Proxy

CentOS 6 だと libcurl が微妙に古いようで yum の中の curl に SOCKS プロキシを指定する簡単な方法がわかりませんでした。curl そのものは SOCKS プロキシに対応しているようなのですが・・・

なので、hostA で HTTP プロキシを立てることにします。

プロキシサーバなら Squid とか Apache とかでも出来ますが、これだけの用途なら node.js で作るのが簡単かもしれません。

hostA
$ npm install http-proxy@0.9

$ cat <<EOS> fproxy.js
var net = require('net');
var url = require('url');
var server = require('http').createServer();
var httpProxy = require('http-proxy');
var proxy = new httpProxy.RoutingProxy();

server.on('request', function(req, res) {
    var uri = url.parse(req.url);
    proxy.proxyRequest(req, res, {
        host: uri.hostname,
        port: uri.port || 80
    });
});

server.on('connect', function(req, socket, head) {
    var arr = req.url.split(':', 2);
    var conn = net.connect(arr[1], arr[0], function() {
        socket.write("HTTP/1.1 200 OK\r\n\r\n");
        socket.pipe(conn);
        conn.pipe(socket);
    });
});

server.listen(8080, '127.0.0.1');
EOS

プロキシサーバを実行します。

hostA
$ node fproxy.js &

-R でポートフォワードしつつ hostC にログインします。

hostA
$ ssh -R 8080:localhost:8080 -o "ProxyCommand ssh hostB -W %h:%p" hostC

hostC の 8080 ポートが hostA の 8080 ポートに転送されているので ALL_PROXY 環境変数でプロキシとして指定しつつ yum します。

hostC
$ ALL_PROXY=http://localhost:8080 yum list
53
56
1

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
53
56