|
こんにちは。 初めて書き込みいたします。 私は、CGIの使えないサイトで、ちょっとしたプロフのページを管理しています。 このサイトでは、自作CGIは一切使えず、既成のCGIを使うしかないのですが、最近、BBSのほうにおかしな書き込みが増えて困っています。 そこで、アクセス元のログを取ろうと考えまして、自作CGIを書きましたがここで問題が生じました。 おわかりかと思いますが、自作CGIを直接設置できないことが問題です。 ただ、このサイトでは、外部から一枚だけ、画像をリンクして表示できるんですね。 そこで、画像の参照元である手持ちのサーバの.htaccessをいじり、 画像がCGIとして機能するように設定しました。 それで、このCGIファイルを画像のように偽装してサイトにアップロードしました。 これによって、外部CGIを呼び出してログを保存することが出来ましたが、私の考えで言えば、いまどき、 print map {"$_ = $ENV{$_}"} keys %ENV; で表示されるデータなど、あまりあてにはできない... できれば、もっと確実なところで、匿名Proxy経由であれば、telnetを起動して接続元をファイルに保存、などの手法をとりたいのです。 ところが、画像のトリガーを使った方式ではこれが上手くいきません。 ヘッダの出し方に問題があるはずですが、なんとかならないものでしょうか? パワーユーザーの皆様、良い知恵がございましたらご教授ください。 宜しくお願いいたします<m(__)m> |
|
はじめまして^^ ネットワーク関連のプログラムいつも参考にさせていただいております。 今回ちょっとおききしたいことがありまして書き込ませていただきます。 内容がこちらのページの趣旨と離れて申し訳ないのですが、 お返事いただければ幸いです。 いきなり本題にはいらせていただきます。 <a href="$ENV{'SCRIPT_NAME'}?para=data"> としてリンクを作成して、その先のページで <form action="$ENV{'SCRIPT_NAME'}?para2=data2" method='POST'> とします。 このときフォームデータの取り込みのハッシュを%FORMとしたとき 2つめの$FORM{'para2'}が存在しません。 これがなぜおこるのかさっぱりわかりません。 またメソッドをGETでも試しましたがダメでした。 ただし、出力先のURLにはhttp://***.cgi?para2=data2と表示されます。でもprint文では表示されないのです。 原因がわかれば教えていただけないでしょうか? ちなみにperl5でapache1.3.14仕様です。 よろしくおねがいします;; |
|
>>3427 Mule 試してませんが、画像側で Location: telnet://example.com:1234 ではダメですか? (ダメなような気もしますが) 掲示板側では img src でしか外部リソースを呼び出せない、 という条件のもとでは、これ以外の方法は思いつきません でした。 >>3428 perler 誰かが環境変数 %ENV を解析し、その結果を %FORM に セットしなければならないわけですが、その部分はどこが 担当していますか? (CGI モジュールですか?) |
|
>>3429 68user ご返事ありがとうございます。 Locationは私も考えましたが、その方法は無理でした。 しかし、コマンドで上手く行きそうです。 現在、実験中ですので、詳細はまたご報告いたします。 とりあえず、今日はご報告まで。 お忙しい中、返事をいただきましてありがとうございました。 |
|
>>3430 Mule できそうですか。ぜひ結果を教えてください。 |
|
初歩的な質問で、申し訳ないのですが、教えていただけると助かります。 Bシェルでは、 if [$a = $b] then echo "ok!" fi などと、if文の中で、変数同士の値を比較してイコールならば、とかけますが、 Cシェルでは出来ないのでしょうか? |
|
通りすがりですが、 #!/bin/csh set a = 2; set b = 2; if(a == b) then echo "a = b" else if(a < b) then echo "a < b" else echo "a > b" endif で良かったと思います。 |
|
cshさん書き込みありがとうございます 実は、変数には、どの値が入ってくるか、分からないのです。 例えば、 ps -o user,pid,ppid,comm -A | grep -i $1 | grep -v grep > lis.txt set cmd1=(`awk '{print $2}' lis.txt`) set cmd2=(`awk '{print $3}' lis.txt`) @ cnt1=0 @ cnt2=0 foreach pid1 ( $cmd1 ) @ cnt1++ foreach ppid1 ( $cmd2 ) @ cnt2++ if ( $pid1 と$ppid1に入った値がイコールならば ) then echo 'zero!!' echo $pid1 $ppid1 >> procs1.txt ....... end end 。。。。。。みたいに。その、かっこの中を、どう書いてもエラーが出るんです。基本的なミスなのか、それともcでは出来ないのか、、、分からなくて。 if ($a==1) thenはOKでも、($a==$b)、はだめでした。 |
|
あ、すみません。。。。半角カナ。 |
|
>>3434 初心者 HP-UX11.0の環境で確認しましたが「==」で問題無く一致を検知できました。 「==」の前後に空白が無いと上記OSでは文法上のエラーになりました。 ご参考になれば。 |
|
>3429 お早いお返事ありがとうございました。 質問の答えなのですが、同プログラム内で%FORMによみこんでおります。 sub func { my($query,$pair); if($ENV{'REQUEST_METHOD'} eq 'POST'){ read(STDIN,$query,$ENV{'CONTENT_LENGTH'}; }else{$query=$ENV{'QUERY_STRING'};} foreach $pair (split/&/,$query){ ($key,$value)=split(/=/,$pair); #デコード処理 $FORM{$key}=$value; } このサブルーチンで処理させております。 ちなみにただのメールフォームではなにも問題なく動作します。 |
|
BSD UNIX 類のどれか欲しいんですけどお勧めはありますか? |
|
>>3437 perler > <form action="$ENV{'SCRIPT_NAME'}?para2=data2" method='POST'> という書き方をした場合、メソッドは POST ですが para2=data2 は 環境変数 QUERY_STRING 経由で渡されます。よって、 POST なら標準入力から読む というやり方では、QUERY_STRING からの入力は無視されてしまいます。 >>3438 超初心者 初心者ということであれば、FreeBSD 4.9-RELEASE がお勧めです。 http://www.h4.dion.ne.jp/~katsuwo/index.html |
|
>>3434 初心者 シェルの一行目を #/bin/csh -x に変更して再実行すれば 実際に変数に何が入ってくるか確認できますよ。 |
|
No. 3436 の通りすがりさん、No. 3440 zshさん、 書き込みありがとうございます 私の環境が違うのかも知れません。下記のように表示されてるので。 Digital UNIX V4.0B (Rev. 564 Digital UNIX Japanese Support V4.0A (rev. 3.1) で、やっぱりおっしゃるとおり実行したのだけど、だめなんです。 if ( $a == $b ) の、右辺の変数名が、分かりません、とかそう言うエラーが出るので、 結局 @ df=$a - $b if ($df == 0 ) で、何とかうまくいきました。 ありがとうございました。 |
|
>>3431 68user こんにちは、Muleです。 すみません、コマンドでtelnet起動、失敗しました(^^; これが出来たら、結構使えるスクリプトになるかもと思っていたのですが、やはり無理がありますかね... コード全体の流れとしては、 プロキシのチェックルーチンをよび、flagが立っていればif分岐、という典型的な処理です。 if($flag){ #telnetを起動し、接続元をファイルに記録する処理 } else{ my $img = 'file.gif'; my $byte = (stat $img)[7]; print "Content-Type: image/gif\n"; print "Content-Length: $byte\n\n"; open IMG,$img; binmode((binmode(IMG),$|=1)[0]); print map {$_} <IMG>; close IMG; } やはり、イメージで呼び出すという方式では、FTPで、というのが、現実的でしょうか? socketと組み合わせれば、なんとかなりそうな気がしていろいろ試してみましたが...上手く行かないものですね。 |
|
>>3442 Mule わたしは http は proxy 経由かもしれないが、ftp や telnet は proxy 経由でないことを期待して、クライアント側から ftp や telnet でサーバに接続させるように仕向けて、 IP アドレスを取得する と思っていたのですが、そうではないようですね。 > コード全体の流れとしては、プロキシのチェックルーチンをよび、 > flagが立っていればif分岐、という典型的な処理です。 「proxy のチェック」というのは公開 proxy サーバかどうかを 調べるため、クライアントの IP アドレスに接続してみる、という ことですよね。 telnet で接続、というのは http://x68000.startshop.co.jp/~68user/unix/pickup?sleep てな方法でできます。もちろん代わりに Socket を使ってもいいです。 方法はともかく、公開 proxy かどうかの判断はやろうと思えばできます。 で、なぜ if($flag){ #telnetを起動し、接続元をファイルに記録する処理 } と proxy チェックルーチンを呼んだ後 ($flag が確定した後) に もう一度 telnet を実行する必要があるのでしょうか? #telnet を起動し、クライアントの IP アドレスに接続。 #接続できたら $flag=1; if($flag){ #接続元をファイルに記録する処理 open(LOG, ">log"); print LOG "$ENV{REMOTE_ADDR} is open proxy\n"; close(LOG); } とすればよいのではないですか? |
|
>>3439 68user お返事ありがとうございました。 なるほど、それがperlの仕様なんですね^^ 原因がわかりました。 実は <form action="$ENV{'SCRIPT_NAME'}?para2=data2 method='POST'> <input type="hidden" name="mode" value="res"> <input type="submit" value="返信"> </form> とやっていたためPOSTとGETが混在してしまっていたようでした。 この形ではPOSTをGETにかえても成功しませんでした。 管理人さんの助言でこれに気づくことができました。 どうもありがとうございました。 結果だけお伝えしておきます。 method='POST'の場合 http://xxx.cgi?para2=data2となりmode=resがおくられない。 method='GET'の場合 http://xxx.cgi?mode=resとなりpara2=data2がおくられない。 でした。 |
|
>>3444 perler > なるほど、それがperlの仕様なんですね^^ perl とは関係ないです。これは HTML と CGI の領域です。 apache-1.3.29・IE6・Mozilla-1.5 で試した結果、 > method='GET'の場合 > http://xxx.cgi?mode=resとなりpara2=data2がおくられない。 これは正しいです。正確に言うと 「ブラウザが para2=data2 を送らない」 です。 > method='POST'の場合 > http://xxx.cgi?para2=data2となりmode=resがおくられない。 これは間違いです。標準入力を解析していないだけ、でしょう。 以下の CGI スクリプトを実行し、GET と POST それぞれで QUERY_STRING と標準入力にどういう値が入っているか確認 してください。 ------- #!/usr/local/bin/perl print "Content-type: text/html\n\n"; $script_name = $0; $script_name =~ s|.*/||; print <<END; <html><body> <form action="$script_name?para2=data2" method='GET'> <input type="hidden" name="mode" value="res"> <input type="submit" value="GET"> </form> <form action="$script_name?para2=data2" method='POST'> <input type="hidden" name="mode" value="res"> <input type="submit" value="POST"> </form> END print "REQUEST_METHOD=$ENV{REQUEST_METHOD}<br>\n"; print "QUERY_STRING=$ENV{QUERY_STRING}<br>\n"; print "STDIN=\n"; print <STDIN>; |
|
>>3445 68user お返事ありがとうございました。 なるほど、標準入力を解析しないということがわかりました。 パラメーターを指定しているのにPOSTをつかったのがいけなかったようですね。 またGETをつかってもパラメーターを送らないので素直に違う方法を考えます。 ご教授ありがとうございました。 |
|
>>3443 68user こんにちは、Muleです。 ご返事、ありがとうございます。 中途半端なコードを書いたせいか、誤解があったようですが、わたしも68user様が言われた、 >http は proxy 経由かもしれないが、ftp や telnet は >proxy 経由でないことを期待して、クライアント側から >ftp や telnet でサーバに接続させるように仕向けて、 >IP アドレスを取得する という、まさにそのことを考えております。 proxyのルーチンは、proxy経由かどうかを最初にチェックする為のもので、 httpからのアクセスがproxy経由でなければ、画像を出力し普通に接続元を記録する。 そうでなければ、クライアント側からtelnetでサーバに接続させて、接続元を記録する、という流れです。 FTPと書いたのは、わたしのほうで、FTPを用意し、CGIから出力する画像の参照元に、FTPサーバにある画像を指定して出力させれば、FTPのログに元の接続先が残るのではないかと思うからです。 考え方として、何か大きな間違いをおかしているでしょうか? ご指摘いただければ、幸いです。 |
|
>>3447 Mule > そうでなければ、クライアント側からtelnetでサーバに接続させて、 > 接続元を記録する、という流れです。 なるほど。つまり、 >>3442 Mule のサンプルは、 接続元 IP アドレスに接続 [*1] if ( 接続成功 ){ クライアント側が telnet でサーバに接続してくるような 出力を行なう (例えば Location とか)。[*2] } else { 画像を表示 } ということですね? もしそうなら納得です。 ただ、*1 の部分は可能ですが、*2 の部分はよほどセキュリティが 甘いブラウザでないと無理なのではないか、と思います。 |
|
>>3448 68user さっそくのご返事、感謝いたします。 私が考えているのは、68user様のひながたに沿って考えると、最初にtelnetを起動するというのではないです。 たとえば、こんな感じになると思います。 use CGI qw(:standard); $addr = remote_addr; $host = remote_host; $host = gethostbyaddr(pack("C4",split /\./,$addr),2) if($host eq '' || $host eq $addr); unless($host){ クライアント側が telnet でサーバに接続してくるような 出力を行なう (例えば Location とか)。 } else { 画像を表示 } です。 素朴に疑問なのですが、最初にtelnetを起動して、接続元に接続できるかどうかの判定を行わなければ、理屈的に無理なのでしょうか? 私は、proxy経由のアクセスがあった時にのみ、if文を実行させたいと思うのですが... |
|
>>3449 Mule > $host = gethostbyaddr(pack("C4",split /\./,$addr),2) if($host eq '' || $host eq $addr); 逆引きに成功したら (つまりクライアントが FQDN を持って いたら) proxy 経由でない、逆引きに失敗したら proxy 経由 という判定方法ですね。 これは proxy 判定にはなっていません。なぜなら技術的には、 「FQDN を持つかどうかと proxy サーバであるかどうか」 は関係がないからです。 後は統計的に 「proxy サーバは FQDN を持たないケースが多い」 と言えるかどうかですが、特にそういうこともないと思います。 むしろわたしは 「proxy サーバは FQDN を持つ可能性が高い」 と思います。 > 素朴に疑問なのですが、最初にtelnetを起動して、接続元に > 接続できるかどうかの判定を行わなければ、理屈的に無理 > なのでしょうか? 理屈的には、100% の精度の proxy 判定は不可能です。 ただ、完璧でなくていいなら、以下のような策はあります。 1. proxy 特有のヘッダ、例えば以下のようなものが設定されて いるか調べる。 HTTP_PROXY_CONNECTION HTTP_SP_HOST HTTP_VIA HTTP_X_FORWARDED_FOR http://taruo.net/e/ などで判定しているのはコレでしょう。 http://www2s.biglobe.ne.jp/~cru/library/lq/index.html でも 同様の判定を行っているようです。 ただし、proxy サーバの管理者が適切に設定すれば、これらの ヘッダを渡さないようにすることは可能です。 2. クライアント側の適当なポートに接続し、公開 proxy か どうか (誰でも接続できる proxy かどうか) 判断する。 例えば 2ch ではこれをやっているんでしょう。 http://info.2ch.net/guide/faq.html#F5 ただし、以下のような欠点があります。 - どのポート番号に接続するかは適当に決めなければならない。 全ポートをポートスキャンしていると時間がかかる。 - あくまで「公開 proxy」かどうかの判定にしか使えない。 (世の中の proxy の大多数を占める) 特定のネットワーク内から のみ使用可能な proxy は判定できない。 - ポートスキャンは反社会的。やりすぎると相手からクレームを 付けられる可能性が高い。 3. telnet・Java Applet などで直接接続させるよう仕向ける。 詳しくは以下のサイトをどうぞ。 http://akademeia.info/main/lecture3/tokubetu_IP_nuki.htm http://www.nurs.or.jp/~telnet/tips.html の 「telnetプロトコルによるIP抜き」 ただしこれも反社会的です。いきなりこれをやられたら、 わたしならそのサイトには二度と行きません。 普通は 1 でやめておくのがいいでしょう。2・3 は真面目な ページでやるには過激すぎると思います。 |
|
質問ではないんで、邪魔だったら消してくださいね。 過去ログを時間が許すままに読んじゃいました。 とってもおもしろかったです^^ まだまだいっぱい残っているので読破しようとおもいます。 言語はたくさん覚えたけど、UNIXには触ったことがないというある意味 希少なプログラマーなのでちょっとわからないこともあるんですけど、 予想するのが楽しいです。 最近のログをみていると応援の書き込みが少なかったので「管理がんばってください」の意味をこめてかきこませていただきました。 お目汚し失礼いたしました。 |
|
大変、参考になりました。 私がproxyのチェックを行う際には、hostが存在するかどうかの他に、以下のような環境変数を配列に入れて、foreach文や正規表現と組み合わせてチェックしています。 @proxy = ("HTTP_CLIENT_IP", "HTTP_VIA", "HTTP_CACHE_INFO", "HTTP_CACHE_CONTROL", "HTTP_FORWARDED", "HTTP_X_FORWARDED_FOR","HTTP_SP_HOST", "HTTP_TE","HTTP_XONNECTION","HTTP_PROXY_CONNECTION", "HTTP_XROXY_CONNECTION","HTTP_X_LOCKING", "HTTP_PRAGMA","HTTP_IF_MODIFIED_SINCE","HTTP_PC_REMOTE_ADDR"); この他に、 $ENV{'HTTP_CONNECTION'}を調べ、値がkeep-alive以外であればproxyと... しかしこの方法では、精度の高いproxyの判定は、厳しいのではないか...というのが現実でした。 最初から言えばよかったのかも知れませんが...というか、上手く説明できなったのですが、 私がやりたかったことは、結局のところ、 imgタグでしかCGIを起動できない環境で、3 ができるかどうかでした。 コードを直接置ける環境での、3のコードは書いたことがありますので、これをイメージをトリガーにした方法で実装できるかどうかが問題でした。 (telnetの自動起動は、いくらでも未然に防げるものの...) これまでいろいろご教授いただきまして、ありがとうございました。 また書き込みにくるかもしれませんが、暫くは教えていただいた情報を元に試行錯誤してみます。 それでは、よい休日を。 |
|
みなさん こんにちは。 すごく簡単な質問だと思うのですが、 過去ログを見てもわからなかったため質問いたします。 UNIXコマンドの compress a 1>/dev/null 2>&1 というコマンドについて。 compress a は、aファイルをcompress形式で圧縮するということはわかるのですが、 1>/dev/null 2>&1 は、どういう処理をしているのかわかりません。 よろしくお願いします。 |