社内プロキシに虐げられてる人たちはVPSとか借りて社外にプロキシ立ててsshトンネルで繋ぐとウハウハですよってお話

More than 1 year has passed since last update.

概要

社内プロキシに様々なサイトへのアクセスをブロックされたり、社外サーバにsshできなかったりする人向けに社外プロキシを立ててあらゆるサイトにアクセスする方法のまとめです。(後述しますが半分くらいネタポストです。)

他にも以下のような効果がありますので、プロキシフリーな会社にお勤めもし良かったら参考にして頂ければと思います。

  • なぜか2015年になっても存在するカフェとかホテルとかでの保護されていなかったりする無線wifiを使っても盗聴されない。
  • 日本からアクセスできないサイトにアクセスできる。(海外のデータセンタ上のVMを使った場合)

なお、非認証プロキシを例にしてます。認証プロキシでもあまり変わらないとは思いますが、環境が無いため未確認です。また、プロキシの挙動や設定方法はプロキシサーバの種類や設定によって多岐に渡るため、全てのプロキシで同じ方法が使えるとは限らないとは思います。

最後に環境構築が面倒な人向けにDigitalOcean上に環境を構築するVagrantfile(with Ansible Provisioner)を載せてます。DigitalOceanはただの趣味なので、他のクラウドサービスでも同じことはできます。

Disclaimer

タイトルは釣りです。

自分の場合はノマドなのでカフェとかのオープンなwifiが怖くて使うのがメインなんですが、ネタになりそうな方を前面に押し出してますのでご了承ください。タイトルの用途で使うなら申請すれば通るけど急いでる場合等に、上長やセキュリティ部門の許可を得て使う程度かと思います。
本ポストの内容を社内規程に抵触するような用途で使っても責任は負いかねます。

ブコメにてタイトルの用途で使う場合はDNSも変更しないと社内のDNS参照してしまうってツッコミを頂きましたが、wifiの安全性を気にして使う用途では問題ないので手順には追記しません。他にも抜け漏れあるかもしれないので、タイトルの用途で使うのはマジで辞めといた方が良いかと思われます。

また、プロキシで制限すべき・すべきでない論は会社の扱う情報や業種・業態、立場・思想などによって様々な意見があるというのは認識しております。しかし、Qiitaの目的は技術情報の共有かと思いますので、技術情報の共有と関係ない議論は控えさせて頂きますのでご了承ください。

思ったより反響が大きかったのでネタポストなのにマジな注意を書いてごめんなさいm(_ _)m
色々な方のご意見が聞けたのは大変勉強になってます。引き続きご意見頂けると励みになります。

手順

ということで手順です。一応ステップ分けて書きます。

社外サーバにsshアクセスする

社内ネットワークから社外ネットワークへのアクセスはhttp(80番ポート)とhttps(443番ポート)以外は許可していないことが多いと思います。

proxy01.png

よって基本的には社外にあるssh(22番ポート)サーバへのアクセスはできません。
最近ではクラウド上にサーバを立てることも多いと思いますが、保守的な会社だとsshのアクセス先の許可は申請ベースだったり、そもそも通らなかったりすることもあるかと思います。

proxy02.png

これの回避は非常に簡単で、単にsshでアクセスする社外のサーバで動いているsshのListenポートを443にしてしまえば良いです。プロキシがhttpとhttpsしか通さないのであればhttpsのポートでsshしてしまえば良いということです。

proxy03.png

変更するのはサーバ側の/etc/ssh/sshd_configのみです。
Portを変えたらsshdを(再)起動するだけです。

/etc/ssh/sshd_config
#Port 22
Port 443

ただし、社内のアクセス元のsshクライアントからプロキシ越しにアクセスする際にcorkscrewというツールが必要になります。Ubuntu14.04ではaptで入りました。CentOSではビルドしてインストールする必要がありますが、上記の公式サイトから落としてきたファイルを解凍して./configure,make,make installで素直に入りました。

corkscrewをインストールしたら~/.ssh/configProxyCommandcorkscrewを使うように設定します。実際に追加が必要なのはProxyCommand /usr/local/bin/corkscrew <proxyサーバのIP> <proxyサーバのポート> %h %pのみですが、参考までに自分の~/.ssh/configに記載しているものを書いておくと以下のようにしています。

~/.ssh/config
Host <sshで指定するときの名前>
  ServerAliveInterval 10
  User      <ssh接続先のユーザ名>
  Port      443
  HostName  <ssh接続する社外サーバのhost名/IP>
  UserKnownHostsFile /dev/null
  StrictHostKeyChecking no
  PasswordAuthentication no
  IdentitiesOnly yes
  LogLevel FATAL
  ProxyCommand /usr/local/bin/corkscrew <proxyサーバのIP> <proxyサーバのポート> %h %p

自分の場合はsshキーでのみのアクセスに制限しています。この場合、sshキーは事前に自宅等経由でコピーをするか一度パスワードでのアクセスを許可してコピーする必要があります。

社内プロキシで阻まれるサイトにブラウザアクセスする

ここまででsshで社外のサーバにアクセスできます。sshでアクセスできればそのサーバを踏み台としてほぼ何でもできますが、何かをダウンロードする場合には社外のサーバでwget等してから社内のサーバでscpとかしないといけないので不便です。ということで、次は社内マシンのブラウザから全てのサイトにアクセスできるようにしてみます。

流れとしては、以下のようになります。

  • 社外に立てたサーバにプロキシを立てる
  • 社外サーバに社内のマシンから443ポートでsshトンネルを張る
  • sshトンネル越しで社外サーバのプロキシを指定する

※本ポストへのコメントでsshの-Dオプション使えばプロキシソフトは不要とのツッコミを頂きました。実際に確認したところ不要でした。しかし、 書き換えが面倒くさいので説明の分かりやすさとURLフィルタ等のプロキシソフト自体のメリットを考えて、以降の説明はこのままとさせて頂きます。

社外サーバにプロキシを立てる

まずは社外サーバにプロキシを立てます。プロキシソフトは何でも良いですが、今回はprivoxyを使いました。ちょっと脱線しますが、privoxyは以下の点でオススメです。

  • URLフィルター等により広告のカットやURL置換等ができる(例えば何かと問題の起きるadblock等を個別のクライアントに入れなくても良くなります。)。
  • URLフィルタの設定を変えても再起動が不要のため、複数のユーザで使っていても影響が出にくい。

今回はとりあえず普通のプロキシとして動けば良いので、yumで入れて起動するだけです。

CentOS6系の例
sudo yum install privoxy
sudo service privoxy restart

serviceコマンドは叩かなくてもインストールした時点で起動するかもです。

proxy04.png

社外サーバに社内のマシンからsshトンネルを張る

社内のマシンから先ほどprivoxyをインストールした社外のマシンにsshトンネルを張ります。社内のマシンは常に立っているサーバがベターだと思いますが、実際にブラウザを立ち上げるノートPC等でも大丈夫です。

sshトンネルを張る
ssh -L 0.0.0.0:8888:localhost:8118 <社外サーバのIPまたはホスト名>

~/.ssh/configで指定していなければ、443ポートの指定(-pオプション)やユーザ名の指定(-lオプション)も必要になります。

これで上記のコマンドを実行した社内のマシンの8888ポートにアクセスすれば社外サーバの8118ポートにフォワードされるsshトンネルができます。常時起動している社内サーバから実行する場合はscreenやtmux等のセッションの中で起動しておけば良いでしょう。`

なお、設定方法は省略しますがセキュリティのためにもiptables/firewalld等は適切に設定してください。

proxy05.png

ブラウザからsshトンネルを張った社内サーバをプロキシ指定する

あとはブラウザを立ち上げる社内のマシンでsshトンネルを張った社内ローカルサーバのIP:PORT(今回の例だとlocal:8888)を指定すれば良いだけです。

こうすることで、ローカルサーバの8888ポートへのアクセスは社外サーバの443ポートへのsshトンネル経由でリモートサーバの8118ポートのprivoxyにフォワードされるため、リモートサーバがアクセスできる全てのサイトにブラウザからアクセス可能になります。

また、ローカルのサーバとリモートのサーバ間はsshでつながっているため、社内プロキシ等のアクセスログで具体的にどのサイトにアクセスしたかを把握することもできません。(ローカルサーバとリモートサーバ間が接続されていることは把握できます。)

さらに、最初にも書きましたが副次的な効果として、カフェとかホテルとかの怪しいwifiを使ってssl非対応サイトにアクセスしてもローカルとリモートプロキシ間の通信は保護されます。(自分の場合はこの用途がメイン)

ただし、残念ながらSSH通信の内容を傍受できるMan In The Middle Attack的な挙動をするタイプのプロキシは乗り越えられないと思います。このポストを見て危機感を持った管理者の方はその手のプロキシの導入を検討するのも良いかもしれません。

proxy06.png

環境構築用のVagrantfileとAnsibleのplaybook

上記の環境を構築するVagrantfileとPlaybookです。READMEは英語で色々書いてますが、このポストの内容を読めば読まなくて大丈夫です。
https://github.com/daikikohara/vagrant-do-privoxy

なお、残念ながらこれは社内プロキシ下ではなく、自宅等社外から実行する必要があります。

VagrantとVagrantのdigital_ocean用のプラグインとAnsibleは事前にインストールをお願いします。

Ubuntuでのインストール方法例
sudo apt-get install vagrant ansible
sudo vagrant plugin install vagrant-digitalocean

# vagrant実行マシンであとでプロキシ配下からsshする場合はcorkscrewもインストールしておく
sudo apt-get install corkscrew
# Vagrantfileで指定したsshの鍵を作ってなかったら以下も実行
ssh-keygen

続いて上記のレポジトリをcloneしてきて、各ファイルを適宜編集してください。最低限編集が必要なのは以下辺りかと思います。

  • Vagrantfile
    • DigitalOceanのアクセストークン
  • playbook(roles/proxy/tasks/main.yml)
    • コピーするsshキーを記載する(vagrant実行マシン以外の社内マシンのsshキー等)
    • 上記で指定したファイルをroles/proxy/files以下に配置する

編集したらVMを起動します。

sudo vagrant up --provider=digital_ocean

あとは社内サーバからsshトンネルを張って、社内のブラウザからsshトンネルを張ったマシンのIP/ポートを指定すればOKです。

なお、vagrant実行マシンでvagrant sshするときはVagrantfileのポートを443に変更してください。(サンプルではコメントアウトされているのを外せばOKです。)
また、vagrant実行マシンを社内に持っていってsshするときはVagrantfile内のproxycommandcorkscrewを使うようにしてください。(こちらもコメントアウトされているのを外せばOKです。)

なお、この機会にDigitalOceanに申し込むという方がいる場合、こちらから申し込んで頂けますと貧しい子供(のようなおっさん)を一人救うことができますw
https://www.digitalocean.com/?refcode=7be3336a0400

(※追記: 何人か申し込んでくれたみたいです。ありがとうございます!申し込んだ側もお得なので良かったら是非)

最後に

以上です。

いざというときのために用意しておくと何かと便利です。
ただし最初にも書きましたが、社内ルールに抵触する使い方はしないようお気をつけください。

Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.