:>/dev/null

ラガードエンジニアの不撓不屈の精神/unlearning/go beyond

squidによる多段プロキシ

多段でプロキシを組む場合、つまずいたのでメモがてら残しておく。

以下の様なパターンでアクセスが発生する。

  • PC => WWW
  • PC => PROXY (外部Proxy)(認証有) => WWW
  • PC => PROXY (イントラGW) => PROXY(外部Proxy)(認証有) => WWW

今回の目的

  • 外部Proxyサーバを経由して、アクセスさせる事により外部連携時のIP申請を省略する。
  • イントラGWを経由する事により、外部Proxyサーバの認証情報を一括管理する。
    • 各PCで外部Proxyサーバの認証情報を保持したくない。⇒セキュリティーポリシー・メンテナンス低下
  • 上記構成を実現する為、下記ネットワークを組む。
    • 各PC(ルーティング設定) ⇒ イントラGW ⇒ 外部Proxy ⇒ 外部接続

設定関連

各クライアントPC

  • OSのシステムファイルへイントラGWを指定
$ cat /etc/environment
# プロキシ設定 ==============================================
# 実際の環境変数の設定
export http_proxy="http://gwproxy.mysrv.com:3128"
export https_proxy="http://gwproxy.mysrv.com:3128"
# プロキシを利用しないアドレスの指定(必須)
export no_proxy="127.0.0.1,localhost"
export NO_PROXY="$no_proxy"

イントラGW

$ sudo vim /etc/squid/squid.conf
acl localnet src 192.168.0.0/16
http_access allow localnet
cache_peer proxy.srv.com parent 3128 0 proxy-only login=ID:PASS
never_direct allow all
never_direct allow CONNECT
visible_hostname unknown
forwarded_for off
  • cache_peer [上位プロキシの IP アドレス] parent [上位プロキシの ポート番号] [icp ポート番号] no-query [login=id:PASS]
  • proxy-only…ピアから取ってきたオブジェクトは、ローカルに保存しない
  • never_direct allow all…全てのリクエストを上位プロキシに転送する
  • never_direct allow CONNECT…社外ネットワークに接続する場合のSSL接続は、上位Proxyへパス(SSLはデフォルトで直接接続しようとする)
  • visible_hostname unknown…ホスト名の非表示
    • 「HTTP_VIA」というプロキシサーバーのホスト名を表示する環境変数を表示させない。 squid.conf では、「visible_hostname」というセクションがこれに対応しており、ここには通常は自分のホスト名を記述するのですが、「unknown」としてあたかも判別できなかったかのようにします。
  • forwarded_for off…一応IP隠す。

挙動確認

  • 各クライアントPCから下記コマンド発行
$ curl -v -H 'Cache-Control: no-cache' -L 'http://google.com/'

// 443の場合
$ git clone https://[user]@stash.test.com/src/test.git mydir

ホワイトリスト・除外リスト

never_direct

インターネット接続、つまりここまでに定義されていないドメインへのアクセスは、最終的に暗黙の転送先へ転送されます。
プロキシを使用する範囲、つまり「Exampleドメイン以外」の直接取得を禁止します。
never_direct allow yahoo
never_direct allow !example

always_direct

Exampleドメインだけは明示的に直接取得を許可します。さもないとプロキシーへ投げます。
always_direct allow example

サンプル
acl all src 0.0.0.0/0.0.0.0
acl host1 src [GIP:xxx.xxx.xxx.xxx]/255.255.255.255
acl yahoo dstdomain .yahoo.ne.jp .yimg.jp
acl google dstdomain .google.com .google.co.jp
acl mydomain dstdomain .mydomain.com .mydomain.co.jp


#always_direct allow host1
#always_direct allow yahoo
#always_direct allow google
always_direct allow !mydomain ←mydomainは親プロキシを経由。通常特定URL許可指定するが、今回は特定URLのみ親プロキシを経由する為
#always_direct allow all ←上記マッチしなかったもの、つまり「上記リストではないもの」は親プロキシを経由せず直接アクセス許可
# cat access.log
1495610456.780    126 10.131.0.206 TCP_MISS/200 103173 GET http://www.mydomain.com/ - FIRSTUP_PARENT/[親プロキシIP] text/html←親プロキシ経由
1495610490.536    204 10.131.0.206 TCP_MISS/200 46298 GET http://www.google.co.jp/? - HIER_DIRECT/[DST_IP] text/html←直接アクセス
// 443の場合
1497595884.998   2082 127.0.0.1 TCP_TUNNEL/200 4728 CONNECT stash.test.com:443 - FIRSTUP_PARENT/[親プロキシIP] -

ref)
Squid→Squidへ の多段プロキシ - それマグで!
cache_peer

HTTP proxy越しにSSHする

イントラGW

$ sudo vim /etc/squid/squid.conf

# ssh proxy
acl SSH_ports port 2222
acl Safe_ports port 2222        # ssh
http_access allow CONNECT SSH_ports

各クライアントPC

  • sshのconfig設定を使用してssh設定を行う
$ cat .ssh/config 
Host stash.test.com
        User user
        HostName stash.test.com
        Port 2222
        IdentityFile ~/.ssh/test.key
        ProxyCommand connect -H gwproxy.mysrv.com:3128 %h %p

$ chmod 600 .ssh/config
$ vim .ssh/test.key
-- 鍵内容をコピー ---
$ chmod 600 .ssh/test.key

// connectコマンドが「/bin/bash: line 0: exec: connect: not found」の場合
$ rpm -ivh http://mirror.fairway.ne.jp/dag/redhat/el6/en/x86_64/rpmforge/RPMS/rpmforge-release-0.5.3-1.el6.rf.x86_64.rpm
$ rpm -ivh http://mirror.fairway.ne.jp/dag/redhat/el7/en/x86_64/rpmforge/RPMS/rpmforge-release-0.5.3-1.el7.rf.x86_64.rpm
$ yum install --enablerepo=rpmforge connect

// sshプロトコルよりソース取得
$ git clone ssh://git@stash.test.com:2222/test/test.git mydir
# cat access.log
1497509393.078      1 127.0.0.1 TCP_TUNNEL/502 0 CONNECT stash.test.com:2222 - FIRSTUP_PARENT/[親プロキシIP] - ←親プロキシ経由(親プロキシ側で拒否されている)
1498460374.471   7051 10.131.0.217 TCP_TUNNEL/200 1700614 CONNECT stash.test.com:2222 - FIRSTUP_PARENT/[親プロキシIP] - ←親プロキシ経由(正常接続)

CentOSCVSを使用する場合

proxy経由でcvsを使用する場合、cvs 1.12.7以降で対応されいる様だが
CentOS6の標準repoでは現時点(20170712)でv1.11.xしか提供されてない為、src⇒buildの必要有り。
※CentOS7系では対象ソース無し

$yum install rpm-build.x86_64 libtool zlib-devel krb5-devel pam-devel
$mkdir -p /usr/src/redhat/{BUILD,RPMS,SOURCES,SPECS,SRPMS}
$wget -P /usr/src/redhat/SRPMS http://ftp.tmapy.cz/tmapy-twist/centos/6Server/obsolete/SRPMS/cvs-1.12.13-2.el6.1.src.rpm
$rpmbuild --rebuild /usr/src/redhat/SRPMS/cvs-1.12.13-2.el6.1.src.rpm
$rpm -ivh /root/rpmbuild/RPMS/x86_64/cvs-1.12.13-2.el6.1.x86_64.rpm
  • 挙動確認
cvs -d ":pserver;proxy=gwproxy.mysrv.com;proxyport=3128:[user]@[cvs_server]:[port]/usr/home/cvsroot" login

ref)
Ubuntu日本語フォーラム / [質問] cvs pserver proxy経由でのアクセスについて

  • エラー対応
    sshdで「refused connect from ...」で繋がらない

    • 原因
      TCP Wrapperの可能性。
----hosts.allowの内容----
ALL: 192.168.0.0/255.255.0.0
ALL: 127.0.0.1
  • 対策 hosts.allowに設定追加。
sshd: ALL