:>/dev/null

ラガードエンジニアの不撓不屈の精神

Centos7でFirewalldを用いたポートフォワード設定

CentOS 7で採用されたFirewallでのポートフォワード設定を構築したのでメモしておく。
firewall-cmd –directよりfirewall-cmd –add-rich-ruleの方が個人的には分かりやすく感じたのでこちらで。

  • 以下構築要件
    • 内部ネットワークは全許可
    • 80番ポートにアクセスしてきたらsquidの3128番ポートへポートフォワード
firewall-cmd --add-masquerade
firewall-cmd --add-rich-rule="rule family="ipv4" source address="10.0.0.0/8" accept"
firewall-cmd --add-rich-rule='rule family="ipv4" source address="10.0.0.0/8" forward-port port="80" protocol="tcp" to-port="3128"'
※firewall-cmd --directの場合、[firewall-cmd --direct --add-forward-port=port=80:proto=tcp:toport=3128]

# firewall-cmd --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: ens160 ens192
  sources: 
  services: dhcpv6-client ssh
  ports: 
  protocols: 
  masquerade: yes
  forward-ports: 
  sourceports: 
  icmp-blocks: 
  rich rules: 
        rule family="ipv4" source address="10.0.0.0/8" accept
        rule family="ipv4" source address="10.0.0.0/8" forward-port port="80" protocol="tcp" to-port="3128"

これは”–permanent“が無いので一時的な設定になります。
firewall-cmd –reloadを実行すれば解除できます。
ルールを削除する場合、sed -i -e "s/--add-forward-port --remove-forward-port/"

参考

透過型proxyの構築まで~その2~ - いつまでも高みを目指して

Firewalldで特定のポートに特定のネットワークから許可 ← RootLinks Co., Ltd.

Centos系でのMASQUERADE構築

Centos7

●マスカレードホストルータ

  • firewallコマンドにてMASQUERADE設定
# firewall-cmd --direct --get-all-rules
firewall-cmd --direct --add-rule ipv4 nat POSTROUTING 0 -s 10.0.0.0/8 -j MASQUERADE
firewall-cmd --direct --add-rule ipv4 filter POSTROUTING 0 -t nat -s [src_server_gip] -j MASQUERADE
firewall-cmd --direct --add-rule ipv4 filter FORWARD 0 -o ens160 -j ACCEPT
firewall-cmd --direct --add-rule ipv4 filter FORWARD 0 -i ens192 -m state --state RELATED,ESTABLISHED -j ACCEPT

※ens160:GIP,ens192:LIP
※ルール削除する場合、sed -i -e "s/--add-rule --remove-rule/"

# vim /etc/sysctl.conf
net.ipv4.ip_forward=1
  • 設定確認
# sysctl -p
net.ipv4.ip_forward=1

●適用&確認

# systemctl unmask firewalld
# systemctl enable firewalld
# systemctl start firewalld
# systemctl status firewalld

●一時的設定と恒久的設定について

設定のコマンドを説明する前に一時的設定と恒久的設定について説明していきます。

一時的設定(–permanentオプション無し)

「firewall-cmd」コマンドで設定を行う際に、「–permanent」オプションを指定しなければその設定は一時的な設定となり、サーバや>「firewalld」のサービスを再起動すると設定が消えてしまいます。

恒久的設定(–permanentオプションあり)

サーバの再起動や「firewalld」サービスの再起動で設定が消えてしまわないようにするためには、「–permanent」オプションを使用して設> 定を行う必要があります。

その際、「–permanent」オプションを指定して設定を行った場合は、そのままでは「firewalld」に設定が反映されないため「fiewall-cmd –reload」で設定を反映させる必要があります。

●子クライアント

# route add default gw [MASQUERADE_server_ip]
※削除する場合 route del default gw [MASQUERADE_server_ip]
  • ルーティングの永続化
    • /etc/sysconfig/network-scripts/route-[インタフェース名]
    • これに下記のようなルーティング情報を記載
# cat /etc/sysconfig/network-scripts/route-eth0
[dst_server_gip]/32 via [MASQUERADE_server_ip] eth0
  • 特定Dstの場合、ルーティング追加にて個別設定可能
# route add -net [dst_server_gip] netmask 255.255.255.255 gw [MASQUERADE_server_ip] eth0
  • 確認
# ip route show

Centos6

●マスカレードホストルータ

  • iptablesコマンドにてMASQUERADE設定
# iptables -t nat -I PREROUTING -i eth0 -s 172.31.0.0/16 -p tcp --dport 80 -j DNAT --to-destination [MASQUERADE_server_ip:port]

※上記で正常に動作しない場合、下記書き方も検討

# iptables -t nat -A PREROUTING -i eth0 -s ! [src_server_ip] -p tcp --dport 80 -j DNAT --to [MASQUERADE_server_ip:port]
# iptables -t nat -A POSTROUTING -o eth0 -s 172.31.0.0/16 -d [MASQUERADE_server_ip] -j SNAT --to [src_server_ip]
# iptables -A FORWARD -s 172.31.0.0/16 -d [MASQUERADE_server_ip] -i eth0 -o eth0 -p tcp --dport [MASQUERADE_server_port] -j ACCEPT

参考

firewalldの設定方法(基本設定編) | server-memo.net

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/'

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

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/xxx.xxx.xxx.xxx text/html←親プロキシ経由
1495610490.536    204 10.131.0.206 TCP_MISS/200 46298 GET http://www.google.co.jp/? - HIER_DIRECT/xxx.xxx.xxx.xxx text/html←直接アクセス

参考

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

cache_peer

PHPのcRUL関数を用いたProxy接続

PHPでの開発時、Proxy経由で外部連携等々でcRUL接続を行う場合のサンプルコードを以下に示す。

<?php

$ch = curl_init();
$fp = fopen("/tmp/test.txt", "w");

// 通信内容を保存するためのテンポラリファイル
$errfp = tmpfile();

$loginpassw = 'ID:PASS';
$proxy_ip = 'http://proxy.test.com';
$proxy_port = '3128';
$url = 'http://www.google.com';

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

// proxy接続を無効にする場合、以下ブロックをコメント
curl_setopt($ch, CURLOPT_PROXYPORT, $proxy_port);
curl_setopt($ch, CURLOPT_PROXYTYPE, 'HTTP');
curl_setopt($ch, CURLOPT_PROXY, $proxy_ip);
curl_setopt($ch, CURLOPT_PROXYUSERPWD, $loginpassw);

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_FRESH_CONNECT, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 2);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_STDERR, $errfp);
curl_setopt($ch, CURLOPT_FAILONERROR, 1);



// file output
//curl_setopt($ch, CURLOPT_FILE, $fp);

$ret = curl_exec($ch);
print_r($ret);


// 記録した通信内容を読み出す
fseek($errfp, 0);
while (($line = fgets($errfp)) !== FALSE) {
    $tmp .= $line . "<br />";
}
// 通信状況を出力
echo $tmp;

curl_close($ch);
fclose($fp);
?>

参考

https://ameblo.jp/itboy/entry-11983530735.html

■wwwサーバのProfileとして読み込ませる事も可能

wwwサーバをapacheユーザーとして起動しいる場合
proxy-user = "ID:PASS"
proxy = "http://proxy.test.com:3128"

■システム全体へ適用

OS構成ファイル/etc/environmentへ配置

  • environmentファイル作成
    • $ vim /etc/environment
# プロキシ設定 ==============================================
# 実際の環境変数の設定
export http_proxy="http://ID:PASS@proxy.test.com:3128"
export https_proxy="http://ID:PASS@proxy.test.com:3128"
# 大文字バージョンしか認識しないプログラム用
export HTTP_PROXY="http://ID:PASS@proxy.test.com:3128"
export HTTPS_PROXY="http://ID:PASS@proxy.test.com:3128"
# プロキシを利用しないアドレスの指定(必須)
export no_proxy="127.0.0.1,localhost"
export NO_PROXY="$no_proxy"

上記により全てのユーザーで共通して使用可能。

■蛇足

curl の基本設定ファイルを作ることが出来る
~/.curlrc

Default config file, see -K, --config for details.

.curlrc に書く書き方は -K で指定する config ファイルと同じ

  • ①configファイル作成
    • $ vim /etc/curlrc
      • [/var/www/.curlrc]参照
  • ②configファイル指定した挙動確認
ここら辺を良しなに作成する一括設定スクリプト

下記サイト参照

http://www.magtranetwork.com/aws/batch_proxy_settings.html

中国のインターネット通信状況

中国国内からのパフォーマンス比較サイト

また別サイトの過去情報ですが、下記に調査結果を転載

<Yahoo・Googleへの上海からのアクセススピード> Yahoo・Googleへの上海からのアクセススピードを計測したところ(2/2 12:30時点)、Yahoo!JAPANのスピードは、8.3 KB/秒、Yahoo!中国雅> 虎(サーバー在中国)のスピードは、188.1 KB/秒という結果になっています。つまり、Yahoo!中国雅虎のアクセススピードは、Yahoo!JAPAN> のアクセススピードの22.6倍の速さとなっており、大きな差が生じています。

参考

https://www.value-press.com/pressrelease/34618

`

www site performance

■スピード調査方法

  • 1.以下をコピー
javascript:(function(){%20var%20d=document;%20var%20s=d.createElement('scr'+'ipt');%20s.charset='UTF-8';%20s.language='javascr'+'ipt';%20s.type='text/javascr'+'ipt';%20s.src='//web-tan.forum.impressrd.jp/tools/pagespeedtiming/pagesppedtiming.js?t='+(new%20Date()).getTime();%20d.getElementsByTagName('head')[0].appendChild(s);%20})();
  • 2.アドレスバーの[☆](星)をクリック
  • 3.[編集]ボタンをクリック
  • 4.[URL]にカーソルを移動して中身を全部消してクリップボードの内容を貼り付ける
  • 5.[名前]には「ページ速度チェック」とか適当に入れる
  • 6.完了ボタンをクリックし保存
  • 7.調査対象サイトをchromeで表示(アドレスバーに対象URLを貼り付ける)
  • 8.6で保存したブックマークを表示する
  • 9.解析結果が表示されるので保存する
    • 9-1.キーボードのctrl+Aにて全選択
    • 9-2.キーボードのctrl+Cにて全コピー
  • 10.txtエディターに貼り付ける
  • 11.貼り付け結果を調査称名で保存する

参考

http://web-tan.forum.impressrd.jp/e/2013/01/29/14562

goでHello World

■install

  # vim go.sh
  export PATH=$PATH:/usr/local/go/bin
  • /usr/local/go/bin/go version

■config

●niginx

 # vim /etc/nginx/nginx.conf

    location / {
        try_files $uri $uri.html $uri/index.html @rails-unicorn;
    }

    location /golang {
        fastcgi_pass 127.0.0.1:8190;
        include fastcgi.conf;
    }

■code

  • sample.go
package main

import (
  "fmt"
  "net"
  "net/http"
  "net/http/fcgi"
)

func viewHandler(res http.ResponseWriter, req *http.Request) {
  fmt.Fprintf(res, "<h1>%s</h1><div>%s</div>", "'Hello World", "fastCGI ")
}

func main() {
  l, err := net.Listen("tcp", "127.0.0.1:8190")
    if err != nil {
        return
    }
    http.HandleFunc("/", viewHandler)
    fcgi.Serve(l, nil)
}

■go run

  • systemctl start nginx.service
  • systemctl status nginx.service
  • cd {インストールディレクトリ}/
  • go run sample.go

■go build

  • go build sample.go
  • /samlpe &