いつきコンテンツ

ヘルプ

カウンター


2009-03-13 うおーWEBrickすげぇー

簡単すぎるー

が、はまると深い(笑)

[日記][プログラム] WEBrick (ruby) でproxy! 特に認証

いや、ヘッダとかコンテンツとかフィルタリングとか妙な動作を(笑)したい訳よ。分かるかなぁ?(笑)

それはともかく。

個人で使うなら、ほとんどのケースがRubyist Magazine - WEBrickでプロキシサーバを作って遊ぶのページだけで事足りる。

ぶっちゃけると

#!/usr/bin/env ruby

require 'webrick'
require 'webrick/httpproxy'

server = WEBrick::HTTPProxyServer.new({
:BindAddress => '127.0.0.1',
:Port => 3128,
:ProxyVia => false
})

trap('INT'){ server.shutdown }

server.start

こんな感じでできあがりなのである(ruby環境必須)

いやぁ楽ちんだねぇ。ここまでならば

ポート番号が3128なのはsquidへの嫌がらせです(ぉぃ

さて、次の段階へ行くよ~


認証してみましょう。プロキシ認証。圧縮proxy - とある技術屋の戯言当たりを参考に。

proxy_user、proxy_passってユーザとパスワードで認証。

こんな感じ

#!/usr/bin/env ruby

require 'webrick'
require 'webrick/httpproxy'

server = WEBrick::HTTPProxyServer.new({
:ProxyAuthProc => Proc.new() { | req, res |
WEBrick::HTTPAuth.proxy_basic_auth(req, res, 'proxy') { | user, pass |
user == 'proxy_user' and pass == 'proxy_pass'
}
},
:BindAddress => '127.0.0.1',
:Port => 3128,
:ProxyVia => false
})

trap('INT'){ server.shutdown }

server.start

ぶっちゃけ、:ProxyAuthProcの行が増えただけ。

固定じゃなくてどこかに問い合わせたければ、多分user ==とか書いてある行を書き変えれば良い。

ここまでもまぁまぁ楽。さて、地獄はまだまだだぜ!?


次。多段プロキシ。認証がなければかなり簡単。

#!/usr/bin/env ruby

require 'webrick'
require 'webrick/httpproxy'
require 'uri'

server = WEBrick::HTTPProxyServer.new({
:BindAddress => '127.0.0.1',
:Port => 3129,
:ProxyVia => false,
:ProxyURI => URI.parse('http://localhost:3128')
})

trap('INT'){ server.shutdown }

server.start

最初のバージョンから、:ProxyURIの行が増えただけ。ポートがぶつかるからここからのポートは3189で(一個ずらしただけカヨ)

認証無しのプロキシならこれで終了。

さて。認証の話に移ろうか。

さっきの(認証有りの)プロキシと組み合わせて見ると分かりますが、この組み合わせだと、「Proxy Authentication Required」と言われます。要するに上位のProxyサーバに問い合わせたらパスワードがねーよケッと言われてます。実はこの解決法は、「多人数に対して」多段プロキシを提供しないのであれば凄く簡単に解決できます。

#!/usr/bin/env ruby

require 'webrick'
require 'webrick/httpproxy'
require 'uri'

server = WEBrick::HTTPProxyServer.new({
:BindAddress => '127.0.0.1',
:Port => 3129,
:ProxyVia => false,
:ProxyURI => URI.parse('http://proxy_user:proxy_pass@localhost:3128')
})

trap('INT'){ server.shutdown }

server.start

ぶっちゃけ、:ProxyURIで指定するURIをhttp://ユーザ名:パスワード@サーバ名:ポート とするだけ。

この表記、httpの他の認証や、ftpのエセURL(ftp://anonymous:ituki@ftpserver/)とかにも使えます。覚えておくと便利かも。

まあ、ここまでは使ってる人が多い(?)と思われるのですんなり来ました。ここまでは


さて、今日みごとに踏み抜いた床を見てみましょう。死ぬかと思いました。

やりたかったこと:上位の認証有りのプロキシサーバに対して、複数ユーザを(上位で認証するIDとPASSを用いて)認証有りで、多段プロキシ

何言ってるか分かりますか?(笑)

先ほどは:ProxyURIで指定したproxy_userとproxy_passですが、今回は、人ごとに別のuserとpassが割当たっていて、親のproxyサーバのユーザとパスワードで認証したい。

当然ですが固定の人になるわけにはいかないので、URI.parseでIDとパスワードを指定する方法は使えません。

これ、どこかに正解あるのかなぁ……

と言う訳で、私なりの解です。

#!/usr/bin/env ruby

require 'webrick'
require 'webrick/httpproxy'
require 'uri'

module WEBrick
class HTTPProxyServerAuth < HTTPProxyServer
def proxy_auth(req, res)
if proc = @config[:ProxyAuthProc]
proc.call(req, res)
end
if req["Proxy-Authorization"] and (proxy = @config[:ProxyURI]) then
/^Basic\s+(.*)/o =~ req["Proxy-Authorization"]
up = ($1).unpack("m*")[0].split(":", 2)
proxy.user = up[0]
req.user = up[0]
proxy.password = up[1]
@config[:ProxyURI] = proxy
end
res["Proxy-Authenticate"] = "Basic realm=\"proxy\""
req.header.delete("proxy-authorization")
end
end
end

server = WEBrick::HTTPProxyServerAuth.new({
:BindAddress => '127.0.0.1',
:Port => 3129,
:ProxyVia => false,
:ProxyURI => URI.parse('http://localhost:3128')
})

trap('INT'){ server.shutdown }

server.start

(違ってたらゴメン)

もう魔法の言葉に見えるよママン。

HTTPProxyServerを継承したHTTPProxyServerAuthで、proxy_authで強引に:ProxyURIに書いてあったかのように書き換える作戦です。

変なヘッダ吐いてたらゴメン(^^; んでもって3129で待機してる(下位の)プロキシサーバに、407なのに認証したかのようにユーザ名が残るのは仕様です……いやなら21行目のreq.user = up[0]を削除のこと(ただし、認証が通っても誰か分からなくなります。多分(^^;)

誰かもっといい方法プリーズ!(笑)

[情報] iTunes 8.1 登場。2 件の欠陥が修正

使ってる人はアップデート

[ネタ] 「データ消去費用を振り込め」――mixiかたる詐欺に注意

なんぞそれ(笑)

最近確かにmixiかたるメールは多いですが。

[日記] やべ、スキャナ踏んだ

大丈夫か?(汗

……プラスティック部分がパキパキと音を立てるようにwww

Last Update: 2009-03-13 21:54:26

カレンダー

2003|04|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|07|08|11|
2013|03|05|08|
2014|01|
2015|04|05|06|07|09|10|12|
2016|01|03|05|06|10|11|
2017|06|
2018|05|08|09|10|11|
2019|04|08|12|
2020|03|08|09|11|
2021|05|
2022|04|
2023|12|
Generated by tDiary version 4.1.2 + amazon(DB Patch 0.2.1) + counter(DB Patch 0.2) + IKPatch version beta 4.0.1.
Powered by Ruby version 2.1.5-p273 with ruby-fcgi