linuxの最近のブログ記事
squidを使ってプロクシサーバをたてた。
NATの内側にproxyがある。
http/httpsは問題ないが、LAN内のブラウザ→squid→ftpリソース、だと取得できない。
試しにsquidが動作しているサーバでwgetを使って同じftpリソースを取得してみたがこっちはOK。なので、ネットワーク的にはいけるはず。
PASVになってないのかな?と思ってtsharkでキャプチャしてみると、PASVに対して肯定応答をもらっているのに、その後なぜかPORTを送り、相手のサーバからConnection確立できない、という応答。
今度はstraceで様子を見てみると、PASVを送ったあと相手のサーバに接続しようとしたところでconnectがEACCESでエラーになっている。
どういうこと?と思ったけど「squid ftp selinux」で検索してみると良くある話題のようだ。
selinuxポリシー内で、squidがftp接続に行けるポートを制限しているらしい。
selinuxってこういう制限もするのか。
実のところ、selinuxでブロックされている、ということは後からわかった。
試行錯誤しまくった過程で、iptablesのモジュール(/etc/sysconfig/iptables-configのIPTABLES_MODULES)にip_conntrack_ftp を加えても通るようになった。これはいまだになぜかわかってない・・・。
CentOS:5.3
squid-2.6.STABLE21-3.el5
selinux-policy-2.4.6-203.el5
selinux-policy-targeted-2.4.6-203.el5
NATの内側にproxyがある。
http/httpsは問題ないが、LAN内のブラウザ→squid→ftpリソース、だと取得できない。
試しにsquidが動作しているサーバでwgetを使って同じftpリソースを取得してみたがこっちはOK。なので、ネットワーク的にはいけるはず。
PASVになってないのかな?と思ってtsharkでキャプチャしてみると、PASVに対して肯定応答をもらっているのに、その後なぜかPORTを送り、相手のサーバからConnection確立できない、という応答。
今度はstraceで様子を見てみると、PASVを送ったあと相手のサーバに接続しようとしたところでconnectがEACCESでエラーになっている。
どういうこと?と思ったけど「squid ftp selinux」で検索してみると良くある話題のようだ。
selinuxポリシー内で、squidがftp接続に行けるポートを制限しているらしい。
selinuxってこういう制限もするのか。
実のところ、selinuxでブロックされている、ということは後からわかった。
試行錯誤しまくった過程で、iptablesのモジュール(/etc/sysconfig/iptables-configのIPTABLES_MODULES)にip_conntrack_ftp を加えても通るようになった。これはいまだになぜかわかってない・・・。
CentOS:5.3
squid-2.6.STABLE21-3.el5
selinux-policy-2.4.6-203.el5
selinux-policy-targeted-2.4.6-203.el5
USBデバイスはSCSIデバイスにmapされるんだから、dmesgで確認してmountすればいいさー、と思ってたら変なところでハマってしまった。
あれー?と思って/devを見ると確かに存在しない。
で結局mknodでデバイスファイルを作ってmountした。
いつ終了しちゃったんだろう・・・
ということで、
しかしなんでudevd居なくなってたんやろう。yumで5.1→5.2してから再起動してないからだろうか。
OS: CentOS 5.2
udev-095-14.16.el5
kernel-2.6.18-92.1.6.el5
usb-storage: waiting for device to settle before scanningてな感じのログが出たのでsdb1をmountしようとしたら、
Vendor: BUFFALO Model: ClipDrive Rev: 1.11
Type: Direct-Access ANSI SCSI revision: 02
SCSI device sdb: 258048 512-byte hdwr sectors (132 MB)
sdb: Write Protect is off
sdb: Mode Sense: 03 00 00 00
sdb: assuming drive cache: write through
SCSI device sdb: 258048 512-byte hdwr sectors (132 MB)
sdb: Write Protect is off
sdb: Mode Sense: 03 00 00 00
sdb: assuming drive cache: write through
sdb: sdb1
sd 4:0:0:0: Attached scsi removable disk sdb
sd 4:0:0:0: Attached scsi generic sg1 type 0
mount: スペシャルデバイス /dev/sdb1 が存在しませんと言われる。
あれー?と思って/devを見ると確かに存在しない。
で結局mknodでデバイスファイルを作ってmountした。
mknod /dev/sdb b 8 16で、ウチのudevdはどうなっとるのだと思ってpsしてみたら、居なかった・・・・。
mknod /dev/sdb1 b 8 17
でも、以前mountしたときは最初からあったような・・・
と思って調べたら、udevdがkernelからのイベントを受け取ってruleに従って適宜作成してくれるものらしい。
知らんかった。
いつ終了しちゃったんだろう・・・
ということで、
- 一旦umount
- USBメモリ抜く
- /dev/sdb* をrm
- /sbin/start_udevで改めて起動
- USBメモリ挿す
- /dev/sdb1出来た!
- mount
しかしなんでudevd居なくなってたんやろう。yumで5.1→5.2してから再起動してないからだろうか。
OS: CentOS 5.2
udev-095-14.16.el5
kernel-2.6.18-92.1.6.el5
FC6→CentOS5.1に変えてから、graphvizを使うプログラムでエラーログが出てた。
最初は↓なメッセージだったので、
そしたら今度は、↓なメッセージ
と「graphviz format: "png" not recognized.」でgoogle検索したら2chのスレッドがヒット。
曰く、
ということで、graphviz-gdもダウンロードしてきてインストール。
2chって、こういうノウハウもあるからあなどれんな~
最初は↓なメッセージだったので、
Error: Layout was not done. Missing layout plugins?graphviz本家からEL5用のrpmをダウンロードしてきてインストールした。
そしたら今度は、↓なメッセージ
Format: "png" not recognized.んー、なんでじゃ。
と「graphviz format: "png" not recognized.」でgoogle検索したら2chのスレッドがヒット。
曰く、
743 名前:login:Penguin:2007/07/18(水) 04:04:48 ID:8oFxpWqqあ、ソレだ。
>>740
CentOS4にRHEL4用のrpm入れて使ってるけど
そんな問題起こってない。まったく問題なし。
文字コードをUTF8に変換してTrueTypeフォント指定すれば
日本語も出てるしね。Vine-2.6時代に四苦八苦してたのが嘘のよう。
まさかgraphviz-gd入れてないとか言わないよな?
ということで、graphviz-gdもダウンロードしてきてインストール。
2chって、こういうノウハウもあるからあなどれんな~
「subversionのリポジトリブラウザとBTSとWikiが一緒になった」というtracを使ってみる。というか以前から使っていたのだが環境の問題かあちこちいじらないと動かなかったのでメモ。
当初はmod_pythonを用いようとしたのだが、Segmentation FaultまたはAbortでapacheが死んでしまった。以下の要求を満たす形で構築したい、ので試行錯誤した。
- ブラウザだけ用意できればアクセスできるようにしたい。httpsでアクセスしたい。
- 外から見た場合に、https://xxxx.exmple.com:2222/のようなポート番号指定のURLではなくhttps://xxxx.example.com/project/のように表現したい。→穴を開けるポートを増やしたくない。
- ウチではサーバにlinuxを使っている。外部公開しているポイントの穴を増やすことも避けたいが、iptablesによる許可ポートもできるだけ増やしたくない。
- 認証はapacheの機能で行いたい。
- これは「セキュリティはインフラサイドで確保するもの」という自身のポリシーもあるけど、Active DirectoryでSubversionのリポジトリとtracの認証を共通化したかった+apacheの認証モジュールの多さと設定の柔軟さを活かしたいから、という理由
- 外部からはhttpsで接続したい
- プライベートなプロジェクトを管理したいから。
- CGI型はかなりレスポンスが遅くなるので採用しない。
- なのでmod_pythonを選択したいところだが、apacheが死んでしまう問題を解決できなかったのでスタンドアロン型を選んだ。
- また、スタンドアロン型といっても管理するアクセスログが増えるのはイヤで、apacheのログとひっくるめて管理できるようにしたい。
- フロントエンドはapacheで、認証もここで行う。ついでにSSLも可に。
- 内部でtracdを動かし、apache→tracd間はmod_proxyでリバースプロクシでつなぐ
導入
- trac本家はここ(http://www.edgewall.com/trac/)だが、日本語化したものをインタアクト株式会社が公開しているのでありがたく使わせてもらう。
- ClearSilver、SQLite、パイソンバインディングなどもろもろ用意せねばならんのだが、このあたりは既に詳しいページが多数あるので割愛。
設定
- SSLの設定はあちこちに情報があるので割愛。
- tracの設定もあちこちに情報があるので割愛。ただ、今回想定している環境は「外向きにはhttps」なので、デフォルトのままだとtracdが返す情報(特にLocationヘッダ)でhttpスキームを使われてしまうのでbase_urlを指定した。
(projectenv)/conf/trac.ini
[trac]
base_url = https://外向け/trac
- リバースプロクシは以下のような感じ。(Location内にリバースプロクシ設定を書いているので、パラメータが略されている点に注意)
<Location /trac>
ProxyPass http://tracdのIP:tracdのポート/trac
ProxyPassReverse http://tracdのIP:tracdのポート/trac
</Location> - 認証の設定もあちこちに情報があるので割愛。ふつーにtracのURL範囲を認証要に設定すればよい。BasicでもKerberosでも任意選択できる。
- ここまででhttps://外向け/trac/へのアクセスがapacheにより認証されたうえで、内部で動作しているtracdにプロクシされるはず。ウチの環境の場合、内部は内部ネットワーク向けのDNSを動かしていて、外向けのFQDNと内部ホストのFQDNを同じにしているので(IPは異なる)、これが異なる場合はcookie関係の設定が必要かも。
tracユーザの識別問題
- trac上のユーザ識別も必要だ。なぜならチケットの発行やマイルストーンの編集などの権限判断は「trac上のユーザ」で行われるから。したがってapacheで認証したユーザをなんとかしてtracdにも認識させたい。tracdで使う認証がBasicまたはDigestであれば、apacheとtracdの間で認証データベースを共有することで解決できる。しかし今回のように「BasicでもDigestでもなくKerberosが使いたい」「mod_proxyを介している」という条件が加わると、tracdの認証オプションだけは解決できないようだ。
- で、「apacheで認証したリクエストだけがtracdに到達する」という状況から「tracdへのアクセスは認証済み」と考える。Authorizationフィールドからユーザ名を抜き出してtracユーザとして使用することにする。
- 下のようなパッチをあてて、tracdのコマンドラインオプションと「認証しない認証クラス」を捏造する。
--- trac-0.9.5-ja-1/scripts/tracd 2005-12-02 10:10:17.000000000 +0900
+++ trac-0.9.5-ja-1kai/scripts/tracd 2006-06-04 20:38:59.000000000 +0900
@@ -16,6 +16,7 @@
# Author: Jonas Borgstr
from trac.web.standalone import BasicAuth, DigestAuth, TracHTTPServer
+from trac.web.TrustedAuth import *
import getopt
import locale
@@ -56,6 +57,7 @@
try:
opts, args = getopt.getopt(sys.argv[1:], "a:p:b:de:",
["auth=", "port=", "hostname=","daemonize",
+ "trusted-auth=",
"env-parent-dir=", "basic-auth="])
except getopt.GetoptError, e:
print e
@@ -66,6 +68,8 @@
add_auth(auths, a, DigestAuth)
if o == '--basic-auth':
add_auth(auths, a, BasicAuth)
+ if o == '--trusted-auth':
+ add_auth(auths, a, TrustedAuth)
if o in ("-p", "--port"):
port = int(a)
elif o in ("-b", "--hostname"):
--- trac-0.9.5-ja-1/trac/web/TrustedAuth.py 1970-01-01 09:00:00.000000000 +0900
+++ trac-0.9.5-ja-1kai/trac/web/TrustedAuth.py 2006-06-04 20:40:22.000000000 +0900
@@ -0,0 +1,67 @@
+# -*- coding: utf-8 -*-
+#
+# This is adhoc auth?-module under tracd.
+#
+# If you are using tracd and external proxy(ex. mod_proxy) with some auth
+# method, the access for tracd is already authorized.
+#
+# TrustedAuth regard the user as already trusted.
+# The user extraced from Authorization field.
+#
+# Author: tckz<tckz@nifty.com>
+#
+
+from trac import util, __version__
+from trac.web.api import Request
+from trac.web.cgi_frontend import TracFieldStorage
+
+import urllib2
+
+try:
+ from base64 import b64decode
+except ImportError:
+ from base64 import decodestring as b64decode
+
+
+class TrustedAuth:
+ def __init__(self, dummy, realm):
+ self.realm = realm
+
+ def send_auth_request(self, req):
+ req.send_response(401)
+ req.end_headers()
+
+ def parse_auth_header(self, authorization):
+ values = {}
+ for value in urllib2.parse_http_list(authorization):
+ n, v = value.split('=', 1)
+ if v[0] == '"' and v[-1] == '"':
+ values[n] = v[1:-1]
+ else:
+ values[n] = v
+ return values
+
+ def do_auth(self, req):
+ if not 'Authorization' in req.headers:
+ self.send_auth_request(req)
+ return None
+
+ user = ""
+ if req.headers['Authorization'].startswith('Basic'):
+ auth = req.headers['Authorization'][len('Basic')+1:]
+ auth = b64decode(auth).split(':')
+ if len(auth) == 2:
+ user, password = auth
+ elif req.headers['Authorization'].startswith('Digest'):
+ auth = self.parse_auth_header(req.headers['Authorization'][7:])
+ if auth.has_key('username'):
+ user = auth['username']
+ else:
+ self.send_auth_request(req)
+
+ if user == "":
+ self.send_auth_request(req)
+ return None
+
+ return user
+
- tracd起動時のコマンドラインは↓のような感じで。--trusted-authの引数にカンマ区切りの3要素を指定しなければならないのは、元々tracdのadd_authメソッドに手を入れていないから。「*」部分はtracプロジェクト名。「*」にすると全部のプロジェクトが対象となる(元々の仕様)
/usr/bin/tracd --trusted-auth '*,,' -p ポート -b localhostとか -d -e parent-dir-of-envs
最近、Typekeyによるサインインができないのはなぜだろう?と思っていたら
> The TypeKey signature is out of date (-632 seconds old). Ensure that your server's clock is correct
ということだった。ntp動かしてなかったっけ・・・。時刻を補正してサインインしたらOK。
specをちびっと触ったのでメモ。
- SQLite home pageからダウンロードしたsqlite-3.3.4.tar.gzを任意の場所に展開する。
- sqlite-3.3.4.tar.gzを/usr/src/redhat/SOURCE/にコピーする(コピー先は環境により変わるのかな??)
- specをビルドする過程でtclshが必要だったので、tclもインストールした。
- 展開したディレクトリにある「spec.template」を編集して「rpmbuild -bb spec.template」
[aaa@bbb sqlite-3.3.4]# diff -u /usr/src/redhat/BUILD/sqlite-3.3.4/spec.template spec.template
--- /usr/src/redhat/BUILD/sqlite-3.3.4/spec.template 2005-12-20 02:30:55.000000000 +0900
+++ spec.template 2006-03-14 23:16:30.000000000 +0900
@@ -1,5 +1,5 @@
%define name sqlite
-%define version SQLITE_VERSION
+%define version 3.3.4
%define release 1
Name: %{name}
@@ -30,7 +30,7 @@
to develop programs that use the sqlite database library.
%prep
-%setup -q -n %{name}
+%setup -q -n %{name}-%{version}
%build
CFLAGS="%optflags -DNDEBUG=1" CXXFLAGS="%optflags -DNDEBUG=1" ./configure --prefix=%{_prefix}
